├── .editorconfig ├── .eslintignore ├── .eslintrc.cjs ├── .github └── workflows │ └── deploy.workflow.yaml ├── .gitignore ├── .husky └── pre-commit ├── .prettierignore ├── .prettierrc.cjs ├── .vscode └── extensions.json ├── LICENSE ├── README.md ├── index.html ├── package copy.json ├── package.json ├── pnpm-lock.yaml ├── postcss.config.cjs ├── public ├── assets │ ├── chrisvdev1.png │ ├── fonts │ │ ├── inter-latin-400-normal.woff │ │ ├── inter-latin-400-normal.woff2 │ │ └── inter-latin-variable-wghtOnly-normal.woff2 │ ├── get_url_params.js │ ├── load_css.js │ ├── niceDuck.jpg │ ├── pato1.jpg │ ├── pato2.jpg │ ├── pato3.jpg │ ├── pato4.jpg │ ├── pato5.jpg │ ├── quack.gif │ └── st-chrisvdev.gif └── vite.svg ├── src ├── App.jsx ├── app.css ├── certs │ ├── cert.pem │ ├── key.pem │ ├── notebook.net.crt │ └── notebook.net.key ├── commands │ ├── filter_user.js │ └── speak.js ├── components │ ├── Message.jsx │ ├── StyleMessage.jsx │ └── message.css ├── filters │ ├── commands_filter.js │ ├── is_not_a_message.js │ └── users_filter.js ├── hooks │ ├── use_connect_websocket_to_twitch_irc.js │ ├── use_message_logic.js │ └── use_message_queue.js ├── index.css ├── lib │ ├── channel_resources.js │ ├── commands_container.js │ ├── commands_container_sonny.js │ ├── containers.js │ ├── get_avatar.js │ ├── get_url_params.js │ ├── get_variable.js │ ├── massage_filters.js │ ├── message_pre_processor.js │ ├── message_to_render_processor.js │ ├── new_tts_config_vault.js │ ├── regex_dynamic.js │ ├── render_badges.js │ ├── render_emoji.js │ ├── tts.js │ ├── tts_config_vault.js │ └── users_data_storage.js ├── main.jsx ├── middlewares │ ├── action.js │ ├── anti_ganzos.js │ ├── avatar_placer.js │ ├── defaultAvatar.js │ ├── filter_html_tags.js │ ├── get_message_emojis.js │ ├── link_remover.js │ ├── long_words_remover.js │ ├── message_cleaner.js │ ├── pato_bot_middleware.js │ ├── place_emojis.js │ ├── place_hearts.js │ ├── place_html.js │ ├── render_commands.js │ ├── speak_message_render.js │ ├── to_tts.js │ ├── tts_always_on.js │ └── username_placer.js └── render_commands │ └── html.js ├── tailwind.config.cjs ├── todo.txt └── vite.config.js /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | charset = utf-8 7 | end_of_line = lf 8 | indent_size = 2 9 | indent_style = space 10 | insert_final_newline = true 11 | trim_trailing_whitespace = true 12 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | dist 2 | -------------------------------------------------------------------------------- /.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | browser: true, 4 | es2021: true, 5 | node: true 6 | }, 7 | extends: ['standard', 'plugin:react/recommended', 'prettier'], 8 | overrides: [ 9 | { 10 | env: { 11 | node: true 12 | }, 13 | files: ['.eslintrc.{js,cjs}'], 14 | parserOptions: { 15 | sourceType: 'script' 16 | } 17 | } 18 | ], 19 | parserOptions: { 20 | ecmaVersion: 'latest', 21 | sourceType: 'module' 22 | }, 23 | settings: { 24 | react: { 25 | version: 'detect' 26 | } 27 | }, 28 | plugins: ['react'] 29 | } 30 | -------------------------------------------------------------------------------- /.github/workflows/deploy.workflow.yaml: -------------------------------------------------------------------------------- 1 | name: Deploy 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | jobs: 9 | deploy: 10 | name: Deploy 11 | runs-on: ubuntu-latest 12 | permissions: 13 | contents: write 14 | concurrency: 15 | group: ${{ github.workflow }}-${{ github.ref }} 16 | env: 17 | VITE_CLIENT_ID: ${{ secrets.VITE_CLIENT_ID }} 18 | VITE_REDIRECT_URI: https://chrisvdev.github.io/obs-chat 19 | 20 | steps: 21 | - name: Checkout 22 | uses: actions/checkout@v3 23 | - name: Setup pnpm 24 | uses: pnpm/action-setup@v2 25 | with: 26 | version: 8 27 | - name: Install Dependencies 28 | run: pnpm install 29 | - name: Build 30 | run: pnpm run build --base=/obs-chat/ 31 | - name: Deploy 32 | uses: peaceiris/actions-gh-pages@v3 33 | with: 34 | github_token: ${{ secrets.GITHUB_TOKEN }} 35 | publish_dir: ./dist 36 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | .eslintcache 16 | 17 | # Editor directories and files 18 | .vscode/* 19 | !.vscode/extensions.json 20 | .idea 21 | .DS_Store 22 | *.suo 23 | *.ntvs* 24 | *.njsproj 25 | *.sln 26 | *.sw? 27 | 28 | # Enviroment Variables 29 | .env 30 | .env-back 31 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | . "$(dirname -- "$0")/_/husky.sh" 3 | 4 | npx lint-staged 5 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | dist 2 | -------------------------------------------------------------------------------- /.prettierrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | semi: false, 3 | singleQuote: true, 4 | trailingComma: 'none', 5 | printWidth: 80 6 | } 7 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "esbenp.prettier-vscode", 4 | "standard.vscode-standard", 5 | "dbaeumer.vscode-eslint", 6 | "editorconfig.editorconfig" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU AFFERO GENERAL PUBLIC LICENSE 2 | Version 3, 19 November 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU Affero General Public License is a free, copyleft license for 11 | software and other kinds of works, specifically designed to ensure 12 | cooperation with the community in the case of network server software. 13 | 14 | The licenses for most software and other practical works are designed 15 | to take away your freedom to share and change the works. By contrast, 16 | our General Public Licenses are intended to guarantee your freedom to 17 | share and change all versions of a program--to make sure it remains free 18 | software for all its users. 19 | 20 | When we speak of free software, we are referring to freedom, not 21 | price. Our General Public Licenses are designed to make sure that you 22 | have the freedom to distribute copies of free software (and charge for 23 | them if you wish), that you receive source code or can get it if you 24 | want it, that you can change the software or use pieces of it in new 25 | free programs, and that you know you can do these things. 26 | 27 | Developers that use our General Public Licenses protect your rights 28 | with two steps: (1) assert copyright on the software, and (2) offer 29 | you this License which gives you legal permission to copy, distribute 30 | and/or modify the software. 31 | 32 | A secondary benefit of defending all users' freedom is that 33 | improvements made in alternate versions of the program, if they 34 | receive widespread use, become available for other developers to 35 | incorporate. Many developers of free software are heartened and 36 | encouraged by the resulting cooperation. However, in the case of 37 | software used on network servers, this result may fail to come about. 38 | The GNU General Public License permits making a modified version and 39 | letting the public access it on a server without ever releasing its 40 | source code to the public. 41 | 42 | The GNU Affero General Public License is designed specifically to 43 | ensure that, in such cases, the modified source code becomes available 44 | to the community. It requires the operator of a network server to 45 | provide the source code of the modified version running there to the 46 | users of that server. Therefore, public use of a modified version, on 47 | a publicly accessible server, gives the public access to the source 48 | code of the modified version. 49 | 50 | An older license, called the Affero General Public License and 51 | published by Affero, was designed to accomplish similar goals. This is 52 | a different license, not a version of the Affero GPL, but Affero has 53 | released a new version of the Affero GPL which permits relicensing under 54 | this license. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | TERMS AND CONDITIONS 60 | 61 | 0. Definitions. 62 | 63 | "This License" refers to version 3 of the GNU Affero General Public License. 64 | 65 | "Copyright" also means copyright-like laws that apply to other kinds of 66 | works, such as semiconductor masks. 67 | 68 | "The Program" refers to any copyrightable work licensed under this 69 | License. Each licensee is addressed as "you". "Licensees" and 70 | "recipients" may be individuals or organizations. 71 | 72 | To "modify" a work means to copy from or adapt all or part of the work 73 | in a fashion requiring copyright permission, other than the making of an 74 | exact copy. The resulting work is called a "modified version" of the 75 | earlier work or a work "based on" the earlier work. 76 | 77 | A "covered work" means either the unmodified Program or a work based 78 | on the Program. 79 | 80 | To "propagate" a work means to do anything with it that, without 81 | permission, would make you directly or secondarily liable for 82 | infringement under applicable copyright law, except executing it on a 83 | computer or modifying a private copy. Propagation includes copying, 84 | distribution (with or without modification), making available to the 85 | public, and in some countries other activities as well. 86 | 87 | To "convey" a work means any kind of propagation that enables other 88 | parties to make or receive copies. Mere interaction with a user through 89 | a computer network, with no transfer of a copy, is not conveying. 90 | 91 | An interactive user interface displays "Appropriate Legal Notices" 92 | to the extent that it includes a convenient and prominently visible 93 | feature that (1) displays an appropriate copyright notice, and (2) 94 | tells the user that there is no warranty for the work (except to the 95 | extent that warranties are provided), that licensees may convey the 96 | work under this License, and how to view a copy of this License. If 97 | the interface presents a list of user commands or options, such as a 98 | menu, a prominent item in the list meets this criterion. 99 | 100 | 1. Source Code. 101 | 102 | The "source code" for a work means the preferred form of the work 103 | for making modifications to it. "Object code" means any non-source 104 | form of a work. 105 | 106 | A "Standard Interface" means an interface that either is an official 107 | standard defined by a recognized standards body, or, in the case of 108 | interfaces specified for a particular programming language, one that 109 | is widely used among developers working in that language. 110 | 111 | The "System Libraries" of an executable work include anything, other 112 | than the work as a whole, that (a) is included in the normal form of 113 | packaging a Major Component, but which is not part of that Major 114 | Component, and (b) serves only to enable use of the work with that 115 | Major Component, or to implement a Standard Interface for which an 116 | implementation is available to the public in source code form. A 117 | "Major Component", in this context, means a major essential component 118 | (kernel, window system, and so on) of the specific operating system 119 | (if any) on which the executable work runs, or a compiler used to 120 | produce the work, or an object code interpreter used to run it. 121 | 122 | The "Corresponding Source" for a work in object code form means all 123 | the source code needed to generate, install, and (for an executable 124 | work) run the object code and to modify the work, including scripts to 125 | control those activities. However, it does not include the work's 126 | System Libraries, or general-purpose tools or generally available free 127 | programs which are used unmodified in performing those activities but 128 | which are not part of the work. For example, Corresponding Source 129 | includes interface definition files associated with source files for 130 | the work, and the source code for shared libraries and dynamically 131 | linked subprograms that the work is specifically designed to require, 132 | such as by intimate data communication or control flow between those 133 | subprograms and other parts of the work. 134 | 135 | The Corresponding Source need not include anything that users 136 | can regenerate automatically from other parts of the Corresponding 137 | Source. 138 | 139 | The Corresponding Source for a work in source code form is that 140 | same work. 141 | 142 | 2. Basic Permissions. 143 | 144 | All rights granted under this License are granted for the term of 145 | copyright on the Program, and are irrevocable provided the stated 146 | conditions are met. This License explicitly affirms your unlimited 147 | permission to run the unmodified Program. The output from running a 148 | covered work is covered by this License only if the output, given its 149 | content, constitutes a covered work. This License acknowledges your 150 | rights of fair use or other equivalent, as provided by copyright law. 151 | 152 | You may make, run and propagate covered works that you do not 153 | convey, without conditions so long as your license otherwise remains 154 | in force. You may convey covered works to others for the sole purpose 155 | of having them make modifications exclusively for you, or provide you 156 | with facilities for running those works, provided that you comply with 157 | the terms of this License in conveying all material for which you do 158 | not control copyright. Those thus making or running the covered works 159 | for you must do so exclusively on your behalf, under your direction 160 | and control, on terms that prohibit them from making any copies of 161 | your copyrighted material outside their relationship with you. 162 | 163 | Conveying under any other circumstances is permitted solely under 164 | the conditions stated below. Sublicensing is not allowed; section 10 165 | makes it unnecessary. 166 | 167 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 168 | 169 | No covered work shall be deemed part of an effective technological 170 | measure under any applicable law fulfilling obligations under article 171 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 172 | similar laws prohibiting or restricting circumvention of such 173 | measures. 174 | 175 | When you convey a covered work, you waive any legal power to forbid 176 | circumvention of technological measures to the extent such circumvention 177 | is effected by exercising rights under this License with respect to 178 | the covered work, and you disclaim any intention to limit operation or 179 | modification of the work as a means of enforcing, against the work's 180 | users, your or third parties' legal rights to forbid circumvention of 181 | technological measures. 182 | 183 | 4. Conveying Verbatim Copies. 184 | 185 | You may convey verbatim copies of the Program's source code as you 186 | receive it, in any medium, provided that you conspicuously and 187 | appropriately publish on each copy an appropriate copyright notice; 188 | keep intact all notices stating that this License and any 189 | non-permissive terms added in accord with section 7 apply to the code; 190 | keep intact all notices of the absence of any warranty; and give all 191 | recipients a copy of this License along with the Program. 192 | 193 | You may charge any price or no price for each copy that you convey, 194 | and you may offer support or warranty protection for a fee. 195 | 196 | 5. Conveying Modified Source Versions. 197 | 198 | You may convey a work based on the Program, or the modifications to 199 | produce it from the Program, in the form of source code under the 200 | terms of section 4, provided that you also meet all of these conditions: 201 | 202 | a) The work must carry prominent notices stating that you modified 203 | it, and giving a relevant date. 204 | 205 | b) The work must carry prominent notices stating that it is 206 | released under this License and any conditions added under section 207 | 7. This requirement modifies the requirement in section 4 to 208 | "keep intact all notices". 209 | 210 | c) You must license the entire work, as a whole, under this 211 | License to anyone who comes into possession of a copy. This 212 | License will therefore apply, along with any applicable section 7 213 | additional terms, to the whole of the work, and all its parts, 214 | regardless of how they are packaged. This License gives no 215 | permission to license the work in any other way, but it does not 216 | invalidate such permission if you have separately received it. 217 | 218 | d) If the work has interactive user interfaces, each must display 219 | Appropriate Legal Notices; however, if the Program has interactive 220 | interfaces that do not display Appropriate Legal Notices, your 221 | work need not make them do so. 222 | 223 | A compilation of a covered work with other separate and independent 224 | works, which are not by their nature extensions of the covered work, 225 | and which are not combined with it such as to form a larger program, 226 | in or on a volume of a storage or distribution medium, is called an 227 | "aggregate" if the compilation and its resulting copyright are not 228 | used to limit the access or legal rights of the compilation's users 229 | beyond what the individual works permit. Inclusion of a covered work 230 | in an aggregate does not cause this License to apply to the other 231 | parts of the aggregate. 232 | 233 | 6. Conveying Non-Source Forms. 234 | 235 | You may convey a covered work in object code form under the terms 236 | of sections 4 and 5, provided that you also convey the 237 | machine-readable Corresponding Source under the terms of this License, 238 | in one of these ways: 239 | 240 | a) Convey the object code in, or embodied in, a physical product 241 | (including a physical distribution medium), accompanied by the 242 | Corresponding Source fixed on a durable physical medium 243 | customarily used for software interchange. 244 | 245 | b) Convey the object code in, or embodied in, a physical product 246 | (including a physical distribution medium), accompanied by a 247 | written offer, valid for at least three years and valid for as 248 | long as you offer spare parts or customer support for that product 249 | model, to give anyone who possesses the object code either (1) a 250 | copy of the Corresponding Source for all the software in the 251 | product that is covered by this License, on a durable physical 252 | medium customarily used for software interchange, for a price no 253 | more than your reasonable cost of physically performing this 254 | conveying of source, or (2) access to copy the 255 | Corresponding Source from a network server at no charge. 256 | 257 | c) Convey individual copies of the object code with a copy of the 258 | written offer to provide the Corresponding Source. This 259 | alternative is allowed only occasionally and noncommercially, and 260 | only if you received the object code with such an offer, in accord 261 | with subsection 6b. 262 | 263 | d) Convey the object code by offering access from a designated 264 | place (gratis or for a charge), and offer equivalent access to the 265 | Corresponding Source in the same way through the same place at no 266 | further charge. You need not require recipients to copy the 267 | Corresponding Source along with the object code. If the place to 268 | copy the object code is a network server, the Corresponding Source 269 | may be on a different server (operated by you or a third party) 270 | that supports equivalent copying facilities, provided you maintain 271 | clear directions next to the object code saying where to find the 272 | Corresponding Source. Regardless of what server hosts the 273 | Corresponding Source, you remain obligated to ensure that it is 274 | available for as long as needed to satisfy these requirements. 275 | 276 | e) Convey the object code using peer-to-peer transmission, provided 277 | you inform other peers where the object code and Corresponding 278 | Source of the work are being offered to the general public at no 279 | charge under subsection 6d. 280 | 281 | A separable portion of the object code, whose source code is excluded 282 | from the Corresponding Source as a System Library, need not be 283 | included in conveying the object code work. 284 | 285 | A "User Product" is either (1) a "consumer product", which means any 286 | tangible personal property which is normally used for personal, family, 287 | or household purposes, or (2) anything designed or sold for incorporation 288 | into a dwelling. In determining whether a product is a consumer product, 289 | doubtful cases shall be resolved in favor of coverage. For a particular 290 | product received by a particular user, "normally used" refers to a 291 | typical or common use of that class of product, regardless of the status 292 | of the particular user or of the way in which the particular user 293 | actually uses, or expects or is expected to use, the product. A product 294 | is a consumer product regardless of whether the product has substantial 295 | commercial, industrial or non-consumer uses, unless such uses represent 296 | the only significant mode of use of the product. 297 | 298 | "Installation Information" for a User Product means any methods, 299 | procedures, authorization keys, or other information required to install 300 | and execute modified versions of a covered work in that User Product from 301 | a modified version of its Corresponding Source. The information must 302 | suffice to ensure that the continued functioning of the modified object 303 | code is in no case prevented or interfered with solely because 304 | modification has been made. 305 | 306 | If you convey an object code work under this section in, or with, or 307 | specifically for use in, a User Product, and the conveying occurs as 308 | part of a transaction in which the right of possession and use of the 309 | User Product is transferred to the recipient in perpetuity or for a 310 | fixed term (regardless of how the transaction is characterized), the 311 | Corresponding Source conveyed under this section must be accompanied 312 | by the Installation Information. But this requirement does not apply 313 | if neither you nor any third party retains the ability to install 314 | modified object code on the User Product (for example, the work has 315 | been installed in ROM). 316 | 317 | The requirement to provide Installation Information does not include a 318 | requirement to continue to provide support service, warranty, or updates 319 | for a work that has been modified or installed by the recipient, or for 320 | the User Product in which it has been modified or installed. Access to a 321 | network may be denied when the modification itself materially and 322 | adversely affects the operation of the network or violates the rules and 323 | protocols for communication across the network. 324 | 325 | Corresponding Source conveyed, and Installation Information provided, 326 | in accord with this section must be in a format that is publicly 327 | documented (and with an implementation available to the public in 328 | source code form), and must require no special password or key for 329 | unpacking, reading or copying. 330 | 331 | 7. Additional Terms. 332 | 333 | "Additional permissions" are terms that supplement the terms of this 334 | License by making exceptions from one or more of its conditions. 335 | Additional permissions that are applicable to the entire Program shall 336 | be treated as though they were included in this License, to the extent 337 | that they are valid under applicable law. If additional permissions 338 | apply only to part of the Program, that part may be used separately 339 | under those permissions, but the entire Program remains governed by 340 | this License without regard to the additional permissions. 341 | 342 | When you convey a copy of a covered work, you may at your option 343 | remove any additional permissions from that copy, or from any part of 344 | it. (Additional permissions may be written to require their own 345 | removal in certain cases when you modify the work.) You may place 346 | additional permissions on material, added by you to a covered work, 347 | for which you have or can give appropriate copyright permission. 348 | 349 | Notwithstanding any other provision of this License, for material you 350 | add to a covered work, you may (if authorized by the copyright holders of 351 | that material) supplement the terms of this License with terms: 352 | 353 | a) Disclaiming warranty or limiting liability differently from the 354 | terms of sections 15 and 16 of this License; or 355 | 356 | b) Requiring preservation of specified reasonable legal notices or 357 | author attributions in that material or in the Appropriate Legal 358 | Notices displayed by works containing it; or 359 | 360 | c) Prohibiting misrepresentation of the origin of that material, or 361 | requiring that modified versions of such material be marked in 362 | reasonable ways as different from the original version; or 363 | 364 | d) Limiting the use for publicity purposes of names of licensors or 365 | authors of the material; or 366 | 367 | e) Declining to grant rights under trademark law for use of some 368 | trade names, trademarks, or service marks; or 369 | 370 | f) Requiring indemnification of licensors and authors of that 371 | material by anyone who conveys the material (or modified versions of 372 | it) with contractual assumptions of liability to the recipient, for 373 | any liability that these contractual assumptions directly impose on 374 | those licensors and authors. 375 | 376 | All other non-permissive additional terms are considered "further 377 | restrictions" within the meaning of section 10. If the Program as you 378 | received it, or any part of it, contains a notice stating that it is 379 | governed by this License along with a term that is a further 380 | restriction, you may remove that term. If a license document contains 381 | a further restriction but permits relicensing or conveying under this 382 | License, you may add to a covered work material governed by the terms 383 | of that license document, provided that the further restriction does 384 | not survive such relicensing or conveying. 385 | 386 | If you add terms to a covered work in accord with this section, you 387 | must place, in the relevant source files, a statement of the 388 | additional terms that apply to those files, or a notice indicating 389 | where to find the applicable terms. 390 | 391 | Additional terms, permissive or non-permissive, may be stated in the 392 | form of a separately written license, or stated as exceptions; 393 | the above requirements apply either way. 394 | 395 | 8. Termination. 396 | 397 | You may not propagate or modify a covered work except as expressly 398 | provided under this License. Any attempt otherwise to propagate or 399 | modify it is void, and will automatically terminate your rights under 400 | this License (including any patent licenses granted under the third 401 | paragraph of section 11). 402 | 403 | However, if you cease all violation of this License, then your 404 | license from a particular copyright holder is reinstated (a) 405 | provisionally, unless and until the copyright holder explicitly and 406 | finally terminates your license, and (b) permanently, if the copyright 407 | holder fails to notify you of the violation by some reasonable means 408 | prior to 60 days after the cessation. 409 | 410 | Moreover, your license from a particular copyright holder is 411 | reinstated permanently if the copyright holder notifies you of the 412 | violation by some reasonable means, this is the first time you have 413 | received notice of violation of this License (for any work) from that 414 | copyright holder, and you cure the violation prior to 30 days after 415 | your receipt of the notice. 416 | 417 | Termination of your rights under this section does not terminate the 418 | licenses of parties who have received copies or rights from you under 419 | this License. If your rights have been terminated and not permanently 420 | reinstated, you do not qualify to receive new licenses for the same 421 | material under section 10. 422 | 423 | 9. Acceptance Not Required for Having Copies. 424 | 425 | You are not required to accept this License in order to receive or 426 | run a copy of the Program. Ancillary propagation of a covered work 427 | occurring solely as a consequence of using peer-to-peer transmission 428 | to receive a copy likewise does not require acceptance. However, 429 | nothing other than this License grants you permission to propagate or 430 | modify any covered work. These actions infringe copyright if you do 431 | not accept this License. Therefore, by modifying or propagating a 432 | covered work, you indicate your acceptance of this License to do so. 433 | 434 | 10. Automatic Licensing of Downstream Recipients. 435 | 436 | Each time you convey a covered work, the recipient automatically 437 | receives a license from the original licensors, to run, modify and 438 | propagate that work, subject to this License. You are not responsible 439 | for enforcing compliance by third parties with this License. 440 | 441 | An "entity transaction" is a transaction transferring control of an 442 | organization, or substantially all assets of one, or subdividing an 443 | organization, or merging organizations. If propagation of a covered 444 | work results from an entity transaction, each party to that 445 | transaction who receives a copy of the work also receives whatever 446 | licenses to the work the party's predecessor in interest had or could 447 | give under the previous paragraph, plus a right to possession of the 448 | Corresponding Source of the work from the predecessor in interest, if 449 | the predecessor has it or can get it with reasonable efforts. 450 | 451 | You may not impose any further restrictions on the exercise of the 452 | rights granted or affirmed under this License. For example, you may 453 | not impose a license fee, royalty, or other charge for exercise of 454 | rights granted under this License, and you may not initiate litigation 455 | (including a cross-claim or counterclaim in a lawsuit) alleging that 456 | any patent claim is infringed by making, using, selling, offering for 457 | sale, or importing the Program or any portion of it. 458 | 459 | 11. Patents. 460 | 461 | A "contributor" is a copyright holder who authorizes use under this 462 | License of the Program or a work on which the Program is based. The 463 | work thus licensed is called the contributor's "contributor version". 464 | 465 | A contributor's "essential patent claims" are all patent claims 466 | owned or controlled by the contributor, whether already acquired or 467 | hereafter acquired, that would be infringed by some manner, permitted 468 | by this License, of making, using, or selling its contributor version, 469 | but do not include claims that would be infringed only as a 470 | consequence of further modification of the contributor version. For 471 | purposes of this definition, "control" includes the right to grant 472 | patent sublicenses in a manner consistent with the requirements of 473 | this License. 474 | 475 | Each contributor grants you a non-exclusive, worldwide, royalty-free 476 | patent license under the contributor's essential patent claims, to 477 | make, use, sell, offer for sale, import and otherwise run, modify and 478 | propagate the contents of its contributor version. 479 | 480 | In the following three paragraphs, a "patent license" is any express 481 | agreement or commitment, however denominated, not to enforce a patent 482 | (such as an express permission to practice a patent or covenant not to 483 | sue for patent infringement). To "grant" such a patent license to a 484 | party means to make such an agreement or commitment not to enforce a 485 | patent against the party. 486 | 487 | If you convey a covered work, knowingly relying on a patent license, 488 | and the Corresponding Source of the work is not available for anyone 489 | to copy, free of charge and under the terms of this License, through a 490 | publicly available network server or other readily accessible means, 491 | then you must either (1) cause the Corresponding Source to be so 492 | available, or (2) arrange to deprive yourself of the benefit of the 493 | patent license for this particular work, or (3) arrange, in a manner 494 | consistent with the requirements of this License, to extend the patent 495 | license to downstream recipients. "Knowingly relying" means you have 496 | actual knowledge that, but for the patent license, your conveying the 497 | covered work in a country, or your recipient's use of the covered work 498 | in a country, would infringe one or more identifiable patents in that 499 | country that you have reason to believe are valid. 500 | 501 | If, pursuant to or in connection with a single transaction or 502 | arrangement, you convey, or propagate by procuring conveyance of, a 503 | covered work, and grant a patent license to some of the parties 504 | receiving the covered work authorizing them to use, propagate, modify 505 | or convey a specific copy of the covered work, then the patent license 506 | you grant is automatically extended to all recipients of the covered 507 | work and works based on it. 508 | 509 | A patent license is "discriminatory" if it does not include within 510 | the scope of its coverage, prohibits the exercise of, or is 511 | conditioned on the non-exercise of one or more of the rights that are 512 | specifically granted under this License. You may not convey a covered 513 | work if you are a party to an arrangement with a third party that is 514 | in the business of distributing software, under which you make payment 515 | to the third party based on the extent of your activity of conveying 516 | the work, and under which the third party grants, to any of the 517 | parties who would receive the covered work from you, a discriminatory 518 | patent license (a) in connection with copies of the covered work 519 | conveyed by you (or copies made from those copies), or (b) primarily 520 | for and in connection with specific products or compilations that 521 | contain the covered work, unless you entered into that arrangement, 522 | or that patent license was granted, prior to 28 March 2007. 523 | 524 | Nothing in this License shall be construed as excluding or limiting 525 | any implied license or other defenses to infringement that may 526 | otherwise be available to you under applicable patent law. 527 | 528 | 12. No Surrender of Others' Freedom. 529 | 530 | If conditions are imposed on you (whether by court order, agreement or 531 | otherwise) that contradict the conditions of this License, they do not 532 | excuse you from the conditions of this License. If you cannot convey a 533 | covered work so as to satisfy simultaneously your obligations under this 534 | License and any other pertinent obligations, then as a consequence you may 535 | not convey it at all. For example, if you agree to terms that obligate you 536 | to collect a royalty for further conveying from those to whom you convey 537 | the Program, the only way you could satisfy both those terms and this 538 | License would be to refrain entirely from conveying the Program. 539 | 540 | 13. Remote Network Interaction; Use with the GNU General Public License. 541 | 542 | Notwithstanding any other provision of this License, if you modify the 543 | Program, your modified version must prominently offer all users 544 | interacting with it remotely through a computer network (if your version 545 | supports such interaction) an opportunity to receive the Corresponding 546 | Source of your version by providing access to the Corresponding Source 547 | from a network server at no charge, through some standard or customary 548 | means of facilitating copying of software. This Corresponding Source 549 | shall include the Corresponding Source for any work covered by version 3 550 | of the GNU General Public License that is incorporated pursuant to the 551 | following paragraph. 552 | 553 | Notwithstanding any other provision of this License, you have 554 | permission to link or combine any covered work with a work licensed 555 | under version 3 of the GNU General Public License into a single 556 | combined work, and to convey the resulting work. The terms of this 557 | License will continue to apply to the part which is the covered work, 558 | but the work with which it is combined will remain governed by version 559 | 3 of the GNU General Public License. 560 | 561 | 14. Revised Versions of this License. 562 | 563 | The Free Software Foundation may publish revised and/or new versions of 564 | the GNU Affero General Public License from time to time. Such new versions 565 | will be similar in spirit to the present version, but may differ in detail to 566 | address new problems or concerns. 567 | 568 | Each version is given a distinguishing version number. If the 569 | Program specifies that a certain numbered version of the GNU Affero General 570 | Public License "or any later version" applies to it, you have the 571 | option of following the terms and conditions either of that numbered 572 | version or of any later version published by the Free Software 573 | Foundation. If the Program does not specify a version number of the 574 | GNU Affero General Public License, you may choose any version ever published 575 | by the Free Software Foundation. 576 | 577 | If the Program specifies that a proxy can decide which future 578 | versions of the GNU Affero General Public License can be used, that proxy's 579 | public statement of acceptance of a version permanently authorizes you 580 | to choose that version for the Program. 581 | 582 | Later license versions may give you additional or different 583 | permissions. However, no additional obligations are imposed on any 584 | author or copyright holder as a result of your choosing to follow a 585 | later version. 586 | 587 | 15. Disclaimer of Warranty. 588 | 589 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 590 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 591 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 592 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 593 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 594 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 595 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 596 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 597 | 598 | 16. Limitation of Liability. 599 | 600 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 601 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 602 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 603 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 604 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 605 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 606 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 607 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 608 | SUCH DAMAGES. 609 | 610 | 17. Interpretation of Sections 15 and 16. 611 | 612 | If the disclaimer of warranty and limitation of liability provided 613 | above cannot be given local legal effect according to their terms, 614 | reviewing courts shall apply local law that most closely approximates 615 | an absolute waiver of all civil liability in connection with the 616 | Program, unless a warranty or assumption of liability accompanies a 617 | copy of the Program in return for a fee. 618 | 619 | END OF TERMS AND CONDITIONS 620 | 621 | How to Apply These Terms to Your New Programs 622 | 623 | If you develop a new program, and you want it to be of the greatest 624 | possible use to the public, the best way to achieve this is to make it 625 | free software which everyone can redistribute and change under these terms. 626 | 627 | To do so, attach the following notices to the program. It is safest 628 | to attach them to the start of each source file to most effectively 629 | state the exclusion of warranty; and each file should have at least 630 | the "copyright" line and a pointer to where the full notice is found. 631 | 632 | 633 | Copyright (C) 634 | 635 | This program is free software: you can redistribute it and/or modify 636 | it under the terms of the GNU Affero General Public License as published 637 | by the Free Software Foundation, either version 3 of the License, or 638 | (at your option) any later version. 639 | 640 | This program is distributed in the hope that it will be useful, 641 | but WITHOUT ANY WARRANTY; without even the implied warranty of 642 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 643 | GNU Affero General Public License for more details. 644 | 645 | You should have received a copy of the GNU Affero General Public License 646 | along with this program. If not, see . 647 | 648 | Also add information on how to contact you by electronic and paper mail. 649 | 650 | If your software can interact with users remotely through a computer 651 | network, you should also make sure that it provides a way for users to 652 | get its source. For example, if your program is a web application, its 653 | interface could display a "Source" link that leads users to an archive 654 | of the code. There are many ways you could offer source, and different 655 | solutions will be better for different programs; see section 13 for the 656 | specific requirements. 657 | 658 | You should also get your employer (if you work as a programmer) or school, 659 | if any, to sign a "copyright disclaimer" for the program, if necessary. 660 | For more information on this, and how to apply and follow the GNU AGPL, see 661 | . 662 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # obs-chat 2 | A Twitch chat viewer with a TTS integrated, made with React for use in OBS or any streaming software capable of using a browser as a source, which, in addition to using the twitch API, uses WebSockets to connect to their IRC server. 3 | 4 | ## You can use it in two ways... 5 | 6 | ### Building it 7 | 8 | **Prerequisites**: You need to have an account on [Twitch Developers](https://dev.twitch.tv/) to use the console for register an application and get the client ID. Then on the application panel you need to register the allowed URLs to redirect in case of a OAuth login (Always you need to register the URL "http://localhost:5173/" to develop in this repo) 9 | 10 | In order to launch or build the App you need to have an .env file like this 11 | 12 | ``` 13 | VITE_CLIENT_ID=dasdpljsadjpojsdiofgbhdfaiuogvb //the client ID given form the Twitch Developres console 14 | VITE_CHANNEL=chrisvdev // only for development if you need to hardcode the channel to watch 15 | VITE_DEFAULT_AVATAR= //to change the default avatar 16 | VITE_REDIRECT_URI=https://obs-chat.christianvillegas.com/&scope=chat%3Aread //only for build, if you don't give it the default redirect is to http://localhost:5173/&scope=chat%3Aread 17 | ``` 18 | 19 | 20 | ### Use it 21 | 22 | Go to the [project web page](https://chrisvdev.github.io/CVTalk/) 😉 23 | 24 | ... 25 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | OBS Chat Viewer 10 | 11 | 12 |
13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /package copy.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "obs-chat", 3 | "version": "0.0.0", 4 | "private": true, 5 | "type": "module", 6 | "scripts": { 7 | "build": "vite build", 8 | "dev": "vite", 9 | "prepare": "husky install", 10 | "preview": "vite preview" 11 | }, 12 | "lint-staged": { 13 | "./**/*.{js,mjs,cjs}": [ 14 | "eslint --cache --fix --ext .js,.mjs,.cjs ./", 15 | "prettier --cache --write \"./**/*.{js,mjs,cjs}\"" 16 | ], 17 | "./src/**/*.jsx": [ 18 | "eslint --cache --ext .jsx ./src/ --fix", 19 | "prettier --cache --write \"./src/**/*.jsx\"" 20 | ], 21 | "./src/**/*.css": "prettier --cache --write \"./src/styles/*.css\"", 22 | "./**/*.json": "prettier --cache --write \"./**/*.json\"", 23 | "./**/*.md": "prettier --cache --write \"./**/*.md\"" 24 | }, 25 | "dependencies": { 26 | "axios": "^1.3.5", 27 | "react": "^18.2.0", 28 | "react-dom": "^18.2.0", 29 | "react-use-websocket": "^4.3.1", 30 | "validator": "^13.11.0" 31 | }, 32 | "devDependencies": { 33 | "@types/react": "^18.0.28", 34 | "@types/react-dom": "^18.0.11", 35 | "@vitejs/plugin-react-swc": "^3.0.0", 36 | "autoprefixer": "^10.4.14", 37 | "eslint": "^8.0.1", 38 | "eslint-config-prettier": "^9.0.0", 39 | "eslint-config-standard": "^17.1.0", 40 | "eslint-plugin-import": "^2.25.2", 41 | "eslint-plugin-n": "^15.0.0 || ^16.0.0 ", 42 | "eslint-plugin-promise": "^6.0.0", 43 | "eslint-plugin-react": "^7.33.2", 44 | "husky": "^8.0.3", 45 | "lint-staged": "^14.0.1", 46 | "postcss": "^8.4.21", 47 | "prettier": "^3.0.2", 48 | "tailwindcss": "^3.2.7", 49 | "vite": "^4.2.0" 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "obs-chat", 3 | "version": "0.0.0", 4 | "private": true, 5 | "type": "module", 6 | "scripts": { 7 | "build": "vite build", 8 | "dev": "vite", 9 | "prepare": "husky install", 10 | "preview": "vite preview" 11 | }, 12 | "lint-staged": { 13 | "./**/*.{js,mjs,cjs}": [ 14 | "eslint --cache --fix --ext .js,.mjs,.cjs ./", 15 | "prettier --cache --write \"./**/*.{js,mjs,cjs}\"" 16 | ], 17 | "./src/**/*.jsx": [ 18 | "eslint --cache --ext .jsx ./src/ --fix", 19 | "prettier --cache --write \"./src/**/*.jsx\"" 20 | ], 21 | "./**/*.json": "prettier --cache --write \"./**/*.json\"", 22 | "./**/*.md": "prettier --cache --write \"./**/*.md\"" 23 | }, 24 | "dependencies": { 25 | "axios": "^1.3.5", 26 | "react": "^18.2.0", 27 | "react-dom": "^18.2.0", 28 | "react-use-websocket": "^4.3.1", 29 | "validator": "^13.11.0" 30 | }, 31 | "devDependencies": { 32 | "@types/react": "^18.0.28", 33 | "@types/react-dom": "^18.0.11", 34 | "@vitejs/plugin-react-swc": "^3.0.0", 35 | "autoprefixer": "^10.4.14", 36 | "eslint": "^8.0.1", 37 | "eslint-config-prettier": "^9.0.0", 38 | "eslint-config-standard": "^17.1.0", 39 | "eslint-plugin-import": "^2.25.2", 40 | "eslint-plugin-n": "^15.0.0 || ^16.0.0 ", 41 | "eslint-plugin-promise": "^6.0.0", 42 | "eslint-plugin-react": "^7.33.2", 43 | "husky": "^8.0.3", 44 | "lint-staged": "^14.0.1", 45 | "postcss": "^8.4.21", 46 | "prettier": "^3.0.2", 47 | "tailwindcss": "^3.2.7", 48 | "vite": "^4.2.0" 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: '6.0' 2 | 3 | settings: 4 | autoInstallPeers: true 5 | excludeLinksFromLockfile: false 6 | 7 | dependencies: 8 | axios: 9 | specifier: ^1.3.5 10 | version: 1.3.5 11 | react: 12 | specifier: ^18.2.0 13 | version: 18.2.0 14 | react-dom: 15 | specifier: ^18.2.0 16 | version: 18.2.0(react@18.2.0) 17 | react-use-websocket: 18 | specifier: ^4.3.1 19 | version: 4.3.1(react-dom@18.2.0)(react@18.2.0) 20 | validator: 21 | specifier: ^13.11.0 22 | version: 13.11.0 23 | 24 | devDependencies: 25 | '@types/react': 26 | specifier: ^18.0.28 27 | version: 18.0.28 28 | '@types/react-dom': 29 | specifier: ^18.0.11 30 | version: 18.0.11 31 | '@vitejs/plugin-react-swc': 32 | specifier: ^3.0.0 33 | version: 3.2.0(vite@4.2.0) 34 | autoprefixer: 35 | specifier: ^10.4.14 36 | version: 10.4.14(postcss@8.4.21) 37 | eslint: 38 | specifier: ^8.0.1 39 | version: 8.0.1 40 | eslint-config-prettier: 41 | specifier: ^9.0.0 42 | version: 9.0.0(eslint@8.0.1) 43 | eslint-config-standard: 44 | specifier: ^17.1.0 45 | version: 17.1.0(eslint-plugin-import@2.25.2)(eslint-plugin-n@15.0.0)(eslint-plugin-promise@6.0.0)(eslint@8.0.1) 46 | eslint-plugin-import: 47 | specifier: ^2.25.2 48 | version: 2.25.2(eslint@8.0.1) 49 | eslint-plugin-n: 50 | specifier: '^15.0.0 || ^16.0.0 ' 51 | version: 15.0.0(eslint@8.0.1) 52 | eslint-plugin-promise: 53 | specifier: ^6.0.0 54 | version: 6.0.0(eslint@8.0.1) 55 | eslint-plugin-react: 56 | specifier: ^7.33.2 57 | version: 7.33.2(eslint@8.0.1) 58 | husky: 59 | specifier: ^8.0.3 60 | version: 8.0.3 61 | lint-staged: 62 | specifier: ^14.0.1 63 | version: 14.0.1 64 | postcss: 65 | specifier: ^8.4.21 66 | version: 8.4.21 67 | prettier: 68 | specifier: ^3.0.2 69 | version: 3.0.2 70 | tailwindcss: 71 | specifier: ^3.2.7 72 | version: 3.2.7(postcss@8.4.21) 73 | vite: 74 | specifier: ^4.2.0 75 | version: 4.2.0 76 | 77 | packages: 78 | 79 | /@aashutoshrathi/word-wrap@1.2.6: 80 | resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==} 81 | engines: {node: '>=0.10.0'} 82 | dev: true 83 | 84 | /@esbuild/android-arm64@0.17.12: 85 | resolution: {integrity: sha512-WQ9p5oiXXYJ33F2EkE3r0FRDFVpEdcDiwNX3u7Xaibxfx6vQE0Sb8ytrfQsA5WO6kDn6mDfKLh6KrPBjvkk7xA==} 86 | engines: {node: '>=12'} 87 | cpu: [arm64] 88 | os: [android] 89 | requiresBuild: true 90 | dev: true 91 | optional: true 92 | 93 | /@esbuild/android-arm@0.17.12: 94 | resolution: {integrity: sha512-E/sgkvwoIfj4aMAPL2e35VnUJspzVYl7+M1B2cqeubdBhADV4uPon0KCc8p2G+LqSJ6i8ocYPCqY3A4GGq0zkQ==} 95 | engines: {node: '>=12'} 96 | cpu: [arm] 97 | os: [android] 98 | requiresBuild: true 99 | dev: true 100 | optional: true 101 | 102 | /@esbuild/android-x64@0.17.12: 103 | resolution: {integrity: sha512-m4OsaCr5gT+se25rFPHKQXARMyAehHTQAz4XX1Vk3d27VtqiX0ALMBPoXZsGaB6JYryCLfgGwUslMqTfqeLU0w==} 104 | engines: {node: '>=12'} 105 | cpu: [x64] 106 | os: [android] 107 | requiresBuild: true 108 | dev: true 109 | optional: true 110 | 111 | /@esbuild/darwin-arm64@0.17.12: 112 | resolution: {integrity: sha512-O3GCZghRIx+RAN0NDPhyyhRgwa19MoKlzGonIb5hgTj78krqp9XZbYCvFr9N1eUxg0ZQEpiiZ4QvsOQwBpP+lg==} 113 | engines: {node: '>=12'} 114 | cpu: [arm64] 115 | os: [darwin] 116 | requiresBuild: true 117 | dev: true 118 | optional: true 119 | 120 | /@esbuild/darwin-x64@0.17.12: 121 | resolution: {integrity: sha512-5D48jM3tW27h1qjaD9UNRuN+4v0zvksqZSPZqeSWggfMlsVdAhH3pwSfQIFJwcs9QJ9BRibPS4ViZgs3d2wsCA==} 122 | engines: {node: '>=12'} 123 | cpu: [x64] 124 | os: [darwin] 125 | requiresBuild: true 126 | dev: true 127 | optional: true 128 | 129 | /@esbuild/freebsd-arm64@0.17.12: 130 | resolution: {integrity: sha512-OWvHzmLNTdF1erSvrfoEBGlN94IE6vCEaGEkEH29uo/VoONqPnoDFfShi41Ew+yKimx4vrmmAJEGNoyyP+OgOQ==} 131 | engines: {node: '>=12'} 132 | cpu: [arm64] 133 | os: [freebsd] 134 | requiresBuild: true 135 | dev: true 136 | optional: true 137 | 138 | /@esbuild/freebsd-x64@0.17.12: 139 | resolution: {integrity: sha512-A0Xg5CZv8MU9xh4a+7NUpi5VHBKh1RaGJKqjxe4KG87X+mTjDE6ZvlJqpWoeJxgfXHT7IMP9tDFu7IZ03OtJAw==} 140 | engines: {node: '>=12'} 141 | cpu: [x64] 142 | os: [freebsd] 143 | requiresBuild: true 144 | dev: true 145 | optional: true 146 | 147 | /@esbuild/linux-arm64@0.17.12: 148 | resolution: {integrity: sha512-cK3AjkEc+8v8YG02hYLQIQlOznW+v9N+OI9BAFuyqkfQFR+DnDLhEM5N8QRxAUz99cJTo1rLNXqRrvY15gbQUg==} 149 | engines: {node: '>=12'} 150 | cpu: [arm64] 151 | os: [linux] 152 | requiresBuild: true 153 | dev: true 154 | optional: true 155 | 156 | /@esbuild/linux-arm@0.17.12: 157 | resolution: {integrity: sha512-WsHyJ7b7vzHdJ1fv67Yf++2dz3D726oO3QCu8iNYik4fb5YuuReOI9OtA+n7Mk0xyQivNTPbl181s+5oZ38gyA==} 158 | engines: {node: '>=12'} 159 | cpu: [arm] 160 | os: [linux] 161 | requiresBuild: true 162 | dev: true 163 | optional: true 164 | 165 | /@esbuild/linux-ia32@0.17.12: 166 | resolution: {integrity: sha512-jdOBXJqcgHlah/nYHnj3Hrnl9l63RjtQ4vn9+bohjQPI2QafASB5MtHAoEv0JQHVb/xYQTFOeuHnNYE1zF7tYw==} 167 | engines: {node: '>=12'} 168 | cpu: [ia32] 169 | os: [linux] 170 | requiresBuild: true 171 | dev: true 172 | optional: true 173 | 174 | /@esbuild/linux-loong64@0.17.12: 175 | resolution: {integrity: sha512-GTOEtj8h9qPKXCyiBBnHconSCV9LwFyx/gv3Phw0pa25qPYjVuuGZ4Dk14bGCfGX3qKF0+ceeQvwmtI+aYBbVA==} 176 | engines: {node: '>=12'} 177 | cpu: [loong64] 178 | os: [linux] 179 | requiresBuild: true 180 | dev: true 181 | optional: true 182 | 183 | /@esbuild/linux-mips64el@0.17.12: 184 | resolution: {integrity: sha512-o8CIhfBwKcxmEENOH9RwmUejs5jFiNoDw7YgS0EJTF6kgPgcqLFjgoc5kDey5cMHRVCIWc6kK2ShUePOcc7RbA==} 185 | engines: {node: '>=12'} 186 | cpu: [mips64el] 187 | os: [linux] 188 | requiresBuild: true 189 | dev: true 190 | optional: true 191 | 192 | /@esbuild/linux-ppc64@0.17.12: 193 | resolution: {integrity: sha512-biMLH6NR/GR4z+ap0oJYb877LdBpGac8KfZoEnDiBKd7MD/xt8eaw1SFfYRUeMVx519kVkAOL2GExdFmYnZx3A==} 194 | engines: {node: '>=12'} 195 | cpu: [ppc64] 196 | os: [linux] 197 | requiresBuild: true 198 | dev: true 199 | optional: true 200 | 201 | /@esbuild/linux-riscv64@0.17.12: 202 | resolution: {integrity: sha512-jkphYUiO38wZGeWlfIBMB72auOllNA2sLfiZPGDtOBb1ELN8lmqBrlMiucgL8awBw1zBXN69PmZM6g4yTX84TA==} 203 | engines: {node: '>=12'} 204 | cpu: [riscv64] 205 | os: [linux] 206 | requiresBuild: true 207 | dev: true 208 | optional: true 209 | 210 | /@esbuild/linux-s390x@0.17.12: 211 | resolution: {integrity: sha512-j3ucLdeY9HBcvODhCY4b+Ds3hWGO8t+SAidtmWu/ukfLLG/oYDMaA+dnugTVAg5fnUOGNbIYL9TOjhWgQB8W5g==} 212 | engines: {node: '>=12'} 213 | cpu: [s390x] 214 | os: [linux] 215 | requiresBuild: true 216 | dev: true 217 | optional: true 218 | 219 | /@esbuild/linux-x64@0.17.12: 220 | resolution: {integrity: sha512-uo5JL3cgaEGotaqSaJdRfFNSCUJOIliKLnDGWaVCgIKkHxwhYMm95pfMbWZ9l7GeW9kDg0tSxcy9NYdEtjwwmA==} 221 | engines: {node: '>=12'} 222 | cpu: [x64] 223 | os: [linux] 224 | requiresBuild: true 225 | dev: true 226 | optional: true 227 | 228 | /@esbuild/netbsd-x64@0.17.12: 229 | resolution: {integrity: sha512-DNdoRg8JX+gGsbqt2gPgkgb00mqOgOO27KnrWZtdABl6yWTST30aibGJ6geBq3WM2TIeW6COs5AScnC7GwtGPg==} 230 | engines: {node: '>=12'} 231 | cpu: [x64] 232 | os: [netbsd] 233 | requiresBuild: true 234 | dev: true 235 | optional: true 236 | 237 | /@esbuild/openbsd-x64@0.17.12: 238 | resolution: {integrity: sha512-aVsENlr7B64w8I1lhHShND5o8cW6sB9n9MUtLumFlPhG3elhNWtE7M1TFpj3m7lT3sKQUMkGFjTQBrvDDO1YWA==} 239 | engines: {node: '>=12'} 240 | cpu: [x64] 241 | os: [openbsd] 242 | requiresBuild: true 243 | dev: true 244 | optional: true 245 | 246 | /@esbuild/sunos-x64@0.17.12: 247 | resolution: {integrity: sha512-qbHGVQdKSwi0JQJuZznS4SyY27tYXYF0mrgthbxXrZI3AHKuRvU+Eqbg/F0rmLDpW/jkIZBlCO1XfHUBMNJ1pg==} 248 | engines: {node: '>=12'} 249 | cpu: [x64] 250 | os: [sunos] 251 | requiresBuild: true 252 | dev: true 253 | optional: true 254 | 255 | /@esbuild/win32-arm64@0.17.12: 256 | resolution: {integrity: sha512-zsCp8Ql+96xXTVTmm6ffvoTSZSV2B/LzzkUXAY33F/76EajNw1m+jZ9zPfNJlJ3Rh4EzOszNDHsmG/fZOhtqDg==} 257 | engines: {node: '>=12'} 258 | cpu: [arm64] 259 | os: [win32] 260 | requiresBuild: true 261 | dev: true 262 | optional: true 263 | 264 | /@esbuild/win32-ia32@0.17.12: 265 | resolution: {integrity: sha512-FfrFjR4id7wcFYOdqbDfDET3tjxCozUgbqdkOABsSFzoZGFC92UK7mg4JKRc/B3NNEf1s2WHxJ7VfTdVDPN3ng==} 266 | engines: {node: '>=12'} 267 | cpu: [ia32] 268 | os: [win32] 269 | requiresBuild: true 270 | dev: true 271 | optional: true 272 | 273 | /@esbuild/win32-x64@0.17.12: 274 | resolution: {integrity: sha512-JOOxw49BVZx2/5tW3FqkdjSD/5gXYeVGPDcB0lvap0gLQshkh1Nyel1QazC+wNxus3xPlsYAgqU1BUmrmCvWtw==} 275 | engines: {node: '>=12'} 276 | cpu: [x64] 277 | os: [win32] 278 | requiresBuild: true 279 | dev: true 280 | optional: true 281 | 282 | /@eslint/eslintrc@1.4.1: 283 | resolution: {integrity: sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==} 284 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 285 | dependencies: 286 | ajv: 6.12.6 287 | debug: 4.3.4 288 | espree: 9.6.1 289 | globals: 13.21.0 290 | ignore: 5.2.4 291 | import-fresh: 3.3.0 292 | js-yaml: 4.1.0 293 | minimatch: 3.1.2 294 | strip-json-comments: 3.1.1 295 | transitivePeerDependencies: 296 | - supports-color 297 | dev: true 298 | 299 | /@humanwhocodes/config-array@0.6.0: 300 | resolution: {integrity: sha512-JQlEKbcgEUjBFhLIF4iqM7u/9lwgHRBcpHrmUNCALK0Q3amXN6lxdoXLnF0sm11E9VqTmBALR87IlUg1bZ8A9A==} 301 | engines: {node: '>=10.10.0'} 302 | dependencies: 303 | '@humanwhocodes/object-schema': 1.2.1 304 | debug: 4.3.4 305 | minimatch: 3.1.2 306 | transitivePeerDependencies: 307 | - supports-color 308 | dev: true 309 | 310 | /@humanwhocodes/object-schema@1.2.1: 311 | resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} 312 | dev: true 313 | 314 | /@nodelib/fs.scandir@2.1.5: 315 | resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} 316 | engines: {node: '>= 8'} 317 | dependencies: 318 | '@nodelib/fs.stat': 2.0.5 319 | run-parallel: 1.2.0 320 | dev: true 321 | 322 | /@nodelib/fs.stat@2.0.5: 323 | resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} 324 | engines: {node: '>= 8'} 325 | dev: true 326 | 327 | /@nodelib/fs.walk@1.2.8: 328 | resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} 329 | engines: {node: '>= 8'} 330 | dependencies: 331 | '@nodelib/fs.scandir': 2.1.5 332 | fastq: 1.15.0 333 | dev: true 334 | 335 | /@swc/core-darwin-arm64@1.3.41: 336 | resolution: {integrity: sha512-D4fybODToO/BvuP35bionDUrSuTVVr8eW+mApr1unOqb3mfiqOrVv0VP2fpWNRYiA+xMq+oBCB6KcGpL60HKWQ==} 337 | engines: {node: '>=10'} 338 | cpu: [arm64] 339 | os: [darwin] 340 | requiresBuild: true 341 | dev: true 342 | optional: true 343 | 344 | /@swc/core-darwin-x64@1.3.41: 345 | resolution: {integrity: sha512-0RoVyiPCnylf3TG77C3S86PRSmaq+SaYB4VDLJFz3qcEHz1pfP0LhyskhgX4wjQV1mveDzFEn1BVAuo0eOMwZA==} 346 | engines: {node: '>=10'} 347 | cpu: [x64] 348 | os: [darwin] 349 | requiresBuild: true 350 | dev: true 351 | optional: true 352 | 353 | /@swc/core-linux-arm-gnueabihf@1.3.41: 354 | resolution: {integrity: sha512-mZW7GeY7Uw1nkKoWpx898ou20oCSt8MR+jAVuAhMjX+G4Zr0WWXYSigWNiRymhR6Q9KhyvoFpMckguSvYWmXsw==} 355 | engines: {node: '>=10'} 356 | cpu: [arm] 357 | os: [linux] 358 | requiresBuild: true 359 | dev: true 360 | optional: true 361 | 362 | /@swc/core-linux-arm64-gnu@1.3.41: 363 | resolution: {integrity: sha512-e91LGn+6KuLFw3sWk5swwGc/dP4tXs0mg3HrhjImRoofU02Bb9aHcj5zgrSO8ZByvDtm/Knn16h1ojxIMOFaxg==} 364 | engines: {node: '>=10'} 365 | cpu: [arm64] 366 | os: [linux] 367 | requiresBuild: true 368 | dev: true 369 | optional: true 370 | 371 | /@swc/core-linux-arm64-musl@1.3.41: 372 | resolution: {integrity: sha512-Q7hmrniLWsQ7zjtImGcjx1tl5/Qxpel+fC+OXTnGvAyyoGssSftIBlXMnqVLteL78zhxIPAzi+gizWAe5RGqrA==} 373 | engines: {node: '>=10'} 374 | cpu: [arm64] 375 | os: [linux] 376 | requiresBuild: true 377 | dev: true 378 | optional: true 379 | 380 | /@swc/core-linux-x64-gnu@1.3.41: 381 | resolution: {integrity: sha512-h4sv1sCfZQgRIwmykz8WPqVpbvHb13Qm3SsrbOudhAp2MuzpWzsgMP5hAEpdCP/nWreiCz3aoM6L8JeakRDq0g==} 382 | engines: {node: '>=10'} 383 | cpu: [x64] 384 | os: [linux] 385 | requiresBuild: true 386 | dev: true 387 | optional: true 388 | 389 | /@swc/core-linux-x64-musl@1.3.41: 390 | resolution: {integrity: sha512-Z7c26i38378d0NT/dcz8qPSAXm41lqhNzykdhKhI+95mA9m4pskP18T/0I45rmyx1ywifypu+Ip+SXmKeVSPgQ==} 391 | engines: {node: '>=10'} 392 | cpu: [x64] 393 | os: [linux] 394 | requiresBuild: true 395 | dev: true 396 | optional: true 397 | 398 | /@swc/core-win32-arm64-msvc@1.3.41: 399 | resolution: {integrity: sha512-I0CYnPc+ZGc912YeN0TykIOf/Q7yJQHRwDuhewwD6RkbiSEaVfSux5pAmmdoKw2aGMSq+cwLmgPe9HYLRNz+4w==} 400 | engines: {node: '>=10'} 401 | cpu: [arm64] 402 | os: [win32] 403 | requiresBuild: true 404 | dev: true 405 | optional: true 406 | 407 | /@swc/core-win32-ia32-msvc@1.3.41: 408 | resolution: {integrity: sha512-EygN4CVDWF29/U2T5fXGfWyLvRbMd2hiUgkciAl7zHuyJ6nKl+kpodqV2A0Wd4sFtSNedU0gQEBEXEe7cqvmsA==} 409 | engines: {node: '>=10'} 410 | cpu: [ia32] 411 | os: [win32] 412 | requiresBuild: true 413 | dev: true 414 | optional: true 415 | 416 | /@swc/core-win32-x64-msvc@1.3.41: 417 | resolution: {integrity: sha512-Mfp8qD1hNwWWRy0ISdwQJu1g0UYoVTtuQlO0z3aGbXqL51ew9e56+8j3M1U9i95lXFyWkARgjDCcKkQi+WezyA==} 418 | engines: {node: '>=10'} 419 | cpu: [x64] 420 | os: [win32] 421 | requiresBuild: true 422 | dev: true 423 | optional: true 424 | 425 | /@swc/core@1.3.41: 426 | resolution: {integrity: sha512-v6P2dfqJDpZ/7RXPvWge9oI6YgolDM0jtNhQZ2qdXrLBzaWQdDoBGBTJ8KN/nTgGhX3IkNvSB1fafXQ+nVnqAQ==} 427 | engines: {node: '>=10'} 428 | requiresBuild: true 429 | optionalDependencies: 430 | '@swc/core-darwin-arm64': 1.3.41 431 | '@swc/core-darwin-x64': 1.3.41 432 | '@swc/core-linux-arm-gnueabihf': 1.3.41 433 | '@swc/core-linux-arm64-gnu': 1.3.41 434 | '@swc/core-linux-arm64-musl': 1.3.41 435 | '@swc/core-linux-x64-gnu': 1.3.41 436 | '@swc/core-linux-x64-musl': 1.3.41 437 | '@swc/core-win32-arm64-msvc': 1.3.41 438 | '@swc/core-win32-ia32-msvc': 1.3.41 439 | '@swc/core-win32-x64-msvc': 1.3.41 440 | dev: true 441 | 442 | /@types/json5@0.0.29: 443 | resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} 444 | dev: true 445 | 446 | /@types/prop-types@15.7.5: 447 | resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==} 448 | dev: true 449 | 450 | /@types/react-dom@18.0.11: 451 | resolution: {integrity: sha512-O38bPbI2CWtgw/OoQoY+BRelw7uysmXbWvw3nLWO21H1HSh+GOlqPuXshJfjmpNlKiiSDG9cc1JZAaMmVdcTlw==} 452 | dependencies: 453 | '@types/react': 18.0.28 454 | dev: true 455 | 456 | /@types/react@18.0.28: 457 | resolution: {integrity: sha512-RD0ivG1kEztNBdoAK7lekI9M+azSnitIn85h4iOiaLjaTrMjzslhaqCGaI4IyCJ1RljWiLCEu4jyrLLgqxBTew==} 458 | dependencies: 459 | '@types/prop-types': 15.7.5 460 | '@types/scheduler': 0.16.2 461 | csstype: 3.1.1 462 | dev: true 463 | 464 | /@types/scheduler@0.16.2: 465 | resolution: {integrity: sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==} 466 | dev: true 467 | 468 | /@vitejs/plugin-react-swc@3.2.0(vite@4.2.0): 469 | resolution: {integrity: sha512-IcBoXL/mcH7JdQr/nfDlDwTdIaH8Rg7LpfQDF4nAht+juHWIuv6WhpKPCSfY4+zztAaB07qdBoFz1XCZsgo3pQ==} 470 | peerDependencies: 471 | vite: ^4 472 | dependencies: 473 | '@swc/core': 1.3.41 474 | vite: 4.2.0 475 | dev: true 476 | 477 | /acorn-jsx@5.3.2(acorn@8.10.0): 478 | resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} 479 | peerDependencies: 480 | acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 481 | dependencies: 482 | acorn: 8.10.0 483 | dev: true 484 | 485 | /acorn-node@1.8.2: 486 | resolution: {integrity: sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==} 487 | dependencies: 488 | acorn: 7.4.1 489 | acorn-walk: 7.2.0 490 | xtend: 4.0.2 491 | dev: true 492 | 493 | /acorn-walk@7.2.0: 494 | resolution: {integrity: sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==} 495 | engines: {node: '>=0.4.0'} 496 | dev: true 497 | 498 | /acorn@7.4.1: 499 | resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==} 500 | engines: {node: '>=0.4.0'} 501 | hasBin: true 502 | dev: true 503 | 504 | /acorn@8.10.0: 505 | resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==} 506 | engines: {node: '>=0.4.0'} 507 | hasBin: true 508 | dev: true 509 | 510 | /ajv@6.12.6: 511 | resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} 512 | dependencies: 513 | fast-deep-equal: 3.1.3 514 | fast-json-stable-stringify: 2.1.0 515 | json-schema-traverse: 0.4.1 516 | uri-js: 4.4.1 517 | dev: true 518 | 519 | /ansi-colors@4.1.3: 520 | resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} 521 | engines: {node: '>=6'} 522 | dev: true 523 | 524 | /ansi-escapes@5.0.0: 525 | resolution: {integrity: sha512-5GFMVX8HqE/TB+FuBJGuO5XG0WrsA6ptUqoODaT/n9mmUaZFkqnBueB4leqGBCmrUHnCnC4PCZTCd0E7QQ83bA==} 526 | engines: {node: '>=12'} 527 | dependencies: 528 | type-fest: 1.4.0 529 | dev: true 530 | 531 | /ansi-regex@5.0.1: 532 | resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} 533 | engines: {node: '>=8'} 534 | dev: true 535 | 536 | /ansi-regex@6.0.1: 537 | resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} 538 | engines: {node: '>=12'} 539 | dev: true 540 | 541 | /ansi-styles@4.3.0: 542 | resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} 543 | engines: {node: '>=8'} 544 | dependencies: 545 | color-convert: 2.0.1 546 | dev: true 547 | 548 | /ansi-styles@6.2.1: 549 | resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} 550 | engines: {node: '>=12'} 551 | dev: true 552 | 553 | /anymatch@3.1.3: 554 | resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} 555 | engines: {node: '>= 8'} 556 | dependencies: 557 | normalize-path: 3.0.0 558 | picomatch: 2.3.1 559 | dev: true 560 | 561 | /arg@5.0.2: 562 | resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} 563 | dev: true 564 | 565 | /argparse@2.0.1: 566 | resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} 567 | dev: true 568 | 569 | /array-buffer-byte-length@1.0.0: 570 | resolution: {integrity: sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==} 571 | dependencies: 572 | call-bind: 1.0.2 573 | is-array-buffer: 3.0.2 574 | dev: true 575 | 576 | /array-includes@3.1.6: 577 | resolution: {integrity: sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==} 578 | engines: {node: '>= 0.4'} 579 | dependencies: 580 | call-bind: 1.0.2 581 | define-properties: 1.2.0 582 | es-abstract: 1.22.1 583 | get-intrinsic: 1.2.1 584 | is-string: 1.0.7 585 | dev: true 586 | 587 | /array.prototype.flat@1.3.1: 588 | resolution: {integrity: sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==} 589 | engines: {node: '>= 0.4'} 590 | dependencies: 591 | call-bind: 1.0.2 592 | define-properties: 1.2.0 593 | es-abstract: 1.22.1 594 | es-shim-unscopables: 1.0.0 595 | dev: true 596 | 597 | /array.prototype.flatmap@1.3.1: 598 | resolution: {integrity: sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==} 599 | engines: {node: '>= 0.4'} 600 | dependencies: 601 | call-bind: 1.0.2 602 | define-properties: 1.2.0 603 | es-abstract: 1.22.1 604 | es-shim-unscopables: 1.0.0 605 | dev: true 606 | 607 | /array.prototype.tosorted@1.1.1: 608 | resolution: {integrity: sha512-pZYPXPRl2PqWcsUs6LOMn+1f1532nEoPTYowBtqLwAW+W8vSVhkIGnmOX1t/UQjD6YGI0vcD2B1U7ZFGQH9jnQ==} 609 | dependencies: 610 | call-bind: 1.0.2 611 | define-properties: 1.2.0 612 | es-abstract: 1.22.1 613 | es-shim-unscopables: 1.0.0 614 | get-intrinsic: 1.2.1 615 | dev: true 616 | 617 | /arraybuffer.prototype.slice@1.0.1: 618 | resolution: {integrity: sha512-09x0ZWFEjj4WD8PDbykUwo3t9arLn8NIzmmYEJFpYekOAQjpkGSyrQhNoRTcwwcFRu+ycWF78QZ63oWTqSjBcw==} 619 | engines: {node: '>= 0.4'} 620 | dependencies: 621 | array-buffer-byte-length: 1.0.0 622 | call-bind: 1.0.2 623 | define-properties: 1.2.0 624 | get-intrinsic: 1.2.1 625 | is-array-buffer: 3.0.2 626 | is-shared-array-buffer: 1.0.2 627 | dev: true 628 | 629 | /asynciterator.prototype@1.0.0: 630 | resolution: {integrity: sha512-wwHYEIS0Q80f5mosx3L/dfG5t5rjEa9Ft51GTaNt862EnpyGHpgz2RkZvLPp1oF5TnAiTohkEKVEu8pQPJI7Vg==} 631 | dependencies: 632 | has-symbols: 1.0.3 633 | dev: true 634 | 635 | /asynckit@0.4.0: 636 | resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} 637 | dev: false 638 | 639 | /autoprefixer@10.4.14(postcss@8.4.21): 640 | resolution: {integrity: sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ==} 641 | engines: {node: ^10 || ^12 || >=14} 642 | hasBin: true 643 | peerDependencies: 644 | postcss: ^8.1.0 645 | dependencies: 646 | browserslist: 4.21.5 647 | caniuse-lite: 1.0.30001467 648 | fraction.js: 4.2.0 649 | normalize-range: 0.1.2 650 | picocolors: 1.0.0 651 | postcss: 8.4.21 652 | postcss-value-parser: 4.2.0 653 | dev: true 654 | 655 | /available-typed-arrays@1.0.5: 656 | resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==} 657 | engines: {node: '>= 0.4'} 658 | dev: true 659 | 660 | /axios@1.3.5: 661 | resolution: {integrity: sha512-glL/PvG/E+xCWwV8S6nCHcrfg1exGx7vxyUIivIA1iL7BIh6bePylCfVHwp6k13ao7SATxB6imau2kqY+I67kw==} 662 | dependencies: 663 | follow-redirects: 1.15.2 664 | form-data: 4.0.0 665 | proxy-from-env: 1.1.0 666 | transitivePeerDependencies: 667 | - debug 668 | dev: false 669 | 670 | /balanced-match@1.0.2: 671 | resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} 672 | dev: true 673 | 674 | /binary-extensions@2.2.0: 675 | resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} 676 | engines: {node: '>=8'} 677 | dev: true 678 | 679 | /brace-expansion@1.1.11: 680 | resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} 681 | dependencies: 682 | balanced-match: 1.0.2 683 | concat-map: 0.0.1 684 | dev: true 685 | 686 | /braces@3.0.2: 687 | resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} 688 | engines: {node: '>=8'} 689 | dependencies: 690 | fill-range: 7.0.1 691 | dev: true 692 | 693 | /browserslist@4.21.5: 694 | resolution: {integrity: sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==} 695 | engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} 696 | hasBin: true 697 | dependencies: 698 | caniuse-lite: 1.0.30001467 699 | electron-to-chromium: 1.4.332 700 | node-releases: 2.0.10 701 | update-browserslist-db: 1.0.10(browserslist@4.21.5) 702 | dev: true 703 | 704 | /call-bind@1.0.2: 705 | resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} 706 | dependencies: 707 | function-bind: 1.1.1 708 | get-intrinsic: 1.2.1 709 | dev: true 710 | 711 | /callsites@3.1.0: 712 | resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} 713 | engines: {node: '>=6'} 714 | dev: true 715 | 716 | /camelcase-css@2.0.1: 717 | resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} 718 | engines: {node: '>= 6'} 719 | dev: true 720 | 721 | /caniuse-lite@1.0.30001467: 722 | resolution: {integrity: sha512-cEdN/5e+RPikvl9AHm4uuLXxeCNq8rFsQ+lPHTfe/OtypP3WwnVVbjn+6uBV7PaFL6xUFzTh+sSCOz1rKhcO+Q==} 723 | dev: true 724 | 725 | /chalk@4.1.2: 726 | resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} 727 | engines: {node: '>=10'} 728 | dependencies: 729 | ansi-styles: 4.3.0 730 | supports-color: 7.2.0 731 | dev: true 732 | 733 | /chalk@5.3.0: 734 | resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} 735 | engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} 736 | dev: true 737 | 738 | /chokidar@3.5.3: 739 | resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} 740 | engines: {node: '>= 8.10.0'} 741 | dependencies: 742 | anymatch: 3.1.3 743 | braces: 3.0.2 744 | glob-parent: 5.1.2 745 | is-binary-path: 2.1.0 746 | is-glob: 4.0.3 747 | normalize-path: 3.0.0 748 | readdirp: 3.6.0 749 | optionalDependencies: 750 | fsevents: 2.3.2 751 | dev: true 752 | 753 | /cli-cursor@4.0.0: 754 | resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==} 755 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 756 | dependencies: 757 | restore-cursor: 4.0.0 758 | dev: true 759 | 760 | /cli-truncate@3.1.0: 761 | resolution: {integrity: sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==} 762 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 763 | dependencies: 764 | slice-ansi: 5.0.0 765 | string-width: 5.1.2 766 | dev: true 767 | 768 | /color-convert@2.0.1: 769 | resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} 770 | engines: {node: '>=7.0.0'} 771 | dependencies: 772 | color-name: 1.1.4 773 | dev: true 774 | 775 | /color-name@1.1.4: 776 | resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} 777 | dev: true 778 | 779 | /colorette@2.0.20: 780 | resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} 781 | dev: true 782 | 783 | /combined-stream@1.0.8: 784 | resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} 785 | engines: {node: '>= 0.8'} 786 | dependencies: 787 | delayed-stream: 1.0.0 788 | dev: false 789 | 790 | /commander@11.0.0: 791 | resolution: {integrity: sha512-9HMlXtt/BNoYr8ooyjjNRdIilOTkVJXB+GhxMTtOKwk0R4j4lS4NpjuqmRxroBfnfTSHQIHQB7wryHhXarNjmQ==} 792 | engines: {node: '>=16'} 793 | dev: true 794 | 795 | /concat-map@0.0.1: 796 | resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} 797 | dev: true 798 | 799 | /cross-spawn@7.0.3: 800 | resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} 801 | engines: {node: '>= 8'} 802 | dependencies: 803 | path-key: 3.1.1 804 | shebang-command: 2.0.0 805 | which: 2.0.2 806 | dev: true 807 | 808 | /cssesc@3.0.0: 809 | resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} 810 | engines: {node: '>=4'} 811 | hasBin: true 812 | dev: true 813 | 814 | /csstype@3.1.1: 815 | resolution: {integrity: sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==} 816 | dev: true 817 | 818 | /debug@2.6.9: 819 | resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} 820 | peerDependencies: 821 | supports-color: '*' 822 | peerDependenciesMeta: 823 | supports-color: 824 | optional: true 825 | dependencies: 826 | ms: 2.0.0 827 | dev: true 828 | 829 | /debug@3.2.7: 830 | resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} 831 | peerDependencies: 832 | supports-color: '*' 833 | peerDependenciesMeta: 834 | supports-color: 835 | optional: true 836 | dependencies: 837 | ms: 2.1.3 838 | dev: true 839 | 840 | /debug@4.3.4: 841 | resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} 842 | engines: {node: '>=6.0'} 843 | peerDependencies: 844 | supports-color: '*' 845 | peerDependenciesMeta: 846 | supports-color: 847 | optional: true 848 | dependencies: 849 | ms: 2.1.2 850 | dev: true 851 | 852 | /deep-is@0.1.4: 853 | resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} 854 | dev: true 855 | 856 | /define-properties@1.2.0: 857 | resolution: {integrity: sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==} 858 | engines: {node: '>= 0.4'} 859 | dependencies: 860 | has-property-descriptors: 1.0.0 861 | object-keys: 1.1.1 862 | dev: true 863 | 864 | /defined@1.0.1: 865 | resolution: {integrity: sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==} 866 | dev: true 867 | 868 | /delayed-stream@1.0.0: 869 | resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} 870 | engines: {node: '>=0.4.0'} 871 | dev: false 872 | 873 | /detective@5.2.1: 874 | resolution: {integrity: sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw==} 875 | engines: {node: '>=0.8.0'} 876 | hasBin: true 877 | dependencies: 878 | acorn-node: 1.8.2 879 | defined: 1.0.1 880 | minimist: 1.2.8 881 | dev: true 882 | 883 | /didyoumean@1.2.2: 884 | resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} 885 | dev: true 886 | 887 | /dlv@1.1.3: 888 | resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} 889 | dev: true 890 | 891 | /doctrine@2.1.0: 892 | resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} 893 | engines: {node: '>=0.10.0'} 894 | dependencies: 895 | esutils: 2.0.3 896 | dev: true 897 | 898 | /doctrine@3.0.0: 899 | resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} 900 | engines: {node: '>=6.0.0'} 901 | dependencies: 902 | esutils: 2.0.3 903 | dev: true 904 | 905 | /eastasianwidth@0.2.0: 906 | resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} 907 | dev: true 908 | 909 | /electron-to-chromium@1.4.332: 910 | resolution: {integrity: sha512-c1Vbv5tuUlBFp0mb3mCIjw+REEsgthRgNE8BlbEDKmvzb8rxjcVki6OkQP83vLN34s0XCxpSkq7AZNep1a6xhw==} 911 | dev: true 912 | 913 | /emoji-regex@9.2.2: 914 | resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} 915 | dev: true 916 | 917 | /enquirer@2.4.1: 918 | resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} 919 | engines: {node: '>=8.6'} 920 | dependencies: 921 | ansi-colors: 4.1.3 922 | strip-ansi: 6.0.1 923 | dev: true 924 | 925 | /es-abstract@1.22.1: 926 | resolution: {integrity: sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw==} 927 | engines: {node: '>= 0.4'} 928 | dependencies: 929 | array-buffer-byte-length: 1.0.0 930 | arraybuffer.prototype.slice: 1.0.1 931 | available-typed-arrays: 1.0.5 932 | call-bind: 1.0.2 933 | es-set-tostringtag: 2.0.1 934 | es-to-primitive: 1.2.1 935 | function.prototype.name: 1.1.5 936 | get-intrinsic: 1.2.1 937 | get-symbol-description: 1.0.0 938 | globalthis: 1.0.3 939 | gopd: 1.0.1 940 | has: 1.0.3 941 | has-property-descriptors: 1.0.0 942 | has-proto: 1.0.1 943 | has-symbols: 1.0.3 944 | internal-slot: 1.0.5 945 | is-array-buffer: 3.0.2 946 | is-callable: 1.2.7 947 | is-negative-zero: 2.0.2 948 | is-regex: 1.1.4 949 | is-shared-array-buffer: 1.0.2 950 | is-string: 1.0.7 951 | is-typed-array: 1.1.12 952 | is-weakref: 1.0.2 953 | object-inspect: 1.12.3 954 | object-keys: 1.1.1 955 | object.assign: 4.1.4 956 | regexp.prototype.flags: 1.5.0 957 | safe-array-concat: 1.0.0 958 | safe-regex-test: 1.0.0 959 | string.prototype.trim: 1.2.7 960 | string.prototype.trimend: 1.0.6 961 | string.prototype.trimstart: 1.0.6 962 | typed-array-buffer: 1.0.0 963 | typed-array-byte-length: 1.0.0 964 | typed-array-byte-offset: 1.0.0 965 | typed-array-length: 1.0.4 966 | unbox-primitive: 1.0.2 967 | which-typed-array: 1.1.11 968 | dev: true 969 | 970 | /es-iterator-helpers@1.0.13: 971 | resolution: {integrity: sha512-LK3VGwzvaPWobO8xzXXGRUOGw8Dcjyfk62CsY/wfHN75CwsJPbuypOYJxK6g5RyEL8YDjIWcl6jgd8foO6mmrA==} 972 | dependencies: 973 | asynciterator.prototype: 1.0.0 974 | call-bind: 1.0.2 975 | define-properties: 1.2.0 976 | es-abstract: 1.22.1 977 | es-set-tostringtag: 2.0.1 978 | function-bind: 1.1.1 979 | get-intrinsic: 1.2.1 980 | globalthis: 1.0.3 981 | has-property-descriptors: 1.0.0 982 | has-proto: 1.0.1 983 | has-symbols: 1.0.3 984 | internal-slot: 1.0.5 985 | iterator.prototype: 1.1.0 986 | safe-array-concat: 1.0.0 987 | dev: true 988 | 989 | /es-set-tostringtag@2.0.1: 990 | resolution: {integrity: sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==} 991 | engines: {node: '>= 0.4'} 992 | dependencies: 993 | get-intrinsic: 1.2.1 994 | has: 1.0.3 995 | has-tostringtag: 1.0.0 996 | dev: true 997 | 998 | /es-shim-unscopables@1.0.0: 999 | resolution: {integrity: sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==} 1000 | dependencies: 1001 | has: 1.0.3 1002 | dev: true 1003 | 1004 | /es-to-primitive@1.2.1: 1005 | resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} 1006 | engines: {node: '>= 0.4'} 1007 | dependencies: 1008 | is-callable: 1.2.7 1009 | is-date-object: 1.0.5 1010 | is-symbol: 1.0.4 1011 | dev: true 1012 | 1013 | /esbuild@0.17.12: 1014 | resolution: {integrity: sha512-bX/zHl7Gn2CpQwcMtRogTTBf9l1nl+H6R8nUbjk+RuKqAE3+8FDulLA+pHvX7aA7Xe07Iwa+CWvy9I8Y2qqPKQ==} 1015 | engines: {node: '>=12'} 1016 | hasBin: true 1017 | requiresBuild: true 1018 | optionalDependencies: 1019 | '@esbuild/android-arm': 0.17.12 1020 | '@esbuild/android-arm64': 0.17.12 1021 | '@esbuild/android-x64': 0.17.12 1022 | '@esbuild/darwin-arm64': 0.17.12 1023 | '@esbuild/darwin-x64': 0.17.12 1024 | '@esbuild/freebsd-arm64': 0.17.12 1025 | '@esbuild/freebsd-x64': 0.17.12 1026 | '@esbuild/linux-arm': 0.17.12 1027 | '@esbuild/linux-arm64': 0.17.12 1028 | '@esbuild/linux-ia32': 0.17.12 1029 | '@esbuild/linux-loong64': 0.17.12 1030 | '@esbuild/linux-mips64el': 0.17.12 1031 | '@esbuild/linux-ppc64': 0.17.12 1032 | '@esbuild/linux-riscv64': 0.17.12 1033 | '@esbuild/linux-s390x': 0.17.12 1034 | '@esbuild/linux-x64': 0.17.12 1035 | '@esbuild/netbsd-x64': 0.17.12 1036 | '@esbuild/openbsd-x64': 0.17.12 1037 | '@esbuild/sunos-x64': 0.17.12 1038 | '@esbuild/win32-arm64': 0.17.12 1039 | '@esbuild/win32-ia32': 0.17.12 1040 | '@esbuild/win32-x64': 0.17.12 1041 | dev: true 1042 | 1043 | /escalade@3.1.1: 1044 | resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} 1045 | engines: {node: '>=6'} 1046 | dev: true 1047 | 1048 | /escape-string-regexp@4.0.0: 1049 | resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} 1050 | engines: {node: '>=10'} 1051 | dev: true 1052 | 1053 | /eslint-config-prettier@9.0.0(eslint@8.0.1): 1054 | resolution: {integrity: sha512-IcJsTkJae2S35pRsRAwoCE+925rJJStOdkKnLVgtE+tEpqU0EVVM7OqrwxqgptKdX29NUwC82I5pXsGFIgSevw==} 1055 | hasBin: true 1056 | peerDependencies: 1057 | eslint: '>=7.0.0' 1058 | dependencies: 1059 | eslint: 8.0.1 1060 | dev: true 1061 | 1062 | /eslint-config-standard@17.1.0(eslint-plugin-import@2.25.2)(eslint-plugin-n@15.0.0)(eslint-plugin-promise@6.0.0)(eslint@8.0.1): 1063 | resolution: {integrity: sha512-IwHwmaBNtDK4zDHQukFDW5u/aTb8+meQWZvNFWkiGmbWjD6bqyuSSBxxXKkCftCUzc1zwCH2m/baCNDLGmuO5Q==} 1064 | engines: {node: '>=12.0.0'} 1065 | peerDependencies: 1066 | eslint: ^8.0.1 1067 | eslint-plugin-import: ^2.25.2 1068 | eslint-plugin-n: '^15.0.0 || ^16.0.0 ' 1069 | eslint-plugin-promise: ^6.0.0 1070 | dependencies: 1071 | eslint: 8.0.1 1072 | eslint-plugin-import: 2.25.2(eslint@8.0.1) 1073 | eslint-plugin-n: 15.0.0(eslint@8.0.1) 1074 | eslint-plugin-promise: 6.0.0(eslint@8.0.1) 1075 | dev: true 1076 | 1077 | /eslint-import-resolver-node@0.3.9: 1078 | resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} 1079 | dependencies: 1080 | debug: 3.2.7 1081 | is-core-module: 2.13.0 1082 | resolve: 1.22.4 1083 | transitivePeerDependencies: 1084 | - supports-color 1085 | dev: true 1086 | 1087 | /eslint-module-utils@2.8.0(eslint-import-resolver-node@0.3.9)(eslint@8.0.1): 1088 | resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==} 1089 | engines: {node: '>=4'} 1090 | peerDependencies: 1091 | '@typescript-eslint/parser': '*' 1092 | eslint: '*' 1093 | eslint-import-resolver-node: '*' 1094 | eslint-import-resolver-typescript: '*' 1095 | eslint-import-resolver-webpack: '*' 1096 | peerDependenciesMeta: 1097 | '@typescript-eslint/parser': 1098 | optional: true 1099 | eslint: 1100 | optional: true 1101 | eslint-import-resolver-node: 1102 | optional: true 1103 | eslint-import-resolver-typescript: 1104 | optional: true 1105 | eslint-import-resolver-webpack: 1106 | optional: true 1107 | dependencies: 1108 | debug: 3.2.7 1109 | eslint: 8.0.1 1110 | eslint-import-resolver-node: 0.3.9 1111 | transitivePeerDependencies: 1112 | - supports-color 1113 | dev: true 1114 | 1115 | /eslint-plugin-es@4.1.0(eslint@8.0.1): 1116 | resolution: {integrity: sha512-GILhQTnjYE2WorX5Jyi5i4dz5ALWxBIdQECVQavL6s7cI76IZTDWleTHkxz/QT3kvcs2QlGHvKLYsSlPOlPXnQ==} 1117 | engines: {node: '>=8.10.0'} 1118 | peerDependencies: 1119 | eslint: '>=4.19.1' 1120 | dependencies: 1121 | eslint: 8.0.1 1122 | eslint-utils: 2.1.0 1123 | regexpp: 3.2.0 1124 | dev: true 1125 | 1126 | /eslint-plugin-import@2.25.2(eslint@8.0.1): 1127 | resolution: {integrity: sha512-qCwQr9TYfoBHOFcVGKY9C9unq05uOxxdklmBXLVvcwo68y5Hta6/GzCZEMx2zQiu0woKNEER0LE7ZgaOfBU14g==} 1128 | engines: {node: '>=4'} 1129 | peerDependencies: 1130 | '@typescript-eslint/parser': '*' 1131 | eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 1132 | peerDependenciesMeta: 1133 | '@typescript-eslint/parser': 1134 | optional: true 1135 | dependencies: 1136 | array-includes: 3.1.6 1137 | array.prototype.flat: 1.3.1 1138 | debug: 2.6.9 1139 | doctrine: 2.1.0 1140 | eslint: 8.0.1 1141 | eslint-import-resolver-node: 0.3.9 1142 | eslint-module-utils: 2.8.0(eslint-import-resolver-node@0.3.9)(eslint@8.0.1) 1143 | has: 1.0.3 1144 | is-core-module: 2.11.0 1145 | is-glob: 4.0.3 1146 | minimatch: 3.1.2 1147 | object.values: 1.1.6 1148 | resolve: 1.22.1 1149 | tsconfig-paths: 3.14.2 1150 | transitivePeerDependencies: 1151 | - eslint-import-resolver-typescript 1152 | - eslint-import-resolver-webpack 1153 | - supports-color 1154 | dev: true 1155 | 1156 | /eslint-plugin-n@15.0.0(eslint@8.0.1): 1157 | resolution: {integrity: sha512-cb70VSsNjteEL+sInXvlyewuE4OCW9CFmcOQKxyQzdAsoK+7pWpygf2q/Vsw/5dKSniO7qbawLjDqAakaILCIw==} 1158 | engines: {node: '>=12.22.0'} 1159 | peerDependencies: 1160 | eslint: '>=7.0.0' 1161 | dependencies: 1162 | eslint: 8.0.1 1163 | eslint-plugin-es: 4.1.0(eslint@8.0.1) 1164 | eslint-utils: 3.0.0(eslint@8.0.1) 1165 | ignore: 5.2.4 1166 | is-core-module: 2.11.0 1167 | minimatch: 3.1.2 1168 | resolve: 1.22.1 1169 | semver: 6.3.1 1170 | dev: true 1171 | 1172 | /eslint-plugin-promise@6.0.0(eslint@8.0.1): 1173 | resolution: {integrity: sha512-7GPezalm5Bfi/E22PnQxDWH2iW9GTvAlUNTztemeHb6c1BniSyoeTrM87JkC0wYdi6aQrZX9p2qEiAno8aTcbw==} 1174 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 1175 | peerDependencies: 1176 | eslint: ^7.0.0 || ^8.0.0 1177 | dependencies: 1178 | eslint: 8.0.1 1179 | dev: true 1180 | 1181 | /eslint-plugin-react@7.33.2(eslint@8.0.1): 1182 | resolution: {integrity: sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw==} 1183 | engines: {node: '>=4'} 1184 | peerDependencies: 1185 | eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 1186 | dependencies: 1187 | array-includes: 3.1.6 1188 | array.prototype.flatmap: 1.3.1 1189 | array.prototype.tosorted: 1.1.1 1190 | doctrine: 2.1.0 1191 | es-iterator-helpers: 1.0.13 1192 | eslint: 8.0.1 1193 | estraverse: 5.3.0 1194 | jsx-ast-utils: 3.3.5 1195 | minimatch: 3.1.2 1196 | object.entries: 1.1.6 1197 | object.fromentries: 2.0.6 1198 | object.hasown: 1.1.2 1199 | object.values: 1.1.6 1200 | prop-types: 15.8.1 1201 | resolve: 2.0.0-next.4 1202 | semver: 6.3.1 1203 | string.prototype.matchall: 4.0.8 1204 | dev: true 1205 | 1206 | /eslint-scope@6.0.0: 1207 | resolution: {integrity: sha512-uRDL9MWmQCkaFus8RF5K9/L/2fn+80yoW3jkD53l4shjCh26fCtvJGasxjUqP5OT87SYTxCVA3BwTUzuELx9kA==} 1208 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 1209 | dependencies: 1210 | esrecurse: 4.3.0 1211 | estraverse: 5.3.0 1212 | dev: true 1213 | 1214 | /eslint-utils@2.1.0: 1215 | resolution: {integrity: sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==} 1216 | engines: {node: '>=6'} 1217 | dependencies: 1218 | eslint-visitor-keys: 1.3.0 1219 | dev: true 1220 | 1221 | /eslint-utils@3.0.0(eslint@8.0.1): 1222 | resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} 1223 | engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} 1224 | peerDependencies: 1225 | eslint: '>=5' 1226 | dependencies: 1227 | eslint: 8.0.1 1228 | eslint-visitor-keys: 2.1.0 1229 | dev: true 1230 | 1231 | /eslint-visitor-keys@1.3.0: 1232 | resolution: {integrity: sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==} 1233 | engines: {node: '>=4'} 1234 | dev: true 1235 | 1236 | /eslint-visitor-keys@2.1.0: 1237 | resolution: {integrity: sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==} 1238 | engines: {node: '>=10'} 1239 | dev: true 1240 | 1241 | /eslint-visitor-keys@3.4.3: 1242 | resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} 1243 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 1244 | dev: true 1245 | 1246 | /eslint@8.0.1: 1247 | resolution: {integrity: sha512-LsgcwZgQ72vZ+SMp4K6pAnk2yFDWL7Ti4pJaRvsZ0Hsw2h8ZjUIW38a9AFn2cZXdBMlScMFYYgsSp4ttFI/0bA==} 1248 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 1249 | hasBin: true 1250 | dependencies: 1251 | '@eslint/eslintrc': 1.4.1 1252 | '@humanwhocodes/config-array': 0.6.0 1253 | ajv: 6.12.6 1254 | chalk: 4.1.2 1255 | cross-spawn: 7.0.3 1256 | debug: 4.3.4 1257 | doctrine: 3.0.0 1258 | enquirer: 2.4.1 1259 | escape-string-regexp: 4.0.0 1260 | eslint-scope: 6.0.0 1261 | eslint-utils: 3.0.0(eslint@8.0.1) 1262 | eslint-visitor-keys: 3.4.3 1263 | espree: 9.6.1 1264 | esquery: 1.5.0 1265 | esutils: 2.0.3 1266 | fast-deep-equal: 3.1.3 1267 | file-entry-cache: 6.0.1 1268 | functional-red-black-tree: 1.0.1 1269 | glob-parent: 6.0.2 1270 | globals: 13.21.0 1271 | ignore: 4.0.6 1272 | import-fresh: 3.3.0 1273 | imurmurhash: 0.1.4 1274 | is-glob: 4.0.3 1275 | js-yaml: 4.1.0 1276 | json-stable-stringify-without-jsonify: 1.0.1 1277 | levn: 0.4.1 1278 | lodash.merge: 4.6.2 1279 | minimatch: 3.1.2 1280 | natural-compare: 1.4.0 1281 | optionator: 0.9.3 1282 | progress: 2.0.3 1283 | regexpp: 3.2.0 1284 | semver: 7.5.4 1285 | strip-ansi: 6.0.1 1286 | strip-json-comments: 3.1.1 1287 | text-table: 0.2.0 1288 | v8-compile-cache: 2.4.0 1289 | transitivePeerDependencies: 1290 | - supports-color 1291 | dev: true 1292 | 1293 | /espree@9.6.1: 1294 | resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} 1295 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 1296 | dependencies: 1297 | acorn: 8.10.0 1298 | acorn-jsx: 5.3.2(acorn@8.10.0) 1299 | eslint-visitor-keys: 3.4.3 1300 | dev: true 1301 | 1302 | /esquery@1.5.0: 1303 | resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} 1304 | engines: {node: '>=0.10'} 1305 | dependencies: 1306 | estraverse: 5.3.0 1307 | dev: true 1308 | 1309 | /esrecurse@4.3.0: 1310 | resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} 1311 | engines: {node: '>=4.0'} 1312 | dependencies: 1313 | estraverse: 5.3.0 1314 | dev: true 1315 | 1316 | /estraverse@5.3.0: 1317 | resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} 1318 | engines: {node: '>=4.0'} 1319 | dev: true 1320 | 1321 | /esutils@2.0.3: 1322 | resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} 1323 | engines: {node: '>=0.10.0'} 1324 | dev: true 1325 | 1326 | /eventemitter3@5.0.1: 1327 | resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} 1328 | dev: true 1329 | 1330 | /execa@7.2.0: 1331 | resolution: {integrity: sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==} 1332 | engines: {node: ^14.18.0 || ^16.14.0 || >=18.0.0} 1333 | dependencies: 1334 | cross-spawn: 7.0.3 1335 | get-stream: 6.0.1 1336 | human-signals: 4.3.1 1337 | is-stream: 3.0.0 1338 | merge-stream: 2.0.0 1339 | npm-run-path: 5.1.0 1340 | onetime: 6.0.0 1341 | signal-exit: 3.0.7 1342 | strip-final-newline: 3.0.0 1343 | dev: true 1344 | 1345 | /fast-deep-equal@3.1.3: 1346 | resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} 1347 | dev: true 1348 | 1349 | /fast-glob@3.2.12: 1350 | resolution: {integrity: sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==} 1351 | engines: {node: '>=8.6.0'} 1352 | dependencies: 1353 | '@nodelib/fs.stat': 2.0.5 1354 | '@nodelib/fs.walk': 1.2.8 1355 | glob-parent: 5.1.2 1356 | merge2: 1.4.1 1357 | micromatch: 4.0.5 1358 | dev: true 1359 | 1360 | /fast-json-stable-stringify@2.1.0: 1361 | resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} 1362 | dev: true 1363 | 1364 | /fast-levenshtein@2.0.6: 1365 | resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} 1366 | dev: true 1367 | 1368 | /fastq@1.15.0: 1369 | resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} 1370 | dependencies: 1371 | reusify: 1.0.4 1372 | dev: true 1373 | 1374 | /file-entry-cache@6.0.1: 1375 | resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} 1376 | engines: {node: ^10.12.0 || >=12.0.0} 1377 | dependencies: 1378 | flat-cache: 3.0.4 1379 | dev: true 1380 | 1381 | /fill-range@7.0.1: 1382 | resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} 1383 | engines: {node: '>=8'} 1384 | dependencies: 1385 | to-regex-range: 5.0.1 1386 | dev: true 1387 | 1388 | /flat-cache@3.0.4: 1389 | resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==} 1390 | engines: {node: ^10.12.0 || >=12.0.0} 1391 | dependencies: 1392 | flatted: 3.2.7 1393 | rimraf: 3.0.2 1394 | dev: true 1395 | 1396 | /flatted@3.2.7: 1397 | resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==} 1398 | dev: true 1399 | 1400 | /follow-redirects@1.15.2: 1401 | resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==} 1402 | engines: {node: '>=4.0'} 1403 | peerDependencies: 1404 | debug: '*' 1405 | peerDependenciesMeta: 1406 | debug: 1407 | optional: true 1408 | dev: false 1409 | 1410 | /for-each@0.3.3: 1411 | resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} 1412 | dependencies: 1413 | is-callable: 1.2.7 1414 | dev: true 1415 | 1416 | /form-data@4.0.0: 1417 | resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} 1418 | engines: {node: '>= 6'} 1419 | dependencies: 1420 | asynckit: 0.4.0 1421 | combined-stream: 1.0.8 1422 | mime-types: 2.1.35 1423 | dev: false 1424 | 1425 | /fraction.js@4.2.0: 1426 | resolution: {integrity: sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==} 1427 | dev: true 1428 | 1429 | /fs.realpath@1.0.0: 1430 | resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} 1431 | dev: true 1432 | 1433 | /fsevents@2.3.2: 1434 | resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} 1435 | engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} 1436 | os: [darwin] 1437 | requiresBuild: true 1438 | dev: true 1439 | optional: true 1440 | 1441 | /function-bind@1.1.1: 1442 | resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} 1443 | dev: true 1444 | 1445 | /function.prototype.name@1.1.5: 1446 | resolution: {integrity: sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==} 1447 | engines: {node: '>= 0.4'} 1448 | dependencies: 1449 | call-bind: 1.0.2 1450 | define-properties: 1.2.0 1451 | es-abstract: 1.22.1 1452 | functions-have-names: 1.2.3 1453 | dev: true 1454 | 1455 | /functional-red-black-tree@1.0.1: 1456 | resolution: {integrity: sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==} 1457 | dev: true 1458 | 1459 | /functions-have-names@1.2.3: 1460 | resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} 1461 | dev: true 1462 | 1463 | /get-intrinsic@1.2.1: 1464 | resolution: {integrity: sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==} 1465 | dependencies: 1466 | function-bind: 1.1.1 1467 | has: 1.0.3 1468 | has-proto: 1.0.1 1469 | has-symbols: 1.0.3 1470 | dev: true 1471 | 1472 | /get-stream@6.0.1: 1473 | resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} 1474 | engines: {node: '>=10'} 1475 | dev: true 1476 | 1477 | /get-symbol-description@1.0.0: 1478 | resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} 1479 | engines: {node: '>= 0.4'} 1480 | dependencies: 1481 | call-bind: 1.0.2 1482 | get-intrinsic: 1.2.1 1483 | dev: true 1484 | 1485 | /glob-parent@5.1.2: 1486 | resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} 1487 | engines: {node: '>= 6'} 1488 | dependencies: 1489 | is-glob: 4.0.3 1490 | dev: true 1491 | 1492 | /glob-parent@6.0.2: 1493 | resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} 1494 | engines: {node: '>=10.13.0'} 1495 | dependencies: 1496 | is-glob: 4.0.3 1497 | dev: true 1498 | 1499 | /glob@7.2.3: 1500 | resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} 1501 | dependencies: 1502 | fs.realpath: 1.0.0 1503 | inflight: 1.0.6 1504 | inherits: 2.0.4 1505 | minimatch: 3.1.2 1506 | once: 1.4.0 1507 | path-is-absolute: 1.0.1 1508 | dev: true 1509 | 1510 | /globals@13.21.0: 1511 | resolution: {integrity: sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==} 1512 | engines: {node: '>=8'} 1513 | dependencies: 1514 | type-fest: 0.20.2 1515 | dev: true 1516 | 1517 | /globalthis@1.0.3: 1518 | resolution: {integrity: sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==} 1519 | engines: {node: '>= 0.4'} 1520 | dependencies: 1521 | define-properties: 1.2.0 1522 | dev: true 1523 | 1524 | /gopd@1.0.1: 1525 | resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} 1526 | dependencies: 1527 | get-intrinsic: 1.2.1 1528 | dev: true 1529 | 1530 | /has-bigints@1.0.2: 1531 | resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} 1532 | dev: true 1533 | 1534 | /has-flag@4.0.0: 1535 | resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} 1536 | engines: {node: '>=8'} 1537 | dev: true 1538 | 1539 | /has-property-descriptors@1.0.0: 1540 | resolution: {integrity: sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==} 1541 | dependencies: 1542 | get-intrinsic: 1.2.1 1543 | dev: true 1544 | 1545 | /has-proto@1.0.1: 1546 | resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==} 1547 | engines: {node: '>= 0.4'} 1548 | dev: true 1549 | 1550 | /has-symbols@1.0.3: 1551 | resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} 1552 | engines: {node: '>= 0.4'} 1553 | dev: true 1554 | 1555 | /has-tostringtag@1.0.0: 1556 | resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==} 1557 | engines: {node: '>= 0.4'} 1558 | dependencies: 1559 | has-symbols: 1.0.3 1560 | dev: true 1561 | 1562 | /has@1.0.3: 1563 | resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} 1564 | engines: {node: '>= 0.4.0'} 1565 | dependencies: 1566 | function-bind: 1.1.1 1567 | dev: true 1568 | 1569 | /human-signals@4.3.1: 1570 | resolution: {integrity: sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==} 1571 | engines: {node: '>=14.18.0'} 1572 | dev: true 1573 | 1574 | /husky@8.0.3: 1575 | resolution: {integrity: sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==} 1576 | engines: {node: '>=14'} 1577 | hasBin: true 1578 | dev: true 1579 | 1580 | /ignore@4.0.6: 1581 | resolution: {integrity: sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==} 1582 | engines: {node: '>= 4'} 1583 | dev: true 1584 | 1585 | /ignore@5.2.4: 1586 | resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==} 1587 | engines: {node: '>= 4'} 1588 | dev: true 1589 | 1590 | /import-fresh@3.3.0: 1591 | resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} 1592 | engines: {node: '>=6'} 1593 | dependencies: 1594 | parent-module: 1.0.1 1595 | resolve-from: 4.0.0 1596 | dev: true 1597 | 1598 | /imurmurhash@0.1.4: 1599 | resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} 1600 | engines: {node: '>=0.8.19'} 1601 | dev: true 1602 | 1603 | /inflight@1.0.6: 1604 | resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} 1605 | dependencies: 1606 | once: 1.4.0 1607 | wrappy: 1.0.2 1608 | dev: true 1609 | 1610 | /inherits@2.0.4: 1611 | resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} 1612 | dev: true 1613 | 1614 | /internal-slot@1.0.5: 1615 | resolution: {integrity: sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==} 1616 | engines: {node: '>= 0.4'} 1617 | dependencies: 1618 | get-intrinsic: 1.2.1 1619 | has: 1.0.3 1620 | side-channel: 1.0.4 1621 | dev: true 1622 | 1623 | /is-array-buffer@3.0.2: 1624 | resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==} 1625 | dependencies: 1626 | call-bind: 1.0.2 1627 | get-intrinsic: 1.2.1 1628 | is-typed-array: 1.1.12 1629 | dev: true 1630 | 1631 | /is-async-function@2.0.0: 1632 | resolution: {integrity: sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==} 1633 | engines: {node: '>= 0.4'} 1634 | dependencies: 1635 | has-tostringtag: 1.0.0 1636 | dev: true 1637 | 1638 | /is-bigint@1.0.4: 1639 | resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} 1640 | dependencies: 1641 | has-bigints: 1.0.2 1642 | dev: true 1643 | 1644 | /is-binary-path@2.1.0: 1645 | resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} 1646 | engines: {node: '>=8'} 1647 | dependencies: 1648 | binary-extensions: 2.2.0 1649 | dev: true 1650 | 1651 | /is-boolean-object@1.1.2: 1652 | resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} 1653 | engines: {node: '>= 0.4'} 1654 | dependencies: 1655 | call-bind: 1.0.2 1656 | has-tostringtag: 1.0.0 1657 | dev: true 1658 | 1659 | /is-callable@1.2.7: 1660 | resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} 1661 | engines: {node: '>= 0.4'} 1662 | dev: true 1663 | 1664 | /is-core-module@2.11.0: 1665 | resolution: {integrity: sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==} 1666 | dependencies: 1667 | has: 1.0.3 1668 | dev: true 1669 | 1670 | /is-core-module@2.13.0: 1671 | resolution: {integrity: sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==} 1672 | dependencies: 1673 | has: 1.0.3 1674 | dev: true 1675 | 1676 | /is-date-object@1.0.5: 1677 | resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} 1678 | engines: {node: '>= 0.4'} 1679 | dependencies: 1680 | has-tostringtag: 1.0.0 1681 | dev: true 1682 | 1683 | /is-extglob@2.1.1: 1684 | resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} 1685 | engines: {node: '>=0.10.0'} 1686 | dev: true 1687 | 1688 | /is-finalizationregistry@1.0.2: 1689 | resolution: {integrity: sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==} 1690 | dependencies: 1691 | call-bind: 1.0.2 1692 | dev: true 1693 | 1694 | /is-fullwidth-code-point@4.0.0: 1695 | resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==} 1696 | engines: {node: '>=12'} 1697 | dev: true 1698 | 1699 | /is-generator-function@1.0.10: 1700 | resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} 1701 | engines: {node: '>= 0.4'} 1702 | dependencies: 1703 | has-tostringtag: 1.0.0 1704 | dev: true 1705 | 1706 | /is-glob@4.0.3: 1707 | resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} 1708 | engines: {node: '>=0.10.0'} 1709 | dependencies: 1710 | is-extglob: 2.1.1 1711 | dev: true 1712 | 1713 | /is-map@2.0.2: 1714 | resolution: {integrity: sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==} 1715 | dev: true 1716 | 1717 | /is-negative-zero@2.0.2: 1718 | resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==} 1719 | engines: {node: '>= 0.4'} 1720 | dev: true 1721 | 1722 | /is-number-object@1.0.7: 1723 | resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} 1724 | engines: {node: '>= 0.4'} 1725 | dependencies: 1726 | has-tostringtag: 1.0.0 1727 | dev: true 1728 | 1729 | /is-number@7.0.0: 1730 | resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} 1731 | engines: {node: '>=0.12.0'} 1732 | dev: true 1733 | 1734 | /is-regex@1.1.4: 1735 | resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} 1736 | engines: {node: '>= 0.4'} 1737 | dependencies: 1738 | call-bind: 1.0.2 1739 | has-tostringtag: 1.0.0 1740 | dev: true 1741 | 1742 | /is-set@2.0.2: 1743 | resolution: {integrity: sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==} 1744 | dev: true 1745 | 1746 | /is-shared-array-buffer@1.0.2: 1747 | resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==} 1748 | dependencies: 1749 | call-bind: 1.0.2 1750 | dev: true 1751 | 1752 | /is-stream@3.0.0: 1753 | resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} 1754 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 1755 | dev: true 1756 | 1757 | /is-string@1.0.7: 1758 | resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} 1759 | engines: {node: '>= 0.4'} 1760 | dependencies: 1761 | has-tostringtag: 1.0.0 1762 | dev: true 1763 | 1764 | /is-symbol@1.0.4: 1765 | resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} 1766 | engines: {node: '>= 0.4'} 1767 | dependencies: 1768 | has-symbols: 1.0.3 1769 | dev: true 1770 | 1771 | /is-typed-array@1.1.12: 1772 | resolution: {integrity: sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==} 1773 | engines: {node: '>= 0.4'} 1774 | dependencies: 1775 | which-typed-array: 1.1.11 1776 | dev: true 1777 | 1778 | /is-weakmap@2.0.1: 1779 | resolution: {integrity: sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==} 1780 | dev: true 1781 | 1782 | /is-weakref@1.0.2: 1783 | resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} 1784 | dependencies: 1785 | call-bind: 1.0.2 1786 | dev: true 1787 | 1788 | /is-weakset@2.0.2: 1789 | resolution: {integrity: sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==} 1790 | dependencies: 1791 | call-bind: 1.0.2 1792 | get-intrinsic: 1.2.1 1793 | dev: true 1794 | 1795 | /isarray@2.0.5: 1796 | resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} 1797 | dev: true 1798 | 1799 | /isexe@2.0.0: 1800 | resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} 1801 | dev: true 1802 | 1803 | /iterator.prototype@1.1.0: 1804 | resolution: {integrity: sha512-rjuhAk1AJ1fssphHD0IFV6TWL40CwRZ53FrztKx43yk2v6rguBYsY4Bj1VU4HmoMmKwZUlx7mfnhDf9cOp4YTw==} 1805 | dependencies: 1806 | define-properties: 1.2.0 1807 | get-intrinsic: 1.2.1 1808 | has-symbols: 1.0.3 1809 | has-tostringtag: 1.0.0 1810 | reflect.getprototypeof: 1.0.3 1811 | dev: true 1812 | 1813 | /js-tokens@4.0.0: 1814 | resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} 1815 | 1816 | /js-yaml@4.1.0: 1817 | resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} 1818 | hasBin: true 1819 | dependencies: 1820 | argparse: 2.0.1 1821 | dev: true 1822 | 1823 | /json-schema-traverse@0.4.1: 1824 | resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} 1825 | dev: true 1826 | 1827 | /json-stable-stringify-without-jsonify@1.0.1: 1828 | resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} 1829 | dev: true 1830 | 1831 | /json5@1.0.2: 1832 | resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} 1833 | hasBin: true 1834 | dependencies: 1835 | minimist: 1.2.8 1836 | dev: true 1837 | 1838 | /jsx-ast-utils@3.3.5: 1839 | resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} 1840 | engines: {node: '>=4.0'} 1841 | dependencies: 1842 | array-includes: 3.1.6 1843 | array.prototype.flat: 1.3.1 1844 | object.assign: 4.1.4 1845 | object.values: 1.1.6 1846 | dev: true 1847 | 1848 | /levn@0.4.1: 1849 | resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} 1850 | engines: {node: '>= 0.8.0'} 1851 | dependencies: 1852 | prelude-ls: 1.2.1 1853 | type-check: 0.4.0 1854 | dev: true 1855 | 1856 | /lilconfig@2.1.0: 1857 | resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} 1858 | engines: {node: '>=10'} 1859 | dev: true 1860 | 1861 | /lint-staged@14.0.1: 1862 | resolution: {integrity: sha512-Mw0cL6HXnHN1ag0mN/Dg4g6sr8uf8sn98w2Oc1ECtFto9tvRF7nkXGJRbx8gPlHyoR0pLyBr2lQHbWwmUHe1Sw==} 1863 | engines: {node: ^16.14.0 || >=18.0.0} 1864 | hasBin: true 1865 | dependencies: 1866 | chalk: 5.3.0 1867 | commander: 11.0.0 1868 | debug: 4.3.4 1869 | execa: 7.2.0 1870 | lilconfig: 2.1.0 1871 | listr2: 6.6.1 1872 | micromatch: 4.0.5 1873 | pidtree: 0.6.0 1874 | string-argv: 0.3.2 1875 | yaml: 2.3.1 1876 | transitivePeerDependencies: 1877 | - enquirer 1878 | - supports-color 1879 | dev: true 1880 | 1881 | /listr2@6.6.1: 1882 | resolution: {integrity: sha512-+rAXGHh0fkEWdXBmX+L6mmfmXmXvDGEKzkjxO+8mP3+nI/r/CWznVBvsibXdxda9Zz0OW2e2ikphN3OwCT/jSg==} 1883 | engines: {node: '>=16.0.0'} 1884 | peerDependencies: 1885 | enquirer: '>= 2.3.0 < 3' 1886 | peerDependenciesMeta: 1887 | enquirer: 1888 | optional: true 1889 | dependencies: 1890 | cli-truncate: 3.1.0 1891 | colorette: 2.0.20 1892 | eventemitter3: 5.0.1 1893 | log-update: 5.0.1 1894 | rfdc: 1.3.0 1895 | wrap-ansi: 8.1.0 1896 | dev: true 1897 | 1898 | /lodash.merge@4.6.2: 1899 | resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} 1900 | dev: true 1901 | 1902 | /log-update@5.0.1: 1903 | resolution: {integrity: sha512-5UtUDQ/6edw4ofyljDNcOVJQ4c7OjDro4h3y8e1GQL5iYElYclVHJ3zeWchylvMaKnDbDilC8irOVyexnA/Slw==} 1904 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 1905 | dependencies: 1906 | ansi-escapes: 5.0.0 1907 | cli-cursor: 4.0.0 1908 | slice-ansi: 5.0.0 1909 | strip-ansi: 7.1.0 1910 | wrap-ansi: 8.1.0 1911 | dev: true 1912 | 1913 | /loose-envify@1.4.0: 1914 | resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} 1915 | hasBin: true 1916 | dependencies: 1917 | js-tokens: 4.0.0 1918 | 1919 | /lru-cache@6.0.0: 1920 | resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} 1921 | engines: {node: '>=10'} 1922 | dependencies: 1923 | yallist: 4.0.0 1924 | dev: true 1925 | 1926 | /merge-stream@2.0.0: 1927 | resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} 1928 | dev: true 1929 | 1930 | /merge2@1.4.1: 1931 | resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} 1932 | engines: {node: '>= 8'} 1933 | dev: true 1934 | 1935 | /micromatch@4.0.5: 1936 | resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} 1937 | engines: {node: '>=8.6'} 1938 | dependencies: 1939 | braces: 3.0.2 1940 | picomatch: 2.3.1 1941 | dev: true 1942 | 1943 | /mime-db@1.52.0: 1944 | resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} 1945 | engines: {node: '>= 0.6'} 1946 | dev: false 1947 | 1948 | /mime-types@2.1.35: 1949 | resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} 1950 | engines: {node: '>= 0.6'} 1951 | dependencies: 1952 | mime-db: 1.52.0 1953 | dev: false 1954 | 1955 | /mimic-fn@2.1.0: 1956 | resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} 1957 | engines: {node: '>=6'} 1958 | dev: true 1959 | 1960 | /mimic-fn@4.0.0: 1961 | resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} 1962 | engines: {node: '>=12'} 1963 | dev: true 1964 | 1965 | /minimatch@3.1.2: 1966 | resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} 1967 | dependencies: 1968 | brace-expansion: 1.1.11 1969 | dev: true 1970 | 1971 | /minimist@1.2.8: 1972 | resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} 1973 | dev: true 1974 | 1975 | /ms@2.0.0: 1976 | resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} 1977 | dev: true 1978 | 1979 | /ms@2.1.2: 1980 | resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} 1981 | dev: true 1982 | 1983 | /ms@2.1.3: 1984 | resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} 1985 | dev: true 1986 | 1987 | /nanoid@3.3.4: 1988 | resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==} 1989 | engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} 1990 | hasBin: true 1991 | dev: true 1992 | 1993 | /natural-compare@1.4.0: 1994 | resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} 1995 | dev: true 1996 | 1997 | /node-releases@2.0.10: 1998 | resolution: {integrity: sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==} 1999 | dev: true 2000 | 2001 | /normalize-path@3.0.0: 2002 | resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} 2003 | engines: {node: '>=0.10.0'} 2004 | dev: true 2005 | 2006 | /normalize-range@0.1.2: 2007 | resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} 2008 | engines: {node: '>=0.10.0'} 2009 | dev: true 2010 | 2011 | /npm-run-path@5.1.0: 2012 | resolution: {integrity: sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==} 2013 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 2014 | dependencies: 2015 | path-key: 4.0.0 2016 | dev: true 2017 | 2018 | /object-assign@4.1.1: 2019 | resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} 2020 | engines: {node: '>=0.10.0'} 2021 | dev: true 2022 | 2023 | /object-hash@3.0.0: 2024 | resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} 2025 | engines: {node: '>= 6'} 2026 | dev: true 2027 | 2028 | /object-inspect@1.12.3: 2029 | resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==} 2030 | dev: true 2031 | 2032 | /object-keys@1.1.1: 2033 | resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} 2034 | engines: {node: '>= 0.4'} 2035 | dev: true 2036 | 2037 | /object.assign@4.1.4: 2038 | resolution: {integrity: sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==} 2039 | engines: {node: '>= 0.4'} 2040 | dependencies: 2041 | call-bind: 1.0.2 2042 | define-properties: 1.2.0 2043 | has-symbols: 1.0.3 2044 | object-keys: 1.1.1 2045 | dev: true 2046 | 2047 | /object.entries@1.1.6: 2048 | resolution: {integrity: sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w==} 2049 | engines: {node: '>= 0.4'} 2050 | dependencies: 2051 | call-bind: 1.0.2 2052 | define-properties: 1.2.0 2053 | es-abstract: 1.22.1 2054 | dev: true 2055 | 2056 | /object.fromentries@2.0.6: 2057 | resolution: {integrity: sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg==} 2058 | engines: {node: '>= 0.4'} 2059 | dependencies: 2060 | call-bind: 1.0.2 2061 | define-properties: 1.2.0 2062 | es-abstract: 1.22.1 2063 | dev: true 2064 | 2065 | /object.hasown@1.1.2: 2066 | resolution: {integrity: sha512-B5UIT3J1W+WuWIU55h0mjlwaqxiE5vYENJXIXZ4VFe05pNYrkKuK0U/6aFcb0pKywYJh7IhfoqUfKVmrJJHZHw==} 2067 | dependencies: 2068 | define-properties: 1.2.0 2069 | es-abstract: 1.22.1 2070 | dev: true 2071 | 2072 | /object.values@1.1.6: 2073 | resolution: {integrity: sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==} 2074 | engines: {node: '>= 0.4'} 2075 | dependencies: 2076 | call-bind: 1.0.2 2077 | define-properties: 1.2.0 2078 | es-abstract: 1.22.1 2079 | dev: true 2080 | 2081 | /once@1.4.0: 2082 | resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} 2083 | dependencies: 2084 | wrappy: 1.0.2 2085 | dev: true 2086 | 2087 | /onetime@5.1.2: 2088 | resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} 2089 | engines: {node: '>=6'} 2090 | dependencies: 2091 | mimic-fn: 2.1.0 2092 | dev: true 2093 | 2094 | /onetime@6.0.0: 2095 | resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} 2096 | engines: {node: '>=12'} 2097 | dependencies: 2098 | mimic-fn: 4.0.0 2099 | dev: true 2100 | 2101 | /optionator@0.9.3: 2102 | resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} 2103 | engines: {node: '>= 0.8.0'} 2104 | dependencies: 2105 | '@aashutoshrathi/word-wrap': 1.2.6 2106 | deep-is: 0.1.4 2107 | fast-levenshtein: 2.0.6 2108 | levn: 0.4.1 2109 | prelude-ls: 1.2.1 2110 | type-check: 0.4.0 2111 | dev: true 2112 | 2113 | /parent-module@1.0.1: 2114 | resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} 2115 | engines: {node: '>=6'} 2116 | dependencies: 2117 | callsites: 3.1.0 2118 | dev: true 2119 | 2120 | /path-is-absolute@1.0.1: 2121 | resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} 2122 | engines: {node: '>=0.10.0'} 2123 | dev: true 2124 | 2125 | /path-key@3.1.1: 2126 | resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} 2127 | engines: {node: '>=8'} 2128 | dev: true 2129 | 2130 | /path-key@4.0.0: 2131 | resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} 2132 | engines: {node: '>=12'} 2133 | dev: true 2134 | 2135 | /path-parse@1.0.7: 2136 | resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} 2137 | dev: true 2138 | 2139 | /picocolors@1.0.0: 2140 | resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} 2141 | dev: true 2142 | 2143 | /picomatch@2.3.1: 2144 | resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} 2145 | engines: {node: '>=8.6'} 2146 | dev: true 2147 | 2148 | /pidtree@0.6.0: 2149 | resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==} 2150 | engines: {node: '>=0.10'} 2151 | hasBin: true 2152 | dev: true 2153 | 2154 | /pify@2.3.0: 2155 | resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} 2156 | engines: {node: '>=0.10.0'} 2157 | dev: true 2158 | 2159 | /postcss-import@14.1.0(postcss@8.4.21): 2160 | resolution: {integrity: sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==} 2161 | engines: {node: '>=10.0.0'} 2162 | peerDependencies: 2163 | postcss: ^8.0.0 2164 | dependencies: 2165 | postcss: 8.4.21 2166 | postcss-value-parser: 4.2.0 2167 | read-cache: 1.0.0 2168 | resolve: 1.22.1 2169 | dev: true 2170 | 2171 | /postcss-js@4.0.1(postcss@8.4.21): 2172 | resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==} 2173 | engines: {node: ^12 || ^14 || >= 16} 2174 | peerDependencies: 2175 | postcss: ^8.4.21 2176 | dependencies: 2177 | camelcase-css: 2.0.1 2178 | postcss: 8.4.21 2179 | dev: true 2180 | 2181 | /postcss-load-config@3.1.4(postcss@8.4.21): 2182 | resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==} 2183 | engines: {node: '>= 10'} 2184 | peerDependencies: 2185 | postcss: '>=8.0.9' 2186 | ts-node: '>=9.0.0' 2187 | peerDependenciesMeta: 2188 | postcss: 2189 | optional: true 2190 | ts-node: 2191 | optional: true 2192 | dependencies: 2193 | lilconfig: 2.1.0 2194 | postcss: 8.4.21 2195 | yaml: 1.10.2 2196 | dev: true 2197 | 2198 | /postcss-nested@6.0.0(postcss@8.4.21): 2199 | resolution: {integrity: sha512-0DkamqrPcmkBDsLn+vQDIrtkSbNkv5AD/M322ySo9kqFkCIYklym2xEmWkwo+Y3/qZo34tzEPNUw4y7yMCdv5w==} 2200 | engines: {node: '>=12.0'} 2201 | peerDependencies: 2202 | postcss: ^8.2.14 2203 | dependencies: 2204 | postcss: 8.4.21 2205 | postcss-selector-parser: 6.0.11 2206 | dev: true 2207 | 2208 | /postcss-selector-parser@6.0.11: 2209 | resolution: {integrity: sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==} 2210 | engines: {node: '>=4'} 2211 | dependencies: 2212 | cssesc: 3.0.0 2213 | util-deprecate: 1.0.2 2214 | dev: true 2215 | 2216 | /postcss-value-parser@4.2.0: 2217 | resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} 2218 | dev: true 2219 | 2220 | /postcss@8.4.21: 2221 | resolution: {integrity: sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==} 2222 | engines: {node: ^10 || ^12 || >=14} 2223 | dependencies: 2224 | nanoid: 3.3.4 2225 | picocolors: 1.0.0 2226 | source-map-js: 1.0.2 2227 | dev: true 2228 | 2229 | /prelude-ls@1.2.1: 2230 | resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} 2231 | engines: {node: '>= 0.8.0'} 2232 | dev: true 2233 | 2234 | /prettier@3.0.2: 2235 | resolution: {integrity: sha512-o2YR9qtniXvwEZlOKbveKfDQVyqxbEIWn48Z8m3ZJjBjcCmUy3xZGIv+7AkaeuaTr6yPXJjwv07ZWlsWbEy1rQ==} 2236 | engines: {node: '>=14'} 2237 | hasBin: true 2238 | dev: true 2239 | 2240 | /progress@2.0.3: 2241 | resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} 2242 | engines: {node: '>=0.4.0'} 2243 | dev: true 2244 | 2245 | /prop-types@15.8.1: 2246 | resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} 2247 | dependencies: 2248 | loose-envify: 1.4.0 2249 | object-assign: 4.1.1 2250 | react-is: 16.13.1 2251 | dev: true 2252 | 2253 | /proxy-from-env@1.1.0: 2254 | resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} 2255 | dev: false 2256 | 2257 | /punycode@2.3.0: 2258 | resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} 2259 | engines: {node: '>=6'} 2260 | dev: true 2261 | 2262 | /queue-microtask@1.2.3: 2263 | resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} 2264 | dev: true 2265 | 2266 | /quick-lru@5.1.1: 2267 | resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} 2268 | engines: {node: '>=10'} 2269 | dev: true 2270 | 2271 | /react-dom@18.2.0(react@18.2.0): 2272 | resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==} 2273 | peerDependencies: 2274 | react: ^18.2.0 2275 | dependencies: 2276 | loose-envify: 1.4.0 2277 | react: 18.2.0 2278 | scheduler: 0.23.0 2279 | dev: false 2280 | 2281 | /react-is@16.13.1: 2282 | resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} 2283 | dev: true 2284 | 2285 | /react-use-websocket@4.3.1(react-dom@18.2.0)(react@18.2.0): 2286 | resolution: {integrity: sha512-zHPLWrgcqydJaak2O5V9hiz4q2dwkwqNQqpgFVmSuPxLZdsZlnDs8DVHy3WtHH+A6ms/8aHIyX7+7ulOcrnR0Q==} 2287 | peerDependencies: 2288 | react: '>= 18.0.0' 2289 | react-dom: '>= 18.0.0' 2290 | dependencies: 2291 | react: 18.2.0 2292 | react-dom: 18.2.0(react@18.2.0) 2293 | dev: false 2294 | 2295 | /react@18.2.0: 2296 | resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} 2297 | engines: {node: '>=0.10.0'} 2298 | dependencies: 2299 | loose-envify: 1.4.0 2300 | dev: false 2301 | 2302 | /read-cache@1.0.0: 2303 | resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} 2304 | dependencies: 2305 | pify: 2.3.0 2306 | dev: true 2307 | 2308 | /readdirp@3.6.0: 2309 | resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} 2310 | engines: {node: '>=8.10.0'} 2311 | dependencies: 2312 | picomatch: 2.3.1 2313 | dev: true 2314 | 2315 | /reflect.getprototypeof@1.0.3: 2316 | resolution: {integrity: sha512-TTAOZpkJ2YLxl7mVHWrNo3iDMEkYlva/kgFcXndqMgbo/AZUmmavEkdXV+hXtE4P8xdyEKRzalaFqZVuwIk/Nw==} 2317 | engines: {node: '>= 0.4'} 2318 | dependencies: 2319 | call-bind: 1.0.2 2320 | define-properties: 1.2.0 2321 | es-abstract: 1.22.1 2322 | get-intrinsic: 1.2.1 2323 | globalthis: 1.0.3 2324 | which-builtin-type: 1.1.3 2325 | dev: true 2326 | 2327 | /regexp.prototype.flags@1.5.0: 2328 | resolution: {integrity: sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==} 2329 | engines: {node: '>= 0.4'} 2330 | dependencies: 2331 | call-bind: 1.0.2 2332 | define-properties: 1.2.0 2333 | functions-have-names: 1.2.3 2334 | dev: true 2335 | 2336 | /regexpp@3.2.0: 2337 | resolution: {integrity: sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==} 2338 | engines: {node: '>=8'} 2339 | dev: true 2340 | 2341 | /resolve-from@4.0.0: 2342 | resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} 2343 | engines: {node: '>=4'} 2344 | dev: true 2345 | 2346 | /resolve@1.22.1: 2347 | resolution: {integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==} 2348 | hasBin: true 2349 | dependencies: 2350 | is-core-module: 2.11.0 2351 | path-parse: 1.0.7 2352 | supports-preserve-symlinks-flag: 1.0.0 2353 | dev: true 2354 | 2355 | /resolve@1.22.4: 2356 | resolution: {integrity: sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==} 2357 | hasBin: true 2358 | dependencies: 2359 | is-core-module: 2.13.0 2360 | path-parse: 1.0.7 2361 | supports-preserve-symlinks-flag: 1.0.0 2362 | dev: true 2363 | 2364 | /resolve@2.0.0-next.4: 2365 | resolution: {integrity: sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==} 2366 | hasBin: true 2367 | dependencies: 2368 | is-core-module: 2.11.0 2369 | path-parse: 1.0.7 2370 | supports-preserve-symlinks-flag: 1.0.0 2371 | dev: true 2372 | 2373 | /restore-cursor@4.0.0: 2374 | resolution: {integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==} 2375 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 2376 | dependencies: 2377 | onetime: 5.1.2 2378 | signal-exit: 3.0.7 2379 | dev: true 2380 | 2381 | /reusify@1.0.4: 2382 | resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} 2383 | engines: {iojs: '>=1.0.0', node: '>=0.10.0'} 2384 | dev: true 2385 | 2386 | /rfdc@1.3.0: 2387 | resolution: {integrity: sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==} 2388 | dev: true 2389 | 2390 | /rimraf@3.0.2: 2391 | resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} 2392 | hasBin: true 2393 | dependencies: 2394 | glob: 7.2.3 2395 | dev: true 2396 | 2397 | /rollup@3.19.1: 2398 | resolution: {integrity: sha512-lAbrdN7neYCg/8WaoWn/ckzCtz+jr70GFfYdlf50OF7387HTg+wiuiqJRFYawwSPpqfqDNYqK7smY/ks2iAudg==} 2399 | engines: {node: '>=14.18.0', npm: '>=8.0.0'} 2400 | hasBin: true 2401 | optionalDependencies: 2402 | fsevents: 2.3.2 2403 | dev: true 2404 | 2405 | /run-parallel@1.2.0: 2406 | resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} 2407 | dependencies: 2408 | queue-microtask: 1.2.3 2409 | dev: true 2410 | 2411 | /safe-array-concat@1.0.0: 2412 | resolution: {integrity: sha512-9dVEFruWIsnie89yym+xWTAYASdpw3CJV7Li/6zBewGf9z2i1j31rP6jnY0pHEO4QZh6N0K11bFjWmdR8UGdPQ==} 2413 | engines: {node: '>=0.4'} 2414 | dependencies: 2415 | call-bind: 1.0.2 2416 | get-intrinsic: 1.2.1 2417 | has-symbols: 1.0.3 2418 | isarray: 2.0.5 2419 | dev: true 2420 | 2421 | /safe-regex-test@1.0.0: 2422 | resolution: {integrity: sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==} 2423 | dependencies: 2424 | call-bind: 1.0.2 2425 | get-intrinsic: 1.2.1 2426 | is-regex: 1.1.4 2427 | dev: true 2428 | 2429 | /scheduler@0.23.0: 2430 | resolution: {integrity: sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==} 2431 | dependencies: 2432 | loose-envify: 1.4.0 2433 | dev: false 2434 | 2435 | /semver@6.3.1: 2436 | resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} 2437 | hasBin: true 2438 | dev: true 2439 | 2440 | /semver@7.5.4: 2441 | resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} 2442 | engines: {node: '>=10'} 2443 | hasBin: true 2444 | dependencies: 2445 | lru-cache: 6.0.0 2446 | dev: true 2447 | 2448 | /shebang-command@2.0.0: 2449 | resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} 2450 | engines: {node: '>=8'} 2451 | dependencies: 2452 | shebang-regex: 3.0.0 2453 | dev: true 2454 | 2455 | /shebang-regex@3.0.0: 2456 | resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} 2457 | engines: {node: '>=8'} 2458 | dev: true 2459 | 2460 | /side-channel@1.0.4: 2461 | resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} 2462 | dependencies: 2463 | call-bind: 1.0.2 2464 | get-intrinsic: 1.2.1 2465 | object-inspect: 1.12.3 2466 | dev: true 2467 | 2468 | /signal-exit@3.0.7: 2469 | resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} 2470 | dev: true 2471 | 2472 | /slice-ansi@5.0.0: 2473 | resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} 2474 | engines: {node: '>=12'} 2475 | dependencies: 2476 | ansi-styles: 6.2.1 2477 | is-fullwidth-code-point: 4.0.0 2478 | dev: true 2479 | 2480 | /source-map-js@1.0.2: 2481 | resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} 2482 | engines: {node: '>=0.10.0'} 2483 | dev: true 2484 | 2485 | /string-argv@0.3.2: 2486 | resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} 2487 | engines: {node: '>=0.6.19'} 2488 | dev: true 2489 | 2490 | /string-width@5.1.2: 2491 | resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} 2492 | engines: {node: '>=12'} 2493 | dependencies: 2494 | eastasianwidth: 0.2.0 2495 | emoji-regex: 9.2.2 2496 | strip-ansi: 7.1.0 2497 | dev: true 2498 | 2499 | /string.prototype.matchall@4.0.8: 2500 | resolution: {integrity: sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg==} 2501 | dependencies: 2502 | call-bind: 1.0.2 2503 | define-properties: 1.2.0 2504 | es-abstract: 1.22.1 2505 | get-intrinsic: 1.2.1 2506 | has-symbols: 1.0.3 2507 | internal-slot: 1.0.5 2508 | regexp.prototype.flags: 1.5.0 2509 | side-channel: 1.0.4 2510 | dev: true 2511 | 2512 | /string.prototype.trim@1.2.7: 2513 | resolution: {integrity: sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==} 2514 | engines: {node: '>= 0.4'} 2515 | dependencies: 2516 | call-bind: 1.0.2 2517 | define-properties: 1.2.0 2518 | es-abstract: 1.22.1 2519 | dev: true 2520 | 2521 | /string.prototype.trimend@1.0.6: 2522 | resolution: {integrity: sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==} 2523 | dependencies: 2524 | call-bind: 1.0.2 2525 | define-properties: 1.2.0 2526 | es-abstract: 1.22.1 2527 | dev: true 2528 | 2529 | /string.prototype.trimstart@1.0.6: 2530 | resolution: {integrity: sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==} 2531 | dependencies: 2532 | call-bind: 1.0.2 2533 | define-properties: 1.2.0 2534 | es-abstract: 1.22.1 2535 | dev: true 2536 | 2537 | /strip-ansi@6.0.1: 2538 | resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} 2539 | engines: {node: '>=8'} 2540 | dependencies: 2541 | ansi-regex: 5.0.1 2542 | dev: true 2543 | 2544 | /strip-ansi@7.1.0: 2545 | resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} 2546 | engines: {node: '>=12'} 2547 | dependencies: 2548 | ansi-regex: 6.0.1 2549 | dev: true 2550 | 2551 | /strip-bom@3.0.0: 2552 | resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} 2553 | engines: {node: '>=4'} 2554 | dev: true 2555 | 2556 | /strip-final-newline@3.0.0: 2557 | resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} 2558 | engines: {node: '>=12'} 2559 | dev: true 2560 | 2561 | /strip-json-comments@3.1.1: 2562 | resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} 2563 | engines: {node: '>=8'} 2564 | dev: true 2565 | 2566 | /supports-color@7.2.0: 2567 | resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} 2568 | engines: {node: '>=8'} 2569 | dependencies: 2570 | has-flag: 4.0.0 2571 | dev: true 2572 | 2573 | /supports-preserve-symlinks-flag@1.0.0: 2574 | resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} 2575 | engines: {node: '>= 0.4'} 2576 | dev: true 2577 | 2578 | /tailwindcss@3.2.7(postcss@8.4.21): 2579 | resolution: {integrity: sha512-B6DLqJzc21x7wntlH/GsZwEXTBttVSl1FtCzC8WP4oBc/NKef7kaax5jeihkkCEWc831/5NDJ9gRNDK6NEioQQ==} 2580 | engines: {node: '>=12.13.0'} 2581 | hasBin: true 2582 | peerDependencies: 2583 | postcss: ^8.0.9 2584 | dependencies: 2585 | arg: 5.0.2 2586 | chokidar: 3.5.3 2587 | color-name: 1.1.4 2588 | detective: 5.2.1 2589 | didyoumean: 1.2.2 2590 | dlv: 1.1.3 2591 | fast-glob: 3.2.12 2592 | glob-parent: 6.0.2 2593 | is-glob: 4.0.3 2594 | lilconfig: 2.1.0 2595 | micromatch: 4.0.5 2596 | normalize-path: 3.0.0 2597 | object-hash: 3.0.0 2598 | picocolors: 1.0.0 2599 | postcss: 8.4.21 2600 | postcss-import: 14.1.0(postcss@8.4.21) 2601 | postcss-js: 4.0.1(postcss@8.4.21) 2602 | postcss-load-config: 3.1.4(postcss@8.4.21) 2603 | postcss-nested: 6.0.0(postcss@8.4.21) 2604 | postcss-selector-parser: 6.0.11 2605 | postcss-value-parser: 4.2.0 2606 | quick-lru: 5.1.1 2607 | resolve: 1.22.1 2608 | transitivePeerDependencies: 2609 | - ts-node 2610 | dev: true 2611 | 2612 | /text-table@0.2.0: 2613 | resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} 2614 | dev: true 2615 | 2616 | /to-regex-range@5.0.1: 2617 | resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} 2618 | engines: {node: '>=8.0'} 2619 | dependencies: 2620 | is-number: 7.0.0 2621 | dev: true 2622 | 2623 | /tsconfig-paths@3.14.2: 2624 | resolution: {integrity: sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==} 2625 | dependencies: 2626 | '@types/json5': 0.0.29 2627 | json5: 1.0.2 2628 | minimist: 1.2.8 2629 | strip-bom: 3.0.0 2630 | dev: true 2631 | 2632 | /type-check@0.4.0: 2633 | resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} 2634 | engines: {node: '>= 0.8.0'} 2635 | dependencies: 2636 | prelude-ls: 1.2.1 2637 | dev: true 2638 | 2639 | /type-fest@0.20.2: 2640 | resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} 2641 | engines: {node: '>=10'} 2642 | dev: true 2643 | 2644 | /type-fest@1.4.0: 2645 | resolution: {integrity: sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==} 2646 | engines: {node: '>=10'} 2647 | dev: true 2648 | 2649 | /typed-array-buffer@1.0.0: 2650 | resolution: {integrity: sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==} 2651 | engines: {node: '>= 0.4'} 2652 | dependencies: 2653 | call-bind: 1.0.2 2654 | get-intrinsic: 1.2.1 2655 | is-typed-array: 1.1.12 2656 | dev: true 2657 | 2658 | /typed-array-byte-length@1.0.0: 2659 | resolution: {integrity: sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==} 2660 | engines: {node: '>= 0.4'} 2661 | dependencies: 2662 | call-bind: 1.0.2 2663 | for-each: 0.3.3 2664 | has-proto: 1.0.1 2665 | is-typed-array: 1.1.12 2666 | dev: true 2667 | 2668 | /typed-array-byte-offset@1.0.0: 2669 | resolution: {integrity: sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==} 2670 | engines: {node: '>= 0.4'} 2671 | dependencies: 2672 | available-typed-arrays: 1.0.5 2673 | call-bind: 1.0.2 2674 | for-each: 0.3.3 2675 | has-proto: 1.0.1 2676 | is-typed-array: 1.1.12 2677 | dev: true 2678 | 2679 | /typed-array-length@1.0.4: 2680 | resolution: {integrity: sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==} 2681 | dependencies: 2682 | call-bind: 1.0.2 2683 | for-each: 0.3.3 2684 | is-typed-array: 1.1.12 2685 | dev: true 2686 | 2687 | /unbox-primitive@1.0.2: 2688 | resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} 2689 | dependencies: 2690 | call-bind: 1.0.2 2691 | has-bigints: 1.0.2 2692 | has-symbols: 1.0.3 2693 | which-boxed-primitive: 1.0.2 2694 | dev: true 2695 | 2696 | /update-browserslist-db@1.0.10(browserslist@4.21.5): 2697 | resolution: {integrity: sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==} 2698 | hasBin: true 2699 | peerDependencies: 2700 | browserslist: '>= 4.21.0' 2701 | dependencies: 2702 | browserslist: 4.21.5 2703 | escalade: 3.1.1 2704 | picocolors: 1.0.0 2705 | dev: true 2706 | 2707 | /uri-js@4.4.1: 2708 | resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} 2709 | dependencies: 2710 | punycode: 2.3.0 2711 | dev: true 2712 | 2713 | /util-deprecate@1.0.2: 2714 | resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} 2715 | dev: true 2716 | 2717 | /v8-compile-cache@2.4.0: 2718 | resolution: {integrity: sha512-ocyWc3bAHBB/guyqJQVI5o4BZkPhznPYUG2ea80Gond/BgNWpap8TOmLSeeQG7bnh2KMISxskdADG59j7zruhw==} 2719 | dev: true 2720 | 2721 | /validator@13.11.0: 2722 | resolution: {integrity: sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==} 2723 | engines: {node: '>= 0.10'} 2724 | dev: false 2725 | 2726 | /vite@4.2.0: 2727 | resolution: {integrity: sha512-AbDTyzzwuKoRtMIRLGNxhLRuv1FpRgdIw+1y6AQG73Q5+vtecmvzKo/yk8X/vrHDpETRTx01ABijqUHIzBXi0g==} 2728 | engines: {node: ^14.18.0 || >=16.0.0} 2729 | hasBin: true 2730 | peerDependencies: 2731 | '@types/node': '>= 14' 2732 | less: '*' 2733 | sass: '*' 2734 | stylus: '*' 2735 | sugarss: '*' 2736 | terser: ^5.4.0 2737 | peerDependenciesMeta: 2738 | '@types/node': 2739 | optional: true 2740 | less: 2741 | optional: true 2742 | sass: 2743 | optional: true 2744 | stylus: 2745 | optional: true 2746 | sugarss: 2747 | optional: true 2748 | terser: 2749 | optional: true 2750 | dependencies: 2751 | esbuild: 0.17.12 2752 | postcss: 8.4.21 2753 | resolve: 1.22.1 2754 | rollup: 3.19.1 2755 | optionalDependencies: 2756 | fsevents: 2.3.2 2757 | dev: true 2758 | 2759 | /which-boxed-primitive@1.0.2: 2760 | resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} 2761 | dependencies: 2762 | is-bigint: 1.0.4 2763 | is-boolean-object: 1.1.2 2764 | is-number-object: 1.0.7 2765 | is-string: 1.0.7 2766 | is-symbol: 1.0.4 2767 | dev: true 2768 | 2769 | /which-builtin-type@1.1.3: 2770 | resolution: {integrity: sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==} 2771 | engines: {node: '>= 0.4'} 2772 | dependencies: 2773 | function.prototype.name: 1.1.5 2774 | has-tostringtag: 1.0.0 2775 | is-async-function: 2.0.0 2776 | is-date-object: 1.0.5 2777 | is-finalizationregistry: 1.0.2 2778 | is-generator-function: 1.0.10 2779 | is-regex: 1.1.4 2780 | is-weakref: 1.0.2 2781 | isarray: 2.0.5 2782 | which-boxed-primitive: 1.0.2 2783 | which-collection: 1.0.1 2784 | which-typed-array: 1.1.11 2785 | dev: true 2786 | 2787 | /which-collection@1.0.1: 2788 | resolution: {integrity: sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==} 2789 | dependencies: 2790 | is-map: 2.0.2 2791 | is-set: 2.0.2 2792 | is-weakmap: 2.0.1 2793 | is-weakset: 2.0.2 2794 | dev: true 2795 | 2796 | /which-typed-array@1.1.11: 2797 | resolution: {integrity: sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==} 2798 | engines: {node: '>= 0.4'} 2799 | dependencies: 2800 | available-typed-arrays: 1.0.5 2801 | call-bind: 1.0.2 2802 | for-each: 0.3.3 2803 | gopd: 1.0.1 2804 | has-tostringtag: 1.0.0 2805 | dev: true 2806 | 2807 | /which@2.0.2: 2808 | resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} 2809 | engines: {node: '>= 8'} 2810 | hasBin: true 2811 | dependencies: 2812 | isexe: 2.0.0 2813 | dev: true 2814 | 2815 | /wrap-ansi@8.1.0: 2816 | resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} 2817 | engines: {node: '>=12'} 2818 | dependencies: 2819 | ansi-styles: 6.2.1 2820 | string-width: 5.1.2 2821 | strip-ansi: 7.1.0 2822 | dev: true 2823 | 2824 | /wrappy@1.0.2: 2825 | resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} 2826 | dev: true 2827 | 2828 | /xtend@4.0.2: 2829 | resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} 2830 | engines: {node: '>=0.4'} 2831 | dev: true 2832 | 2833 | /yallist@4.0.0: 2834 | resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} 2835 | dev: true 2836 | 2837 | /yaml@1.10.2: 2838 | resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} 2839 | engines: {node: '>= 6'} 2840 | dev: true 2841 | 2842 | /yaml@2.3.1: 2843 | resolution: {integrity: sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==} 2844 | engines: {node: '>= 14'} 2845 | dev: true 2846 | -------------------------------------------------------------------------------- /postcss.config.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {} 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /public/assets/chrisvdev1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chrisvdev/obs-chat/0b7ee21585c27d98b57a0db9280e89f1ecc63b0f/public/assets/chrisvdev1.png -------------------------------------------------------------------------------- /public/assets/fonts/inter-latin-400-normal.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chrisvdev/obs-chat/0b7ee21585c27d98b57a0db9280e89f1ecc63b0f/public/assets/fonts/inter-latin-400-normal.woff -------------------------------------------------------------------------------- /public/assets/fonts/inter-latin-400-normal.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chrisvdev/obs-chat/0b7ee21585c27d98b57a0db9280e89f1ecc63b0f/public/assets/fonts/inter-latin-400-normal.woff2 -------------------------------------------------------------------------------- /public/assets/fonts/inter-latin-variable-wghtOnly-normal.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chrisvdev/obs-chat/0b7ee21585c27d98b57a0db9280e89f1ecc63b0f/public/assets/fonts/inter-latin-variable-wghtOnly-normal.woff2 -------------------------------------------------------------------------------- /public/assets/get_url_params.js: -------------------------------------------------------------------------------- 1 | export default function getURLParams() { 2 | const url = new URL(document.location.href.replace('#', '?')) 3 | const params = {} 4 | url.searchParams.forEach((value, name) => (params[name] = value)) 5 | return params 6 | } 7 | -------------------------------------------------------------------------------- /public/assets/load_css.js: -------------------------------------------------------------------------------- 1 | import getURLParams from './get_url_params.js' 2 | 3 | const { style } = JSON.parse(localStorage.getItem('variables')) || {} 4 | 5 | const params = getURLParams() 6 | if (params.style) { 7 | fetch(params.style) 8 | .then((response) => response.text()) 9 | .then((response) => { 10 | const externalStyle = document.createElement('style') 11 | externalStyle.innerText = response 12 | document.body.appendChild(externalStyle) 13 | }) 14 | } else { 15 | if (style) 16 | fetch(style) 17 | .then((response) => response.text()) 18 | .then((response) => { 19 | const externalStyle = document.createElement('style') 20 | externalStyle.innerText = response 21 | document.body.appendChild(externalStyle) 22 | }) 23 | } 24 | -------------------------------------------------------------------------------- /public/assets/niceDuck.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chrisvdev/obs-chat/0b7ee21585c27d98b57a0db9280e89f1ecc63b0f/public/assets/niceDuck.jpg -------------------------------------------------------------------------------- /public/assets/pato1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chrisvdev/obs-chat/0b7ee21585c27d98b57a0db9280e89f1ecc63b0f/public/assets/pato1.jpg -------------------------------------------------------------------------------- /public/assets/pato2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chrisvdev/obs-chat/0b7ee21585c27d98b57a0db9280e89f1ecc63b0f/public/assets/pato2.jpg -------------------------------------------------------------------------------- /public/assets/pato3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chrisvdev/obs-chat/0b7ee21585c27d98b57a0db9280e89f1ecc63b0f/public/assets/pato3.jpg -------------------------------------------------------------------------------- /public/assets/pato4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chrisvdev/obs-chat/0b7ee21585c27d98b57a0db9280e89f1ecc63b0f/public/assets/pato4.jpg -------------------------------------------------------------------------------- /public/assets/pato5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chrisvdev/obs-chat/0b7ee21585c27d98b57a0db9280e89f1ecc63b0f/public/assets/pato5.jpg -------------------------------------------------------------------------------- /public/assets/quack.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chrisvdev/obs-chat/0b7ee21585c27d98b57a0db9280e89f1ecc63b0f/public/assets/quack.gif -------------------------------------------------------------------------------- /public/assets/st-chrisvdev.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chrisvdev/obs-chat/0b7ee21585c27d98b57a0db9280e89f1ecc63b0f/public/assets/st-chrisvdev.gif -------------------------------------------------------------------------------- /public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/App.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import useMessageQueue from './hooks/use_message_queue.js' 3 | import Message from './components/Message.jsx' 4 | import StyledMessage from './components/StyleMessage.jsx' 5 | import getVariable, { RENDER, STYLE } from './lib/get_variable.js' 6 | 7 | const render = getVariable(RENDER) 8 | const style = getVariable(STYLE) 9 | 10 | export default function App() { 11 | const cue = useMessageQueue() 12 | return render ? ( 13 | style ? ( 14 |
15 | {cue 16 | .filter((message) => Boolean(message.userId)) 17 | .map((message, i) => ( 18 | 19 | ))} 20 |
21 | ) : ( 22 |
23 | {cue 24 | .filter((message) => Boolean(message.userId)) 25 | .map((message, i) => ( 26 | 27 | ))} 28 |
29 | ) 30 | ) : ( 31 |
32 |

No Render

33 |
34 | ) 35 | } 36 | -------------------------------------------------------------------------------- /src/app.css: -------------------------------------------------------------------------------- 1 | .subscriber { 2 | text-shadow: 0 0 5 #8205B4 3 | } 4 | -------------------------------------------------------------------------------- /src/certs/cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIEWTCCAsGgAwIBAgIRAPnC98Z+upvYh8ynufZvUW4wDQYJKoZIhvcNAQELBQAw 3 | gY8xHjAcBgNVBAoTFW1rY2VydCBkZXZlbG9wbWVudCBDQTEyMDAGA1UECwwpY2hy 4 | aXN0aWFuQGNocmlzLW5vdGUgKENocmlzdGlhbiBWaWxsZWdhcykxOTA3BgNVBAMM 5 | MG1rY2VydCBjaHJpc3RpYW5AY2hyaXMtbm90ZSAoQ2hyaXN0aWFuIFZpbGxlZ2Fz 6 | KTAeFw0yMzEwMTkwMjEwMjVaFw0yNjAxMTkwMjEwMjVaMF0xJzAlBgNVBAoTHm1r 7 | Y2VydCBkZXZlbG9wbWVudCBjZXJ0aWZpY2F0ZTEyMDAGA1UECwwpY2hyaXN0aWFu 8 | QGNocmlzLW5vdGUgKENocmlzdGlhbiBWaWxsZWdhcykwggEiMA0GCSqGSIb3DQEB 9 | AQUAA4IBDwAwggEKAoIBAQDLmzNB0mQJyj1lyT0BboB1Yr7QxCLXfBN4ihU0gkFq 10 | 0AEXIPfXs3A6Bg1eAo9f0mI1yiv4YRq7gJpU0BDv/ez11B0ioDWoZluPOLjXVBen 11 | BpZo/kPMz2Ex3cnS5x8SJTbGqmuPdED3PKJ0SeASIEORP1M/7FfeB1DFRED5Ruy7 12 | s9LXLho6DgauS8DAdsp0wWd0GyKmICeNQ5g2Xtdp4X6MJjbHVRn2qnwBrHnR3piW 13 | PDJJ7hbzy7SznVQ6Yc75FMGw6eiMvWetDLI6w7u6d9khVXdbcea/cVTrwsqbCoha 14 | PdHAvusJNjUCPQd8a8xyxo13j8m5fXuKrkBeu4s8bv8DAgMBAAGjYTBfMA4GA1Ud 15 | DwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATAfBgNVHSMEGDAWgBQuxcrE 16 | 5RAeWPr82v618Da3rJGjOTAXBgNVHREEEDAOggxub3RlYm9vay5uZXQwDQYJKoZI 17 | hvcNAQELBQADggGBADK0dzCFG76KKq0fNvmPi1Jaqrq0l2iSdAgew8ZuF9XsustX 18 | WKtZ7A9tsoVJ3dQtZB29S/kPetX4voejsymuBlVtObl64Gviu1FY5TXfiP3X70C7 19 | /JT/bfYw6WclR7LoZnZaDEqA/91sMkUsNF27nj0tpyX//87Rf3wbuCP4KwBGolXu 20 | tRxqy18LwMPU4kpkr8wS9VT79ndUfo0+w6JBtfw1FC6P7hnMVDmJwSk5YiEf82nS 21 | bza6Kdk9X6ZUmxL/J0mSSTEBet8xr1K/mL6whKSkNyMWAnK8Yj3GZjDCHhv1h2jN 22 | /CwRxRUCPDdaOWz83FAtzh1nqDz+VBZ2n75+Hw/v28cuPXshXcE2UV70Q9B7jYSo 23 | ZBXQigqIGQu2J9SZ+yNFFPyh2geAb8CfWVTtFua5yhptafEhyRcwMZqgWu+7IFl2 24 | z3DN8D+UrY/nANZ4vogKjaGSd4E4HQD/Gib5T5FEcbt1uVIk9OInUVw9kG/97B1S 25 | ijMmDNFKb6lD60ajRA== 26 | -----END CERTIFICATE----- 27 | -------------------------------------------------------------------------------- /src/certs/key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDLmzNB0mQJyj1l 3 | yT0BboB1Yr7QxCLXfBN4ihU0gkFq0AEXIPfXs3A6Bg1eAo9f0mI1yiv4YRq7gJpU 4 | 0BDv/ez11B0ioDWoZluPOLjXVBenBpZo/kPMz2Ex3cnS5x8SJTbGqmuPdED3PKJ0 5 | SeASIEORP1M/7FfeB1DFRED5Ruy7s9LXLho6DgauS8DAdsp0wWd0GyKmICeNQ5g2 6 | Xtdp4X6MJjbHVRn2qnwBrHnR3piWPDJJ7hbzy7SznVQ6Yc75FMGw6eiMvWetDLI6 7 | w7u6d9khVXdbcea/cVTrwsqbCohaPdHAvusJNjUCPQd8a8xyxo13j8m5fXuKrkBe 8 | u4s8bv8DAgMBAAECggEAFVJQYNE2dqv+F/2l7NN0klZf4x7XAzfUFihnphMJ5LSZ 9 | mKF0MttwojLmDXU5LHCspjNgvWb11LLX9o+/ZlJyESBAWNLsK5FkfzASc0I0I+KV 10 | t7MAyJ7i78TpELPxVgYdoVpRXzluYDWyUXk3BM7qJHi8MBKA9RhRBgdqwnAB9Hnl 11 | hac12EJxMNf6ztW2U2b4fcjm1JMHmIqh1clvoBq8CiJvGd3jRIdUDmknDWjjTLIJ 12 | /NoGxEXpf1l3wmUmTqzRxiGybae9/ykxwm3tpv7HBXv1sklwPUlYbIPZRluf8YqU 13 | vqIF5vOpHHaTAuTwn6Bjc/THLNbhgCuU4We/lGiQiQKBgQDh2mJLPnOMoFfig/sE 14 | szptBuu9R1Ythwakvi0UxqATN8Lm9sBGFv6N5LdeUsG/zbq5gqrL5nlBSQgAtHNw 15 | WDqH3JTslyZjcS/Ypd9VORV5Zr2XlzIyfPc3GWPAjueJIvA+TiZ0IF5pbQBl9q/d 16 | UBYwMHXQpw9yZC+SUhvwIl3o9QKBgQDmyJ8Qw91EVGiifHkxVEKbzUJSelwnn20+ 17 | DovnD6Pjx+4jme9j/bbf/E+VYHP+b5qM2cOMxBx78tjM8c91M8c5Arepu9dDPVj+ 18 | AHs1C+fpn2a0OgEq0GMmS133ILsZ4WDQF4OXz3T7NlqHbmKddiHCBCL+uAJL4Xvq 19 | 7QFyvFwtFwKBgQCUKJ6ynZVPeyAsCEhzHOAHBbM/x7xQwXMqP1dzeZkpAjtpKBWZ 20 | 5Ru4GYHw7nkLSfpkF8PTXq3MlgwZ6kaQPFCpL5rCWaVlNqschDOtxHTB3xQgjZ7w 21 | X+oMyysU9qoM3E6dkMbJBzLoFglc2ickF5V2p1OiPPV1JSPP6O1K6kCQwQKBgQC+ 22 | queIEVoAdwBPpij2kVfKouV1gPQcJEI78Aaz6p8LtIVR0n8OjHIHUcxqbFrIzmnQ 23 | jqVZ6jhiSzvE7s7oVNP2jQEycSeivM+GYt1n8SM0R+axZe7K8YnI/KFwaBFMi4DR 24 | y2uEA/jxB3H5zEAbOZsgUQych2gWSv93E0KMCYTaFwKBgQCrlrt5qjeMx23jFW13 25 | uUOQbMwDYP67xXB7uQgXIAct4DQ4cZIY4/V1qpTXErU0VEkRUfeR3JciPjaXmDWn 26 | s71+4E2D3GivmxZkO7EjWQijjTuHRjrfUwuxqryuvvP6vWuZ8dNRATop0bJWfy+b 27 | 24ezzhcwt6Qqua3yrfO8QAbDzw== 28 | -----END PRIVATE KEY----- 29 | -------------------------------------------------------------------------------- /src/certs/notebook.net.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDSjCCAjKgAwIBAgIURY+CVD2bHq8nvaPVTLdHbvl/CbwwDQYJKoZIhvcNAQEL 3 | BQAwFzEVMBMGA1UEAwwMbm90ZWJvb2submV0MB4XDTIzMTAxOTAyMzM1M1oXDTIz 4 | MTExODAyMzM1M1owFzEVMBMGA1UEAwwMbm90ZWJvb2submV0MIIBIjANBgkqhkiG 5 | 9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwG0jZSOcxtQuBKXzk3SREQmPyPfBsqmkiahx 6 | /ftqKvw+d5zeckb0jUZuAfOROJJcKLPennrUD08xbPL9zCk9zJjyqdGK6ItVzFa5 7 | ewOYFO78ety2riBYUpmQmxkd7hnp5BAH9uP4dIdbRPuFEl3qDw/M++fmWBoZTIp4 8 | W3WkF5YITAbgylKRs8OWK9FNcmNPSnV9yqb7rVmFxNbNx40ipqk5X7FP5hei09FW 9 | V/w1g3GiA9nJuR3KMfdaSuudMO1ktPqKHq/k8m6SPxunIwLsLN4JXtVbbzk7NYFn 10 | cBo0U+DpC23BUmh0nv7jGmavgTGFDjq5f6QMljDY860XwFMXZwIDAQABo4GNMIGK 11 | MB0GA1UdDgQWBBSvMf8gqyVv2yr/btq26e8XoqPcYDA8BgNVHSMENTAzoRukGTAX 12 | MRUwEwYDVQQDDAxub3RlYm9vay5uZXSCFEWPglQ9mx6vJ72j1Uy3R275fwm8MAkG 13 | A1UdEwQCMAAwCwYDVR0PBAQDAgTwMBMGA1UdJQQMMAoGCCsGAQUFBwMBMA0GCSqG 14 | SIb3DQEBCwUAA4IBAQCB1dgkM4xKvEV0faHPKhBf65QNjf5Jif24h6Sh7DW955xM 15 | GcaZB/KcuFiZYPclfduy5pT1uuZkE1A5B+il8quptz5fLhV4q1FAgFAd0rVmxR1q 16 | PMRqWPhRQwGJvZWSg+xzU5invPklCd3SjpDNcl8pFF072oa9CRNbqUV04XB8cf9c 17 | 35pxFenY2kWA2LPX7QV9weKfIRTu9AEoRYzuRGapMz1iC/0ZXjN9IzmU1k4ZkLrf 18 | MPKPgLIm9V0Uh6yyKoBG25MVEF6ijfyqcbh/U0ainDUaHMEjGe1/4bmWOewE8jiM 19 | nlFVpV69vYqFAyYpf058lMfMJ8QJx0VK+1vkhDJD 20 | -----END CERTIFICATE----- 21 | -------------------------------------------------------------------------------- /src/certs/notebook.net.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDAbSNlI5zG1C4E 3 | pfOTdJERCY/I98GyqaSJqHH9+2oq/D53nN5yRvSNRm4B85E4klwos96eetQPTzFs 4 | 8v3MKT3MmPKp0Yroi1XMVrl7A5gU7vx63LauIFhSmZCbGR3uGenkEAf24/h0h1tE 5 | +4USXeoPD8z75+ZYGhlMinhbdaQXlghMBuDKUpGzw5Yr0U1yY09KdX3KpvutWYXE 6 | 1s3HjSKmqTlfsU/mF6LT0VZX/DWDcaID2cm5Hcox91pK650w7WS0+ooer+TybpI/ 7 | G6cjAuws3gle1VtvOTs1gWdwGjRT4OkLbcFSaHSe/uMaZq+BMYUOOrl/pAyWMNjz 8 | rRfAUxdnAgMBAAECggEAAvZrMhZvRnxjzPyFGIMV7K46AX0XBVopR1lJkAB77Pd/ 9 | OrY2konXIAmyjeMjHDzcoF/MkKIRe77bYvMGx0rnQawlKEoqmlPy2TeImYU/pSrc 10 | xkN5qIqk8XidylWDqXPKrxE0Hi/6VkjzNcetj8/UV7EFledHG5ojQ5NqMPZJtXc5 11 | /aQZz9eQ/rYaupaUiiu3M2ihUn8NoVG4F9+lYeGDHi/UPKDDW5kWqM7kepY9AkOn 12 | EatRUC5r9gxZwB22/xINqWZP9h4p/THaF4SwiNsgEsCfGun9pWkT2TRI8WTUmlmI 13 | J3Jkqz7p63G3+13cpKmrFDuTf9tl1+ndVmseTXNCyQKBgQD50ePVJKB7BRuy1h53 14 | vtqS3XZsgpqATWLgZQ/h/NNl/xR8oVxV/6kCkvR8ThduT2A/KO8MBFcBe1vDaFdd 15 | W8eZgcjS+mzgRrOjF9q4sn+Q9ThbpGF/d7OKbSPnLCMoiN99vS6tT6YYxspS8wDK 16 | QO11e1sL6vGU+oPDN/Awp1WqSwKBgQDFL8ZS9MJeKOwGrenb2oqr5xOv0nuT5A+o 17 | xpkv6G/n3N/7zY4Q5Y7IXeZrjOIW/yCGSzcdOw9Pkj9JowgrVgXktd1j0D/yT+zX 18 | +KAPyqs1MN/Q2+s3teE3b0biByFq5BbbdCo+eRjViaUa6kq+zoWV0J1Fs2xDhGiE 19 | iSHz5JTV1QKBgQDmL1FAeYktER3egJB+QWrgXBLcFNMLWUK8BCLIVc7rckeMNpn/ 20 | 25v89S80wjewuo6yY6MvbWhFw0ZgHOoy6XhWp1FFpN1hIYQvyLEN8dq81FZjimkT 21 | rFXQPJQSU4bpuIRFNWWm53bh6XlPSPz3Xy/tSgYwSwDiBpoV7JryGZ1DVQKBgCwj 22 | i5NaMn/9TQgZufV6r/vW1/NNfFgYfuDaw8OTlikiqgildJ2XpSR40HFWse1P4qnt 23 | AENMyxqWtA/5rIR21w7hHtOO9CF7fprBjqK6TSS08gTAlaB82BMel5FU40gYEn3B 24 | PQuK8+Io04p4045ukDx+3BWUGjHq27J/N9huXFqZAoGBAOvSY9nn1ir5bQ1m4TeP 25 | xtMCkyxKxIHXzP13IYzjOstft8zwbQpmhDIC/9e1fdR3QbaSFo6AZcpu+HlvysCV 26 | +WXQ7eJFAnt6quQzV6IUFyZFAcvDS9xbL3PaLDyi7g7ARU/wOQPMOJrFFtmQ6Y64 27 | IfXgzYM+4CGybmRgXHjPD7G1 28 | -----END PRIVATE KEY----- 29 | -------------------------------------------------------------------------------- /src/commands/filter_user.js: -------------------------------------------------------------------------------- 1 | import { bannedUsersContainer } from '../filters/users_filter' 2 | 3 | function addFilteredUser(message) { 4 | const { msg, mod, streamer } = message 5 | if (mod || streamer) { 6 | const userNames = msg.toLowerCase().split(' ') 7 | bannedUsersContainer.addBannedUsers(userNames) 8 | } 9 | return true 10 | } 11 | function removeFilteredUser(message) { 12 | const { msg, mod, streamer } = message 13 | if (mod || streamer) { 14 | const userNames = msg.toLowerCase().split(' ') 15 | bannedUsersContainer.removeBannedUsers(userNames) 16 | } 17 | return true 18 | } 19 | 20 | const filterUsers = { 21 | addFilteredUser, 22 | removeFilteredUser 23 | } 24 | export default filterUsers 25 | -------------------------------------------------------------------------------- /src/commands/speak.js: -------------------------------------------------------------------------------- 1 | import getVariable, { TTS, TTS_ACCENT, TTS_INDEX } from '../lib/get_variable' 2 | import tts from '../lib/tts' 3 | import ttsConfigVault from '../lib/new_tts_config_vault' 4 | 5 | const ttsEnabled = getVariable(TTS) 6 | const ttsAccent = getVariable(TTS_ACCENT) || 'es-AR' 7 | // eslint-disable-next-line prefer-const 8 | let ttsIndex = Number(getVariable(TTS_INDEX)) 9 | ttsIndex > 0 && (ttsIndex -= 1) 10 | 11 | // eslint-disable-next-line no-unused-vars 12 | const [ACCENT_OR_MODIFIER, VARIANT] = [0, 1] 13 | 14 | // const isAAccent = /^[a-zA-Z]{1,2}-[a-zA-Z]{1,2}$/g 15 | 16 | function isAlphabetCharacter(char) { 17 | return /^[a-zA-Z]$/.test(char) 18 | } 19 | 20 | function normalize(accent) { 21 | console.log(accent) 22 | const chars = accent.split('') 23 | if ( 24 | chars.length === 5 && 25 | chars.reduce( 26 | (prev, char, index) => 27 | prev && (index === 2 ? char === '-' : isAlphabetCharacter(char)), 28 | true 29 | ) 30 | ) { 31 | let [prev, post] = accent.split('-') 32 | prev = prev.toLowerCase() 33 | post = post.toUpperCase() 34 | return `${prev}-${post}` 35 | } 36 | return 'nt-VD' 37 | } 38 | 39 | function isAnAccent(toEvaluate) { 40 | const result = tts.isAValidVoice(toEvaluate) 41 | return result 42 | } 43 | 44 | /* 45 | function isAnModifier (toEvaluate) { 46 | return toEvaluate[0] === '-' 47 | } 48 | */ 49 | 50 | const ACC = 0 51 | const VAR = 1 52 | 53 | function config(message) { 54 | const { msg, userName } = message 55 | const words = msg.split(' ').map((word) => word.trim()) 56 | const acce = normalize(words[ACC]) 57 | const vari = Math.ceil(Number(words[VAR])) || 1 58 | const valid = tts.isAValidVoice(acce) && tts.isAValidVariant(acce, vari) 59 | console.log(acce, vari, valid, userName) 60 | if (valid) { 61 | ttsConfigVault.setConfig(userName, acce, !isNaN(vari) ? vari : 1) 62 | } 63 | return true 64 | } 65 | 66 | function reset({ userName }) { 67 | ttsConfigVault.resetConfig(userName) 68 | return true 69 | } 70 | 71 | function speak(message) { 72 | // los uqe votaron que no, la tienen adentro - Sonny - 8/7/2024 73 | const { msg, userName } = message 74 | 75 | if (ttsEnabled) { 76 | const config = ttsConfigVault.getConfig(userName) 77 | let accent = config ? config.accent : ttsAccent 78 | let variant = config ? config.variant : ttsIndex || 1 79 | const words = msg 80 | .replace('!speak ', '') 81 | .split(' ') 82 | .map((word) => word.trim()) 83 | if (isAnAccent(words[0])) { 84 | accent = normalize(String(words.splice(0, 1))) 85 | if (!Number.isNaN(Number(words[0]))) { 86 | variant = Number(words.splice(0, 1)) 87 | } 88 | } 89 | message.speak = { 90 | toRead: words.join(' ').trim().replaceAll(':3', 'AliMoyi'), 91 | accent, 92 | variant 93 | } 94 | return false 95 | } 96 | } 97 | 98 | const TextToSpeak = { 99 | speak, 100 | reset, 101 | config 102 | } 103 | 104 | export default TextToSpeak 105 | -------------------------------------------------------------------------------- /src/components/Message.jsx: -------------------------------------------------------------------------------- 1 | /* eslint-disable react/prop-types */ 2 | import React, { useState } from 'react' 3 | import renderBadges from '../lib/render_badges' 4 | import getAvatar from '../lib/get_avatar' 5 | import './message.css' 6 | import getVariable, { DEFAULT_AVATAR } from '../lib/get_variable' 7 | 8 | const defaultAvatar = getVariable(DEFAULT_AVATAR) 9 | 10 | function _getOrnament(badges) { 11 | if (badges.includes('mod')) return 'from-twitch-mod to-twitch-mod_light' 12 | if (badges.includes('vip')) return 'from-twitch-vip to-twitch-vip_light' 13 | if (badges.includes('broadcaster')) 14 | return 'from-twitch-brd to-twitch-brd_light' 15 | if (badges.includes('subscriber')) 16 | return 'from-twitch-sub to-twitch-sub_light' 17 | return ' from-[#111] to-[#333]' 18 | } 19 | 20 | export default function Message({ message, i }) { 21 | const avatar = getAvatar(message.userId) 22 | const badges = renderBadges(message.badges) 23 | const [loaded, setLoaded] = useState(false) 24 | return ( 25 |
31 | {badges[0] && badges[0]('absolute top-2 left-11')} 32 |
33 |
38 | { 42 | setLoaded(true) 43 | }} 44 | /> 45 | 50 |
51 | 61 | {message.displayName} 62 | 63 |
64 |
69 |
72 |
73 | {badges.slice(1, badges.length).map((badge, i) => badge('ml-1', i))} 74 |
75 |

