├── .github └── FUNDING.yml ├── .gitignore ├── LICENSE.md ├── README.md ├── examples └── boxicons.yml ├── manifest.json ├── package.json ├── rollup.config.js ├── screenshots └── 01.png ├── src ├── createIconSetting.ts ├── iconManager.ts ├── icons.ts ├── main.ts ├── svg.ts └── types.d.ts ├── styles.css ├── tsconfig.json ├── versions.json └── yarn.lock /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: mgmeyers 2 | custom: https://www.buymeacoffee.com/mgme 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Intellij 2 | *.iml 3 | .idea 4 | 5 | # npm 6 | node_modules 7 | package-lock.json 8 | 9 | # build 10 | main.js 11 | *.js.map 12 | .env 13 | .DS_Store 14 | .hotreload -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 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 General Public License is a free, copyleft license for 11 | software and other kinds of works. 12 | 13 | The licenses for most software and other practical works are designed 14 | to take away your freedom to share and change the works. By contrast, 15 | the GNU General Public License is intended to guarantee your freedom to 16 | share and change all versions of a program--to make sure it remains free 17 | software for all its users. We, the Free Software Foundation, use the 18 | GNU General Public License for most of our software; it applies also to 19 | any other work released this way by its authors. You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | them if you wish), that you receive source code or can get it if you 26 | want it, that you can change the software or use pieces of it in new 27 | free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you 30 | these rights or asking you to surrender the rights. Therefore, you have 31 | certain responsibilities if you distribute copies of the software, or if 32 | you modify it: responsibilities to respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must pass on to the recipients the same 36 | freedoms that you received. You must make sure that they, too, receive 37 | or can get the source code. And you must show them these terms so they 38 | know their rights. 39 | 40 | Developers that use the GNU GPL protect your rights with two steps: 41 | (1) assert copyright on the software, and (2) offer you this License 42 | giving you legal permission to copy, distribute and/or modify it. 43 | 44 | For the developers' and authors' protection, the GPL clearly explains 45 | that there is no warranty for this free software. For both users' and 46 | authors' sake, the GPL requires that modified versions be marked as 47 | changed, so that their problems will not be attributed erroneously to 48 | authors of previous versions. 49 | 50 | Some devices are designed to deny users access to install or run 51 | modified versions of the software inside them, although the manufacturer 52 | can do so. This is fundamentally incompatible with the aim of 53 | protecting users' freedom to change the software. The systematic 54 | pattern of such abuse occurs in the area of products for individuals to 55 | use, which is precisely where it is most unacceptable. Therefore, we 56 | have designed this version of the GPL to prohibit the practice for those 57 | products. If such problems arise substantially in other domains, we 58 | stand ready to extend this provision to those domains in future versions 59 | of the GPL, as needed to protect the freedom of users. 60 | 61 | Finally, every program is threatened constantly by software patents. 62 | States should not allow patents to restrict development and use of 63 | software on general-purpose computers, but in those that do, we wish to 64 | avoid the special danger that patents applied to a free program could 65 | make it effectively proprietary. To prevent this, the GPL assures that 66 | patents cannot be used to render the program non-free. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | TERMS AND CONDITIONS 72 | 73 | 0. Definitions. 74 | 75 | "This License" refers to version 3 of the GNU General Public License. 76 | 77 | "Copyright" also means copyright-like laws that apply to other kinds of 78 | works, such as semiconductor masks. 79 | 80 | "The Program" refers to any copyrightable work licensed under this 81 | License. Each licensee is addressed as "you". "Licensees" and 82 | "recipients" may be individuals or organizations. 83 | 84 | To "modify" a work means to copy from or adapt all or part of the work 85 | in a fashion requiring copyright permission, other than the making of an 86 | exact copy. The resulting work is called a "modified version" of the 87 | earlier work or a work "based on" the earlier work. 88 | 89 | A "covered work" means either the unmodified Program or a work based 90 | on the Program. 91 | 92 | To "propagate" a work means to do anything with it that, without 93 | permission, would make you directly or secondarily liable for 94 | infringement under applicable copyright law, except executing it on a 95 | computer or modifying a private copy. Propagation includes copying, 96 | distribution (with or without modification), making available to the 97 | public, and in some countries other activities as well. 98 | 99 | To "convey" a work means any kind of propagation that enables other 100 | parties to make or receive copies. Mere interaction with a user through 101 | a computer network, with no transfer of a copy, is not conveying. 102 | 103 | An interactive user interface displays "Appropriate Legal Notices" 104 | to the extent that it includes a convenient and prominently visible 105 | feature that (1) displays an appropriate copyright notice, and (2) 106 | tells the user that there is no warranty for the work (except to the 107 | extent that warranties are provided), that licensees may convey the 108 | work under this License, and how to view a copy of this License. If 109 | the interface presents a list of user commands or options, such as a 110 | menu, a prominent item in the list meets this criterion. 111 | 112 | 1. Source Code. 113 | 114 | The "source code" for a work means the preferred form of the work 115 | for making modifications to it. "Object code" means any non-source 116 | form of a work. 117 | 118 | A "Standard Interface" means an interface that either is an official 119 | standard defined by a recognized standards body, or, in the case of 120 | interfaces specified for a particular programming language, one that 121 | is widely used among developers working in that language. 122 | 123 | The "System Libraries" of an executable work include anything, other 124 | than the work as a whole, that (a) is included in the normal form of 125 | packaging a Major Component, but which is not part of that Major 126 | Component, and (b) serves only to enable use of the work with that 127 | Major Component, or to implement a Standard Interface for which an 128 | implementation is available to the public in source code form. A 129 | "Major Component", in this context, means a major essential component 130 | (kernel, window system, and so on) of the specific operating system 131 | (if any) on which the executable work runs, or a compiler used to 132 | produce the work, or an object code interpreter used to run it. 133 | 134 | The "Corresponding Source" for a work in object code form means all 135 | the source code needed to generate, install, and (for an executable 136 | work) run the object code and to modify the work, including scripts to 137 | control those activities. However, it does not include the work's 138 | System Libraries, or general-purpose tools or generally available free 139 | programs which are used unmodified in performing those activities but 140 | which are not part of the work. For example, Corresponding Source 141 | includes interface definition files associated with source files for 142 | the work, and the source code for shared libraries and dynamically 143 | linked subprograms that the work is specifically designed to require, 144 | such as by intimate data communication or control flow between those 145 | subprograms and other parts of the work. 146 | 147 | The Corresponding Source need not include anything that users 148 | can regenerate automatically from other parts of the Corresponding 149 | Source. 150 | 151 | The Corresponding Source for a work in source code form is that 152 | same work. 153 | 154 | 2. Basic Permissions. 155 | 156 | All rights granted under this License are granted for the term of 157 | copyright on the Program, and are irrevocable provided the stated 158 | conditions are met. This License explicitly affirms your unlimited 159 | permission to run the unmodified Program. The output from running a 160 | covered work is covered by this License only if the output, given its 161 | content, constitutes a covered work. This License acknowledges your 162 | rights of fair use or other equivalent, as provided by copyright law. 163 | 164 | You may make, run and propagate covered works that you do not 165 | convey, without conditions so long as your license otherwise remains 166 | in force. You may convey covered works to others for the sole purpose 167 | of having them make modifications exclusively for you, or provide you 168 | with facilities for running those works, provided that you comply with 169 | the terms of this License in conveying all material for which you do 170 | not control copyright. Those thus making or running the covered works 171 | for you must do so exclusively on your behalf, under your direction 172 | and control, on terms that prohibit them from making any copies of 173 | your copyrighted material outside their relationship with you. 174 | 175 | Conveying under any other circumstances is permitted solely under 176 | the conditions stated below. Sublicensing is not allowed; section 10 177 | makes it unnecessary. 178 | 179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 180 | 181 | No covered work shall be deemed part of an effective technological 182 | measure under any applicable law fulfilling obligations under article 183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 184 | similar laws prohibiting or restricting circumvention of such 185 | measures. 186 | 187 | When you convey a covered work, you waive any legal power to forbid 188 | circumvention of technological measures to the extent such circumvention 189 | is effected by exercising rights under this License with respect to 190 | the covered work, and you disclaim any intention to limit operation or 191 | modification of the work as a means of enforcing, against the work's 192 | users, your or third parties' legal rights to forbid circumvention of 193 | technological measures. 194 | 195 | 4. Conveying Verbatim Copies. 196 | 197 | You may convey verbatim copies of the Program's source code as you 198 | receive it, in any medium, provided that you conspicuously and 199 | appropriately publish on each copy an appropriate copyright notice; 200 | keep intact all notices stating that this License and any 201 | non-permissive terms added in accord with section 7 apply to the code; 202 | keep intact all notices of the absence of any warranty; and give all 203 | recipients a copy of this License along with the Program. 204 | 205 | You may charge any price or no price for each copy that you convey, 206 | and you may offer support or warranty protection for a fee. 207 | 208 | 5. Conveying Modified Source Versions. 209 | 210 | You may convey a work based on the Program, or the modifications to 211 | produce it from the Program, in the form of source code under the 212 | terms of section 4, provided that you also meet all of these conditions: 213 | 214 | a) The work must carry prominent notices stating that you modified 215 | it, and giving a relevant date. 216 | 217 | b) The work must carry prominent notices stating that it is 218 | released under this License and any conditions added under section 219 | 7. This requirement modifies the requirement in section 4 to 220 | "keep intact all notices". 221 | 222 | c) You must license the entire work, as a whole, under this 223 | License to anyone who comes into possession of a copy. This 224 | License will therefore apply, along with any applicable section 7 225 | additional terms, to the whole of the work, and all its parts, 226 | regardless of how they are packaged. This License gives no 227 | permission to license the work in any other way, but it does not 228 | invalidate such permission if you have separately received it. 229 | 230 | d) If the work has interactive user interfaces, each must display 231 | Appropriate Legal Notices; however, if the Program has interactive 232 | interfaces that do not display Appropriate Legal Notices, your 233 | work need not make them do so. 234 | 235 | A compilation of a covered work with other separate and independent 236 | works, which are not by their nature extensions of the covered work, 237 | and which are not combined with it such as to form a larger program, 238 | in or on a volume of a storage or distribution medium, is called an 239 | "aggregate" if the compilation and its resulting copyright are not 240 | used to limit the access or legal rights of the compilation's users 241 | beyond what the individual works permit. Inclusion of a covered work 242 | in an aggregate does not cause this License to apply to the other 243 | parts of the aggregate. 244 | 245 | 6. Conveying Non-Source Forms. 246 | 247 | You may convey a covered work in object code form under the terms 248 | of sections 4 and 5, provided that you also convey the 249 | machine-readable Corresponding Source under the terms of this License, 250 | in one of these ways: 251 | 252 | a) Convey the object code in, or embodied in, a physical product 253 | (including a physical distribution medium), accompanied by the 254 | Corresponding Source fixed on a durable physical medium 255 | customarily used for software interchange. 256 | 257 | b) Convey the object code in, or embodied in, a physical product 258 | (including a physical distribution medium), accompanied by a 259 | written offer, valid for at least three years and valid for as 260 | long as you offer spare parts or customer support for that product 261 | model, to give anyone who possesses the object code either (1) a 262 | copy of the Corresponding Source for all the software in the 263 | product that is covered by this License, on a durable physical 264 | medium customarily used for software interchange, for a price no 265 | more than your reasonable cost of physically performing this 266 | conveying of source, or (2) access to copy the 267 | Corresponding Source from a network server at no charge. 268 | 269 | c) Convey individual copies of the object code with a copy of the 270 | written offer to provide the Corresponding Source. This 271 | alternative is allowed only occasionally and noncommercially, and 272 | only if you received the object code with such an offer, in accord 273 | with subsection 6b. 274 | 275 | d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | 288 | e) Convey the object code using peer-to-peer transmission, provided 289 | you inform other peers where the object code and Corresponding 290 | Source of the work are being offered to the general public at no 291 | charge under subsection 6d. 292 | 293 | A separable portion of the object code, whose source code is excluded 294 | from the Corresponding Source as a System Library, need not be 295 | included in conveying the object code work. 296 | 297 | A "User Product" is either (1) a "consumer product", which means any 298 | tangible personal property which is normally used for personal, family, 299 | or household purposes, or (2) anything designed or sold for incorporation 300 | into a dwelling. In determining whether a product is a consumer product, 301 | doubtful cases shall be resolved in favor of coverage. For a particular 302 | product received by a particular user, "normally used" refers to a 303 | typical or common use of that class of product, regardless of the status 304 | of the particular user or of the way in which the particular user 305 | actually uses, or expects or is expected to use, the product. A product 306 | is a consumer product regardless of whether the product has substantial 307 | commercial, industrial or non-consumer uses, unless such uses represent 308 | the only significant mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to install 312 | and execute modified versions of a covered work in that User Product from 313 | a modified version of its Corresponding Source. The information must 314 | suffice to ensure that the continued functioning of the modified object 315 | code is in no case prevented or interfered with solely because 316 | modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or updates 331 | for a work that has been modified or installed by the recipient, or for 332 | the User Product in which it has been modified or installed. Access to a 333 | network may be denied when the modification itself materially and 334 | adversely affects the operation of the network or violates the rules and 335 | protocols for communication across the network. 336 | 337 | Corresponding Source conveyed, and Installation Information provided, 338 | in accord with this section must be in a format that is publicly 339 | documented (and with an implementation available to the public in 340 | source code form), and must require no special password or key for 341 | unpacking, reading or copying. 342 | 343 | 7. Additional Terms. 344 | 345 | "Additional permissions" are terms that supplement the terms of this 346 | License by making exceptions from one or more of its conditions. 347 | Additional permissions that are applicable to the entire Program shall 348 | be treated as though they were included in this License, to the extent 349 | that they are valid under applicable law. If additional permissions 350 | apply only to part of the Program, that part may be used separately 351 | under those permissions, but the entire Program remains governed by 352 | this License without regard to the additional permissions. 353 | 354 | When you convey a copy of a covered work, you may at your option 355 | remove any additional permissions from that copy, or from any part of 356 | it. (Additional permissions may be written to require their own 357 | removal in certain cases when you modify the work.) You may place 358 | additional permissions on material, added by you to a covered work, 359 | for which you have or can give appropriate copyright permission. 360 | 361 | Notwithstanding any other provision of this License, for material you 362 | add to a covered work, you may (if authorized by the copyright holders of 363 | that material) supplement the terms of this License with terms: 364 | 365 | a) Disclaiming warranty or limiting liability differently from the 366 | terms of sections 15 and 16 of this License; or 367 | 368 | b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | 372 | c) Prohibiting misrepresentation of the origin of that material, or 373 | requiring that modified versions of such material be marked in 374 | reasonable ways as different from the original version; or 375 | 376 | d) Limiting the use for publicity purposes of names of licensors or 377 | authors of the material; or 378 | 379 | e) Declining to grant rights under trademark law for use of some 380 | trade names, trademarks, or service marks; or 381 | 382 | f) Requiring indemnification of licensors and authors of that 383 | material by anyone who conveys the material (or modified versions of 384 | it) with contractual assumptions of liability to the recipient, for 385 | any liability that these contractual assumptions directly impose on 386 | those licensors and authors. 387 | 388 | All other non-permissive additional terms are considered "further 389 | restrictions" within the meaning of section 10. If the Program as you 390 | received it, or any part of it, contains a notice stating that it is 391 | governed by this License along with a term that is a further 392 | restriction, you may remove that term. If a license document contains 393 | a further restriction but permits relicensing or conveying under this 394 | License, you may add to a covered work material governed by the terms 395 | of that license document, provided that the further restriction does 396 | not survive such relicensing or conveying. 397 | 398 | If you add terms to a covered work in accord with this section, you 399 | must place, in the relevant source files, a statement of the 400 | additional terms that apply to those files, or a notice indicating 401 | where to find the applicable terms. 402 | 403 | Additional terms, permissive or non-permissive, may be stated in the 404 | form of a separately written license, or stated as exceptions; 405 | the above requirements apply either way. 406 | 407 | 8. Termination. 408 | 409 | You may not propagate or modify a covered work except as expressly 410 | provided under this License. Any attempt otherwise to propagate or 411 | modify it is void, and will automatically terminate your rights under 412 | this License (including any patent licenses granted under the third 413 | paragraph of section 11). 414 | 415 | However, if you cease all violation of this License, then your 416 | license from a particular copyright holder is reinstated (a) 417 | provisionally, unless and until the copyright holder explicitly and 418 | finally terminates your license, and (b) permanently, if the copyright 419 | holder fails to notify you of the violation by some reasonable means 420 | prior to 60 days after the cessation. 421 | 422 | Moreover, your license from a particular copyright holder is 423 | reinstated permanently if the copyright holder notifies you of the 424 | violation by some reasonable means, this is the first time you have 425 | received notice of violation of this License (for any work) from that 426 | copyright holder, and you cure the violation prior to 30 days after 427 | your receipt of the notice. 428 | 429 | Termination of your rights under this section does not terminate the 430 | licenses of parties who have received copies or rights from you under 431 | this License. If your rights have been terminated and not permanently 432 | reinstated, you do not qualify to receive new licenses for the same 433 | material under section 10. 434 | 435 | 9. Acceptance Not Required for Having Copies. 436 | 437 | You are not required to accept this License in order to receive or 438 | run a copy of the Program. Ancillary propagation of a covered work 439 | occurring solely as a consequence of using peer-to-peer transmission 440 | to receive a copy likewise does not require acceptance. However, 441 | nothing other than this License grants you permission to propagate or 442 | modify any covered work. These actions infringe copyright if you do 443 | not accept this License. Therefore, by modifying or propagating a 444 | covered work, you indicate your acceptance of this License to do so. 445 | 446 | 10. Automatic Licensing of Downstream Recipients. 447 | 448 | Each time you convey a covered work, the recipient automatically 449 | receives a license from the original licensors, to run, modify and 450 | propagate that work, subject to this License. You are not responsible 451 | for enforcing compliance by third parties with this License. 452 | 453 | An "entity transaction" is a transaction transferring control of an 454 | organization, or substantially all assets of one, or subdividing an 455 | organization, or merging organizations. If propagation of a covered 456 | work results from an entity transaction, each party to that 457 | transaction who receives a copy of the work also receives whatever 458 | licenses to the work the party's predecessor in interest had or could 459 | give under the previous paragraph, plus a right to possession of the 460 | Corresponding Source of the work from the predecessor in interest, if 461 | the predecessor has it or can get it with reasonable efforts. 462 | 463 | You may not impose any further restrictions on the exercise of the 464 | rights granted or affirmed under this License. For example, you may 465 | not impose a license fee, royalty, or other charge for exercise of 466 | rights granted under this License, and you may not initiate litigation 467 | (including a cross-claim or counterclaim in a lawsuit) alleging that 468 | any patent claim is infringed by making, using, selling, offering for 469 | sale, or importing the Program or any portion of it. 470 | 471 | 11. Patents. 472 | 473 | A "contributor" is a copyright holder who authorizes use under this 474 | License of the Program or a work on which the Program is based. The 475 | work thus licensed is called the contributor's "contributor version". 476 | 477 | A contributor's "essential patent claims" are all patent claims 478 | owned or controlled by the contributor, whether already acquired or 479 | hereafter acquired, that would be infringed by some manner, permitted 480 | by this License, of making, using, or selling its contributor version, 481 | but do not include claims that would be infringed only as a 482 | consequence of further modification of the contributor version. For 483 | purposes of this definition, "control" includes the right to grant 484 | patent sublicenses in a manner consistent with the requirements of 485 | this License. 486 | 487 | Each contributor grants you a non-exclusive, worldwide, royalty-free 488 | patent license under the contributor's essential patent claims, to 489 | make, use, sell, offer for sale, import and otherwise run, modify and 490 | propagate the contents of its contributor version. 491 | 492 | In the following three paragraphs, a "patent license" is any express 493 | agreement or commitment, however denominated, not to enforce a patent 494 | (such as an express permission to practice a patent or covenant not to 495 | sue for patent infringement). To "grant" such a patent license to a 496 | party means to make such an agreement or commitment not to enforce a 497 | patent against the party. 498 | 499 | If you convey a covered work, knowingly relying on a patent license, 500 | and the Corresponding Source of the work is not available for anyone 501 | to copy, free of charge and under the terms of this License, through a 502 | publicly available network server or other readily accessible means, 503 | then you must either (1) cause the Corresponding Source to be so 504 | available, or (2) arrange to deprive yourself of the benefit of the 505 | patent license for this particular work, or (3) arrange, in a manner 506 | consistent with the requirements of this License, to extend the patent 507 | license to downstream recipients. "Knowingly relying" means you have 508 | actual knowledge that, but for the patent license, your conveying the 509 | covered work in a country, or your recipient's use of the covered work 510 | in a country, would infringe one or more identifiable patents in that 511 | country that you have reason to believe are valid. 512 | 513 | If, pursuant to or in connection with a single transaction or 514 | arrangement, you convey, or propagate by procuring conveyance of, a 515 | covered work, and grant a patent license to some of the parties 516 | receiving the covered work authorizing them to use, propagate, modify 517 | or convey a specific copy of the covered work, then the patent license 518 | you grant is automatically extended to all recipients of the covered 519 | work and works based on it. 520 | 521 | A patent license is "discriminatory" if it does not include within 522 | the scope of its coverage, prohibits the exercise of, or is 523 | conditioned on the non-exercise of one or more of the rights that are 524 | specifically granted under this License. You may not convey a covered 525 | work if you are a party to an arrangement with a third party that is 526 | in the business of distributing software, under which you make payment 527 | to the third party based on the extent of your activity of conveying 528 | the work, and under which the third party grants, to any of the 529 | parties who would receive the covered work from you, a discriminatory 530 | patent license (a) in connection with copies of the covered work 531 | conveyed by you (or copies made from those copies), or (b) primarily 532 | for and in connection with specific products or compilations that 533 | contain the covered work, unless you entered into that arrangement, 534 | or that patent license was granted, prior to 28 March 2007. 535 | 536 | Nothing in this License shall be construed as excluding or limiting 537 | any implied license or other defenses to infringement that may 538 | otherwise be available to you under applicable patent law. 539 | 540 | 12. No Surrender of Others' Freedom. 541 | 542 | If conditions are imposed on you (whether by court order, agreement or 543 | otherwise) that contradict the conditions of this License, they do not 544 | excuse you from the conditions of this License. If you cannot convey a 545 | covered work so as to satisfy simultaneously your obligations under this 546 | License and any other pertinent obligations, then as a consequence you may 547 | not convey it at all. For example, if you agree to terms that obligate you 548 | to collect a royalty for further conveying from those to whom you convey 549 | the Program, the only way you could satisfy both those terms and this 550 | License would be to refrain entirely from conveying the Program. 551 | 552 | 13. Use with the GNU Affero General Public License. 553 | 554 | Notwithstanding any other provision of this License, you have 555 | permission to link or combine any covered work with a work licensed 556 | under version 3 of the GNU Affero General Public License into a single 557 | combined work, and to convey the resulting work. The terms of this 558 | License will continue to apply to the part which is the covered work, 559 | but the special requirements of the GNU Affero General Public License, 560 | section 13, concerning interaction through a network will apply to the 561 | combination as such. 562 | 563 | 14. Revised Versions of this License. 564 | 565 | The Free Software Foundation may publish revised and/or new versions of 566 | the GNU General Public License from time to time. Such new versions will 567 | be similar in spirit to the present version, but may differ in detail to 568 | address new problems or concerns. 569 | 570 | Each version is given a distinguishing version number. If the 571 | Program specifies that a certain numbered version of the GNU General 572 | Public License "or any later version" applies to it, you have the 573 | option of following the terms and conditions either of that numbered 574 | version or of any later version published by the Free Software 575 | Foundation. If the Program does not specify a version number of the 576 | GNU General Public License, you may choose any version ever published 577 | by the Free Software Foundation. 578 | 579 | If the Program specifies that a proxy can decide which future 580 | versions of the GNU General Public License can be used, that proxy's 581 | public statement of acceptance of a version permanently authorizes you 582 | to choose that version for the Program. 583 | 584 | Later license versions may give you additional or different 585 | permissions. However, no additional obligations are imposed on any 586 | author or copyright holder as a result of your choosing to follow a 587 | later version. 588 | 589 | 15. Disclaimer of Warranty. 590 | 591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 599 | 600 | 16. Limitation of Liability. 601 | 602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 610 | SUCH DAMAGES. 611 | 612 | 17. Interpretation of Sections 15 and 16. 613 | 614 | If the disclaimer of warranty and limitation of liability provided 615 | above cannot be given local legal effect according to their terms, 616 | reviewing courts shall apply local law that most closely approximates 617 | an absolute waiver of all civil liability in connection with the 618 | Program, unless a warranty or assumption of liability accompanies a 619 | copy of the Program in return for a fee. 620 | 621 | END OF TERMS AND CONDITIONS 622 | 623 | How to Apply These Terms to Your New Programs 624 | 625 | If you develop a new program, and you want it to be of the greatest 626 | possible use to the public, the best way to achieve this is to make it 627 | free software which everyone can redistribute and change under these terms. 628 | 629 | To do so, attach the following notices to the program. It is safest 630 | to attach them to the start of each source file to most effectively 631 | state the exclusion of warranty; and each file should have at least 632 | the "copyright" line and a pointer to where the full notice is found. 633 | 634 | 635 | Copyright (C) 636 | 637 | This program is free software: you can redistribute it and/or modify 638 | it under the terms of the GNU General Public License as published by 639 | the Free Software Foundation, either version 3 of the License, or 640 | (at your option) any later version. 641 | 642 | This program is distributed in the hope that it will be useful, 643 | but WITHOUT ANY WARRANTY; without even the implied warranty of 644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 645 | GNU General Public License for more details. 646 | 647 | You should have received a copy of the GNU General Public License 648 | along with this program. If not, see . 649 | 650 | Also add information on how to contact you by electronic and paper mail. 651 | 652 | If the program does terminal interaction, make it output a short 653 | notice like this when it starts in an interactive mode: 654 | 655 | Copyright (C) 656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 657 | This is free software, and you are welcome to redistribute it 658 | under certain conditions; type `show c' for details. 659 | 660 | The hypothetical commands `show w' and `show c' should show the appropriate 661 | parts of the General Public License. Of course, your program's commands 662 | might be different; for a GUI interface, you would use an "about box". 663 | 664 | You should also get your employer (if you work as a programmer) or school, 665 | if any, to sign a "copyright disclaimer" for the program, if necessary. 666 | For more information on this, and how to apply and follow the GNU GPL, see 667 | . 668 | 669 | The GNU General Public License does not permit incorporating your program 670 | into proprietary programs. If your program is a subroutine library, you 671 | may consider it more useful to permit linking proprietary applications with 672 | the library. If this is what you want to do, use the GNU Lesser General 673 | Public License instead of this License. But first, please read 674 | . -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Obsidian Icon Swapper 2 | 3 | This plugin allows users to replace Obsidian's UI icons. Icon configurations can be exported and imported. **Icons must be supplied in SVG format.** 4 | 5 | Plugin screenshot 6 | 7 | Included in this repo is an example using [Boxicons](https://boxicons.com/). Download and import [examples/boxicons.yml](./examples/boxicons.yml) to test it out. -------------------------------------------------------------------------------- /examples/boxicons.yml: -------------------------------------------------------------------------------- 1 | blocks: 12 | audio-file: 26 | bracket-glyph: 30 | broken-link: 41 | bullet-list-glyph: 47 | bullet-list: 53 | calendar-with-checkmark: 60 | check-in-circle: 66 | check-small: 72 | checkbox-glyph: 75 | checkmark: 78 | clock: 84 | cloud: 92 | code-glyph: 95 | create-new: 102 | cross-in-box: 109 | cross: 113 | crossed-star: 124 | dice: 132 | document: 141 | documents: 149 | dot-network: 164 | double-down-arrow-glyph: 168 | double-up-arrow-glyph: 172 | down-arrow-with-tail: 175 | down-chevron-glyph: 178 | enter: 184 | exit-fullscreen: 190 | expand-vertically: 193 | filled-pin: 203 | folder: 209 | fullscreen: 215 | gear: 246 | hashtag: 253 | go-to-file: 263 | help: 274 | highlight-glyph: 281 | horizontal-split: 284 | image-file: 291 | image-glyph: 298 | indent-glyph: 303 | info: 309 | install: 313 | keyboard-glyph: 347 | left-arrow-with-tail: 350 | left-arrow: 352 | left-chevron-glyph: 355 | lines-of-text: 359 | link-glyph: 371 | link: 382 | magnifying-glass: 392 | microphone-filled: 399 | microphone: 408 | minus-with-circle: 414 | note-glyph: 423 | number-list-glyph: 453 | open-vault: 461 | pane-layout: 471 | paper-plane: 478 | paused: 484 | pdf-file: 501 | pencil: 507 | pin: 517 | plus-with-circle: 524 | popup-open: 529 | presentation: 535 | price-tag-glyph: 543 | quote-glyph: 570 | redo-glyph: 574 | reset: 601 | right-arrow-with-tail: 604 | right-arrow: 606 | right-chevron-glyph: 609 | right-triangle: 612 | run-command: 618 | search: 628 | sheets-in-box: 634 | stacked-levels: 640 | star-list: 646 | star: 659 | strikethrough-glyph: 667 | switch: 692 | sync-small: 717 | sync: 742 | tag-glyph: 749 | three-horizontal-bars: 752 | trash: 758 | undo-glyph: 762 | unindent-glyph: 766 | up-and-down-arrows: 770 | up-arrow-with-tail: 773 | up-chevron-glyph: 776 | vault: 784 | vertical-split: 787 | vertical-three-dots: 793 | wrench-screwdriver-glyph: 799 | clock-glyph: 805 | command-glyph: 811 | add-note-glyph: 818 | calendar-glyph: 827 | dice-glyph: 840 | duplicate-glyph: 848 | file-explorer-glyph: 856 | graph-glyph: 876 | import-glyph: 882 | languages: 891 | links-coming-in: 960 | links-going-out: 1028 | merge-files-glyph: 1035 | merge-files: 1042 | open-elsewhere-glyph: 1048 | paper-plane-glyph: 1056 | paste-text: 1065 | paste: 1074 | percent-sign-glyph: 1080 | play-audio-glyph: 1086 | presentation-glyph: 1093 | question-mark-glyph: 1104 | restore-file-glyph: 1131 | scissors-glyph: 1144 | scissors: 1157 | search-glyph: 1167 | select-all-text: 1180 | split: 1188 | star-glyph: 1197 | stop-audio-glyph: 1202 | two-blank-pages: 1210 | tomorrow-glyph: 1218 | yesterday-glyph: 1225 | workspace-glyph: 1238 | box-glyph: 1246 | -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "obsidian-icon-swapper", 3 | "name": "Icon Swapper", 4 | "version": "0.0.6", 5 | "minAppVersion": "0.11.5", 6 | "description": "Allows swapping out Obsidian's default icons.", 7 | "author": "mgmeyers", 8 | "authorUrl": "https://github.com/mgmeyers/obsidian-icon-swapper", 9 | "isDesktopOnly": false 10 | } 11 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "obsidian-sample-plugin", 3 | "version": "0.9.7", 4 | "description": "This is a sample plugin for Obsidian (https://obsidian.md)", 5 | "main": "main.js", 6 | "scripts": { 7 | "dev": "rollup --config rollup.config.js -w", 8 | "build": "rollup --config rollup.config.js --environment BUILD:production" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "MIT", 13 | "devDependencies": { 14 | "@rollup/plugin-commonjs": "^15.1.0", 15 | "@rollup/plugin-node-resolve": "^9.0.0", 16 | "@rollup/plugin-typescript": "^6.0.0", 17 | "@types/node": "^14.14.2", 18 | "obsidian": "https://github.com/obsidianmd/obsidian-api/tarball/master", 19 | "rollup": "^2.32.1", 20 | "tslib": "^2.0.3", 21 | "typescript": "^4.0.3" 22 | }, 23 | "dependencies": { 24 | "dotenv": "^8.2.0", 25 | "element-to-path": "^1.2.0", 26 | "rollup-plugin-copy": "^3.4.0", 27 | "svg-path-tools": "^1.0.0", 28 | "svgson": "^5.2.1", 29 | "yaml": "^1.10.2" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import typescript from "@rollup/plugin-typescript"; 2 | import { nodeResolve } from "@rollup/plugin-node-resolve"; 3 | import commonjs from "@rollup/plugin-commonjs"; 4 | 5 | const isProd = process.env.BUILD === "production"; 6 | 7 | const banner = `/* 8 | THIS IS A GENERATED/BUNDLED FILE BY ROLLUP 9 | if you want to view the source visit the plugins github repository 10 | */ 11 | `; 12 | 13 | const output = [ 14 | { 15 | input: "./src/main.ts", 16 | output: { 17 | dir: ".", 18 | sourcemap: isProd ? false : "inline", 19 | sourcemapExcludeSources: isProd, 20 | format: "cjs", 21 | exports: "default", 22 | banner, 23 | }, 24 | external: ["obsidian"], 25 | plugins: [typescript(), nodeResolve({ browser: true }), commonjs()], 26 | }, 27 | ]; 28 | 29 | export default output; 30 | -------------------------------------------------------------------------------- /screenshots/01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgmeyers/obsidian-icon-swapper/970e9ac122119bcb548e08bfdb83093441f9cc06/screenshots/01.png -------------------------------------------------------------------------------- /src/createIconSetting.ts: -------------------------------------------------------------------------------- 1 | import { setIcon, Setting, TextAreaComponent } from "obsidian"; 2 | import { IconManager, validSvgRegEx } from "./iconManager"; 3 | 4 | interface Options { 5 | containerEl: HTMLElement; 6 | name: string; 7 | iconManager: IconManager; 8 | } 9 | 10 | export function createIconSetting({ containerEl, name, iconManager }: Options) { 11 | let textComponent: TextAreaComponent; 12 | 13 | new Setting(containerEl) 14 | 15 | // SVG input textarea 16 | .addTextArea((textarea) => { 17 | textComponent = textarea; 18 | 19 | if (iconManager.icons[name]) { 20 | textarea.setValue(`${iconManager.icons[name]}`); 21 | } 22 | 23 | textarea.onChange(async (v) => { 24 | const svg = v.trim(); 25 | 26 | if (svg && validSvgRegEx.test(svg)) { 27 | await iconManager.setIcon({ name, svg }); 28 | } else { 29 | await iconManager.revertIcon({ name }); 30 | } 31 | }); 32 | }) 33 | 34 | // Reset icon button 35 | .addExtraButton((b) => { 36 | b.setIcon("reset") 37 | .setTooltip("Restore default") 38 | .onClick(async () => { 39 | textComponent.setValue(""); 40 | await iconManager.revertIcon({ name }); 41 | }); 42 | }) 43 | 44 | // Icon display 45 | .then((setting) => { 46 | setting.nameEl.createDiv( 47 | { cls: "icon-swapper-container" }, 48 | (container) => { 49 | container.createDiv({ cls: "icon-swapper-icon" }, (icon) => { 50 | // Note: This, confusingly, is obsidian's `setIcon`, not `iconManager.setIcon`. 51 | // It's used to render an icon to the DOM 52 | setIcon(icon, name, 20); 53 | }); 54 | 55 | container.createDiv({ cls: "icon-swapper-container" }, (icoName) => { 56 | icoName.setText(name); 57 | }); 58 | } 59 | ); 60 | }); 61 | } 62 | -------------------------------------------------------------------------------- /src/iconManager.ts: -------------------------------------------------------------------------------- 1 | import { INode, parse, stringify } from "svgson"; 2 | import { 3 | getDefaultIconSVG, 4 | getMaxViewBox, 5 | replaceIconSVG, 6 | scalePath, 7 | } from "./svg"; 8 | 9 | export const validSvgRegEx = /^]+?>[\w\W]+?<\/svg>?/i; 10 | 11 | // Convert a user-supplied SVG to the correct format and size for addIcon 12 | export async function svgToIcon(value: string) { 13 | try { 14 | const parsed = await parse(value); 15 | const maxViewBox = getMaxViewBox(parsed); 16 | const children: string[] = []; 17 | 18 | if (maxViewBox) { 19 | parsed.children.forEach((path: INode) => { 20 | children.push( 21 | stringify( 22 | // Scale the SVG to 100x100 only if the viewbox isn't already at 100 23 | maxViewBox === 100 24 | ? path 25 | : scalePath(path, { scale: 100 / maxViewBox, round: 3 }) 26 | ) 27 | ); 28 | }); 29 | } 30 | 31 | return children.join(""); 32 | } catch (e) { 33 | console.error("Error parsing SVG:", e); 34 | } 35 | } 36 | 37 | export interface Icons { 38 | [k: string]: string; 39 | } 40 | 41 | type SaveFn = (icons: Icons) => Promise; 42 | type LoadFn = () => Promise; 43 | 44 | export class IconManager { 45 | defaults: Icons; 46 | icons: Icons; 47 | save: SaveFn; 48 | load: LoadFn; 49 | 50 | constructor(save: SaveFn, load: LoadFn) { 51 | this.defaults = {}; 52 | this.icons = {}; 53 | this.save = save; 54 | this.load = load; 55 | } 56 | 57 | async loadIcons() { 58 | const icons = await this.load(); 59 | 60 | for (const icon in icons) { 61 | await this.setIcon({ 62 | name: icon, 63 | svg: icons[icon], 64 | shouldSave: false, 65 | isTrustedSource: true, 66 | }); 67 | } 68 | } 69 | 70 | async setIcon(opts: { 71 | name: string; 72 | svg: string; 73 | shouldSave?: boolean; 74 | isTrustedSource?: boolean; 75 | }) { 76 | const { name, svg, shouldSave = true, isTrustedSource = false } = opts; 77 | 78 | // Store a copy of the default icon if we haven't already 79 | if (!this.defaults[name]) { 80 | this.defaults[name] = getDefaultIconSVG(name); 81 | } 82 | 83 | const iconSVG = isTrustedSource ? svg : await svgToIcon(svg); 84 | 85 | replaceIconSVG(name, iconSVG); 86 | this.icons[name] = iconSVG; 87 | 88 | if (shouldSave) { 89 | await this.save(this.icons); 90 | } 91 | } 92 | 93 | async setAll(icons: Icons) { 94 | for (const icon in icons) { 95 | const svg = (icons[icon] || "").trim(); 96 | 97 | // Try to validate the SVG string as best we can 98 | if (!svg) continue; 99 | if (!validSvgRegEx.test(svg)) continue; 100 | 101 | await this.setIcon({ name: icon, svg, shouldSave: false }); 102 | } 103 | 104 | await this.save(this.icons); 105 | } 106 | 107 | async revertIcon(opts: { name: string; shouldSave?: boolean }) { 108 | const { name, shouldSave = true } = opts; 109 | 110 | // Replace the supplied icon with the default 111 | if (this.icons[name]) { 112 | replaceIconSVG(name, this.defaults[name]); 113 | delete this.icons[name]; 114 | } 115 | 116 | if (shouldSave) { 117 | await this.save(this.icons); 118 | } 119 | } 120 | 121 | async revertAll(opts: { shouldSave?: boolean } = {}) { 122 | const { shouldSave = true } = opts; 123 | 124 | for (const icon in this.icons) { 125 | this.revertIcon({ name: icon, shouldSave: false }); 126 | } 127 | 128 | if (shouldSave) { 129 | await this.save(this.icons); 130 | } 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /src/icons.ts: -------------------------------------------------------------------------------- 1 | // This list was taken from obsidian's app.js 2 | export const icons = [ 3 | "add-note-glyph", 4 | "any-key", 5 | "audio-file", 6 | "blocks", 7 | "bold-glyph", 8 | "box-glyph", 9 | "bracket-glyph", 10 | "broken-link", 11 | "bullet-list-glyph", 12 | "bullet-list", 13 | "calendar-glyph", 14 | "calendar-with-checkmark", 15 | "check-in-circle", 16 | "check-small", 17 | "checkbox-glyph", 18 | "checkmark", 19 | "clock-glyph", 20 | "clock", 21 | "cloud", 22 | "code-glyph", 23 | "command-glyph", 24 | "compress-glyph", 25 | "create-new", 26 | "cross-in-box", 27 | "cross", 28 | "crossed-star", 29 | "dice-glyph", 30 | "dice", 31 | "document", 32 | "documents", 33 | "dot-network", 34 | "double-down-arrow-glyph", 35 | "double-up-arrow-glyph", 36 | "down-arrow-with-tail", 37 | "down-chevron-glyph", 38 | "down-curly-arrow-glyph", 39 | "duplicate-glyph", 40 | "enlarge-glyph", 41 | "enter", 42 | "exit-fullscreen", 43 | "expand-vertically", 44 | "file-explorer-glyph", 45 | "filled-pin", 46 | "folder", 47 | "forward-arrow", 48 | "fullscreen", 49 | "gear", 50 | "github-glyph", 51 | "go-to-file", 52 | "graph-glyph", 53 | "hashtag", 54 | "heading-glyph", 55 | "help", 56 | "highlight-glyph", 57 | "horizontal-split", 58 | "image-file", 59 | "image-glyph", 60 | "import-glyph", 61 | "indent-glyph", 62 | "info", 63 | "install", 64 | "italic-glyph", 65 | "keyboard-glyph", 66 | "languages", 67 | "left-arrow-with-tail", 68 | "left-arrow", 69 | "left-chevron-glyph", 70 | "lines-of-text", 71 | "link-glyph", 72 | "link", 73 | "links-coming-in", 74 | "links-going-out", 75 | "logo-crystal", 76 | "magnifying-glass", 77 | "merge-files-glyph", 78 | "merge-files", 79 | "microphone-filled", 80 | "microphone", 81 | "minus-with-circle", 82 | "navigate-glyph", 83 | "note-glyph", 84 | "number-list-glyph", 85 | "open-elsewhere-glyph", 86 | "open-vault", 87 | "pane-layout", 88 | "paper-plane-glyph", 89 | "paper-plane", 90 | "paste-text", 91 | "paste", 92 | "paused", 93 | "pdf-file", 94 | "pencil", 95 | "percent-sign-glyph", 96 | "pin", 97 | "play-audio-glyph", 98 | "plus-minus-glyph", 99 | "plus-with-circle", 100 | "popup-open", 101 | "presentation-glyph", 102 | "presentation", 103 | "price-tag-glyph", 104 | "question-mark-glyph", 105 | "quote-glyph", 106 | "reading-glasses", 107 | "redo-glyph", 108 | "reset", 109 | "restore-file-glyph", 110 | "right-arrow-with-tail", 111 | "right-arrow", 112 | "right-chevron-glyph", 113 | "right-triangle", 114 | "run-command", 115 | "scissors-glyph", 116 | "scissors", 117 | "search-glyph", 118 | "search", 119 | "select-all-text", 120 | "sheets-in-box", 121 | "split", 122 | "stacked-levels", 123 | "star-glyph", 124 | "star-list", 125 | "star", 126 | "stop-audio-glyph", 127 | "strikethrough-glyph", 128 | "switch", 129 | "sync-small", 130 | "sync", 131 | "tag-glyph", 132 | "three-horizontal-bars", 133 | "tomorrow-glyph", 134 | "trash", 135 | "two-blank-pages", 136 | "undo-glyph", 137 | "unindent-glyph", 138 | "up-and-down-arrows", 139 | "up-arrow-with-tail", 140 | "up-chevron-glyph", 141 | "up-curly-arrow-glyph", 142 | "uppercase-lowercase-a", 143 | "vault", 144 | "vertical-split", 145 | "vertical-three-dots", 146 | "wand-glyph", 147 | "wand", 148 | "workspace-glyph", 149 | "wrench-screwdriver-glyph", 150 | "yesterday-glyph", 151 | ]; 152 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import { 2 | App, 3 | ButtonComponent, 4 | Modal, 5 | Plugin, 6 | PluginSettingTab, 7 | Setting, 8 | TextAreaComponent, 9 | } from "obsidian"; 10 | import { parse, stringify } from "yaml"; 11 | 12 | import { icons } from "./icons"; 13 | import { createIconSetting } from "./createIconSetting"; 14 | import { IconManager, Icons } from "./iconManager"; 15 | 16 | export default class IconSwapperPlugin extends Plugin { 17 | settingsTab: IconSwapperSettingsTab; 18 | iconManager: IconManager; 19 | 20 | async onload() { 21 | // Set up the settings tab 22 | this.settingsTab = new IconSwapperSettingsTab(this.app, this); 23 | this.addSettingTab(this.settingsTab); 24 | 25 | // Set up the icon manager 26 | const saveIcons = async (icons: Icons) => await this.saveData(icons); 27 | const loadIcons = async () => Object.assign({}, await this.loadData()); 28 | 29 | this.iconManager = new IconManager(saveIcons, loadIcons); 30 | 31 | // Load any stored icons 32 | await this.iconManager.loadIcons(); 33 | 34 | document.body.addClass("icon-swapper-enabled"); 35 | } 36 | 37 | onunload() { 38 | // Revert all icons back to default, but don't save anything 39 | this.iconManager.revertAll({ shouldSave: false }); 40 | document.body.removeClass("icon-swapper-enabled"); 41 | } 42 | } 43 | 44 | class ExportModal extends Modal { 45 | plugin: IconSwapperPlugin; 46 | 47 | constructor(app: App, plugin: IconSwapperPlugin) { 48 | super(app); 49 | this.plugin = plugin; 50 | } 51 | 52 | onOpen() { 53 | let { contentEl, modalEl } = this; 54 | 55 | modalEl.addClass("modal-icon-swapper"); 56 | 57 | new Setting(contentEl) 58 | .setName("Export icon configuration") 59 | .then((setting) => { 60 | // We only store the interior of the SVG in settings, so for safety and consistency, 61 | // we wrap the exported SVG with an svg tag set to the correct viewbox 62 | const wrappedIcons = Object.keys(this.plugin.iconManager.icons).reduce<{ 63 | [k: string]: string; 64 | }>((icons, currentIcon) => { 65 | icons[ 66 | currentIcon 67 | ] = `${this.plugin.iconManager.icons[currentIcon]}`; 68 | return icons; 69 | }, {}); 70 | 71 | const output = stringify(wrappedIcons); 72 | 73 | // Build a copy to clipboard link 74 | setting.controlEl.createEl( 75 | "a", 76 | { 77 | cls: "icon-swapper-copy", 78 | text: "Copy to clipboard", 79 | href: "#", 80 | }, 81 | (copyButton) => { 82 | new TextAreaComponent(contentEl) 83 | .setValue(output) 84 | .then((textarea) => { 85 | textarea.inputEl.setAttr("disabled", true); 86 | 87 | copyButton.addEventListener("click", (e) => { 88 | e.preventDefault(); 89 | 90 | // Select the textarea contents and copy them to the clipboard 91 | textarea.inputEl.select(); 92 | document.execCommand("copy"); 93 | 94 | copyButton.addClass("success"); 95 | 96 | setTimeout(() => { 97 | // If the button is still in the dom, remove the success class 98 | if (copyButton.parentNode) { 99 | copyButton.removeClass("success"); 100 | } 101 | }, 2000); 102 | }); 103 | }); 104 | } 105 | ); 106 | 107 | // Build a download link 108 | setting.controlEl.createEl("a", { 109 | cls: "icon-swapper-download", 110 | text: "Download", 111 | attr: { 112 | download: "icons.yml", 113 | href: `data:text/yaml;charset=utf-8,${encodeURIComponent(output)}`, 114 | }, 115 | }); 116 | }); 117 | } 118 | 119 | onClose() { 120 | let { contentEl } = this; 121 | contentEl.empty(); 122 | } 123 | } 124 | 125 | class ImportModal extends Modal { 126 | plugin: IconSwapperPlugin; 127 | 128 | constructor(app: App, plugin: IconSwapperPlugin) { 129 | super(app); 130 | this.plugin = plugin; 131 | } 132 | 133 | onOpen() { 134 | let { contentEl, modalEl } = this; 135 | 136 | modalEl.addClass("modal-icon-swapper"); 137 | 138 | new Setting(contentEl) 139 | .setName("Import icon configuration") 140 | .setDesc("Warning: this will override any existing icon configuration"); 141 | 142 | new Setting(contentEl).then((setting) => { 143 | // Build an error message container 144 | const errorSpan = createSpan({ 145 | cls: "icon-swapper-import-error", 146 | text: "Error importing config", 147 | }); 148 | 149 | setting.nameEl.appendChild(errorSpan); 150 | 151 | // Attempt to parse the imported data and close if successful 152 | const importAndClose = async (str: string) => { 153 | if (str) { 154 | try { 155 | const importedSettings = parse(str); 156 | 157 | await this.plugin.iconManager.revertAll({ shouldSave: false }); 158 | await this.plugin.iconManager.setAll(importedSettings); 159 | 160 | this.plugin.settingsTab.display(); 161 | this.close(); 162 | } catch (e) { 163 | errorSpan.addClass("active"); 164 | errorSpan.setText(`Error importing icon settings: ${e}`); 165 | } 166 | } else { 167 | errorSpan.addClass("active"); 168 | errorSpan.setText(`Error importing icon settings: config is empty`); 169 | } 170 | }; 171 | 172 | // Build a file input 173 | setting.controlEl.createEl( 174 | "input", 175 | { 176 | cls: "icon-swapper-import-input", 177 | attr: { 178 | id: "icon-swapper-import-input", 179 | name: "icon-swapper-import-input", 180 | type: "file", 181 | accept: ".yml", 182 | }, 183 | }, 184 | (importInput) => { 185 | // Set up a FileReader so we can parse the file contents 186 | importInput.addEventListener("change", (e) => { 187 | const reader = new FileReader(); 188 | 189 | reader.onload = async (e: ProgressEvent) => { 190 | await importAndClose(e.target.result.toString().trim()); 191 | }; 192 | 193 | reader.readAsText((e.target as HTMLInputElement).files[0]); 194 | }); 195 | } 196 | ); 197 | 198 | // Build a label we will style as a link 199 | setting.controlEl.createEl("label", { 200 | cls: "icon-swapper-import-label", 201 | text: "Import from file", 202 | attr: { 203 | for: "icon-swapper-import-input", 204 | }, 205 | }); 206 | 207 | new TextAreaComponent(contentEl) 208 | .setPlaceholder("Paste config here...") 209 | .then((ta) => { 210 | new ButtonComponent(contentEl) 211 | .setButtonText("Save") 212 | .onClick(async () => { 213 | await importAndClose(ta.getValue().trim()); 214 | }); 215 | }); 216 | }); 217 | } 218 | 219 | onClose() { 220 | let { contentEl } = this; 221 | contentEl.empty(); 222 | } 223 | } 224 | 225 | class IconSwapperSettingsTab extends PluginSettingTab { 226 | plugin: IconSwapperPlugin; 227 | 228 | constructor(app: App, plugin: IconSwapperPlugin) { 229 | super(app, plugin); 230 | this.plugin = plugin; 231 | } 232 | 233 | display(): void { 234 | let { containerEl } = this; 235 | 236 | containerEl.empty(); 237 | containerEl.addClass("icon-swapper"); 238 | 239 | new Setting(containerEl) 240 | .then((setting) => { 241 | // Build and import link to open the import modal 242 | setting.controlEl.createEl( 243 | "a", 244 | { 245 | cls: "icon-swapper-import", 246 | text: "Import", 247 | href: "#", 248 | }, 249 | (el) => { 250 | el.addEventListener("click", (e) => { 251 | e.preventDefault(); 252 | new ImportModal(this.app, this.plugin).open(); 253 | }); 254 | } 255 | ); 256 | 257 | // Build and export link to open the export modal 258 | setting.controlEl.createEl( 259 | "a", 260 | { 261 | cls: "icon-swapper-export", 262 | text: "Export", 263 | href: "#", 264 | }, 265 | (el) => { 266 | el.addEventListener("click", (e) => { 267 | e.preventDefault(); 268 | new ExportModal(this.app, this.plugin).open(); 269 | }); 270 | } 271 | ); 272 | }) 273 | 274 | // Build a revert link 275 | .addExtraButton((b) => { 276 | b.setIcon("reset") 277 | .setTooltip("Restore default icons") 278 | .onClick(async () => { 279 | await this.plugin.iconManager.revertAll(); 280 | 281 | // Rebuild settings pane after the changes have been made 282 | this.display(); 283 | }); 284 | }); 285 | 286 | // Build a setting for each icon 287 | icons.forEach((name) => { 288 | createIconSetting({ 289 | containerEl, 290 | name, 291 | iconManager: this.plugin.iconManager, 292 | }); 293 | }); 294 | } 295 | } 296 | -------------------------------------------------------------------------------- /src/svg.ts: -------------------------------------------------------------------------------- 1 | import { INode } from "svgson"; 2 | import toPath from "element-to-path"; 3 | import { 4 | parse as pathParse, 5 | stringify as pathStringify, 6 | scale, 7 | } from "svg-path-tools"; 8 | import { addIcon, setIcon } from "obsidian"; 9 | 10 | // Parse the viewbox attribute for the maximum value 11 | // This is used to scale the svgs 12 | export function getMaxViewBox(parsedSVG: INode) { 13 | const vb = parsedSVG.attributes.viewBox; 14 | 15 | if (!vb) { 16 | return 0; 17 | } 18 | 19 | return vb.split(" ").reduce((prev, c) => { 20 | const next = parseInt(c); 21 | 22 | if (prev > next) { 23 | return prev; 24 | } 25 | 26 | return next; 27 | }, 0); 28 | } 29 | 30 | // Scale a parsed SVG child element; adapted from https://github.com/elrumordelaluz/svg-path-tools 31 | export function scalePath( 32 | node: INode, 33 | scaleOptions: { scale: number; round: number } 34 | ) { 35 | const o = Object.assign({}, node); 36 | const { scale: s } = scaleOptions || { scale: 1 }; 37 | 38 | if (/(rect|circle|ellipse|polygon|polyline|line|path)/.test(o.name)) { 39 | const path = toPath(o); 40 | const parseD = pathParse(path); 41 | const scaleD = scale(parseD, scaleOptions); 42 | const d = pathStringify(scaleD); 43 | 44 | o.attributes = Object.assign({}, o.attributes, { 45 | d, 46 | }); 47 | 48 | for (const attr in o.attributes) { 49 | if (attr === "stroke-width" || attr === "strokeWidth") { 50 | o.attributes[attr] = +o.attributes[attr] * s; 51 | } 52 | if (!/fill|stroke|opacity|d/.test(attr)) { 53 | delete o.attributes[attr]; 54 | } else if (/fill|stroke/.test(attr)) { 55 | o.attributes[attr] = "currentColor"; 56 | } 57 | } 58 | 59 | if (!o.attributes.fill) o.attributes.fill = "currentColor"; 60 | if ( 61 | !o.attributes.stroke && 62 | (o.attributes.strokeWidth || o.attributes["stroke-width"]) 63 | ) 64 | o.attributes.stroke = "currentColor"; 65 | 66 | o.name = "path"; 67 | } else if (o.children && Array.isArray(o.children)) { 68 | const _scale = (c: any) => scalePath(c, scaleOptions); 69 | o.children = o.children.map(_scale); 70 | } 71 | 72 | return o; 73 | } 74 | 75 | // Retrieve the default SVG markup for a given icon name 76 | export function getDefaultIconSVG(name: string) { 77 | const container = createDiv("div"); 78 | setIcon(container, name); 79 | 80 | const inner = container.children[0].innerHTML; 81 | container.remove(); 82 | 83 | return inner; 84 | } 85 | 86 | // Override a default icon's SVG markup 87 | export function replaceIconSVG(name: string, content: string) { 88 | addIcon(name, content); 89 | 90 | // Replace any icons that already exist in the dom 91 | document.querySelectorAll(`svg.${name}`).forEach((el) => { 92 | el.innerHTML = content; 93 | }); 94 | } 95 | -------------------------------------------------------------------------------- /src/types.d.ts: -------------------------------------------------------------------------------- 1 | declare module "element-to-path"; 2 | declare module "svg-path-tools"; -------------------------------------------------------------------------------- /styles.css: -------------------------------------------------------------------------------- 1 | .icon-swapper textarea { 2 | flex-grow: 1; 3 | font-family: var(--font-monospace) !important; 4 | font-size: 12px; 5 | } 6 | 7 | .icon-swapper .setting-item:not(.setting-item-heading) .setting-item-control { 8 | width: 60%; 9 | flex-grow: 0; 10 | } 11 | 12 | .icon-swapper-container { 13 | display: flex; 14 | flex-direction: column; 15 | align-items: center; 16 | justify-content: center; 17 | line-height: 1; 18 | } 19 | 20 | .icon-swapper-icon { 21 | display: flex; 22 | margin-bottom: 10px; 23 | } 24 | 25 | .icon-swapper-name { 26 | font-size: 13px; 27 | } 28 | 29 | .icon-swapper-import-input { 30 | width: 0.1px; 31 | height: 0.1px; 32 | opacity: 0; 33 | overflow: hidden; 34 | position: absolute; 35 | z-index: -1; 36 | } 37 | 38 | .icon-swapper-import-label { 39 | cursor: pointer; 40 | color: var(--text-accent); 41 | text-decoration: underline; 42 | } 43 | 44 | .icon-swapper-import-label:hover { 45 | color: var(--text-accent-hover); 46 | } 47 | 48 | .icon-swapper-export, 49 | .icon-swapper-import { 50 | display: inline-block; 51 | margin-right: 10px; 52 | } 53 | 54 | .icon-swapper-copy, 55 | .icon-swapper-download { 56 | position: relative; 57 | display: inline-block; 58 | margin-left: 10px; 59 | } 60 | 61 | .icon-swapper-copy:before { 62 | color: var(--interactive-success); 63 | content: "✓"; 64 | position: absolute; 65 | left: -18px; 66 | font-weight: bold; 67 | opacity: 0; 68 | transition: 150ms opacity ease-in-out; 69 | } 70 | 71 | .icon-swapper-copy.success:before { 72 | opacity: 1; 73 | } 74 | 75 | .modal-icon-swapper { 76 | height: 70vh; 77 | display: flex; 78 | flex-direction: column; 79 | } 80 | 81 | .modal-icon-swapper .modal-content { 82 | flex-grow: 1; 83 | margin: 0; 84 | display: flex; 85 | flex-direction: column; 86 | } 87 | 88 | .modal-icon-swapper textarea { 89 | display: block; 90 | width: 100%; 91 | height: 100%; 92 | font-family: var(--font-monospace) !important; 93 | font-size: 12px; 94 | white-space: pre; 95 | overflow-wrap: normal; 96 | overflow-x: scroll; 97 | } 98 | 99 | .modal-icon-swapper .setting-item { 100 | align-items: flex-start; 101 | } 102 | 103 | .modal-icon-swapper button { 104 | margin: 10px 0 0; 105 | } 106 | 107 | .icon-swapper-import-error { 108 | display: none; 109 | color: var(--text-error); 110 | } 111 | 112 | .icon-swapper-import-error.active { 113 | display: block; 114 | } -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowSyntheticDefaultImports": true, 4 | "baseUrl": ".", 5 | "inlineSourceMap": true, 6 | "inlineSources": true, 7 | "module": "ESNext", 8 | "target": "es6", 9 | "allowJs": true, 10 | "noImplicitAny": true, 11 | "moduleResolution": "node", 12 | "importHelpers": true, 13 | "lib": [ 14 | "dom", 15 | "es5", 16 | "scripthost", 17 | "es2015" 18 | ] 19 | }, 20 | "include": [ 21 | "**/*.ts" 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /versions.json: -------------------------------------------------------------------------------- 1 | { 2 | "0.0.1": "0.11.5" 3 | } 4 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@nodelib/fs.scandir@2.1.4": 6 | version "2.1.4" 7 | resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz#d4b3549a5db5de2683e0c1071ab4f140904bbf69" 8 | integrity sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA== 9 | dependencies: 10 | "@nodelib/fs.stat" "2.0.4" 11 | run-parallel "^1.1.9" 12 | 13 | "@nodelib/fs.stat@2.0.4", "@nodelib/fs.stat@^2.0.2": 14 | version "2.0.4" 15 | resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz#a3f2dd61bab43b8db8fa108a121cfffe4c676655" 16 | integrity sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q== 17 | 18 | "@nodelib/fs.walk@^1.2.3": 19 | version "1.2.6" 20 | resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz#cce9396b30aa5afe9e3756608f5831adcb53d063" 21 | integrity sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow== 22 | dependencies: 23 | "@nodelib/fs.scandir" "2.1.4" 24 | fastq "^1.6.0" 25 | 26 | "@rollup/plugin-commonjs@^15.1.0": 27 | version "15.1.0" 28 | resolved "https://registry.yarnpkg.com/@rollup/plugin-commonjs/-/plugin-commonjs-15.1.0.tgz#1e7d076c4f1b2abf7e65248570e555defc37c238" 29 | integrity sha512-xCQqz4z/o0h2syQ7d9LskIMvBSH4PX5PjYdpSSvgS+pQik3WahkQVNWg3D8XJeYjZoVWnIUQYDghuEMRGrmQYQ== 30 | dependencies: 31 | "@rollup/pluginutils" "^3.1.0" 32 | commondir "^1.0.1" 33 | estree-walker "^2.0.1" 34 | glob "^7.1.6" 35 | is-reference "^1.2.1" 36 | magic-string "^0.25.7" 37 | resolve "^1.17.0" 38 | 39 | "@rollup/plugin-node-resolve@^9.0.0": 40 | version "9.0.0" 41 | resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-9.0.0.tgz#39bd0034ce9126b39c1699695f440b4b7d2b62e6" 42 | integrity sha512-gPz+utFHLRrd41WMP13Jq5mqqzHL3OXrfj3/MkSyB6UBIcuNt9j60GCbarzMzdf1VHFpOxfQh/ez7wyadLMqkg== 43 | dependencies: 44 | "@rollup/pluginutils" "^3.1.0" 45 | "@types/resolve" "1.17.1" 46 | builtin-modules "^3.1.0" 47 | deepmerge "^4.2.2" 48 | is-module "^1.0.0" 49 | resolve "^1.17.0" 50 | 51 | "@rollup/plugin-typescript@^6.0.0": 52 | version "6.1.0" 53 | resolved "https://registry.yarnpkg.com/@rollup/plugin-typescript/-/plugin-typescript-6.1.0.tgz#289e7f0ea12fd659bd13ad59dda73b9055538b83" 54 | integrity sha512-hJxaiE6WyNOsK+fZpbFh9CUijZYqPQuAOWO5khaGTUkM8DYNNyA2TDlgamecE+qLOG1G1+CwbWMAx3rbqpp6xQ== 55 | dependencies: 56 | "@rollup/pluginutils" "^3.1.0" 57 | resolve "^1.17.0" 58 | 59 | "@rollup/pluginutils@^3.1.0": 60 | version "3.1.0" 61 | resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-3.1.0.tgz#706b4524ee6dc8b103b3c995533e5ad680c02b9b" 62 | integrity sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg== 63 | dependencies: 64 | "@types/estree" "0.0.39" 65 | estree-walker "^1.0.1" 66 | picomatch "^2.2.2" 67 | 68 | "@types/codemirror@0.0.98": 69 | version "0.0.98" 70 | resolved "https://registry.yarnpkg.com/@types/codemirror/-/codemirror-0.0.98.tgz#b35c7a4ab1fc1684b08a4e3eb65240020556ebfb" 71 | integrity sha512-cbty5LPayy2vNSeuUdjNA9tggG+go5vAxmnLDRWpiZI5a+RDBi9dlozy4/jW/7P/gletbBWbQREEa7A81YxstA== 72 | dependencies: 73 | "@types/tern" "*" 74 | 75 | "@types/estree@*": 76 | version "0.0.47" 77 | resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.47.tgz#d7a51db20f0650efec24cd04994f523d93172ed4" 78 | integrity sha512-c5ciR06jK8u9BstrmJyO97m+klJrrhCf9u3rLu3DEAJBirxRqSCvDQoYKmxuYwQI5SZChAWu+tq9oVlGRuzPAg== 79 | 80 | "@types/estree@0.0.39": 81 | version "0.0.39" 82 | resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f" 83 | integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw== 84 | 85 | "@types/fs-extra@^8.0.1": 86 | version "8.1.1" 87 | resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-8.1.1.tgz#1e49f22d09aa46e19b51c0b013cb63d0d923a068" 88 | integrity sha512-TcUlBem321DFQzBNuz8p0CLLKp0VvF/XH9E4KHNmgwyp4E3AfgI5cjiIVZWlbfThBop2qxFIh4+LeY6hVWWZ2w== 89 | dependencies: 90 | "@types/node" "*" 91 | 92 | "@types/glob@^7.1.1": 93 | version "7.1.3" 94 | resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.3.tgz#e6ba80f36b7daad2c685acd9266382e68985c183" 95 | integrity sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w== 96 | dependencies: 97 | "@types/minimatch" "*" 98 | "@types/node" "*" 99 | 100 | "@types/minimatch@*": 101 | version "3.0.4" 102 | resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.4.tgz#f0ec25dbf2f0e4b18647313ac031134ca5b24b21" 103 | integrity sha512-1z8k4wzFnNjVK/tlxvrWuK5WMt6mydWWP7+zvH5eFep4oj+UkrfiJTRtjCeBXNpwaA/FYqqtb4/QS4ianFpIRA== 104 | 105 | "@types/node@*", "@types/node@^14.14.2": 106 | version "14.14.37" 107 | resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.37.tgz#a3dd8da4eb84a996c36e331df98d82abd76b516e" 108 | integrity sha512-XYmBiy+ohOR4Lh5jE379fV2IU+6Jn4g5qASinhitfyO71b/sCo6MKsMLF5tc7Zf2CE8hViVQyYSobJNke8OvUw== 109 | 110 | "@types/resolve@1.17.1": 111 | version "1.17.1" 112 | resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.17.1.tgz#3afd6ad8967c77e4376c598a82ddd58f46ec45d6" 113 | integrity sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw== 114 | dependencies: 115 | "@types/node" "*" 116 | 117 | "@types/tern@*": 118 | version "0.23.3" 119 | resolved "https://registry.yarnpkg.com/@types/tern/-/tern-0.23.3.tgz#4b54538f04a88c9ff79de1f6f94f575a7f339460" 120 | integrity sha512-imDtS4TAoTcXk0g7u4kkWqedB3E4qpjXzCpD2LU5M5NAXHzCDsypyvXSaG7mM8DKYkCRa7tFp4tS/lp/Wo7Q3w== 121 | dependencies: 122 | "@types/estree" "*" 123 | 124 | array-union@^2.1.0: 125 | version "2.1.0" 126 | resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" 127 | integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== 128 | 129 | balanced-match@^1.0.0: 130 | version "1.0.2" 131 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" 132 | integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== 133 | 134 | brace-expansion@^1.1.7: 135 | version "1.1.11" 136 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" 137 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== 138 | dependencies: 139 | balanced-match "^1.0.0" 140 | concat-map "0.0.1" 141 | 142 | braces@^3.0.1: 143 | version "3.0.2" 144 | resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" 145 | integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== 146 | dependencies: 147 | fill-range "^7.0.1" 148 | 149 | builtin-modules@^3.1.0: 150 | version "3.2.0" 151 | resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.2.0.tgz#45d5db99e7ee5e6bc4f362e008bf917ab5049887" 152 | integrity sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA== 153 | 154 | colorette@^1.1.0: 155 | version "1.2.2" 156 | resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94" 157 | integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w== 158 | 159 | commondir@^1.0.1: 160 | version "1.0.1" 161 | resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" 162 | integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= 163 | 164 | concat-map@0.0.1: 165 | version "0.0.1" 166 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 167 | integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= 168 | 169 | deep-rename-keys@^0.2.1: 170 | version "0.2.1" 171 | resolved "https://registry.yarnpkg.com/deep-rename-keys/-/deep-rename-keys-0.2.1.tgz#ede78537d7a66a2be61517e2af956d7f58a3f1d8" 172 | integrity sha1-7eeFN9emaivmFRfir5Vtf1ij8dg= 173 | dependencies: 174 | kind-of "^3.0.2" 175 | rename-keys "^1.1.2" 176 | 177 | deepmerge@^4.2.2: 178 | version "4.2.2" 179 | resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" 180 | integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== 181 | 182 | dir-glob@^3.0.1: 183 | version "3.0.1" 184 | resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" 185 | integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== 186 | dependencies: 187 | path-type "^4.0.0" 188 | 189 | dotenv@^8.2.0: 190 | version "8.2.0" 191 | resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a" 192 | integrity sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw== 193 | 194 | element-to-path@^1.2.0: 195 | version "1.2.0" 196 | resolved "https://registry.yarnpkg.com/element-to-path/-/element-to-path-1.2.0.tgz#5091c7961447917779c9742d602b0aceca8df17f" 197 | integrity sha512-QURDQymbFRumDvYbBlgjFgIX8M4yfDHkSePRiuVAM1C6DyCKuDo4/G8oRubUyQum5uXcLr8fofuTl7z6bSSswA== 198 | 199 | estree-walker@^1.0.1: 200 | version "1.0.1" 201 | resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-1.0.1.tgz#31bc5d612c96b704106b477e6dd5d8aa138cb700" 202 | integrity sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg== 203 | 204 | estree-walker@^2.0.1: 205 | version "2.0.2" 206 | resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" 207 | integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== 208 | 209 | eventemitter3@^2.0.0: 210 | version "2.0.3" 211 | resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-2.0.3.tgz#b5e1079b59fb5e1ba2771c0a993be060a58c99ba" 212 | integrity sha1-teEHm1n7XhuidxwKmTvgYKWMmbo= 213 | 214 | fast-glob@^3.0.3: 215 | version "3.2.5" 216 | resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.5.tgz#7939af2a656de79a4f1901903ee8adcaa7cb9661" 217 | integrity sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg== 218 | dependencies: 219 | "@nodelib/fs.stat" "^2.0.2" 220 | "@nodelib/fs.walk" "^1.2.3" 221 | glob-parent "^5.1.0" 222 | merge2 "^1.3.0" 223 | micromatch "^4.0.2" 224 | picomatch "^2.2.1" 225 | 226 | fastq@^1.6.0: 227 | version "1.11.0" 228 | resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.11.0.tgz#bb9fb955a07130a918eb63c1f5161cc32a5d0858" 229 | integrity sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g== 230 | dependencies: 231 | reusify "^1.0.4" 232 | 233 | fill-range@^7.0.1: 234 | version "7.0.1" 235 | resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" 236 | integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== 237 | dependencies: 238 | to-regex-range "^5.0.1" 239 | 240 | fs-extra@^8.1.0: 241 | version "8.1.0" 242 | resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" 243 | integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== 244 | dependencies: 245 | graceful-fs "^4.2.0" 246 | jsonfile "^4.0.0" 247 | universalify "^0.1.0" 248 | 249 | fs.realpath@^1.0.0: 250 | version "1.0.0" 251 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" 252 | integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= 253 | 254 | fsevents@~2.3.1: 255 | version "2.3.2" 256 | resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" 257 | integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== 258 | 259 | function-bind@^1.1.1: 260 | version "1.1.1" 261 | resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" 262 | integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== 263 | 264 | get-value@^2.0.3: 265 | version "2.0.6" 266 | resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" 267 | integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= 268 | 269 | glob-parent@^5.1.0: 270 | version "5.1.2" 271 | resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" 272 | integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== 273 | dependencies: 274 | is-glob "^4.0.1" 275 | 276 | glob@^7.1.3, glob@^7.1.6: 277 | version "7.1.6" 278 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" 279 | integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== 280 | dependencies: 281 | fs.realpath "^1.0.0" 282 | inflight "^1.0.4" 283 | inherits "2" 284 | minimatch "^3.0.4" 285 | once "^1.3.0" 286 | path-is-absolute "^1.0.0" 287 | 288 | globby@10.0.1: 289 | version "10.0.1" 290 | resolved "https://registry.yarnpkg.com/globby/-/globby-10.0.1.tgz#4782c34cb75dd683351335c5829cc3420e606b22" 291 | integrity sha512-sSs4inE1FB2YQiymcmTv6NWENryABjUNPeWhOvmn4SjtKybglsyPZxFB3U1/+L1bYi0rNZDqCLlHyLYDl1Pq5A== 292 | dependencies: 293 | "@types/glob" "^7.1.1" 294 | array-union "^2.1.0" 295 | dir-glob "^3.0.1" 296 | fast-glob "^3.0.3" 297 | glob "^7.1.3" 298 | ignore "^5.1.1" 299 | merge2 "^1.2.3" 300 | slash "^3.0.0" 301 | 302 | graceful-fs@^4.1.6, graceful-fs@^4.2.0: 303 | version "4.2.6" 304 | resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee" 305 | integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ== 306 | 307 | has-value@^0.3.1: 308 | version "0.3.1" 309 | resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" 310 | integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= 311 | dependencies: 312 | get-value "^2.0.3" 313 | has-values "^0.1.4" 314 | isobject "^2.0.0" 315 | 316 | has-values@^0.1.4: 317 | version "0.1.4" 318 | resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" 319 | integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= 320 | 321 | has@^1.0.3: 322 | version "1.0.3" 323 | resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" 324 | integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== 325 | dependencies: 326 | function-bind "^1.1.1" 327 | 328 | ignore@^5.1.1: 329 | version "5.1.8" 330 | resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" 331 | integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== 332 | 333 | inflight@^1.0.4: 334 | version "1.0.6" 335 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 336 | integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= 337 | dependencies: 338 | once "^1.3.0" 339 | wrappy "1" 340 | 341 | inherits@2: 342 | version "2.0.4" 343 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" 344 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 345 | 346 | is-buffer@^1.1.5: 347 | version "1.1.6" 348 | resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" 349 | integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== 350 | 351 | is-core-module@^2.2.0: 352 | version "2.2.0" 353 | resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.2.0.tgz#97037ef3d52224d85163f5597b2b63d9afed981a" 354 | integrity sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ== 355 | dependencies: 356 | has "^1.0.3" 357 | 358 | is-extglob@^2.1.1: 359 | version "2.1.1" 360 | resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" 361 | integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= 362 | 363 | is-glob@^4.0.1: 364 | version "4.0.1" 365 | resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" 366 | integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== 367 | dependencies: 368 | is-extglob "^2.1.1" 369 | 370 | is-module@^1.0.0: 371 | version "1.0.0" 372 | resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591" 373 | integrity sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE= 374 | 375 | is-number@^7.0.0: 376 | version "7.0.0" 377 | resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" 378 | integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== 379 | 380 | is-plain-object@^2.0.1: 381 | version "2.0.4" 382 | resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" 383 | integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== 384 | dependencies: 385 | isobject "^3.0.1" 386 | 387 | is-plain-object@^3.0.0: 388 | version "3.0.1" 389 | resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-3.0.1.tgz#662d92d24c0aa4302407b0d45d21f2251c85f85b" 390 | integrity sha512-Xnpx182SBMrr/aBik8y+GuR4U1L9FqMSojwDQwPMmxyC6bvEqly9UBCxhauBF5vNh2gwWJNX6oDV7O+OM4z34g== 391 | 392 | is-reference@^1.2.1: 393 | version "1.2.1" 394 | resolved "https://registry.yarnpkg.com/is-reference/-/is-reference-1.2.1.tgz#8b2dac0b371f4bc994fdeaba9eb542d03002d0b7" 395 | integrity sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ== 396 | dependencies: 397 | "@types/estree" "*" 398 | 399 | isarray@1.0.0: 400 | version "1.0.0" 401 | resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" 402 | integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= 403 | 404 | isobject@^2.0.0: 405 | version "2.1.0" 406 | resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" 407 | integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= 408 | dependencies: 409 | isarray "1.0.0" 410 | 411 | isobject@^3.0.0, isobject@^3.0.1: 412 | version "3.0.1" 413 | resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" 414 | integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= 415 | 416 | jsonfile@^4.0.0: 417 | version "4.0.0" 418 | resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" 419 | integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= 420 | optionalDependencies: 421 | graceful-fs "^4.1.6" 422 | 423 | kind-of@^3.0.2: 424 | version "3.2.2" 425 | resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" 426 | integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= 427 | dependencies: 428 | is-buffer "^1.1.5" 429 | 430 | magic-string@^0.25.7: 431 | version "0.25.7" 432 | resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.7.tgz#3f497d6fd34c669c6798dcb821f2ef31f5445051" 433 | integrity sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA== 434 | dependencies: 435 | sourcemap-codec "^1.4.4" 436 | 437 | merge2@^1.2.3, merge2@^1.3.0: 438 | version "1.4.1" 439 | resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" 440 | integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== 441 | 442 | micromatch@^4.0.2: 443 | version "4.0.2" 444 | resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259" 445 | integrity sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q== 446 | dependencies: 447 | braces "^3.0.1" 448 | picomatch "^2.0.5" 449 | 450 | minimatch@^3.0.4: 451 | version "3.0.4" 452 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" 453 | integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== 454 | dependencies: 455 | brace-expansion "^1.1.7" 456 | 457 | "obsidian@https://github.com/obsidianmd/obsidian-api/tarball/master": 458 | version "0.11.7" 459 | resolved "https://github.com/obsidianmd/obsidian-api/tarball/master#28c00facf01a4f832d3e4ffb879139c7a627aa52" 460 | dependencies: 461 | "@types/codemirror" "0.0.98" 462 | 463 | omit-deep@0.3.0: 464 | version "0.3.0" 465 | resolved "https://registry.yarnpkg.com/omit-deep/-/omit-deep-0.3.0.tgz#21c8af3499bcadd29651a232cbcacbc52445ebec" 466 | integrity sha1-IcivNJm8rdKWUaIyy8rLxSRF6+w= 467 | dependencies: 468 | is-plain-object "^2.0.1" 469 | unset-value "^0.1.1" 470 | 471 | once@^1.3.0: 472 | version "1.4.0" 473 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 474 | integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= 475 | dependencies: 476 | wrappy "1" 477 | 478 | path-is-absolute@^1.0.0: 479 | version "1.0.1" 480 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 481 | integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= 482 | 483 | path-parse@^1.0.6: 484 | version "1.0.6" 485 | resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" 486 | integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== 487 | 488 | path-type@^4.0.0: 489 | version "4.0.0" 490 | resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" 491 | integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== 492 | 493 | picomatch@^2.0.5, picomatch@^2.2.1, picomatch@^2.2.2: 494 | version "2.2.2" 495 | resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" 496 | integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== 497 | 498 | queue-microtask@^1.2.2: 499 | version "1.2.3" 500 | resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" 501 | integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== 502 | 503 | rename-keys@^1.1.2: 504 | version "1.2.0" 505 | resolved "https://registry.yarnpkg.com/rename-keys/-/rename-keys-1.2.0.tgz#be602fb0b750476b513ebe85ba4465d03254f0a3" 506 | integrity sha512-U7XpAktpbSgHTRSNRrjKSrjYkZKuhUukfoBlXWXUExCAqhzh1TU3BDRAfJmarcl5voKS+pbKU9MvyLWKZ4UEEg== 507 | 508 | resolve@^1.17.0: 509 | version "1.20.0" 510 | resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" 511 | integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== 512 | dependencies: 513 | is-core-module "^2.2.0" 514 | path-parse "^1.0.6" 515 | 516 | reusify@^1.0.4: 517 | version "1.0.4" 518 | resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" 519 | integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== 520 | 521 | rollup-plugin-copy@^3.4.0: 522 | version "3.4.0" 523 | resolved "https://registry.yarnpkg.com/rollup-plugin-copy/-/rollup-plugin-copy-3.4.0.tgz#f1228a3ffb66ffad8606e2f3fb7ff23141ed3286" 524 | integrity sha512-rGUmYYsYsceRJRqLVlE9FivJMxJ7X6jDlP79fmFkL8sJs7VVMSVyA2yfyL+PGyO/vJs4A87hwhgVfz61njI+uQ== 525 | dependencies: 526 | "@types/fs-extra" "^8.0.1" 527 | colorette "^1.1.0" 528 | fs-extra "^8.1.0" 529 | globby "10.0.1" 530 | is-plain-object "^3.0.0" 531 | 532 | rollup@^2.32.1: 533 | version "2.45.0" 534 | resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.45.0.tgz#bfcce2347c96f15f5c78ac860bc38e3349ba27c9" 535 | integrity sha512-JJznbtGIsHZfKH0Sa9RpCAy5JarH8SWvBzRAGuRkgzAafb8e8D7VSMJ0O1Bsix1nn91koN/Ecvl2+ZWhljcuTw== 536 | optionalDependencies: 537 | fsevents "~2.3.1" 538 | 539 | run-parallel@^1.1.9: 540 | version "1.2.0" 541 | resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" 542 | integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== 543 | dependencies: 544 | queue-microtask "^1.2.2" 545 | 546 | slash@^3.0.0: 547 | version "3.0.0" 548 | resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" 549 | integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== 550 | 551 | sourcemap-codec@^1.4.4: 552 | version "1.4.8" 553 | resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" 554 | integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== 555 | 556 | svg-path-tools@^1.0.0: 557 | version "1.0.0" 558 | resolved "https://registry.yarnpkg.com/svg-path-tools/-/svg-path-tools-1.0.0.tgz#cb03f0a07da9b83769a8f4efe0090950cbdf8d76" 559 | integrity sha512-bBvb8aqFRkds749JhsKXd9v88wXISryj0Pan6TDI7iDLiHVAg+lV7J1ufGgbLmpR+Xdf083eH8boBMzyqpDyGQ== 560 | 561 | svgson@^5.2.1: 562 | version "5.2.1" 563 | resolved "https://registry.yarnpkg.com/svgson/-/svgson-5.2.1.tgz#7481fb1af4a58be542a6bd2020c168c6b71381cb" 564 | integrity sha512-nbM6QuyZiKzQ0Uo51VDta93YJAr96ikyT40PsgJRrzynOGsOlnmJ6zAK5hUFyE5gnxcg7yuOPUWbUlmV9K0+Dg== 565 | dependencies: 566 | deep-rename-keys "^0.2.1" 567 | omit-deep "0.3.0" 568 | xml-reader "2.4.3" 569 | 570 | to-regex-range@^5.0.1: 571 | version "5.0.1" 572 | resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" 573 | integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== 574 | dependencies: 575 | is-number "^7.0.0" 576 | 577 | tslib@^2.0.3: 578 | version "2.2.0" 579 | resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.2.0.tgz#fb2c475977e35e241311ede2693cee1ec6698f5c" 580 | integrity sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w== 581 | 582 | typescript@^4.0.3: 583 | version "4.2.4" 584 | resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.4.tgz#8610b59747de028fda898a8aef0e103f156d0961" 585 | integrity sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg== 586 | 587 | universalify@^0.1.0: 588 | version "0.1.2" 589 | resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" 590 | integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== 591 | 592 | unset-value@^0.1.1: 593 | version "0.1.2" 594 | resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-0.1.2.tgz#506810b867f27c2a5a6e9b04833631f6de58d310" 595 | integrity sha1-UGgQuGfyfCpabpsEgzYx9t5Y0xA= 596 | dependencies: 597 | has-value "^0.3.1" 598 | isobject "^3.0.0" 599 | 600 | wrappy@1: 601 | version "1.0.2" 602 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 603 | integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= 604 | 605 | xml-lexer@^0.2.2: 606 | version "0.2.2" 607 | resolved "https://registry.yarnpkg.com/xml-lexer/-/xml-lexer-0.2.2.tgz#518193a4aa334d58fc7d248b549079b89907e046" 608 | integrity sha1-UYGTpKozTVj8fSSLVJB5uJkH4EY= 609 | dependencies: 610 | eventemitter3 "^2.0.0" 611 | 612 | xml-reader@2.4.3: 613 | version "2.4.3" 614 | resolved "https://registry.yarnpkg.com/xml-reader/-/xml-reader-2.4.3.tgz#9f810caf7c425a5aafb848b1c45103c9e71d7530" 615 | integrity sha1-n4EMr3xCWlqvuEixxFEDyecddTA= 616 | dependencies: 617 | eventemitter3 "^2.0.0" 618 | xml-lexer "^0.2.2" 619 | 620 | yaml@^1.10.2: 621 | version "1.10.2" 622 | resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" 623 | integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== 624 | --------------------------------------------------------------------------------