diff options
66 files changed, 4992 insertions, 3315 deletions
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index b6a81206..b96ef5a4 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,4 +1,4 @@ -- [ ] I agree to license my contribution under LGPL-3.0 **or** my contribution is from another project with a license compatible with LGPL-3.0 +- [ ] I agree to license my contribution under GPL-3.0 and agree to allow distribution on app stores as outlined in [LICENSE-APPSTORE](https://github.com/ajayyy/SponsorBlock/blob/master/LICENSE-APPSTORE.txt) To test this pull request, follow the [instructions in the wiki](https://github.com/ajayyy/SponsorBlock/wiki/Testing-a-Pull-Request). diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ac044615..96b68aec 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,4 +1,4 @@ -If you make any contributions to SponsorBlock after this file was created, you are agreeing that any code you have contributed will be licensed under LGPL-3.0 or later. +If you make any contributions to SponsorBlock after this file was created, you are agreeing that any code you have contributed will be licensed under GPL-3.0 and agree to allow distribution on app stores as outlined in LICENSE-APPSTORE. # Translations https://crowdin.com/project/sponsorblock @@ -1,165 +1,674 @@ - GNU LESSER GENERAL PUBLIC LICENSE + GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 - Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + <program> Copyright (C) <year> <name of author> + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +<http://www.gnu.org/licenses/>. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +<http://www.gnu.org/philosophy/why-not-lgpl.html>. diff --git a/LICENSE-APPSTORE.txt b/LICENSE-APPSTORE.txt new file mode 100644 index 00000000..414a3de7 --- /dev/null +++ b/LICENSE-APPSTORE.txt @@ -0,0 +1,13 @@ +The developers are aware that the terms of service that +apply to apps distributed via Apple's App Store services and similar app stores may conflict +with rights granted under the SponsorBlock license, the GNU General +Public License, version 3. The copyright holders of the SponsorBlock +project do not wish this conflict to prevent the otherwise-compliant +distribution of derived apps via the App Store and similar app stores. +Therefore, we have committed not to pursue any license +violation that results solely from the conflict between the GNU GPLv3 +and the Apple App Store terms of service or similar app stores. In +other words, as long as you comply with the GPL in all other respects, +including its requirements to provide users with source code and the +text of the license, we will not object to your distribution of the +SponsorBlock project through the App Store.
\ No newline at end of file diff --git a/LICENSE-HISTORY.txt b/LICENSE-HISTORY.txt new file mode 100644 index 00000000..25bdd313 --- /dev/null +++ b/LICENSE-HISTORY.txt @@ -0,0 +1,171 @@ +Prior to commit 7338af3b384e2297eaf710443121ac840099a9f1, this project was licensed under LGPL 3.0. + +You must follow LICENSE instead if you want to use any newer version. + +---- + + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. @@ -75,4 +75,4 @@ Icons made by: ### License -This project is licensed under GNU LGPL v3 or any later version +This project is licensed under GNU GPL v3 or any later version diff --git a/ci/generateList.ts b/ci/generateList.ts index 7c0f8882..b3da21cc 100644 --- a/ci/generateList.ts +++ b/ci/generateList.ts @@ -7,8 +7,7 @@ This file should not be shipped with the extension /* Criteria for inclusion: Invidious -- 30d uptime >= 90% -- available for at least 80/90 days +- uptime >= 80% - must have been up for at least 90 days - HTTPS only - url includes name (this is to avoid redirects) diff --git a/ci/invidiousCI.ts b/ci/invidiousCI.ts index d27a3a4e..d97250d0 100644 --- a/ci/invidiousCI.ts +++ b/ci/invidiousCI.ts @@ -1,31 +1,34 @@ -import { InvidiousInstance, instanceMap } from "./invidiousType" +import { InvidiousInstance, monitor } from "./invidiousType" import * as data from "../ci/invidious_instances.json"; // only https servers -const mapped: instanceMap = data - .filter((i: InvidiousInstance) => i[1]?.type === "https") - .map((instance: InvidiousInstance) => { +const mapped = (data as InvidiousInstance[]) + .filter((i) => + i[1]?.type === "https" + && i[1]?.monitor?.enabled + ) + .map((instance) => { + const monitor = instance[1].monitor as monitor; return { name: instance[0], url: instance[1].uri, - dailyRatios: instance[1].monitor.dailyRatios, - thirtyDayUptime: instance[1]?.monitor["30dRatio"].ratio, + uptime: monitor.uptime || 0, + down: monitor.down ?? false, + created_at: monitor.created_at, } }); // reliability and sanity checks const reliableCheck = mapped .filter(instance => { - // 30d uptime >= 90% - const thirtyDayUptime = Number(instance.thirtyDayUptime) >= 90; - // available for at least 80/90 days - const dailyRatioCheck = instance.dailyRatios.filter(status => status.label !== "black"); - return thirtyDayUptime && dailyRatioCheck.length >= 80; + const uptime = instance.uptime > 80 && !instance.down; + const nameIncluded = instance.url.includes(instance.name); + const ninetyDays = 90 * 24 * 60 * 60 * 1000; + const ninetyDaysAgo = new Date(Date.now() - ninetyDays); + const createdAt = new Date(instance.created_at).getTime() < ninetyDaysAgo.getTime(); + return uptime && nameIncluded && createdAt; }) - // url includes name - .filter(instance => instance.url.includes(instance.name)); -export function getInvidiousList(): string[] { - return reliableCheck.map(instance => instance.name).sort() -}
\ No newline at end of file +export const getInvidiousList = (): string[] => + reliableCheck.map(instance => instance.name).sort()
\ No newline at end of file diff --git a/ci/invidiousType.ts b/ci/invidiousType.ts index e5f682bb..46abdb04 100644 --- a/ci/invidiousType.ts +++ b/ci/invidiousType.ts @@ -1,54 +1,72 @@ -type ratio = { - ratio: string; - label: string; -} - -export type instanceMap = { - name: string; - url: string; - dailyRatios: {ratio: string; label: string }[]; - thirtyDayUptime: string; -}[] - export type InvidiousInstance = [ string, { flag: string; region: string; - stats: null | { - version: string; - software: { - name: string; - version: string; - branch: string; - }; - openRegistrations: boolean; - usage: { - users: { - total: number; - activeHalfyear: number; - activeMonth: number; - }; - }; - metadata: { - updatedAt: number; - lastChannelRefreshedAt: number; - }; - }; - cors: boolean | null; - api: boolean | null; + stats: null | ivStats; + cors: null | boolean; + api: null | boolean; type: "https" | "http" | "onion" | "i2p"; uri: string; - monitor: null | { - monitorId: number; - createdAt: number; - statusClass: string; - name: string; - url: string | null; - type: "HTTP(s)"; - dailyRatios: ratio[]; - "90dRatio": ratio; - "30dRatio": ratio; - }; + monitor: null | monitor; } -]
\ No newline at end of file +] + +export type monitor = { + token: string; + url: string; + alias: string; + last_status: number; + uptime: number; + down: boolean; + down_since: null | string; + up_since: null | string; + error: null | string; + period: number; + apdex_t: number; + string_match: string; + enabled: boolean; + published: boolean; + disabled_locations: string[]; + recipients: string[]; + last_check_at: string; + next_check_at: string; + created_at: string; + mute_until: null | string; + favicon_url: string; + custom_headers: Record<string, string>; + http_verb: string; + http_body: string; + ssl: { + tested_at: string; + expires_at: string; + valid: boolean; + error: null | string; + }; +} + +export type ivStats = { + version: string; + software: { + name: "invidious" | string; + version: string; + branch: "master" | string; + }; + openRegistrations: boolean; + usage: { + users: { + total: number; + activeHalfyear: number; + activeMonth: number; + }; + }; + metadata: { + updatedAt: number; + lastChannelRefreshedAt: number; + }; + playback: { + totalRequests: number; + successfulRequests: number; + ratio: number; + }; +}
\ No newline at end of file diff --git a/ci/invidiouslist.json b/ci/invidiouslist.json index d012c624..645422cc 100644 --- a/ci/invidiouslist.json +++ b/ci/invidiouslist.json @@ -1 +1 @@ -["www.youtubekids.com","anontube.lvkaszus.pl","inv.bp.projectsegfau.lt","inv.makerlab.tech","inv.pistasjis.net","inv.tux.pizza","inv.zzls.xyz","invidious.asir.dev","invidious.flokinet.to","invidious.io.lol","invidious.lunar.icu","invidious.no-logs.com","invidious.privacydev.net","invidious.private.coffee","invidious.protokolla.fi","invidious.slipfox.xyz","invidious.tiekoetter.com","iv.ggtyler.dev","iv.melmac.space","iv.nboeck.de","onion.tube","vid.priv.au","vid.puffyan.us","yewtu.be","yt.artemislena.eu","yt.drgnz.club","yt.oelrichsgarcia.de"]
\ No newline at end of file +["www.youtubekids.com","inv.nadeko.net","inv.tux.pizza","invidious.adminforge.de","invidious.jing.rocks","invidious.nerdvpn.de","invidious.perennialte.ch","invidious.privacyredirect.com","invidious.reallyaweso.me","invidious.yourdevice.ch","iv.ggtyler.dev","iv.nboeck.de","yewtu.be"]
\ No newline at end of file diff --git a/manifest/chrome-manifest-extra.json b/manifest/chrome-manifest-extra.json index 9cb5082d..4fa0fed7 100644 --- a/manifest/chrome-manifest-extra.json +++ b/manifest/chrome-manifest-extra.json @@ -1,12 +1,156 @@ { - "optional_permissions": [ - "declarativeContent", - "webNavigation" + "host_permissions": [ + "https://*.youtube.com/*", + "https://sponsor.ajay.app/*" ], + "optional_host_permissions": [ + "*://*/*" + ], + "web_accessible_resources": [{ + "resources": [ + "icons/LogoSponsorBlocker256px.png", + "icons/IconSponsorBlocker256px.png", + "icons/PlayerStartIconSponsorBlocker.svg", + "icons/PlayerStopIconSponsorBlocker.svg", + "icons/PlayerUploadIconSponsorBlocker.svg", + "icons/PlayerUploadFailedIconSponsorBlocker.svg", + "icons/PlayerCancelSegmentIconSponsorBlocker.svg", + "icons/clipboard.svg", + "icons/settings.svg", + "icons/pencil.svg", + "icons/check.svg", + "icons/check-smaller.svg", + "icons/upvote.png", + "icons/downvote.png", + "icons/thumbs_down.svg", + "icons/thumbs_down_locked.svg", + "icons/thumbs_up.svg", + "icons/help.svg", + "icons/report.png", + "icons/close.png", + "icons/skipIcon.svg", + "icons/refresh.svg", + "icons/beep.ogg", + "icons/pause.svg", + "icons/stop.svg", + "icons/skip.svg", + "icons/heart.svg", + "icons/visible.svg", + "icons/not_visible.svg", + "icons/sort.svg", + "icons/money.svg", + "icons/segway.png", + "icons/close-smaller.svg", + "icons/right-arrow.svg", + "icons/campaign.svg", + "icons/star.svg", + "icons/lightbulb.svg", + "icons/bolt.svg", + "icons/stopwatch.svg", + "icons/music-note.svg", + "icons/import.svg", + "icons/export.svg", + "icons/PlayerInfoIconSponsorBlocker.svg", + "icons/PlayerDeleteIconSponsorBlocker.svg", + "icons/dearrow.svg", + "popup.html", + "popup.css", + "content.css", + "shared.css", + "js/document.js", + "libs/Source+Sans+Pro.css", + "libs/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwlxdu.woff2", + "libs/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwmRduz8A.woff2", + "libs/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwmBduz8A.woff2", + "libs/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwlBduz8A.woff2" + ], + "matches": ["<all_urls>"] + }], + "content_scripts": [ + { + "world": "MAIN", + "js": [ + "./js/document.js" + ], + "matches": [ + "https://*.youtube.com/*", + "https://www.youtube-nocookie.com/embed/*" + ], + "exclude_matches": [ + "https://accounts.youtube.com/RotateCookiesPage*" + ], + "all_frames": true, + "run_at": "document_start" + }, + { + "world": "ISOLATED", + "js": [ + "./js/content.js" + ], + "css": [ + "content.css", + "shared.css" + ], + "matches": [ + "https://*.youtube.com/*", + "https://www.youtube-nocookie.com/embed/*" + ], + "exclude_matches": [ + "https://accounts.youtube.com/RotateCookiesPage*" + ], + "all_frames": true, + "run_at": "document_start" + } + ], + "action": { + "default_title": "SponsorBlock", + "default_popup": "popup.html", + "default_icon": { + "16": "icons/IconSponsorBlocker16px.png", + "32": "icons/IconSponsorBlocker32px.png", + "64": "icons/IconSponsorBlocker64px.png", + "128": "icons/IconSponsorBlocker128px.png" + }, + "theme_icons": [ + { + "light": "icons/IconSponsorBlocker16px.png", + "dark": "icons/IconSponsorBlocker16px.png", + "size": 16 + }, + { + "light": "icons/IconSponsorBlocker32px.png", + "dark": "icons/IconSponsorBlocker32px.png", + "size": 32 + }, + { + "light": "icons/IconSponsorBlocker64px.png", + "dark": "icons/IconSponsorBlocker64px.png", + "size": 64 + }, + { + "light": "icons/IconSponsorBlocker128px.png", + "dark": "icons/IconSponsorBlocker128px.png", + "size": 128 + }, + { + "light": "icons/IconSponsorBlocker256px.png", + "dark": "icons/IconSponsorBlocker256px.png", + "size": 256 + }, + { + "light": "icons/IconSponsorBlocker512px.png", + "dark": "icons/IconSponsorBlocker512px.png", + "size": 512 + }, + { + "light": "icons/IconSponsorBlocker1024px.png", + "dark": "icons/IconSponsorBlocker1024px.png", + "size": 1024 + } + ] + }, "background": { - "persistent": false + "service_worker": "./js/background.js" }, - "permissions": [ - "https://*.youtube.com/*" - ] + "manifest_version": 3 } diff --git a/manifest/firefox-manifest-extra.json b/manifest/firefox-manifest-extra.json index 2a5c45c3..d7788721 100644 --- a/manifest/firefox-manifest-extra.json +++ b/manifest/firefox-manifest-extra.json @@ -1,18 +1,16 @@ { "browser_specific_settings": { "gecko": { - "id": "[email protected]" + "id": "[email protected]", + "strict_min_version": "56.0" }, "gecko_android": { - "strict_min_version": "79.0" + "strict_min_version": "113.0" } }, "background": { "persistent": false }, - "permissions": [ - "scripting" - ], "browser_action": { "default_area": "navbar" } diff --git a/manifest/manifest-v2-extra.json b/manifest/manifest-v2-extra.json new file mode 100644 index 00000000..1c33efe7 --- /dev/null +++ b/manifest/manifest-v2-extra.json @@ -0,0 +1,136 @@ +{ + "web_accessible_resources": [ + "icons/LogoSponsorBlocker256px.png", + "icons/IconSponsorBlocker256px.png", + "icons/PlayerStartIconSponsorBlocker.svg", + "icons/PlayerStopIconSponsorBlocker.svg", + "icons/PlayerUploadIconSponsorBlocker.svg", + "icons/PlayerUploadFailedIconSponsorBlocker.svg", + "icons/PlayerCancelSegmentIconSponsorBlocker.svg", + "icons/clipboard.svg", + "icons/settings.svg", + "icons/pencil.svg", + "icons/check.svg", + "icons/check-smaller.svg", + "icons/upvote.png", + "icons/downvote.png", + "icons/thumbs_down.svg", + "icons/thumbs_down_locked.svg", + "icons/thumbs_up.svg", + "icons/help.svg", + "icons/report.png", + "icons/close.png", + "icons/skipIcon.svg", + "icons/refresh.svg", + "icons/beep.ogg", + "icons/pause.svg", + "icons/stop.svg", + "icons/skip.svg", + "icons/heart.svg", + "icons/visible.svg", + "icons/not_visible.svg", + "icons/sort.svg", + "icons/money.svg", + "icons/segway.png", + "icons/close-smaller.svg", + "icons/right-arrow.svg", + "icons/campaign.svg", + "icons/star.svg", + "icons/lightbulb.svg", + "icons/bolt.svg", + "icons/stopwatch.svg", + "icons/music-note.svg", + "icons/import.svg", + "icons/export.svg", + "icons/PlayerInfoIconSponsorBlocker.svg", + "icons/PlayerDeleteIconSponsorBlocker.svg", + "icons/dearrow.svg", + "popup.html", + "popup.css", + "content.css", + "shared.css", + "js/document.js", + "libs/Source+Sans+Pro.css", + "libs/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwlxdu.woff2", + "libs/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwmRduz8A.woff2", + "libs/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwmBduz8A.woff2", + "libs/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwlBduz8A.woff2" + ], + "permissions": [ + "https://sponsor.ajay.app/*" + ], + "optional_permissions": [ + "*://*/*" + ], + "browser_action": { + "default_title": "SponsorBlock", + "default_popup": "popup.html", + "default_icon": { + "16": "icons/IconSponsorBlocker16px.png", + "32": "icons/IconSponsorBlocker32px.png", + "64": "icons/IconSponsorBlocker64px.png", + "128": "icons/IconSponsorBlocker128px.png" + }, + "theme_icons": [ + { + "light": "icons/IconSponsorBlocker16px.png", + "dark": "icons/IconSponsorBlocker16px.png", + "size": 16 + }, + { + "light": "icons/IconSponsorBlocker32px.png", + "dark": "icons/IconSponsorBlocker32px.png", + "size": 32 + }, + { + "light": "icons/IconSponsorBlocker64px.png", + "dark": "icons/IconSponsorBlocker64px.png", + "size": 64 + }, + { + "light": "icons/IconSponsorBlocker128px.png", + "dark": "icons/IconSponsorBlocker128px.png", + "size": 128 + }, + { + "light": "icons/IconSponsorBlocker256px.png", + "dark": "icons/IconSponsorBlocker256px.png", + "size": 256 + }, + { + "light": "icons/IconSponsorBlocker512px.png", + "dark": "icons/IconSponsorBlocker512px.png", + "size": 512 + }, + { + "light": "icons/IconSponsorBlocker1024px.png", + "dark": "icons/IconSponsorBlocker1024px.png", + "size": 1024 + } + ] + }, + "background": { + "scripts":[ + "./js/background.js" + ] + }, + "content_scripts": [{ + "run_at": "document_start", + "matches": [ + "https://*.youtube.com/*", + "https://www.youtube-nocookie.com/embed/*" + ], + "exclude_matches": [ + "https://accounts.youtube.com/RotateCookiesPage*" + ], + "all_frames": true, + "js": [ + "./js/content.js" + ], + "css": [ + "content.css", + "shared.css" + ] + }], + "manifest_version": 2 +} diff --git a/manifest/manifest.json b/manifest/manifest.json index ece790f8..ec696f4e 100644 --- a/manifest/manifest.json +++ b/manifest/manifest.json @@ -1,141 +1,10 @@ { "name": "__MSG_fullName__", "short_name": "SponsorBlock", - "version": "5.4.24", + "version": "5.7", "default_locale": "en", "description": "__MSG_Description__", "homepage_url": "https://sponsor.ajay.app", - "content_scripts": [{ - "run_at": "document_start", - "matches": [ - "https://*.youtube.com/*", - "https://www.youtube-nocookie.com/embed/*" - ], - "all_frames": true, - "js": [ - "./js/content.js" - ], - "css": [ - "content.css", - "shared.css" - ] - }], - "web_accessible_resources": [ - "icons/LogoSponsorBlocker256px.png", - "icons/IconSponsorBlocker256px.png", - "icons/PlayerStartIconSponsorBlocker.svg", - "icons/PlayerStopIconSponsorBlocker.svg", - "icons/PlayerUploadIconSponsorBlocker.svg", - "icons/PlayerUploadFailedIconSponsorBlocker.svg", - "icons/PlayerCancelSegmentIconSponsorBlocker.svg", - "icons/clipboard.svg", - "icons/settings.svg", - "icons/pencil.svg", - "icons/check.svg", - "icons/check-smaller.svg", - "icons/upvote.png", - "icons/downvote.png", - "icons/thumbs_down.svg", - "icons/thumbs_down_locked.svg", - "icons/thumbs_up.svg", - "icons/help.svg", - "icons/report.png", - "icons/close.png", - "icons/skipIcon.svg", - "icons/refresh.svg", - "icons/beep.ogg", - "icons/pause.svg", - "icons/stop.svg", - "icons/skip.svg", - "icons/heart.svg", - "icons/visible.svg", - "icons/not_visible.svg", - "icons/sort.svg", - "icons/money.svg", - "icons/segway.png", - "icons/close-smaller.svg", - "icons/right-arrow.svg", - "icons/campaign.svg", - "icons/star.svg", - "icons/lightbulb.svg", - "icons/bolt.svg", - "icons/stopwatch.svg", - "icons/music-note.svg", - "icons/import.svg", - "icons/export.svg", - "icons/PlayerInfoIconSponsorBlocker.svg", - "icons/PlayerDeleteIconSponsorBlocker.svg", - "icons/dearrow.svg", - "popup.html", - "popup.css", - "content.css", - "shared.css", - "js/document.js", - "libs/Source+Sans+Pro.css", - "libs/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwlxdu.woff2", - "libs/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwmRduz8A.woff2", - "libs/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwmBduz8A.woff2", - "libs/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwlBduz8A.woff2" - ], - "permissions": [ - "storage", - "https://sponsor.ajay.app/*" - ], - "optional_permissions": [ - "*://*/*" - ], - "browser_action": { - "default_title": "SponsorBlock", - "default_popup": "popup.html", - "default_icon": { - "16": "icons/IconSponsorBlocker16px.png", - "32": "icons/IconSponsorBlocker32px.png", - "64": "icons/IconSponsorBlocker64px.png", - "128": "icons/IconSponsorBlocker128px.png" - }, - "theme_icons": [ - { - "light": "icons/IconSponsorBlocker16px.png", - "dark": "icons/IconSponsorBlocker16px.png", - "size": 16 - }, - { - "light": "icons/IconSponsorBlocker32px.png", - "dark": "icons/IconSponsorBlocker32px.png", - "size": 32 - }, - { - "light": "icons/IconSponsorBlocker64px.png", - "dark": "icons/IconSponsorBlocker64px.png", - "size": 64 - }, - { - "light": "icons/IconSponsorBlocker128px.png", - "dark": "icons/IconSponsorBlocker128px.png", - "size": 128 - }, - { - "light": "icons/IconSponsorBlocker256px.png", - "dark": "icons/IconSponsorBlocker256px.png", - "size": 256 - }, - { - "light": "icons/IconSponsorBlocker512px.png", - "dark": "icons/IconSponsorBlocker512px.png", - "size": 512 - }, - { - "light": "icons/IconSponsorBlocker1024px.png", - "dark": "icons/IconSponsorBlocker1024px.png", - "size": 1024 - } - ] - }, - "background": { - "scripts":[ - "./js/background.js" - ] - }, "icons": { "16": "icons/IconSponsorBlocker16px.png", "32": "icons/IconSponsorBlocker32px.png", @@ -145,9 +14,12 @@ "512": "icons/IconSponsorBlocker512px.png", "1024": "icons/IconSponsorBlocker1024px.png" }, + "permissions": [ + "storage", + "scripting" + ], "options_ui": { "page": "options/options.html", "open_in_tab": true - }, - "manifest_version": 2 + } } diff --git a/manifest/safari-manifest-extra.json b/manifest/safari-manifest-extra.json index 1706b2c3..902381c9 100644 --- a/manifest/safari-manifest-extra.json +++ b/manifest/safari-manifest-extra.json @@ -2,9 +2,6 @@ "background": { "persistent": false }, - "permissions": [ - "scripting" - ], "optional_permissions": [ "webNavigation" ] diff --git a/maze-utils b/maze-utils -Subproject 92d368b051c1af360ab9db45215df274b71de8f +Subproject e9523b0c5d12834e329783a771628ab1bf92db1 diff --git a/package-lock.json b/package-lock.json index 4e986143..aa572ca8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,7 +25,7 @@ "url": "https://paypal.me/ajayyy" } ], - "license": "LGPL-3.0-or-later", + "license": "GPL-3.0", "dependencies": { "content-scripts-register-polyfill": "^4.0.2", "react": "^18.2.0", @@ -56,8 +56,8 @@ "ts-loader": "^9.4.2", "ts-node": "^10.9.1", "typescript": "4.9", - "web-ext": "^7.6.2", - "webpack": "^5.75.0", + "web-ext": "^8.2.0", + "webpack": "^5.94.0", "webpack-cli": "^4.10.0", "webpack-merge": "^5.8.0" }, @@ -65,6 +65,15 @@ "node": ">=16" } }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/@ampproject/remapping": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", @@ -79,12 +88,13 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", - "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", "dev": true, "dependencies": { - "@babel/highlight": "^7.18.6" + "@babel/highlight": "^7.22.13", + "chalk": "^2.4.2" }, "engines": { "node": ">=6.9.0" @@ -130,13 +140,14 @@ } }, "node_modules/@babel/generator": { - "version": "7.19.3", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.19.3.tgz", - "integrity": "sha512-fqVZnmp1ncvZU757UzDheKZpfPgatqY59XtW2/j/18H7u76akb8xqvjw82f+i2UKd/ksYsSick/BCLQUUtJ/qQ==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz", + "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==", "dev": true, "dependencies": { - "@babel/types": "^7.19.3", + "@babel/types": "^7.23.0", "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" }, "engines": { @@ -176,34 +187,34 @@ } }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", - "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-function-name": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", - "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "dev": true, "dependencies": { - "@babel/template": "^7.18.10", - "@babel/types": "^7.19.0" + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-hoist-variables": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", - "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", "dev": true, "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -262,30 +273,30 @@ } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", - "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", "dev": true, "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", - "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", + "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "dev": true, "engines": { "node": ">=6.9.0" @@ -315,13 +326,13 @@ } }, "node_modules/@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", + "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", "js-tokens": "^4.0.0" }, "engines": { @@ -329,9 +340,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.20.13", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.13.tgz", - "integrity": "sha512-gFDLKMfpiXCsjt4za2JA9oTMn70CeseCehb11kRZgvd7+F67Hih3OHOK24cRrWECJ/ljfPGac6ygXAs/C8kIvw==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", + "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -518,45 +529,45 @@ } }, "node_modules/@babel/runtime": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.0.tgz", - "integrity": "sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.7.tgz", + "integrity": "sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==", "dev": true, "dependencies": { - "regenerator-runtime": "^0.13.11" + "regenerator-runtime": "^0.14.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/template": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", - "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.18.10", - "@babel/types": "^7.18.10" + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.19.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.19.3.tgz", - "integrity": "sha512-qh5yf6149zhq2sgIXmwjnsvmnNQC2iw70UFjp4olxucKrWd/dvlUsBI88VSLUsnMNF7/vnOiA+nk1+yLoCqROQ==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.19.3", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.19.3", - "@babel/types": "^7.19.3", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", + "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.0", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.0", + "@babel/types": "^7.23.0", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -565,13 +576,13 @@ } }, "node_modules/@babel/types": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz", - "integrity": "sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", + "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==", "dev": true, "dependencies": { - "@babel/helper-string-parser": "^7.19.4", - "@babel/helper-validator-identifier": "^7.19.1", + "@babel/helper-string-parser": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" }, "engines": { @@ -607,13 +618,13 @@ } }, "node_modules/@devicefarmer/adbkit": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/@devicefarmer/adbkit/-/adbkit-3.2.3.tgz", - "integrity": "sha512-wK9rVrabs4QU0oK8Jnwi+HRBEm+s1x/o63kgthUe0y7K1bfcYmgLuQf41/adsj/5enddlSxzkJavl2EwOu+r1g==", + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/@devicefarmer/adbkit/-/adbkit-3.2.6.tgz", + "integrity": "sha512-8lO1hSeTgtxcOHhp4tTWq/JaOysp5KNbbyFoxNEBnwkCDZu/Bji3ZfOaG++Riv9jN6c9bgdLBOZqJTC5VJPRKQ==", "dev": true, "dependencies": { "@devicefarmer/adbkit-logcat": "^2.1.2", - "@devicefarmer/adbkit-monkey": "~1.2.0", + "@devicefarmer/adbkit-monkey": "~1.2.1", "bluebird": "~3.7", "commander": "^9.1.0", "debug": "~4.3.1", @@ -628,9 +639,9 @@ } }, "node_modules/@devicefarmer/adbkit-logcat": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@devicefarmer/adbkit-logcat/-/adbkit-logcat-2.1.2.tgz", - "integrity": "sha512-G4grpEa5s9s9wCRs8YB9LjFSnz0Os3g3RYIwZSxH3JFfV3aejL5xlu4hHMH4JY+d4oCCwImcEZJcFPY9BEP21w==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@devicefarmer/adbkit-logcat/-/adbkit-logcat-2.1.3.tgz", + "integrity": "sha512-yeaGFjNBc/6+svbDeul1tNHtNChw6h8pSHAt5D+JsedUrMTN7tla7B15WLDyekxsuS2XlZHRxpuC6m92wiwCNw==", "dev": true, "engines": { "node": ">= 4" @@ -646,9 +657,9 @@ } }, "node_modules/@devicefarmer/adbkit/node_modules/commander": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-9.3.0.tgz", - "integrity": "sha512-hv95iU5uXPbK83mjrJKuZyFM/LBAoCV/XhVGkS5Je6tl7sxr6A0ITMw5WoRV46/UaJ46Nllm3Xt7IaJhXTIkzw==", + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", "dev": true, "engines": { "node": "^12.20.0 || >=14" @@ -679,23 +690,23 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.0.tgz", - "integrity": "sha512-vITaYzIcNmjn5tF5uxcZ/ft7/RXGrMUIS9HalWckEOF6ESiwXKoMzAQf2UW0aVd6rnOeExTJVd5hmWXucBKGXQ==", + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", "dev": true, "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, "node_modules/@eslint/eslintrc": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.2.tgz", - "integrity": "sha512-3W4f5tDUra+pA+FzgugqL2pRimUTDJWKr7BINqOpkZrC0uYI0NIc0/JFgBROCU07HR6GieA5m3/rsPIhDmCXTQ==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.5.1", + "espree": "^9.6.0", "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", @@ -733,39 +744,10 @@ } } }, - "node_modules/@eslint/eslintrc/node_modules/eslint-visitor-keys": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz", - "integrity": "sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/eslintrc/node_modules/espree": { - "version": "9.5.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.1.tgz", - "integrity": "sha512-5yxtHSZXRSW5pvv3hAlXM5+/Oswi1AUFqBmbibKb5s6bp3rGIDkyXU6xCoyuuLhijr4SFwPrXRoZjz0AZDN9tg==", - "dev": true, - "dependencies": { - "acorn": "^8.8.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.20.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", - "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -802,9 +784,9 @@ } }, "node_modules/@eslint/js": { - "version": "8.36.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.36.0.tgz", - "integrity": "sha512-lxJ9R5ygVm8ZWgYdUweoq5ownDlJ4upvoWmO4eLxBYHdMo+vZ/Rx0EN6MbKWDJOSUGrqJy2Gt+Dyv/VKml0fjg==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -821,13 +803,13 @@ } }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.8", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", - "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", "dev": true, "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", "minimatch": "^3.0.5" }, "engines": { @@ -848,11 +830,107 @@ } }, "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", + "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", "dev": true }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -1569,65 +1647,67 @@ } }, "node_modules/@jridgewell/resolve-uri": { - "version": "3.0.4", - "integrity": "sha512-cz8HFjOFfUBtvN+NXYSFMHYRdxZMaEl0XypVrhzxBgadKIXhIkRd8aMeHhmF56Sl7SuS8OnUpQ73/k9LE4VnLg==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", "dev": true, "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/set-array": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.1.tgz", - "integrity": "sha512-Ct5MqZkLGEXTVmQYbGtx9SVqD2fqwvdubdps5D3djjAkgkKwT918VNOz65pEHFaYTeWcukmJmH5SwsA9Tn2ObQ==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "dev": true, "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/source-map": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz", - "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==", + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", "dev": true, "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" } }, "node_modules/@jridgewell/source-map/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dev": true, "dependencies": { - "@jridgewell/set-array": "^1.0.1", + "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.10", - "integrity": "sha512-Ht8wIW5v165atIX1p+JvKR5ONzUyF4Ac8DZIQ5kZs9zrb6M8SJNXpx1zn04rn65VjBMygRoMXcyYwNK0fT7bEg==", + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", "dev": true }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.15", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz", - "integrity": "sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==", + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, "node_modules/@mdn/browser-compat-data": { - "version": "5.2.42", - "resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-5.2.42.tgz", - "integrity": "sha512-CD/2ai1W45cDN/zN2AcYduDavU+nq9aStyQizi4MHxnwkRvS/H24WIjgc1qD8CISoqXa8AAIe+A+zpWxwV7a2Q==", + "version": "5.5.34", + "resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-5.5.34.tgz", + "integrity": "sha512-e8k7+8r3jiJuP7FMH6AL1OnmfQqLyABhTM+NmRDvFeAbMgtFcNQLHpmT7uza5cBnxI01+CAU3aSsIgcKGRdEBQ==", "dev": true }, "node_modules/@nodelib/fs.scandir": { @@ -1665,6 +1745,16 @@ "node": ">= 8" } }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, "node_modules/@pnpm/network.ca-file": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@pnpm/network.ca-file/-/network.ca-file-1.0.1.tgz", @@ -1739,9 +1829,9 @@ } }, "node_modules/@testim/chrome-version": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@testim/chrome-version/-/chrome-version-1.1.3.tgz", - "integrity": "sha512-g697J3WxV/Zytemz8aTuKjTGYtta9+02kva3C1xc7KXB8GdbfE1akGJIsZLyY/FSh2QrnE+fiB7vmWU3XNcb6A==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@testim/chrome-version/-/chrome-version-1.1.4.tgz", + "integrity": "sha512-kIhULpw9TrGYnHp/8VfdcneIcxKnLixmADtukQRtJUmsVlMg0niMkwV0xZmi8hqa57xqilIHjWFA0GKvEjVU5g==", "dev": true }, "node_modules/@tootallnate/once": { @@ -1824,30 +1914,10 @@ "@types/har-format": "*" } }, - "node_modules/@types/eslint": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.1.tgz", - "integrity": "sha512-GE44+DNEyxxh2Kc6ro/VkIj+9ma0pO0bwv9+uHSyBrikYOHr8zYcdPvnBOp1aw8s+CjRvuSx7CyWqRrNFQ59mA==", - "dev": true, - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "node_modules/@types/eslint-scope": { - "version": "3.7.3", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.3.tgz", - "integrity": "sha512-PB3ldyrcnAicT35TWPs5IcwKD8S333HMaa2VVv4+wdvebJkjWuW/xESoB8IwRcog8HYVYamb1g/R31Qv5Bx03g==", - "dev": true, - "dependencies": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, "node_modules/@types/estree": { - "version": "0.0.51", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz", - "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", "dev": true }, "node_modules/@types/filesystem": { @@ -2050,9 +2120,9 @@ "dev": true }, "node_modules/@types/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==", + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", + "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", "dev": true, "dependencies": { "@types/node": "*" @@ -2359,149 +2429,155 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, "node_modules/@webassemblyjs/ast": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", - "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", + "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", "dev": true, "dependencies": { - "@webassemblyjs/helper-numbers": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1" + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" } }, "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz", - "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", "dev": true }, "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz", - "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", "dev": true }, "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz", - "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", + "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", "dev": true }, "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz", - "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", "dev": true, "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz", - "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", "dev": true }, "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz", - "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", + "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.12.1" } }, "node_modules/@webassemblyjs/ieee754": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz", - "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", "dev": true, "dependencies": { "@xtuc/ieee754": "^1.2.0" } }, "node_modules/@webassemblyjs/leb128": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz", - "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", "dev": true, "dependencies": { "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/utf8": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz", - "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", "dev": true }, "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz", - "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", + "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/helper-wasm-section": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-opt": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", - "@webassemblyjs/wast-printer": "1.11.1" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-opt": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1", + "@webassemblyjs/wast-printer": "1.12.1" } }, "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz", - "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", + "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" } }, "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz", - "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", + "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1" } }, "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz", - "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", + "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" } }, "node_modules/@webassemblyjs/wast-printer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz", - "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", + "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/ast": "1.12.1", "@xtuc/long": "4.2.2" } }, @@ -2572,9 +2648,9 @@ } }, "node_modules/acorn": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", - "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -2593,6 +2669,15 @@ "acorn-walk": "^8.0.2" } }, + "node_modules/acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", + "dev": true, + "peerDependencies": { + "acorn": "^8" + } + }, "node_modules/acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", @@ -2612,58 +2697,57 @@ } }, "node_modules/addons-linter": { - "version": "5.32.0", - "resolved": "https://registry.npmjs.org/addons-linter/-/addons-linter-5.32.0.tgz", - "integrity": "sha512-Lf6oOyw8X9z5BMd9xhQwSbPlN2PUlzDLnYLAVT5lkrgXEx0fO9hRk4JRxWZ8+rFGz+mCIA2TTClZF2f+MKgJQA==", + "version": "6.31.1", + "resolved": "https://registry.npmjs.org/addons-linter/-/addons-linter-6.31.1.tgz", + "integrity": "sha512-R9FCyVzqU/h5A2aB1t+jD8t4QKLuLxYqc1FjmjJ0nZrn1qNCna1jFOajt5R1T8pwt0H4WXgT+uwWSD2BdkBzqQ==", "dev": true, "dependencies": { "@fluent/syntax": "0.19.0", - "@mdn/browser-compat-data": "5.2.42", + "@mdn/browser-compat-data": "5.5.34", "addons-moz-compare": "1.3.0", - "addons-scanner-utils": "8.5.0", - "ajv": "8.12.0", + "addons-scanner-utils": "9.11.0", + "ajv": "8.16.0", "chalk": "4.1.2", "cheerio": "1.0.0-rc.12", "columnify": "1.6.0", "common-tags": "1.8.2", "deepmerge": "4.3.1", - "eslint": "8.36.0", + "eslint": "8.57.0", "eslint-plugin-no-unsanitized": "4.0.2", - "eslint-visitor-keys": "3.3.0", - "espree": "9.5.0", + "eslint-visitor-keys": "4.0.0", + "espree": "10.0.1", "esprima": "4.0.1", "fast-json-patch": "3.1.1", - "glob": "9.3.0", - "image-size": "1.0.2", + "glob": "10.4.2", + "image-size": "1.1.1", "is-mergeable-object": "1.1.1", "jed": "1.1.1", "json-merge-patch": "1.0.2", "os-locale": "5.0.0", - "pino": "8.11.0", - "postcss": "8.4.21", + "pino": "8.20.0", "relaxed-json": "1.0.3", - "semver": "7.3.8", + "semver": "7.6.2", "sha.js": "2.4.11", "source-map-support": "0.5.21", "tosource": "1.0.0", "upath": "2.0.1", - "yargs": "17.7.1", + "yargs": "17.7.2", "yauzl": "2.10.0" }, "bin": { "addons-linter": "bin/addons-linter" }, "engines": { - "node": ">=12.21.0" + "node": ">=16.0.0" } }, "node_modules/addons-linter/node_modules/addons-scanner-utils": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/addons-scanner-utils/-/addons-scanner-utils-8.5.0.tgz", - "integrity": "sha512-X35SYZRdSnxx7UZuAk+DizKihQp2Ze2c5GV+5nnRr/FFyx/fOgE3Zo8jdhzSne57PENE9w1ZVocBLJTN6UDB3g==", + "version": "9.11.0", + "resolved": "https://registry.npmjs.org/addons-scanner-utils/-/addons-scanner-utils-9.11.0.tgz", + "integrity": "sha512-X95V8ymnue9EHmOLz3zJTGHvHDFlWKiavlH+kJKOlv2sJDWFvD3TWeJMHJgxS9GKOqT/545mOXvX3vuuGGum+g==", "dev": true, "dependencies": { - "@types/yauzl": "2.10.0", + "@types/yauzl": "2.10.3", "common-tags": "1.8.2", "first-chunk-stream": "3.0.0", "strip-bom-stream": "4.0.0", @@ -2672,8 +2756,8 @@ }, "peerDependencies": { "body-parser": "1.20.2", - "express": "4.18.2", - "node-fetch": "2.6.7", + "express": "4.19.2", + "node-fetch": "2.6.11", "safe-compare": "1.1.4" }, "peerDependenciesMeta": { @@ -2692,15 +2776,15 @@ } }, "node_modules/addons-linter/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz", + "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==", "dev": true, "dependencies": { - "fast-deep-equal": "^3.1.1", + "fast-deep-equal": "^3.1.3", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "uri-js": "^4.4.1" }, "funding": { "type": "github", @@ -2765,19 +2849,53 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/addons-linter/node_modules/eslint-visitor-keys": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", + "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/addons-linter/node_modules/espree": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.0.1.tgz", + "integrity": "sha512-MWkrWZbJsL2UwnjxTX3gG8FneachS/Mwg7tdGXce011sJd5b0JG54vat5KHnfSBODZ3Wvzd2WnjxyzsRoVv+ww==", + "dev": true, + "dependencies": { + "acorn": "^8.11.3", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/addons-linter/node_modules/glob": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.0.tgz", - "integrity": "sha512-EAZejC7JvnQINayvB/7BJbpZpNOJ8Lrw2OZNEvQxe0vaLn1SuwMcfV7/MNaX8L/T0wmptBFI4YMtDvSBxYDc7w==", + "version": "10.4.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.2.tgz", + "integrity": "sha512-GwMlUF6PkPo3Gk21UxkCohOv0PLcIXVtKyLlpEI28R/cO/4eNOdmLk3CMW1wROV/WR/EsZOWAfBbBOqYvs88/w==", "dev": true, "dependencies": { - "fs.realpath": "^1.0.0", - "minimatch": "^7.4.1", - "minipass": "^4.2.4", - "path-scurry": "^1.6.1" + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": ">=16 || 14 >=14.18" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -2799,24 +2917,33 @@ "dev": true }, "node_modules/addons-linter/node_modules/minimatch": { - "version": "7.4.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.6.tgz", - "integrity": "sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" }, "engines": { - "node": ">=10" + "node": ">=16 || 14 >=14.17" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/addons-linter/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, "node_modules/addons-linter/node_modules/node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.11.tgz", + "integrity": "sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==", "dev": true, "optional": true, "peer": true, @@ -2836,13 +2963,10 @@ } }, "node_modules/addons-linter/node_modules/semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, "bin": { "semver": "bin/semver.js" }, @@ -2897,12 +3021,12 @@ "dev": true }, "node_modules/adm-zip": { - "version": "0.5.10", - "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.10.tgz", - "integrity": "sha512-x0HvcHqVJNTPk/Bw8JbLWlWoo6Wwnsug0fnYYro1HBrjxZ3G7/AZk7Ahv8JwDe1uIcz8eBqvu86FuF1POiG7vQ==", + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.16.tgz", + "integrity": "sha512-TGw5yVi4saajsSEgz25grObGHEUaDrniwvA2qwSC060KfqGPdglhvPMA2lPIoxs3PQIItj2iag35fONcQqgUaQ==", "dev": true, "engines": { - "node": ">=6.0" + "node": ">=12.0" } }, "node_modules/agent-base": { @@ -3126,24 +3250,6 @@ "get-intrinsic": "^1.1.3" } }, - "node_modules/asn1": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", - "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", - "dev": true, - "dependencies": { - "safer-buffer": "~2.1.0" - } - }, - "node_modules/assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", - "dev": true, - "engines": { - "node": ">=0.8" - } - }, "node_modules/asynckit": { "version": "0.4.0", "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", @@ -3179,28 +3285,13 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/aws4": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz", - "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==", - "dev": true - }, "node_modules/axios": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.2.6.tgz", - "integrity": "sha512-rC/7F08XxZwjMV4iuWv+JpD3E0Ksqg9nac4IIg6RwNuF0JTeWoCo/mBNG54+tNhhI11G3/VDRbdDQTs9hGp4pQ==", + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", + "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", "dev": true, "dependencies": { - "follow-redirects": "^1.15.0", + "follow-redirects": "^1.15.6", "form-data": "^4.0.0", "proxy-from-env": "^1.1.0" } @@ -3405,13 +3496,13 @@ } ] }, - "node_modules/bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "node_modules/big-integer": { + "version": "1.6.52", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz", + "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==", "dev": true, - "dependencies": { - "tweetnacl": "^0.14.3" + "engines": { + "node": ">=0.6" } }, "node_modules/bluebird": { @@ -3563,6 +3654,18 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/bplist-parser": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.2.0.tgz", + "integrity": "sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==", + "dev": true, + "dependencies": { + "big-integer": "^1.6.44" + }, + "engines": { + "node": ">= 5.10.0" + } + }, "node_modules/brace-expansion": { "version": "1.1.11", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", @@ -3573,21 +3676,21 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" } }, "node_modules/browserslist": { - "version": "4.21.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", - "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", + "version": "4.23.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz", + "integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==", "dev": true, "funding": [ { @@ -3597,13 +3700,17 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "dependencies": { - "caniuse-lite": "^1.0.30001400", - "electron-to-chromium": "^1.4.251", - "node-releases": "^2.0.6", - "update-browserslist-db": "^1.0.9" + "caniuse-lite": "^1.0.30001646", + "electron-to-chromium": "^1.5.4", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.0" }, "bin": { "browserslist": "cli.js" @@ -3664,17 +3771,26 @@ "node": "*" } }, - "node_modules/buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", - "dev": true - }, "node_modules/buffer-from": { "version": "1.1.1", "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", "dev": true }, + "node_modules/bundle-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-3.0.0.tgz", + "integrity": "sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw==", + "dev": true, + "dependencies": { + "run-applescript": "^5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/bunyan": { "version": "1.8.15", "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.8.15.tgz", @@ -3750,9 +3866,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001418", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001418.tgz", - "integrity": "sha512-oIs7+JL3K9JRQ3jPZjlH6qyYDp+nBTCais7hjh0s+fuBwufc7uZ7hPYMXrDOJhV360KGMTcczMRObk0/iMqZRg==", + "version": "1.0.30001657", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001657.tgz", + "integrity": "sha512-DPbJAlP8/BAXy3IgiWmZKItubb3TYGP0WscQQlVGIfT4s/YlFYVuJgyOsQNP7rJRChx/qdMeLJQJP0Sgg2yjNA==", "dev": true, "funding": [ { @@ -3762,15 +3878,13 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ] }, - "node_modules/caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", - "dev": true - }, "node_modules/chalk": { "version": "2.4.2", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", @@ -4089,9 +4203,9 @@ } }, "node_modules/compare-versions": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-5.0.1.tgz", - "integrity": "sha512-v8Au3l0b+Nwkp4G142JcgJFh1/TUhdxut7wzD1Nq1dyp5oa3tXaqb03EXOAB6jS4gMlalkjAUPZBMiAfKUixHQ==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-5.0.3.tgz", + "integrity": "sha512-4UZlZP8Z99MGEY+Ovg/uJxJuvoXuN4M6B3hKaiackiHrgzQFEe3diJi1mf1PNHbFujM7FvLrK2bpgIaImbtZ1A==", "dev": true }, "node_modules/concat-map": { @@ -4349,17 +4463,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/core-js": { - "version": "3.29.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.29.0.tgz", - "integrity": "sha512-VG23vuEisJNkGl6XQmFJd3rEG/so/CNatqeE+7uZAwTSwFeB/qaO0be8xZYUNWprJ/GIwL8aMt9cj1kvbpTZhg==", - "dev": true, - "hasInstallScript": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, "node_modules/core-util-is": { "version": "1.0.2", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", @@ -4484,18 +4587,6 @@ "integrity": "sha512-2u44ZG2OcNUO9HDp/Jl8C07x6pU/eTR3ncV91SiK3dhG9TWvRVsCoJw14Ckx5DgWkzGA3waZWO3d7pgqpUI/XA==", "dev": true }, - "node_modules/dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", - "dev": true, - "dependencies": { - "assert-plus": "^1.0.0" - }, - "engines": { - "node": ">=0.10" - } - }, "node_modules/data-uri-to-buffer": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", @@ -4619,15 +4710,6 @@ "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", "dev": true }, - "node_modules/deepcopy": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/deepcopy/-/deepcopy-2.1.0.tgz", - "integrity": "sha512-8cZeTb1ZKC3bdSCP6XOM1IsTczIO73fdqtwa2B0N15eAz7gmyhQo+mc5gnFuulsgN3vIQYmTgbmQVKalH1dKvQ==", - "dev": true, - "dependencies": { - "type-detect": "^4.0.8" - } - }, "node_modules/deepmerge": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", @@ -4637,6 +4719,150 @@ "node": ">=0.10.0" } }, + "node_modules/default-browser": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-4.0.0.tgz", + "integrity": "sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA==", + "dev": true, + "dependencies": { + "bundle-name": "^3.0.0", + "default-browser-id": "^3.0.0", + "execa": "^7.1.1", + "titleize": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-3.0.0.tgz", + "integrity": "sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA==", + "dev": true, + "dependencies": { + "bplist-parser": "^0.2.0", + "untildify": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser/node_modules/execa": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-7.2.0.tgz", + "integrity": "sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.1", + "human-signals": "^4.3.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^3.0.7", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": "^14.18.0 || ^16.14.0 || >=18.0.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/default-browser/node_modules/human-signals": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz", + "integrity": "sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==", + "dev": true, + "engines": { + "node": ">=14.18.0" + } + }, + "node_modules/default-browser/node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser/node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser/node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dev": true, + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser/node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser/node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/defaults": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", @@ -4659,12 +4885,15 @@ } }, "node_modules/define-lazy-prop": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", - "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", "dev": true, "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/define-properties": { @@ -4793,14 +5022,14 @@ } }, "node_modules/domutils": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz", - "integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", "dev": true, "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", - "domhandler": "^5.0.1" + "domhandler": "^5.0.3" }, "funding": { "url": "https://github.com/fb55/domutils?sponsor=1" @@ -4841,29 +5070,10 @@ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", "dev": true }, - "node_modules/ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", - "dev": true, - "dependencies": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "node_modules/ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.0.1" - } - }, "node_modules/electron-to-chromium": { - "version": "1.4.275", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.275.tgz", - "integrity": "sha512-aJeQQ+Hl9Jyyzv4chBqYJwmVRY46N5i2BEX5Cuyk/5gFCUZ5F3i7Hnba6snZftWla7Gglwc5pIgcd+E7cW+rPg==", + "version": "1.5.15", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.15.tgz", + "integrity": "sha512-Z4rIDoImwEJW+YYKnPul4DzqsWVqYetYVN3XqDmRpgV0mjz0hYTaeeh+8/9CL1bk3AHYmF4freW/NTiVoXA2gA==", "dev": true }, "node_modules/emittery": { @@ -4892,9 +5102,9 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz", - "integrity": "sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ==", + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", + "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", "dev": true, "dependencies": { "graceful-fs": "^4.2.4", @@ -4985,9 +5195,9 @@ } }, "node_modules/es-module-lexer": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz", - "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==", + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", + "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", "dev": true }, "node_modules/es-set-tostringtag": { @@ -5036,18 +5246,10 @@ "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", "dev": true }, - "node_modules/es6-promisify": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-7.0.0.tgz", - "integrity": "sha512-ginqzK3J90Rd4/Yz7qRrqUeIpe3TwSXTPPZtPne7tGBPeAaQiU8qt4fpKApnxHcq1AwtUdHVg5P77x/yrggG8Q==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/escalade": { - "version": "3.1.1", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true, "engines": { "node": ">=6" @@ -5105,27 +5307,28 @@ } }, "node_modules/eslint": { - "version": "8.36.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.36.0.tgz", - "integrity": "sha512-Y956lmS7vDqomxlaaQAHVmeb4tNMp2FWIvU/RnU5BD3IKMD/MJPr76xdyr68P8tV1iNMvN2mRK0yy3c+UjL+bw==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.4.0", - "@eslint/eslintrc": "^2.0.1", - "@eslint/js": "8.36.0", - "@humanwhocodes/config-array": "^0.11.8", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.10.0", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.1", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.5.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -5133,22 +5336,19 @@ "find-up": "^5.0.0", "glob-parent": "^6.0.2", "globals": "^13.19.0", - "grapheme-splitter": "^1.0.4", + "graphemer": "^1.4.0", "ignore": "^5.2.0", - "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "is-path-inside": "^3.0.3", - "js-sdsl": "^4.1.4", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.1", + "optionator": "^0.9.3", "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", "text-table": "^0.2.0" }, "bin": { @@ -5274,12 +5474,15 @@ } }, "node_modules/eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/eslint/node_modules/ansi-styles": { @@ -5362,9 +5565,9 @@ } }, "node_modules/eslint/node_modules/eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, "dependencies": { "esrecurse": "^4.3.0", @@ -5372,6 +5575,9 @@ }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/eslint/node_modules/estraverse": { @@ -5474,17 +5680,17 @@ } }, "node_modules/eslint/node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", "dev": true, "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "type-check": "^0.4.0" }, "engines": { "node": ">= 0.8.0" @@ -5565,14 +5771,14 @@ } }, "node_modules/espree": { - "version": "9.5.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.0.tgz", - "integrity": "sha512-JPbJGhKc47++oo4JkEoTe2wjy4fmMwvFpgJT9cQzmfXKp22Dr6Hf1tdCteLz1h0P3t+mGvWZ+4Uankvh8+c6zw==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, "dependencies": { - "acorn": "^8.8.0", + "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" + "eslint-visitor-keys": "^3.4.1" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -5714,12 +5920,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, "node_modules/extract-zip": { "version": "2.0.1", "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", @@ -5753,15 +5953,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", - "dev": true, - "engines": [ - "node >=0.6.0" - ] - }, "node_modules/fast-deep-equal": { "version": "3.1.3", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", @@ -5799,9 +5990,9 @@ "dev": true }, "node_modules/fast-redact": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.1.2.tgz", - "integrity": "sha512-+0em+Iya9fKGfEQGcd62Yv6onjBmmhV1uh86XVfOU8VwAe6kaFdQCWI9s0/Nnugx5Vd9tdbZ7e6gE2tR9dzXdw==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.5.0.tgz", + "integrity": "sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==", "dev": true, "engines": { "node": ">=6" @@ -5873,9 +6064,9 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "dependencies": { "to-regex-range": "^5.0.1" @@ -5898,9 +6089,9 @@ } }, "node_modules/firefox-profile": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/firefox-profile/-/firefox-profile-4.3.2.tgz", - "integrity": "sha512-/C+Eqa0YgIsQT2p66p7Ygzqe7NlE/GNTbhw2SBCm5V3OsWDPITNdTPEcH2Q2fe7eMpYYNPKdUcuVioZBZiR6kA==", + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/firefox-profile/-/firefox-profile-4.6.0.tgz", + "integrity": "sha512-I9rAm1w8U3CdhgO4EzTJsCvgcbvynZn9lOySkZf78wUdUIQH2w9QOKf3pAX+THt2XMSSR3kJSuM8P7bYux9j8g==", "dev": true, "dependencies": { "adm-zip": "~0.5.x", @@ -5979,9 +6170,9 @@ "dev": true }, "node_modules/follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", "dev": true, "funding": [ { @@ -6007,13 +6198,32 @@ "is-callable": "^1.1.3" } }, - "node_modules/forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", + "node_modules/foreground-child": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", + "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, "engines": { - "node": "*" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/fork-ts-checker-webpack-plugin": { @@ -6153,20 +6363,6 @@ "node": ">=8" } }, - "node_modules/form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dev": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 0.12" - } - }, "node_modules/form-data-encoder": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz", @@ -6260,9 +6456,9 @@ } }, "node_modules/fx-runner": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/fx-runner/-/fx-runner-1.3.0.tgz", - "integrity": "sha512-5b37H4GCyhF+Nf8xk9mylXoDq4wb7pbGAXxlCXp/631UTeeZomWSYcEGXumY4wk8g2QAqjPMGdWW+RbNt8PUcA==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/fx-runner/-/fx-runner-1.4.0.tgz", + "integrity": "sha512-rci1g6U0rdTg6bAaBboP7XdRu01dzTAaKXxFf+PUqGuCv6Xu7o8NZdY1D5MvKGIjb6EdS1g3VlXOgksir1uGkg==", "dev": true, "dependencies": { "commander": "2.9.0", @@ -6375,15 +6571,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", - "dev": true, - "dependencies": { - "assert-plus": "^1.0.0" - } - }, "node_modules/glob": { "version": "7.2.0", "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", @@ -6533,35 +6720,18 @@ "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", "dev": true }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, "node_modules/growly": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", "integrity": "sha512-+xGQY0YyAWCnqy7Cd++hc2JqMYzlm0dG30Jd0beaA64sROr8C4nt8Yc9V5Ro3avlSUDTN0ulqP/VBKi1/lLygw==", "dev": true }, - "node_modules/har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "deprecated": "this library is no longer supported", - "dev": true, - "dependencies": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/has": { "version": "1.0.3", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", @@ -6710,21 +6880,6 @@ "node": ">= 6" } }, - "node_modules/http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", - "dev": true, - "dependencies": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - }, - "engines": { - "node": ">=0.8", - "npm": ">=1.3.7" - } - }, "node_modules/http2-wrapper": { "version": "2.1.11", "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.1.11.tgz", @@ -6801,9 +6956,9 @@ } }, "node_modules/image-size": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.0.2.tgz", - "integrity": "sha512-xfOoWjceHntRb3qFCrh5ZFORYH8XCdYpASltMhZ/Q0KZiOwjdE/Yl2QCiWdwD+lygV5bMCvauzgu5PxBX/Yerg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.1.1.tgz", + "integrity": "sha512-541xKlUw6jr/6gGuk92F+mYM5zaFAc5ahphvkqvNe2bQ6gVBkd6bfrmVJ2t4KDAfikAYZyIqTnktX3i6/aQDrQ==", "dev": true, "dependencies": { "queue": "6.0.2" @@ -6812,7 +6967,7 @@ "image-size": "bin/image-size.js" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.x" } }, "node_modules/immediate": { @@ -7119,6 +7274,39 @@ "node": ">=0.10.0" } }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "dev": true, + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-inside-container/node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "dev": true, + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-installed-globally": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", @@ -7402,12 +7590,6 @@ "node": ">=0.10.0" } }, - "node_modules/isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", - "dev": true - }, "node_modules/istanbul-lib-coverage": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", @@ -7495,6 +7677,21 @@ "node": ">=8" } }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, "node_modules/jed": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/jed/-/jed-1.1.1.tgz", @@ -9191,6 +9388,7 @@ }, "node_modules/jest-worker/node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, "engines": { @@ -9199,6 +9397,7 @@ }, "node_modules/jest-worker/node_modules/supports-color": { "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "dependencies": { @@ -9212,20 +9411,14 @@ } }, "node_modules/jose": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/jose/-/jose-4.13.1.tgz", - "integrity": "sha512-MSJQC5vXco5Br38mzaQKiq9mwt7lwj2eXpgpRyQYNHYt2lq1PjkWa7DLXX0WVcQLE9HhMh3jPiufS7fhJf+CLQ==", + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/jose/-/jose-5.4.1.tgz", + "integrity": "sha512-U6QajmpV/nhL9SyfAewo000fkiRQ+Yd2H0lBxJJ9apjpOgkOcBQJWOrMo917lxLptdS/n/o/xPzMkXhF46K8hQ==", "dev": true, "funding": { "url": "https://github.com/sponsors/panva" } }, - "node_modules/js-sdsl": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.5.tgz", - "integrity": "sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q==", - "dev": true - }, "node_modules/js-tokens": { "version": "4.0.0", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" @@ -9243,12 +9436,6 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", - "dev": true - }, "node_modules/jsdom": { "version": "20.0.1", "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-20.0.1.tgz", @@ -9341,12 +9528,6 @@ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "dev": true }, - "node_modules/json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", - "dev": true - }, "node_modules/json-schema-traverse": { "version": "0.4.1", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", @@ -9357,12 +9538,6 @@ "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", "dev": true }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true - }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", @@ -9387,52 +9562,6 @@ "graceful-fs": "^4.1.6" } }, - "node_modules/jsonwebtoken": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.0.tgz", - "integrity": "sha512-tuGfYXxkQGDPnLJ7SibiQgVgeDgfbPq2k2ICcbgqW8WxWLBAxKQM/ZCu/IT8SOSwmaYl4dpTFCW5xZv7YbbWUw==", - "dev": true, - "dependencies": { - "jws": "^3.2.2", - "lodash": "^4.17.21", - "ms": "^2.1.1", - "semver": "^7.3.8" - }, - "engines": { - "node": ">=12", - "npm": ">=6" - } - }, - "node_modules/jsonwebtoken/node_modules/semver": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz", - "integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jsprim": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", - "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", - "dev": true, - "dependencies": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.4.0", - "verror": "1.10.0" - }, - "engines": { - "node": ">=0.6.0" - } - }, "node_modules/jsx-ast-utils": { "version": "3.1.0", "integrity": "sha512-d4/UOjg+mxAWxCiF0c5UTSwyqbchkbqCvK87aBovhnh8GtysTjWmgC63tY0cJx/HzGgm9qnA147jVBdpOiQ2RA==", @@ -9446,9 +9575,9 @@ } }, "node_modules/jszip": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.0.tgz", - "integrity": "sha512-LDfVtOLtOxb9RXkYOwPyNBTQDL4eUbqahtoY6x07GiDJHwSYvn8sHHIw8wINImV3MqbMNve2gSuM1DDqEKk09Q==", + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", + "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", "dev": true, "dependencies": { "lie": "~3.3.0", @@ -9457,27 +9586,6 @@ "setimmediate": "^1.0.5" } }, - "node_modules/jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", - "dev": true, - "dependencies": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", - "dev": true, - "dependencies": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - }, "node_modules/keyv": { "version": "4.5.2", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.2.tgz", @@ -9949,24 +10057,6 @@ "dev": true, "optional": true }, - "node_modules/nanoid": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", - "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, "node_modules/natural-compare": { "version": "1.4.0", "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", @@ -10020,9 +10110,9 @@ } }, "node_modules/node-fetch": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.1.tgz", - "integrity": "sha512-cRVc/kyto/7E5shrWca1Wsea4y6tL9iYJE5FBCius3JQfb/4P4I295PfhgbJQBLTx6lATE4z+wK0rPM4VS2uow==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", "dev": true, "dependencies": { "data-uri-to-buffer": "^4.0.0", @@ -10082,9 +10172,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", - "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==", + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", "dev": true }, "node_modules/normalize-path": { @@ -10138,15 +10228,6 @@ "integrity": "sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==", "dev": true }, - "node_modules/oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true, - "engines": { - "node": "*" - } - }, "node_modules/object-assign": { "version": "4.1.1", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", @@ -10252,10 +10333,13 @@ } }, "node_modules/on-exit-leak-free": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.0.tgz", - "integrity": "sha512-VuCaZZAjReZ3vUwgOB8LxAosIurDiAW0s13rI1YwmaP++jvcxP77AWoQvenZebpCA2m8WC1/EosPYPMjnRAp/w==", - "dev": true + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz", + "integrity": "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==", + "dev": true, + "engines": { + "node": ">=14.0.0" + } }, "node_modules/once": { "version": "1.4.0", @@ -10281,17 +10365,18 @@ } }, "node_modules/open": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", - "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/open/-/open-9.1.0.tgz", + "integrity": "sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg==", "dev": true, "dependencies": { - "define-lazy-prop": "^2.0.0", - "is-docker": "^2.1.1", + "default-browser": "^4.0.0", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", "is-wsl": "^2.2.0" }, "engines": { - "node": ">=12" + "node": ">=14.16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -10468,6 +10553,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/package-json-from-dist": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", + "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", + "dev": true + }, "node_modules/package-json/node_modules/semver": { "version": "7.3.7", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", @@ -10575,28 +10666,34 @@ "dev": true }, "node_modules/path-scurry": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.6.1.tgz", - "integrity": "sha512-OW+5s+7cw6253Q4E+8qQ/u1fVvcJQCJo/VFD8pje+dbJCF1n5ZRMV2AEHbGp+5Q7jxQIYJxkHopnj6nzdGeZLA==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", "dev": true, "dependencies": { - "lru-cache": "^7.14.1", - "minipass": "^4.0.2" + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "engines": { - "node": ">=14" + "node": ">=16 || 14 >=14.18" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/path-scurry/node_modules/lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + }, + "node_modules/path-scurry/node_modules/minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", "dev": true, "engines": { - "node": ">=12" + "node": ">=16 || 14 >=14.17" } }, "node_modules/path-type": { @@ -10612,15 +10709,10 @@ "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", "dev": true }, - "node_modules/performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", - "dev": true - }, "node_modules/picocolors": { - "version": "1.0.0", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", + "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==", "dev": true }, "node_modules/picomatch": { @@ -10636,21 +10728,21 @@ } }, "node_modules/pino": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/pino/-/pino-8.11.0.tgz", - "integrity": "sha512-Z2eKSvlrl2rH8p5eveNUnTdd4AjJk8tAsLkHYZQKGHP4WTh2Gi1cOSOs3eWPqaj+niS3gj4UkoreoaWgF3ZWYg==", + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/pino/-/pino-8.20.0.tgz", + "integrity": "sha512-uhIfMj5TVp+WynVASaVEJFTncTUe4dHBq6CWplu/vBgvGHhvBvQfxz+vcOrnnBQdORH3izaGEurLfNlq3YxdFQ==", "dev": true, "dependencies": { "atomic-sleep": "^1.0.0", "fast-redact": "^3.1.1", "on-exit-leak-free": "^2.1.0", - "pino-abstract-transport": "v1.0.0", + "pino-abstract-transport": "^1.1.0", "pino-std-serializers": "^6.0.0", - "process-warning": "^2.0.0", + "process-warning": "^3.0.0", "quick-format-unescaped": "^4.0.3", "real-require": "^0.2.0", "safe-stable-stringify": "^2.3.1", - "sonic-boom": "^3.1.0", + "sonic-boom": "^3.7.0", "thread-stream": "^2.0.0" }, "bin": { @@ -10658,9 +10750,9 @@ } }, "node_modules/pino-abstract-transport": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-1.0.0.tgz", - "integrity": "sha512-c7vo5OpW4wIS42hUVcT5REsL8ZljsUfBjqV/e2sFxmFEFZiq1XLUp5EYLtuDH6PEHq9W1egWqRbnLUP5FuZmOA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-1.2.0.tgz", + "integrity": "sha512-Guhh8EZfPCfH+PMXAb6rKOjGQEoy0xlAIn+irODG5kgfYV+BQ0rGYYWTIel3P5mmyXqkYkPmdIkywsn6QKUR1Q==", "dev": true, "dependencies": { "readable-stream": "^4.0.0", @@ -10668,24 +10760,25 @@ } }, "node_modules/pino-abstract-transport/node_modules/readable-stream": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.3.0.tgz", - "integrity": "sha512-MuEnA0lbSi7JS8XM+WNJlWZkHAAdm7gETHdFK//Q/mChGyj2akEFtdLZh32jSdkWGbRwCW9pn6g3LWDdDeZnBQ==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", + "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", "dev": true, "dependencies": { "abort-controller": "^3.0.0", "buffer": "^6.0.3", "events": "^3.3.0", - "process": "^0.11.10" + "process": "^0.11.10", + "string_decoder": "^1.3.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/pino-std-serializers": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-6.2.0.tgz", - "integrity": "sha512-IWgSzUL8X1w4BIWTwErRgtV8PyOGOOi60uqv0oKuS/fOA8Nco/OeI6lBuc4dyP8MMfdFwyHqTMcBIA7nDiqEqA==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-6.2.2.tgz", + "integrity": "sha512-cHjPPsE+vhj/tnhCy/wiMh3M3z3h/j15zHQX+S9GkTBgqJuTuJzYJ4gUyACLhDaJ7kk9ba9iRDmbH2tJU03OiA==", "dev": true }, "node_modules/pirates": { @@ -10697,30 +10790,6 @@ "node": ">= 6" } }, - "node_modules/postcss": { - "version": "8.4.21", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz", - "integrity": "sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - } - ], - "dependencies": { - "nanoid": "^3.3.4", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, "node_modules/prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", @@ -10777,9 +10846,9 @@ "dev": true }, "node_modules/process-warning": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-2.2.0.tgz", - "integrity": "sha512-/1WZ8+VQjR6avWOgHeEPd7SDQmFQ1B5mC1eRXsCm5TarlNmx/wCsa5GEaxGm05BORRtyG/Ex/3xq3TuRvq57qg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-3.0.0.tgz", + "integrity": "sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ==", "dev": true }, "node_modules/promise-toolbox": { @@ -10826,6 +10895,7 @@ }, "node_modules/proxy-from-env": { "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", "dev": true }, @@ -10883,15 +10953,6 @@ } ] }, - "node_modules/qs": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", - "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", - "dev": true, - "engines": { - "node": ">=0.6" - } - }, "node_modules/querystringify": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", @@ -11061,9 +11122,9 @@ } }, "node_modules/regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", "dev": true }, "node_modules/regexp.prototype.flags": { @@ -11137,61 +11198,6 @@ "node": ">= 0.10.0" } }, - "node_modules/request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", - "dev": true, - "dependencies": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/request/node_modules/tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dev": true, - "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/request/node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "dev": true, - "bin": { - "uuid": "bin/uuid" - } - }, "node_modules/require-directory": { "version": "2.1.1", "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", @@ -11346,6 +11352,21 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/run-applescript": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-5.0.0.tgz", + "integrity": "sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg==", + "dev": true, + "dependencies": { + "execa": "^5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -11426,9 +11447,9 @@ } }, "node_modules/safe-stable-stringify": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz", - "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", + "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==", "dev": true, "engines": { "node": ">=10" @@ -11441,9 +11462,9 @@ "dev": true }, "node_modules/sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", + "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==", "dev": true }, "node_modules/saxes": { @@ -11572,9 +11593,9 @@ } }, "node_modules/serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "dev": true, "dependencies": { "randombytes": "^2.1.0" @@ -11658,24 +11679,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/sign-addon": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/sign-addon/-/sign-addon-5.3.0.tgz", - "integrity": "sha512-7nHlCzhQgVMLBNiXVEgbG/raq48awOW0lYMN5uo1BaB3mp0+k8M8pvDwbfTlr3apcxZJsk9HQsAW1POwoJugpQ==", - "dev": true, - "dependencies": { - "common-tags": "1.8.2", - "core-js": "3.29.0", - "deepcopy": "2.1.0", - "es6-error": "4.1.1", - "es6-promisify": "7.0.0", - "jsonwebtoken": "9.0.0", - "mz": "2.7.0", - "request": "2.88.2", - "source-map-support": "0.5.21", - "stream-to-promise": "3.0.0" - } - }, "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", @@ -11698,9 +11701,9 @@ } }, "node_modules/sonic-boom": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-3.3.0.tgz", - "integrity": "sha512-LYxp34KlZ1a2Jb8ZQgFCK3niIHzibdwtwNUWKg0qQRzsDoJ3Gfgkf8KdBTFU3SkejDEIlWwnSnpVdOZIhFMl/g==", + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-3.8.1.tgz", + "integrity": "sha512-y4Z8LCDBuum+PBP3lSV7RHrXscqksve/bi0as7mhwVnBW+/wUqKT/2Kb7um8yqcFy0duYbbPxzt89Zy2nOCaxg==", "dev": true, "dependencies": { "atomic-sleep": "^1.0.0" @@ -11714,15 +11717,6 @@ "node": ">=0.10.0" } }, - "node_modules/source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/source-map-support": { "version": "0.5.21", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", @@ -11776,31 +11770,6 @@ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, - "node_modules/sshpk": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", - "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", - "dev": true, - "dependencies": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "bin": { - "sshpk-conv": "bin/sshpk-conv", - "sshpk-sign": "bin/sshpk-sign", - "sshpk-verify": "bin/sshpk-verify" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/stack-utils": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", @@ -11822,27 +11791,13 @@ "node": ">=8" } }, - "node_modules/stream-to-array": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/stream-to-array/-/stream-to-array-2.3.0.tgz", - "integrity": "sha512-UsZtOYEn4tWU2RGLOXr/o/xjRBftZRlG3dEWoaHr8j4GuypJ3isitGbVyjQKAuMu+xbiop8q224TjiZWc4XTZA==", - "dev": true, - "dependencies": { - "any-promise": "^1.1.0" - } - }, - "node_modules/stream-to-promise": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/stream-to-promise/-/stream-to-promise-3.0.0.tgz", - "integrity": "sha512-h+7wLeFiYegOdgTfTxjRsrT7/Op7grnKEIHWgaO1RTHwcwk7xRreMr3S8XpDfDMesSxzgM2V4CxNCFAGo6ssnA==", + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "dev": true, "dependencies": { - "any-promise": "~1.3.0", - "end-of-stream": "~1.4.1", - "stream-to-array": "~2.3.0" - }, - "engines": { - "node": ">= 10" + "safe-buffer": "~5.2.0" } }, "node_modules/string-length": { @@ -11872,6 +11827,21 @@ "node": ">=8" } }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/string.prototype.matchall": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz", @@ -11931,6 +11901,19 @@ "node": ">=8" } }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-bom": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", @@ -12033,13 +12016,13 @@ } }, "node_modules/terser": { - "version": "5.14.2", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.14.2.tgz", - "integrity": "sha512-oL0rGeM/WFQCUd0y2QrWxYnq7tfSuKBiqTjRPWrRgB46WD/kiwHwF8T23z78H6Q6kGCuuHcPB+KULHRdxvVGQA==", + "version": "5.31.6", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.6.tgz", + "integrity": "sha512-PQ4DAriWzKj+qgehQ7LK5bQqCFNMmlhjR2PFFLuqGCpuCAauxemVBWwWOxo3UIwWQx8+Pr61Df++r76wDmkQBg==", "dev": true, "dependencies": { - "@jridgewell/source-map": "^0.3.2", - "acorn": "^8.5.0", + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, @@ -12051,16 +12034,16 @@ } }, "node_modules/terser-webpack-plugin": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.1.tgz", - "integrity": "sha512-GvlZdT6wPQKbDNW/GDQzZFg/j4vKU96yl2q6mcUkzKOgW4gwf1Z8cZToUCrz31XHlPWH8MVb1r2tFtdDtTGJ7g==", + "version": "5.3.10", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", + "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", "dev": true, "dependencies": { + "@jridgewell/trace-mapping": "^0.3.20", "jest-worker": "^27.4.5", "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.0", - "source-map": "^0.6.1", - "terser": "^5.7.2" + "serialize-javascript": "^6.0.1", + "terser": "^5.26.0" }, "engines": { "node": ">= 10.13.0" @@ -12085,9 +12068,9 @@ } }, "node_modules/terser-webpack-plugin/node_modules/schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.8", @@ -12143,9 +12126,9 @@ } }, "node_modules/thread-stream": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-2.3.0.tgz", - "integrity": "sha512-kaDqm1DET9pp3NXwR8382WHbnpXnRkN9xGN9dQt3B2+dmXiW8X1SOwmFOxAErEQ47ObhZ96J6yhZNXuyCOL7KA==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-2.7.0.tgz", + "integrity": "sha512-qQiRWsU/wvNolI6tbbCKd9iKaTnCXsTwVxhhKM6nctPdujTyztjlbUkUTUymidWcMnZ5pWR0ej4a0tjsW021vw==", "dev": true, "dependencies": { "real-require": "^0.2.0" @@ -12157,30 +12140,25 @@ "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", "dev": true }, - "node_modules/tmp": { - "version": "0.2.1", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "node_modules/titleize": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/titleize/-/titleize-3.0.0.tgz", + "integrity": "sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ==", "dev": true, - "dependencies": { - "rimraf": "^3.0.0" - }, "engines": { - "node": ">=8.17.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/tmp/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "node_modules/tmp": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", + "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "engines": { + "node": ">=14.14" } }, "node_modules/tmpl": { @@ -12220,9 +12198,9 @@ } }, "node_modules/tough-cookie": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.2.tgz", - "integrity": "sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", + "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", "dev": true, "dependencies": { "psl": "^1.1.33", @@ -12484,24 +12462,6 @@ "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" } }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", - "dev": true - }, "node_modules/type-check": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", @@ -12616,6 +12576,15 @@ "node": ">= 10.0.0" } }, + "node_modules/untildify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", + "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/upath": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/upath/-/upath-2.0.1.tgz", @@ -12627,9 +12596,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", - "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", + "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", "dev": true, "funding": [ { @@ -12639,14 +12608,18 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" + "escalade": "^3.1.2", + "picocolors": "^1.0.1" }, "bin": { - "browserslist-lint": "cli.js" + "update-browserslist-db": "cli.js" }, "peerDependencies": { "browserslist": ">= 4.21.0" @@ -12708,8 +12681,9 @@ } }, "node_modules/uri-js": { - "version": "4.2.2", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, "dependencies": { "punycode": "^2.1.0" @@ -12759,20 +12733,6 @@ "node": ">=10.12.0" } }, - "node_modules/verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", - "dev": true, - "engines": [ - "node >=0.6.0" - ], - "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, "node_modules/w3c-xmlserializer": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-3.0.0.tgz", @@ -12795,9 +12755,9 @@ } }, "node_modules/watchpack": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", - "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", + "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==", "dev": true, "dependencies": { "glob-to-regexp": "^0.4.1", @@ -12817,68 +12777,97 @@ } }, "node_modules/web-ext": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/web-ext/-/web-ext-7.6.2.tgz", - "integrity": "sha512-xlxbzgFBIS/UWWlvWxyR1PIqRRzDj1cutoHh+VZu4ZTcJTfv35KVdKkLRZv4PQwHu4dg8VfTg7WEcNP4QLaaFQ==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/web-ext/-/web-ext-8.2.0.tgz", + "integrity": "sha512-krU7rmxaG96b3Q9Enbry9/pmE/5FUGkvajCGfJCD+J79rt7JFjhVpw1Dszz4BqQkTd3y8cG5wJ3p1uC6uyAwcA==", "dev": true, "dependencies": { - "@babel/runtime": "7.21.0", - "@devicefarmer/adbkit": "3.2.3", - "addons-linter": "5.32.0", + "@babel/runtime": "7.24.7", + "@devicefarmer/adbkit": "3.2.6", + "addons-linter": "6.31.1", "bunyan": "1.8.15", - "camelcase": "7.0.1", + "camelcase": "8.0.0", "chrome-launcher": "0.15.1", "debounce": "1.2.1", "decamelize": "6.0.0", "es6-error": "4.1.1", - "firefox-profile": "4.3.2", - "fs-extra": "11.1.0", - "fx-runner": "1.3.0", - "import-fresh": "3.3.0", - "jose": "4.13.1", - "mkdirp": "1.0.4", + "firefox-profile": "4.6.0", + "fs-extra": "11.2.0", + "fx-runner": "1.4.0", + "https-proxy-agent": "^7.0.0", + "jose": "5.4.1", + "jszip": "3.10.1", + "mkdirp": "3.0.1", "multimatch": "6.0.0", "mz": "2.7.0", - "node-fetch": "3.3.1", + "node-fetch": "3.3.2", "node-notifier": "10.0.1", - "open": "8.4.2", - "parse-json": "6.0.2", + "open": "9.1.0", + "parse-json": "7.1.1", "promise-toolbox": "0.21.0", - "sign-addon": "5.3.0", "source-map-support": "0.5.21", "strip-bom": "5.0.0", - "strip-json-comments": "5.0.0", - "tmp": "0.2.1", + "strip-json-comments": "5.0.1", + "tmp": "0.2.3", "update-notifier": "6.0.2", - "watchpack": "2.4.0", - "ws": "8.13.0", - "yargs": "17.7.1", + "watchpack": "2.4.1", + "ws": "8.17.1", + "yargs": "17.7.2", "zip-dir": "2.0.0" }, "bin": { "web-ext": "bin/web-ext.js" }, "engines": { - "node": ">=14.0.0", - "npm": ">=6.9.0" + "node": ">=18.0.0", + "npm": ">=8.0.0" + } + }, + "node_modules/web-ext/node_modules/agent-base": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "dev": true, + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" } }, "node_modules/web-ext/node_modules/camelcase": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-7.0.1.tgz", - "integrity": "sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-8.0.0.tgz", + "integrity": "sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==", "dev": true, "engines": { - "node": ">=14.16" + "node": ">=16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/web-ext/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, "node_modules/web-ext/node_modules/fs-extra": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.0.tgz", - "integrity": "sha512-0rcTq621PD5jM/e0a3EJoGC/1TC5ZBCERW82LQuwfGnCa1V8w7dpYH1yNu+SLb6E5dkeCBzKEyLGlFrnr+dUyw==", + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", "dev": true, "dependencies": { "graceful-fs": "^4.2.0", @@ -12889,39 +12878,72 @@ "node": ">=14.14" } }, + "node_modules/web-ext/node_modules/https-proxy-agent": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", + "dev": true, + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/web-ext/node_modules/json-parse-even-better-errors": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.2.tgz", + "integrity": "sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/web-ext/node_modules/lines-and-columns": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-2.0.3.tgz", - "integrity": "sha512-cNOjgCnLB+FnvWWtyRTzmB3POJ+cXxTA81LoW7u8JdmhfXzriropYwpjShnz1QLLWsQwY7nIxoDmcPTwphDK9w==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-2.0.4.tgz", + "integrity": "sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A==", "dev": true, "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } }, "node_modules/web-ext/node_modules/mkdirp": { - "version": "1.0.4", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", "dev": true, "bin": { - "mkdirp": "bin/cmd.js" + "mkdirp": "dist/cjs/src/bin.js" }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/web-ext/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, "node_modules/web-ext/node_modules/parse-json": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-6.0.2.tgz", - "integrity": "sha512-SA5aMiaIjXkAiBrW/yPgLgQAQg42f7K3ACO+2l/zOvtQBwX58DMUsFJXelW2fx3yMBmWOVkR6j1MGsdSbCA4UA==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-7.1.1.tgz", + "integrity": "sha512-SgOTCX/EZXtZxBE5eJ97P4yGM5n37BwRU+YMsH4vNzFqJV/oWFXXCmwFlgWUM4PrakybVOueJJ6pwHqSVhTFDw==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.16.0", + "@babel/code-frame": "^7.21.4", "error-ex": "^1.3.2", - "json-parse-even-better-errors": "^2.3.1", - "lines-and-columns": "^2.0.2" + "json-parse-even-better-errors": "^3.0.0", + "lines-and-columns": "^2.0.3", + "type-fest": "^3.8.0" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -12940,9 +12962,21 @@ } }, "node_modules/web-ext/node_modules/strip-json-comments": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-5.0.0.tgz", - "integrity": "sha512-V1LGY4UUo0jgwC+ELQ2BNWfPa17TIuwBLg+j1AA/9RPzKINl1lhxVEu2r+ZTTO8aetIsUzE5Qj6LMSBkoGYKKw==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-5.0.1.tgz", + "integrity": "sha512-0fk9zBqO67Nq5M/m45qHCJxylV/DhBlIOVExqgOMiCCrzrhU6tCibRXNqE3jwJLftzE9SNuZtYbpzcO+i9FiKw==", + "dev": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/web-ext/node_modules/type-fest": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.1.tgz", + "integrity": "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==", "dev": true, "engines": { "node": ">=14.16" @@ -12952,9 +12986,9 @@ } }, "node_modules/web-streams-polyfill": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz", - "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", "dev": true, "engines": { "node": ">= 8" @@ -13015,34 +13049,33 @@ } }, "node_modules/webpack": { - "version": "5.75.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.75.0.tgz", - "integrity": "sha512-piaIaoVJlqMsPtX/+3KTTO6jfvrSYgauFVdt8cr9LTHKmcq/AMd4mhzsiP7ZF/PGRNPGA8336jldh9l2Kt2ogQ==", + "version": "5.94.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.94.0.tgz", + "integrity": "sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg==", "dev": true, "dependencies": { - "@types/eslint-scope": "^3.7.3", - "@types/estree": "^0.0.51", - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/wasm-edit": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", + "@types/estree": "^1.0.5", + "@webassemblyjs/ast": "^1.12.1", + "@webassemblyjs/wasm-edit": "^1.12.1", + "@webassemblyjs/wasm-parser": "^1.12.1", "acorn": "^8.7.1", - "acorn-import-assertions": "^1.7.6", - "browserslist": "^4.14.5", + "acorn-import-attributes": "^1.9.5", + "browserslist": "^4.21.10", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.10.0", - "es-module-lexer": "^0.9.0", + "enhanced-resolve": "^5.17.1", + "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.9", + "graceful-fs": "^4.2.11", "json-parse-even-better-errors": "^2.3.1", "loader-runner": "^4.2.0", "mime-types": "^2.1.27", "neo-async": "^2.6.2", - "schema-utils": "^3.1.0", + "schema-utils": "^3.2.0", "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.1.3", - "watchpack": "^2.4.0", + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.1", "webpack-sources": "^3.2.3" }, "bin": { @@ -13130,19 +13163,16 @@ "node": ">=10.0.0" } }, - "node_modules/webpack/node_modules/acorn-import-assertions": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", - "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==", - "dev": true, - "peerDependencies": { - "acorn": "^8" - } + "node_modules/webpack/node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true }, "node_modules/webpack/node_modules/schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.8", @@ -13360,6 +13390,57 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "node_modules/wrap-ansi/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -13411,9 +13492,9 @@ } }, "node_modules/ws": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", - "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", "dev": true, "engines": { "node": ">=10.0.0" @@ -13505,9 +13586,9 @@ } }, "node_modules/yargs": { - "version": "17.7.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", - "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==", + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, "dependencies": { "cliui": "^8.0.1", @@ -13578,6 +13659,12 @@ } }, "dependencies": { + "@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true + }, "@ampproject/remapping": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", @@ -13589,12 +13676,13 @@ } }, "@babel/code-frame": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", - "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", "dev": true, "requires": { - "@babel/highlight": "^7.18.6" + "@babel/highlight": "^7.22.13", + "chalk": "^2.4.2" } }, "@babel/compat-data": { @@ -13627,13 +13715,14 @@ } }, "@babel/generator": { - "version": "7.19.3", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.19.3.tgz", - "integrity": "sha512-fqVZnmp1ncvZU757UzDheKZpfPgatqY59XtW2/j/18H7u76akb8xqvjw82f+i2UKd/ksYsSick/BCLQUUtJ/qQ==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz", + "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==", "dev": true, "requires": { - "@babel/types": "^7.19.3", + "@babel/types": "^7.23.0", "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" }, "dependencies": { @@ -13663,28 +13752,28 @@ } }, "@babel/helper-environment-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", - "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", "dev": true }, "@babel/helper-function-name": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", - "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "dev": true, "requires": { - "@babel/template": "^7.18.10", - "@babel/types": "^7.19.0" + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" } }, "@babel/helper-hoist-variables": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", - "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", "dev": true, "requires": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" } }, "@babel/helper-module-imports": { @@ -13728,24 +13817,24 @@ } }, "@babel/helper-split-export-declaration": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", - "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", "dev": true, "requires": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" } }, "@babel/helper-string-parser": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", - "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", + "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", "dev": true }, "@babel/helper-validator-identifier": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "dev": true }, "@babel/helper-validator-option": { @@ -13766,20 +13855,20 @@ } }, "@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", + "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", "js-tokens": "^4.0.0" } }, "@babel/parser": { - "version": "7.20.13", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.13.tgz", - "integrity": "sha512-gFDLKMfpiXCsjt4za2JA9oTMn70CeseCehb11kRZgvd7+F67Hih3OHOK24cRrWECJ/ljfPGac6ygXAs/C8kIvw==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", + "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==", "dev": true }, "@babel/plugin-syntax-async-generators": { @@ -13909,51 +13998,51 @@ } }, "@babel/runtime": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.0.tgz", - "integrity": "sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.7.tgz", + "integrity": "sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==", "dev": true, "requires": { - "regenerator-runtime": "^0.13.11" + "regenerator-runtime": "^0.14.0" } }, "@babel/template": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", - "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", "dev": true, "requires": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.18.10", - "@babel/types": "^7.18.10" + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" } }, "@babel/traverse": { - "version": "7.19.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.19.3.tgz", - "integrity": "sha512-qh5yf6149zhq2sgIXmwjnsvmnNQC2iw70UFjp4olxucKrWd/dvlUsBI88VSLUsnMNF7/vnOiA+nk1+yLoCqROQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.19.3", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.19.3", - "@babel/types": "^7.19.3", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", + "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.0", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.0", + "@babel/types": "^7.23.0", "debug": "^4.1.0", "globals": "^11.1.0" } }, "@babel/types": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz", - "integrity": "sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", + "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==", "dev": true, "requires": { - "@babel/helper-string-parser": "^7.19.4", - "@babel/helper-validator-identifier": "^7.19.1", + "@babel/helper-string-parser": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" } }, @@ -13985,13 +14074,13 @@ } }, "@devicefarmer/adbkit": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/@devicefarmer/adbkit/-/adbkit-3.2.3.tgz", - "integrity": "sha512-wK9rVrabs4QU0oK8Jnwi+HRBEm+s1x/o63kgthUe0y7K1bfcYmgLuQf41/adsj/5enddlSxzkJavl2EwOu+r1g==", + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/@devicefarmer/adbkit/-/adbkit-3.2.6.tgz", + "integrity": "sha512-8lO1hSeTgtxcOHhp4tTWq/JaOysp5KNbbyFoxNEBnwkCDZu/Bji3ZfOaG++Riv9jN6c9bgdLBOZqJTC5VJPRKQ==", "dev": true, "requires": { "@devicefarmer/adbkit-logcat": "^2.1.2", - "@devicefarmer/adbkit-monkey": "~1.2.0", + "@devicefarmer/adbkit-monkey": "~1.2.1", "bluebird": "~3.7", "commander": "^9.1.0", "debug": "~4.3.1", @@ -14000,17 +14089,17 @@ }, "dependencies": { "commander": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-9.3.0.tgz", - "integrity": "sha512-hv95iU5uXPbK83mjrJKuZyFM/LBAoCV/XhVGkS5Je6tl7sxr6A0ITMw5WoRV46/UaJ46Nllm3Xt7IaJhXTIkzw==", + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", "dev": true } } }, "@devicefarmer/adbkit-logcat": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@devicefarmer/adbkit-logcat/-/adbkit-logcat-2.1.2.tgz", - "integrity": "sha512-G4grpEa5s9s9wCRs8YB9LjFSnz0Os3g3RYIwZSxH3JFfV3aejL5xlu4hHMH4JY+d4oCCwImcEZJcFPY9BEP21w==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@devicefarmer/adbkit-logcat/-/adbkit-logcat-2.1.3.tgz", + "integrity": "sha512-yeaGFjNBc/6+svbDeul1tNHtNChw6h8pSHAt5D+JsedUrMTN7tla7B15WLDyekxsuS2XlZHRxpuC6m92wiwCNw==", "dev": true }, "@devicefarmer/adbkit-monkey": { @@ -14035,20 +14124,20 @@ } }, "@eslint-community/regexpp": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.0.tgz", - "integrity": "sha512-vITaYzIcNmjn5tF5uxcZ/ft7/RXGrMUIS9HalWckEOF6ESiwXKoMzAQf2UW0aVd6rnOeExTJVd5hmWXucBKGXQ==", + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", "dev": true }, "@eslint/eslintrc": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.2.tgz", - "integrity": "sha512-3W4f5tDUra+pA+FzgugqL2pRimUTDJWKr7BINqOpkZrC0uYI0NIc0/JFgBROCU07HR6GieA5m3/rsPIhDmCXTQ==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.5.1", + "espree": "^9.6.0", "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", @@ -14072,27 +14161,10 @@ "ms": "2.1.2" } }, - "eslint-visitor-keys": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz", - "integrity": "sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==", - "dev": true - }, - "espree": { - "version": "9.5.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.1.tgz", - "integrity": "sha512-5yxtHSZXRSW5pvv3hAlXM5+/Oswi1AUFqBmbibKb5s6bp3rGIDkyXU6xCoyuuLhijr4SFwPrXRoZjz0AZDN9tg==", - "dev": true, - "requires": { - "acorn": "^8.8.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.0" - } - }, "globals": { - "version": "13.20.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", - "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -14116,9 +14188,9 @@ } }, "@eslint/js": { - "version": "8.36.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.36.0.tgz", - "integrity": "sha512-lxJ9R5ygVm8ZWgYdUweoq5ownDlJ4upvoWmO4eLxBYHdMo+vZ/Rx0EN6MbKWDJOSUGrqJy2Gt+Dyv/VKml0fjg==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", "dev": true }, "@fluent/syntax": { @@ -14128,13 +14200,13 @@ "dev": true }, "@humanwhocodes/config-array": { - "version": "0.11.8", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", - "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", "dev": true, "requires": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", "minimatch": "^3.0.5" } }, @@ -14145,11 +14217,76 @@ "dev": true }, "@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", + "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", "dev": true }, + "@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "requires": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true + }, + "ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true + }, + "emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "requires": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + } + }, + "strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "requires": { + "ansi-regex": "^6.0.1" + } + }, + "wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "requires": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + } + } + } + }, "@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -14694,58 +14831,60 @@ } }, "@jridgewell/resolve-uri": { - "version": "3.0.4", - "integrity": "sha512-cz8HFjOFfUBtvN+NXYSFMHYRdxZMaEl0XypVrhzxBgadKIXhIkRd8aMeHhmF56Sl7SuS8OnUpQ73/k9LE4VnLg==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", "dev": true }, "@jridgewell/set-array": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.1.tgz", - "integrity": "sha512-Ct5MqZkLGEXTVmQYbGtx9SVqD2fqwvdubdps5D3djjAkgkKwT918VNOz65pEHFaYTeWcukmJmH5SwsA9Tn2ObQ==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "dev": true }, "@jridgewell/source-map": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz", - "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==", + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", "dev": true, "requires": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" }, "dependencies": { "@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dev": true, "requires": { - "@jridgewell/set-array": "^1.0.1", + "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/trace-mapping": "^0.3.24" } } } }, "@jridgewell/sourcemap-codec": { - "version": "1.4.10", - "integrity": "sha512-Ht8wIW5v165atIX1p+JvKR5ONzUyF4Ac8DZIQ5kZs9zrb6M8SJNXpx1zn04rn65VjBMygRoMXcyYwNK0fT7bEg==", + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", "dev": true }, "@jridgewell/trace-mapping": { - "version": "0.3.15", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz", - "integrity": "sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==", + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, "@mdn/browser-compat-data": { - "version": "5.2.42", - "resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-5.2.42.tgz", - "integrity": "sha512-CD/2ai1W45cDN/zN2AcYduDavU+nq9aStyQizi4MHxnwkRvS/H24WIjgc1qD8CISoqXa8AAIe+A+zpWxwV7a2Q==", + "version": "5.5.34", + "resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-5.5.34.tgz", + "integrity": "sha512-e8k7+8r3jiJuP7FMH6AL1OnmfQqLyABhTM+NmRDvFeAbMgtFcNQLHpmT7uza5cBnxI01+CAU3aSsIgcKGRdEBQ==", "dev": true }, "@nodelib/fs.scandir": { @@ -14774,6 +14913,13 @@ "fastq": "^1.6.0" } }, + "@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true + }, "@pnpm/network.ca-file": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@pnpm/network.ca-file/-/network.ca-file-1.0.1.tgz", @@ -14833,9 +14979,9 @@ } }, "@testim/chrome-version": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@testim/chrome-version/-/chrome-version-1.1.3.tgz", - "integrity": "sha512-g697J3WxV/Zytemz8aTuKjTGYtta9+02kva3C1xc7KXB8GdbfE1akGJIsZLyY/FSh2QrnE+fiB7vmWU3XNcb6A==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@testim/chrome-version/-/chrome-version-1.1.4.tgz", + "integrity": "sha512-kIhULpw9TrGYnHp/8VfdcneIcxKnLixmADtukQRtJUmsVlMg0niMkwV0xZmi8hqa57xqilIHjWFA0GKvEjVU5g==", "dev": true }, "@tootallnate/once": { @@ -14915,30 +15061,10 @@ "@types/har-format": "*" } }, - "@types/eslint": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.1.tgz", - "integrity": "sha512-GE44+DNEyxxh2Kc6ro/VkIj+9ma0pO0bwv9+uHSyBrikYOHr8zYcdPvnBOp1aw8s+CjRvuSx7CyWqRrNFQ59mA==", - "dev": true, - "requires": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "@types/eslint-scope": { - "version": "3.7.3", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.3.tgz", - "integrity": "sha512-PB3ldyrcnAicT35TWPs5IcwKD8S333HMaa2VVv4+wdvebJkjWuW/xESoB8IwRcog8HYVYamb1g/R31Qv5Bx03g==", - "dev": true, - "requires": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, "@types/estree": { - "version": "0.0.51", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz", - "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", "dev": true }, "@types/filesystem": { @@ -15141,9 +15267,9 @@ "dev": true }, "@types/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==", + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", + "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", "dev": true, "requires": { "@types/node": "*" @@ -15321,149 +15447,155 @@ "eslint-visitor-keys": "^3.3.0" } }, + "@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, "@webassemblyjs/ast": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", - "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", + "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", "dev": true, "requires": { - "@webassemblyjs/helper-numbers": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1" + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" } }, "@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz", - "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", "dev": true }, "@webassemblyjs/helper-api-error": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz", - "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", "dev": true }, "@webassemblyjs/helper-buffer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz", - "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", + "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", "dev": true }, "@webassemblyjs/helper-numbers": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz", - "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", "dev": true, "requires": { - "@webassemblyjs/floating-point-hex-parser": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", "@xtuc/long": "4.2.2" } }, "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz", - "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", "dev": true }, "@webassemblyjs/helper-wasm-section": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz", - "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", + "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.12.1" } }, "@webassemblyjs/ieee754": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz", - "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", "dev": true, "requires": { "@xtuc/ieee754": "^1.2.0" } }, "@webassemblyjs/leb128": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz", - "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", "dev": true, "requires": { "@xtuc/long": "4.2.2" } }, "@webassemblyjs/utf8": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz", - "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", "dev": true }, "@webassemblyjs/wasm-edit": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz", - "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", + "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/helper-wasm-section": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-opt": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", - "@webassemblyjs/wast-printer": "1.11.1" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-opt": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1", + "@webassemblyjs/wast-printer": "1.12.1" } }, "@webassemblyjs/wasm-gen": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz", - "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", + "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" } }, "@webassemblyjs/wasm-opt": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz", - "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", + "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1" } }, "@webassemblyjs/wasm-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz", - "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", + "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" } }, "@webassemblyjs/wast-printer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz", - "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", + "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/ast": "1.12.1", "@xtuc/long": "4.2.2" } }, @@ -15518,9 +15650,9 @@ } }, "acorn": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", - "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true }, "acorn-globals": { @@ -15533,6 +15665,13 @@ "acorn-walk": "^8.0.2" } }, + "acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", + "dev": true, + "requires": {} + }, "acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", @@ -15547,52 +15686,51 @@ "dev": true }, "addons-linter": { - "version": "5.32.0", - "resolved": "https://registry.npmjs.org/addons-linter/-/addons-linter-5.32.0.tgz", - "integrity": "sha512-Lf6oOyw8X9z5BMd9xhQwSbPlN2PUlzDLnYLAVT5lkrgXEx0fO9hRk4JRxWZ8+rFGz+mCIA2TTClZF2f+MKgJQA==", + "version": "6.31.1", + "resolved": "https://registry.npmjs.org/addons-linter/-/addons-linter-6.31.1.tgz", + "integrity": "sha512-R9FCyVzqU/h5A2aB1t+jD8t4QKLuLxYqc1FjmjJ0nZrn1qNCna1jFOajt5R1T8pwt0H4WXgT+uwWSD2BdkBzqQ==", "dev": true, "requires": { "@fluent/syntax": "0.19.0", - "@mdn/browser-compat-data": "5.2.42", + "@mdn/browser-compat-data": "5.5.34", "addons-moz-compare": "1.3.0", - "addons-scanner-utils": "8.5.0", - "ajv": "8.12.0", + "addons-scanner-utils": "9.11.0", + "ajv": "8.16.0", "chalk": "4.1.2", "cheerio": "1.0.0-rc.12", "columnify": "1.6.0", "common-tags": "1.8.2", "deepmerge": "4.3.1", - "eslint": "8.36.0", + "eslint": "8.57.0", "eslint-plugin-no-unsanitized": "4.0.2", - "eslint-visitor-keys": "3.3.0", - "espree": "9.5.0", + "eslint-visitor-keys": "4.0.0", + "espree": "10.0.1", "esprima": "4.0.1", "fast-json-patch": "3.1.1", - "glob": "9.3.0", - "image-size": "1.0.2", + "glob": "10.4.2", + "image-size": "1.1.1", "is-mergeable-object": "1.1.1", "jed": "1.1.1", "json-merge-patch": "1.0.2", "os-locale": "5.0.0", - "pino": "8.11.0", - "postcss": "8.4.21", + "pino": "8.20.0", "relaxed-json": "1.0.3", - "semver": "7.3.8", + "semver": "7.6.2", "sha.js": "2.4.11", "source-map-support": "0.5.21", "tosource": "1.0.0", "upath": "2.0.1", - "yargs": "17.7.1", + "yargs": "17.7.2", "yauzl": "2.10.0" }, "dependencies": { "addons-scanner-utils": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/addons-scanner-utils/-/addons-scanner-utils-8.5.0.tgz", - "integrity": "sha512-X35SYZRdSnxx7UZuAk+DizKihQp2Ze2c5GV+5nnRr/FFyx/fOgE3Zo8jdhzSne57PENE9w1ZVocBLJTN6UDB3g==", + "version": "9.11.0", + "resolved": "https://registry.npmjs.org/addons-scanner-utils/-/addons-scanner-utils-9.11.0.tgz", + "integrity": "sha512-X95V8ymnue9EHmOLz3zJTGHvHDFlWKiavlH+kJKOlv2sJDWFvD3TWeJMHJgxS9GKOqT/545mOXvX3vuuGGum+g==", "dev": true, "requires": { - "@types/yauzl": "2.10.0", + "@types/yauzl": "2.10.3", "common-tags": "1.8.2", "first-chunk-stream": "3.0.0", "strip-bom-stream": "4.0.0", @@ -15601,15 +15739,15 @@ } }, "ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz", + "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==", "dev": true, "requires": { - "fast-deep-equal": "^3.1.1", + "fast-deep-equal": "^3.1.3", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "uri-js": "^4.4.1" } }, "ansi-styles": { @@ -15655,16 +15793,35 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "eslint-visitor-keys": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", + "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", + "dev": true + }, + "espree": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.0.1.tgz", + "integrity": "sha512-MWkrWZbJsL2UwnjxTX3gG8FneachS/Mwg7tdGXce011sJd5b0JG54vat5KHnfSBODZ3Wvzd2WnjxyzsRoVv+ww==", + "dev": true, + "requires": { + "acorn": "^8.11.3", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.0.0" + } + }, "glob": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.0.tgz", - "integrity": "sha512-EAZejC7JvnQINayvB/7BJbpZpNOJ8Lrw2OZNEvQxe0vaLn1SuwMcfV7/MNaX8L/T0wmptBFI4YMtDvSBxYDc7w==", + "version": "10.4.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.2.tgz", + "integrity": "sha512-GwMlUF6PkPo3Gk21UxkCohOv0PLcIXVtKyLlpEI28R/cO/4eNOdmLk3CMW1wROV/WR/EsZOWAfBbBOqYvs88/w==", "dev": true, "requires": { - "fs.realpath": "^1.0.0", - "minimatch": "^7.4.1", - "minipass": "^4.2.4", - "path-scurry": "^1.6.1" + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" } }, "has-flag": { @@ -15680,18 +15837,24 @@ "dev": true }, "minimatch": { - "version": "7.4.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.6.tgz", - "integrity": "sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "requires": { "brace-expansion": "^2.0.1" } }, + "minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true + }, "node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.11.tgz", + "integrity": "sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==", "dev": true, "optional": true, "peer": true, @@ -15700,13 +15863,10 @@ } }, "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true }, "supports-color": { "version": "7.2.0", @@ -15754,9 +15914,9 @@ "dev": true }, "adm-zip": { - "version": "0.5.10", - "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.10.tgz", - "integrity": "sha512-x0HvcHqVJNTPk/Bw8JbLWlWoo6Wwnsug0fnYYro1HBrjxZ3G7/AZk7Ahv8JwDe1uIcz8eBqvu86FuF1POiG7vQ==", + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.16.tgz", + "integrity": "sha512-TGw5yVi4saajsSEgz25grObGHEUaDrniwvA2qwSC060KfqGPdglhvPMA2lPIoxs3PQIItj2iag35fONcQqgUaQ==", "dev": true }, "agent-base": { @@ -15925,21 +16085,6 @@ "get-intrinsic": "^1.1.3" } }, - "asn1": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", - "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", - "dev": true, - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", - "dev": true - }, "asynckit": { "version": "0.4.0", "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", @@ -15963,25 +16108,13 @@ "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", "dev": true }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", - "dev": true - }, - "aws4": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz", - "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==", - "dev": true - }, "axios": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.2.6.tgz", - "integrity": "sha512-rC/7F08XxZwjMV4iuWv+JpD3E0Ksqg9nac4IIg6RwNuF0JTeWoCo/mBNG54+tNhhI11G3/VDRbdDQTs9hGp4pQ==", + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", + "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", "dev": true, "requires": { - "follow-redirects": "^1.15.0", + "follow-redirects": "^1.15.6", "form-data": "^4.0.0", "proxy-from-env": "^1.1.0" }, @@ -16131,14 +16264,11 @@ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", "dev": true }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", - "dev": true, - "requires": { - "tweetnacl": "^0.14.3" - } + "big-integer": { + "version": "1.6.52", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz", + "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==", + "dev": true }, "bluebird": { "version": "3.7.2", @@ -16237,6 +16367,15 @@ } } }, + "bplist-parser": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.2.0.tgz", + "integrity": "sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==", + "dev": true, + "requires": { + "big-integer": "^1.6.44" + } + }, "brace-expansion": { "version": "1.1.11", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", @@ -16247,24 +16386,24 @@ } }, "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "requires": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" } }, "browserslist": { - "version": "4.21.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", - "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", + "version": "4.23.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz", + "integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001400", - "electron-to-chromium": "^1.4.251", - "node-releases": "^2.0.6", - "update-browserslist-db": "^1.0.9" + "caniuse-lite": "^1.0.30001646", + "electron-to-chromium": "^1.5.4", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.0" } }, "bs-logger": { @@ -16299,17 +16438,20 @@ "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", "dev": true }, - "buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", - "dev": true - }, "buffer-from": { "version": "1.1.1", "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", "dev": true }, + "bundle-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-3.0.0.tgz", + "integrity": "sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw==", + "dev": true, + "requires": { + "run-applescript": "^5.0.0" + } + }, "bunyan": { "version": "1.8.15", "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.8.15.tgz", @@ -16364,15 +16506,9 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001418", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001418.tgz", - "integrity": "sha512-oIs7+JL3K9JRQ3jPZjlH6qyYDp+nBTCais7hjh0s+fuBwufc7uZ7hPYMXrDOJhV360KGMTcczMRObk0/iMqZRg==", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", + "version": "1.0.30001657", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001657.tgz", + "integrity": "sha512-DPbJAlP8/BAXy3IgiWmZKItubb3TYGP0WscQQlVGIfT4s/YlFYVuJgyOsQNP7rJRChx/qdMeLJQJP0Sgg2yjNA==", "dev": true }, "chalk": { @@ -16612,9 +16748,9 @@ "dev": true }, "compare-versions": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-5.0.1.tgz", - "integrity": "sha512-v8Au3l0b+Nwkp4G142JcgJFh1/TUhdxut7wzD1Nq1dyp5oa3tXaqb03EXOAB6jS4gMlalkjAUPZBMiAfKUixHQ==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-5.0.3.tgz", + "integrity": "sha512-4UZlZP8Z99MGEY+Ovg/uJxJuvoXuN4M6B3hKaiackiHrgzQFEe3diJi1mf1PNHbFujM7FvLrK2bpgIaImbtZ1A==", "dev": true }, "concat-map": { @@ -16808,12 +16944,6 @@ } } }, - "core-js": { - "version": "3.29.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.29.0.tgz", - "integrity": "sha512-VG23vuEisJNkGl6XQmFJd3rEG/so/CNatqeE+7uZAwTSwFeB/qaO0be8xZYUNWprJ/GIwL8aMt9cj1kvbpTZhg==", - "dev": true - }, "core-util-is": { "version": "1.0.2", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", @@ -16912,15 +17042,6 @@ "integrity": "sha512-2u44ZG2OcNUO9HDp/Jl8C07x6pU/eTR3ncV91SiK3dhG9TWvRVsCoJw14Ckx5DgWkzGA3waZWO3d7pgqpUI/XA==", "dev": true }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, "data-uri-to-buffer": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", @@ -17004,21 +17125,101 @@ "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", "dev": true }, - "deepcopy": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/deepcopy/-/deepcopy-2.1.0.tgz", - "integrity": "sha512-8cZeTb1ZKC3bdSCP6XOM1IsTczIO73fdqtwa2B0N15eAz7gmyhQo+mc5gnFuulsgN3vIQYmTgbmQVKalH1dKvQ==", - "dev": true, - "requires": { - "type-detect": "^4.0.8" - } - }, "deepmerge": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", "dev": true }, + "default-browser": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-4.0.0.tgz", + "integrity": "sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA==", + "dev": true, + "requires": { + "bundle-name": "^3.0.0", + "default-browser-id": "^3.0.0", + "execa": "^7.1.1", + "titleize": "^3.0.0" + }, + "dependencies": { + "execa": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-7.2.0.tgz", + "integrity": "sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.1", + "human-signals": "^4.3.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^3.0.7", + "strip-final-newline": "^3.0.0" + } + }, + "human-signals": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz", + "integrity": "sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==", + "dev": true + }, + "is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true + }, + "mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true + }, + "npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dev": true, + "requires": { + "path-key": "^4.0.0" + } + }, + "onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "requires": { + "mimic-fn": "^4.0.0" + } + }, + "path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true + }, + "strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true + } + } + }, + "default-browser-id": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-3.0.0.tgz", + "integrity": "sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA==", + "dev": true, + "requires": { + "bplist-parser": "^0.2.0", + "untildify": "^4.0.0" + } + }, "defaults": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", @@ -17035,9 +17236,9 @@ "dev": true }, "define-lazy-prop": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", - "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", "dev": true }, "define-properties": { @@ -17124,14 +17325,14 @@ } }, "domutils": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz", - "integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", "dev": true, "requires": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", - "domhandler": "^5.0.1" + "domhandler": "^5.0.3" } }, "dot-prop": { @@ -17159,29 +17360,10 @@ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", "dev": true }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", - "dev": true, - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, "electron-to-chromium": { - "version": "1.4.275", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.275.tgz", - "integrity": "sha512-aJeQQ+Hl9Jyyzv4chBqYJwmVRY46N5i2BEX5Cuyk/5gFCUZ5F3i7Hnba6snZftWla7Gglwc5pIgcd+E7cW+rPg==", + "version": "1.5.15", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.15.tgz", + "integrity": "sha512-Z4rIDoImwEJW+YYKnPul4DzqsWVqYetYVN3XqDmRpgV0mjz0hYTaeeh+8/9CL1bk3AHYmF4freW/NTiVoXA2gA==", "dev": true }, "emittery": { @@ -17204,9 +17386,9 @@ } }, "enhanced-resolve": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz", - "integrity": "sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ==", + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", + "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", "dev": true, "requires": { "graceful-fs": "^4.2.4", @@ -17276,9 +17458,9 @@ } }, "es-module-lexer": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz", - "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==", + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", + "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", "dev": true }, "es-set-tostringtag": { @@ -17318,15 +17500,10 @@ "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", "dev": true }, - "es6-promisify": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-7.0.0.tgz", - "integrity": "sha512-ginqzK3J90Rd4/Yz7qRrqUeIpe3TwSXTPPZtPne7tGBPeAaQiU8qt4fpKApnxHcq1AwtUdHVg5P77x/yrggG8Q==", - "dev": true - }, "escalade": { - "version": "3.1.1", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true }, "escape-goat": { @@ -17362,27 +17539,28 @@ } }, "eslint": { - "version": "8.36.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.36.0.tgz", - "integrity": "sha512-Y956lmS7vDqomxlaaQAHVmeb4tNMp2FWIvU/RnU5BD3IKMD/MJPr76xdyr68P8tV1iNMvN2mRK0yy3c+UjL+bw==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.4.0", - "@eslint/eslintrc": "^2.0.1", - "@eslint/js": "8.36.0", - "@humanwhocodes/config-array": "^0.11.8", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.10.0", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.1", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.5.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -17390,22 +17568,19 @@ "find-up": "^5.0.0", "glob-parent": "^6.0.2", "globals": "^13.19.0", - "grapheme-splitter": "^1.0.4", + "graphemer": "^1.4.0", "ignore": "^5.2.0", - "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "is-path-inside": "^3.0.3", - "js-sdsl": "^4.1.4", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.1", + "optionator": "^0.9.3", "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", "text-table": "^0.2.0" }, "dependencies": { @@ -17460,9 +17635,9 @@ "dev": true }, "eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, "requires": { "esrecurse": "^4.3.0", @@ -17536,17 +17711,17 @@ } }, "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", "dev": true, "requires": { + "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "type-check": "^0.4.0" } }, "p-limit": { @@ -17680,20 +17855,20 @@ } }, "eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true }, "espree": { - "version": "9.5.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.0.tgz", - "integrity": "sha512-JPbJGhKc47++oo4JkEoTe2wjy4fmMwvFpgJT9cQzmfXKp22Dr6Hf1tdCteLz1h0P3t+mGvWZ+4Uankvh8+c6zw==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, "requires": { - "acorn": "^8.8.0", + "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" + "eslint-visitor-keys": "^3.4.1" } }, "esprima": { @@ -17790,12 +17965,6 @@ "jest-util": "^29.5.0" } }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, "extract-zip": { "version": "2.0.1", "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", @@ -17817,12 +17986,6 @@ } } }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", - "dev": true - }, "fast-deep-equal": { "version": "3.1.3", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", @@ -17857,9 +18020,9 @@ "dev": true }, "fast-redact": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.1.2.tgz", - "integrity": "sha512-+0em+Iya9fKGfEQGcd62Yv6onjBmmhV1uh86XVfOU8VwAe6kaFdQCWI9s0/Nnugx5Vd9tdbZ7e6gE2tR9dzXdw==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.5.0.tgz", + "integrity": "sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==", "dev": true }, "fastest-levenshtein": { @@ -17912,9 +18075,9 @@ } }, "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "requires": { "to-regex-range": "^5.0.1" @@ -17931,9 +18094,9 @@ } }, "firefox-profile": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/firefox-profile/-/firefox-profile-4.3.2.tgz", - "integrity": "sha512-/C+Eqa0YgIsQT2p66p7Ygzqe7NlE/GNTbhw2SBCm5V3OsWDPITNdTPEcH2Q2fe7eMpYYNPKdUcuVioZBZiR6kA==", + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/firefox-profile/-/firefox-profile-4.6.0.tgz", + "integrity": "sha512-I9rAm1w8U3CdhgO4EzTJsCvgcbvynZn9lOySkZf78wUdUIQH2w9QOKf3pAX+THt2XMSSR3kJSuM8P7bYux9j8g==", "dev": true, "requires": { "adm-zip": "~0.5.x", @@ -17995,9 +18158,9 @@ "dev": true }, "follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", "dev": true }, "for-each": { @@ -18009,11 +18172,23 @@ "is-callable": "^1.1.3" } }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", - "dev": true + "foreground-child": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", + "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "dependencies": { + "signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true + } + } }, "fork-ts-checker-webpack-plugin": { "version": "7.3.0", @@ -18106,17 +18281,6 @@ } } }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, "form-data-encoder": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz", @@ -18185,9 +18349,9 @@ "dev": true }, "fx-runner": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/fx-runner/-/fx-runner-1.3.0.tgz", - "integrity": "sha512-5b37H4GCyhF+Nf8xk9mylXoDq4wb7pbGAXxlCXp/631UTeeZomWSYcEGXumY4wk8g2QAqjPMGdWW+RbNt8PUcA==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/fx-runner/-/fx-runner-1.4.0.tgz", + "integrity": "sha512-rci1g6U0rdTg6bAaBboP7XdRu01dzTAaKXxFf+PUqGuCv6Xu7o8NZdY1D5MvKGIjb6EdS1g3VlXOgksir1uGkg==", "dev": true, "requires": { "commander": "2.9.0", @@ -18269,15 +18433,6 @@ "get-intrinsic": "^1.1.1" } }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, "glob": { "version": "7.2.0", "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", @@ -18388,28 +18543,18 @@ "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", "dev": true }, + "graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, "growly": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", "integrity": "sha512-+xGQY0YyAWCnqy7Cd++hc2JqMYzlm0dG30Jd0beaA64sROr8C4nt8Yc9V5Ro3avlSUDTN0ulqP/VBKi1/lLygw==", "dev": true }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", - "dev": true - }, - "har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "dev": true, - "requires": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - } - }, "has": { "version": "1.0.3", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", @@ -18509,17 +18654,6 @@ "debug": "4" } }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, "http2-wrapper": { "version": "2.1.11", "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.1.11.tgz", @@ -18567,9 +18701,9 @@ "dev": true }, "image-size": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.0.2.tgz", - "integrity": "sha512-xfOoWjceHntRb3qFCrh5ZFORYH8XCdYpASltMhZ/Q0KZiOwjdE/Yl2QCiWdwD+lygV5bMCvauzgu5PxBX/Yerg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.1.1.tgz", + "integrity": "sha512-541xKlUw6jr/6gGuk92F+mYM5zaFAc5ahphvkqvNe2bQ6gVBkd6bfrmVJ2t4KDAfikAYZyIqTnktX3i6/aQDrQ==", "dev": true, "requires": { "queue": "6.0.2" @@ -18784,6 +18918,23 @@ "is-extglob": "^2.1.1" } }, + "is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "dev": true, + "requires": { + "is-docker": "^3.0.0" + }, + "dependencies": { + "is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "dev": true + } + } + }, "is-installed-globally": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", @@ -18980,12 +19131,6 @@ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", "dev": true }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", - "dev": true - }, "istanbul-lib-coverage": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", @@ -19054,6 +19199,16 @@ "istanbul-lib-report": "^3.0.0" } }, + "jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "requires": { + "@isaacs/cliui": "^8.0.2", + "@pkgjs/parseargs": "^0.11.0" + } + }, "jed": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/jed/-/jed-1.1.1.tgz", @@ -20307,11 +20462,13 @@ "dependencies": { "has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, "supports-color": { "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "requires": { @@ -20321,15 +20478,9 @@ } }, "jose": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/jose/-/jose-4.13.1.tgz", - "integrity": "sha512-MSJQC5vXco5Br38mzaQKiq9mwt7lwj2eXpgpRyQYNHYt2lq1PjkWa7DLXX0WVcQLE9HhMh3jPiufS7fhJf+CLQ==", - "dev": true - }, - "js-sdsl": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.5.tgz", - "integrity": "sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q==", + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/jose/-/jose-5.4.1.tgz", + "integrity": "sha512-U6QajmpV/nhL9SyfAewo000fkiRQ+Yd2H0lBxJJ9apjpOgkOcBQJWOrMo917lxLptdS/n/o/xPzMkXhF46K8hQ==", "dev": true }, "js-tokens": { @@ -20346,12 +20497,6 @@ "esprima": "^4.0.0" } }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", - "dev": true - }, "jsdom": { "version": "20.0.1", "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-20.0.1.tgz", @@ -20426,12 +20571,6 @@ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "dev": true }, - "json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", - "dev": true - }, "json-schema-traverse": { "version": "0.4.1", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", @@ -20442,12 +20581,6 @@ "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", "dev": true }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true - }, "json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", @@ -20464,41 +20597,6 @@ "universalify": "^2.0.0" } }, - "jsonwebtoken": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.0.tgz", - "integrity": "sha512-tuGfYXxkQGDPnLJ7SibiQgVgeDgfbPq2k2ICcbgqW8WxWLBAxKQM/ZCu/IT8SOSwmaYl4dpTFCW5xZv7YbbWUw==", - "dev": true, - "requires": { - "jws": "^3.2.2", - "lodash": "^4.17.21", - "ms": "^2.1.1", - "semver": "^7.3.8" - }, - "dependencies": { - "semver": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz", - "integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - } - } - }, - "jsprim": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", - "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", - "dev": true, - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.4.0", - "verror": "1.10.0" - } - }, "jsx-ast-utils": { "version": "3.1.0", "integrity": "sha512-d4/UOjg+mxAWxCiF0c5UTSwyqbchkbqCvK87aBovhnh8GtysTjWmgC63tY0cJx/HzGgm9qnA147jVBdpOiQ2RA==", @@ -20509,9 +20607,9 @@ } }, "jszip": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.0.tgz", - "integrity": "sha512-LDfVtOLtOxb9RXkYOwPyNBTQDL4eUbqahtoY6x07GiDJHwSYvn8sHHIw8wINImV3MqbMNve2gSuM1DDqEKk09Q==", + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", + "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", "dev": true, "requires": { "lie": "~3.3.0", @@ -20520,27 +20618,6 @@ "setimmediate": "^1.0.5" } }, - "jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", - "dev": true, - "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", - "dev": true, - "requires": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - }, "keyv": { "version": "4.5.2", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.2.tgz", @@ -20910,12 +20987,6 @@ "dev": true, "optional": true }, - "nanoid": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", - "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", - "dev": true - }, "natural-compare": { "version": "1.4.0", "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", @@ -20953,9 +21024,9 @@ "dev": true }, "node-fetch": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.1.tgz", - "integrity": "sha512-cRVc/kyto/7E5shrWca1Wsea4y6tL9iYJE5FBCius3JQfb/4P4I295PfhgbJQBLTx6lATE4z+wK0rPM4VS2uow==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", "dev": true, "requires": { "data-uri-to-buffer": "^4.0.0", @@ -21001,9 +21072,9 @@ } }, "node-releases": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", - "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==", + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", "dev": true }, "normalize-path": { @@ -21042,12 +21113,6 @@ "integrity": "sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==", "dev": true }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true - }, "object-assign": { "version": "4.1.1", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", @@ -21120,9 +21185,9 @@ } }, "on-exit-leak-free": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.0.tgz", - "integrity": "sha512-VuCaZZAjReZ3vUwgOB8LxAosIurDiAW0s13rI1YwmaP++jvcxP77AWoQvenZebpCA2m8WC1/EosPYPMjnRAp/w==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz", + "integrity": "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==", "dev": true }, "once": { @@ -21143,13 +21208,14 @@ } }, "open": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", - "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/open/-/open-9.1.0.tgz", + "integrity": "sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg==", "dev": true, "requires": { - "define-lazy-prop": "^2.0.0", - "is-docker": "^2.1.1", + "default-browser": "^4.0.0", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", "is-wsl": "^2.2.0" } }, @@ -21283,6 +21349,12 @@ } } }, + "package-json-from-dist": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", + "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", + "dev": true + }, "pako": { "version": "1.0.10", "integrity": "sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw==", @@ -21351,19 +21423,25 @@ "dev": true }, "path-scurry": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.6.1.tgz", - "integrity": "sha512-OW+5s+7cw6253Q4E+8qQ/u1fVvcJQCJo/VFD8pje+dbJCF1n5ZRMV2AEHbGp+5Q7jxQIYJxkHopnj6nzdGeZLA==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", "dev": true, "requires": { - "lru-cache": "^7.14.1", - "minipass": "^4.0.2" + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "dependencies": { "lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + }, + "minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", "dev": true } } @@ -21378,15 +21456,10 @@ "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", "dev": true }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", - "dev": true - }, "picocolors": { - "version": "1.0.0", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", + "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==", "dev": true }, "picomatch": { @@ -21396,28 +21469,28 @@ "dev": true }, "pino": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/pino/-/pino-8.11.0.tgz", - "integrity": "sha512-Z2eKSvlrl2rH8p5eveNUnTdd4AjJk8tAsLkHYZQKGHP4WTh2Gi1cOSOs3eWPqaj+niS3gj4UkoreoaWgF3ZWYg==", + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/pino/-/pino-8.20.0.tgz", + "integrity": "sha512-uhIfMj5TVp+WynVASaVEJFTncTUe4dHBq6CWplu/vBgvGHhvBvQfxz+vcOrnnBQdORH3izaGEurLfNlq3YxdFQ==", "dev": true, "requires": { "atomic-sleep": "^1.0.0", "fast-redact": "^3.1.1", "on-exit-leak-free": "^2.1.0", - "pino-abstract-transport": "v1.0.0", + "pino-abstract-transport": "^1.1.0", "pino-std-serializers": "^6.0.0", - "process-warning": "^2.0.0", + "process-warning": "^3.0.0", "quick-format-unescaped": "^4.0.3", "real-require": "^0.2.0", "safe-stable-stringify": "^2.3.1", - "sonic-boom": "^3.1.0", + "sonic-boom": "^3.7.0", "thread-stream": "^2.0.0" } }, "pino-abstract-transport": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-1.0.0.tgz", - "integrity": "sha512-c7vo5OpW4wIS42hUVcT5REsL8ZljsUfBjqV/e2sFxmFEFZiq1XLUp5EYLtuDH6PEHq9W1egWqRbnLUP5FuZmOA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-1.2.0.tgz", + "integrity": "sha512-Guhh8EZfPCfH+PMXAb6rKOjGQEoy0xlAIn+irODG5kgfYV+BQ0rGYYWTIel3P5mmyXqkYkPmdIkywsn6QKUR1Q==", "dev": true, "requires": { "readable-stream": "^4.0.0", @@ -21425,23 +21498,24 @@ }, "dependencies": { "readable-stream": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.3.0.tgz", - "integrity": "sha512-MuEnA0lbSi7JS8XM+WNJlWZkHAAdm7gETHdFK//Q/mChGyj2akEFtdLZh32jSdkWGbRwCW9pn6g3LWDdDeZnBQ==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", + "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", "dev": true, "requires": { "abort-controller": "^3.0.0", "buffer": "^6.0.3", "events": "^3.3.0", - "process": "^0.11.10" + "process": "^0.11.10", + "string_decoder": "^1.3.0" } } } }, "pino-std-serializers": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-6.2.0.tgz", - "integrity": "sha512-IWgSzUL8X1w4BIWTwErRgtV8PyOGOOi60uqv0oKuS/fOA8Nco/OeI6lBuc4dyP8MMfdFwyHqTMcBIA7nDiqEqA==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-6.2.2.tgz", + "integrity": "sha512-cHjPPsE+vhj/tnhCy/wiMh3M3z3h/j15zHQX+S9GkTBgqJuTuJzYJ4gUyACLhDaJ7kk9ba9iRDmbH2tJU03OiA==", "dev": true }, "pirates": { @@ -21450,17 +21524,6 @@ "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", "dev": true }, - "postcss": { - "version": "8.4.21", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz", - "integrity": "sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==", - "dev": true, - "requires": { - "nanoid": "^3.3.4", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" - } - }, "prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", @@ -21504,9 +21567,9 @@ "dev": true }, "process-warning": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-2.2.0.tgz", - "integrity": "sha512-/1WZ8+VQjR6avWOgHeEPd7SDQmFQ1B5mC1eRXsCm5TarlNmx/wCsa5GEaxGm05BORRtyG/Ex/3xq3TuRvq57qg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-3.0.0.tgz", + "integrity": "sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ==", "dev": true }, "promise-toolbox": { @@ -21547,6 +21610,7 @@ }, "proxy-from-env": { "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", "dev": true }, @@ -21585,12 +21649,6 @@ "integrity": "sha512-rLSBxJjP+4DQOgcJAx6RZHT2he2pkhQdSnofG5VWyVl6GRq/K02ISOuOLcsMOrtKDIJb8JN2zm3FFzWNbezdPw==", "dev": true }, - "qs": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", - "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", - "dev": true - }, "querystringify": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", @@ -21726,9 +21784,9 @@ } }, "regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", "dev": true }, "regexp.prototype.flags": { @@ -21775,52 +21833,6 @@ "commander": "^2.6.0" } }, - "request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "dev": true, - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "dependencies": { - "tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dev": true, - "requires": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - } - }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "dev": true - } - } - }, "require-directory": { "version": "2.1.1", "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", @@ -21928,6 +21940,15 @@ } } }, + "run-applescript": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-5.0.0.tgz", + "integrity": "sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg==", + "dev": true, + "requires": { + "execa": "^5.0.0" + } + }, "run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -21979,9 +22000,9 @@ } }, "safe-stable-stringify": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz", - "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", + "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==", "dev": true }, "safer-buffer": { @@ -21991,9 +22012,9 @@ "dev": true }, "sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", + "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==", "dev": true }, "saxes": { @@ -22091,9 +22112,9 @@ } }, "serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "dev": true, "requires": { "randombytes": "^2.1.0" @@ -22162,24 +22183,6 @@ "object-inspect": "^1.9.0" } }, - "sign-addon": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/sign-addon/-/sign-addon-5.3.0.tgz", - "integrity": "sha512-7nHlCzhQgVMLBNiXVEgbG/raq48awOW0lYMN5uo1BaB3mp0+k8M8pvDwbfTlr3apcxZJsk9HQsAW1POwoJugpQ==", - "dev": true, - "requires": { - "common-tags": "1.8.2", - "core-js": "3.29.0", - "deepcopy": "2.1.0", - "es6-error": "4.1.1", - "es6-promisify": "7.0.0", - "jsonwebtoken": "9.0.0", - "mz": "2.7.0", - "request": "2.88.2", - "source-map-support": "0.5.21", - "stream-to-promise": "3.0.0" - } - }, "signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", @@ -22199,9 +22202,9 @@ "dev": true }, "sonic-boom": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-3.3.0.tgz", - "integrity": "sha512-LYxp34KlZ1a2Jb8ZQgFCK3niIHzibdwtwNUWKg0qQRzsDoJ3Gfgkf8KdBTFU3SkejDEIlWwnSnpVdOZIhFMl/g==", + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-3.8.1.tgz", + "integrity": "sha512-y4Z8LCDBuum+PBP3lSV7RHrXscqksve/bi0as7mhwVnBW+/wUqKT/2Kb7um8yqcFy0duYbbPxzt89Zy2nOCaxg==", "dev": true, "requires": { "atomic-sleep": "^1.0.0" @@ -22212,12 +22215,6 @@ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true }, - "source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", - "dev": true - }, "source-map-support": { "version": "0.5.21", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", @@ -22264,23 +22261,6 @@ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, - "sshpk": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", - "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", - "dev": true, - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - } - }, "stack-utils": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", @@ -22298,24 +22278,13 @@ } } }, - "stream-to-array": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/stream-to-array/-/stream-to-array-2.3.0.tgz", - "integrity": "sha512-UsZtOYEn4tWU2RGLOXr/o/xjRBftZRlG3dEWoaHr8j4GuypJ3isitGbVyjQKAuMu+xbiop8q224TjiZWc4XTZA==", - "dev": true, - "requires": { - "any-promise": "^1.1.0" - } - }, - "stream-to-promise": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/stream-to-promise/-/stream-to-promise-3.0.0.tgz", - "integrity": "sha512-h+7wLeFiYegOdgTfTxjRsrT7/Op7grnKEIHWgaO1RTHwcwk7xRreMr3S8XpDfDMesSxzgM2V4CxNCFAGo6ssnA==", + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "dev": true, "requires": { - "any-promise": "~1.3.0", - "end-of-stream": "~1.4.1", - "stream-to-array": "~2.3.0" + "safe-buffer": "~5.2.0" } }, "string-length": { @@ -22339,6 +22308,17 @@ "strip-ansi": "^6.0.1" } }, + "string-width-cjs": { + "version": "npm:[email protected]", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, "string.prototype.matchall": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz", @@ -22386,6 +22366,15 @@ "ansi-regex": "^5.0.1" } }, + "strip-ansi-cjs": { + "version": "npm:[email protected]", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, "strip-bom": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", @@ -22458,34 +22447,34 @@ } }, "terser": { - "version": "5.14.2", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.14.2.tgz", - "integrity": "sha512-oL0rGeM/WFQCUd0y2QrWxYnq7tfSuKBiqTjRPWrRgB46WD/kiwHwF8T23z78H6Q6kGCuuHcPB+KULHRdxvVGQA==", + "version": "5.31.6", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.6.tgz", + "integrity": "sha512-PQ4DAriWzKj+qgehQ7LK5bQqCFNMmlhjR2PFFLuqGCpuCAauxemVBWwWOxo3UIwWQx8+Pr61Df++r76wDmkQBg==", "dev": true, "requires": { - "@jridgewell/source-map": "^0.3.2", - "acorn": "^8.5.0", + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", "commander": "^2.20.0", "source-map-support": "~0.5.20" } }, "terser-webpack-plugin": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.1.tgz", - "integrity": "sha512-GvlZdT6wPQKbDNW/GDQzZFg/j4vKU96yl2q6mcUkzKOgW4gwf1Z8cZToUCrz31XHlPWH8MVb1r2tFtdDtTGJ7g==", + "version": "5.3.10", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", + "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", "dev": true, "requires": { + "@jridgewell/trace-mapping": "^0.3.20", "jest-worker": "^27.4.5", "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.0", - "source-map": "^0.6.1", - "terser": "^5.7.2" + "serialize-javascript": "^6.0.1", + "terser": "^5.26.0" }, "dependencies": { "schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "dev": true, "requires": { "@types/json-schema": "^7.0.8", @@ -22530,9 +22519,9 @@ } }, "thread-stream": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-2.3.0.tgz", - "integrity": "sha512-kaDqm1DET9pp3NXwR8382WHbnpXnRkN9xGN9dQt3B2+dmXiW8X1SOwmFOxAErEQ47ObhZ96J6yhZNXuyCOL7KA==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-2.7.0.tgz", + "integrity": "sha512-qQiRWsU/wvNolI6tbbCKd9iKaTnCXsTwVxhhKM6nctPdujTyztjlbUkUTUymidWcMnZ5pWR0ej4a0tjsW021vw==", "dev": true, "requires": { "real-require": "^0.2.0" @@ -22544,24 +22533,17 @@ "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", "dev": true }, + "titleize": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/titleize/-/titleize-3.0.0.tgz", + "integrity": "sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ==", + "dev": true + }, "tmp": { - "version": "0.2.1", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", - "dev": true, - "requires": { - "rimraf": "^3.0.0" - }, - "dependencies": { - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } - } + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", + "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", + "dev": true }, "tmpl": { "version": "1.0.5", @@ -22591,9 +22573,9 @@ "dev": true }, "tough-cookie": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.2.tgz", - "integrity": "sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", + "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", "dev": true, "requires": { "psl": "^1.1.33", @@ -22754,21 +22736,6 @@ "tslib": "^1.8.1" } }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "dev": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", - "dev": true - }, "type-check": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", @@ -22849,6 +22816,12 @@ "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", "dev": true }, + "untildify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", + "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", + "dev": true + }, "upath": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/upath/-/upath-2.0.1.tgz", @@ -22856,13 +22829,13 @@ "dev": true }, "update-browserslist-db": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", - "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", + "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", "dev": true, "requires": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" + "escalade": "^3.1.2", + "picocolors": "^1.0.1" } }, "update-notifier": { @@ -22905,8 +22878,9 @@ } }, "uri-js": { - "version": "4.2.2", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, "requires": { "punycode": "^2.1.0" @@ -22950,17 +22924,6 @@ "convert-source-map": "^1.6.0" } }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, "w3c-xmlserializer": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-3.0.0.tgz", @@ -22980,9 +22943,9 @@ } }, "watchpack": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", - "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", + "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==", "dev": true, "requires": { "glob-to-regexp": "^0.4.1", @@ -22999,55 +22962,73 @@ } }, "web-ext": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/web-ext/-/web-ext-7.6.2.tgz", - "integrity": "sha512-xlxbzgFBIS/UWWlvWxyR1PIqRRzDj1cutoHh+VZu4ZTcJTfv35KVdKkLRZv4PQwHu4dg8VfTg7WEcNP4QLaaFQ==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/web-ext/-/web-ext-8.2.0.tgz", + "integrity": "sha512-krU7rmxaG96b3Q9Enbry9/pmE/5FUGkvajCGfJCD+J79rt7JFjhVpw1Dszz4BqQkTd3y8cG5wJ3p1uC6uyAwcA==", "dev": true, "requires": { - "@babel/runtime": "7.21.0", - "@devicefarmer/adbkit": "3.2.3", - "addons-linter": "5.32.0", + "@babel/runtime": "7.24.7", + "@devicefarmer/adbkit": "3.2.6", + "addons-linter": "6.31.1", "bunyan": "1.8.15", - "camelcase": "7.0.1", + "camelcase": "8.0.0", "chrome-launcher": "0.15.1", "debounce": "1.2.1", "decamelize": "6.0.0", "es6-error": "4.1.1", - "firefox-profile": "4.3.2", - "fs-extra": "11.1.0", - "fx-runner": "1.3.0", - "import-fresh": "3.3.0", - "jose": "4.13.1", - "mkdirp": "1.0.4", + "firefox-profile": "4.6.0", + "fs-extra": "11.2.0", + "fx-runner": "1.4.0", + "https-proxy-agent": "^7.0.0", + "jose": "5.4.1", + "jszip": "3.10.1", + "mkdirp": "3.0.1", "multimatch": "6.0.0", "mz": "2.7.0", - "node-fetch": "3.3.1", + "node-fetch": "3.3.2", "node-notifier": "10.0.1", - "open": "8.4.2", - "parse-json": "6.0.2", + "open": "9.1.0", + "parse-json": "7.1.1", "promise-toolbox": "0.21.0", - "sign-addon": "5.3.0", "source-map-support": "0.5.21", "strip-bom": "5.0.0", - "strip-json-comments": "5.0.0", - "tmp": "0.2.1", + "strip-json-comments": "5.0.1", + "tmp": "0.2.3", "update-notifier": "6.0.2", - "watchpack": "2.4.0", - "ws": "8.13.0", - "yargs": "17.7.1", + "watchpack": "2.4.1", + "ws": "8.17.1", + "yargs": "17.7.2", "zip-dir": "2.0.0" }, "dependencies": { + "agent-base": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "dev": true, + "requires": { + "debug": "^4.3.4" + } + }, "camelcase": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-7.0.1.tgz", - "integrity": "sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-8.0.0.tgz", + "integrity": "sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==", "dev": true }, + "debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "requires": { + "ms": "^2.1.3" + } + }, "fs-extra": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.0.tgz", - "integrity": "sha512-0rcTq621PD5jM/e0a3EJoGC/1TC5ZBCERW82LQuwfGnCa1V8w7dpYH1yNu+SLb6E5dkeCBzKEyLGlFrnr+dUyw==", + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", "dev": true, "requires": { "graceful-fs": "^4.2.0", @@ -23055,27 +23036,51 @@ "universalify": "^2.0.0" } }, + "https-proxy-agent": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", + "dev": true, + "requires": { + "agent-base": "^7.0.2", + "debug": "4" + } + }, + "json-parse-even-better-errors": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.2.tgz", + "integrity": "sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==", + "dev": true + }, "lines-and-columns": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-2.0.3.tgz", - "integrity": "sha512-cNOjgCnLB+FnvWWtyRTzmB3POJ+cXxTA81LoW7u8JdmhfXzriropYwpjShnz1QLLWsQwY7nIxoDmcPTwphDK9w==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-2.0.4.tgz", + "integrity": "sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A==", "dev": true }, "mkdirp": { - "version": "1.0.4", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "dev": true + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, "parse-json": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-6.0.2.tgz", - "integrity": "sha512-SA5aMiaIjXkAiBrW/yPgLgQAQg42f7K3ACO+2l/zOvtQBwX58DMUsFJXelW2fx3yMBmWOVkR6j1MGsdSbCA4UA==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-7.1.1.tgz", + "integrity": "sha512-SgOTCX/EZXtZxBE5eJ97P4yGM5n37BwRU+YMsH4vNzFqJV/oWFXXCmwFlgWUM4PrakybVOueJJ6pwHqSVhTFDw==", "dev": true, "requires": { - "@babel/code-frame": "^7.16.0", + "@babel/code-frame": "^7.21.4", "error-ex": "^1.3.2", - "json-parse-even-better-errors": "^2.3.1", - "lines-and-columns": "^2.0.2" + "json-parse-even-better-errors": "^3.0.0", + "lines-and-columns": "^2.0.3", + "type-fest": "^3.8.0" } }, "strip-bom": { @@ -23085,17 +23090,23 @@ "dev": true }, "strip-json-comments": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-5.0.0.tgz", - "integrity": "sha512-V1LGY4UUo0jgwC+ELQ2BNWfPa17TIuwBLg+j1AA/9RPzKINl1lhxVEu2r+ZTTO8aetIsUzE5Qj6LMSBkoGYKKw==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-5.0.1.tgz", + "integrity": "sha512-0fk9zBqO67Nq5M/m45qHCJxylV/DhBlIOVExqgOMiCCrzrhU6tCibRXNqE3jwJLftzE9SNuZtYbpzcO+i9FiKw==", + "dev": true + }, + "type-fest": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.1.tgz", + "integrity": "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==", "dev": true } } }, "web-streams-polyfill": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz", - "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", "dev": true }, "webext-content-scripts": { @@ -23134,48 +23145,46 @@ "dev": true }, "webpack": { - "version": "5.75.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.75.0.tgz", - "integrity": "sha512-piaIaoVJlqMsPtX/+3KTTO6jfvrSYgauFVdt8cr9LTHKmcq/AMd4mhzsiP7ZF/PGRNPGA8336jldh9l2Kt2ogQ==", + "version": "5.94.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.94.0.tgz", + "integrity": "sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg==", "dev": true, "requires": { - "@types/eslint-scope": "^3.7.3", - "@types/estree": "^0.0.51", - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/wasm-edit": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", + "@types/estree": "^1.0.5", + "@webassemblyjs/ast": "^1.12.1", + "@webassemblyjs/wasm-edit": "^1.12.1", + "@webassemblyjs/wasm-parser": "^1.12.1", "acorn": "^8.7.1", - "acorn-import-assertions": "^1.7.6", - "browserslist": "^4.14.5", + "acorn-import-attributes": "^1.9.5", + "browserslist": "^4.21.10", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.10.0", - "es-module-lexer": "^0.9.0", + "enhanced-resolve": "^5.17.1", + "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.9", + "graceful-fs": "^4.2.11", "json-parse-even-better-errors": "^2.3.1", "loader-runner": "^4.2.0", "mime-types": "^2.1.27", "neo-async": "^2.6.2", - "schema-utils": "^3.1.0", + "schema-utils": "^3.2.0", "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.1.3", - "watchpack": "^2.4.0", + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.1", "webpack-sources": "^3.2.3" }, "dependencies": { - "acorn-import-assertions": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", - "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==", - "dev": true, - "requires": {} + "graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true }, "schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "dev": true, "requires": { "@types/json-schema": "^7.0.8", @@ -23394,6 +23403,43 @@ } } }, + "wrap-ansi-cjs": { + "version": "npm:[email protected]", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + } + } + }, "wrappy": { "version": "1.0.2", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", @@ -23412,9 +23458,9 @@ } }, "ws": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", - "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", "dev": true, "requires": {} }, @@ -23471,9 +23517,9 @@ "dev": true }, "yargs": { - "version": "17.7.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", - "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==", + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, "requires": { "cliui": "^8.0.1", diff --git a/package.json b/package.json index 1c4f20e2..c1f47910 100644 --- a/package.json +++ b/package.json @@ -38,14 +38,14 @@ "ts-loader": "^9.4.2", "ts-node": "^10.9.1", "typescript": "4.9", - "web-ext": "^7.6.2", - "webpack": "^5.75.0", + "web-ext": "^8.2.0", + "webpack": "^5.94.0", "webpack-cli": "^4.10.0", "webpack-merge": "^5.8.0" }, "scripts": { "web-run": "npm run web-run:chrome", - "web-sign": "web-ext sign -s dist", + "web-sign": "web-ext sign --channel unlisted -s dist", "web-run:firefox": "cd dist && web-ext run --start-url https://addons.mozilla.org/firefox/addon/ublock-origin/", "web-run:firefox-android": "cd dist && web-ext run -t firefox-android --firefox-apk org.mozilla.fenix", "web-run:chrome": "cd dist && web-ext run --start-url https://chrome.google.com/webstore/detail/ublock-origin/cjpalhdlnbpafiamejdnhcphjbkeiagm -t chromium", @@ -96,6 +96,6 @@ "url": "git+https://github.com/ajayyy/SponsorBlock.git" }, "author": "Ajay Ramachandran", - "license": "LGPL-3.0-or-later", + "license": "GPL-3.0", "private": true } diff --git a/public/_locales b/public/_locales -Subproject 81f5afdd156aa04e43fdef26e179f5784a12bb3 +Subproject 3c5a80ca9cc600c7c03b8d513cd80df8aa17b24 diff --git a/public/content.css b/public/content.css index 39051417..db095af0 100644 --- a/public/content.css +++ b/public/content.css @@ -26,6 +26,11 @@ transition: transform .1s cubic-bezier(0,0,0.2,1); } +/* May 2024 hover preview */ +.YtPlayerProgressBarProgressBar #previewbar { + transform: none; +} + .ytp-big-mode #previewbar { transform: scaleY(0.625) translateY(-30%) translateY(1.5px); } @@ -320,11 +325,6 @@ div:hover > .sponsorBlockChapterBar { padding-bottom: 7.8%; } -/* if two are very close to eachother */ -.secondSkipNotice { - bottom: 290px; -} - .noticeLeftIcon { display: flex; align-items: center; @@ -742,6 +742,7 @@ input::-webkit-inner-spin-button { color: white; font-size: 12px; z-index: 10000; + font-weight: normal; } .sponsorBlockTooltip a { @@ -764,6 +765,12 @@ input::-webkit-inner-spin-button { right: 50%; } +.sponsorBlockTooltip.sbTriangle.sbTopTriangle::after { + bottom: 100%; + top: unset; + border-color: transparent transparent rgba(28, 28, 28, 0.7) transparent; +} + .sponsorBlockLockedColor { color: #ffc83d !important; } @@ -778,6 +785,18 @@ input::-webkit-inner-spin-button { line-height: 1.5em; } +/* Description on right layout */ +#title > #categoryPillParent { + font-size: 2rem; + font-weight: bold; + display: flex; + justify-content: center; + line-height: 2.8rem; +} +#title > #categoryPillParent > #categoryPill.cbPillOpen { + margin-bottom: 5px; +} + #categoryPillParent { height: fit-content; margin-top: auto; diff --git a/public/help/index.html b/public/help/index.html index f3ac8212..d2e848f4 100644 --- a/public/help/index.html +++ b/public/help/index.html @@ -34,6 +34,20 @@ Come contribute, make some suggestions and help out on <a href="https://discord.gg/SponsorBlock">Discord</a> or on <a href="https://matrix.to/#/#sponsor:ajay.app?via=ajay.app&via=matrix.org&via=mozilla.org">Matrix</a>. </p> + <a href="https://dearrow.ajay.app" + target="_blank" + id="dearrow-link" + class="dearrow-link hidden" + rel="noreferrer"> + <img src="/icons/dearrow.svg"/> + + <span id="dearrow-link-text"> + + </span> + + <img src="/icons/close.png" class="close-button"/> + </a> + <p style="margin-bottom: 0; margin-top: 0" class="bigText center">__MSG_helpPageReviewOptions__</p> <p class="smallText"> diff --git a/public/help/styles.css b/public/help/styles.css index 99ff809d..9c4720d0 100644 --- a/public/help/styles.css +++ b/public/help/styles.css @@ -322,4 +322,33 @@ svg { cursor: default; background-color: var(--disabled); color: grey; +} + +.dearrow-link { + display: flex; + align-items: center; + justify-content: center; + text-decoration: none; + + font-size: 16px; +} + +.dearrow-link img { + width: 35px; + padding: 10px +} + +.dearrow-link .close-button { + opacity: 0; + width: 15px; + filter: invert(0.3); + transition: opacity 0.2s; +} + +.dearrow-link:hover .close-button { + opacity: 1; +} + +.hidden { + display: none; }
\ No newline at end of file diff --git a/public/options/options.css b/public/options/options.css index 4ff811de..13cad69d 100644 --- a/public/options/options.css +++ b/public/options/options.css @@ -717,4 +717,16 @@ svg { .dearrow-link > img { width: 40px; margin-right: 4px; +} + +.dearrow-link .close-button { + opacity: 0; + width: 15px; + filter: invert(0.3); + transition: opacity 0.2s; + margin-left: 10px; +} + +.dearrow-link:hover .close-button { + opacity: 1; }
\ No newline at end of file diff --git a/public/options/options.html b/public/options/options.html index 5e9f32de..b9258f33 100644 --- a/public/options/options.html +++ b/public/options/options.html @@ -75,6 +75,8 @@ <span class="promotion-description"> __MSG_DeArrowPromotionMessage__ </span> + + <img src="/icons/close.png" class="close-button"/> </a> </div> @@ -217,20 +219,22 @@ __MSG_showSkipNotice__ </label> </div> - </div> - - <div data-type="selector" data-sync="noticeVisibilityMode"> - <label class="optionLabel" for="noticeVisibilityMode">__MSG_noticeVisibilityLabel__:</label> - <select id="noticeVisibilityMode" class="selector-element optionsSelector" > - <option value="0">__MSG_noticeVisibilityMode0__</option> - <option value="1">__MSG_noticeVisibilityMode1__</option> - <option value="2">__MSG_noticeVisibilityMode2__</option> - <option value="3">__MSG_noticeVisibilityMode3__</option> - <option value="4">__MSG_noticeVisibilityMode4__</option> - </select> + <div data-type="selector" data-sync="noticeVisibilityMode" data-dependent-on="dontShowNotice"> + <br/> + + <label class="optionLabel" for="noticeVisibilityMode">__MSG_noticeVisibilityLabel__:</label> + + <select id="noticeVisibilityMode" class="selector-element optionsSelector" > + <option value="0">__MSG_noticeVisibilityMode0__</option> + <option value="1">__MSG_noticeVisibilityMode1__</option> + <option value="2">__MSG_noticeVisibilityMode2__</option> + <option value="3">__MSG_noticeVisibilityMode3__</option> + <option value="4">__MSG_noticeVisibilityMode4__</option> + </select> + </div> </div> - + <div data-type="toggle" data-sync="showCategoryGuidelines"> <div class="switch-container"> <label class="switch"> @@ -357,6 +361,18 @@ <div class="small-description">__MSG_showTimeWithSkipsDescription__</div> </div> + <div data-type="toggle" data-sync="cleanPopup" data-no-safari="true"> + <div class="switch-container"> + <label class="switch"> + <input id="cleanPopup" type="checkbox" checked> + <span class="slider round"></span> + </label> + <label class="switch-label" for="cleanPopup"> + __MSG_cleanPopup__ + </label> + </div> + </div> + <div data-type="toggle" data-sync="darkMode"> <div class="switch-container"> <label class="switch"> @@ -419,12 +435,27 @@ <div class="inline"></div> </div> + <div data-type="keybind-change" data-sync="closeSkipNoticeKeybind"> + <label class="optionLabel">__MSG_setCloseSkipNoticeKeybind__:</label> + <div class="inline"></div> + </div> + <div data-type="keybind-change" data-sync="startSponsorKeybind"> <label class="optionLabel">__MSG_setStartSponsorShortcut__:</label> <div class="inline"></div> </div> <div data-type="keybind-change" data-sync="submitKeybind"> + <label class="optionLabel">__MSG_setOpenSubmissionMenuKeybind__:</label> + <div class="inline"></div> + </div> + + <div data-type="keybind-change" data-sync="previewKeybind"> + <label class="optionLabel">__MSG_setPreviewKeybind__:</label> + <div class="inline"></div> + </div> + + <div data-type="keybind-change" data-sync="actuallySubmitKeybind"> <label class="optionLabel">__MSG_setSubmitKeybind__:</label> <div class="inline"></div> </div> @@ -488,6 +519,31 @@ </div> </div> + <div data-type="private-text-change" data-sync-type="local" data-sync="*" data-confirm-message="exportOptionsWarning"> + <h2>__MSG_exportOtherData__</h2> + + <div> + <div class="option-button trigger-button inline"> + __MSG_exportOptionsCopy__ + </div> + <div class="option-button download-button inline"> + __MSG_exportOptionsDownload__ + </div> + <label for="importLocalOptions" class="option-button inline"> + __MSG_exportOptionsUpload__ + </label> + <input id="importLocalOptions" type="file" class="upload-button hidden" /> + </div> + + <div class="option-hidden-section hidden spacing indent"> + <textarea class="option-text-box" rows="10" style="width:80%"></textarea> + + <div class="option-button text-change-set"> + __MSG_setOptions__ + </div> + </div> + </div> + <div data-type="button-press" data-sync="resetToDefault" data-confirm-message="confirmResetToDefault"> <div class="option-button trigger-button"> __MSG_resetToDefault__ @@ -580,7 +636,19 @@ <div class="small-description">__MSG_whatTrackDownvotes__</div> </div> - + + <div data-type="toggle" data-sync="trackDownvotesInPrivate" data-confirm-on="false"> + <div class="switch-container"> + <label class="switch"> + <input id="trackDownvotesInPrivate" type="checkbox" checked> + <span class="slider round"></span> + </label> + <label class="switch-label" for="trackDownvotesInPrivate"> + __MSG_enableTrackDownvotesInPrivate__ + </label> + </div> + </div> + <div data-type="button-press" data-sync="copyDebugInformation" data-confirm-message="copyDebugInformation"> <div class="option-button trigger-button"> __MSG_copyDebugInformation__ diff --git a/public/popup.css b/public/popup.css index cd954c06..13d533fc 100644 --- a/public/popup.css +++ b/public/popup.css @@ -130,6 +130,7 @@ top: 5px; right: 5px; opacity: 0.5; + z-index: 1; } .sbCloseButton:hover { diff --git a/public/popup.html b/public/popup.html index e628cd20..2b5034f7 100644 --- a/public/popup.html +++ b/public/popup.html @@ -20,7 +20,7 @@ __MSG_betaServerWarning__ </div> - <header class="sbPopupLogo"> + <header id="sbPopupLogo" class="sbPopupLogo"> <img src="icons/IconSponsorBlocker256px.png" alt="SponsorBlock" width="40" height="40" id="sponsorBlockPopupLogo"> <p class="u-mZ">SponsorBlock</p> </header> @@ -111,7 +111,7 @@ </div> <!-- Your Work box --> - <div class="sbYourWorkBox"> + <div id="sbYourWorkBox" class="sbYourWorkBox"> <h1 class="sbHeader" style="padding: 8px 15px;"> __MSG_yourWork__ </h1> @@ -196,6 +196,8 @@ <a href="https://discord.gg/SponsorBlock" target="_blank" rel="noopener">Discord</a> <a href="https://matrix.to/#/#sponsor:ajay.app?via=ajay.app&via=matrix.org&via=mozilla.org" target="_blank" rel="noopener">Matrix</a> <a href="https://sponsor.ajay.app/donate" target="_blank" rel="noopener" id="sbDonate">__MSG_Donate__</a> + <br /> + <a id="debugLogs">__MSG_copyDebugLogs__</a> </footer> <button id="showNoticeAgain" style="display: none">__MSG_showNotice__</button> diff --git a/public/shared.css b/public/shared.css index 005d3500..5fd1c9d2 100644 --- a/public/shared.css +++ b/public/shared.css @@ -14,7 +14,7 @@ } .sponsorSkipNoticeParent { - min-width: 375px; + min-width: 390px; max-width: 50%; } diff --git a/src/background.ts b/src/background.ts index d7d95819..a5a70219 100644 --- a/src/background.ts +++ b/src/background.ts @@ -7,13 +7,9 @@ import { sendRealRequestToCustomServer, setupBackgroundRequestProxy } from "../m import { setupTabUpdates } from "../maze-utils/src/tab-updates"; import { generateUserID } from "../maze-utils/src/setup"; -// Make the config public for debugging purposes - -window.SB = Config; - import Utils from "./utils"; import { getExtensionIdsToImportFrom } from "./utils/crossExtension"; -import { isFirefoxOrSafari } from "../maze-utils/src"; +import { isFirefoxOrSafari, waitFor } from "../maze-utils/src"; import { injectUpdatedScripts } from "../maze-utils/src/cleanup"; import { logWarn } from "./utils/logger"; import { chromeP } from "../maze-utils/src/browserApi"; @@ -121,14 +117,15 @@ chrome.runtime.onInstalled.addListener(function () { const userID = Config.config.userID; // If there is no userID, then it is the first install. - if (!userID){ + if (!userID && !Config.local.alreadyInstalled){ //open up the install page - chrome.tabs.create({url: chrome.extension.getURL("/help/index.html")}); + chrome.tabs.create({url: chrome.runtime.getURL("/help/index.html")}); //generate a userID const newUserID = generateUserID(); //save this UUID Config.config.userID = newUserID; + Config.local.alreadyInstalled = true; // Don't show update notification Config.config.categoryPillUpdate = true; @@ -136,14 +133,21 @@ chrome.runtime.onInstalled.addListener(function () { if (Config.config.supportInvidious) { if (!(await utils.containsInvidiousPermission())) { - chrome.tabs.create({url: chrome.extension.getURL("/permissions/index.html")}); + chrome.tabs.create({url: chrome.runtime.getURL("/permissions/index.html")}); } } }, 1500); - // Only do this once the old version understands how to clean itself up - if (!isFirefoxOrSafari() && chrome.runtime.getManifest().version !== "5.4.13") { + if (!isFirefoxOrSafari()) { injectUpdatedScripts().catch(logWarn); + + waitFor(() => Config.isReady()).then(() => { + if (Config.config.supportInvidious) { + injectUpdatedScripts([ + utils.getExtraSiteRegistration() + ]) + } + }).catch(logWarn); } }); @@ -159,8 +163,8 @@ async function registerFirefoxContentScript(options: Registration) { ids: [options.id] }).catch(() => []); - if (existingRegistrations.length > 0 - && existingRegistrations[0].matches.every((match) => options.matches.includes(match))) { + if (existingRegistrations && existingRegistrations.length > 0 + && options.matches.every((match) => existingRegistrations[0].matches.includes(match))) { // No need to register another script, already registered return; } @@ -221,27 +225,35 @@ async function submitVote(type: number, UUID: string, category: string) { const typeSection = (type !== undefined) ? "&type=" + type : "&category=" + category; - //publish this vote - const response = await asyncRequestToServer("POST", "/api/voteOnSponsorTime?UUID=" + UUID + "&userID=" + userID + typeSection); - - if (response.ok) { - return { - successType: 1, - responseText: await response.text() - }; - } else if (response.status == 405) { - //duplicate vote - return { - successType: 0, - statusCode: response.status, - responseText: await response.text() - }; - } else { - //error while connect + try { + const response = await asyncRequestToServer("POST", "/api/voteOnSponsorTime?UUID=" + UUID + "&userID=" + userID + typeSection); + + if (response.ok) { + return { + successType: 1, + responseText: await response.text() + }; + } else if (response.status == 405) { + //duplicate vote + return { + successType: 0, + statusCode: response.status, + responseText: await response.text() + }; + } else { + //error while connect + return { + successType: -1, + statusCode: response.status, + responseText: await response.text() + }; + } + } catch (e) { + console.error(e); return { successType: -1, - statusCode: response.status, - responseText: await response.text() + statusCode: -1, + responseText: "" }; } } diff --git a/src/components/CategoryPillComponent.tsx b/src/components/CategoryPillComponent.tsx index 1d39a400..e4c5a3ed 100644 --- a/src/components/CategoryPillComponent.tsx +++ b/src/components/CategoryPillComponent.tsx @@ -6,7 +6,7 @@ import ThumbsUpSvg from "../svg-icons/thumbs_up_svg"; import ThumbsDownSvg from "../svg-icons/thumbs_down_svg"; import { downvoteButtonColor, SkipNoticeAction } from "../utils/noticeUtils"; import { VoteResponse } from "../messageTypes"; -import { AnimationUtils } from "../utils/animationUtils"; +import { AnimationUtils } from "../../maze-utils/src/animationUtils"; import { Tooltip } from "../render/Tooltip"; import { getErrorMessage } from "../../maze-utils/src/formating"; @@ -23,12 +23,14 @@ export interface CategoryPillState { } class CategoryPillComponent extends React.Component<CategoryPillProps, CategoryPillState> { - + mainRef: React.MutableRefObject<HTMLSpanElement>; tooltip?: Tooltip; constructor(props: CategoryPillProps) { super(props); + this.mainRef = React.createRef(); + this.state = { segment: null, show: false, @@ -43,17 +45,21 @@ class CategoryPillComponent extends React.Component<CategoryPillProps, CategoryP color: this.getTextColor(), } + // To be able to remove the margin from the parent + this.mainRef?.current?.parentElement?.classList?.toggle("cbPillOpen", this.state.show); + return ( <span style={style} className={"sponsorBlockCategoryPill" + (!this.props.showTextByDefault ? " sbPillNoText" : "")} aria-label={this.getTitleText()} onClick={(e) => this.toggleOpen(e)} onMouseEnter={() => this.openTooltip()} - onMouseLeave={() => this.closeTooltip()}> + onMouseLeave={() => this.closeTooltip()} + ref={this.mainRef}> <span className="sponsorBlockCategoryPillTitleSection"> <img className="sponsorSkipLogo sponsorSkipObject" - src={chrome.extension.getURL("icons/IconSponsorBlocker256px.png")}> + src={chrome.runtime.getURL("icons/IconSponsorBlocker256px.png")}> </img> { @@ -86,7 +92,7 @@ class CategoryPillComponent extends React.Component<CategoryPillProps, CategoryP )} {/* Close Button */} - <img src={chrome.extension.getURL("icons/close.png")} + <img src={chrome.runtime.getURL("icons/close.png")} className="categoryPillClose" onClick={() => { this.setState({ show: false }); diff --git a/src/components/ChapterVoteComponent.tsx b/src/components/ChapterVoteComponent.tsx index d50878a6..677a966d 100644 --- a/src/components/ChapterVoteComponent.tsx +++ b/src/components/ChapterVoteComponent.tsx @@ -6,7 +6,7 @@ import ThumbsUpSvg from "../svg-icons/thumbs_up_svg"; import ThumbsDownSvg from "../svg-icons/thumbs_down_svg"; import { downvoteButtonColor, SkipNoticeAction } from "../utils/noticeUtils"; import { VoteResponse } from "../messageTypes"; -import { AnimationUtils } from "../utils/animationUtils"; +import { AnimationUtils } from "../../maze-utils/src/animationUtils"; import { Tooltip } from "../render/Tooltip"; import { getErrorMessage } from "../../maze-utils/src/formating"; diff --git a/src/components/NoticeComponent.tsx b/src/components/NoticeComponent.tsx index 0e3526d1..56a96378 100644 --- a/src/components/NoticeComponent.tsx +++ b/src/components/NoticeComponent.tsx @@ -41,6 +41,13 @@ export interface NoticeProps { children?: React.ReactNode; } +interface MouseDownInfo { + x: number; + y: number; + right: number; + bottom: number; +} + export interface NoticeState { maxCountdownTime: () => number; @@ -50,8 +57,16 @@ export interface NoticeState { mouseHovering: boolean; startFaded: boolean; + + mouseDownInfo: MouseDownInfo | null; + mouseMoved: boolean; + right: number; + bottom: number; } +// Limits for dragging notice around +const bounds = [10, 100, 10, 10]; + class NoticeComponent extends React.Component<NoticeProps, NoticeState> { countdownInterval: NodeJS.Timeout; @@ -61,6 +76,8 @@ class NoticeComponent extends React.Component<NoticeProps, NoticeState> { parentRef: React.RefObject<HTMLDivElement>; + handleMouseMoveBinded: (e: MouseEvent) => void = this.handleMouseMove.bind(this); + constructor(props: NoticeProps) { super(props); @@ -87,7 +104,12 @@ class NoticeComponent extends React.Component<NoticeProps, NoticeState> { countdownMode: CountdownMode.Timer, mouseHovering: false, - startFaded: this.props.startFaded ?? false + startFaded: this.props.startFaded ?? false, + + mouseDownInfo: null, + mouseMoved: false, + right: bounds[0], + bottom: props.showInSecondSlot ? 290 : bounds[1] } } @@ -98,6 +120,9 @@ class NoticeComponent extends React.Component<NoticeProps, NoticeState> { render(): React.ReactElement { const noticeStyle: React.CSSProperties = { zIndex: this.props.zIndex || (1000 + this.amountOfPreviousNotices), + right: this.state.right, + bottom: this.state.bottom, + userSelect: this.state.mouseDownInfo && this.state.mouseMoved ? "none" : "auto", ...(this.props.style ?? {}) } @@ -107,7 +132,29 @@ class NoticeComponent extends React.Component<NoticeProps, NoticeState> { + (this.props.showInSecondSlot ? " secondSkipNotice" : "") + (this.props.extraClass ? ` ${this.props.extraClass}` : "")} onMouseEnter={(e) => this.onMouseEnter(e) } - onMouseLeave={() => this.timerMouseLeave()} + onMouseLeave={() => { + this.timerMouseLeave(); + }} + onMouseDown={(e) => { + document.addEventListener("mousemove", this.handleMouseMoveBinded); + + this.setState({ + mouseDownInfo: { + x: e.clientX, + y: e.clientY, + right: this.state.right, + bottom: this.state.bottom + }, + mouseMoved: false + }); + }} + onMouseUp={() => { + document.removeEventListener("mousemove", this.handleMouseMoveBinded); + + this.setState({ + mouseDownInfo: null + }); + }} ref={this.parentRef} style={noticeStyle} > <div className={"sponsorSkipNoticeTableContainer" @@ -160,7 +207,7 @@ class NoticeComponent extends React.Component<NoticeProps, NoticeState> { {/* Close button */} - <img src={chrome.extension.getURL("icons/close.png")} + <img src={chrome.runtime.getURL("icons/close.png")} className={"sponsorSkipObject sponsorSkipNoticeButton sponsorSkipNoticeCloseButton sponsorSkipNoticeRightButton" + (this.props.biggerCloseButton ? " biggerCloseButton" : "")} onClick={() => this.close()}> @@ -395,6 +442,31 @@ class NoticeComponent extends React.Component<NoticeProps, NoticeState> { getElement(): React.RefObject<HTMLDivElement> { return this.parentRef; } + + componentWillUnmount(): void { + document.removeEventListener("mousemove", this.handleMouseMoveBinded); + } + + // For dragging around notice + handleMouseMove(e: MouseEvent): void { + if (this.state.mouseDownInfo && e.buttons === 1) { + const [mouseX, mouseY] = [e.clientX, e.clientY]; + + const deltaX = mouseX - this.state.mouseDownInfo.x; + const deltaY = mouseY - this.state.mouseDownInfo.y; + + if (deltaX > 0 || deltaY > 0) this.setState({ mouseMoved: true }); + + const element = this.parentRef.current; + const parent = element.parentElement.parentElement; + this.setState({ + right: Math.min(parent.clientWidth - element.clientWidth - bounds[2], Math.max(bounds[0], this.state.mouseDownInfo.right - deltaX)), + bottom: Math.min(parent.clientHeight - element.clientHeight - bounds[3], Math.max(bounds[1], this.state.mouseDownInfo.bottom - deltaY)) + }); + } else { + document.removeEventListener("mousemove", this.handleMouseMoveBinded); + } + } } export default NoticeComponent; diff --git a/src/components/SkipNoticeComponent.tsx b/src/components/SkipNoticeComponent.tsx index d03e135e..32270f9c 100644 --- a/src/components/SkipNoticeComponent.tsx +++ b/src/components/SkipNoticeComponent.tsx @@ -14,6 +14,8 @@ import PencilSvg from "../svg-icons/pencil_svg"; import { downvoteButtonColor, SkipNoticeAction } from "../utils/noticeUtils"; import { generateUserID } from "../../maze-utils/src/setup"; import { keybindToString } from "../../maze-utils/src/config"; +import { getFormattedTime } from "../../maze-utils/src/formating"; +import { getCurrentTime, getVideo } from "../../maze-utils/src/video"; enum SkipButtonState { Undo, // Unskip @@ -316,6 +318,7 @@ class SkipNoticeComponent extends React.Component<SkipNoticeProps, SkipNoticeSta <select id={"sponsorTimeCategories" + this.idSuffix} className="sponsorTimeCategories sponsorTimeEditSelector" defaultValue={this.segments[0].category} + onMouseDown={(e) => e.stopPropagation()} ref={this.categoryOptionRef}> {this.getCategoryOptions()} @@ -386,8 +389,10 @@ class SkipNoticeComponent extends React.Component<SkipNoticeProps, SkipNoticeSta style={{opacity: this.getSubmissionChooserOpacity(i), color: this.getSubmissionChooserColor(i)}} onClick={() => this.performAction(i)} + autoFocus={i == 0} key={"submission" + i + this.segments[i].category + this.idSuffix}> - {(i + 1) + ". " + chrome.i18n.getMessage("category_" + this.segments[i].category)} + {`${(i + 1)}. ${chrome.i18n.getMessage("category_" + + this.segments[i].category)} (${getFormattedTime(this.segments[i].segment[0])})`} </button> ); } @@ -456,6 +461,15 @@ class SkipNoticeComponent extends React.Component<SkipNoticeProps, SkipNoticeSta if (this.segments.length === 1) { this.performAction(0, action); } else { + if (this.state.smaller) { + this.setState({ + smaller: false + }); + + this.noticeRef.current.fadedMouseEnter(); + this.noticeRef.current.resetCountdown(); + } + switch (action ?? this.state.actionState) { case SkipNoticeAction.None: this.resetStateToStart(); @@ -550,10 +564,10 @@ class SkipNoticeComponent extends React.Component<SkipNoticeProps, SkipNoticeSta source: SponsorSourceType.Local }; - const segmentTimes = Config.config.unsubmittedSegments[sponsorVideoID] || []; + const segmentTimes = Config.local.unsubmittedSegments[sponsorVideoID] || []; segmentTimes.push(sponsorTimesSubmitting); - Config.config.unsubmittedSegments[sponsorVideoID] = segmentTimes; - Config.forceSyncUpdate("unsubmittedSegments"); + Config.local.unsubmittedSegments[sponsorVideoID] = segmentTimes; + Config.forceLocalUpdate("unsubmittedSegments"); this.props.contentContainer().sponsorTimesSubmitting.push(sponsorTimesSubmitting); this.props.contentContainer().updatePreviewBar(); @@ -672,7 +686,7 @@ class SkipNoticeComponent extends React.Component<SkipNoticeProps, SkipNoticeSta getFullDurationCountdown(index: number): () => number { return () => { const sponsorTime = this.segments[index]; - const duration = Math.round((sponsorTime.segment[1] - this.contentContainer().v.currentTime) * (1 / this.contentContainer().v.playbackRate)); + const duration = Math.round((sponsorTime.segment[1] - getCurrentTime()) * (1 / getVideo().playbackRate)); return Math.max(duration, Config.config.skipNoticeDuration); }; diff --git a/src/components/SponsorTimeEditComponent.tsx b/src/components/SponsorTimeEditComponent.tsx index 22e10d42..d77ea6eb 100644 --- a/src/components/SponsorTimeEditComponent.tsx +++ b/src/components/SponsorTimeEditComponent.tsx @@ -2,14 +2,14 @@ import * as React from "react"; import * as CompileConfig from "../../config.json"; import Config from "../config"; import { ActionType, Category, ChannelIDStatus, ContentContainer, SponsorTime } from "../types"; -import Utils from "../utils"; import SubmissionNoticeComponent from "./SubmissionNoticeComponent"; import { RectangleTooltip } from "../render/RectangleTooltip"; import SelectorComponent, { SelectorOption } from "./SelectorComponent"; import { DEFAULT_CATEGORY } from "../utils/categoryUtils"; import { getFormattedTime, getFormattedTimeToSeconds } from "../../maze-utils/src/formating"; - -const utils = new Utils(); +import { asyncRequestToServer } from "../utils/requests"; +import { defaultPreviewTime } from "../utils/constants"; +import { getVideo, getVideoDuration } from "../../maze-utils/src/video"; export interface SponsorTimeEditProps { index: number; @@ -28,13 +28,14 @@ export interface SponsorTimeEditState { editing: boolean; sponsorTimeEdits: [string, string]; selectedCategory: Category; + selectedActionType: ActionType; description: string; suggestedNames: SelectorOption[]; chapterNameSelectorOpen: boolean; chapterNameSelectorHovering: boolean; } -const categoryNamesGrams: string[] = [].concat(...CompileConfig.categoryList.filter((name) => name !== "chapter") +const categoryNamesGrams: string[] = [].concat(...CompileConfig.categoryList.filter((name) => !["chapter", "intro"].includes(name)) .map((name) => chrome.i18n.getMessage("category_" + name).split(/\/|\s|-/))); class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, SponsorTimeEditState> { @@ -70,7 +71,8 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo this.state = { editing: false, sponsorTimeEdits: [null, null], - selectedCategory: DEFAULT_CATEGORY as Category, + selectedCategory: sponsorTime.category ?? DEFAULT_CATEGORY as Category, + selectedActionType: sponsorTime.actionType, description: sponsorTime.description || "", suggestedNames: [], chapterNameSelectorOpen: false, @@ -80,13 +82,15 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo componentDidMount(): void { // Prevent inputs from triggering key events - document.getElementById("sponsorTimeEditContainer" + this.idSuffix).addEventListener('keydown', function (event) { - event.stopPropagation(); + document.getElementById("sponsorTimeEditContainer" + this.idSuffix).addEventListener('keydown', (e) => { + e.stopPropagation(); }); // Prevent scrolling while changing times - document.getElementById("sponsorTimesContainer" + this.idSuffix).addEventListener('wheel', function (event) { - event.preventDefault(); + document.getElementById("sponsorTimesContainer" + this.idSuffix).addEventListener('wheel', (e) => { + if (this.state.editing) { + e.preventDefault(); + } }, {passive: false}); // Add as a config listener @@ -121,14 +125,14 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo const timeDisplayStyle: React.CSSProperties = {}; const sponsorTime = this.props.contentContainer().sponsorTimesSubmitting[this.props.index]; const segment = sponsorTime.segment; - if (sponsorTime?.actionType === ActionType.Full) timeDisplayStyle.display = "none"; + if (this.state.selectedActionType === ActionType.Full) timeDisplayStyle.display = "none"; if (this.state.editing) { timeDisplay = ( <div id={"sponsorTimesContainer" + this.idSuffix} style={timeDisplayStyle} className="sponsorTimeDisplay"> - {sponsorTime.actionType !== ActionType.Poi ? ( + {this.state.selectedActionType !== ActionType.Poi ? ( <span id={"startButton" + this.idSuffix} className="sponsorNowButton" onClick={() => this.setTimeTo(0, 0)}> @@ -145,14 +149,14 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo className="sponsorTimeEdit sponsorTimeEditInput" type="text" style={{color: "inherit", backgroundColor: "inherit"}} - value={this.state.sponsorTimeEdits[0]} + value={this.state.sponsorTimeEdits[0] ?? ""} onKeyDown={(e) => e.stopPropagation()} onKeyUp={(e) => e.stopPropagation()} onChange={(e) => this.handleOnChange(0, e, sponsorTime, e.target.value)} onWheel={(e) => this.changeTimesWhenScrolling(0, e, sponsorTime)}> </input> - {sponsorTime.actionType !== ActionType.Poi ? ( + {this.state.selectedActionType !== ActionType.Poi ? ( <span> <span> {" " + chrome.i18n.getMessage("to") + " "} @@ -162,7 +166,7 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo className="sponsorTimeEdit sponsorTimeEditInput" type="text" style={{color: "inherit", backgroundColor: "inherit"}} - value={this.state.sponsorTimeEdits[1]} + value={this.state.sponsorTimeEdits[1] ?? ""} onKeyDown={(e) => e.stopPropagation()} onKeyUp={(e) => e.stopPropagation()} onChange={(e) => this.handleOnChange(1, e, sponsorTime, e.target.value)} @@ -192,7 +196,7 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo className="sponsorTimeDisplay" onClick={this.toggleEditTime.bind(this)}> {getFormattedTime(segment[0], true) + - ((!isNaN(segment[1]) && sponsorTime.actionType !== ActionType.Poi) + ((!isNaN(segment[1]) && this.state.selectedActionType !== ActionType.Poi) ? " " + chrome.i18n.getMessage("to") + " " + getFormattedTime(segment[1], true) : "")} </div> ); @@ -207,9 +211,9 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo <div style={{position: "relative"}}> <select id={"sponsorTimeCategories" + this.idSuffix} className="sponsorTimeEditSelector sponsorTimeCategories" - defaultValue={sponsorTime.category} ref={this.categoryOptionRef} style={{color: "inherit", backgroundColor: "inherit"}} + value={this.state.selectedCategory} onChange={(event) => this.categorySelectionChange(event)}> {this.getCategoryOptions()} </select> @@ -220,7 +224,7 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo target="_blank" rel="noreferrer"> <img id={"sponsorTimeCategoriesHelpButton" + this.idSuffix} className="helpButton" - src={chrome.extension.getURL("icons/help.svg")} + src={chrome.runtime.getURL("icons/help.svg")} title={chrome.i18n.getMessage("categoryGuidelines")} /> </a> </div> @@ -232,7 +236,7 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo <div style={{position: "relative"}}> <select id={"sponsorTimeActionTypes" + this.idSuffix} className="sponsorTimeEditSelector sponsorTimeActionTypes" - defaultValue={sponsorTime.actionType} + value={this.state.selectedActionType} style={{color: "inherit", backgroundColor: "inherit"}} ref={this.actionTypeOptionRef} onChange={(e) => this.actionTypeSelectionChange(e)}> @@ -242,7 +246,7 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo ): ""} {/* Chapter Name */} - {sponsorTime.actionType === ActionType.Chapter ? ( + {this.state.selectedActionType=== ActionType.Chapter ? ( <div onBlur={() => this.setState({chapterNameSelectorOpen: false})}> <input id={"chapterName" + this.idSuffix} className="sponsorTimeEdit sponsorTimeEditInput sponsorChapterNameInput" @@ -269,48 +273,49 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo </div> ): ""} - <br/> - {/* Editing Tools */} - <span id={"sponsorTimeDeleteButton" + this.idSuffix} - className="sponsorTimeEditButton" - onClick={this.deleteTime.bind(this)}> - {chrome.i18n.getMessage("delete")} - </span> - - {(!isNaN(segment[1]) && ![ActionType.Poi, ActionType.Full].includes(sponsorTime.actionType)) - && sponsorTime.actionType !== ActionType.Chapter ? ( - <span id={"sponsorTimePreviewButton" + this.idSuffix} + <div style={{ marginTop: "3px" }}> + <span id={"sponsorTimeDeleteButton" + this.idSuffix} className="sponsorTimeEditButton" - onClick={(e) => this.previewTime(e.ctrlKey, e.shiftKey)}> - {chrome.i18n.getMessage("preview")} + onClick={this.deleteTime.bind(this)}> + {chrome.i18n.getMessage("delete")} </span> - ): ""} - {(!isNaN(segment[1]) && sponsorTime.actionType != ActionType.Full) ? ( - <span id={"sponsorTimeInspectButton" + this.idSuffix} - className="sponsorTimeEditButton" - onClick={this.inspectTime.bind(this)}> - {chrome.i18n.getMessage("inspect")} - </span> - ): ""} + {(!isNaN(segment[1]) && ![ActionType.Poi, ActionType.Full].includes(this.state.selectedActionType)) + && this.state.selectedActionType !== ActionType.Chapter ? ( + <span id={"sponsorTimePreviewButton" + this.idSuffix} + className="sponsorTimeEditButton" + onClick={(e) => this.previewTime(e.ctrlKey, e.shiftKey)}> + {chrome.i18n.getMessage("preview")} + </span> + ): ""} - {(!isNaN(segment[1]) && ![ActionType.Poi, ActionType.Full].includes(sponsorTime.actionType)) ? ( - <span id={"sponsorTimePreviewEndButton" + this.idSuffix} - className="sponsorTimeEditButton" - onClick={(e) => this.previewTime(e.ctrlKey, e.shiftKey, true)}> - {chrome.i18n.getMessage("End")} - </span> - ): ""} + {(!isNaN(segment[1]) && this.state.selectedActionType != ActionType.Full) ? ( + <span id={"sponsorTimeInspectButton" + this.idSuffix} + className="sponsorTimeEditButton" + onClick={this.inspectTime.bind(this)}> + {chrome.i18n.getMessage("inspect")} + </span> + ): ""} + + {(!isNaN(segment[1]) && ![ActionType.Poi, ActionType.Full].includes(this.state.selectedActionType)) ? ( + <span id={"sponsorTimePreviewEndButton" + this.idSuffix} + className="sponsorTimeEditButton" + onClick={(e) => this.previewTime(e.ctrlKey, e.shiftKey, true)}> + {chrome.i18n.getMessage("End")} + </span> + ): ""} + + {(!isNaN(segment[1]) && this.state.selectedActionType != ActionType.Full) ? ( + <span id={"sponsorTimeEditButton" + this.idSuffix} + className="sponsorTimeEditButton" + onClick={this.toggleEditTime.bind(this)}> + {this.state.editing ? chrome.i18n.getMessage("save") : chrome.i18n.getMessage("edit")} + </span> + ): ""} + </div> - {(!isNaN(segment[1]) && sponsorTime.actionType != ActionType.Full) ? ( - <span id={"sponsorTimeEditButton" + this.idSuffix} - className="sponsorTimeEditButton" - onClick={this.toggleEditTime.bind(this)}> - {this.state.editing ? chrome.i18n.getMessage("save") : chrome.i18n.getMessage("edit")} - </span> - ): ""} </div> ); } @@ -397,7 +402,7 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo checkToShowFullVideoWarning(): void { const sponsorTime = this.props.contentContainer().sponsorTimesSubmitting[this.props.index]; const segmentDuration = sponsorTime.segment[1] - sponsorTime.segment[0]; - const videoPercentage = segmentDuration / this.props.contentContainer().v.duration; + const videoPercentage = segmentDuration / getVideoDuration(); if (videoPercentage > 0.6 && !this.fullVideoWarningShown && (sponsorTime.category === "sponsor" || sponsorTime.category === "selfpromo" || sponsorTime.category === "chooseACategory")) { @@ -454,6 +459,9 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo categorySelectionChange(event: React.ChangeEvent<HTMLSelectElement>): void { const chosenCategory = event.target.value as Category; + this.setState({ + selectedCategory: chosenCategory + }); // See if show more categories was pressed if (chosenCategory !== DEFAULT_CATEGORY && !Config.config.categorySelections.some((category) => category.name === chosenCategory)) { @@ -481,6 +489,10 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo actionTypeSelectionChange(event: React.ChangeEvent<HTMLSelectElement>): void { const sponsorTime = this.props.contentContainer().sponsorTimesSubmitting[this.props.index]; + this.setState({ + selectedActionType: event.target.value as ActionType + }); + this.handleReplacingLostTimes(sponsorTime.category, event.target.value as ActionType, sponsorTime); this.saveEditTimes(); } @@ -542,7 +554,7 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo } setTimeToEnd(): void { - this.setTimeTo(1, this.props.contentContainer().v.duration); + this.setTimeTo(1, getVideoDuration()); } /** @@ -590,7 +602,25 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo getFormattedTime(sponsorTime.segment[1], true)]; } + lastEditTime = 0; + editTimeTimeout: NodeJS.Timeout | null = null; saveEditTimes(): void { + // Rate limit edits + const timeSinceLastEdit = Date.now() - this.lastEditTime; + const rateLimitTime = 200; + if (timeSinceLastEdit < rateLimitTime) { + if (!this.editTimeTimeout) { + this.editTimeTimeout = setTimeout(() => { + this.saveEditTimes(); + }, rateLimitTime - timeSinceLastEdit) + } + + return; + } + + this.lastEditTime = Date.now(); + this.editTimeTimeout = null; + const sponsorTimesSubmitting = this.props.contentContainer().sponsorTimesSubmitting; const category = this.categoryOptionRef.current.value as Category @@ -606,9 +636,12 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo if (addingTime) { this.props.contentContainer().updateEditButtonsOnPlayer(); } + } else if (startTime !== null) { + // Only start time is valid, still an incomplete segment + sponsorTimesSubmitting[this.props.index].segment[0] = startTime; } } else if (this.state.sponsorTimeEdits[1] === null && category === "outro" && !sponsorTimesSubmitting[this.props.index].segment[1]) { - sponsorTimesSubmitting[this.props.index].segment[1] = this.props.contentContainer().v.duration; + sponsorTimesSubmitting[this.props.index].segment[1] = getVideoDuration(); this.props.contentContainer().updateEditButtonsOnPlayer(); } @@ -616,12 +649,15 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo const actionType = this.getNextActionType(category, this.actionTypeOptionRef?.current?.value as ActionType); sponsorTimesSubmitting[this.props.index].actionType = actionType; + this.setState({ + selectedActionType: actionType + }); const description = actionType === ActionType.Chapter ? this.descriptionOptionRef?.current?.value : ""; sponsorTimesSubmitting[this.props.index].description = description; - Config.config.unsubmittedSegments[this.props.contentContainer().sponsorVideoID] = sponsorTimesSubmitting; - Config.forceSyncUpdate("unsubmittedSegments"); + Config.local.unsubmittedSegments[this.props.contentContainer().sponsorVideoID] = sponsorTimesSubmitting; + Config.forceLocalUpdate("unsubmittedSegments"); this.props.contentContainer().updatePreviewBar(); @@ -640,7 +676,7 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo previewTime(ctrlPressed = false, shiftPressed = false, skipToEndTime = false): void { const sponsorTimes = this.props.contentContainer().sponsorTimesSubmitting; const index = this.props.index; - let seekTime = 2; + let seekTime = defaultPreviewTime; if (ctrlPressed) seekTime = 0.5; if (shiftPressed) seekTime = 0.25; @@ -648,7 +684,7 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo const endTime = sponsorTimes[index].segment[1]; // If segment starts at 0:00, start playback at the end of the segment - const skipTime = (startTime === 0 || skipToEndTime) ? endTime : (startTime - (seekTime * this.props.contentContainer().v.playbackRate)); + const skipTime = (startTime === 0 || skipToEndTime) ? endTime : (startTime - (seekTime * getVideo().playbackRate)); this.props.contentContainer().previewTime(skipTime, !skipToEndTime); } @@ -671,11 +707,11 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo //save this if (sponsorTimes.length > 0) { - Config.config.unsubmittedSegments[this.props.contentContainer().sponsorVideoID] = sponsorTimes; + Config.local.unsubmittedSegments[this.props.contentContainer().sponsorVideoID] = sponsorTimes; } else { - delete Config.config.unsubmittedSegments[this.props.contentContainer().sponsorVideoID]; + delete Config.local.unsubmittedSegments[this.props.contentContainer().sponsorVideoID]; } - Config.forceSyncUpdate("unsubmittedSegments"); + Config.forceLocalUpdate("unsubmittedSegments"); this.props.contentContainer().updatePreviewBar(); @@ -710,7 +746,7 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo if (this.props.contentContainer().channelIDInfo.status !== ChannelIDStatus.Found) return; this.fetchingSuggestions = true; - const result = await utils.asyncRequestToServer("GET", "/api/chapterNames", { + const result = await asyncRequestToServer("GET", "/api/chapterNames", { description, channelID: this.props.contentContainer().channelIDInfo.id }); diff --git a/src/components/SubmissionNoticeComponent.tsx b/src/components/SubmissionNoticeComponent.tsx index e81c2bdf..28703767 100644 --- a/src/components/SubmissionNoticeComponent.tsx +++ b/src/components/SubmissionNoticeComponent.tsx @@ -9,12 +9,13 @@ import NoticeTextSelectionComponent from "./NoticeTextSectionComponent"; import SponsorTimeEditComponent from "./SponsorTimeEditComponent"; import { getGuidelineInfo } from "../utils/constants"; import { exportTimes } from "../utils/exporter"; +import { getVideo, isCurrentTimeWrong } from "../../maze-utils/src/video"; export interface SubmissionNoticeProps { // Contains functions and variables from the content script needed by the skip notice contentContainer: ContentContainer; - callback: () => unknown; + callback: () => Promise<boolean>; closeListener: () => void; } @@ -38,6 +39,8 @@ class SubmissionNoticeComponent extends React.Component<SubmissionNoticeProps, S guidelinesReminder: GenericNotice; + lastSegmentCount: number; + constructor(props: SubmissionNoticeProps) { super(props); this.noticeRef = React.createRef(); @@ -47,12 +50,14 @@ class SubmissionNoticeComponent extends React.Component<SubmissionNoticeProps, S const noticeTitle = chrome.i18n.getMessage("confirmNoticeTitle"); + this.lastSegmentCount = this.props.contentContainer().sponsorTimesSubmitting.length; + // Setup state this.state = { noticeTitle, messages: [], idSuffix: "SubmissionNotice" - } + }; } componentDidMount(): void { @@ -62,9 +67,16 @@ class SubmissionNoticeComponent extends React.Component<SubmissionNoticeProps, S this.forceUpdate(); }); - this.videoObserver.observe(this.contentContainer().v, { + this.videoObserver.observe(getVideo(), { attributes: true }); + + // Prevent zooming while changing times + document.getElementById("sponsorSkipNoticeMiddleRow" + this.state.idSuffix).addEventListener('wheel', function (event) { + if (event.ctrlKey) { + event.preventDefault(); + } + }, {passive: false}); } componentWillUnmount(): void { @@ -73,6 +85,22 @@ class SubmissionNoticeComponent extends React.Component<SubmissionNoticeProps, S } } + componentDidUpdate() { + const currentSegmentCount = this.props.contentContainer().sponsorTimesSubmitting.length; + if (currentSegmentCount > this.lastSegmentCount) { + this.lastSegmentCount = currentSegmentCount; + + this.scrollToBottom(); + } + } + + scrollToBottom() { + const scrollElement = this.noticeRef.current.getElement().current.querySelector("#sponsorSkipNoticeMiddleRowSubmissionNotice"); + scrollElement.scrollTo({ + top: scrollElement.scrollHeight + 1000 + }); + } + render(): React.ReactElement { const sortButton = <img id={"sponsorSkipSortButton" + this.state.idSuffix} @@ -80,7 +108,7 @@ class SubmissionNoticeComponent extends React.Component<SubmissionNoticeProps, S onClick={() => this.sortSegments()} title={chrome.i18n.getMessage("sortSegments")} key="sortButton" - src={chrome.extension.getURL("icons/sort.svg")}> + src={chrome.runtime.getURL("icons/sort.svg")}> </img>; const exportButton = <img id={"sponsorSkipExportButton" + this.state.idSuffix} @@ -88,7 +116,7 @@ class SubmissionNoticeComponent extends React.Component<SubmissionNoticeProps, S onClick={() => this.exportSegments()} title={chrome.i18n.getMessage("exportSegments")} key="exportButton" - src={chrome.extension.getURL("icons/export.svg")}> + src={chrome.runtime.getURL("icons/export.svg")}> </img>; return ( <NoticeComponent noticeTitle={this.state.noticeTitle} @@ -104,7 +132,8 @@ class SubmissionNoticeComponent extends React.Component<SubmissionNoticeProps, S {/* Sponsor Time List */} <tr id={"sponsorSkipNoticeMiddleRow" + this.state.idSuffix} className="sponsorTimeMessagesRow" - style={{maxHeight: (this.contentContainer().v.offsetHeight - 200) + "px"}}> + style={{maxHeight: (getVideo()?.offsetHeight - 200) + "px"}} + onMouseDown={(e) => e.stopPropagation()}> <td style={{width: "100%"}}> {this.getSponsorTimeMessages()} </td> @@ -187,6 +216,11 @@ class SubmissionNoticeComponent extends React.Component<SubmissionNoticeProps, S } submit(): void { + if (isCurrentTimeWrong()) { + alert(chrome.i18n.getMessage("submissionFailedServerSideAds")); + return; + } + // save all items for (const ref of this.timeEditRefs) { ref.current.saveEditTimes(); @@ -211,17 +245,19 @@ class SubmissionNoticeComponent extends React.Component<SubmissionNoticeProps, S } } - this.props.callback(); - - this.cancel(); + this.props.callback().then((success) => { + if (success) { + this.cancel(); + } + }); } sortSegments(): void { let sponsorTimesSubmitting = this.props.contentContainer().sponsorTimesSubmitting; sponsorTimesSubmitting = sponsorTimesSubmitting.sort((a, b) => a.segment[0] - b.segment[0]); - Config.config.unsubmittedSegments[this.props.contentContainer().sponsorVideoID] = sponsorTimesSubmitting; - Config.forceSyncUpdate("unsubmittedSegments"); + Config.local.unsubmittedSegments[this.props.contentContainer().sponsorVideoID] = sponsorTimesSubmitting; + Config.forceLocalUpdate("unsubmittedSegments"); this.forceUpdate(); } @@ -253,7 +289,7 @@ class SubmissionNoticeComponent extends React.Component<SubmissionNoticeProps, S categoryChangeListener(index: number, category: Category): void { const dialogWidth = this.noticeRef?.current?.getElement()?.current?.offsetWidth; if (category !== "chooseACategory" && Config.config.showCategoryGuidelines - && this.contentContainer().v.offsetWidth > dialogWidth * 2) { + && getVideo().offsetWidth > dialogWidth * 2) { const options = { title: chrome.i18n.getMessage(`category_${category}`), textBoxes: getGuidelineInfo(category), diff --git a/src/components/options/KeybindDialogComponent.tsx b/src/components/options/KeybindDialogComponent.tsx index 057a3b05..b034d7eb 100644 --- a/src/components/options/KeybindDialogComponent.tsx +++ b/src/components/options/KeybindDialogComponent.tsx @@ -141,9 +141,12 @@ class KeybindDialogComponent extends React.Component<KeybindDialogProps, Keybind return {message: chrome.i18n.getMessage("youtubeKeybindWarning"), blocking: false}; } - if (this.props.option != "skipKeybind" && this.equals(Config.config['skipKeybind']) || - this.props.option != "submitKeybind" && this.equals(Config.config['submitKeybind']) || - this.props.option != "startSponsorKeybind" && this.equals(Config.config['startSponsorKeybind'])) + if (this.props.option !== "skipKeybind" && this.equals(Config.config['skipKeybind']) || + this.props.option !== "submitKeybind" && this.equals(Config.config['submitKeybind']) || + this.props.option !== "actuallySubmitKeybind" && this.equals(Config.config['actuallySubmitKeybind']) || + this.props.option !== "previewKeybind" && this.equals(Config.config['previewKeybind']) || + this.props.option !== "closeSkipNoticeKeybind" && this.equals(Config.config['closeSkipNoticeKeybind']) || + this.props.option !== "startSponsorKeybind" && this.equals(Config.config['startSponsorKeybind'])) return {message: chrome.i18n.getMessage("keyAlreadyUsed"), blocking: true}; return null; diff --git a/src/components/options/UnsubmittedVideoListComponent.tsx b/src/components/options/UnsubmittedVideoListComponent.tsx index e63feb99..8bca8cf4 100644 --- a/src/components/options/UnsubmittedVideoListComponent.tsx +++ b/src/components/options/UnsubmittedVideoListComponent.tsx @@ -24,7 +24,7 @@ class UnsubmittedVideoListComponent extends React.Component<UnsubmittedVideoList render(): React.ReactElement { // Render nothing if there are no unsubmitted segments - if (Object.keys(Config.config.unsubmittedSegments).length == 0) + if (Object.keys(Config.local.unsubmittedSegments).length == 0) return <></>; return ( @@ -58,7 +58,7 @@ class UnsubmittedVideoListComponent extends React.Component<UnsubmittedVideoList getUnsubmittedVideos(): JSX.Element[] { const elements: JSX.Element[] = []; - for (const videoID of Object.keys(Config.config.unsubmittedSegments)) { + for (const videoID of Object.keys(Config.local.unsubmittedSegments)) { elements.push( <UnsubmittedVideoListItem videoID={videoID} key={videoID}> </UnsubmittedVideoListItem> diff --git a/src/components/options/UnsubmittedVideoListItem.tsx b/src/components/options/UnsubmittedVideoListItem.tsx index b2150457..bc8ca28c 100644 --- a/src/components/options/UnsubmittedVideoListItem.tsx +++ b/src/components/options/UnsubmittedVideoListItem.tsx @@ -23,7 +23,7 @@ class UnsubmittedVideoListItem extends React.Component<UnsubmittedVideosListItem } render(): React.ReactElement { - const segmentCount = Config.config.unsubmittedSegments[this.props.videoID]?.length ?? 0; + const segmentCount = Config.local.unsubmittedSegments[this.props.videoID]?.length ?? 0; return ( <> @@ -69,17 +69,17 @@ class UnsubmittedVideoListItem extends React.Component<UnsubmittedVideosListItem clearSegments(): void { if (confirm(chrome.i18n.getMessage("clearThis"))) { - delete Config.config.unsubmittedSegments[this.props.videoID]; - Config.forceSyncUpdate("unsubmittedSegments"); + delete Config.local.unsubmittedSegments[this.props.videoID]; + Config.forceLocalUpdate("unsubmittedSegments"); } } exportSegments(): void { - this.copyToClipboard(exportTimes(Config.config.unsubmittedSegments[this.props.videoID])); + this.copyToClipboard(exportTimes(Config.local.unsubmittedSegments[this.props.videoID])); } exportSegmentsAsURL(): void { - this.copyToClipboard(`https://youtube.com/watch?v=${this.props.videoID}${exportTimesAsHashParam(Config.config.unsubmittedSegments[this.props.videoID])}`) + this.copyToClipboard(`https://youtube.com/watch?v=${this.props.videoID}${exportTimesAsHashParam(Config.local.unsubmittedSegments[this.props.videoID])}`) } copyToClipboard(text: string): void { diff --git a/src/components/options/UnsubmittedVideosComponent.tsx b/src/components/options/UnsubmittedVideosComponent.tsx index 3806b881..0e642ab6 100644 --- a/src/components/options/UnsubmittedVideosComponent.tsx +++ b/src/components/options/UnsubmittedVideosComponent.tsx @@ -21,8 +21,8 @@ class UnsubmittedVideosComponent extends React.Component<UnsubmittedVideosProps, } render(): React.ReactElement { - const videoCount = Object.keys(Config.config.unsubmittedSegments).length; - const segmentCount = Object.values(Config.config.unsubmittedSegments).reduce((acc: number, vid: Array<unknown>) => acc + vid.length, 0); + const videoCount = Object.keys(Config.local.unsubmittedSegments).length; + const segmentCount = Object.values(Config.local.unsubmittedSegments).reduce((acc: number, vid: Array<unknown>) => acc + vid.length, 0); return <> <div style={{marginBottom: "10px"}}> @@ -48,7 +48,7 @@ class UnsubmittedVideosComponent extends React.Component<UnsubmittedVideosProps, clearAllSegments(): void { if (confirm(chrome.i18n.getMessage("clearUnsubmittedSegmentsConfirm"))) - Config.config.unsubmittedSegments = {}; + Config.local.unsubmittedSegments = {}; } } diff --git a/src/config.ts b/src/config.ts index 4dab0dab..383bfcf6 100644 --- a/src/config.ts +++ b/src/config.ts @@ -12,8 +12,6 @@ interface SBConfig { userID: string; isVip: boolean; permissions: Record<Category, Permission>; - /* Contains unsubmitted segments that the user has created. */ - unsubmittedSegments: Record<string, SponsorTime[]>; defaultCategory: Category; renderSegmentsAsChapters: boolean; whitelistedChannels: string[]; @@ -31,6 +29,7 @@ interface SBConfig { trackViewCount: boolean; trackViewCountInPrivate: boolean; trackDownvotes: boolean; + trackDownvotesInPrivate: boolean; dontShowNotice: boolean; noticeVisibilityMode: NoticeVisbilityMode; hideVideoPlayerControls: boolean; @@ -75,7 +74,10 @@ interface SBConfig { allowScrollingToEdit: boolean; deArrowInstalled: boolean; showDeArrowPromotion: boolean; + showDeArrowInSettings: boolean; + shownDeArrowPromotion: boolean; showZoomToFillError2: boolean; + cleanPopup: boolean; // Used to cache calculated text color info categoryPillColors: { @@ -89,8 +91,11 @@ interface SBConfig { skipToHighlightKeybind: Keybind; startSponsorKeybind: Keybind; submitKeybind: Keybind; + actuallySubmitKeybind: Keybind; + previewKeybind: Keybind; nextChapterKeybind: Keybind; previousChapterKeybind: Keybind; + closeSkipNoticeKeybind: Keybind; // What categories should be skipped categorySelections: CategorySelection[]; @@ -134,6 +139,12 @@ interface SBStorage { /* VideoID prefixes to UUID prefixes */ downvotedSegments: Record<VideoID & HashedValue, VideoDownvotes>; navigationApiAvailable: boolean; + + // Used when sync storage disabled + alreadyInstalled: boolean; + + /* Contains unsubmitted segments that the user has created. */ + unsubmittedSegments: Record<string, SponsorTime[]>; } class ConfigClass extends ProtoConfig<SBConfig, SBStorage> { @@ -145,6 +156,10 @@ class ConfigClass extends ProtoConfig<SBConfig, SBStorage> { skipCount: this.config.skipCount, sponsorTimesContributed: this.config.sponsorTimesContributed }); + + chrome.storage.local.set({ + ...this.localDefaults, + }); } } @@ -153,6 +168,14 @@ function migrateOldSyncFormats(config: SBConfig) { chrome.storage.sync.remove("showZoomToFillError"); } + if (config["unsubmittedSegments"] && Object.keys(config["unsubmittedSegments"]).length > 0) { + chrome.storage.local.set({ + unsubmittedSegments: config["unsubmittedSegments"] + }, () => { + chrome.storage.sync.remove("unsubmittedSegments"); + }); + } + if (!config["chapterCategoryAdded"]) { config["chapterCategoryAdded"] = true; @@ -166,15 +189,6 @@ function migrateOldSyncFormats(config: SBConfig) { } } - if (config["segmentTimes"]) { - const unsubmittedSegments = {}; - for (const item of config["segmentTimes"]) { - unsubmittedSegments[item[0]] = item[1]; - } - - chrome.storage.sync.remove("segmentTimes", () => config.unsubmittedSegments = unsubmittedSegments); - } - if (config["exclusive_accessCategoryAdded"] !== undefined) { chrome.storage.sync.remove("exclusive_accessCategoryAdded"); } @@ -260,7 +274,6 @@ const syncDefaults = { userID: null, isVip: false, permissions: {}, - unsubmittedSegments: {}, defaultCategory: "chooseACategory" as Category, renderSegmentsAsChapters: false, whitelistedChannels: [], @@ -278,6 +291,7 @@ const syncDefaults = { trackViewCount: true, trackViewCountInPrivate: true, trackDownvotes: true, + trackDownvotesInPrivate: false, dontShowNotice: false, noticeVisibilityMode: NoticeVisbilityMode.FadedForAutoSkip, hideVideoPlayerControls: false, @@ -317,7 +331,10 @@ const syncDefaults = { allowScrollingToEdit: true, deArrowInstalled: false, showDeArrowPromotion: true, + showDeArrowInSettings: true, + shownDeArrowPromotion: false, showZoomToFillError2: true, + cleanPopup: false, categoryPillColors: {}, @@ -332,8 +349,11 @@ const syncDefaults = { skipToHighlightKeybind: { key: "Enter", ctrl: true }, startSponsorKeybind: { key: ";" }, submitKeybind: { key: "'" }, + actuallySubmitKeybind: { key: "'", ctrl: true }, + previewKeybind: { key: ";", ctrl: true }, nextChapterKeybind: { key: "ArrowRight", ctrl: true }, previousChapterKeybind: { key: "ArrowLeft", ctrl: true }, + closeSkipNoticeKeybind: { key: "Backspace" }, categorySelections: [{ name: "sponsor" as Category, @@ -450,8 +470,33 @@ const syncDefaults = { const localDefaults = { downvotedSegments: {}, - navigationApiAvailable: null + navigationApiAvailable: null, + alreadyInstalled: false, + + unsubmittedSegments: {} }; const Config = new ConfigClass(syncDefaults, localDefaults, migrateOldSyncFormats); -export default Config;
\ No newline at end of file +export default Config; + +export function generateDebugDetails(): string { + // Build output debug information object + const output = { + debug: { + userAgent: navigator.userAgent, + platform: navigator.platform, + language: navigator.language, + extensionVersion: chrome.runtime.getManifest().version + }, + config: JSON.parse(JSON.stringify(Config.cachedSyncConfig)) // Deep clone config object + }; + + // Sanitise sensitive user config values + delete output.config.userID; + output.config.serverAddress = (output.config.serverAddress === CompileConfig.serverAddress) + ? "Default server address" : "Custom server address"; + output.config.invidiousInstances = output.config.invidiousInstances.length; + output.config.whitelistedChannels = output.config.whitelistedChannels.length; + + return JSON.stringify(output, null, 4); +}
\ No newline at end of file diff --git a/src/content.ts b/src/content.ts index de537005..04c2dcd3 100644 --- a/src/content.ts +++ b/src/content.ts @@ -26,27 +26,31 @@ import { SkipButtonControlBar } from "./js-components/skipButtonControlBar"; import { getStartTimeFromUrl } from "./utils/urlParser"; import { getControls, getExistingChapters, getHashParams, isPlayingPlaylist, isVisible } from "./utils/pageUtils"; import { CategoryPill } from "./render/CategoryPill"; -import { AnimationUtils } from "./utils/animationUtils"; +import { AnimationUtils } from "../maze-utils/src/animationUtils"; import { GenericUtils } from "./utils/genericUtils"; -import { logDebug } from "./utils/logger"; +import { logDebug, logWarn } from "./utils/logger"; import { importTimes } from "./utils/exporter"; import { ChapterVote } from "./render/ChapterVote"; import { openWarningDialog } from "./utils/warnings"; import { isFirefoxOrSafari, waitFor } from "../maze-utils/src"; import { getErrorMessage, getFormattedTime } from "../maze-utils/src/formating"; -import { getChannelIDInfo, getVideo, getIsAdPlaying, getIsLivePremiere, setIsAdPlaying, checkVideoIDChange, getVideoID, getYouTubeVideoID, setupVideoModule, checkIfNewVideoID, isOnInvidious, isOnMobileYouTube } from "../maze-utils/src/video"; -import { Keybind, StorageChangesObject, isSafari, keybindEquals } from "../maze-utils/src/config"; -import { findValidElement, waitForElement } from "../maze-utils/src/dom" +import { getChannelIDInfo, getVideo, getIsAdPlaying, getIsLivePremiere, setIsAdPlaying, checkVideoIDChange, getVideoID, getYouTubeVideoID, setupVideoModule, checkIfNewVideoID, isOnInvidious, isOnMobileYouTube, getLastNonInlineVideoID, triggerVideoIDChange, triggerVideoElementChange, getIsInline, getCurrentTime, setCurrentTime, getVideoDuration, verifyCurrentTime } from "../maze-utils/src/video"; +import { Keybind, StorageChangesObject, isSafari, keybindEquals, keybindToString } from "../maze-utils/src/config"; +import { findValidElement } from "../maze-utils/src/dom" import { getHash, HashedValue } from "../maze-utils/src/hash"; import { generateUserID } from "../maze-utils/src/setup"; import { updateAll } from "../maze-utils/src/thumbnailManagement"; import { setupThumbnailListener } from "./utils/thumbnails"; import * as documentScript from "../dist/js/document.js"; -import { Tooltip } from "./render/Tooltip"; -import { isDeArrowInstalled } from "./utils/crossExtension"; import { runCompatibilityChecks } from "./utils/compatibility"; import { cleanPage } from "./utils/pageCleaner"; import { addCleanupListener } from "../maze-utils/src/cleanup"; +import { hideDeArrowPromotion, tryShowingDeArrowPromotion } from "./dearrowPromotion"; +import { asyncRequestToServer } from "./utils/requests"; +import { isMobileControlsOpen } from "./utils/mobileUtils"; +import { defaultPreviewTime } from "./utils/constants"; +import { onVideoPage } from "../maze-utils/src/pageInfo"; +import { getSegmentsForVideo } from "./utils/segmentData"; cleanPage(); @@ -57,47 +61,12 @@ utils.wait(() => Config.isReady(), 5000, 10).then(() => { addCSS(); setCategoryColorCSSVariables(); - // DeArrow promotion - setTimeout(async () => { - if (document.URL === "https://www.youtube.com/" - && Config.config.showDeArrowPromotion - && Config.config.showUpsells - && Config.config.showNewFeaturePopups - && (Config.config.skipCount > 30 || !Config.config.trackViewCount) - && Math.random() < 0.05) { - - if (!await isDeArrowInstalled()) { - const element = await waitForElement("#contents") as HTMLElement; - if (element) { - Config.config.showDeArrowPromotion = false; - - new Tooltip({ - text: chrome.i18n.getMessage("DeArrowPromotionMessage2"), - linkOnClick: () => window.open("https://dearrow.ajay.app"), - referenceNode: element, - prependElement: element.firstElementChild as HTMLElement, - timeout: 15000, - positionRealtive: false, - containerAbsolute: true, - bottomOffset: "inherit", - topOffset: "-82px", - leftOffset: "0", - rightOffset: "0", - displayTriangle: false, - center: true, - opacity: 1 - }); - } - } else { - Config.config.showDeArrowPromotion = false; - } - } - }, 5000); - runCompatibilityChecks(); }); const skipBuffer = 0.003; +// If this close to the end, skip to the end +const endTimeSkipBuffer = 0.5; //was sponsor data found when doing SponsorsLookup let sponsorDataFound = false; @@ -105,12 +74,15 @@ let sponsorDataFound = false; let sponsorTimes: SponsorTime[] = []; let existingChaptersImported = false; let importingChaptersWaitingForFocus = false; +let importingChaptersWaiting = false; +let triedImportingChapters = false; // List of open skip notices const skipNotices: SkipNotice[] = []; let activeSkipKeybindElement: ToggleSkippable = null; let retryFetchTimeout: NodeJS.Timeout = null; let shownSegmentFailedToFetchWarning = false; let selectedSegment: SegmentUUID | null = null; +let previewedSegment = false; // JSON video info let videoInfo: VideoInfo = null; @@ -156,13 +128,10 @@ setupVideoModule({ updateVisibilityOfPlayerControlsButton(); }, resetValues, - documentScript + documentScript: chrome.runtime.getManifest().manifest_version === 2 ? documentScript : undefined }, () => Config); setupThumbnailListener(); -//the video id of the last preview bar update -let lastPreviewBarUpdate: VideoID; - // Is the video currently being switched let switchingVideos = null; @@ -171,6 +140,9 @@ let switchingVideos = null; let lastCheckTime = 0; let lastCheckVideoTime = -1; +// To determine if a video resolution change is happening +let firstPlay = true; + //is this channel whitelised from getting sponsors skipped let channelWhitelisted = false; @@ -200,7 +172,6 @@ let submissionNotice: SubmissionNotice = null; let lastResponseStatus: number; let retryCount = 0; -let lookupWaiting = false; // Contains all of the functions and variables needed by the skip notice const skipNoticeContentContainer: ContentContainer = () => ({ @@ -210,7 +181,6 @@ const skipNoticeContentContainer: ContentContainer = () => ({ sponsorTimes, sponsorTimesSubmitting, skipNotices, - v: getVideo(), sponsorVideoID: getVideoID(), reskipSponsorTime, updatePreviewBar, @@ -251,7 +221,7 @@ function messageListener(request: Message, sender: unknown, sendResponse: (respo found: sponsorDataFound, status: lastResponseStatus, sponsorTimes: sponsorTimes, - time: getVideo().currentTime, + time: getCurrentTime() ?? 0, onMobileYouTube: isOnMobileYouTube() }); @@ -286,13 +256,20 @@ function messageListener(request: Message, sender: unknown, sendResponse: (respo break; case "submitTimes": - submitSponsorTimes(); + openSubmissionMenu(); break; case "refreshSegments": // update video on refresh if videoID invalid - if (!getVideoID()) checkVideoIDChange(); + if (!getVideoID()) { + checkVideoIDChange(); + } + // if popup rescieves no response, or the videoID is invalid, + // it will assume the page is not a video page and stop the refresh animation + sendResponse({ hasVideo: getVideoID() != null }); // fetch segments - sponsorsLookup(false); + if (getVideoID()) { + sponsorsLookup(false, true); + } break; case "unskip": @@ -302,8 +279,7 @@ function messageListener(request: Message, sender: unknown, sendResponse: (respo reskipSponsorTime(sponsorTimes.find((segment) => segment.UUID === request.UUID), true); break; case "selectSegment": - selectedSegment = request.UUID; - updatePreviewBar(); + selectSegment(request.UUID); break; case "submitVote": vote(request.type, request.UUID).then((response) => sendResponse(response)); @@ -325,13 +301,15 @@ function messageListener(request: Message, sender: unknown, sendResponse: (respo navigator.clipboard.writeText(request.text); break; case "importSegments": { - const importedSegments = importTimes(request.data, getVideo().duration); + const importedSegments = importTimes(request.data, getVideoDuration()); let addedSegments = false; for (const segment of importedSegments) { if (!sponsorTimesSubmitting.some( (s) => Math.abs(s.segment[0] - segment.segment[0]) < 1 && Math.abs(s.segment[1] - segment.segment[1]) < 1)) { - if (segment.category === "chapter" && !utils.getCategorySelection("chapter")) { + const hasChaptersPermission = (Config.config.showCategoryWithoutPermission + || Config.config.permissions["chapter"]); + if (segment.category === "chapter" && (!utils.getCategorySelection("chapter") || !hasChaptersPermission)) { segment.category = "chooseACategory" as Category; segment.actionType = ActionType.Skip; segment.description = ""; @@ -343,12 +321,12 @@ function messageListener(request: Message, sender: unknown, sendResponse: (respo } if (addedSegments) { - Config.config.unsubmittedSegments[getVideoID()] = sponsorTimesSubmitting; - Config.forceSyncUpdate("unsubmittedSegments"); + Config.local.unsubmittedSegments[getVideoID()] = sponsorTimesSubmitting; + Config.forceLocalUpdate("unsubmittedSegments"); updateEditButtonsOnPlayer(); updateSponsorTimesSubmitting(false); - submitSponsorTimes(); + openSubmissionMenu(); } sendResponse({ @@ -368,6 +346,12 @@ function messageListener(request: Message, sender: unknown, sendResponse: (respo metaKey: request.metaKey })); break; + case "getLogs": + sendResponse({ + debug: window["SBLogs"].debug, + warn: window["SBLogs"].warn + }); + break; } sendResponse({}); @@ -385,7 +369,7 @@ function contentConfigUpdateListener(changes: StorageChangesObject) { updateVisibilityOfPlayerControlsButton() break; case "categorySelections": - sponsorsLookup(); + sponsorsLookup(true, true); break; case "barTypes": setCategoryColorCSSVariables(); @@ -406,9 +390,12 @@ function resetValues() { lastCheckTime = 0; lastCheckVideoTime = -1; retryCount = 0; + previewedSegment = false; + firstPlay = true; sponsorTimes = []; existingChaptersImported = false; + triedImportingChapters = false; sponsorSkipped = []; lastResponseStatus = 0; shownSegmentFailedToFetchWarning = false; @@ -425,8 +412,9 @@ function resetValues() { //reset sponsor data found check sponsorDataFound = false; - if (switchingVideos === null) { - // When first loading a video, it is not switching videos + // When first loading a video, it is not switching videos + // Hover play also doesn't need this check + if (switchingVideos === null || !onVideoPage()) { switchingVideos = false; } else { switchingVideos = true; @@ -439,6 +427,8 @@ function resetValues() { for (let i = 0; i < skipNotices.length; i++) { skipNotices.pop()?.close(); } + + hideDeArrowPromotion(); } function videoIDChange(): void { @@ -479,26 +469,38 @@ function videoIDChange(): void { // Clear unsubmitted segments from the previous video sponsorTimesSubmitting = []; updateSponsorTimesSubmitting(); + + tryShowingDeArrowPromotion().catch(logWarn); + + checkPreviewbarState(); + + if (getIsInline()) { + // Hover preview progress bar can take some time to appear + // and if the miniplayer is also active then it would + // attach to the wrong one + setTimeout(checkPreviewbarState, 500); + setTimeout(checkPreviewbarState, 1000); + setTimeout(checkPreviewbarState, 3000); + } } function handleMobileControlsMutations(): void { - if (!chrome.runtime?.id) return; + // Don't update while scrubbing + if (!chrome.runtime?.id + || document.querySelector(".YtProgressBarProgressBarPlayheadDotInDragging")) return; updateVisibilityOfPlayerControlsButton(); skipButtonControlBar?.updateMobileControls(); if (previewBar !== null) { - if (document.body.contains(previewBar.container)) { - const progressBarBackground = document.querySelector<HTMLElement>(".progress-bar-background"); - - if (progressBarBackground !== null) { - updatePreviewBarPositionMobile(progressBarBackground); - } + if (!previewBar.parent.contains(previewBar.container) && isMobileControlsOpen()) { + previewBar.createElement(); + updatePreviewBar(); return; - } else { - // The container does not exist anymore, remove that old preview bar + } else if (!previewBar.parent.isConnected) { + // The parent does not exist anymore, remove that old preview bar previewBar.remove(); previewBar = null; } @@ -508,26 +510,32 @@ function handleMobileControlsMutations(): void { createPreviewBar(); } -/** - * Creates a preview bar on the video - */ -function createPreviewBar(): void { - if (previewBar !== null) return; - +function getPreviewBarAttachElement(): HTMLElement | null { const progressElementOptions = [{ - // For mobile YouTube - selector: ".progress-bar-background", - isVisibleCheck: true - }, { // For new mobile YouTube (#1287) selector: ".progress-bar-line", isVisibleCheck: true }, { - // For Desktop YouTube + // For newer mobile YouTube (Jan 2024) + selector: ".YtProgressBarProgressBarLine", + isVisibleCheck: true + }, { + // For newer mobile YouTube (May 2024) + selector: ".YtmProgressBarProgressBarLine", + isVisibleCheck: true + }, { + // For desktop YouTube hover play + // Priority is given to the hover play progress bar over the main progress bar + // for miniplayer + hover preview case + // Second is new hover play selector + selector: "#video-preview .ytp-progress-bar, #video-preview .YtProgressBarLineHost", + isVisibleCheck: true + }, { + // For desktop YouTube selector: ".ytp-progress-bar", isVisibleCheck: true }, { - // For Desktop YouTube + // For desktop YouTube selector: ".no-model.cue-range-marker", isVisibleCheck: true }, { @@ -550,13 +558,26 @@ function createPreviewBar(): void { const el = option.isVisibleCheck ? findValidElement(allElements) : allElements[0]; if (el) { - const chapterVote = new ChapterVote(voteAsync); - previewBar = new PreviewBar(el, isOnMobileYouTube(), isOnInvidious(), chapterVote, () => importExistingChapters(true)); + return el; + } + } - updatePreviewBar(); + return null; +} - break; - } +/** + * Creates a preview bar on the video + */ +function createPreviewBar(): void { + if (previewBar !== null) return; + + const el = getPreviewBarAttachElement(); + + if (el) { + const chapterVote = new ChapterVote(voteAsync); + previewBar = new PreviewBar(el, isOnMobileYouTube(), isOnInvidious(), chapterVote, () => importExistingChapters(true)); + + updatePreviewBar(); } } @@ -623,7 +644,8 @@ async function startSponsorSchedule(includeIntersectingSegments = false, current updateActiveSegment(currentTime); - if (getVideo().paused) return; + if ((getVideo().paused && getCurrentTime() !== 0) // Allow autoplay disabled videos to skip before playing + || (getCurrentTime() >= getVideoDuration() - 0.01 && getVideoDuration() > 1)) return; const skipInfo = getNextSkipIndex(currentTime, includeIntersectingSegments, includeNonIntersectingSegments); const currentSkip = skipInfo.array[skipInfo.index]; @@ -673,7 +695,7 @@ async function startSponsorSchedule(includeIntersectingSegments = false, current let forcedIncludeNonIntersectingSegments = true; if (incorrectVideoCheck(videoID, currentSkip)) return; - forceVideoTime ||= Math.max(getVideo().currentTime, getVirtualTime()); + forceVideoTime ||= Math.max(getCurrentTime(), getVirtualTime()); if ((shouldSkip(currentSkip) || sponsorTimesSubmitting?.some((segment) => segment.segment === currentSkip.segment))) { if (forceVideoTime >= skipTime[0] - skipBuffer && forceVideoTime < skipTime[1]) { @@ -702,8 +724,12 @@ async function startSponsorSchedule(includeIntersectingSegments = false, current forcedSkipTime = skipTime[0] + 0.001; } else { forcedSkipTime = skipTime[1]; - forcedIncludeIntersectingSegments = true; forcedIncludeNonIntersectingSegments = false; + + // Only if not at the end of the video + if (Math.abs(skipTime[1] - getVideoDuration()) > endTimeSkipBuffer) { + forcedIncludeIntersectingSegments = true; + } } } else { forcedSkipTime = forceVideoTime + 0.001; @@ -732,38 +758,38 @@ async function startSponsorSchedule(includeIntersectingSegments = false, current // Use interval instead of timeout near the end to combat imprecise video time const startIntervalTime = forceStartIntervalTime || performance.now(); - const startVideoTime = Math.max(currentTime, getVideo().currentTime); + const startVideoTime = Math.max(currentTime, getCurrentTime()); delayTime = (skipTime?.[0] - startVideoTime) * 1000 * (1 / getVideo().playbackRate); let startWaitingForReportedTimeToChange = true; - const reportedVideoTimeAtStart = getVideo().currentTime; - logDebug(`Starting setInterval skipping ${getVideo().currentTime} to skip at ${skipTime[0]}`); + const reportedVideoTimeAtStart = getCurrentTime(); + logDebug(`Starting setInterval skipping ${getCurrentTime()} to skip at ${skipTime[0]}`); if (currentSkipInterval !== null) clearInterval(currentSkipInterval); currentSkipInterval = setInterval(() => { // Estimate delay, but only take the current time right after a change // Current time remains the same for many "frames" on Firefox if (isFirefoxOrSafari() && !lastKnownVideoTime.fromPause && startWaitingForReportedTimeToChange - && reportedVideoTimeAtStart !== getVideo().currentTime) { + && reportedVideoTimeAtStart !== getCurrentTime()) { startWaitingForReportedTimeToChange = false; - const delay = getVirtualTime() - getVideo().currentTime; + const delay = getVirtualTime() - getCurrentTime(); if (delay > 0) lastKnownVideoTime.approximateDelay = delay; } const intervalDuration = performance.now() - startIntervalTime; - if (intervalDuration + skipBuffer * 1000 >= delayTime || getVideo().currentTime >= skipTime[0]) { + if (intervalDuration + skipBuffer * 1000 >= delayTime || getCurrentTime() >= skipTime[0]) { clearInterval(currentSkipInterval); - if (!isFirefoxOrSafari() && !getVideo().muted && !inMuteSegment(getVideo().currentTime, true)) { + if (!isFirefoxOrSafari() && !getVideo().muted && !inMuteSegment(getCurrentTime(), true)) { // Workaround for more accurate skipping on Chromium getVideo().muted = true; getVideo().muted = false; } - skippingFunction(Math.max(getVideo().currentTime, startVideoTime + getVideo().playbackRate * Math.max(delayTime, intervalDuration) / 1000)); + skippingFunction(Math.max(getCurrentTime(), startVideoTime + getVideo().playbackRate * Math.max(delayTime, intervalDuration) / 1000)); } }, 0); } else { - logDebug(`Starting timeout to skip ${getVideo().currentTime} to skip at ${skipTime[0]}`); + logDebug(`Starting timeout to skip ${getCurrentTime()} to skip at ${skipTime[0]}`); const offset = (isFirefoxOrSafari() && !isSafari() ? 600 : 150); // Schedule for right before to be more precise than normal timeout @@ -787,15 +813,16 @@ function getVirtualTime(): number { (performance.now() - lastKnownVideoTime.preciseTime) * getVideo().playbackRate / 1000 + lastKnownVideoTime.videoTime : null); if (Config.config.useVirtualTime && !isSafari() && virtualTime - && Math.abs(virtualTime - getVideo().currentTime) < 0.2 && getVideo().currentTime !== 0) { - return Math.max(virtualTime, getVideo().currentTime); + && Math.abs(virtualTime - getCurrentTime()) < 0.2 && getCurrentTime() !== 0) { + return Math.max(virtualTime, getCurrentTime()); } else { - return getVideo().currentTime; + return getCurrentTime(); } } function inMuteSegment(currentTime: number, includeOverlap: boolean): boolean { const checkFunction = (segment) => segment.actionType === ActionType.Mute + && segment.hidden === SponsorHideType.Visible && segment.segment[0] <= currentTime && (segment.segment[1] > currentTime || (includeOverlap && segment.segment[1] + 0.02 > currentTime)); return sponsorTimes?.some(checkFunction) || sponsorTimesSubmitting.some(checkFunction); @@ -805,6 +832,8 @@ function inMuteSegment(currentTime: number, includeOverlap: boolean): boolean { * This makes sure the videoID is still correct and if the sponsorTime is included */ function incorrectVideoCheck(videoID?: string, sponsorTime?: SponsorTime): boolean { + if (!onVideoPage()) return false; + const currentVideoID = getYouTubeVideoID(); const recordedVideoID = videoID || getVideoID(); if (currentVideoID !== recordedVideoID || (sponsorTime @@ -828,14 +857,16 @@ let playbackRateCheckInterval: NodeJS.Timeout | null = null; let lastPlaybackSpeed = 1; let setupVideoListenersFirstTime = true; function setupVideoListeners() { + const video = getVideo(); + //wait until it is loaded - getVideo().addEventListener('loadstart', videoOnReadyListener) - getVideo().addEventListener('durationchange', durationChangeListener); + video.addEventListener('loadstart', videoOnReadyListener) + video.addEventListener('durationchange', durationChangeListener); if (setupVideoListenersFirstTime) { addCleanupListener(() => { - getVideo().removeEventListener('loadstart', videoOnReadyListener); - getVideo().removeEventListener('durationchange', durationChangeListener); + video.removeEventListener('loadstart', videoOnReadyListener); + video.removeEventListener('durationchange', durationChangeListener); }); } @@ -844,6 +875,7 @@ function setupVideoListeners() { let startedWaiting = false; let lastPausedAtZero = true; + let lastVideoDataChange = 0; const rateChangeListener = () => { updateVirtualTime(); @@ -851,18 +883,17 @@ function setupVideoListeners() { startSponsorSchedule(); }; - getVideo().addEventListener('ratechange', rateChangeListener); + video.addEventListener('ratechange', rateChangeListener); // Used by videospeed extension (https://github.com/igrigorik/videospeed/pull/740) - getVideo().addEventListener('videoSpeed_ratechange', rateChangeListener); + video.addEventListener('videoSpeed_ratechange', rateChangeListener); const playListener = () => { - // If it is not the first event, then the only way to get to 0 is if there is a seek event - // This check makes sure that changing the video resolution doesn't cause the extension to think it - // gone back to the begining - if (getVideo().readyState <= HTMLMediaElement.HAVE_CURRENT_DATA - && getVideo().currentTime === 0) return; + // Prevent video resolution changes from causing skips + if (!firstPlay && Date.now() - lastVideoDataChange < 200 && video.currentTime === 0) return; + firstPlay = false; updateVirtualTime(); + checkForMiniplayerPlaying(); if (switchingVideos || lastPausedAtZero) { switchingVideos = false; @@ -878,15 +909,15 @@ function setupVideoListeners() { updateAdFlag(); // Make sure it doesn't get double called with the playing event - if (Math.abs(lastCheckVideoTime - getVideo().currentTime) > 0.3 - || (lastCheckVideoTime !== getVideo().currentTime && Date.now() - lastCheckTime > 2000)) { + if (Math.abs(lastCheckVideoTime - video.currentTime) > 0.3 + || (lastCheckVideoTime !== video.currentTime && Date.now() - lastCheckTime > 2000)) { lastCheckTime = Date.now(); - lastCheckVideoTime = getVideo().currentTime; + lastCheckVideoTime = video.currentTime; startSponsorSchedule(); } }; - getVideo().addEventListener('play', playListener); + video.addEventListener('play', playListener); const playingListener = () => { updateVirtualTime(); @@ -894,8 +925,8 @@ function setupVideoListeners() { if (startedWaiting) { startedWaiting = false; - logDebug(`[SB] Playing event after buffering: ${Math.abs(lastCheckVideoTime - getVideo().currentTime) > 0.3 - || (lastCheckVideoTime !== getVideo().currentTime && Date.now() - lastCheckTime > 2000)}`); + logDebug(`[SB] Playing event after buffering: ${Math.abs(lastCheckVideoTime - video.currentTime) > 0.3 + || (lastCheckVideoTime !== video.currentTime && Date.now() - lastCheckTime > 2000)}`); } if (switchingVideos) { @@ -907,63 +938,63 @@ function setupVideoListeners() { } // Make sure it doesn't get double called with the play event - if (Math.abs(lastCheckVideoTime - getVideo().currentTime) > 0.3 - || (lastCheckVideoTime !== getVideo().currentTime && Date.now() - lastCheckTime > 2000)) { + if (Math.abs(lastCheckVideoTime - video.currentTime) > 0.3 + || (lastCheckVideoTime !== video.currentTime && Date.now() - lastCheckTime > 2000)) { lastCheckTime = Date.now(); - lastCheckVideoTime = getVideo().currentTime; + lastCheckVideoTime = video.currentTime; startSponsorSchedule(); } if (playbackRateCheckInterval) clearInterval(playbackRateCheckInterval); - lastPlaybackSpeed = getVideo().playbackRate; + lastPlaybackSpeed = video.playbackRate; // Video speed controller compatibility // That extension makes rate change events not propagate if (document.body.classList.contains("vsc-initialized")) { playbackRateCheckInterval = setInterval(() => { - if ((!getVideoID() || getVideo().paused) && playbackRateCheckInterval) { + if ((!getVideoID() || video.paused) && playbackRateCheckInterval) { // Video is gone, stop checking clearInterval(playbackRateCheckInterval); return; } - if (getVideo().playbackRate !== lastPlaybackSpeed) { - lastPlaybackSpeed = getVideo().playbackRate; + if (video.playbackRate !== lastPlaybackSpeed) { + lastPlaybackSpeed = video.playbackRate; rateChangeListener(); } }, 2000); } }; - getVideo().addEventListener('playing', playingListener); + video.addEventListener('playing', playingListener); const seekingListener = () => { lastKnownVideoTime.fromPause = false; - if (!getVideo().paused){ + if (!video.paused){ // Reset lastCheckVideoTime lastCheckTime = Date.now(); - lastCheckVideoTime = getVideo().currentTime; + lastCheckVideoTime = video.currentTime; updateVirtualTime(); clearWaitingTime(); // Sometimes looped videos loop back to almost zero, but not quite - if (getVideo().loop && getVideo().currentTime < 0.2) { + if (video.loop && video.currentTime < 0.2 && getCurrentTime() < 0.2) { startSponsorSchedule(false, 0); } else { startSponsorSchedule(); } } else { - updateActiveSegment(getVideo().currentTime); + updateActiveSegment(getCurrentTime()); - if (getVideo().currentTime === 0) { + if (getCurrentTime() === 0) { lastPausedAtZero = true; } } }; - getVideo().addEventListener('seeking', seekingListener); + video.addEventListener('seeking', seekingListener); const stoppedPlayback = () => { // Reset lastCheckVideoTime @@ -974,7 +1005,7 @@ function setupVideoListeners() { lastKnownVideoTime.videoTime = null; lastKnownVideoTime.preciseTime = null; - updateWaitingTime(); + updateWaitingTime(video); cancelSponsorSchedule(); }; @@ -983,26 +1014,46 @@ function setupVideoListeners() { stoppedPlayback(); }; - getVideo().addEventListener('pause', pauseListener); + video.addEventListener('pause', pauseListener); const waitingListener = () => { logDebug("[SB] Not skipping due to buffering"); startedWaiting = true; stoppedPlayback(); }; - getVideo().addEventListener('waiting', waitingListener); + video.addEventListener('waiting', waitingListener); + + // When video data is changed + const emptyListener = () => { + lastVideoDataChange = Date.now(); + + if (firstPlay && video.currentTime === 0) { + playListener(); + } + } + video.addEventListener('emptied', emptyListener); + + // For when autoplay is off to skip before starting playback + const metadataLoadedListener = () => { + if (firstPlay && getCurrentTime() === 0) { + playListener(); + } + } + video.addEventListener('loadedmetadata', metadataLoadedListener) startSponsorSchedule(); if (setupVideoListenersFirstTime) { addCleanupListener(() => { - getVideo().removeEventListener('play', playListener); - getVideo().removeEventListener('playing', playingListener); - getVideo().removeEventListener('seeking', seekingListener); - getVideo().removeEventListener('ratechange', rateChangeListener); - getVideo().removeEventListener('videoSpeed_ratechange', rateChangeListener); - getVideo().removeEventListener('pause', pauseListener); - getVideo().removeEventListener('waiting', waitingListener); + video.removeEventListener('play', playListener); + video.removeEventListener('playing', playingListener); + video.removeEventListener('seeking', seekingListener); + video.removeEventListener('ratechange', rateChangeListener); + video.removeEventListener('videoSpeed_ratechange', rateChangeListener); + video.removeEventListener('pause', pauseListener); + video.removeEventListener('waiting', waitingListener); + video.removeEventListener('empty', emptyListener); + video.removeEventListener('loadedmetadata', metadataLoadedListener); if (playbackRateCheckInterval) clearInterval(playbackRateCheckInterval); }); @@ -1015,7 +1066,7 @@ function setupVideoListeners() { function updateVirtualTime() { if (currentVirtualTimeInterval) clearInterval(currentVirtualTimeInterval); - lastKnownVideoTime.videoTime = getVideo().currentTime; + lastKnownVideoTime.videoTime = getCurrentTime(); lastKnownVideoTime.preciseTime = performance.now(); // If on Firefox, wait for the second time change (time remains fixed for many "frames" for privacy reasons) @@ -1027,21 +1078,21 @@ function updateVirtualTime() { currentVirtualTimeInterval = setInterval(() => { const frameTime = performance.now() - lastPerformanceTime; - if (lastTime !== getVideo().currentTime) { + if (lastTime !== getCurrentTime()) { rawCount++; // If there is lag, give it another shot at finding a good change time if (frameTime < 20 || rawCount > 30) { count++; } - lastTime = getVideo().currentTime; + lastTime = getCurrentTime(); } if (count > 1) { const delay = lastKnownVideoTime.fromPause && lastKnownVideoTime.approximateDelay ? lastKnownVideoTime.approximateDelay : 0; - lastKnownVideoTime.videoTime = getVideo().currentTime + delay; + lastKnownVideoTime.videoTime = getCurrentTime() + delay; lastKnownVideoTime.preciseTime = performance.now(); clearInterval(currentVirtualTimeInterval); @@ -1053,8 +1104,8 @@ function updateVirtualTime() { } } -function updateWaitingTime(): void { - lastTimeFromWaitingEvent = getVideo().currentTime; +function updateWaitingTime(video: HTMLVideoElement): void { + lastTimeFromWaitingEvent = video.currentTime; } function clearWaitingTime(): void { @@ -1071,6 +1122,7 @@ function setupSkipButtonControlBar() { openNotice: true, forceAutoSkip: true }), + selectSegment, onMobileYouTube: isOnMobileYouTube() }); } @@ -1086,44 +1138,20 @@ function setupCategoryPill() { categoryPill.attachToPage(isOnMobileYouTube(), isOnInvidious(), voteAsync); } -async function sponsorsLookup(keepOldSubmissions = true) { - if (lookupWaiting) return; - //there is still no video here - if (!getVideo()) { - lookupWaiting = true; - setTimeout(() => { - lookupWaiting = false; - sponsorsLookup() - }, 100); +async function sponsorsLookup(keepOldSubmissions = true, ignoreCache = false) { + const videoID = getVideoID() + if (!videoID) { + console.error("[SponsorBlock] Attempted to fetch segments with a null/undefined videoID."); return; } - const categories: string[] = Config.config.categorySelections.map((category) => category.name); - - const extraRequestData: Record<string, unknown> = {}; - const hashParams = getHashParams(); - if (hashParams.requiredSegment) extraRequestData.requiredSegment = hashParams.requiredSegment; - - const hashPrefix = (await getHash(getVideoID(), 1)).slice(0, 4) as VideoID & HashedValue; - const response = await utils.asyncRequestToServer('GET', "/api/skipSegments/" + hashPrefix, { - categories, - actionTypes: getEnabledActionTypes(), - userAgent: `${chrome.runtime.id}`, - ...extraRequestData - }); + const segmentData = await getSegmentsForVideo(videoID, ignoreCache); // store last response status - lastResponseStatus = response?.status; - - if (response?.ok) { - const receivedSegments: SponsorTime[] = JSON.parse(response.responseText) - ?.filter((video) => video.videoID === getVideoID()) - ?.map((video) => video.segments)?.[0] - ?.map((segment) => ({ - ...segment, - source: SponsorSourceType.Server - })) - ?.sort((a, b) => a.segment[0] - b.segment[0]); + lastResponseStatus = segmentData.status; + if (segmentData.status === 200) { + const receivedSegments = segmentData.segments; + if (receivedSegments && receivedSegments.length) { sponsorDataFound = true; @@ -1163,6 +1191,7 @@ async function sponsorsLookup(keepOldSubmissions = true) { } // See if some segments should be hidden + const hashPrefix = (await getHash(videoID, 1)).slice(0, 4) as VideoID & HashedValue; const downvotedData = Config.local.downvotedSegments[hashPrefix]; if (downvotedData) { for (const segment of sponsorTimes) { @@ -1174,13 +1203,14 @@ async function sponsorsLookup(keepOldSubmissions = true) { } } + if (!getVideo()) { + //there is still no video here + await waitFor(() => getVideo(), 5000, 10); + } + startSkipScheduleCheckingForStartSponsors(); - //update the preview bar - //leave the type blank for now until categories are added - if (lastPreviewBarUpdate == getVideoID() || (lastPreviewBarUpdate == null && !isNaN(getVideo().duration))) { - //set it now - //otherwise the listener can handle it + if (!isNaN(getVideoDuration())) { updatePreviewBar(); } } else { @@ -1198,7 +1228,7 @@ async function sponsorsLookup(keepOldSubmissions = true) { found: sponsorDataFound, status: lastResponseStatus, sponsorTimes: sponsorTimes, - time: getVideo().currentTime, + time: getCurrentTime() ?? 0, onMobileYouTube: isOnMobileYouTube() }); @@ -1208,10 +1238,10 @@ async function sponsorsLookup(keepOldSubmissions = true) { } function importExistingChapters(wait: boolean) { - if (!existingChaptersImported) { - const waitCondition = () => getVideo()?.duration && getExistingChapters(getVideoID(), getVideo().duration); + if (!existingChaptersImported && !importingChaptersWaiting && !triedImportingChapters && onVideoPage() && !isOnMobileYouTube()) { + const waitCondition = () => getVideoDuration() && getExistingChapters(getVideoID(), getVideoDuration()); - if (!waitCondition() && wait && !document.hasFocus() && !importingChaptersWaitingForFocus) { + if (wait && !document.hasFocus() && !importingChaptersWaitingForFocus && !waitCondition()) { importingChaptersWaitingForFocus = true; const listener = () => { importExistingChapters(wait); @@ -1219,33 +1249,24 @@ function importExistingChapters(wait: boolean) { }; window.addEventListener("focus", listener); } else { + importingChaptersWaiting = true; waitFor(waitCondition, wait ? 15000 : 0, 400, (c) => c?.length > 0).then((chapters) => { + importingChaptersWaiting = false; + if (!existingChaptersImported && chapters?.length > 0) { sponsorTimes = (sponsorTimes ?? []).concat(...chapters).sort((a, b) => a.segment[0] - b.segment[0]); existingChaptersImported = true; updatePreviewBar(); } - }).catch(() => {}); // eslint-disable-line @typescript-eslint/no-empty-function + }).catch(() => { importingChaptersWaiting = false; triedImportingChapters = true; }); // eslint-disable-line @typescript-eslint/no-empty-function } } } -function getEnabledActionTypes(forceFullVideo = false): ActionType[] { - const actionTypes = [ActionType.Skip, ActionType.Poi, ActionType.Chapter]; - if (Config.config.muteSegments) { - actionTypes.push(ActionType.Mute); - } - if (Config.config.fullVideoSegments || forceFullVideo) { - actionTypes.push(ActionType.Full); - } - - return actionTypes; -} - async function lockedCategoriesLookup(): Promise<void> { const hashPrefix = (await getHash(getVideoID(), 1)).slice(0, 4); - const response = await utils.asyncRequestToServer("GET", "/api/lockCategories/" + hashPrefix); + const response = await asyncRequestToServer("GET", "/api/lockCategories/" + hashPrefix); if (response.ok) { try { @@ -1290,7 +1311,7 @@ function startSkipScheduleCheckingForStartSponsors() { let startingSegmentTime = getStartTimeFromUrl(document.URL) || -1; let found = false; for (const time of sponsorTimes) { - if (time.segment[0] <= getVideo().currentTime && time.segment[0] > startingSegmentTime && time.segment[1] > getVideo().currentTime + if (time.segment[0] <= getCurrentTime() && time.segment[0] > startingSegmentTime && time.segment[1] > getCurrentTime() && time.actionType !== ActionType.Poi) { startingSegmentTime = time.segment[0]; found = true; @@ -1299,7 +1320,7 @@ function startSkipScheduleCheckingForStartSponsors() { } if (!found) { for (const time of sponsorTimesSubmitting) { - if (time.segment[0] <= getVideo().currentTime && time.segment[0] > startingSegmentTime && time.segment[1] > getVideo().currentTime + if (time.segment[0] <= getCurrentTime() && time.segment[0] > startingSegmentTime && time.segment[1] > getCurrentTime() && time.actionType !== ActionType.Poi) { startingSegmentTime = time.segment[0]; found = true; @@ -1310,7 +1331,7 @@ function startSkipScheduleCheckingForStartSponsors() { // For highlight category const poiSegments = sponsorTimes - .filter((time) => time.segment[1] > getVideo().currentTime + .filter((time) => time.segment[1] > getCurrentTime() && time.actionType === ActionType.Poi && time.hidden === SponsorHideType.Visible) .sort((a, b) => b.segment[0] - a.segment[0]); for (const time of poiSegments) { @@ -1321,7 +1342,7 @@ function startSkipScheduleCheckingForStartSponsors() { skipTime: time.segment, skippingSegments: [time], openNotice: true, - unskipTime: getVideo().currentTime + unskipTime: getCurrentTime() }); if (skipOption === CategorySkipOption.AutoSkip) break; } @@ -1340,13 +1361,9 @@ function startSkipScheduleCheckingForStartSponsors() { } } -/** - * This function is required on mobile YouTube and will keep getting called whenever the preview bar disapears - */ -function updatePreviewBarPositionMobile(parent: HTMLElement) { - if (document.getElementById("previewbar") === null) { - previewBar.createElement(parent); - } +function selectSegment(UUID: SegmentUUID): void { + selectedSegment = UUID; + updatePreviewBar(); } function updatePreviewBar(): void { @@ -1374,7 +1391,7 @@ function updatePreviewBar(): void { showLarger: segment.actionType === ActionType.Poi, description: segment.description, source: segment.source, - requiredSegment: requiredSegment && (segment.UUID === requiredSegment || segment.UUID.startsWith(requiredSegment)), + requiredSegment: requiredSegment && (segment.UUID === requiredSegment || segment.UUID?.startsWith(requiredSegment)), selectedSegment: selectedSegment && segment.UUID === selectedSegment }); }); @@ -1392,8 +1409,8 @@ function updatePreviewBar(): void { }); }); - previewBar.set(previewBarSegments.filter((segment) => segment.actionType !== ActionType.Full), getVideo()?.duration) - if (getVideo()) updateActiveSegment(getVideo().currentTime); + previewBar.set(previewBarSegments.filter((segment) => segment.actionType !== ActionType.Full), getVideoDuration()) + if (getVideo()) updateActiveSegment(getCurrentTime()); if (Config.config.showTimeWithSkips) { const skippedDuration = utils.getTimestampsDuration(previewBarSegments @@ -1402,9 +1419,6 @@ function updatePreviewBar(): void { showTimeWithoutSkips(skippedDuration); } - - // Update last video id - lastPreviewBarUpdate = getVideoID(); } //checks if this channel is whitelisted, should be done only after the channelID has been loaded @@ -1428,7 +1442,8 @@ function videoElementChange(newVideo: boolean): void { setupSkipButtonControlBar(); setupCategoryPill(); } - + + updatePreviewBar(); checkPreviewbarState(); // Incase the page is still transitioning, check again in a few seconds @@ -1438,8 +1453,19 @@ function videoElementChange(newVideo: boolean): void { }) } +let checkingPreviewbarAgain = false; function checkPreviewbarState(): void { - if (previewBar && !utils.findReferenceNode()?.contains(previewBar.container)) { + if (!getPreviewBarAttachElement() && !checkingPreviewbarAgain && getVideo() && getVideoID()) { + checkingPreviewbarAgain = true; + setTimeout(() => { + checkingPreviewbarAgain = false; + checkPreviewbarState(); + }, 500); + + return; + } + + if (previewBar && !getPreviewBarAttachElement()?.contains(previewBar.container)) { previewBar.remove(); previewBar = null; } @@ -1575,7 +1601,8 @@ function getStartTimes(sponsorTimes: SponsorTime[], includeIntersectingSegments: && segment.segment[1] > minimum && shouldSkip(segment)))) // Only include intersecting skippable segments && (!hideHiddenSponsors || segment.hidden === SponsorHideType.Visible) && segment.segment.length === 2 - && segment.actionType !== ActionType.Poi; + && segment.actionType !== ActionType.Poi + && segment.actionType !== ActionType.Full; const possibleTimes = sponsorTimes.map((sponsorTime) => ({ ...sponsorTime, @@ -1609,7 +1636,8 @@ function getStartTimes(sponsorTimes: SponsorTime[], includeIntersectingSegments: * @param time */ function previewTime(time: number, unpause = true) { - getVideo().currentTime = time; + previewedSegment = true; + setCurrentTime(time); // Unpause the video if needed if (unpause && getVideo().paused){ @@ -1619,6 +1647,13 @@ function previewTime(time: number, unpause = true) { //send telemetry and count skip function sendTelemetryAndCount(skippingSegments: SponsorTime[], secondsSkipped: number, fullSkip: boolean) { + for (const segment of skippingSegments) { + if (!previewedSegment && sponsorTimesSubmitting.some((s) => s.segment === segment.segment)) { + // Count that as a previewed segment + previewedSegment = true; + } + } + if (!Config.config.trackViewCount || (!Config.config.trackViewCountInPrivate && chrome.extension.inIncognitoContext)) return; let counted = false; @@ -1634,7 +1669,7 @@ function sendTelemetryAndCount(skippingSegments: SponsorTime[], secondsSkipped: counted = true; } - if (fullSkip) utils.asyncRequestToServer("POST", "/api/viewedVideoSponsorTime?UUID=" + segment.UUID); + if (fullSkip) asyncRequestToServer("POST", "/api/viewedVideoSponsorTime?UUID=" + segment.UUID); } } } @@ -1645,24 +1680,25 @@ function skipToTime({v, skipTime, skippingSegments, openNotice, forceAutoSkip, u // There will only be one submission if it is manual skip const autoSkip: boolean = forceAutoSkip || shouldAutoSkip(skippingSegments[0]); + const isSubmittingSegment = sponsorTimesSubmitting.some((time) => time.segment === skippingSegments[0].segment); - if ((autoSkip || sponsorTimesSubmitting.some((time) => time.segment === skippingSegments[0].segment)) - && v.currentTime !== skipTime[1]) { + if ((autoSkip || isSubmittingSegment) + && getCurrentTime() !== skipTime[1]) { switch(skippingSegments[0].actionType) { case ActionType.Poi: case ActionType.Skip: { // Fix for looped videos not working when skipping to the end #426 // for some reason you also can't skip to 1 second before the end - if (v.loop && v.duration > 1 && skipTime[1] >= v.duration - 1) { - v.currentTime = 0; - } else if (v.duration > 1 && skipTime[1] >= v.duration + if (v.loop && getVideoDuration() > 1 && skipTime[1] >= getVideoDuration() - 1) { + setCurrentTime(0); + } else if (getVideoDuration() > 1 && skipTime[1] >= getVideoDuration() && (navigator.vendor === "Apple Computer, Inc." || isPlayingPlaylist())) { // MacOS will loop otherwise #1027 // Sometimes playlists loop too #1804 - v.currentTime = v.duration - 0.001; - } else if (v.duration > 1 && Math.abs(skipTime[1] - v.duration) < 0.5 + setCurrentTime(getVideoDuration() - 0.001); + } else if (getVideoDuration() > 1 && Math.abs(skipTime[1] - getVideoDuration()) < endTimeSkipBuffer && isFirefoxOrSafari() && !isSafari()) { - v.currentTime = v.duration; + setCurrentTime(getVideoDuration()); } else { if (inMuteSegment(skipTime[1], true)) { // Make sure not to mute if skipping into a mute segment @@ -1670,7 +1706,7 @@ function skipToTime({v, skipTime, skippingSegments, openNotice, forceAutoSkip, u videoMuted = true; } - v.currentTime = skipTime[1]; + setCurrentTime(skipTime[1]); } break; @@ -1685,7 +1721,8 @@ function skipToTime({v, skipTime, skippingSegments, openNotice, forceAutoSkip, u } } - if (autoSkip && Config.config.audioNotificationOnSkip) { + if (autoSkip && Config.config.audioNotificationOnSkip + && !isSubmittingSegment && !getVideo()?.muted) { const beep = new Audio(chrome.runtime.getURL("icons/beep.ogg")); beep.volume = getVideo().volume * 0.1; const oldMetadata = navigator.mediaSession.metadata @@ -1727,7 +1764,7 @@ function skipToTime({v, skipTime, skippingSegments, openNotice, forceAutoSkip, u } //send telemetry that a this sponsor was skipped - if (autoSkip) sendTelemetryAndCount(skippingSegments, skipTime[1] - skipTime[0], true); + if (autoSkip || isSubmittingSegment) sendTelemetryAndCount(skippingSegments, skipTime[1] - skipTime[0], true); } function createSkipNotice(skippingSegments: SponsorTime[], autoSkip: boolean, unskipTime: number, startReskip: boolean) { @@ -1755,7 +1792,7 @@ function unskipSponsorTime(segment: SponsorTime, unskipTime: number = null, forc if (forceSeek || segment.actionType === ActionType.Skip) { //add a tiny bit of time to make sure it is not skipped again - getVideo().currentTime = unskipTime ?? segment.segment[0] + 0.001; + setCurrentTime(unskipTime ?? segment.segment[0] + 0.001); } } @@ -1765,11 +1802,11 @@ function reskipSponsorTime(segment: SponsorTime, forceSeek = false) { getVideo().muted = true; videoMuted = true; } else { - const skippedTime = Math.max(segment.segment[1] - getVideo().currentTime, 0); + const skippedTime = Math.max(segment.segment[1] - getCurrentTime(), 0); const segmentDuration = segment.segment[1] - segment.segment[0]; const fullSkip = skippedTime / segmentDuration > manualSkipPercentCount; - getVideo().currentTime = segment.segment[1]; + setCurrentTime(segment.segment[1]); sendTelemetryAndCount([segment], segment.actionType !== ActionType.Chapter ? skippedTime : 0, fullSkip); startSponsorSchedule(true, segment.segment[1], false); } @@ -1795,7 +1832,7 @@ function createButton(baseID: string, title: string, callback: () => void, image newButton.draggable = isDraggable; newButtonImage.id = baseID + "Image"; newButtonImage.className = "playerButtonImage"; - newButtonImage.src = chrome.extension.getURL("icons/" + imageName); + newButtonImage.src = chrome.runtime.getURL("icons/" + imageName); // Append image to button newButton.appendChild(newButtonImage); @@ -1817,7 +1854,8 @@ function shouldAutoSkip(segment: SponsorTime): boolean { return (!Config.config.manualSkipOnFullVideo || !sponsorTimes?.some((s) => s.category === segment.category && s.actionType === ActionType.Full)) && (utils.getCategorySelection(segment.category)?.option === CategorySkipOption.AutoSkip || (Config.config.autoSkipOnMusicVideos && sponsorTimes?.some((s) => s.category === "music_offtopic") - && segment.actionType === ActionType.Skip)); + && segment.actionType === ActionType.Skip) + || sponsorTimesSubmitting.some((s) => s.segment === segment.segment)); } function shouldSkip(segment: SponsorTime): boolean { @@ -1836,7 +1874,7 @@ async function createButtons(): Promise<void> { createButton("startSegment", "sponsorStart", () => startOrEndTimingNewSegment(), "PlayerStartIconSponsorBlocker.svg"); createButton("cancelSegment", "sponsorCancel", () => cancelCreatingSegment(), "PlayerCancelSegmentIconSponsorBlocker.svg"); createButton("delete", "clearTimes", () => clearSponsorTimes(), "PlayerDeleteIconSponsorBlocker.svg"); - createButton("submit", "OpenSubmissionMenu", () => submitSponsorTimes(), "PlayerUploadIconSponsorBlocker.svg"); + createButton("submit", "OpenSubmissionMenu", () => openSubmissionMenu(), "PlayerUploadIconSponsorBlocker.svg"); createButton("info", "openPopup", () => openInfoMenu(), "PlayerInfoIconSponsorBlocker.svg"); const controlsContainer = getControls(); @@ -1894,10 +1932,10 @@ function updateEditButtonsOnPlayer(): void { if (buttonsEnabled) { if (creatingSegment) { - playerButtons.startSegment.image.src = chrome.extension.getURL("icons/PlayerStopIconSponsorBlocker.svg"); + playerButtons.startSegment.image.src = chrome.runtime.getURL("icons/PlayerStopIconSponsorBlocker.svg"); playerButtons.startSegment.button.setAttribute("title", chrome.i18n.getMessage("sponsorEnd")); } else { - playerButtons.startSegment.image.src = chrome.extension.getURL("icons/PlayerStartIconSponsorBlocker.svg"); + playerButtons.startSegment.image.src = chrome.runtime.getURL("icons/PlayerStartIconSponsorBlocker.svg"); playerButtons.startSegment.button.setAttribute("title", chrome.i18n.getMessage("sponsorStart")); } } @@ -1918,13 +1956,14 @@ function getRealCurrentTime(): number { if (playButtonSVGData === replaceSVGData) { // At the end of the video - return getVideo()?.duration; + return getVideoDuration(); } else { - return getVideo().currentTime; + return getCurrentTime(); } } function startOrEndTimingNewSegment() { + verifyCurrentTime(); const roundedTime = Math.round((getRealCurrentTime() + Number.EPSILON) * 1000) / 1000; if (!isSegmentCreationInProgress()) { sponsorTimesSubmitting.push({ @@ -1945,11 +1984,11 @@ function startOrEndTimingNewSegment() { } // Save the newly created segment - Config.config.unsubmittedSegments[getVideoID()] = sponsorTimesSubmitting; - Config.forceSyncUpdate("unsubmittedSegments"); + Config.local.unsubmittedSegments[getVideoID()] = sponsorTimesSubmitting; + Config.forceLocalUpdate("unsubmittedSegments"); // Make sure they know if someone has already submitted something it while they were watching - sponsorsLookup(); + sponsorsLookup(true, true); updateEditButtonsOnPlayer(); updateSponsorTimesSubmitting(false); @@ -1978,13 +2017,13 @@ function cancelCreatingSegment() { if (isSegmentCreationInProgress()) { if (sponsorTimesSubmitting.length > 1) { // If there's more than one segment: remove last sponsorTimesSubmitting.pop(); - Config.config.unsubmittedSegments[getVideoID()] = sponsorTimesSubmitting; + Config.local.unsubmittedSegments[getVideoID()] = sponsorTimesSubmitting; } else { // Otherwise delete the video entry & close submission menu resetSponsorSubmissionNotice(); sponsorTimesSubmitting = []; - delete Config.config.unsubmittedSegments[getVideoID()]; + delete Config.local.unsubmittedSegments[getVideoID()]; } - Config.forceSyncUpdate("unsubmittedSegments"); + Config.forceLocalUpdate("unsubmittedSegments"); } updateEditButtonsOnPlayer(); @@ -1992,7 +2031,7 @@ function cancelCreatingSegment() { } function updateSponsorTimesSubmitting(getFromConfig = true) { - const segmentTimes = Config.config.unsubmittedSegments[getVideoID()]; + const segmentTimes = Config.local.unsubmittedSegments[getVideoID()]; //see if this data should be saved in the sponsorTimesSubmitting variable if (getFromConfig && segmentTimes != undefined) { @@ -2010,6 +2049,9 @@ function updateSponsorTimesSubmitting(getFromConfig = true) { } if (sponsorTimesSubmitting.length > 0) { + // Assume they already previewed a segment + previewedSegment = true; + importExistingChapters(true); } } @@ -2037,7 +2079,6 @@ function openInfoMenu() { //hide info button if (playerButtons.info) playerButtons.info.button.style.display = "none"; - const popup = document.createElement("div"); popup.id = "sponsorBlockPopupContainer"; @@ -2045,8 +2086,38 @@ function openInfoMenu() { frame.width = "374"; frame.height = "500"; frame.style.borderRadius = "12px"; - frame.addEventListener("load", () => frame.contentWindow.postMessage("", "*")); - frame.src = chrome.extension.getURL("popup.html"); + frame.addEventListener("load", async () => { + frame.contentWindow.postMessage("", "*"); + + // To support userstyles applying to the popup + const stylusStyle = document.querySelector(".stylus"); + if (stylusStyle) { + frame.contentWindow.postMessage({ + type: "style", + css: stylusStyle.textContent + }, "*"); + } + + const enhancerStyle = document.getElementById("efyt-theme"); + if (enhancerStyle) { + const enhancerStyleVariables = document.getElementById("efyt-theme-variables"); + if (enhancerStyleVariables) { + const enhancerCss = await fetch(enhancerStyle.getAttribute("href")).then((response) => response.text()); + const enhancerVariablesCss = await fetch(enhancerStyleVariables.getAttribute("href")).then((response) => response.text()); + + if (enhancerCss && enhancerVariablesCss) { + frame.contentWindow.postMessage({ + type: "style", + // Image needs needs to reference the full url now + css: enhancerCss.replace("./images/youtube-deep-dark/IconSponsorBlocker256px.png", + "https://raw.githubusercontent.com/RaitaroH/YouTube-DeepDark/master/YT_Images/IconSponsorBlocker256px.png") + + enhancerVariablesCss + }, "*"); + } + } + } + }); + frame.src = chrome.runtime.getURL("popup.html"); popup.appendChild(frame); const elemHasChild = (elements: NodeListOf<HTMLElement>): Element => { @@ -2093,7 +2164,7 @@ function closeInfoMenu() { function clearSponsorTimes() { const currentVideoID = getVideoID(); - const sponsorTimes = Config.config.unsubmittedSegments[currentVideoID]; + const sponsorTimes = Config.local.unsubmittedSegments[currentVideoID]; if (sponsorTimes != undefined && sponsorTimes.length > 0) { const confirmMessage = chrome.i18n.getMessage("clearThis") + getSegmentsMessage(sponsorTimes) @@ -2103,8 +2174,8 @@ function clearSponsorTimes() { resetSponsorSubmissionNotice(); //clear the sponsor times - delete Config.config.unsubmittedSegments[currentVideoID]; - Config.forceSyncUpdate("unsubmittedSegments"); + delete Config.local.unsubmittedSegments[currentVideoID]; + Config.forceLocalUpdate("unsubmittedSegments"); //clear sponsor times submitting sponsorTimesSubmitting = []; @@ -2218,44 +2289,75 @@ function resetSponsorSubmissionNotice(callRef = true) { submissionNotice = null; } -function submitSponsorTimes() { +function closeSubmissionMenu() { + submissionNotice?.close(); + submissionNotice = null; +} + +function openSubmissionMenu() { if (submissionNotice !== null){ - submissionNotice.close(); - submissionNotice = null; + closeSubmissionMenu(); return; } if (sponsorTimesSubmitting !== undefined && sponsorTimesSubmitting.length > 0) { submissionNotice = new SubmissionNotice(skipNoticeContentContainer, sendSubmitMessage); } +} + +function previewRecentSegment() { + if (sponsorTimesSubmitting !== undefined && sponsorTimesSubmitting.length > 0) { + previewTime(sponsorTimesSubmitting[sponsorTimesSubmitting.length - 1].segment[0] - defaultPreviewTime); + + if (submissionNotice) { + submissionNotice.scrollToBottom(); + } + } +} + +function submitSegments() { + if (sponsorTimesSubmitting !== undefined + && sponsorTimesSubmitting.length > 0 + && submissionNotice !== null) { + submissionNotice.submit(); + } } //send the message to the background js //called after all the checks have been made that it's okay to do so -async function sendSubmitMessage() { +async function sendSubmitMessage(): Promise<boolean> { // check if all segments are full video const onlyFullVideo = sponsorTimesSubmitting.every((segment) => segment.actionType === ActionType.Full); // Block if submitting on a running livestream or premiere if (!onlyFullVideo && (getIsLivePremiere() || isVisible(document.querySelector(".ytp-live-badge")))) { alert(chrome.i18n.getMessage("liveOrPremiere")); - return; + return false; + } + + if (!previewedSegment + && !sponsorTimesSubmitting.every((segment) => + [ActionType.Full, ActionType.Chapter, ActionType.Poi].includes(segment.actionType) + || segment.segment[1] >= getVideoDuration() + || segment.segment[0] === 0)) { + alert(`${chrome.i18n.getMessage("previewSegmentRequired")} ${keybindToString(Config.config.previewKeybind)}`); + return false; } // Add loading animation - playerButtons.submit.image.src = chrome.extension.getURL("icons/PlayerUploadIconSponsorBlocker.svg"); + playerButtons.submit.image.src = chrome.runtime.getURL("icons/PlayerUploadIconSponsorBlocker.svg"); const stopAnimation = AnimationUtils.applyLoadingAnimation(playerButtons.submit.button, 1, () => updateEditButtonsOnPlayer()); //check if a sponsor exceeds the duration of the video for (let i = 0; i < sponsorTimesSubmitting.length; i++) { - if (sponsorTimesSubmitting[i].segment[1] > getVideo().duration) { - sponsorTimesSubmitting[i].segment[1] = getVideo().duration; + if (sponsorTimesSubmitting[i].segment[1] > getVideoDuration()) { + sponsorTimesSubmitting[i].segment[1] = getVideoDuration(); } } //update sponsorTimes - Config.config.unsubmittedSegments[getVideoID()] = sponsorTimesSubmitting; - Config.forceSyncUpdate("unsubmittedSegments"); + Config.local.unsubmittedSegments[getVideoID()] = sponsorTimesSubmitting; + Config.forceLocalUpdate("unsubmittedSegments"); // Check to see if any of the submissions are below the minimum duration set if (Config.config.minDuration > 0) { @@ -2265,16 +2367,16 @@ async function sendSubmitMessage() { const confirmShort = chrome.i18n.getMessage("shortCheck") + "\n\n" + getSegmentsMessage(sponsorTimesSubmitting); - if(!confirm(confirmShort)) return; + if(!confirm(confirmShort)) return false; } } } - const response = await utils.asyncRequestToServer("POST", "/api/skipSegments", { + const response = await asyncRequestToServer("POST", "/api/skipSegments", { videoID: getVideoID(), userID: Config.config.userID, segments: sponsorTimesSubmitting, - videoDuration: getVideo()?.duration, + videoDuration: getVideoDuration(), userAgent: `${chrome.runtime.id}/v${chrome.runtime.getManifest().version}` }); @@ -2282,8 +2384,8 @@ async function sendSubmitMessage() { stopAnimation(); // Remove segments from storage since they've already been submitted - delete Config.config.unsubmittedSegments[getVideoID()]; - Config.forceSyncUpdate("unsubmittedSegments"); + delete Config.local.unsubmittedSegments[getVideoID()]; + Config.forceLocalUpdate("unsubmittedSegments"); const newSegments = sponsorTimesSubmitting; try { @@ -2315,10 +2417,12 @@ async function sendSubmitMessage() { if (fullVideoSegment) { categoryPill?.setSegment(fullVideoSegment); } + + return true; } else { // Show that the upload failed playerButtons.submit.button.style.animation = "unset"; - playerButtons.submit.image.src = chrome.extension.getURL("icons/PlayerUploadFailedIconSponsorBlocker.svg"); + playerButtons.submit.image.src = chrome.runtime.getURL("icons/PlayerUploadFailedIconSponsorBlocker.svg"); if (response.status === 403 && response.responseText.startsWith("Submission rejected due to a tip from a moderator.")) { openWarningDialog(skipNoticeContentContainer); @@ -2326,6 +2430,8 @@ async function sendSubmitMessage() { alert(getErrorMessage(response.status, response.responseText)); } } + + return false; } //get the message that visually displays the video times @@ -2351,54 +2457,50 @@ function getSegmentsMessage(sponsorTimes: SponsorTime[]): string { } function updateActiveSegment(currentTime: number): void { - const activeSegments = previewBar?.updateChapterText(sponsorTimes, sponsorTimesSubmitting, currentTime); + previewBar?.updateChapterText(sponsorTimes, sponsorTimesSubmitting, currentTime); + chrome.runtime.sendMessage({ message: "time", time: currentTime }); - - const chapterSegments = activeSegments?.filter((segment) => segment.actionType === ActionType.Chapter); - if (chapterSegments?.length > 0) { - sendTelemetryAndCount(chapterSegments, 0, true); - } } function nextChapter(): void { const chapters = previewBar.unfilteredChapterGroups?.filter((time) => [ActionType.Chapter, null].includes(time.actionType)); if (!chapters || chapters.length <= 0) return; - lastNextChapterKeybind.time = getVideo().currentTime; + lastNextChapterKeybind.time = getCurrentTime(); lastNextChapterKeybind.date = Date.now(); - const nextChapter = chapters.findIndex((time) => time.segment[0] > getVideo().currentTime); + const nextChapter = chapters.findIndex((time) => time.segment[0] > getCurrentTime()); if (nextChapter !== -1) { - getVideo().currentTime = chapters[nextChapter].segment[0]; + setCurrentTime(chapters[nextChapter].segment[0]); } else { - getVideo().currentTime = getVideo().duration; + setCurrentTime(getVideoDuration()); } } function previousChapter(): void { if (Date.now() - lastNextChapterKeybind.date < 3000) { - getVideo().currentTime = lastNextChapterKeybind.time; + setCurrentTime(lastNextChapterKeybind.time); lastNextChapterKeybind.date = 0; return; } const chapters = previewBar.unfilteredChapterGroups?.filter((time) => [ActionType.Chapter, null].includes(time.actionType)); if (!chapters || chapters.length <= 0) { - getVideo().currentTime = 0; + setCurrentTime(0); return; } // subtract 5 seconds to allow skipping back to the previous chapter if close to start of // the current one - const nextChapter = chapters.findIndex((time) => time.segment[0] > getVideo().currentTime - Math.min(5, time.segment[1] - time.segment[0])); + const nextChapter = chapters.findIndex((time) => time.segment[0] > getCurrentTime() - Math.min(5, time.segment[1] - time.segment[0])); const previousChapter = nextChapter !== -1 ? (nextChapter - 1) : (chapters.length - 1); if (previousChapter !== -1) { - getVideo().currentTime = chapters[previousChapter].segment[0]; + setCurrentTime(chapters[previousChapter].segment[0]); } else { - getVideo().currentTime = 0; + setCurrentTime(0); } } @@ -2436,8 +2538,11 @@ function hotkeyListener(e: KeyboardEvent): void { const skipKey = Config.config.skipKeybind; const skipToHighlightKey = Config.config.skipToHighlightKeybind; + const closeSkipNoticeKey = Config.config.closeSkipNoticeKeybind; const startSponsorKey = Config.config.startSponsorKeybind; - const submitKey = Config.config.submitKeybind; + const submitKey = Config.config.actuallySubmitKeybind; + const previewKey = Config.config.previewKeybind; + const openSubmissionMenuKey = Config.config.submitKeybind; const nextChapterKey = Config.config.nextChapterKeybind; const previousChapterKey = Config.config.previousChapterKeybind; @@ -2453,11 +2558,23 @@ function hotkeyListener(e: KeyboardEvent): void { } return; + } else if (keybindEquals(key, closeSkipNoticeKey)) { + for (let i = 0; i < skipNotices.length; i++) { + skipNotices.pop().close(); + } + + return; } else if (keybindEquals(key, startSponsorKey)) { startOrEndTimingNewSegment(); return; } else if (keybindEquals(key, submitKey)) { - submitSponsorTimes(); + submitSegments(); + return; + } else if (keybindEquals(key, openSubmissionMenuKey)) { + openSubmissionMenu(); + return; + } else if (keybindEquals(key, previewKey)) { + previewRecentSegment(); return; } else if (keybindEquals(key, nextChapterKey)) { if (sponsorTimes.length > 0) e.stopPropagation(); @@ -2476,7 +2593,7 @@ function hotkeyListener(e: KeyboardEvent): void { } else if (key.key == startSponsorKey?.key && startSponsorKey.code == null && !keybindEquals(Config.syncDefaults.startSponsorKeybind, startSponsorKey)) { startOrEndTimingNewSegment(); } else if (key.key == submitKey?.key && submitKey.code == null && !keybindEquals(Config.syncDefaults.submitKeybind, submitKey)) { - submitSponsorTimes(); + openSubmissionMenu(); } } @@ -2493,7 +2610,7 @@ function addCSS() { fileref.rel = "stylesheet"; fileref.type = "text/css"; - fileref.href = chrome.extension.getURL(file); + fileref.href = chrome.runtime.getURL(file); head.appendChild(fileref); } @@ -2544,7 +2661,7 @@ function showTimeWithoutSkips(skippedDuration: number): void { display.appendChild(duration); } - const durationAfterSkips = getFormattedTime(getVideo()?.duration - skippedDuration); + const durationAfterSkips = getFormattedTime(getVideoDuration() - skippedDuration); duration.innerText = (durationAfterSkips == null || skippedDuration <= 0) ? "" : " (" + durationAfterSkips + ")"; } @@ -2577,8 +2694,8 @@ function checkForPreloadedSegment() { } if (pushed) { - Config.config.unsubmittedSegments[getVideoID()] = sponsorTimesSubmitting; - Config.forceSyncUpdate("unsubmittedSegments"); + Config.local.unsubmittedSegments[getVideoID()] = sponsorTimesSubmitting; + Config.forceLocalUpdate("unsubmittedSegments"); } } @@ -2606,3 +2723,22 @@ function setCategoryColorCSSVariables() { styleContainer.innerText = css; } + +/** + * If mini player starts playing, then videoID change might have to be called + */ +function checkForMiniplayerPlaying() { + const miniPlayerUI = document.querySelector(".miniplayer") as HTMLElement; + if (!onVideoPage() && isVisible(miniPlayerUI)) { + const videoID = getLastNonInlineVideoID(); + if (videoID) { + triggerVideoIDChange(videoID); + + // treat as if video element has changed + const video = miniPlayerUI.querySelector("video") as HTMLVideoElement; + if (video && getVideo() !== video) { + triggerVideoElementChange(video); + } + } + } +} diff --git a/src/dearrowPromotion.ts b/src/dearrowPromotion.ts new file mode 100644 index 00000000..f1eec399 --- /dev/null +++ b/src/dearrowPromotion.ts @@ -0,0 +1,74 @@ +import { waitFor } from "../maze-utils/src"; +import { getYouTubeTitleNode } from "../maze-utils/src/elements"; +import { getHash } from "../maze-utils/src/hash"; +import { getVideoID, isOnInvidious, isOnMobileYouTube } from "../maze-utils/src/video"; +import Config from "./config"; +import { Tooltip } from "./render/Tooltip"; +import { isDeArrowInstalled } from "./utils/crossExtension"; +import { isVisible } from "./utils/pageUtils"; +import { asyncRequestToServer } from "./utils/requests"; + +let tooltip: Tooltip = null; +const showDeArrowPromotion = false; +export async function tryShowingDeArrowPromotion() { + if (showDeArrowPromotion + && Config.config.showDeArrowPromotion + && !isOnMobileYouTube() + && !isOnInvidious() + && document.URL.includes("watch") + && Config.config.showUpsells + && Config.config.showNewFeaturePopups + && (Config.config.skipCount > 30 || !Config.config.trackViewCount)) { + + if (!await isDeArrowInstalled()) { + try { + const element = await waitFor(() => getYouTubeTitleNode(), 5000, 500, (e) => isVisible(e)) as HTMLElement; + if (element && element.innerText && badTitle(element.innerText)) { + const hashPrefix = (await getHash(getVideoID(), 1)).slice(0, 4); + const deArrowData = await asyncRequestToServer("GET", "/api/branding/" + hashPrefix); + if (!deArrowData.ok) return; + + const deArrowDataJson = JSON.parse(deArrowData.responseText); + const title = deArrowDataJson?.[getVideoID()]?.titles?.[0]; + if (title && title.title && (title.locked || title.votes > 0)) { + Config.config.showDeArrowPromotion = false; + + tooltip = new Tooltip({ + text: chrome.i18n.getMessage("DeArrowTitleReplacementSuggestion") + "\n\n" + title.title, + linkOnClick: () => { + window.open("https://dearrow.ajay.app"); + Config.config.shownDeArrowPromotion = true; + }, + secondButtonText: chrome.i18n.getMessage("hideNewFeatureUpdates"), + referenceNode: element, + prependElement: element.firstElementChild as HTMLElement, + timeout: 15000, + positionRealtive: false, + containerAbsolute: true, + bottomOffset: "inherit", + topOffset: "55px", + leftOffset: "0", + rightOffset: "0", + topTriangle: true, + center: true, + opacity: 1 + }); + } + } + } catch { } // eslint-disable-line no-empty + } else { + Config.config.showDeArrowPromotion = false; + } + } +} + +/** + * Two upper case words (at least 2 letters long) + */ +function badTitle(title: string): boolean { + return !!title.match(/\p{Lu}{2,} \p{Lu}{2,}[.!? ]/u); +} + +export function hideDeArrowPromotion(): void { + if (tooltip) tooltip.close(); +}
\ No newline at end of file diff --git a/src/globals.d.ts b/src/globals.d.ts index aaaab851..b420496a 100644 --- a/src/globals.d.ts +++ b/src/globals.d.ts @@ -1,19 +1,4 @@ import { SBObject } from "./config"; declare global { interface Window { SB: SBObject } - // Remove this once the API becomes stable and types are shipped in @types/chrome - namespace chrome { - namespace declarativeContent { - export interface RequestContentScriptOptions { - allFrames?: boolean; - css?: string[]; - instanceType?: "declarativeContent.RequestContentScript"; - js?: string[]; - matchAboutBlanck?: boolean; - } - export class RequestContentScript { - constructor(options: RequestContentScriptOptions); - } - } - } } diff --git a/src/help.ts b/src/help.ts index 3b8c636b..67296473 100644 --- a/src/help.ts +++ b/src/help.ts @@ -3,6 +3,7 @@ import Config from "./config"; import { showDonationLink } from "./utils/configUtils"; import { waitFor } from "../maze-utils/src"; +import { isDeArrowInstalled } from "./utils/crossExtension"; if (document.readyState === "complete") { init(); @@ -10,6 +11,32 @@ if (document.readyState === "complete") { document.addEventListener("DOMContentLoaded", init); } +// DeArrow promotion +waitFor(() => Config.isReady()).then(() => { + if (Config.config.showNewFeaturePopups && Config.config.showUpsells) { + isDeArrowInstalled().then((installed) => { + if (!installed) { + const deArrowPromotion = document.getElementById("dearrow-link"); + deArrowPromotion.classList.remove("hidden"); + + deArrowPromotion.addEventListener("click", () => Config.config.showDeArrowPromotion = false); + + const text = deArrowPromotion.querySelector("#dearrow-link-text"); + text.textContent = `${chrome.i18n.getMessage("DeArrowPromotionMessage2").split("?")[0]}? ${chrome.i18n.getMessage("DeArrowPromotionMessage3")}`; + + const closeButton = deArrowPromotion.querySelector(".close-button"); + closeButton.addEventListener("click", (e) => { + e.preventDefault(); + + deArrowPromotion.classList.add("hidden"); + Config.config.showDeArrowPromotion = false; + Config.config.showDeArrowInSettings = false; + }); + } + }); + } +}); + async function init() { localizeHtmlPage(); diff --git a/src/js-components/previewBar.ts b/src/js-components/previewBar.ts index dcee1797..a014d606 100644 --- a/src/js-components/previewBar.ts +++ b/src/js-components/previewBar.ts @@ -1,5 +1,5 @@ /* -Parts of this are inspired from code from VideoSegments, but rewritten and under the LGPLv3 license +Based on code from https://github.com/videosegments/videosegments/commits/f1e111bdfe231947800c6efdd51f62a4e7fef4d4/segmentsbar/segmentsbar.js */ @@ -11,9 +11,9 @@ import { ActionType, Category, SegmentContainer, SponsorHideType, SponsorSourceT import { partition } from "../utils/arrayUtils"; import { DEFAULT_CATEGORY, shortCategoryName } from "../utils/categoryUtils"; import { normalizeChapterName } from "../utils/exporter"; -import { getFormattedTimeToSeconds } from "../../maze-utils/src/formating"; import { findValidElement } from "../../maze-utils/src/dom"; import { addCleanupListener } from "../../maze-utils/src/cleanup"; +import { isVisible } from "../utils/pageUtils"; const TOOLTIP_VISIBLE_CLASS = 'sponsorCategoryTooltipVisible'; const MIN_CHAPTER_SIZE = 0.003; @@ -125,34 +125,11 @@ class PreviewBar { mouseOnSeekBar = false; }); - const observer = new MutationObserver((mutations) => { - if (!mouseOnSeekBar || !this.categoryTooltip || !this.categoryTooltipContainer) return; + seekBar.addEventListener("mousemove", (e: MouseEvent) => { + if (!mouseOnSeekBar || !this.categoryTooltip || !this.categoryTooltipContainer || !chrome.runtime?.id) return; - // Only care about mutations to time tooltip - if (!mutations.some((mutation) => (mutation.target as HTMLElement).classList.contains("ytp-tooltip-text"))) { - return; - } - - const tooltipTextElements = tooltipTextWrapper.querySelectorAll(".ytp-tooltip-text"); - let timeInSeconds: number | null = null; - let noYoutubeChapters = false; - - for (const tooltipTextElement of tooltipTextElements) { - if (tooltipTextElement.classList.contains('ytp-tooltip-text-no-title')) noYoutubeChapters = true; - - const tooltipText = tooltipTextElement.textContent; - if (tooltipText === null || tooltipText.length === 0) continue; - - timeInSeconds = getFormattedTimeToSeconds(tooltipText); - - if (timeInSeconds !== null) break; - } - - if (timeInSeconds === null) { - originalTooltip.style.removeProperty("display"); - - return; - } + let noYoutubeChapters = !!tooltipTextWrapper.querySelector(".ytp-tooltip-text.ytp-tooltip-text-no-title"); + const timeInSeconds = this.decimalToTime((e.clientX - seekBar.getBoundingClientRect().x) / seekBar.clientWidth); // Find the segment at that location, using the shortest if multiple found const [normalSegments, chapterSegments] = @@ -198,15 +175,6 @@ class PreviewBar { this.chapterTooltip.style.textAlign = titleTooltip.style.textAlign; } }); - - observer.observe(tooltipTextWrapper, { - childList: true, - subtree: true, - }); - - addCleanupListener(() => { - observer.disconnect(); - }); } private setTooltipTitle(segment: PreviewBarSegment, tooltip: HTMLElement): void { @@ -224,16 +192,12 @@ class PreviewBar { } } - createElement(parent: HTMLElement): void { - this.parent = parent; + createElement(parent?: HTMLElement): void { + if (parent) this.parent = parent; if (this.onMobileYouTube) { - if (parent.classList.contains("progress-bar-background")) { - parent.style.backgroundColor = "rgba(255, 255, 255, 0.3)"; - parent.style.opacity = "1"; - } - this.container.style.transform = "none"; + this.container.style.height = "var(--yt-progress-bar-height)"; } else if (!this.onInvidious) { this.container.classList.add("sbNotInvidious"); } @@ -262,10 +226,12 @@ class PreviewBar { this.segments = segments ?? []; this.videoDuration = videoDuration ?? 0; + this.updatePageElements(); // Sometimes video duration is inaccurate, pull from accessibility info const ariaDuration = parseInt(this.progressBar?.getAttribute('aria-valuemax')) ?? 0; - if (ariaDuration && Math.abs(ariaDuration - this.videoDuration) > 3) { + const multipleActiveVideos = [...document.querySelectorAll("video")].filter((v) => isVisible(v)).length > 1; + if (!multipleActiveVideos && ariaDuration && Math.abs(ariaDuration - this.videoDuration) > 3) { this.videoDuration = ariaDuration; } @@ -273,7 +239,7 @@ class PreviewBar { } private updatePageElements(): void { - const allProgressBars = document.querySelectorAll('.ytp-progress-bar') as NodeListOf<HTMLElement>; + const allProgressBars = document.querySelectorAll(".ytp-progress-bar") as NodeListOf<HTMLElement>; this.progressBar = findValidElement(allProgressBars) ?? allProgressBars?.[0]; if (this.progressBar) { @@ -311,6 +277,7 @@ class PreviewBar { return (b[1] - b[0]) - (a[1] - a[0]); }); for (const segment of sortedSegments) { + if (segment.actionType === ActionType.Chapter) continue; const bar = this.createBar(segment); this.container.appendChild(bar); @@ -350,7 +317,7 @@ class PreviewBar { bar.style.left = this.timeToPercentage(startTime); if (duration > 0) { - bar.style.right = this.timeToPercentage(this.videoDuration - endTime); + bar.style.right = this.timeToRightPercentage(endTime); } if (this.chapterFilter(barSegment) && segment[1] < this.videoDuration) { bar.style.marginRight = `${this.chapterMargin}px`; @@ -784,6 +751,7 @@ class PreviewBar { updateChapterText(segments: SponsorTime[], submittingSegments: SponsorTime[], currentTime: number): SponsorTime[] { if (!Config.config.showSegmentNameInChapterBar + || Config.config.disableSkipping || ((!segments || segments.length <= 0) && submittingSegments?.length <= 0)) { const chaptersContainer = this.getChaptersContainer(); if (chaptersContainer) { @@ -923,7 +891,22 @@ class PreviewBar { return `${this.timeToDecimal(time) * 100}%` } + timeToRightPercentage(time: number): string { + return `${(1 - this.timeToDecimal(time)) * 100}%` + } + timeToDecimal(time: number): number { + return this.decimalTimeConverter(time, true); + } + + decimalToTime(decimal: number): number { + return this.decimalTimeConverter(decimal, false); + } + + /** + * Decimal to time or time to decimal + */ + decimalTimeConverter(value: number, isTime: boolean): number { if (this.originalChapterBarBlocks?.length > 1 && this.existingChapters.length === this.originalChapterBarBlocks?.length) { // Parent element to still work when display: none const totalPixels = this.originalChapterBar.parentElement.clientWidth; @@ -933,8 +916,9 @@ class PreviewBar { const chapterElement = this.originalChapterBarBlocks[i]; const widthPixels = parseFloat(chapterElement.style.width.replace("px", "")); - if (time >= this.existingChapters[i].segment[1]) { - const marginPixels = chapterElement.style.marginRight ? parseFloat(chapterElement.style.marginRight.replace("px", "")) : 0; + const marginPixels = chapterElement.style.marginRight ? parseFloat(chapterElement.style.marginRight.replace("px", "")) : 0; + if ((isTime && value >= this.existingChapters[i].segment[1]) + || (!isTime && value >= (pixelOffset + widthPixels + marginPixels) / totalPixels)) { pixelOffset += widthPixels + marginPixels; lastCheckedChapter = i; } else { @@ -948,13 +932,22 @@ class PreviewBar { const latestWidth = parseFloat(this.originalChapterBarBlocks[lastCheckedChapter + 1].style.width.replace("px", "")); const latestChapterDuration = latestChapter.segment[1] - latestChapter.segment[0]; - const percentageInCurrentChapter = (time - latestChapter.segment[0]) / latestChapterDuration; - const sizeOfCurrentChapter = latestWidth / totalPixels; - return Math.min(1, ((pixelOffset / totalPixels) + (percentageInCurrentChapter * sizeOfCurrentChapter))); + if (isTime) { + const percentageInCurrentChapter = (value - latestChapter.segment[0]) / latestChapterDuration; + const sizeOfCurrentChapter = latestWidth / totalPixels; + return Math.min(1, ((pixelOffset / totalPixels) + (percentageInCurrentChapter * sizeOfCurrentChapter))); + } else { + const percentageInCurrentChapter = (value * totalPixels - pixelOffset) / latestWidth; + return Math.max(0, latestChapter.segment[0] + (percentageInCurrentChapter * latestChapterDuration)); + } } } - return Math.min(1, time / this.videoDuration); + if (isTime) { + return Math.min(1, value / this.videoDuration); + } else { + return Math.max(0, value * this.videoDuration); + } } /* diff --git a/src/js-components/skipButtonControlBar.ts b/src/js-components/skipButtonControlBar.ts index a4cf31a5..b5c18386 100644 --- a/src/js-components/skipButtonControlBar.ts +++ b/src/js-components/skipButtonControlBar.ts @@ -1,11 +1,13 @@ import Config from "../config"; -import { SponsorTime } from "../types"; +import { SegmentUUID, SponsorTime } from "../types"; import { getSkippingText } from "../utils/categoryUtils"; -import { AnimationUtils } from "../utils/animationUtils"; +import { AnimationUtils } from "../../maze-utils/src/animationUtils"; import { keybindToString } from "../../maze-utils/src/config"; +import { isMobileControlsOpen } from "../utils/mobileUtils"; export interface SkipButtonControlBarProps { skip: (segment: SponsorTime) => void; + selectSegment: (UUID: SegmentUUID) => void; onMobileYouTube: boolean; } @@ -54,8 +56,18 @@ export class SkipButtonControlBar { this.container.appendChild(this.skipIcon); this.container.appendChild(this.textContainer); this.container.addEventListener("click", () => this.toggleSkip()); - this.container.addEventListener("mouseenter", () => this.stopTimer()); - this.container.addEventListener("mouseleave", () => this.startTimer()); + this.container.addEventListener("mouseenter", () => { + this.stopTimer(); + + if (this.segment) { + props.selectSegment(this.segment.UUID); + } + }); + this.container.addEventListener("mouseleave", () => { + this.startTimer(); + + props.selectSegment(null); + }); if (this.onMobileYouTube) { this.container.addEventListener("touchstart", (e) => this.handleTouchStart(e)); this.container.addEventListener("touchmove", (e) => this.handleTouchMove(e)); @@ -172,10 +184,8 @@ export class SkipButtonControlBar { } updateMobileControls(): void { - const overlay = document.getElementById("player-control-overlay"); - - if (overlay && this.enabled) { - if (overlay?.classList?.contains("fadein")) { + if (this.enabled) { + if (isMobileControlsOpen()) { this.showButton(); } else { this.hideButton(); diff --git a/src/messageTypes.ts b/src/messageTypes.ts index 339bfafe..6b9f3225 100644 --- a/src/messageTypes.ts +++ b/src/messageTypes.ts @@ -17,7 +17,8 @@ interface DefaultMessage { | "isChannelWhitelisted" | "submitTimes" | "refreshSegments" - | "closePopup"; + | "closePopup" + | "getLogs"; } interface BoolValueMessage { @@ -103,7 +104,9 @@ export type MessageResponse = | IsChannelWhitelistedResponse | Record<string, never> // empty object response {} | VoteResponse - | ImportSegmentsResponse; + | ImportSegmentsResponse + | RefreshSegmentsResponse + | LogResponse; export interface VoteResponse { successType: number; @@ -115,6 +118,15 @@ interface ImportSegmentsResponse { importedSegments: SponsorTime[]; } +export interface RefreshSegmentsResponse { + hasVideo: boolean; +} + +export interface LogResponse { + debug: string[]; + warn: string[]; +} + export interface TimeUpdateMessage { message: "time"; time: number; diff --git a/src/options.ts b/src/options.ts index 965c9840..ea84858f 100644 --- a/src/options.ts +++ b/src/options.ts @@ -1,8 +1,7 @@ import * as React from "react"; import { createRoot } from 'react-dom/client'; -import Config from "./config"; -import * as CompileConfig from "../config.json"; +import Config, { generateDebugDetails } from "./config"; import * as invidiousList from "../ci/invidiouslist.json"; // Make the config public for debugging purposes @@ -18,6 +17,7 @@ import { StorageChangesObject } from "../maze-utils/src/config"; import { getHash } from "../maze-utils/src/hash"; import { isFirefoxOrSafari } from "../maze-utils/src"; import { isDeArrowInstalled } from "./utils/crossExtension"; +import { asyncRequestToServer } from "./utils/requests"; const utils = new Utils(); let embed = false; @@ -61,6 +61,10 @@ async function init() { Config.configSyncListeners.push(optionsConfigUpdateListener); } + if (!Config.configLocalListeners.includes(optionsLocalConfigUpdateListener)) { + Config.configLocalListeners.push(optionsLocalConfigUpdateListener); + } + await utils.wait(() => Config.config !== null); if (!Config.config.darkMode) { @@ -74,13 +78,22 @@ async function init() { } // DeArrow promotion - if (Config.config.showNewFeaturePopups && Config.config.showUpsells) { + if (Config.config.showNewFeaturePopups && Config.config.showUpsells && Config.config.showDeArrowInSettings) { isDeArrowInstalled().then((installed) => { if (!installed) { const deArrowPromotion = document.getElementById("deArrowPromotion"); deArrowPromotion.classList.remove("hidden"); deArrowPromotion.addEventListener("click", () => Config.config.showDeArrowPromotion = false); + + const closeButton = deArrowPromotion.querySelector(".close-button"); + closeButton.addEventListener("click", (e) => { + e.preventDefault(); + + deArrowPromotion.classList.add("hidden"); + Config.config.showDeArrowPromotion = false; + Config.config.showDeArrowInSettings = false; + }); } }); } @@ -243,10 +256,10 @@ async function init() { if (option == "*") { const downloadButton = optionsElements[i].querySelector(".download-button"); - downloadButton.addEventListener("click", downloadConfig); + downloadButton.addEventListener("click", () => downloadConfig(optionsElements[i])); const uploadButton = optionsElements[i].querySelector(".upload-button"); - uploadButton.addEventListener("change", (e) => uploadConfig(e)); + uploadButton.addEventListener("change", (e) => uploadConfig(e, optionsElements[i] as HTMLElement)); } const privateTextChangeOption = optionsElements[i].getAttribute("data-sync"); @@ -272,7 +285,7 @@ async function init() { break; case "resetToDefault": Config.resetToDefault(); - window.location.reload(); + setTimeout(() => window.location.reload(), 200); break; } }); @@ -396,7 +409,11 @@ function optionsConfigUpdateListener(changes: StorageChangesObject) { for (const chooser of categoryChoosers) { chooser.update(); } - } else if (changes.unsubmittedSegments) { + } +} + +function optionsLocalConfigUpdateListener(changes: StorageChangesObject) { + if (changes.unsubmittedSegments) { for (const chooser of unsubmittedVideos) { chooser.update(); } @@ -530,6 +547,7 @@ function activatePrivateTextChange(element: HTMLElement) { const textBox = <HTMLInputElement> element.querySelector(".option-text-box"); const option = element.getAttribute("data-sync"); + const optionType = element.getAttribute("data-sync-type"); // See if anything extra must be done switch (option) { @@ -542,7 +560,11 @@ function activatePrivateTextChange(element: HTMLElement) { // See if anything extra must be done switch (option) { case "*": { - result = JSON.stringify(Config.cachedSyncConfig); + if (optionType === "local") { + result = JSON.stringify(Config.cachedLocalStorage); + } else { + result = JSON.stringify(Config.cachedSyncConfig); + } break; } } @@ -558,7 +580,7 @@ function activatePrivateTextChange(element: HTMLElement) { switch (option) { case "userID": if (Config.config[option]) { - utils.asyncRequestToServer("GET", "/api/userInfo", { + asyncRequestToServer("GET", "/api/userInfo", { publicUserID: getHash(Config.config[option]), values: ["warnings", "banned"] }).then((result) => { @@ -585,6 +607,7 @@ function activatePrivateTextChange(element: HTMLElement) { */ async function setTextOption(option: string, element: HTMLElement, value: string, callbackOnError?: () => void) { const confirmMessage = element.getAttribute("data-confirm-message"); + const optionType = element.getAttribute("data-sync-type"); if (confirmMessage === null || confirm(chrome.i18n.getMessage(confirmMessage))) { @@ -594,18 +617,21 @@ async function setTextOption(option: string, element: HTMLElement, value: string try { const newConfig = JSON.parse(value); for (const key in newConfig) { - Config.config[key] = newConfig[key]; + if (optionType === "local") { + Config.local[key] = newConfig[key]; + } else { + Config.config[key] = newConfig[key]; + } } - if (newConfig.supportInvidious) { + if (optionType !== "local" && newConfig.supportInvidious) { const checkbox = <HTMLInputElement> document.querySelector("#support-invidious > div > label > input"); checkbox.checked = true; await invidiousOnClick(checkbox, "supportInvidious"); } - window.location.reload(); - + setTimeout(() => window.location.reload(), 200); } catch (e) { alert(chrome.i18n.getMessage("incorrectlyFormattedOptions")); } @@ -620,25 +646,27 @@ async function setTextOption(option: string, element: HTMLElement, value: string } } -function downloadConfig() { +function downloadConfig(element: Element) { + const optionType = element.getAttribute("data-sync-type"); + const file = document.createElement("a"); - const jsonData = JSON.parse(JSON.stringify(Config.cachedSyncConfig)); + const jsonData = JSON.parse(JSON.stringify(optionType === "local" ? Config.cachedLocalStorage : Config.cachedSyncConfig)); const dateTimeString = new Date().toJSON().replace("T", "_").replace(/:/g, ".").replace(/.\d+Z/g, "") file.setAttribute("href", `data:text/json;charset=utf-8,${encodeURIComponent(JSON.stringify(jsonData))}`); - file.setAttribute("download", `SponsorBlockConfig_${dateTimeString}.json`); + file.setAttribute("download", `SponsorBlock${optionType === "local" ? "OtherData" : "Config"}_${dateTimeString}.json`); document.body.append(file); file.click(); file.remove(); } -function uploadConfig(e) { - if (e.target.files.length == 1) { - const file = e.target.files[0]; +function uploadConfig(e: Event, element: HTMLElement) { + const target = e.target as HTMLInputElement; + if (target.files.length == 1) { + const file = target.files[0]; const reader = new FileReader(); - const element = document.querySelector("[data-sync='*']") as HTMLElement; reader.onload = function(ev) { setTextOption("*", element, ev.target.result as string, () => { - e.target.value = null; + target.value = null; }); }; reader.readAsText(file); @@ -669,32 +697,14 @@ function validateServerAddress(input: string): string { } function copyDebugOutputToClipboard() { - // Build output debug information object - const output = { - debug: { - userAgent: navigator.userAgent, - platform: navigator.platform, - language: navigator.language, - extensionVersion: chrome.runtime.getManifest().version - }, - config: JSON.parse(JSON.stringify(Config.cachedSyncConfig)) // Deep clone config object - }; - - // Sanitise sensitive user config values - delete output.config.userID; - output.config.serverAddress = (output.config.serverAddress === CompileConfig.serverAddress) - ? "Default server address" : "Custom server address"; - output.config.invidiousInstances = output.config.invidiousInstances.length; - output.config.whitelistedChannels = output.config.whitelistedChannels.length; - // Copy object to clipboard - navigator.clipboard.writeText(JSON.stringify(output, null, 4)) - .then(() => { + navigator.clipboard.writeText(generateDebugDetails()) + .then(() => { alert(chrome.i18n.getMessage("copyDebugInformationComplete")); - }) - .catch(() => { + }) + .catch(() => { alert(chrome.i18n.getMessage("copyDebugInformationFailed")); - }); + }); } function isIncognitoAllowed(): Promise<boolean> { diff --git a/src/popup.ts b/src/popup.ts index 234096fe..b20723a2 100644 --- a/src/popup.ts +++ b/src/popup.ts @@ -1,4 +1,4 @@ -import Config from "./config"; +import Config, { generateDebugDetails } from "./config"; import Utils from "./utils"; import { @@ -12,14 +12,16 @@ import { GetChannelIDResponse, IsChannelWhitelistedResponse, IsInfoFoundMessageResponse, + LogResponse, Message, MessageResponse, PopupMessage, + RefreshSegmentsResponse, SponsorStartResponse, VoteResponse, } from "./messageTypes"; import { showDonationLink } from "./utils/configUtils"; -import { AnimationUtils } from "./utils/animationUtils"; +import { AnimationUtils } from "../maze-utils/src/animationUtils"; import { shortCategoryName } from "./utils/categoryUtils"; import { localizeHtmlPage } from "../maze-utils/src/setup"; import { exportTimes } from "./utils/exporter"; @@ -27,6 +29,7 @@ import GenericNotice from "./render/GenericNotice"; import { getErrorMessage, getFormattedTime } from "../maze-utils/src/formating"; import { StorageChangesObject } from "../maze-utils/src/config"; import { getHash } from "../maze-utils/src/hash"; +import { asyncRequestToServer, sendRequestToServer } from "./utils/requests"; const utils = new Utils(); @@ -71,6 +74,12 @@ window.addEventListener("message", async (e): Promise<void> => { if (e.source !== window.parent) return; if (e.origin.endsWith('.youtube.com')) { allowPopup = true; + + if (e.data && e.data?.type === "style") { + const style = document.createElement("style"); + style.textContent = e.data.css; + document.head.appendChild(style); + } } }); @@ -87,6 +96,8 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> { type PageElements = { [key: string]: HTMLElement } & InputPageElements let stopLoadingAnimation = null; + // For loading video info from the page + let loadRetryCount = 0; //the start and end time pairs (2d) let sponsorTimes: SponsorTime[] = []; @@ -108,6 +119,10 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> { const PageElements: PageElements = {}; [ + "sbPopupLogo", + "sbYourWorkBox", + "videoInfo", + "sbFooter", "sponsorBlockPopupBody", "sponsorblockPopup", "sponsorStart", @@ -170,7 +185,8 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> { "exportSegmentsButton", "importSegmentsMenu", "importSegmentsText", - "importSegmentsSubmit" + "importSegmentsSubmit", + "debugLogs" ].forEach(id => PageElements[id] = document.getElementById(id)); @@ -198,6 +214,16 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> { } PageElements.sbDonate.addEventListener("click", () => Config.config.donateClicked = Config.config.donateClicked + 1); + if (Config.config.cleanPopup) { + PageElements.sbPopupLogo.classList.add("hidden"); + PageElements.sbYourWorkBox.classList.add("hidden"); + PageElements.sbFooter.classList.add("hidden"); + PageElements.sponsorTimesDonateContainer.classList.add("hidden"); + PageElements.mainControls.classList.add("hidden"); + + PageElements.videoInfo.style.marginTop = "10px"; + } + if (Config.config.testingServer) { PageElements.sbBetaServerWarning.classList.remove("hidden"); PageElements.sbBetaServerWarning.addEventListener("click", function () { @@ -231,6 +257,7 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> { PageElements.helpButton.addEventListener("click", openHelp); PageElements.refreshSegmentsButton.addEventListener("click", refreshSegments); PageElements.sbPopupIconCopyUserID.addEventListener("click", async () => copyToClipboard(await getHash(Config.config.userID))); + PageElements.debugLogs.addEventListener("click", copyDebgLogs); // Forward click events if (window !== window.top) { @@ -279,9 +306,9 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> { PageElements.showNoticeAgain.style.display = "unset"; } - const values = ["userName", "viewCount", "minutesSaved", "vip", "permissions"]; + const values = ["userName", "viewCount", "minutesSaved", "vip", "permissions", "segmentCount"]; - utils.asyncRequestToServer("GET", "/api/userInfo", { + asyncRequestToServer("GET", "/api/userInfo", { publicUserID: await getHash(Config.config.userID), values }).then((res) => { @@ -312,16 +339,18 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> { PageElements.sponsorTimesOthersTimeSavedDisplay.innerText = getFormattedHours(minutesSaved); } + //get the amount of times this user has contributed and display it to thank them + PageElements.sponsorTimesContributionsDisplay.innerText = Math.max(Config.config.sponsorTimesContributed ?? 0, userInfo.segmentCount).toLocaleString(); + PageElements.sponsorTimesContributionsContainer.classList.remove("hidden"); + + PageElements.sponsorTimesOthersTimeSavedEndWord.innerText = chrome.i18n.getMessage("minsLower"); + Config.config.isVip = userInfo.vip; Config.config.permissions = userInfo.permissions; } }); - //get the amount of times this user has contributed and display it to thank them - if (Config.config.sponsorTimesContributed != undefined) { - PageElements.sponsorTimesContributionsDisplay.innerText = Config.config.sponsorTimesContributed.toLocaleString(); - PageElements.sponsorTimesContributionsContainer.classList.remove("hidden"); - } + //get the amount of times this user has skipped a sponsor if (Config.config.skipCount != undefined) { @@ -388,9 +417,18 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> { currentVideoID = result.videoID; loadTabData(tabs, updating); - } else if (result === undefined && chrome.runtime.lastError) { - //this isn't a YouTube video then, or at least the content script is not loaded + } else { + // Handle error if it exists + chrome.runtime.lastError; + + // This isn't a YouTube video then, or at least the content script is not loaded displayNoVideo(); + + // Try again in some time if a failure + loadRetryCount++; + if (loadRetryCount < 6) { + setTimeout(() => getSegmentsFromContentScript(false), 100 * loadRetryCount); + } } }); } @@ -403,7 +441,7 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> { } await utils.wait(() => Config.config !== null, 5000, 10); - sponsorTimes = Config.config.unsubmittedSegments[currentVideoID] ?? []; + sponsorTimes = Config.local.unsubmittedSegments[currentVideoID] ?? []; updateSegmentEditingUI(); messageHandler.sendMessage( @@ -427,37 +465,35 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> { stopLoadingAnimation = null; } - if (chrome.runtime.lastError) { + if (chrome.runtime.lastError || request == undefined || request.found == undefined) { //This page doesn't have the injected content script, or at least not yet + // Or if the request is empty, meaning the current page is not YouTube or a video page displayNoVideo(); return; } - //if request is undefined, then the page currently being browsed is not YouTube - if (request != undefined) { - //remove loading text - PageElements.mainControls.style.display = "block"; - if (request.onMobileYouTube) PageElements.mainControls.classList.add("hidden"); - PageElements.whitelistButton.classList.remove("hidden"); - PageElements.loadingIndicator.style.display = "none"; - - downloadedTimes = request.sponsorTimes ?? []; - displayDownloadedSponsorTimes(downloadedTimes, request.time); - if (request.found) { - PageElements.videoFound.innerHTML = chrome.i18n.getMessage("sponsorFound"); - PageElements.issueReporterImportExport.classList.remove("hidden"); - } else if (request.status == 404 || request.status == 200) { - PageElements.videoFound.innerHTML = chrome.i18n.getMessage("sponsor404"); - PageElements.issueReporterImportExport.classList.remove("hidden"); + //remove loading text + PageElements.mainControls.style.display = "block"; + if (request.onMobileYouTube) PageElements.mainControls.classList.add("hidden"); + PageElements.whitelistButton.classList.remove("hidden"); + PageElements.loadingIndicator.style.display = "none"; + + downloadedTimes = request.sponsorTimes ?? []; + displayDownloadedSponsorTimes(downloadedTimes, request.time); + if (request.found) { + PageElements.videoFound.innerHTML = chrome.i18n.getMessage("sponsorFound"); + PageElements.issueReporterImportExport.classList.remove("hidden"); + } else if (request.status == 404 || request.status == 200) { + PageElements.videoFound.innerHTML = chrome.i18n.getMessage("sponsor404"); + PageElements.issueReporterImportExport.classList.remove("hidden"); + } else { + if (request.status) { + PageElements.videoFound.innerHTML = chrome.i18n.getMessage("connectionError") + request.status; } else { - if (request.status) { - PageElements.videoFound.innerHTML = chrome.i18n.getMessage("connectionError") + request.status; - } else { - PageElements.videoFound.innerHTML = chrome.i18n.getMessage("segmentsStillLoading"); - } - - PageElements.issueReporterImportExport.classList.remove("hidden"); + PageElements.videoFound.innerHTML = chrome.i18n.getMessage("segmentsStillLoading"); } + + PageElements.issueReporterImportExport.classList.remove("hidden"); } //see if whitelist button should be swapped @@ -495,7 +531,7 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> { function startSponsorCallback(response: SponsorStartResponse) { // Only update the segments after a segment was created if (!response.creatingSegment) { - sponsorTimes = Config.config.unsubmittedSegments[currentVideoID] || []; + sponsorTimes = Config.local.unsubmittedSegments[currentVideoID] || []; } // Update the UI @@ -530,7 +566,7 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> { return true; } }) - .sort((a, b) => a.segment[1] - b.segment[1]) + .sort((a, b) => b.segment[1] - a.segment[1]) .sort((a, b) => a.segment[0] - b.segment[0]); //add them as buttons to the issue reporting container @@ -737,7 +773,7 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> { } function isCreatingSegment(): boolean { - const segments = Config.config.unsubmittedSegments[currentVideoID]; + const segments = Config.local.unsubmittedSegments[currentVideoID]; if (!segments) return false; const lastSegment = segments[segments.length - 1]; return lastSegment && lastSegment?.segment?.length !== 2; @@ -804,7 +840,7 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> { PageElements.setUsernameStatus.style.display = "unset"; PageElements.setUsernameStatus.innerText = chrome.i18n.getMessage("Loading"); - utils.sendRequestToServer("POST", "/api/setUsername?userID=" + Config.config.userID + "&username=" + PageElements.usernameInput.value, function (response) { + sendRequestToServer("POST", "/api/setUsername?userID=" + Config.config.userID + "&username=" + PageElements.usernameInput.value, function (response) { if (response.status == 200) { //submitted PageElements.submitUsername.style.display = "none"; @@ -948,9 +984,17 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> { stopLoadingAnimation = AnimationUtils.applyLoadingAnimation(PageElements.refreshSegmentsButton, 0.3); } - function refreshSegments() { + async function refreshSegments() { startLoadingAnimation(); - sendTabMessage({ message: 'refreshSegments' }); + const response = await sendTabMessageAsync({ message: 'refreshSegments' }) as RefreshSegmentsResponse; + + if (response == null || !response.hasVideo) { + if (stopLoadingAnimation != null) { + stopLoadingAnimation(); + stopLoadingAnimation = null; + } + displayNoVideo(); + } } function skipSegment(actionType: ActionType, UUID: SegmentUUID, element?: HTMLElement): void { @@ -1062,7 +1106,7 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> { for (const key in changes) { switch(key) { case "unsubmittedSegments": - sponsorTimes = Config.config.unsubmittedSegments[currentVideoID] ?? []; + sponsorTimes = Config.local.unsubmittedSegments[currentVideoID] ?? []; updateSegmentEditingUI(); break; } @@ -1102,6 +1146,12 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> { } } + function copyDebgLogs() { + sendTabMessage({ message: "getLogs" }, (logs: LogResponse) => { + copyToClipboard(`${generateDebugDetails()}\n\nWarn:\n${logs.warn.join("\n")}\n\nDebug:\n${logs.debug.join("\n")}`); + }); + } + function onMessage(msg: PopupMessage) { switch (msg.message) { case "time": @@ -1112,7 +1162,7 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> { break; case "videoChanged": currentVideoID = msg.videoID - sponsorTimes = Config.config.unsubmittedSegments[currentVideoID] ?? []; + sponsorTimes = Config.local.unsubmittedSegments[currentVideoID] ?? []; updateSegmentEditingUI(); if (msg.whitelisted) { diff --git a/src/render/CategoryPill.tsx b/src/render/CategoryPill.tsx index 57730af9..20923fba 100644 --- a/src/render/CategoryPill.tsx +++ b/src/render/CategoryPill.tsx @@ -43,9 +43,15 @@ export class CategoryPill { } private async attachToPageInternal(): Promise<void> { - const referenceNode = + let referenceNode = await waitFor(() => getYouTubeTitleNode()); + // Experimental YouTube layout with description on right + const isOnDescriptionOnRightLayout = document.querySelector("#title #description"); + if (isOnDescriptionOnRightLayout) { + referenceNode = referenceNode.parentElement; + } + if (referenceNode && !referenceNode.contains(this.container)) { if (!this.container) { this.container = document.createElement('span'); @@ -91,7 +97,9 @@ export class CategoryPill { parent.appendChild(this.container); referenceNode.prepend(parent); - referenceNode.style.display = "flex"; + if (!isOnDescriptionOnRightLayout) { + referenceNode.style.display = "flex"; + } } } diff --git a/src/render/GenericNotice.tsx b/src/render/GenericNotice.tsx index d1a4443c..bbac6c94 100644 --- a/src/render/GenericNotice.tsx +++ b/src/render/GenericNotice.tsx @@ -8,6 +8,7 @@ const utils = new Utils(); import { ContentContainer } from "../types"; import NoticeTextSelectionComponent from "../components/NoticeTextSectionComponent"; import { ButtonListener } from "../../maze-utils/src/components/component-types"; +import { getVideo } from "../../maze-utils/src/video"; export interface TextBox { icon: string; @@ -75,7 +76,7 @@ export default class GenericNotice { {options.textBoxes?.length > 0 ? <tr id={"sponsorSkipNoticeMiddleRow" + this.idSuffix} className="sponsorTimeMessagesRow" - style={{maxHeight: this.contentContainer ? (this.contentContainer().v.offsetHeight - 200) + "px" : null}}> + style={{maxHeight: getVideo() ? (getVideo().offsetHeight - 200) + "px" : null}}> <td style={{width: "100%"}}> {this.getMessageBoxes(this.idSuffix, options.textBoxes)} </td> diff --git a/src/render/RectangleTooltip.tsx b/src/render/RectangleTooltip.tsx index 1b357fa8..d325688a 100644 --- a/src/render/RectangleTooltip.tsx +++ b/src/render/RectangleTooltip.tsx @@ -59,7 +59,7 @@ export class RectangleTooltip { className="sponsorBlockRectangleTooltip" > <div> <img className="sponsorSkipLogo sponsorSkipObject" - src={chrome.extension.getURL("icons/IconSponsorBlocker256px.png")}> + src={chrome.runtime.getURL("icons/IconSponsorBlocker256px.png")}> </img> <span className="sponsorSkipObject"> {this.text + (props.link ? ". " : "")} diff --git a/src/render/SubmissionNotice.tsx b/src/render/SubmissionNotice.tsx index 295d8e2b..c0159cc0 100644 --- a/src/render/SubmissionNotice.tsx +++ b/src/render/SubmissionNotice.tsx @@ -11,7 +11,7 @@ class SubmissionNotice { // Contains functions and variables from the content script needed by the skip notice contentContainer: () => unknown; - callback: () => unknown; + callback: () => Promise<boolean>; noticeRef: React.MutableRefObject<SubmissionNoticeComponent>; @@ -19,7 +19,7 @@ class SubmissionNotice { root: Root; - constructor(contentContainer: ContentContainer, callback: () => unknown) { + constructor(contentContainer: ContentContainer, callback: () => Promise<boolean>) { this.noticeRef = React.createRef(); this.contentContainer = contentContainer; @@ -52,6 +52,14 @@ class SubmissionNotice { this.noticeElement.remove(); } + + submit(): void { + this.noticeRef.current?.submit?.(); + } + + scrollToBottom(): void { + this.noticeRef.current?.scrollToBottom?.(); + } } export default SubmissionNotice;
\ No newline at end of file diff --git a/src/types.ts b/src/types.ts index 460a308d..d8634c91 100644 --- a/src/types.ts +++ b/src/types.ts @@ -10,7 +10,6 @@ export interface ContentContainer { sponsorTimes: SponsorTime[]; sponsorTimesSubmitting: SponsorTime[]; skipNotices: SkipNotice[]; - v: HTMLVideoElement; sponsorVideoID; reskipSponsorTime: (segment: SponsorTime, forceSeek?: boolean) => void; updatePreviewBar: () => void; @@ -57,7 +56,13 @@ export enum ActionType { Poi = "poi" } -export const ActionTypes = [ActionType.Skip, ActionType.Mute]; +export const ActionTypes = [ + ActionType.Skip, + ActionType.Mute, + ActionType.Chapter, + ActionType.Full, + ActionType.Poi +]; export type SegmentUUID = string & { __segmentUUIDBrand: unknown }; export type Category = string & { __categoryBrand: unknown }; diff --git a/src/utils.ts b/src/utils.ts index 7b3a3841..c1887119 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -2,10 +2,8 @@ import Config, { VideoDownvotes } from "./config"; import { CategorySelection, SponsorTime, BackgroundScriptContainer, Registration, VideoID, SponsorHideType, CategorySkipOption } from "./types"; import { getHash, HashedValue } from "../maze-utils/src/hash"; -import * as CompileConfig from "../config.json"; -import { isFirefoxOrSafari, waitFor } from "../maze-utils/src"; +import { waitFor } from "../maze-utils/src"; import { findValidElementFromSelector } from "../maze-utils/src/dom"; -import { FetchResponse, sendRequestToCustomServer } from "../maze-utils/src/background-request-proxy" import { isSafari } from "../maze-utils/src/config"; export default class Utils { @@ -48,10 +46,7 @@ export default class Utils { */ setupExtraSitePermissions(callback: (granted: boolean) => void): void { const permissions = []; - if (!isFirefoxOrSafari()) { - permissions.push("declarativeContent"); - } - if (!isFirefoxOrSafari() || isSafari()) { + if (isSafari()) { permissions.push("webNavigation"); } @@ -69,6 +64,17 @@ export default class Utils { }); } + getExtraSiteRegistration(): Registration { + return { + message: "registerContentScript", + id: "invidious", + allFrames: true, + js: this.js, + css: this.css, + matches: this.getPermissionRegex() + }; + } + /** * Registers the content scripts for the extra sites. * Will use a different method depending on the browser. @@ -77,14 +83,7 @@ export default class Utils { * For now, it is just SB.config.invidiousInstances. */ setupExtraSiteContentScripts(): void { - const registration: Registration = { - message: "registerContentScript", - id: "invidious", - allFrames: true, - js: this.js, - css: this.css, - matches: this.getPermissionRegex() - }; + const registration = this.getExtraSiteRegistration(); if (this.backgroundScriptContainer) { this.backgroundScriptContainer.registerFirefoxContentScript(registration); @@ -108,11 +107,6 @@ export default class Utils { }); } - if (!isFirefoxOrSafari() && chrome.declarativeContent) { - // Only if we have permission - chrome.declarativeContent.onPageChanged.removeRules(["invidious"]); - } - chrome.permissions.remove({ origins: this.getPermissionRegex() }); @@ -137,8 +131,10 @@ export default class Utils { containsInvidiousPermission(): Promise<boolean> { return new Promise((resolve) => { - let permissions = ["declarativeContent"]; - if (isFirefoxOrSafari()) permissions = []; + const permissions = []; + if (isSafari()) { + permissions.push("webNavigation"); + } chrome.permissions.contains({ origins: this.getPermissionRegex(), @@ -240,50 +236,6 @@ export default class Utils { return permissionRegex; } - /** - * Sends a request to a custom server - * - * @param type The request type. "GET", "POST", etc. - * @param address The address to add to the SponsorBlock server address - * @param callback - */ - asyncRequestToCustomServer(type: string, url: string, data = {}): Promise<FetchResponse> { - return sendRequestToCustomServer(type, url, data); - } - - /** - * Sends a request to the SponsorBlock server with address added as a query - * - * @param type The request type. "GET", "POST", etc. - * @param address The address to add to the SponsorBlock server address - * @param callback - */ - async asyncRequestToServer(type: string, address: string, data = {}): Promise<FetchResponse> { - const serverAddress = Config.config.testingServer ? CompileConfig.testingServerAddress : Config.config.serverAddress; - - return await (this.asyncRequestToCustomServer(type, serverAddress + address, data)); - } - - /** - * Sends a request to the SponsorBlock server with address added as a query - * - * @param type The request type. "GET", "POST", etc. - * @param address The address to add to the SponsorBlock server address - * @param callback - */ - sendRequestToServer(type: string, address: string, callback?: (response: FetchResponse) => void): void { - const serverAddress = Config.config.testingServer ? CompileConfig.testingServerAddress : Config.config.serverAddress; - - // Ask the background script to do the work - chrome.runtime.sendMessage({ - message: "sendRequest", - type, - url: serverAddress + address - }, (response) => { - callback(response); - }); - } - findReferenceNode(): HTMLElement { const selectors = [ "#player-container-id", // Mobile YouTube @@ -327,7 +279,8 @@ export default class Utils { } async addHiddenSegment(videoID: VideoID, segmentUUID: string, hidden: SponsorHideType) { - if (chrome.extension.inIncognitoContext || !Config.config.trackDownvotes) return; + if ((chrome.extension.inIncognitoContext && !Config.config.trackDownvotesInPrivate) + || !Config.config.trackDownvotes) return; const hashedVideoID = (await getHash(videoID, 1)).slice(0, 4) as VideoID & HashedValue; const UUIDHash = await getHash(segmentUUID, 1); diff --git a/src/utils/animationUtils.ts b/src/utils/animationUtils.ts deleted file mode 100644 index 08a59ce0..00000000 --- a/src/utils/animationUtils.ts +++ /dev/null @@ -1,78 +0,0 @@ - /** - * Starts a spinning animation and returns a function to be called when it should be stopped - * The callback will be called when the animation is finished - * It waits until a full rotation is complete - */ -function applyLoadingAnimation(element: HTMLElement, time: number, callback?: () => void): () => Promise<void> { - element.style.animation = `rotate ${time}s 0s infinite`; - - return async () => new Promise((resolve) => { - // Make the animation finite - element.style.animation = `rotate ${time}s`; - - // When the animation is over, hide the button - const animationEndListener = () => { - if (callback) callback(); - - element.style.animation = "none"; - - element.removeEventListener("animationend", animationEndListener); - - resolve(); - }; - - element.addEventListener("animationend", animationEndListener); - }); -} - -function setupCustomHideAnimation(element: Element, container: Element, enabled = true, rightSlide = true): { hide: () => void; show: () => void } { - if (enabled) element.classList.add("autoHiding"); - element.classList.add("sbhidden"); - element.classList.add("animationDone"); - if (!rightSlide) element.classList.add("autoHideLeft"); - - let mouseEntered = false; - - return { - hide: () => { - mouseEntered = false; - if (element.classList.contains("autoHiding")) { - element.classList.add("sbhidden"); - } - }, - show: () => { - mouseEntered = true; - element.classList.remove("animationDone"); - - // Wait for next event loop - setTimeout(() => { - if (mouseEntered) element.classList.remove("sbhidden") - }, 10); - } - }; -} - -function setupAutoHideAnimation(element: Element, container: Element, enabled = true, rightSlide = true): void { - const { hide, show } = this.setupCustomHideAnimation(element, container, enabled, rightSlide); - - container.addEventListener("mouseleave", () => hide()); - container.addEventListener("mouseenter", () => show()); -} - -function enableAutoHideAnimation(element: Element): void { - element.classList.add("autoHiding"); - element.classList.add("sbhidden"); -} - -function disableAutoHideAnimation(element: Element): void { - element.classList.remove("autoHiding"); - element.classList.remove("sbhidden"); -} - -export const AnimationUtils = { - applyLoadingAnimation, - setupAutoHideAnimation, - setupCustomHideAnimation, - enableAutoHideAnimation, - disableAutoHideAnimation -};
\ No newline at end of file diff --git a/src/utils/constants.ts b/src/utils/constants.ts index dd44676a..afceb710 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -157,4 +157,6 @@ export function getGuidelineInfo(category: Category): TextBox[] { text: chrome.i18n.getMessage(`generic_guideline2`) }]; } -}
\ No newline at end of file +} + +export const defaultPreviewTime = 2;
\ No newline at end of file diff --git a/src/utils/exporter.ts b/src/utils/exporter.ts index a5871b65..85e1b383 100644 --- a/src/utils/exporter.ts +++ b/src/utils/exporter.ts @@ -53,24 +53,23 @@ export function importTimes(data: string, videoDuration: number): SponsorTime[] titleRight = removeIf(split2[split2.length - 1], specialCharMatchers) const title = titleLeft?.length > titleRight?.length ? titleLeft : titleRight; - if (title) { - const determinedCategory = chapterNames.find(c => c.names.includes(title))?.code as Category; - - const segment: SponsorTime = { - segment: [startTime, getFormattedTimeToSeconds(match[1])], - category: determinedCategory ?? ("chapter" as Category), - actionType: determinedCategory ? ActionType.Skip : ActionType.Chapter, - description: title, - source: SponsorSourceType.Local, - UUID: generateUserID() as SegmentUUID - }; - - if (result.length > 0 && result[result.length - 1].segment[1] === null) { - result[result.length - 1].segment[1] = segment.segment[0]; - } - - result.push(segment); + const determinedCategory = chapterNames.find(c => c.names.includes(title))?.code as Category; + + const category = title ? (determinedCategory ?? ("chapter" as Category)) : "chooseACategory" as Category; + const segment: SponsorTime = { + segment: [startTime, getFormattedTimeToSeconds(match[1])], + category, + actionType: category === "chapter" ? ActionType.Chapter : ActionType.Skip, + description: category === "chapter" ? title : null, + source: SponsorSourceType.Local, + UUID: generateUserID() as SegmentUUID + }; + + if (result.length > 0 && result[result.length - 1].segment[1] === null) { + result[result.length - 1].segment[1] = segment.segment[0]; } + + result.push(segment); } } } @@ -106,5 +105,5 @@ export function exportTimesAsHashParam(segments: SponsorTime[]): string { export function normalizeChapterName(description: string): string { - return description.toLowerCase().replace(/\.|:|-/g, "").replace(/\s+/g, " "); + return description.toLowerCase().replace(/[.:'’`‛‘"‟”-]/ug, "").replace(/\s+/g, " "); }
\ No newline at end of file diff --git a/src/utils/logger.ts b/src/utils/logger.ts index 2d3a1b92..8e9928b5 100644 --- a/src/utils/logger.ts +++ b/src/utils/logger.ts @@ -1,12 +1,22 @@ -window["SBLogs"] = { - debug: [], - warn: [] -}; +if (typeof (window) !== "undefined") { + window["SBLogs"] = { + debug: [], + warn: [] + }; +} export function logDebug(message: string) { - window["SBLogs"].debug.push(`[${new Date().toISOString()}] ${message}`); + if (typeof (window) !== "undefined") { + window["SBLogs"].debug.push(`[${new Date().toISOString()}] ${message}`); + } else { + console.log(`[${new Date().toISOString()}] ${message}`) + } } export function logWarn(message: string) { - window["SBLogs"].warn.push(`[${new Date().toISOString()}] ${message}`); + if (typeof (window) !== "undefined") { + window["SBLogs"].warn.push(`[${new Date().toISOString()}] ${message}`); + } else { + console.warn(`[${new Date().toISOString()}] ${message}`) + } }
\ No newline at end of file diff --git a/src/utils/mobileUtils.ts b/src/utils/mobileUtils.ts new file mode 100644 index 00000000..3cff18f7 --- /dev/null +++ b/src/utils/mobileUtils.ts @@ -0,0 +1,9 @@ +export function isMobileControlsOpen(): boolean { + const overlay = document.getElementById("player-control-overlay"); + + if (overlay) { + return !!overlay?.classList?.contains("fadein"); + } + + return false; +}
\ No newline at end of file diff --git a/src/utils/requests.ts b/src/utils/requests.ts new file mode 100644 index 00000000..8ce80601 --- /dev/null +++ b/src/utils/requests.ts @@ -0,0 +1,47 @@ +import Config from "../config"; +import * as CompileConfig from "../../config.json"; +import { FetchResponse, sendRequestToCustomServer } from "../../maze-utils/src/background-request-proxy"; + +/** + * Sends a request to a custom server + * + * @param type The request type. "GET", "POST", etc. + * @param address The address to add to the SponsorBlock server address + * @param callback + */ +export function asyncRequestToCustomServer(type: string, url: string, data = {}, headers = {}): Promise<FetchResponse> { + return sendRequestToCustomServer(type, url, data, headers); +} + +/** + * Sends a request to the SponsorBlock server with address added as a query + * + * @param type The request type. "GET", "POST", etc. + * @param address The address to add to the SponsorBlock server address + * @param callback + */ +export async function asyncRequestToServer(type: string, address: string, data = {}, headers = {}): Promise<FetchResponse> { + const serverAddress = Config.config.testingServer ? CompileConfig.testingServerAddress : Config.config.serverAddress; + + return await (asyncRequestToCustomServer(type, serverAddress + address, data, headers)); +} + +/** + * Sends a request to the SponsorBlock server with address added as a query + * + * @param type The request type. "GET", "POST", etc. + * @param address The address to add to the SponsorBlock server address + * @param callback + */ +export function sendRequestToServer(type: string, address: string, callback?: (response: FetchResponse) => void): void { + const serverAddress = Config.config.testingServer ? CompileConfig.testingServerAddress : Config.config.serverAddress; + + // Ask the background script to do the work + chrome.runtime.sendMessage({ + message: "sendRequest", + type, + url: serverAddress + address + }, (response) => { + callback(response); + }); +}
\ No newline at end of file diff --git a/src/utils/segmentData.ts b/src/utils/segmentData.ts new file mode 100644 index 00000000..1c2e631a --- /dev/null +++ b/src/utils/segmentData.ts @@ -0,0 +1,104 @@ +import { DataCache } from "../../maze-utils/src/cache"; +import { getHash, HashedValue } from "../../maze-utils/src/hash"; +import Config from "../config"; +import * as CompileConfig from "../../config.json"; +import { ActionType, ActionTypes, SponsorSourceType, SponsorTime, VideoID } from "../types"; +import { getHashParams } from "./pageUtils"; +import { asyncRequestToServer } from "./requests"; + +const segmentDataCache = new DataCache<VideoID, SegmentResponse>(() => { + return { + segments: null, + status: 200 + }; +}, 5); + +const pendingList: Record<VideoID, Promise<SegmentResponse>> = {}; + +export interface SegmentResponse { + segments: SponsorTime[] | null; + status: number; +} + +export async function getSegmentsForVideo(videoID: VideoID, ignoreCache: boolean): Promise<SegmentResponse> { + if (!ignoreCache) { + const cachedData = segmentDataCache.getFromCache(videoID); + if (cachedData) { + segmentDataCache.cacheUsed(videoID); + return cachedData; + } + } + + if (pendingList[videoID]) { + return await pendingList[videoID]; + } + + const pendingData = fetchSegmentsForVideo(videoID); + pendingList[videoID] = pendingData; + + const result = await pendingData; + delete pendingList[videoID]; + + return result; +} + +async function fetchSegmentsForVideo(videoID: VideoID): Promise<SegmentResponse> { + const categories: string[] = Config.config.categorySelections.map((category) => category.name); + + const extraRequestData: Record<string, unknown> = {}; + const hashParams = getHashParams(); + if (hashParams.requiredSegment) extraRequestData.requiredSegment = hashParams.requiredSegment; + + const hashPrefix = (await getHash(videoID, 1)).slice(0, 4) as VideoID & HashedValue; + const response = await asyncRequestToServer('GET', "/api/skipSegments/" + hashPrefix, { + categories: CompileConfig.categoryList, + actionTypes: ActionTypes, + ...extraRequestData + }, { + "X-CLIENT-NAME": `${chrome.runtime.id}/v${chrome.runtime.getManifest().version}` + }); + + if (response.ok) { + const enabledActionTypes = getEnabledActionTypes(); + + const receivedSegments: SponsorTime[] = JSON.parse(response.responseText) + ?.filter((video) => video.videoID === videoID) + ?.map((video) => video.segments)?.[0] + ?.filter((segment) => enabledActionTypes.includes(segment.actionType) && categories.includes(segment.category)) + ?.map((segment) => ({ + ...segment, + source: SponsorSourceType.Server + })) + ?.sort((a, b) => a.segment[0] - b.segment[0]); + + if (receivedSegments && receivedSegments.length) { + const result = { + segments: receivedSegments, + status: response.status + }; + + segmentDataCache.setupCache(videoID).segments = result.segments; + return result; + } else { + // Setup with null data + segmentDataCache.setupCache(videoID); + } + } + + return { + segments: null, + status: response.status + }; +} + +function getEnabledActionTypes(forceFullVideo = false): ActionType[] { + const actionTypes = [ActionType.Skip, ActionType.Poi, ActionType.Chapter]; + if (Config.config.muteSegments) { + actionTypes.push(ActionType.Mute); + } + if (Config.config.fullVideoSegments || forceFullVideo) { + actionTypes.push(ActionType.Full); + } + + return actionTypes; +}
\ No newline at end of file diff --git a/src/utils/thumbnails.ts b/src/utils/thumbnails.ts index 61d28f18..0fb2579e 100644 --- a/src/utils/thumbnails.ts +++ b/src/utils/thumbnails.ts @@ -1,10 +1,15 @@ import { isOnInvidious, parseYouTubeVideoIDFromURL } from "../../maze-utils/src/video"; import Config from "../config"; import { getVideoLabel } from "./videoLabels"; -import { setThumbnailListener } from "../../maze-utils/src/thumbnailManagement"; - -export async function labelThumbnails(thumbnails: HTMLImageElement[]): Promise<void> { - await Promise.all(thumbnails.map((t) => labelThumbnail(t))); +import { getThumbnailSelector, setThumbnailListener } from "../../maze-utils/src/thumbnailManagement"; +import { VideoID } from "../types"; +import { getSegmentsForVideo } from "./segmentData"; + +export async function handleThumbnails(thumbnails: HTMLImageElement[]): Promise<void> { + await Promise.all(thumbnails.map((t) => { + labelThumbnail(t); + setupThumbnailHover(t); + })); } export async function labelThumbnail(thumbnail: HTMLImageElement): Promise<HTMLElement | null> { @@ -13,9 +18,7 @@ export async function labelThumbnail(thumbnail: HTMLImageElement): Promise<HTMLE return null; } - const link = (isOnInvidious() ? thumbnail.parentElement : thumbnail.querySelector("#thumbnail")) as HTMLAnchorElement - if (!link || link.nodeName !== "A" || !link.href) return null; // no link found - const videoID = parseYouTubeVideoIDFromURL(link.href)?.videoID; + const videoID = extractVideoID(thumbnail); if (!videoID) { hideThumbnailLabel(thumbnail); return null; @@ -37,6 +40,37 @@ export async function labelThumbnail(thumbnail: HTMLImageElement): Promise<HTMLE return overlay; } +export async function setupThumbnailHover(thumbnail: HTMLImageElement): Promise<void> { + // Cache would be reset every load due to no SPA + if (isOnInvidious()) return; + + const mainElement = thumbnail.closest("#dismissible") as HTMLElement; + if (mainElement) { + mainElement.removeEventListener("mouseenter", thumbnailHoverListener); + mainElement.addEventListener("mouseenter", thumbnailHoverListener); + } +} + +function thumbnailHoverListener(e: MouseEvent) { + if (!chrome.runtime?.id) return; + + const thumbnail = (e.target as HTMLElement).querySelector(getThumbnailSelector()) as HTMLImageElement; + if (!thumbnail) return; + + // Pre-fetch data for this video + const videoID = extractVideoID(thumbnail); + if (videoID) { + void getSegmentsForVideo(videoID, false); + } +} + +function extractVideoID(thumbnail: HTMLImageElement): VideoID | null { + const link = (isOnInvidious() ? thumbnail.parentElement : thumbnail.querySelector("#thumbnail")) as HTMLAnchorElement + if (!link || link.nodeName !== "A" || !link.href) return null; // no link found + + return parseYouTubeVideoIDFromURL(link.href)?.videoID; +} + function getOldThumbnailLabel(thumbnail: HTMLImageElement): HTMLElement | null { return thumbnail.querySelector(".sponsorThumbnailLabel") as HTMLElement | null; } @@ -109,7 +143,7 @@ function insertSBIconDefinition() { } export function setupThumbnailListener(): void { - setThumbnailListener(labelThumbnails, () => { + setThumbnailListener(handleThumbnails, () => { insertSBIconDefinition(); }, () => Config.isReady()); }
\ No newline at end of file diff --git a/src/utils/videoLabels.ts b/src/utils/videoLabels.ts index 731bfd33..82af788c 100644 --- a/src/utils/videoLabels.ts +++ b/src/utils/videoLabels.ts @@ -2,6 +2,7 @@ import { Category, CategorySkipOption, VideoID } from "../types"; import { getHash } from "../../maze-utils/src/hash"; import Utils from "../utils"; import { logWarn } from "./logger"; +import { asyncRequestToServer } from "./requests"; const utils = new Utils(); @@ -20,7 +21,7 @@ async function getLabelHashBlock(hashPrefix: string): Promise<LabelCacheEntry | return cachedEntry; } - const response = await utils.asyncRequestToServer("GET", `/api/videoLabels/${hashPrefix}`); + const response = await asyncRequestToServer("GET", `/api/videoLabels/${hashPrefix}`); if (response.status !== 200) { // No video labels or server down labelCache[hashPrefix] = { diff --git a/src/utils/warnings.ts b/src/utils/warnings.ts index 72062699..e35c703c 100644 --- a/src/utils/warnings.ts +++ b/src/utils/warnings.ts @@ -3,8 +3,7 @@ import { getHash } from "../../maze-utils/src/hash"; import Config from "../config"; import GenericNotice, { NoticeOptions } from "../render/GenericNotice"; import { ContentContainer } from "../types"; -import Utils from "../utils"; -const utils = new Utils(); +import { asyncRequestToServer } from "./requests"; export interface ChatConfig { displayName: string; @@ -13,14 +12,14 @@ export interface ChatConfig { } export async function openWarningDialog(contentContainer: ContentContainer): Promise<void> { - const userInfo = await utils.asyncRequestToServer("GET", "/api/userInfo", { + const userInfo = await asyncRequestToServer("GET", "/api/userInfo", { publicUserID: await getHash(Config.config.userID), values: ["warningReason"] }); if (userInfo.ok) { const warningReason = JSON.parse(userInfo.responseText)?.warningReason; - const userNameData = await utils.asyncRequestToServer("GET", "/api/getUsername?userID=" + Config.config.userID); + const userNameData = await asyncRequestToServer("GET", "/api/getUsername?userID=" + Config.config.userID); const userName = userNameData.ok ? JSON.parse(userNameData.responseText).userName : ""; const publicUserID = await getHash(Config.config.userID); @@ -43,7 +42,7 @@ export async function openWarningDialog(contentContainer: ContentContainer): Pro { name: chrome.i18n.getMessage("warningConfirmButton"), listener: async () => { - const result = await utils.asyncRequestToServer("POST", "/api/warnUser", { + const result = await asyncRequestToServer("POST", "/api/warnUser", { userID: Config.config.userID, enabled: false }); diff --git a/webpack/webpack.common.js b/webpack/webpack.common.js index 21ff3582..6ba75b12 100644 --- a/webpack/webpack.common.js +++ b/webpack/webpack.common.js @@ -160,7 +160,7 @@ module.exports = env => { if (path.match(/(\/|\\)_locales(\/|\\).+/)) { const parsed = JSON.parse(content.toString()); if (env.browser.toLowerCase() === "safari") { - parsed.fullName.message = parsed.fullName.message.match(/^.+(?= -)/)?.[0] || parsed.fullName.message; + parsed.fullName.message = parsed.fullName.message.match(/^.+(?= [-–])/)?.[0] || parsed.fullName.message; if (parsed.fullName.message.length > 50) { parsed.fullName.message = parsed.fullName.message.slice(0, 47) + "..."; } diff --git a/webpack/webpack.manifest.js b/webpack/webpack.manifest.js index 3041fe6d..a7a5ffcb 100644 --- a/webpack/webpack.manifest.js +++ b/webpack/webpack.manifest.js @@ -11,6 +11,7 @@ const chromeManifestExtra = require("../manifest/chrome-manifest-extra.json"); const safariManifestExtra = require("../manifest/safari-manifest-extra.json"); const betaManifestExtra = require("../manifest/beta-manifest-extra.json"); const firefoxBetaManifestExtra = require("../manifest/firefox-beta-manifest-extra.json"); +const manifestV2ManifestExtra = require("../manifest/manifest-v2-extra.json"); // schema for options object const schema = { @@ -41,12 +42,14 @@ class BuildManifest { // Add missing manifest elements if (this.options.browser.toLowerCase() === "firefox") { + mergeObjects(manifest, manifestV2ManifestExtra); mergeObjects(manifest, firefoxManifestExtra); } else if (this.options.browser.toLowerCase() === "chrome" || this.options.browser.toLowerCase() === "chromium" || this.options.browser.toLowerCase() === "edge") { mergeObjects(manifest, chromeManifestExtra); } else if (this.options.browser.toLowerCase() === "safari") { + mergeObjects(manifest, manifestV2ManifestExtra); mergeObjects(manifest, safariManifestExtra); } |