81 |

82 |
83 |
84 | ) 85 | } 86 | -------------------------------------------------------------------------------- /src/components/StyleMessage.jsx: -------------------------------------------------------------------------------- 1 | /* eslint-disable react/prop-types */ 2 | import React, { useState } from 'react' 3 | import renderBadges from '../lib/render_badges' 4 | import getAvatar from '../lib/get_avatar' 5 | import './message.css' 6 | import getVariable, { DEFAULT_AVATAR } from '../lib/get_variable' 7 | 8 | const defaultAvatar = getVariable(DEFAULT_AVATAR) 9 | 10 | function _getOrnament(badges) { 11 | if (badges.includes('mod')) return 'moderator' 12 | if (badges.includes('vip')) return 'vip' 13 | if (badges.includes('broadcaster')) return 'broadcaster' 14 | if (badges.includes('subscriber')) return 'subscriber' 15 | return 'viewer' 16 | } 17 | 18 | export default function StyledMessage({ message, i }) { 19 | const avatar = getAvatar(message.userId) 20 | const badges = renderBadges(message.badges) 21 | const [loaded, setLoaded] = useState(false) 22 | return ( 23 |
28 | {badges[0] && badges[0]('message_userBadge-primary', 0, true)} 29 |
30 |
31 | { 35 | setLoaded(true) 36 | }} 37 | /> 38 | 43 |
44 | 54 | {message.displayName} 55 | 56 |
57 |
58 |
59 |
60 | {badges 61 | .slice(1, badges.length) 62 | .map((badge, i) => badge('message_userBadge-others', i, true))} 63 |
64 |

71 |

72 |
73 |
74 | ) 75 | } 76 | -------------------------------------------------------------------------------- /src/components/message.css: -------------------------------------------------------------------------------- 1 | .newMessage { 2 | animation-name: newMessage; 3 | animation-duration: 250ms; 4 | animation-iteration-count: 1; 5 | } 6 | 7 | @keyframes newMessage { 8 | 0% { 9 | opacity: 0; 10 | } 11 | 100% { 12 | opacity: 1; 13 | } 14 | } 15 | 16 | .dieingMessage { 17 | animation-name: newMessage; 18 | animation-duration: 300ms; 19 | animation-iteration-count: 1; 20 | } 21 | 22 | @keyframes dieingMessage { 23 | 0% { 24 | opacity: 1; 25 | } 26 | 100% { 27 | opacity: 0; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/filters/commands_filter.js: -------------------------------------------------------------------------------- 1 | import { commandsContainer } from '../lib/containers.js' 2 | import TextToSpeak from '../commands/speak.js' 3 | import filterUsers from '../commands/filter_user.js' 4 | import getVariable, { CHAR_COMMANDS } from '../lib/get_variable.js' 5 | 6 | const charCommands = getVariable(CHAR_COMMANDS)?.split(',') || [] 7 | 8 | commandsContainer.addCommand('!speak', TextToSpeak.speak) 9 | commandsContainer.addCommand('!speak -config', TextToSpeak.config) 10 | commandsContainer.addCommand('!speak -reset', TextToSpeak.reset) 11 | commandsContainer.addCommand('!iacaiate', filterUsers.addFilteredUser) 12 | commandsContainer.addCommand('!iahabla', filterUsers.removeFilteredUser) 13 | 14 | function isA3thPartyCommand(msg) { 15 | return !msg.includes('!hit @jp__is') && charCommands.includes(msg[0]) 16 | } // Pablo (A.K.A. e4yttuh) was here 17 | 18 | export default function commandsFilter(message) { 19 | const { msg, isABot } = message 20 | const isAValidMessage = typeof msg === 'string' 21 | let isACommand = false 22 | if (isAValidMessage && !isABot) { 23 | const command = commandsContainer.foundCommand(msg) 24 | isACommand = 25 | (command && command(message)) || 26 | (command ? false : isA3thPartyCommand(msg)) 27 | } 28 | return isACommand 29 | } 30 | -------------------------------------------------------------------------------- /src/filters/is_not_a_message.js: -------------------------------------------------------------------------------- 1 | export default function isNotAMessage({ msg }) { 2 | return !msg 3 | } 4 | -------------------------------------------------------------------------------- /src/filters/users_filter.js: -------------------------------------------------------------------------------- 1 | import getVariable, { BOTS, CHANNEL } from '../lib/get_variable' 2 | 3 | const channel = getVariable(CHANNEL) 4 | 5 | const userDefinedBots = getVariable(BOTS)?.split(',') 6 | const defaultBots = ['nightbot', 'streamelements', 'el_pato_bot', 'afordibot'] 7 | 8 | const bots = userDefinedBots 9 | ? [...userDefinedBots, ...defaultBots] 10 | : defaultBots 11 | 12 | class BannedUsersContainer { 13 | #bannedUsers = [] 14 | constructor(users = []) { 15 | this.#bannedUsers.push(...users) 16 | } 17 | 18 | get bannedUsers() { 19 | return this.#bannedUsers 20 | } 21 | 22 | set bannedUsers(users) { 23 | this.#bannedUsers = users 24 | } 25 | 26 | addBannedUser(user) { 27 | if (!this.bannedUsers.includes(user) && user !== channel) { 28 | this.bannedUsers.push(user) 29 | } 30 | } 31 | 32 | addBannedUsers(users) { 33 | const filteredUsers = users.filter( 34 | (user) => !this.#bannedUsers.includes(user) && user !== channel 35 | ) 36 | if (filteredUsers.length > 0) { 37 | this.bannedUsers.push(...filteredUsers) 38 | } 39 | } 40 | 41 | removeBannedUser(user) { 42 | if (!bots.includes(user)) { 43 | const index = this.bannedUsers.indexOf(user) 44 | if (index > -1) { 45 | this.bannedUsers.splice(index, 1) 46 | } 47 | } 48 | } 49 | 50 | removeBannedUsers(users) { 51 | const filteredUsers = users.filter((user) => !bots.includes(user)) 52 | if (filteredUsers.length > 0) { 53 | this.bannedUsers = this.bannedUsers.filter( 54 | (user) => !filteredUsers.includes(user) 55 | ) 56 | } 57 | } 58 | } 59 | 60 | export const bannedUsersContainer = new BannedUsersContainer(bots) 61 | 62 | export default function usersFilter(msg) { 63 | if (bannedUsersContainer.bannedUsers.includes(msg.userName)) { 64 | msg.isABot = true 65 | return true 66 | } 67 | return false 68 | } 69 | -------------------------------------------------------------------------------- /src/hooks/use_connect_websocket_to_twitch_irc.js: -------------------------------------------------------------------------------- 1 | import { useState, useEffect } from 'react' 2 | import useWebSocket, { ReadyState } from 'react-use-websocket' 3 | import getVariable, { 4 | ACCESS_TOKEN, 5 | CHANNEL, 6 | CLIENT_ID, 7 | REDIRECT_URI 8 | } from '../lib/get_variable' 9 | 10 | export default function useConnectWebSocketToTwitchIRC() { 11 | const redirectUri = getVariable(REDIRECT_URI) 12 | const accessToken = getVariable(ACCESS_TOKEN) 13 | const clientId = getVariable(CLIENT_ID) 14 | const channel = getVariable(CHANNEL) 15 | 16 | /* 17 | Si no tengo el token para acceder al contenido del chat abro el OAuth de 18 | twitch para conseguirlo. Espero que por param de la URL me llegue el 19 | token de acceso gracias OAuth de Twitch si no lo tengo espero recibir el 20 | param CLientID o tenerlo ya el LocalStorage (registrado ya como APP en 21 | la consola de Twitch) para ejecutar el OAuth y recibir el Token 22 | */ 23 | 24 | if (accessToken === undefined) { 25 | const URL = `https://id.twitch.tv/oauth2/authorize?response_type=token&client_id=${clientId}&redirect_uri=${redirectUri}&scope=chat%3Aread` 26 | 27 | if ('navigation' in window) { 28 | // eslint-disable-next-line no-undef 29 | navigation.navigate(URL) 30 | } else { 31 | window.location.href = URL 32 | } 33 | } 34 | 35 | /* 36 | Una vez tengo el Token de acceso a twitch abro un websocket para 37 | conectarme al IRC, autenticarme y empezar a recibir los mensajes. 38 | */ 39 | const [logged, setLogged] = useState(false) 40 | const webSocket = useWebSocket( 41 | redirectUri 42 | ? 'wss://irc-ws.chat.twitch.tv:443' 43 | : 'ws://irc-ws.chat.twitch.tv:80', 44 | { 45 | share: true, 46 | shouldReconnect: () => true 47 | } 48 | ) 49 | const { sendMessage, lastMessage, readyState } = webSocket 50 | 51 | useEffect(() => { 52 | if (accessToken && !logged && readyState === ReadyState.OPEN) { 53 | sendMessage( 54 | 'CAP REQ :twitch.tv/membership twitch.tv/tags twitch.tv/commands' 55 | ) 56 | sendMessage(`PASS oauth:${accessToken}`) 57 | sendMessage('NICK ChrisVDev_OBS-Chat') 58 | sendMessage(`JOIN #${channel}`) 59 | setLogged(true) 60 | } 61 | if (readyState !== ReadyState.OPEN) setLogged(false) 62 | }, [logged, webSocket]) 63 | 64 | /* 65 | Una vez autenticado separo los mensajes del chat de el resto de la info 66 | que me pasa el IRC. Importante -> de paso contesto al PING para que Twitch 67 | no me cierre la conexión. 68 | */ 69 | const [message, setMessage] = useState('') // ultimo mensaje 70 | useEffect(() => { 71 | if (readyState === ReadyState.OPEN && logged) { 72 | lastMessage && 73 | lastMessage.data.includes('PRIVMSG') && 74 | // PRIVMSG son los mensajes de los usuarios en el canal 75 | setMessage(lastMessage.data) // guardo el ultimo mensaje 76 | lastMessage && 77 | lastMessage.data.includes('PING') && 78 | sendMessage('PONG :tmi.twitch.tv') 79 | } 80 | }, [lastMessage]) 81 | 82 | return message 83 | /* 84 | trigereo una nueva actualización del componente que lo consuma solo si hay un 85 | mensaje nuevo 86 | */ 87 | } 88 | -------------------------------------------------------------------------------- /src/hooks/use_message_logic.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from 'react' 2 | // eslint-disable-next-line max-len 3 | import useConnectWebSocketToTwitchIRC from './use_connect_websocket_to_twitch_irc.js' 4 | import messagePreProcessor from '../lib/message_pre_processor.js' 5 | import messageFilters from '../lib/massage_filters.js' 6 | import messageToRenderProcessor from '../lib/message_to_render_processor.js' 7 | import usersFilter from '../filters/users_filter.js' 8 | import commandsFilter from '../filters/commands_filter.js' 9 | import isNotAMessage from '../filters/is_not_a_message.js' 10 | import ttsAlwaysOn from '../middlewares/tts_always_on.js' 11 | import antiGoose from '../middlewares/anti_ganzos.js' 12 | import action from '../middlewares/action.js' 13 | import usernamePlacer from '../middlewares/username_placer.js' 14 | import renderCommands from '../middlewares/render_commands.js' 15 | import getMessageEmojis from '../middlewares/get_message_emojis.js' 16 | import linkRemover from '../middlewares/link_remover.js' 17 | import longWordsRemover from '../middlewares/long_words_remover.js' 18 | import preloadUserData from '../middlewares/avatar_placer.js' 19 | import messageCleaner from '../middlewares/message_cleaner.js' 20 | import speakMessageRender from '../middlewares/speak_message_render.js' 21 | import filterHTMLTags from '../middlewares/filter_html_tags.js' 22 | import placeEmojis from '../middlewares/place_emojis.js' 23 | import placeHTML from '../middlewares/place_html.js' 24 | import placeHearts from '../middlewares/place_hearts.js' 25 | import patoBotMiddleware from '../middlewares/pato_bot_middleware.js' 26 | import toTTS from '../middlewares/to_tts.js' 27 | import getVariable, { 28 | CHANNEL, 29 | HTMLI, 30 | PATO_BOT, 31 | TTS_ALWAYS_ON 32 | } from '../lib/get_variable.js' 33 | 34 | const channel = getVariable(CHANNEL) 35 | const patoBot = getVariable(PATO_BOT) 36 | const htmli = getVariable(HTMLI) 37 | const TTSAlwaysOn = getVariable(TTS_ALWAYS_ON) 38 | 39 | messagePreProcessor.setChannel(channel) 40 | messagePreProcessor.useMiddleware(getMessageEmojis) 41 | messagePreProcessor.useMiddleware(preloadUserData) 42 | messagePreProcessor.useMiddleware(linkRemover) // hay que arreglar 43 | messagePreProcessor.useMiddleware(longWordsRemover) 44 | messagePreProcessor.useMiddleware(antiGoose) 45 | messagePreProcessor.useMiddleware(usernamePlacer) 46 | messagePreProcessor.useMiddleware(action) 47 | 48 | messageFilters.addFilter(isNotAMessage) 49 | messageFilters.addFilter(usersFilter) 50 | messageFilters.addFilter(commandsFilter) 51 | 52 | messageToRenderProcessor.useMiddleware(ttsAlwaysOn) 53 | messageToRenderProcessor.useMiddleware(renderCommands) 54 | messageToRenderProcessor.useMiddleware(messageCleaner) 55 | !TTSAlwaysOn && messageToRenderProcessor.useMiddleware(speakMessageRender) 56 | messageToRenderProcessor.useMiddleware(filterHTMLTags) 57 | messageToRenderProcessor.useMiddleware(placeHearts) 58 | messageToRenderProcessor.useMiddleware(placeEmojis) 59 | htmli && messageToRenderProcessor.useMiddleware(placeHTML) 60 | patoBot && messageToRenderProcessor.useMiddleware(patoBotMiddleware) 61 | messageToRenderProcessor.useMiddleware(toTTS) 62 | 63 | export default function useMessageLogic() { 64 | const message = useConnectWebSocketToTwitchIRC(channel) 65 | const [messageToRender, setMessageToRender] = useState({}) 66 | useEffect(() => { 67 | const income = messagePreProcessor.processMessage(message) 68 | 69 | if (messageFilters.mustBeFiltered(income)) { 70 | setMessageToRender(messageToRenderProcessor.processMessage(income)) 71 | } 72 | }, [message]) 73 | return messageToRender 74 | } 75 | -------------------------------------------------------------------------------- /src/hooks/use_message_queue.js: -------------------------------------------------------------------------------- 1 | import { useState, useEffect, useCallback } from 'react' 2 | import useMessageLogic from './use_message_logic' 3 | 4 | export default function useMessageQueue() { 5 | const message = useMessageLogic() 6 | const [queue, setQueue] = useState([]) 7 | const [, setInter] = useState(0) 8 | const onRefresh = useCallback( 9 | (cue) => 10 | cue.map((message) => 11 | message.ttl === 1 12 | ? { ...message, dieing: true } 13 | : { ...message, new: false } 14 | ), 15 | [] 16 | ) 17 | useEffect(() => { 18 | message.msg && 19 | setQueue((lastQueue) => [ 20 | ...lastQueue, 21 | { ...message, ttl: 10, new: true } 22 | ]) 23 | }, [message]) 24 | useEffect(() => { 25 | setInter( 26 | setInterval(() => { 27 | setQueue((lastQueue) => 28 | onRefresh( 29 | lastQueue 30 | .map((message) => ({ ...message, ttl: message.ttl - 1 })) 31 | .filter((message) => message.ttl > 0) 32 | ) 33 | ) 34 | }, 2000) 35 | ) 36 | }, []) 37 | return queue 38 | } 39 | -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: Inter; 3 | font-style: normal; 4 | font-weight: 400; 5 | src: 6 | url(./fonts/inter-latin-variable-wghtOnly-normal.woff2) 7 | format('woff2-variations'), 8 | url(./fonts/inter-latin-400-normal.woff2) format('woff2'), 9 | url(./fonts/inter-latin-400-normal.woff) format('woff'); 10 | unicode-range: u+00??, u+0131, u+0152-0153, u+02bb-02bc, u+02c6, u+02da, 11 | u+02dc, u+2000-206f, u+2074, u+20ac, u+2122, u+2191, u+2193, u+2212, u+2215, 12 | u+feff, u+fffd; 13 | } 14 | @tailwind base; 15 | @tailwind components; 16 | @tailwind utilities; 17 | 18 | body { 19 | background-color: #2d2d2d; 20 | } 21 | -------------------------------------------------------------------------------- /src/lib/channel_resources.js: -------------------------------------------------------------------------------- 1 | import getVariable, { CHANNEL, ACCESS_TOKEN, CLIENT_ID } from './get_variable' 2 | import axios from 'axios' 3 | 4 | const channel = getVariable(CHANNEL) 5 | const accessToken = getVariable(ACCESS_TOKEN) 6 | const clientId = getVariable(CLIENT_ID) 7 | 8 | const config = { 9 | headers: { 10 | Authorization: `Bearer ${accessToken}`, 11 | 'Client-Id': clientId 12 | } 13 | } 14 | 15 | class ChannelResources { 16 | constructor() { 17 | this.channelData = {} 18 | this.badges = [] 19 | axios 20 | .get(`https://api.twitch.tv/helix/users?login=${channel}`, config) 21 | .then(({ data }) => { 22 | this.channelData = data.data[0] 23 | // eslint-disable-next-line max-len 24 | axios 25 | .get( 26 | `https://api.twitch.tv/helix/chat/badges?broadcaster_id=${this.channelData.id}`, 27 | config 28 | ) 29 | .then(({ data }) => { 30 | this.badges = [ 31 | ...this.badges, 32 | ...data.data.map(({ set_id: setId, versions }) => ({ 33 | id: setId, 34 | url: versions[0].image_url_2x 35 | })) 36 | ] 37 | }) 38 | }) 39 | axios 40 | .get(`https://api.twitch.tv/helix/chat/badges/global`, config) 41 | .then(({ data }) => { 42 | this.badges = [ 43 | ...this.badges, 44 | ...data.data.map(({ set_id: setId, versions }) => ({ 45 | id: setId, 46 | url: versions[0].image_url_2x 47 | })) 48 | ] 49 | }) 50 | } 51 | } 52 | 53 | const channelResources = new ChannelResources() 54 | 55 | export default channelResources 56 | -------------------------------------------------------------------------------- /src/lib/commands_container.js: -------------------------------------------------------------------------------- 1 | class ComManzContainer { 2 | #commands = {} 3 | #EXEC = Symbol('exec') 4 | #splitKeys(message) { 5 | return message.trim().split(/\s+/) 6 | } 7 | 8 | addCommand(command, cb) { 9 | const keys = this.#splitKeys(command) 10 | let lastRef = this.#commands 11 | keys.forEach((key) => { 12 | if (lastRef[key]) { 13 | lastRef = lastRef[key] 14 | } else { 15 | lastRef[key] = {} 16 | lastRef = lastRef[key] 17 | } 18 | }) 19 | lastRef[this.#EXEC] = cb 20 | } 21 | 22 | foundCommand(message) { 23 | const keys = this.#splitKeys(message) 24 | let lastRef = this.#commands 25 | let keyIndex = 0 26 | const searchCommand = () => { 27 | if (lastRef) { 28 | if (lastRef[keys[keyIndex]]) { 29 | lastRef = lastRef[keys[keyIndex]] 30 | keyIndex++ 31 | return searchCommand() 32 | } 33 | if (lastRef[this.#EXEC]) return lastRef[this.#EXEC] 34 | return false 35 | } 36 | } 37 | const command = searchCommand() 38 | return command 39 | ? (message) => { 40 | message.msg = keys.slice(keyIndex).join(' ') 41 | return command(message) 42 | } 43 | : false 44 | } 45 | } 46 | 47 | export default ComManzContainer 48 | -------------------------------------------------------------------------------- /src/lib/commands_container_sonny.js: -------------------------------------------------------------------------------- 1 | // Based on the logic of a code madded from SonnyArg, THX <3 2 | 3 | class Trigger { 4 | constructor(pattern, priority, execute) { 5 | this.pattern = pattern 6 | this.execute = execute 7 | this.priority = priority 8 | } 9 | 10 | test(msg) { 11 | const result = /^!comando1\s+hola(?:\s+(.+))?$/i.test(msg) 12 | console.log(typeof msg, this.pattern instanceof RegExp, result) 13 | return result 14 | } 15 | 16 | getArgs(msg) { 17 | let ref, ref1 18 | const match = (ref = this.pattern.exec(msg)) != null ? ref : [''] 19 | const capture = (ref1 = match[1]) != null ? ref1 : '' 20 | if (!/\S/.test(capture)) { 21 | return [] 22 | } 23 | return capture.split(/\s+/) 24 | } 25 | } 26 | 27 | function escapeRegex(string) { 28 | return string.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&') 29 | } 30 | 31 | function buildTrigger(command, execute) { 32 | let words 33 | words = command.split(' ') 34 | words = words.map((word) => escapeRegex(word)) 35 | const regex = new RegExp('^!' + words.join('\\s+') + '(?:\\s+(.+))?$', 'i') 36 | console.log(regex) 37 | const priority = words.length 38 | return new Trigger(regex, priority, execute) 39 | } 40 | 41 | class CommandsContainer { 42 | #commands = [] 43 | addCommand(command, cb) { 44 | this.#commands.push(buildTrigger(command, cb)) 45 | this.#commands.sort( 46 | ({ priority: priorityA }, { priority: priorityB }) => 47 | priorityB - priorityA 48 | ) 49 | } 50 | 51 | matchCommand(message) { 52 | return this.#commands.find((trigger) => trigger.test(message)) 53 | } 54 | 55 | executeIfFound(message) { 56 | const trigger = this.matchCommand(message) 57 | if (trigger && typeof trigger.execute === 'function') 58 | return trigger.execute(trigger.getArgs(message)) 59 | return false 60 | } 61 | } 62 | 63 | export default CommandsContainer 64 | -------------------------------------------------------------------------------- /src/lib/containers.js: -------------------------------------------------------------------------------- 1 | import ComManzContainer from './commands_container.js' 2 | 3 | export const commandsContainer = new ComManzContainer() 4 | export const renderCommandsContainer = new ComManzContainer() 5 | -------------------------------------------------------------------------------- /src/lib/get_avatar.js: -------------------------------------------------------------------------------- 1 | import userDataStorage from './users_data_storage' 2 | import getVariable, { DEFAULT_AVATAR } from './get_variable' 3 | 4 | const defaultAvatar = getVariable(DEFAULT_AVATAR) 5 | 6 | export default function getAvatar(userId) { 7 | const avatar = userDataStorage 8 | .getUserData(userId) 9 | .profileImageUrl?.replaceAll('300', '70') 10 | return avatar 11 | ? avatar.includes('user-default-pictures') 12 | ? defaultAvatar 13 | : avatar 14 | : defaultAvatar 15 | } 16 | -------------------------------------------------------------------------------- /src/lib/get_url_params.js: -------------------------------------------------------------------------------- 1 | export default function getURLParams() { 2 | const url = new URL(document.location.href.replace('#', '?')) 3 | const params = {} 4 | url.searchParams.forEach((value, name) => (params[name] = value)) 5 | return params 6 | } 7 | -------------------------------------------------------------------------------- /src/lib/get_variable.js: -------------------------------------------------------------------------------- 1 | import getURLParams from './get_url_params' 2 | const VARIABLES = 'variables' 3 | 4 | // config de twitch 5 | export const REDIRECT_URI = 'redirect_uri' 6 | export const SECRET = 'secret' 7 | export const CLIENT_ID = 'client_id' 8 | export const ACCESS_TOKEN = 'access_token' 9 | export const CHANNEL = 'channel' 10 | 11 | // estilos 12 | export const DEFAULT_AVATAR = 'default_avatar' 13 | export const STYLE = 'style' 14 | 15 | // funciones 16 | export const PATO_BOT = 'pato_bot' 17 | export const TTS = 'tts' 18 | export const TTS_INDEX = 'tts_index' 19 | export const TTS_ACCENT = 'tts_accent' 20 | export const TTS_ALWAYS_ON = 'tts_always_on' 21 | export const TTS_MENTIONS = 'tts_mentions' 22 | export const RENDER = 'render' 23 | export const BOTS = 'bots' 24 | export const HTMLI = 'htmli' 25 | export const CHAR_COMMANDS = 'char_commands' 26 | 27 | let variables = JSON.parse(localStorage.getItem(VARIABLES)) || {} 28 | 29 | variables = { ...variables, ...getURLParams() } 30 | 31 | Object.keys(variables).forEach((key) => { 32 | if (typeof variables[key] === 'string') { 33 | if (variables[key].toLowerCase() === 'true') variables[key] = true 34 | if (`${variables[key]}`.toLowerCase() === 'false') variables[key] = false 35 | } 36 | }) 37 | 38 | typeof variables[TTS_INDEX] === 'string' && 39 | (variables[TTS_INDEX] = Number(variables[TTS_INDEX]) || 1) 40 | 41 | localStorage.setItem(VARIABLES, JSON.stringify(variables)) 42 | 43 | const env = { 44 | redirect_uri: import.meta.env.VITE_REDIRECT_URI || 'http://localhost:5173/', 45 | secret: import.meta.env.VITE_SECRET, 46 | client_id: import.meta.env.VITE_CLIENT_ID, 47 | access_token: import.meta.env.VITE_ACCESS_TOKEN, 48 | channel: import.meta.env.VITE_CHANNEL 49 | } 50 | 51 | variables[DEFAULT_AVATAR] ??= './assets/st-chrisvdev.gif' 52 | 53 | Object.keys(env).forEach((key) => { 54 | if (env[key]) variables[key] = env[key] 55 | }) 56 | 57 | const activeByDefault = [TTS, PATO_BOT, RENDER] 58 | 59 | activeByDefault.forEach((key) => { 60 | if (variables[key] === undefined) variables[key] = true 61 | }) 62 | 63 | export default function getVariable(variable) { 64 | return variables[variable] 65 | } 66 | -------------------------------------------------------------------------------- /src/lib/massage_filters.js: -------------------------------------------------------------------------------- 1 | class MessageFilters { 2 | constructor() { 3 | this.filters = [] 4 | } 5 | 6 | addFilter(cb) { 7 | this.filters.push(cb) 8 | } 9 | 10 | mustBeFiltered(message) { 11 | return !this.filters.reduce((prev, cb) => { 12 | const res = cb(message) 13 | return res || prev 14 | }, false) 15 | } 16 | } 17 | 18 | const messageFilters = new MessageFilters() 19 | 20 | export default messageFilters 21 | -------------------------------------------------------------------------------- /src/lib/message_pre_processor.js: -------------------------------------------------------------------------------- 1 | function toCamelCase(key) { 2 | const words = key.split('-') 3 | if (words.length > 1) { 4 | for (let i = 1; i < words.length; i++) 5 | words[i] = words[i].replace(words[i][0], words[i][0].toUpperCase()) 6 | return words.join('') 7 | } 8 | return key 9 | } 10 | 11 | function apiDecoupler(rawObjMsg) { 12 | return { 13 | msg: rawObjMsg.msg, 14 | badgeInfo: rawObjMsg['@badgeInfo'], 15 | badges: rawObjMsg.badges, 16 | clientNonce: rawObjMsg.clientNonce, 17 | color: rawObjMsg.color, 18 | displayName: rawObjMsg.displayName, 19 | emotes: rawObjMsg.emotes, 20 | firstMsg: rawObjMsg.firstMsg, 21 | flags: rawObjMsg.flags, 22 | id: rawObjMsg.id, 23 | mod: rawObjMsg.mod === '1', 24 | vip: rawObjMsg.vip, 25 | streamer: rawObjMsg.badges?.includes('broadcaster'), 26 | returningChatter: rawObjMsg.returningChatter, 27 | roomId: rawObjMsg.roomId, 28 | subscriber: rawObjMsg.subscriber, 29 | tmiSentTs: rawObjMsg.tmiSentTs, 30 | turbo: rawObjMsg.turbo, 31 | userId: rawObjMsg.userId, 32 | userType: rawObjMsg.userType, 33 | replyParentDisplayName: rawObjMsg.replyParentDisplayName, 34 | replyParentMsgBody: rawObjMsg.replyParentMsgBody, 35 | replyParentMsgId: rawObjMsg.replyParentMsgId, 36 | replyParentUserId: rawObjMsg.replyParentUserId, 37 | replyParentUserLogin: rawObjMsg.replyParentUserLogin, 38 | replyThreadParentMsgId: rawObjMsg.replyThreadParentMsgId, 39 | replyThreadParentUserLogin: rawObjMsg.replyThreadParentUserLogin, 40 | emoteOnly: rawObjMsg.emoteOnly 41 | } 42 | } 43 | 44 | class MessagePreProcessor { 45 | constructor() { 46 | this.middlewares = [] 47 | this.channel = '' 48 | } 49 | 50 | _mkMsgObj = (rawMsg) => { 51 | const [data, msg] = rawMsg.split(`PRIVMSG #${this.channel} :`) 52 | const rawObjMsg = { msg } 53 | data.split(';').forEach((element) => { 54 | if (element) { 55 | const [key, value] = element.split('=') 56 | rawObjMsg[toCamelCase(key)] = value 57 | } 58 | }) 59 | console.log(rawObjMsg) 60 | return apiDecoupler(rawObjMsg) 61 | } 62 | 63 | setChannel(channel) { 64 | this.channel = channel 65 | } 66 | 67 | useMiddleware(cb) { 68 | this.middlewares.push(cb) 69 | } 70 | 71 | processMessage(rawMessage) { 72 | let message = this._mkMsgObj(rawMessage) 73 | this.middlewares.forEach((cb) => { 74 | message = cb(message) 75 | }) 76 | return message 77 | } 78 | } 79 | 80 | const messagePreProcessor = new MessagePreProcessor() 81 | 82 | export default messagePreProcessor 83 | -------------------------------------------------------------------------------- /src/lib/message_to_render_processor.js: -------------------------------------------------------------------------------- 1 | class MessageToRenderProcessor { 2 | constructor() { 3 | this.middlewares = [] 4 | } 5 | 6 | useMiddleware(cb) { 7 | this.middlewares.push(cb) 8 | } 9 | 10 | processMessage(rawMessage) { 11 | let message = rawMessage 12 | this.middlewares.forEach((cb) => { 13 | message = cb(message) 14 | }) 15 | return message 16 | } 17 | } 18 | 19 | const messageToRenderProcessor = new MessageToRenderProcessor() 20 | 21 | export default messageToRenderProcessor 22 | -------------------------------------------------------------------------------- /src/lib/new_tts_config_vault.js: -------------------------------------------------------------------------------- 1 | import tts from './tts.js' 2 | 3 | const VAULT = 'TTS' 4 | 5 | class TTSConfigVault { 6 | #vault 7 | #ls_outdated 8 | constructor() { 9 | this.#vault = JSON.parse(localStorage.getItem(VAULT)) 10 | if (!this.#vault) { 11 | this.#vault = {} 12 | localStorage.setItem(VAULT, '{}') 13 | } 14 | this.#ls_outdated = false 15 | } 16 | 17 | getVault() { 18 | return this.#vault 19 | } 20 | 21 | #LSVaultListener(event) { 22 | console.log('se ha cambiado en LS') 23 | if (event.key === VAULT) { 24 | if (JSON.stringify(this.#vault) === event.newValue) { 25 | this.#ls_outdated = false 26 | window.removeEventListener('storage', this.#LSVaultListener) 27 | console.log('Memoria y LS son iguales') 28 | } else { 29 | localStorage.setItem(VAULT, JSON.stringify(this.#vault)) 30 | console.log('Memoria y LS son diferentes') 31 | } 32 | this.#ls_outdated = false 33 | } 34 | } 35 | 36 | #lsIsOutdated() { 37 | console.log('se ha cambiado en memoria', this.#vault) 38 | if (!this.#ls_outdated) 39 | window.addEventListener('storage', this.#LSVaultListener) 40 | this.#ls_outdated = true 41 | localStorage.setItem(VAULT, JSON.stringify(this.#vault)) 42 | } 43 | 44 | getConfig(userName) { 45 | if (this.getVault()[userName]) { 46 | return this.getVault()[userName] 47 | } else return null 48 | } 49 | 50 | setConfig(userName, accent, variant) { 51 | if (tts.isAValidVoice(accent)) { 52 | this.#vault[userName] = { 53 | accent, 54 | variant: tts.isAValidVariant(accent, variant) ? variant : 1 55 | } 56 | this.#lsIsOutdated() 57 | } 58 | } 59 | 60 | resetConfig(userName) { 61 | if (this.#vault[userName]) { 62 | this.#vault[userName] = undefined 63 | this.#ls_outdated = true 64 | } 65 | 66 | this.#lsIsOutdated() 67 | } 68 | } 69 | 70 | const ttsConfigVault = new TTSConfigVault() 71 | 72 | export default ttsConfigVault 73 | -------------------------------------------------------------------------------- /src/lib/regex_dynamic.js: -------------------------------------------------------------------------------- 1 | // by sonnyARG 😎 2 | 3 | export default function regexDynamic(palabra) { 4 | if (typeof palabra !== 'string') return null 5 | let rgxLetras = `` 6 | ;[...palabra].forEach((letra) => { 7 | // eslint-disable-next-line no-useless-escape 8 | rgxLetras += `[\s]*` + letra 9 | }) 10 | return new RegExp('(' + rgxLetras + ')', 'gi') 11 | } 12 | -------------------------------------------------------------------------------- /src/lib/render_badges.js: -------------------------------------------------------------------------------- 1 | import { createElement } from 'react' 2 | import channelResources from './channel_resources' 3 | 4 | function getBadges(badges) { 5 | return badges.split(',').map((badge) => badge.split('/')[0]) 6 | } 7 | 8 | const getBadge = (id) => 9 | channelResources.badges.filter((badge) => badge.id === id)[0] 10 | 11 | const renderBadge = (id) => 12 | getBadge(id) 13 | ? (className, key, noStyle) => 14 | createElement( 15 | 'img', 16 | { 17 | key: `badges_${id}_${key}`, 18 | className: `${ 19 | noStyle ? 'message_userBadge' : 'z-10 h-5 w-5' 20 | } ${className}`, 21 | src: `${getBadge(id).url}`, 22 | alt: `${id}` 23 | }, 24 | null 25 | ) 26 | : undefined 27 | 28 | export default function renderBadges(badgesStr) { 29 | const badges = getBadges(badgesStr) 30 | return badges.map((badge) => { 31 | return renderBadge(badge) 32 | }) 33 | } 34 | -------------------------------------------------------------------------------- /src/lib/render_emoji.js: -------------------------------------------------------------------------------- 1 | export default function renderEmoji(id) { 2 | // eslint-disable-next-line max-len 3 | return `` 4 | } 5 | -------------------------------------------------------------------------------- /src/lib/tts.js: -------------------------------------------------------------------------------- 1 | class TTS { 2 | #voices 3 | #onReady 4 | #ready 5 | #whenSinthReady 6 | constructor() { 7 | this.#voices = {} 8 | this.#onReady = [] 9 | this.#ready = false 10 | this.#whenSinthReady = () => { 11 | speechSynthesis.getVoices().forEach((voice) => { 12 | const { lang } = voice 13 | if (lang.length === 5) 14 | this.#voices[lang] 15 | ? (this.#voices[lang] += 1) 16 | : (this.#voices[lang] = 1) 17 | this.#ready = true 18 | this.#onReady.forEach((cb) => { 19 | cb(this.#voices) 20 | }) 21 | speechSynthesis.removeEventListener( 22 | 'voiceschanged', 23 | this.#whenSinthReady 24 | ) 25 | }) 26 | } 27 | speechSynthesis.addEventListener('voiceschanged', this.#whenSinthReady) 28 | } 29 | 30 | speak(msj, accent, variant) { 31 | const toSpeak = new SpeechSynthesisUtterance(msj) 32 | toSpeak.voice = this.#voices[accent] 33 | ? variant <= this.#voices[accent] 34 | ? speechSynthesis.getVoices().filter((voice) => voice.lang === accent)[ 35 | variant - 1 36 | ] 37 | : speechSynthesis 38 | .getVoices() 39 | .filter((voice) => voice.lang === accent)[0] 40 | : speechSynthesis.getVoices()[0] 41 | speechSynthesis.speak(toSpeak) 42 | } 43 | 44 | getVoices() { 45 | return structuredClone(this.#voices) 46 | } 47 | 48 | whenReady(cb) { 49 | this.#ready ? cb(this.#voices) : this.#onReady.push(cb) 50 | } 51 | 52 | isAValidVoice(voice) { 53 | return Boolean(this.#voices[voice]) 54 | } 55 | 56 | isAValidVariant(accent, variant) { 57 | if (this.isAValidVoice(accent)) { 58 | return variant <= this.#voices[accent] && variant > 0 59 | } 60 | return false 61 | } 62 | } 63 | 64 | const tts = new TTS() 65 | 66 | export default tts 67 | -------------------------------------------------------------------------------- /src/lib/tts_config_vault.js: -------------------------------------------------------------------------------- 1 | /* 2 | Aquí estaba aprendiendo por primera vez lo que es una clase con métodos estáticos 3 | asi que me los puse a implementar por aprenderlos. No me juzgues, es por amor a 4 | incorporar conocimiento nuevo. Para que veas que se hacer Singletons mírate el 5 | TTS.js 6 | */ 7 | 8 | import tts from './tts.js' 9 | 10 | const VAULT = 'TTS' 11 | 12 | export default class TTSConfigVault { 13 | static getVault() { 14 | let vault = JSON.parse(localStorage.getItem(VAULT)) 15 | if (!vault) { 16 | vault = {} 17 | localStorage.setItem(VAULT, '{}') 18 | } 19 | return vault 20 | } 21 | 22 | static getConfig(userName) { 23 | if (this.getVault()[userName]) { 24 | return this.getVault()[userName] 25 | } else return null 26 | } 27 | 28 | static setConfig(userName, accent, variant) { 29 | if (tts.isAValidVoice(accent)) { 30 | const vault = this.getVault() 31 | 32 | vault[userName] = { 33 | accent, 34 | variant: tts.isAValidVariant(accent, variant) ? variant : 1 35 | } 36 | localStorage.setItem(VAULT, JSON.stringify(vault)) 37 | } 38 | } 39 | 40 | static resetConfig(userName) { 41 | if (this.getVault()[userName]) { 42 | const vault = this.getVault() 43 | vault[userName] = undefined 44 | localStorage.setItem(VAULT, JSON.stringify(vault)) 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/lib/users_data_storage.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | import getVariable, { ACCESS_TOKEN, CLIENT_ID } from './get_variable' 3 | 4 | const clientId = getVariable(CLIENT_ID) 5 | const accessToken = getVariable(ACCESS_TOKEN) 6 | 7 | function apiDecoupler(rawUserData) { 8 | return { 9 | id: rawUserData.id, 10 | login: rawUserData.login, 11 | displayName: rawUserData.display_name, 12 | type: rawUserData.type, 13 | broadcasterType: rawUserData.broadcaster_type, 14 | description: rawUserData.description, 15 | profileImageUrl: rawUserData.profile_image_url, 16 | offlineImageUrl: rawUserData.offline_image_url, 17 | viewCount: rawUserData.view_count, 18 | createdAt: rawUserData.created_at 19 | } 20 | } 21 | 22 | class UsersDataStorage { 23 | #storage 24 | constructor() { 25 | this.#storage = {} 26 | } 27 | 28 | getUserData(userId) { 29 | if (!this.#storage[userId]) { 30 | axios({ 31 | url: `https://api.twitch.tv/helix/users?id=${userId}`, 32 | method: 'GET', 33 | headers: { 34 | Authorization: `Bearer ${accessToken}`, 35 | 'Client-Id': clientId 36 | } 37 | }).then((response) => { 38 | this.#storage[userId] = apiDecoupler(response.data.data[0]) 39 | }) 40 | return apiDecoupler({}) 41 | } 42 | return this.#storage[userId] 43 | } 44 | } 45 | 46 | const userDataStorage = new UsersDataStorage() 47 | 48 | export default userDataStorage 49 | -------------------------------------------------------------------------------- /src/main.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom/client' 3 | import App from './App' 4 | import './index.css' 5 | 6 | ReactDOM.createRoot(document.getElementById('root')).render( 7 | 8 | 9 | 10 | ) 11 | -------------------------------------------------------------------------------- /src/middlewares/action.js: -------------------------------------------------------------------------------- 1 | export default function action(message) { 2 | if (message.msg?.includes('\u0001ACTION ')) { 3 | message.msg = message.msg.replace('\u0001ACTION ', '') 4 | message.msg = message.msg.replace('\u0001', '') 5 | message.msg = `💁 ${message.msg}` 6 | } 7 | return message 8 | } 9 | -------------------------------------------------------------------------------- /src/middlewares/anti_ganzos.js: -------------------------------------------------------------------------------- 1 | // improved by sonnyARG 😎 2 | 3 | import regexDynamic from '../lib/regex_dynamic' 4 | const goose = regexDynamic('goose') 5 | const ganso = regexDynamic('ganso') 6 | const ganzo = regexDynamic('ganzo') 7 | 8 | export default function antiGoose(message) { 9 | if (goose.test(message.msg)) 10 | message.msg = message.msg.replaceAll(goose, ' duck') 11 | if (ganso.test(message.msg)) 12 | message.msg = message.msg.replaceAll(ganso, ' pato') 13 | if (ganzo.test(message.msg)) 14 | message.msg = message.msg.replaceAll(ganzo, ' pato') 15 | return message 16 | } 17 | -------------------------------------------------------------------------------- /src/middlewares/avatar_placer.js: -------------------------------------------------------------------------------- 1 | import userDataStorage from '../lib/users_data_storage' 2 | 3 | export default function preloadUserData(message) { 4 | if (message.userId) userDataStorage.getUserData(message.userId) 5 | return message 6 | } 7 | -------------------------------------------------------------------------------- /src/middlewares/defaultAvatar.js: -------------------------------------------------------------------------------- 1 | export default function defaultAvatar(msg) { 2 | if (msg && msg.avatar?.includes('/user-default-pictures-uv/')) 3 | msg.avatar = '/assets/st-chrisvdev.gif' 4 | return msg 5 | } 6 | -------------------------------------------------------------------------------- /src/middlewares/filter_html_tags.js: -------------------------------------------------------------------------------- 1 | export default function filterHTMLTags(message) { 2 | // obra y gracia de JP__is ❤️ 3 | message.msg = message.msg.replaceAll('<', '<').replaceAll('>', '>') 4 | return message 5 | } 6 | -------------------------------------------------------------------------------- /src/middlewares/get_message_emojis.js: -------------------------------------------------------------------------------- 1 | export default function getMessageEmojis(message) { 2 | const emojis = {} 3 | if (message.emotes) { 4 | const letters = message.msg.split('') 5 | message.emotes.split('/').forEach((rawEmote) => { 6 | let [id, range] = rawEmote.split(':') 7 | const [start, end] = range.split(',')[0].split('-') 8 | range = { 9 | start: Number(start), 10 | end: Number(end) + 1 11 | } 12 | emojis[letters.slice(range.start, range.end).join('')] = id 13 | }) 14 | message.emotes = emojis 15 | } 16 | return message 17 | } 18 | -------------------------------------------------------------------------------- /src/middlewares/link_remover.js: -------------------------------------------------------------------------------- 1 | import isURL from 'validator/es/lib/isURL' 2 | // eslint-disable-next-line max-len 3 | const regURL = 4 | /(https:\/\/www\.|http:\/\/www\.|https:\/\/|http:\/\/)?[a-zA-Z]{2,}(\.[a-zA-Z]{2,})(\.[a-zA-Z]{2,})?\/[a-zA-Z0-9]{2,}|((https:\/\/www\.|http:\/\/www\.|https:\/\/|http:\/\/)?[a-zA-Z]{2,}(\.[a-zA-Z]{2,})(\.[a-zA-Z]{2,})?)|(https:\/\/www\.|http:\/\/www\.|https:\/\/|http:\/\/)?[a-zA-Z0-9]{2,}\.[a-zA-Z0-9]{2,}\.[a-zA-Z0-9]{2,}(\.[a-zA-Z0-9]{2,})?/g 5 | 6 | export default function linkRemover(message) { 7 | Boolean(message.msg) && 8 | (message.msg = message.msg 9 | .split(' ') 10 | .map((word) => { 11 | let url = isURL(word) 12 | regURL.test(word) && (url = true) 13 | return url ? `(${message.displayName} envió un link)` : word 14 | }) 15 | .join(' ')) 16 | return message 17 | } 18 | -------------------------------------------------------------------------------- /src/middlewares/long_words_remover.js: -------------------------------------------------------------------------------- 1 | const mostLongWordInSpanish = 'electroencefalografista' 2 | 3 | export default function longWordsRemover(message) { 4 | Boolean(message.msg) && 5 | (message.msg = message.msg 6 | .split(' ') 7 | .map((word) => { 8 | const longerWord = mostLongWordInSpanish.length < word.length 9 | return longerWord 10 | ? `Muvaffakiyetsezlestiricilestiriveremeyebileceklerimizdenmissinizcesine` 11 | : word 12 | }) 13 | .join(' ')) 14 | return message 15 | } 16 | -------------------------------------------------------------------------------- /src/middlewares/message_cleaner.js: -------------------------------------------------------------------------------- 1 | export default function messageCleaner(message) { 2 | message.msg = message.msg.replace('\r\n', '') 3 | return message 4 | } 5 | -------------------------------------------------------------------------------- /src/middlewares/pato_bot_middleware.js: -------------------------------------------------------------------------------- 1 | const patos = [ 2 | './assets/niceDuck.jpg', 3 | './assets/pato1.jpg', 4 | './assets/pato2.jpg', 5 | './assets/pato3.jpg', 6 | './assets/pato4.jpg', 7 | './assets/pato5.jpg', 8 | './assets/quack.gif' 9 | ] 10 | 11 | export default function patoBotMiddleware(message) { 12 | if (/(\*[\s]*q[\s]*u[\s]*a[\s]*c[\s]*k[\s]*\*)/gi.test(message.msg)) { 13 | // eslint-disable-next-line max-len 14 | message.msg = message.msg.replaceAll( 15 | /(\*[\s]*q[\s]*u[\s]*a[\s]*c[\s]*k[\s]*\*)/gi, 16 | '🦆' 17 | ) 18 | message.quack = patos[Math.ceil(Math.random() * 7) - 1] 19 | } 20 | return message 21 | } 22 | -------------------------------------------------------------------------------- /src/middlewares/place_emojis.js: -------------------------------------------------------------------------------- 1 | import renderEmoji from '../lib/render_emoji' 2 | 3 | export default function placeEmojis(message) { 4 | if (typeof message.emotes === 'object') { 5 | Object.keys(message.emotes).forEach((emojiPattern) => { 6 | message.msg = message.msg.replaceAll( 7 | emojiPattern, 8 | renderEmoji(message.emotes[emojiPattern]) 9 | ) 10 | }) 11 | } 12 | return message 13 | } 14 | -------------------------------------------------------------------------------- /src/middlewares/place_hearts.js: -------------------------------------------------------------------------------- 1 | const afordiLove = { '<3': 'emotesv2_2440c347e7344f0b9248beb83aa4ac87' } 2 | 3 | export default function placeHearts(message) { 4 | if (message.msg?.includes('<3')) { 5 | if (typeof message.emotes === 'object') { 6 | message.emotes = { ...message.emotes, ...afordiLove } 7 | } else message.emotes = afordiLove 8 | } 9 | if (message.msg?.includes(':3')) { 10 | message.msg = message.msg.replaceAll(':3', '😺') 11 | } 12 | return message 13 | } 14 | -------------------------------------------------------------------------------- /src/middlewares/place_html.js: -------------------------------------------------------------------------------- 1 | const notAllowedWords = [ 2 | 'script', 3 | 'src', 4 | 'iframe', 5 | 'fixed', 6 | 'absolute', 7 | '!important', 8 | 'url(', 9 | '