From 70425a496707ad7bfef442c888c5cb3ed17ddd11 Mon Sep 17 00:00:00 2001 From: Vincent Gao Date: Tue, 6 Jun 2023 12:54:09 +1000 Subject: [PATCH] added the missed patch --- .../ckeditor_templates_4.patch | 9011 +++++++++++++++++ 1 file changed, 9011 insertions(+) create mode 100644 patches/ckeditor_templates/ckeditor_templates_4.patch diff --git a/patches/ckeditor_templates/ckeditor_templates_4.patch b/patches/ckeditor_templates/ckeditor_templates_4.patch new file mode 100644 index 0000000..bd9f666 --- /dev/null +++ b/patches/ckeditor_templates/ckeditor_templates_4.patch @@ -0,0 +1,9011 @@ +From 2fcbb589c7d2af5228ff0889534a723ecadf9e0e Mon Sep 17 00:00:00 2001 +From: Marcelo Hespanhol +Date: Wed, 22 Feb 2023 14:35:44 -0500 +Subject: [PATCH 01/11] Make the module compatible with CKEditor 5 + +--- + LICENSE.txt | 339 ++ + README.txt | 73 +- + ckeditor_templates.ckeditor5.yml | 23 + + ckeditor_templates.info.yml | 5 +- + ckeditor_templates.libraries.yml | 16 +- + ckeditor_templates.links.action.yml | 5 + + ckeditor_templates.links.menu.yml | 5 + + ckeditor_templates.permissions.yml | 2 + + ckeditor_templates.routing.yml | 38 + + config/schema/ckeditor_templates.schema.yml | 40 + + css/README.md | 4 + + css/cke_templates.admin.css | 1 + + css/cke_templates.dialog.css | 1 + + css/ckeditor_templates.css | 8 - + js/ckeditor_templates.admin.js | 32 - + js/ckeditor_templates.dialog.js | 22 - + js/dist/ckeditorTemplates.js | 1 + + js/plugin/src/app.js | 6 + + js/plugin/src/ckeditorTemplates.js | 26 + + js/plugin/src/ckeditorTemplatesCommand.js | 41 + + js/plugin/src/ckeditorTemplatesEditing.js | 42 + + js/plugin/src/ckeditorTemplatesUI.js | 51 + + js/plugin/theme/icons/templates.svg | 1 + + js/plugin/theme/images/placeholder.svg | 1 + + package-lock.json | 4455 +++++++++++++++++ + package.json | 32 + + sass/dialog.scss | 47 + + src/CKEditorTemplatesInterface.php | 12 + + src/CKEditorTemplatesListBuilder.php | 100 + + src/Entity/CKEditorTemplates.php | 133 + + src/Form/CKEditorTemplatesDialogForm.php | 285 ++ + src/Form/CKEditorTemplatesEntityForm.php | 139 + + .../CKEditorTemplatesDialog.php | 68 + + .../CKEditorPlugin/CkeditorTemplates.php | 183 - + templates/ckeditor_templates.js.example | 83 - + webpack.config.js | 87 + + 36 files changed, 6021 insertions(+), 386 deletions(-) + create mode 100644 LICENSE.txt + create mode 100644 ckeditor_templates.ckeditor5.yml + create mode 100644 ckeditor_templates.links.action.yml + create mode 100644 ckeditor_templates.links.menu.yml + create mode 100644 ckeditor_templates.permissions.yml + create mode 100644 ckeditor_templates.routing.yml + create mode 100644 config/schema/ckeditor_templates.schema.yml + create mode 100644 css/README.md + create mode 100644 css/cke_templates.admin.css + create mode 100644 css/cke_templates.dialog.css + delete mode 100644 css/ckeditor_templates.css + delete mode 100644 js/ckeditor_templates.admin.js + delete mode 100644 js/ckeditor_templates.dialog.js + create mode 100644 js/dist/ckeditorTemplates.js + create mode 100644 js/plugin/src/app.js + create mode 100644 js/plugin/src/ckeditorTemplates.js + create mode 100644 js/plugin/src/ckeditorTemplatesCommand.js + create mode 100644 js/plugin/src/ckeditorTemplatesEditing.js + create mode 100644 js/plugin/src/ckeditorTemplatesUI.js + create mode 100644 js/plugin/theme/icons/templates.svg + create mode 100644 js/plugin/theme/images/placeholder.svg + create mode 100644 package-lock.json + create mode 100644 package.json + create mode 100644 sass/dialog.scss + create mode 100644 src/CKEditorTemplatesInterface.php + create mode 100644 src/CKEditorTemplatesListBuilder.php + create mode 100644 src/Entity/CKEditorTemplates.php + create mode 100644 src/Form/CKEditorTemplatesDialogForm.php + create mode 100644 src/Form/CKEditorTemplatesEntityForm.php + create mode 100644 src/Plugin/CKEditor5Plugin/CKEditorTemplatesDialog.php + delete mode 100644 src/Plugin/CKEditorPlugin/CkeditorTemplates.php + delete mode 100644 templates/ckeditor_templates.js.example + create mode 100644 webpack.config.js + +diff --git a/LICENSE.txt b/LICENSE.txt +new file mode 100644 +index 0000000..d159169 +--- /dev/null ++++ b/LICENSE.txt +@@ -0,0 +1,339 @@ ++ GNU GENERAL PUBLIC LICENSE ++ Version 2, June 1991 ++ ++ Copyright (C) 1989, 1991 Free Software Foundation, Inc., ++ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ Everyone is permitted to copy and distribute verbatim copies ++ of this license document, but changing it is not allowed. ++ ++ Preamble ++ ++ The licenses for most software are designed to take away your ++freedom to share and change it. By contrast, the GNU General Public ++License is intended to guarantee your freedom to share and change free ++software--to make sure the software is free for all its users. This ++General Public License applies to most of the Free Software ++Foundation's software and to any other program whose authors commit to ++using it. (Some other Free Software Foundation software is covered by ++the GNU Lesser General Public License instead.) You can apply it to ++your programs, too. ++ ++ When we speak of free software, we are referring to freedom, not ++price. Our General Public Licenses are designed to make sure that you ++have the freedom to distribute copies of free software (and charge for ++this service if you wish), that you receive source code or can get it ++if you want it, that you can change the software or use pieces of it ++in new free programs; and that you know you can do these things. ++ ++ To protect your rights, we need to make restrictions that forbid ++anyone to deny you these rights or to ask you to surrender the rights. ++These restrictions translate to certain responsibilities for you if you ++distribute copies of the software, or if you modify it. ++ ++ For example, if you distribute copies of such a program, whether ++gratis or for a fee, you must give the recipients all the rights that ++you have. You must make sure that they, too, receive or can get the ++source code. And you must show them these terms so they know their ++rights. ++ ++ We protect your rights with two steps: (1) copyright the software, and ++(2) offer you this license which gives you legal permission to copy, ++distribute and/or modify the software. ++ ++ Also, for each author's protection and ours, we want to make certain ++that everyone understands that there is no warranty for this free ++software. If the software is modified by someone else and passed on, we ++want its recipients to know that what they have is not the original, so ++that any problems introduced by others will not reflect on the original ++authors' reputations. ++ ++ Finally, any free program is threatened constantly by software ++patents. We wish to avoid the danger that redistributors of a free ++program will individually obtain patent licenses, in effect making the ++program proprietary. To prevent this, we have made it clear that any ++patent must be licensed for everyone's free use or not licensed at all. ++ ++ The precise terms and conditions for copying, distribution and ++modification follow. ++ ++ GNU GENERAL PUBLIC LICENSE ++ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION ++ ++ 0. This License applies to any program or other work which contains ++a notice placed by the copyright holder saying it may be distributed ++under the terms of this General Public License. The "Program", below, ++refers to any such program or work, and a "work based on the Program" ++means either the Program or any derivative work under copyright law: ++that is to say, a work containing the Program or a portion of it, ++either verbatim or with modifications and/or translated into another ++language. (Hereinafter, translation is included without limitation in ++the term "modification".) Each licensee is addressed as "you". ++ ++Activities other than copying, distribution and modification are not ++covered by this License; they are outside its scope. The act of ++running the Program is not restricted, and the output from the Program ++is covered only if its contents constitute a work based on the ++Program (independent of having been made by running the Program). ++Whether that is true depends on what the Program does. ++ ++ 1. You may copy and distribute verbatim copies of the Program's ++source code as you receive it, in any medium, provided that you ++conspicuously and appropriately publish on each copy an appropriate ++copyright notice and disclaimer of warranty; keep intact all the ++notices that refer to this License and to the absence of any warranty; ++and give any other recipients of the Program a copy of this License ++along with the Program. ++ ++You may charge a fee for the physical act of transferring a copy, and ++you may at your option offer warranty protection in exchange for a fee. ++ ++ 2. You may modify your copy or copies of the Program or any portion ++of it, thus forming a work based on the Program, and copy and ++distribute such modifications or work under the terms of Section 1 ++above, provided that you also meet all of these conditions: ++ ++ a) You must cause the modified files to carry prominent notices ++ stating that you changed the files and the date of any change. ++ ++ b) You must cause any work that you distribute or publish, that in ++ whole or in part contains or is derived from the Program or any ++ part thereof, to be licensed as a whole at no charge to all third ++ parties under the terms of this License. ++ ++ c) If the modified program normally reads commands interactively ++ when run, you must cause it, when started running for such ++ interactive use in the most ordinary way, to print or display an ++ announcement including an appropriate copyright notice and a ++ notice that there is no warranty (or else, saying that you provide ++ a warranty) and that users may redistribute the program under ++ these conditions, and telling the user how to view a copy of this ++ License. (Exception: if the Program itself is interactive but ++ does not normally print such an announcement, your work based on ++ the Program is not required to print an announcement.) ++ ++These requirements apply to the modified work as a whole. If ++identifiable sections of that work are not derived from the Program, ++and can be reasonably considered independent and separate works in ++themselves, then this License, and its terms, do not apply to those ++sections when you distribute them as separate works. But when you ++distribute the same sections as part of a whole which is a work based ++on the Program, the distribution of the whole must be on the terms of ++this License, whose permissions for other licensees extend to the ++entire whole, and thus to each and every part regardless of who wrote it. ++ ++Thus, it is not the intent of this section to claim rights or contest ++your rights to work written entirely by you; rather, the intent is to ++exercise the right to control the distribution of derivative or ++collective works based on the Program. ++ ++In addition, mere aggregation of another work not based on the Program ++with the Program (or with a work based on the Program) on a volume of ++a storage or distribution medium does not bring the other work under ++the scope of this License. ++ ++ 3. You may copy and distribute the Program (or a work based on it, ++under Section 2) in object code or executable form under the terms of ++Sections 1 and 2 above provided that you also do one of the following: ++ ++ a) Accompany it with the complete corresponding machine-readable ++ source code, which must be distributed under the terms of Sections ++ 1 and 2 above on a medium customarily used for software interchange; or, ++ ++ b) Accompany it with a written offer, valid for at least three ++ years, to give any third party, for a charge no more than your ++ cost of physically performing source distribution, a complete ++ machine-readable copy of the corresponding source code, to be ++ distributed under the terms of Sections 1 and 2 above on a medium ++ customarily used for software interchange; or, ++ ++ c) Accompany it with the information you received as to the offer ++ to distribute corresponding source code. (This alternative is ++ allowed only for noncommercial distribution and only if you ++ received the program in object code or executable form with such ++ an offer, in accord with Subsection b above.) ++ ++The source code for a work means the preferred form of the work for ++making modifications to it. For an executable work, complete source ++code means all the source code for all modules it contains, plus any ++associated interface definition files, plus the scripts used to ++control compilation and installation of the executable. However, as a ++special exception, the source code distributed need not include ++anything that is normally distributed (in either source or binary ++form) with the major components (compiler, kernel, and so on) of the ++operating system on which the executable runs, unless that component ++itself accompanies the executable. ++ ++If distribution of executable or object code is made by offering ++access to copy from a designated place, then offering equivalent ++access to copy the source code from the same place counts as ++distribution of the source code, even though third parties are not ++compelled to copy the source along with the object code. ++ ++ 4. You may not copy, modify, sublicense, or distribute the Program ++except as expressly provided under this License. Any attempt ++otherwise to copy, modify, sublicense or distribute the Program is ++void, and will automatically terminate your rights under this License. ++However, parties who have received copies, or rights, from you under ++this License will not have their licenses terminated so long as such ++parties remain in full compliance. ++ ++ 5. You are not required to accept this License, since you have not ++signed it. However, nothing else grants you permission to modify or ++distribute the Program or its derivative works. These actions are ++prohibited by law if you do not accept this License. Therefore, by ++modifying or distributing the Program (or any work based on the ++Program), you indicate your acceptance of this License to do so, and ++all its terms and conditions for copying, distributing or modifying ++the Program or works based on it. ++ ++ 6. Each time you redistribute the Program (or any work based on the ++Program), the recipient automatically receives a license from the ++original licensor to copy, distribute or modify the Program subject to ++these terms and conditions. You may not impose any further ++restrictions on the recipients' exercise of the rights granted herein. ++You are not responsible for enforcing compliance by third parties to ++this License. ++ ++ 7. If, as a consequence of a court judgment or allegation of patent ++infringement or for any other reason (not limited to patent issues), ++conditions are imposed on you (whether by court order, agreement or ++otherwise) that contradict the conditions of this License, they do not ++excuse you from the conditions of this License. If you cannot ++distribute so as to satisfy simultaneously your obligations under this ++License and any other pertinent obligations, then as a consequence you ++may not distribute the Program at all. For example, if a patent ++license would not permit royalty-free redistribution of the Program by ++all those who receive copies directly or indirectly through you, then ++the only way you could satisfy both it and this License would be to ++refrain entirely from distribution of the Program. ++ ++If any portion of this section is held invalid or unenforceable under ++any particular circumstance, the balance of the section is intended to ++apply and the section as a whole is intended to apply in other ++circumstances. ++ ++It is not the purpose of this section to induce you to infringe any ++patents or other property right claims or to contest validity of any ++such claims; this section has the sole purpose of protecting the ++integrity of the free software distribution system, which is ++implemented by public license practices. Many people have made ++generous contributions to the wide range of software distributed ++through that system in reliance on consistent application of that ++system; it is up to the author/donor to decide if he or she is willing ++to distribute software through any other system and a licensee cannot ++impose that choice. ++ ++This section is intended to make thoroughly clear what is believed to ++be a consequence of the rest of this License. ++ ++ 8. If the distribution and/or use of the Program is restricted in ++certain countries either by patents or by copyrighted interfaces, the ++original copyright holder who places the Program under this License ++may add an explicit geographical distribution limitation excluding ++those countries, so that distribution is permitted only in or among ++countries not thus excluded. In such case, this License incorporates ++the limitation as if written in the body of this License. ++ ++ 9. The Free Software Foundation may publish revised and/or new versions ++of the General Public License from time to time. Such new versions will ++be similar in spirit to the present version, but may differ in detail to ++address new problems or concerns. ++ ++Each version is given a distinguishing version number. If the Program ++specifies a version number of this License which applies to it and "any ++later version", you have the option of following the terms and conditions ++either of that version or of any later version published by the Free ++Software Foundation. If the Program does not specify a version number of ++this License, you may choose any version ever published by the Free Software ++Foundation. ++ ++ 10. If you wish to incorporate parts of the Program into other free ++programs whose distribution conditions are different, write to the author ++to ask for permission. For software which is copyrighted by the Free ++Software Foundation, write to the Free Software Foundation; we sometimes ++make exceptions for this. Our decision will be guided by the two goals ++of preserving the free status of all derivatives of our free software and ++of promoting the sharing and reuse of software generally. ++ ++ NO WARRANTY ++ ++ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY ++FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN ++OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES ++PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED ++OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS ++TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE ++PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, ++REPAIR OR CORRECTION. ++ ++ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING ++WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR ++REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, ++INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING ++OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED ++TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY ++YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER ++PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE ++POSSIBILITY OF SUCH DAMAGES. ++ ++ END OF TERMS AND CONDITIONS ++ ++ How to Apply These Terms to Your New Programs ++ ++ If you develop a new program, and you want it to be of the greatest ++possible use to the public, the best way to achieve this is to make it ++free software which everyone can redistribute and change under these terms. ++ ++ To do so, attach the following notices to the program. It is safest ++to attach them to the start of each source file to most effectively ++convey the exclusion of warranty; and each file should have at least ++the "copyright" line and a pointer to where the full notice is found. ++ ++ ++ Copyright (C) ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License along ++ with this program; if not, write to the Free Software Foundation, Inc., ++ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ++ ++Also add information on how to contact you by electronic and paper mail. ++ ++If the program is interactive, make it output a short notice like this ++when it starts in an interactive mode: ++ ++ Gnomovision version 69, Copyright (C) year name of author ++ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. ++ This is free software, and you are welcome to redistribute it ++ under certain conditions; type `show c' for details. ++ ++The hypothetical commands `show w' and `show c' should show the appropriate ++parts of the General Public License. Of course, the commands you use may ++be called something other than `show w' and `show c'; they could even be ++mouse-clicks or menu items--whatever suits your program. ++ ++You should also get your employer (if you work as a programmer) or your ++school, if any, to sign a "copyright disclaimer" for the program, if ++necessary. Here is a sample; alter the names: ++ ++ Yoyodyne, Inc., hereby disclaims all copyright interest in the program ++ `Gnomovision' (which makes passes at compilers) written by James Hacker. ++ ++ , 1 April 1989 ++ Ty Coon, President of Vice ++ ++This General Public License does not permit incorporating your program into ++proprietary programs. If your program is a subroutine library, you may ++consider it more useful to permit linking proprietary applications with the ++library. If this is what you want to do, use the GNU Lesser General ++Public License instead of this License. +diff --git a/README.txt b/README.txt +index 126ce0f..441c79f 100755 +--- a/README.txt ++++ b/README.txt +@@ -1,10 +1,10 @@ + INTRODUCTION + ------------ +-This module integrates the CKEditor templates plugin. ++This module provides templates for the CKEditor 5. + + It provides a dialog to offer predefined content templates - with page layout, +-text formatting and styles. Thus, end users can easily insert pre-defined +-snippets of html in CKEditor fields. ++text formatting, and styles. Thus, end users can easily insert predefined ++snippets of HTML in CKEditor fields. + + * For a full description of the module, visit the project page: + https://www.drupal.org/project/ckeditor_templates +@@ -13,65 +13,40 @@ snippets of html in CKEditor fields. + https://www.drupal.org/project/issues/ckeditor_templates?categories=All + + AUDIENCE +---------- +-This module is intended for themers who can manage custom ckeditor templates +-from their theme. As is, it doesn't provide any fonctionnality. ++-------- ++This module is intended for themers who can manage custom CKEditor templates ++from their theme. As is, it doesn't provide any functionality. + + REQUIREMENTS + ------------ +-This module requires to install the CKEditor "Templates" plugin. +-http://ckeditor.com/addon/templates ++This module requires CKEditor 5. + + INSTALLATION + ------------ +-Download the CKEditor "Templates" plugin on the project page : +-http://ckeditor.com/addon/templates +-Create a libraries folder in your drupal root if it doesn't exist +-Extract the plugin archive in the librairies folder +- +-Then install this Drupal module as you would normally install a contributed +-Drupal module. Visit: +-https://www.drupal.org/documentation/install/modules-themes/modules-8 for +-further information. ++Install this Drupal module as you would normally install a contributed ++Drupal module. For more information, visit: ++https://www.drupal.org/documentation/install/modules-themes/modules-8 + + CONFIGURATION +------------- +-- First, you need to add the plugin button in your editor toolbar. +-Go to the format and editor config page and click configure on the format your +-want to edit : +-http://drupalvm.dev/admin/config/content/formats +-- Add the templates button to the toolbar +-- copy the file ckeditor_templates.js.example from the module templates folder +-to your theme templates folder, rename it without .example and customize it : +- x edit the image_path variable to link to your thumbnail folder +- x copy the standard images from the libraries/templates/templates/images +- folder and place them in the folder created previously (image_path). +- x change the templates array in your custom ckeditor_templates.js to include +- any custom templates you want your users to have access to. +- +-If you want to place your template file in a different folder, you can set the +-path on the Editor config page. +- +-If you have a particular setup with non standard path and your template file is +-not found, you can always specify any custom path in the Editor Config Page, +-found at "Configuration", "Text formats and editors". Choose the editor type you +-want to expose the templates to and set path parameter at "Templates", +-"Templates Definition File", in the "CKEditor plugin settings" section. ++------------- ++- First, add the plugin button in your editor toolbar: go to the format and ++editor config page (/admin/config/content/formats), and click configure on the ++format your want to edit. ++- Next, create the templates: go to the CKEditor Templates config page ++(/admin/config/content/ckeditor-templates) and add as many templates as needed. + + WARNING +--------- ++------- + Depending on the configuration of your formats, CKEditor can be restrictive +-about authorized HTML tags. Make sure to use compatible HTML tags in your +-templates. ++about authorized HTML tags. Therefore, make sure to use compatible HTML tags ++in your templates. + +-ROAD MAP +---------- +-Two features could be added : +-- Allowing to add multiple template files so that you don't have to write all +-your templates in one big file +-- Allow to restrict for one editor the template displayed. Thus you could have +-10 templates in a file and display only 3 of them on a specific format. ++MIGRATING FROM CKEDITOR 4 ++------------------------- + ++If you had this module installed for CKEditor 4, all templates will not be ++migrated to the new version for CKEditor 5. Instead, you will have to manually ++create the templates in the new version, as described above. + + MAINTAINERS + ----------- +diff --git a/ckeditor_templates.ckeditor5.yml b/ckeditor_templates.ckeditor5.yml +new file mode 100644 +index 0000000..a387b3c +--- /dev/null ++++ b/ckeditor_templates.ckeditor5.yml +@@ -0,0 +1,23 @@ ++ckeditor_templates_plugin: ++ ckeditor5: ++ plugins: ++ - ckeditorTemplates.CKEditorTemplates ++ config: ++ ckeditorTemplates: ++ openDialog: ++ func: ++ name: Drupal.ckeditor5.openDialog ++ invoke: false ++ dialogSettings: ++ height: 75% ++ dialogClass: ckeditor-templates-widget-modal ++ title: Content Templates ++ drupal: ++ label: Templates ++ elements: false ++ library: ckeditor_templates/ckeditor.templates.dialog ++ admin_library: ckeditor_templates/ckeditor.templates.admin ++ class: Drupal\ckeditor_templates\Plugin\CKEditor5Plugin\CKEditorTemplatesDialog ++ toolbar_items: ++ ckeditorTemplates: ++ label: Templates +diff --git a/ckeditor_templates.info.yml b/ckeditor_templates.info.yml +index 19bbf56..6975f55 100644 +--- a/ckeditor_templates.info.yml ++++ b/ckeditor_templates.info.yml +@@ -2,7 +2,6 @@ name: CKEditor Templates + description: 'Integrates the CKEditor templates plugin.' + package: CKEditor + type: module +-core: 8.x +-core_version_requirement: ^8 || ^9 ++core_version_requirement: ^9.3 || ^10 + dependencies: +-- drupal:ckeditor ++- drupal:ckeditor5 +diff --git a/ckeditor_templates.libraries.yml b/ckeditor_templates.libraries.yml +index 6130ff9..b5ea02b 100644 +--- a/ckeditor_templates.libraries.yml ++++ b/ckeditor_templates.libraries.yml +@@ -1,12 +1,16 @@ + ckeditor.templates.dialog: +- version: 1.x ++ version: 2.x + css: + theme: +- css/ckeditor_templates.css: {} ++ css/cke_templates.dialog.css: {minified: true} + js: +- js/ckeditor_templates.dialog.js: {} ++ js/dist/ckeditorTemplates.js: {} ++ dependencies: ++ - ckeditor5/ckeditor5 ++ - editor/drupal.editor.dialog + + ckeditor.templates.admin: +- version: 1.x +- js: +- js/ckeditor_templates.admin.js: {} ++ version: 2.x ++ css: ++ theme: ++ css/cke_templates.admin.css: {} +diff --git a/ckeditor_templates.links.action.yml b/ckeditor_templates.links.action.yml +new file mode 100644 +index 0000000..52df8f1 +--- /dev/null ++++ b/ckeditor_templates.links.action.yml +@@ -0,0 +1,5 @@ ++entity.ckeditor_templates.add_form: ++ route_name: 'entity.ckeditor_templates.add_form' ++ title: 'Add Template' ++ appears_on: ++ - entity.ckeditor_templates.collection +diff --git a/ckeditor_templates.links.menu.yml b/ckeditor_templates.links.menu.yml +new file mode 100644 +index 0000000..938e2e5 +--- /dev/null ++++ b/ckeditor_templates.links.menu.yml +@@ -0,0 +1,5 @@ ++entity.ckeditor_templates.overview: ++ title: CKEditor Templates ++ parent: system.admin_config_content ++ description: 'List of CKEditor Templates to be used when editing texts.' ++ route_name: entity.ckeditor_templates.collection +diff --git a/ckeditor_templates.permissions.yml b/ckeditor_templates.permissions.yml +new file mode 100644 +index 0000000..faadbaa +--- /dev/null ++++ b/ckeditor_templates.permissions.yml +@@ -0,0 +1,2 @@ ++administer ckeditor templates: ++ title: 'Administer CKEditor Templates' +diff --git a/ckeditor_templates.routing.yml b/ckeditor_templates.routing.yml +new file mode 100644 +index 0000000..1e41357 +--- /dev/null ++++ b/ckeditor_templates.routing.yml +@@ -0,0 +1,38 @@ ++ckeditor_templates.selector: ++ path: '/admin/config/content/ckeditor-templates/template-selector/{editor_id}' ++ defaults: ++ _form: '\Drupal\ckeditor_templates\Form\CKEditorTemplatesDialogForm' ++ requirements: ++ _permission: 'use text format advanced' ++ ++entity.ckeditor_templates.collection: ++ path: '/admin/config/content/ckeditor-templates' ++ defaults: ++ _entity_list: 'ckeditor_templates' ++ _title: 'CKEditor Template Configuration' ++ requirements: ++ _permission: 'administer ckeditor templates' ++ ++entity.ckeditor_templates.add_form: ++ path: '/admin/config/content/ckeditor-templates/add' ++ defaults: ++ _entity_form: 'ckeditor_templates.add' ++ _title: 'Add a CKEditor Template' ++ requirements: ++ _permission: 'administer ckeditor templates' ++ ++entity.ckeditor_templates.edit_form: ++ path: '/admin/config/content/ckeditor-templates/{ckeditor_templates}' ++ defaults: ++ _entity_form: 'ckeditor_templates.edit' ++ _title: 'Edit a CKEditor Template' ++ requirements: ++ _permission: 'administer ckeditor templates' ++ ++entity.ckeditor_templates.delete_form: ++ path: '/admin/config/content/ckeditor-templates/{ckeditor_templates}/delete' ++ defaults: ++ _entity_form: 'ckeditor_templates.delete' ++ _title: 'Delete a CKEditor Template' ++ requirements: ++ _permission: 'administer ckeditor templates' +diff --git a/config/schema/ckeditor_templates.schema.yml b/config/schema/ckeditor_templates.schema.yml +new file mode 100644 +index 0000000..ae7514b +--- /dev/null ++++ b/config/schema/ckeditor_templates.schema.yml +@@ -0,0 +1,40 @@ ++ckeditor_templates.ckeditor_templates.*: ++ type: config_entity ++ label: CKEditor Template ++ mapping: ++ id: ++ type: string ++ label: ID ++ label: ++ type: label ++ label: Title ++ status: ++ type: boolean ++ label: Enabled ++ description: ++ type: string ++ label: Description ++ thumb: ++ type: sequence ++ label: Icon/Image ++ code: ++ type: string ++ label: HTML Code ++ formats: ++ type: sequence ++ label: Available for ++ weight: ++ type: integer ++ label: Weight ++ uuid: ++ type: string ++ ++ckeditor5.plugin.ckeditor_templates_plugin: ++ type: mapping ++ label: Replace Content ++ mapping: ++ replace_content: ++ type: boolean ++ label: 'Replace content' ++ constraints: ++ NotNull: [] +diff --git a/css/README.md b/css/README.md +new file mode 100644 +index 0000000..e78cc75 +--- /dev/null ++++ b/css/README.md +@@ -0,0 +1,4 @@ ++### Important ++ ++The **cke_templates.dialog.css** file in this folder is automatically generated by running the command ++`npm run build`. +diff --git a/css/cke_templates.admin.css b/css/cke_templates.admin.css +new file mode 100644 +index 0000000..cd52fb2 +--- /dev/null ++++ b/css/cke_templates.admin.css +@@ -0,0 +1 @@ ++.ckeditor5-toolbar-button-ckeditorTemplates {background-image: url(../js/plugin/theme/icons/templates.svg)} +diff --git a/css/cke_templates.dialog.css b/css/cke_templates.dialog.css +new file mode 100644 +index 0000000..d2bfc0f +--- /dev/null ++++ b/css/cke_templates.dialog.css +@@ -0,0 +1 @@ ++.ckeditor-templates-widget-modal .form-radios{margin:0;padding:0}.ckeditor-templates-widget-modal .form-radios .form-type-radio.form-item-templates,.ckeditor-templates-widget-modal .form-radios .form-type--radio.form-item--templates{margin:0;padding:0}.ckeditor-templates-widget-modal .form-radios .form-type-radio.form-item-templates input,.ckeditor-templates-widget-modal .form-radios .form-type--radio.form-item--templates input{display:none}.ckeditor-templates-widget-modal .form-radios .form-type-radio.form-item-templates label,.ckeditor-templates-widget-modal .form-radios .form-type--radio.form-item--templates label{display:flex;margin-top:.75rem;padding:.75rem;border:#bcbcbc 1px solid;align-items:flex-start;user-select:none}.ckeditor-templates-widget-modal .form-radios .form-type-radio.form-item-templates label:hover,.ckeditor-templates-widget-modal .form-radios .form-type--radio.form-item--templates label:hover{background-color:#efefef}.ckeditor-templates-widget-modal .form-radios .form-type-radio.form-item-templates label img,.ckeditor-templates-widget-modal .form-radios .form-type--radio.form-item--templates label img{width:5rem;margin-right:.75rem}.ckeditor-templates-widget-modal .form-radios .form-type-radio.form-item-templates label div,.ckeditor-templates-widget-modal .form-radios .form-type--radio.form-item--templates label div{line-height:1.2rem}.ckeditor-templates-widget-modal .form-radios .form-type-radio.form-item-templates label div strong,.ckeditor-templates-widget-modal .form-radios .form-type--radio.form-item--templates label div strong{display:block}.ckeditor-templates-widget-modal .form-radios .form-type-radio.form-item-templates input:checked+label,.ckeditor-templates-widget-modal .form-radios .form-type--radio.form-item--templates input:checked+label{border:#f93 1px solid;background-color:#fffacd} +diff --git a/css/ckeditor_templates.css b/css/ckeditor_templates.css +deleted file mode 100644 +index 70a2f30..0000000 +--- a/css/ckeditor_templates.css ++++ /dev/null +@@ -1,8 +0,0 @@ +-.cke_templates_dialog .cke_dialog_ui_checkbox input { +- vertical-align: middle; +-} +- +-/* Set correct alignment for the "Replace actual content" checkbox */ +-.cke_reset_all .cke_templates_dialog .cke_dialog_ui_checkbox label { +- display: inline-block; +-} +diff --git a/js/ckeditor_templates.admin.js b/js/ckeditor_templates.admin.js +deleted file mode 100644 +index 372e6d8..0000000 +--- a/js/ckeditor_templates.admin.js ++++ /dev/null +@@ -1,32 +0,0 @@ +-/** +- * @file +- * CKEditor 'templates' plugin admin behavior. +- */ +- +-(function ($, Drupal, drupalSettings) { +- +- 'use strict'; +- +- /** +- * Provides the summary for the "templates" plugin settings vertical tab. +- * +- * @type {Drupal~behavior} +- * +- * @prop {Drupal~behaviorAttach} attach +- * Attaches summary behaviour to the "templates" settings vertical tab. +- */ +- Drupal.behaviors.ckeditorTemplatesSettingsSummary = { +- attach: function () { +- $('[data-ckeditor-plugin-id="templates"]').drupalSetSummary(function (context) { +- var templatePathValue = $('input[name="editor[settings][plugins][templates][template_path]').val(); +- var replaceContentValue = $('input[name="editor[settings][plugins][templates][replace_content]').is(':checked'); +- +- var templatePathOutput = templatePathValue ? 'Template file overridden.' : 'Default or theme template file.'; +- var replaceContentOutput = replaceContentValue ? '"Replace content" checked' : '"Replace content" unchecked'; +- +- return templatePathOutput + '
' + replaceContentOutput; +- }); +- } +- }; +- +-})(jQuery, Drupal, drupalSettings); +diff --git a/js/ckeditor_templates.dialog.js b/js/ckeditor_templates.dialog.js +deleted file mode 100644 +index 58cfa0c..0000000 +--- a/js/ckeditor_templates.dialog.js ++++ /dev/null +@@ -1,22 +0,0 @@ +-/** +- * @file +- * Override ckeditor template dialog style. +- */ +- +-(function (CKEDITOR) { +- +- 'use strict'; +- +- CKEDITOR.on('dialogDefinition', function (ev) { +- var dialogName = ev.data.name; +- var dialog = ev.data.definition.dialog; +- +- if (dialogName === 'templates') { +- dialog.on('show', function () { +- var dialogElement = dialog.getElement().getFirst(); +- dialogElement.addClass('cke_templates_dialog'); +- }); +- } +- }); +- +-})(CKEDITOR); +diff --git a/js/dist/ckeditorTemplates.js b/js/dist/ckeditorTemplates.js +new file mode 100644 +index 0000000..d56d71c +--- /dev/null ++++ b/js/dist/ckeditorTemplates.js +@@ -0,0 +1 @@ ++!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.CKEditor5=t():(e.CKEditor5=e.CKEditor5||{},e.CKEditor5.ckeditorTemplates=t())}(self,(()=>(()=>{var e={"ckeditor5/src/core.js":(e,t,o)=>{e.exports=o("dll-reference CKEditor5.dll")("./src/core.js")},"ckeditor5/src/ui.js":(e,t,o)=>{e.exports=o("dll-reference CKEditor5.dll")("./src/ui.js")},"dll-reference CKEditor5.dll":e=>{"use strict";e.exports=CKEditor5.dll}},t={};function o(r){var s=t[r];if(void 0!==s)return s.exports;var i=t[r]={exports:{}};return e[r](i,i.exports,o),i.exports}o.d=(e,t)=>{for(var r in t)o.o(t,r)&&!o.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},o.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t);var r={};return(()=>{"use strict";o.d(r,{default:()=>d});var e=o("ckeditor5/src/core.js"),t=o("ckeditor5/src/ui.js");class s extends e.Plugin{init(){const e=this.editor,o=this.editor.config.get("ckeditorTemplates");o&&o.openDialog&&o.dialogSettings&&o.dialogUrl&&e.ui.componentFactory.add("ckeditorTemplates",(r=>{const s=new t.ButtonView(r);s.set({label:Drupal.t("Templates"),icon:'\n',tooltip:!0});const i=e.commands.get("ckeditorTemplates");return s.bind("isOn","isEnabled").to(i,"value","isEnabled"),this.listenTo(s,"execute",(()=>{const t=o.dialogUrl,r=o.dialogSettings;o.openDialog(t,(({htmlCode:t,replace:o})=>{e.execute("ckeditorTemplates",t,o)}),r)})),s}))}}class i extends e.Command{refresh(){const e=this.editor.model,t=e.document.selection,o=e.schema.findAllowedParent(t.getFirstPosition(),"ckeditorTemplates");this.isEnabled=!!o}execute(e,t){const o=this.editor,r=o.data;if(t)r.set(e);else{const t=o.model;t.change((()=>{const o=r.processor.toView(e),s=r.toModel(o);t.insertContent(s)}))}}}class n extends e.Plugin{static get requires(){return[i]}init(){const e=this.editor,t="ckeditorTemplates";this.editor.model.schema.register(t,{allowWhere:"$block",isObject:!0,isContent:!0,isBlock:!0}),this.editor.commands.add(t,new i(e))}static get pluginName(){return"ckeditorTemplatesEditing"}}class l extends e.Plugin{static get requires(){return[s,n]}static get pluginName(){return"ckeditorTemplates"}}const d={CKEditorTemplates:l}})(),r=r.default})())); +\ No newline at end of file +diff --git a/js/plugin/src/app.js b/js/plugin/src/app.js +new file mode 100644 +index 0000000..8634917 +--- /dev/null ++++ b/js/plugin/src/app.js +@@ -0,0 +1,6 @@ ++import CKEditorTemplates from './ckeditorTemplates'; ++import './../../../sass/dialog.scss'; ++ ++export default { ++ CKEditorTemplates ++}; +diff --git a/js/plugin/src/ckeditorTemplates.js b/js/plugin/src/ckeditorTemplates.js +new file mode 100644 +index 0000000..ec7505f +--- /dev/null ++++ b/js/plugin/src/ckeditorTemplates.js +@@ -0,0 +1,26 @@ ++import { Plugin } from 'ckeditor5/src/core'; ++import CKEditorTemplatesUI from './ckeditorTemplatesUI'; ++import CKEditorTemplatesEditing from './ckeditorTemplatesEditing'; ++ ++/** ++ * Generates a CKEditor 5 plugin. ++ */ ++export default class CKEditorTemplates extends Plugin { ++ ++ /** ++ * @inheritdoc ++ */ ++ static get requires() { ++ return [ ++ CKEditorTemplatesUI, ++ CKEditorTemplatesEditing ++ ]; ++ } ++ ++ /** ++ * @inheritdoc ++ */ ++ static get pluginName() { ++ return 'ckeditorTemplates'; ++ } ++} +diff --git a/js/plugin/src/ckeditorTemplatesCommand.js b/js/plugin/src/ckeditorTemplatesCommand.js +new file mode 100644 +index 0000000..33888a5 +--- /dev/null ++++ b/js/plugin/src/ckeditorTemplatesCommand.js +@@ -0,0 +1,41 @@ ++import { Command } from 'ckeditor5/src/core'; ++ ++/** ++ * Command for injecting code into the CKEditor. ++ */ ++export default class CKEditorTemplatesCommand extends Command { ++ ++ /** ++ * @inheritdoc ++ */ ++ refresh() { ++ const model = this.editor.model; ++ const selection = model.document.selection; ++ const allowedParent = model.schema.findAllowedParent( ++ selection.getFirstPosition(), ++ 'ckeditorTemplates' ++ ); ++ this.isEnabled = !!allowedParent; ++ } ++ ++ /** ++ * @inheritdoc ++ */ ++ execute(htmlCode, replace) { ++ const editor = this.editor; ++ const data = editor.data; ++ ++ if (replace) { ++ data.set(htmlCode); ++ } ++ else { ++ const model = editor.model; ++ model.change(() => { ++ const viewFragment = data.processor.toView(htmlCode); ++ const modelFragment = data.toModel(viewFragment); ++ model.insertContent(modelFragment); ++ }); ++ } ++ } ++ ++} +diff --git a/js/plugin/src/ckeditorTemplatesEditing.js b/js/plugin/src/ckeditorTemplatesEditing.js +new file mode 100644 +index 0000000..b8b387e +--- /dev/null ++++ b/js/plugin/src/ckeditorTemplatesEditing.js +@@ -0,0 +1,42 @@ ++import { Plugin } from 'ckeditor5/src/core'; ++import CKEditorTemplatesCommand from './ckeditorTemplatesCommand'; ++ ++/** ++ * Handles the plugin functionality. ++ */ ++export default class CKEditorTemplatesEditing extends Plugin { ++ ++ /** ++ * @inheritdoc ++ */ ++ static get requires() { ++ return [ ++ CKEditorTemplatesCommand ++ ]; ++ } ++ ++ /** ++ * @inheritdoc ++ */ ++ init() { ++ const editor = this.editor; ++ const plugin = 'ckeditorTemplates'; ++ ++ const schema = { ++ allowWhere: '$block', ++ isObject: true, ++ isContent: true, ++ isBlock: true ++ }; ++ ++ this.editor.model.schema.register(plugin, schema); ++ this.editor.commands.add(plugin, new CKEditorTemplatesCommand(editor)); ++ } ++ ++ /** ++ * @inheritdoc ++ */ ++ static get pluginName() { ++ return 'ckeditorTemplatesEditing'; ++ } ++} +diff --git a/js/plugin/src/ckeditorTemplatesUI.js b/js/plugin/src/ckeditorTemplatesUI.js +new file mode 100644 +index 0000000..5389325 +--- /dev/null ++++ b/js/plugin/src/ckeditorTemplatesUI.js +@@ -0,0 +1,51 @@ ++import { Plugin } from 'ckeditor5/src/core'; ++import { ButtonView } from 'ckeditor5/src/ui'; ++import CKEditorTemplatesIcon from '../theme/icons/templates.svg'; ++ ++/** ++ * Generates a toolbar button. ++ */ ++export default class EmbeddedContentUI extends Plugin { ++ ++ /** ++ * @inheritdoc ++ */ ++ init() { ++ const editor = this.editor; ++ ++ // Gets the options from the Drupal plugin. ++ const dialogOptions = this.editor.config.get('ckeditorTemplates'); ++ if (!dialogOptions || !dialogOptions.openDialog || !dialogOptions.dialogSettings || !dialogOptions.dialogUrl) { ++ return; ++ } ++ ++ // Adds a button to the CKEditor toolbar. ++ editor.ui.componentFactory.add('ckeditorTemplates', (locale) => { ++ ++ // Generates a button view. ++ const buttonView = new ButtonView(locale); ++ buttonView.set({ ++ label: Drupal.t('Templates'), ++ icon: CKEditorTemplatesIcon, ++ tooltip: true ++ }); ++ ++ // Adds a command object to the button. ++ const command = editor.commands.get('ckeditorTemplates'); ++ buttonView.bind('isOn', 'isEnabled').to(command, 'value', 'isEnabled'); ++ ++ // Adds a listener to the button click. ++ this.listenTo(buttonView, 'execute', () => { ++ const url = dialogOptions.dialogUrl; ++ const settings = dialogOptions.dialogSettings; ++ const callback = ({ htmlCode, replace }) => { ++ editor.execute('ckeditorTemplates', htmlCode, replace); ++ }; ++ ++ dialogOptions.openDialog(url, callback, settings); ++ }); ++ ++ return buttonView; ++ }); ++ } ++} +diff --git a/js/plugin/theme/icons/templates.svg b/js/plugin/theme/icons/templates.svg +new file mode 100644 +index 0000000..b60c549 +--- /dev/null ++++ b/js/plugin/theme/icons/templates.svg +@@ -0,0 +1 @@ ++ +diff --git a/js/plugin/theme/images/placeholder.svg b/js/plugin/theme/images/placeholder.svg +new file mode 100644 +index 0000000..20c435c +--- /dev/null ++++ b/js/plugin/theme/images/placeholder.svg +@@ -0,0 +1 @@ ++ +diff --git a/package-lock.json b/package-lock.json +new file mode 100644 +index 0000000..6b5aeaf +--- /dev/null ++++ b/package-lock.json +@@ -0,0 +1,4455 @@ ++{ ++ "name": "ckeditor5-templates", ++ "version": "1.0.0", ++ "lockfileVersion": 3, ++ "requires": true, ++ "packages": { ++ "": { ++ "name": "ckeditor5-templates", ++ "version": "1.0.0", ++ "license": "GPL-2.0-or-later", ++ "dependencies": { ++ "@ckeditor/ckeditor5-basic-styles": "^35.4.0", ++ "@ckeditor/ckeditor5-dev-utils": "^32.0.2", ++ "@ckeditor/ckeditor5-editor-classic": "^35.4.0", ++ "@ckeditor/ckeditor5-engine": "^35.4.0", ++ "@ckeditor/ckeditor5-essentials": "^35.4.0", ++ "@ckeditor/ckeditor5-html-support": "^35.4.0", ++ "@ckeditor/ckeditor5-paragraph": "^35.4.0", ++ "@ckeditor/ckeditor5-theme-lark": "^35.4.0", ++ "ckeditor5": "^35.4.0", ++ "css-loader": "^5.2.7", ++ "mini-css-extract-plugin": "^2.7.2", ++ "postcss-loader": "^4.3.0", ++ "raw-loader": "^4.0.2", ++ "sass": "^1.58.0", ++ "sass-loader": "^13.2.0", ++ "style-loader": "^2.0.0", ++ "terser-webpack-plugin": "^5.3.6", ++ "webpack": "^5.75.0" ++ }, ++ "devDependencies": { ++ "webpack-cli": "^5.0.1" ++ } ++ }, ++ "node_modules/@babel/code-frame": { ++ "version": "7.18.6", ++ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", ++ "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", ++ "dependencies": { ++ "@babel/highlight": "^7.18.6" ++ }, ++ "engines": { ++ "node": ">=6.9.0" ++ } ++ }, ++ "node_modules/@babel/generator": { ++ "version": "7.20.14", ++ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.14.tgz", ++ "integrity": "sha512-AEmuXHdcD3A52HHXxaTmYlb8q/xMEhoRP67B3T4Oq7lbmSoqroMZzjnGj3+i1io3pdnF8iBYVu4Ilj+c4hBxYg==", ++ "dependencies": { ++ "@babel/types": "^7.20.7", ++ "@jridgewell/gen-mapping": "^0.3.2", ++ "jsesc": "^2.5.1" ++ }, ++ "engines": { ++ "node": ">=6.9.0" ++ } ++ }, ++ "node_modules/@babel/helper-environment-visitor": { ++ "version": "7.18.9", ++ "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", ++ "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", ++ "engines": { ++ "node": ">=6.9.0" ++ } ++ }, ++ "node_modules/@babel/helper-function-name": { ++ "version": "7.19.0", ++ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", ++ "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", ++ "dependencies": { ++ "@babel/template": "^7.18.10", ++ "@babel/types": "^7.19.0" ++ }, ++ "engines": { ++ "node": ">=6.9.0" ++ } ++ }, ++ "node_modules/@babel/helper-hoist-variables": { ++ "version": "7.18.6", ++ "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", ++ "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", ++ "dependencies": { ++ "@babel/types": "^7.18.6" ++ }, ++ "engines": { ++ "node": ">=6.9.0" ++ } ++ }, ++ "node_modules/@babel/helper-split-export-declaration": { ++ "version": "7.18.6", ++ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", ++ "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", ++ "dependencies": { ++ "@babel/types": "^7.18.6" ++ }, ++ "engines": { ++ "node": ">=6.9.0" ++ } ++ }, ++ "node_modules/@babel/helper-string-parser": { ++ "version": "7.19.4", ++ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", ++ "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", ++ "engines": { ++ "node": ">=6.9.0" ++ } ++ }, ++ "node_modules/@babel/helper-validator-identifier": { ++ "version": "7.19.1", ++ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", ++ "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", ++ "engines": { ++ "node": ">=6.9.0" ++ } ++ }, ++ "node_modules/@babel/highlight": { ++ "version": "7.18.6", ++ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", ++ "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", ++ "dependencies": { ++ "@babel/helper-validator-identifier": "^7.18.6", ++ "chalk": "^2.0.0", ++ "js-tokens": "^4.0.0" ++ }, ++ "engines": { ++ "node": ">=6.9.0" ++ } ++ }, ++ "node_modules/@babel/highlight/node_modules/ansi-styles": { ++ "version": "3.2.1", ++ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", ++ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", ++ "dependencies": { ++ "color-convert": "^1.9.0" ++ }, ++ "engines": { ++ "node": ">=4" ++ } ++ }, ++ "node_modules/@babel/highlight/node_modules/chalk": { ++ "version": "2.4.2", ++ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", ++ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", ++ "dependencies": { ++ "ansi-styles": "^3.2.1", ++ "escape-string-regexp": "^1.0.5", ++ "supports-color": "^5.3.0" ++ }, ++ "engines": { ++ "node": ">=4" ++ } ++ }, ++ "node_modules/@babel/highlight/node_modules/color-convert": { ++ "version": "1.9.3", ++ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", ++ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", ++ "dependencies": { ++ "color-name": "1.1.3" ++ } ++ }, ++ "node_modules/@babel/highlight/node_modules/color-name": { ++ "version": "1.1.3", ++ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", ++ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" ++ }, ++ "node_modules/@babel/highlight/node_modules/has-flag": { ++ "version": "3.0.0", ++ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", ++ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", ++ "engines": { ++ "node": ">=4" ++ } ++ }, ++ "node_modules/@babel/highlight/node_modules/supports-color": { ++ "version": "5.5.0", ++ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", ++ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", ++ "dependencies": { ++ "has-flag": "^3.0.0" ++ }, ++ "engines": { ++ "node": ">=4" ++ } ++ }, ++ "node_modules/@babel/parser": { ++ "version": "7.20.15", ++ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.15.tgz", ++ "integrity": "sha512-DI4a1oZuf8wC+oAJA9RW6ga3Zbe8RZFt7kD9i4qAspz3I/yHet1VvC3DiSy/fsUvv5pvJuNPh0LPOdCcqinDPg==", ++ "bin": { ++ "parser": "bin/babel-parser.js" ++ }, ++ "engines": { ++ "node": ">=6.0.0" ++ } ++ }, ++ "node_modules/@babel/template": { ++ "version": "7.20.7", ++ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", ++ "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", ++ "dependencies": { ++ "@babel/code-frame": "^7.18.6", ++ "@babel/parser": "^7.20.7", ++ "@babel/types": "^7.20.7" ++ }, ++ "engines": { ++ "node": ">=6.9.0" ++ } ++ }, ++ "node_modules/@babel/traverse": { ++ "version": "7.20.13", ++ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.13.tgz", ++ "integrity": "sha512-kMJXfF0T6DIS9E8cgdLCSAL+cuCK+YEZHWiLK0SXpTo8YRj5lpJu3CDNKiIBCne4m9hhTIqUg6SYTAI39tAiVQ==", ++ "dependencies": { ++ "@babel/code-frame": "^7.18.6", ++ "@babel/generator": "^7.20.7", ++ "@babel/helper-environment-visitor": "^7.18.9", ++ "@babel/helper-function-name": "^7.19.0", ++ "@babel/helper-hoist-variables": "^7.18.6", ++ "@babel/helper-split-export-declaration": "^7.18.6", ++ "@babel/parser": "^7.20.13", ++ "@babel/types": "^7.20.7", ++ "debug": "^4.1.0", ++ "globals": "^11.1.0" ++ }, ++ "engines": { ++ "node": ">=6.9.0" ++ } ++ }, ++ "node_modules/@babel/types": { ++ "version": "7.20.7", ++ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz", ++ "integrity": "sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==", ++ "dependencies": { ++ "@babel/helper-string-parser": "^7.19.4", ++ "@babel/helper-validator-identifier": "^7.19.1", ++ "to-fast-properties": "^2.0.0" ++ }, ++ "engines": { ++ "node": ">=6.9.0" ++ } ++ }, ++ "node_modules/@ckeditor/ckeditor5-basic-styles": { ++ "version": "35.4.0", ++ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-basic-styles/-/ckeditor5-basic-styles-35.4.0.tgz", ++ "integrity": "sha512-6JkoplYMwIHN1E/w3DoY0i95B41sbGwsNAtlvx6qaBvNKkLu4rRCtiBUJDnx8qZxxQXHih5ZOw8bUQHl4mt8hw==", ++ "dependencies": { ++ "ckeditor5": "^35.4.0" ++ }, ++ "engines": { ++ "node": ">=14.0.0", ++ "npm": ">=5.7.1" ++ } ++ }, ++ "node_modules/@ckeditor/ckeditor5-clipboard": { ++ "version": "35.4.0", ++ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-clipboard/-/ckeditor5-clipboard-35.4.0.tgz", ++ "integrity": "sha512-B6rIQxvOrHvO9TZRC8JA0wKk+IfN880UJkYIg1qlhf9HFNVjdVbtHaiCsPD+TzGmQN3XHXfNjgjabGRIn0iZmw==", ++ "dependencies": { ++ "@ckeditor/ckeditor5-core": "^35.4.0", ++ "@ckeditor/ckeditor5-engine": "^35.4.0", ++ "@ckeditor/ckeditor5-utils": "^35.4.0", ++ "@ckeditor/ckeditor5-widget": "^35.4.0", ++ "lodash-es": "^4.17.11" ++ }, ++ "engines": { ++ "node": ">=14.0.0", ++ "npm": ">=5.7.1" ++ } ++ }, ++ "node_modules/@ckeditor/ckeditor5-core": { ++ "version": "35.4.0", ++ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-core/-/ckeditor5-core-35.4.0.tgz", ++ "integrity": "sha512-Rf0H7C4inCj/YC8aii0cT7TC/IuBIQ+tXmu9qd8/1BJ/rz1MCHXtBPApjTbFp33OE3aOFB5+NUaKt05k/dL3OA==", ++ "dependencies": { ++ "@ckeditor/ckeditor5-engine": "^35.4.0", ++ "@ckeditor/ckeditor5-ui": "^35.4.0", ++ "@ckeditor/ckeditor5-utils": "^35.4.0", ++ "lodash-es": "^4.17.15" ++ }, ++ "engines": { ++ "node": ">=14.0.0", ++ "npm": ">=5.7.1" ++ } ++ }, ++ "node_modules/@ckeditor/ckeditor5-dev-translations": { ++ "version": "32.1.2", ++ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-dev-translations/-/ckeditor5-dev-translations-32.1.2.tgz", ++ "integrity": "sha512-TudMnRaiYMTNuDMWExeBh0Mk96GySWzgnh4fkXfoqiABQzd9Pp/Fcl40q0LJl4jtyS3qhQGFz88GxzkxAXXU9Q==", ++ "dependencies": { ++ "@babel/parser": "^7.18.9", ++ "@babel/traverse": "^7.18.9", ++ "chalk": "^4.0.0", ++ "pofile": "^1.0.9", ++ "rimraf": "^3.0.2", ++ "webpack-sources": "^2.0.1" ++ }, ++ "engines": { ++ "node": ">=14.0.0", ++ "npm": ">=5.7.1" ++ } ++ }, ++ "node_modules/@ckeditor/ckeditor5-dev-translations/node_modules/chalk": { ++ "version": "4.1.2", ++ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", ++ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", ++ "dependencies": { ++ "ansi-styles": "^4.1.0", ++ "supports-color": "^7.1.0" ++ }, ++ "engines": { ++ "node": ">=10" ++ }, ++ "funding": { ++ "url": "https://github.com/chalk/chalk?sponsor=1" ++ } ++ }, ++ "node_modules/@ckeditor/ckeditor5-dev-utils": { ++ "version": "32.1.2", ++ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-dev-utils/-/ckeditor5-dev-utils-32.1.2.tgz", ++ "integrity": "sha512-C9c6EnWhOElN5c56xhJ7mYA9AsgZbaME6d8hTGJ43J5ZG6wg7MFwVlRpv0u2unu8whLO6vsjrW7yeqBrFvo65Q==", ++ "dependencies": { ++ "@ckeditor/ckeditor5-dev-translations": "^32.1.2", ++ "chalk": "^3.0.0", ++ "cli-cursor": "^3.1.0", ++ "cli-spinners": "^2.6.1", ++ "cssnano": "^5.0.0", ++ "del": "^5.0.0", ++ "fs-extra": "^8.1.0", ++ "is-interactive": "^1.0.0", ++ "javascript-stringify": "^1.6.0", ++ "postcss": "^8.4.12", ++ "postcss-import": "^14.1.0", ++ "postcss-loader": "^4.3.0", ++ "postcss-mixins": "^9.0.2", ++ "postcss-nesting": "^10.1.4", ++ "raw-loader": "^4.0.1", ++ "shelljs": "^0.8.1", ++ "style-loader": "^2.0.0", ++ "terser-webpack-plugin": "^4.2.3", ++ "through2": "^3.0.1", ++ "ts-loader": "^9.3.0" ++ }, ++ "engines": { ++ "node": ">=14.0.0", ++ "npm": ">=5.7.1" ++ }, ++ "peerDependencies": { ++ "webpack": "^4.43.0 || ^5.24.0" ++ } ++ }, ++ "node_modules/@ckeditor/ckeditor5-dev-utils/node_modules/jest-worker": { ++ "version": "26.6.2", ++ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", ++ "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", ++ "dependencies": { ++ "@types/node": "*", ++ "merge-stream": "^2.0.0", ++ "supports-color": "^7.0.0" ++ }, ++ "engines": { ++ "node": ">= 10.13.0" ++ } ++ }, ++ "node_modules/@ckeditor/ckeditor5-dev-utils/node_modules/p-limit": { ++ "version": "3.1.0", ++ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", ++ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", ++ "dependencies": { ++ "yocto-queue": "^0.1.0" ++ }, ++ "engines": { ++ "node": ">=10" ++ }, ++ "funding": { ++ "url": "https://github.com/sponsors/sindresorhus" ++ } ++ }, ++ "node_modules/@ckeditor/ckeditor5-dev-utils/node_modules/serialize-javascript": { ++ "version": "5.0.1", ++ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", ++ "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", ++ "dependencies": { ++ "randombytes": "^2.1.0" ++ } ++ }, ++ "node_modules/@ckeditor/ckeditor5-dev-utils/node_modules/terser-webpack-plugin": { ++ "version": "4.2.3", ++ "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-4.2.3.tgz", ++ "integrity": "sha512-jTgXh40RnvOrLQNgIkwEKnQ8rmHjHK4u+6UBEi+W+FPmvb+uo+chJXntKe7/3lW5mNysgSWD60KyesnhW8D6MQ==", ++ "dependencies": { ++ "cacache": "^15.0.5", ++ "find-cache-dir": "^3.3.1", ++ "jest-worker": "^26.5.0", ++ "p-limit": "^3.0.2", ++ "schema-utils": "^3.0.0", ++ "serialize-javascript": "^5.0.1", ++ "source-map": "^0.6.1", ++ "terser": "^5.3.4", ++ "webpack-sources": "^1.4.3" ++ }, ++ "engines": { ++ "node": ">= 10.13.0" ++ }, ++ "funding": { ++ "type": "opencollective", ++ "url": "https://opencollective.com/webpack" ++ }, ++ "peerDependencies": { ++ "webpack": "^4.0.0 || ^5.0.0" ++ } ++ }, ++ "node_modules/@ckeditor/ckeditor5-dev-utils/node_modules/webpack-sources": { ++ "version": "1.4.3", ++ "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", ++ "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", ++ "dependencies": { ++ "source-list-map": "^2.0.0", ++ "source-map": "~0.6.1" ++ } ++ }, ++ "node_modules/@ckeditor/ckeditor5-editor-classic": { ++ "version": "35.4.0", ++ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-editor-classic/-/ckeditor5-editor-classic-35.4.0.tgz", ++ "integrity": "sha512-EqAqFD/5oPtDMU2AoH3eJaDplcS8MxfkiRQ5hzeC1JeIPT94w5FCHnB4SAkjLPDnlyZnBWOOYdZSuln2TRIbEw==", ++ "dependencies": { ++ "ckeditor5": "^35.4.0", ++ "lodash-es": "^4.17.15" ++ }, ++ "engines": { ++ "node": ">=14.0.0", ++ "npm": ">=5.7.1" ++ } ++ }, ++ "node_modules/@ckeditor/ckeditor5-engine": { ++ "version": "35.4.0", ++ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-engine/-/ckeditor5-engine-35.4.0.tgz", ++ "integrity": "sha512-67QKtUGJeLM072h9qURvzczYGU3ecuxR9LLmM4dffnV+PBNQ9e8RDCY7PuuEP0pplmAUI6/XqoZJIbk6h7ZV3Q==", ++ "dependencies": { ++ "@ckeditor/ckeditor5-utils": "^35.4.0", ++ "lodash-es": "^4.17.15" ++ }, ++ "engines": { ++ "node": ">=14.0.0", ++ "npm": ">=5.7.1" ++ } ++ }, ++ "node_modules/@ckeditor/ckeditor5-enter": { ++ "version": "35.4.0", ++ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-enter/-/ckeditor5-enter-35.4.0.tgz", ++ "integrity": "sha512-y95RnA/Gw72e220PJKVwNbwPzX4SRs82/rXu1jVyJXty7CcEZqqfyRtW6odICAXr5eKI5XKgzFgpFYULL3D9Nw==", ++ "dependencies": { ++ "@ckeditor/ckeditor5-core": "^35.4.0", ++ "@ckeditor/ckeditor5-engine": "^35.4.0" ++ }, ++ "engines": { ++ "node": ">=14.0.0", ++ "npm": ">=5.7.1" ++ } ++ }, ++ "node_modules/@ckeditor/ckeditor5-essentials": { ++ "version": "35.4.0", ++ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-essentials/-/ckeditor5-essentials-35.4.0.tgz", ++ "integrity": "sha512-tTtTb4NYSQi99LPDzAVUnFhW6iTqSuaylkg0XnDvO2lVR3tAA27gOOjGqc8Ri9NMGGeZkFTvXpnVkXkFnDP2nQ==", ++ "dependencies": { ++ "ckeditor5": "^35.4.0" ++ }, ++ "engines": { ++ "node": ">=14.0.0", ++ "npm": ">=5.7.1" ++ } ++ }, ++ "node_modules/@ckeditor/ckeditor5-html-support": { ++ "version": "35.4.0", ++ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-html-support/-/ckeditor5-html-support-35.4.0.tgz", ++ "integrity": "sha512-h1iV/JQQwqYD6xaVvgIjvx+dat7eZ0jFksEsHhTaYSDX+Qzcr/rFFN3mocWsoaOsn3iZFylOo/dP0NjZm+Yxfw==", ++ "dependencies": { ++ "ckeditor5": "^35.4.0", ++ "lodash-es": "^4.17.15" ++ }, ++ "engines": { ++ "node": ">=14.0.0", ++ "npm": ">=5.7.1" ++ } ++ }, ++ "node_modules/@ckeditor/ckeditor5-paragraph": { ++ "version": "35.4.0", ++ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-paragraph/-/ckeditor5-paragraph-35.4.0.tgz", ++ "integrity": "sha512-8nhkEEFv1WClhH6q/HW8P596d+dlatSVc46kQ2+jGlYirL8P66tV/nK+OiE8z1d897oVr4QPGsqk2qGkRFUChw==", ++ "dependencies": { ++ "@ckeditor/ckeditor5-core": "^35.4.0", ++ "@ckeditor/ckeditor5-ui": "^35.4.0", ++ "@ckeditor/ckeditor5-utils": "^35.4.0" ++ }, ++ "engines": { ++ "node": ">=14.0.0", ++ "npm": ">=5.7.1" ++ } ++ }, ++ "node_modules/@ckeditor/ckeditor5-select-all": { ++ "version": "35.4.0", ++ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-select-all/-/ckeditor5-select-all-35.4.0.tgz", ++ "integrity": "sha512-c+pIIY77SP6ux4/cyD7cCrllQAqtFVSnzNYdy7ygNPqljCGngCnpSV9xfCO/blFo6/zx2vsmzVGdRq3ArzGoMg==", ++ "dependencies": { ++ "@ckeditor/ckeditor5-core": "^35.4.0", ++ "@ckeditor/ckeditor5-ui": "^35.4.0", ++ "@ckeditor/ckeditor5-utils": "^35.4.0" ++ }, ++ "engines": { ++ "node": ">=14.0.0", ++ "npm": ">=5.7.1" ++ } ++ }, ++ "node_modules/@ckeditor/ckeditor5-theme-lark": { ++ "version": "35.4.0", ++ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-theme-lark/-/ckeditor5-theme-lark-35.4.0.tgz", ++ "integrity": "sha512-cf6pJN96KwKrs3KIvxrKR9pGMH2/I6MAFMyliN7O1MbauKeyC6cjwui41Yan10cWwpm6a6PeadyRbwQPa9HUaw==", ++ "dependencies": { ++ "@ckeditor/ckeditor5-ui": "^35.4.0" ++ }, ++ "engines": { ++ "node": ">=14.0.0", ++ "npm": ">=5.7.1" ++ } ++ }, ++ "node_modules/@ckeditor/ckeditor5-typing": { ++ "version": "35.4.0", ++ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-typing/-/ckeditor5-typing-35.4.0.tgz", ++ "integrity": "sha512-Ad/PHWbVWcnAj9oevkkfLqf6CmvCFOti466uhvfOCKRNVf2+/xuGwleOGr8W6Lir/x/qav7ojFjKPKDxqbPXhA==", ++ "dependencies": { ++ "@ckeditor/ckeditor5-core": "^35.4.0", ++ "@ckeditor/ckeditor5-engine": "^35.4.0", ++ "@ckeditor/ckeditor5-utils": "^35.4.0", ++ "lodash-es": "^4.17.15" ++ }, ++ "engines": { ++ "node": ">=14.0.0", ++ "npm": ">=5.7.1" ++ } ++ }, ++ "node_modules/@ckeditor/ckeditor5-ui": { ++ "version": "35.4.0", ++ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-ui/-/ckeditor5-ui-35.4.0.tgz", ++ "integrity": "sha512-0SmYE+k1cYQPqyw2rQsPDV/RpudneBh1bNfiaTOz+rqViJIMe+TxiuK6Fz+znNZ05s0exr+ZHWvMttGqlVoQNw==", ++ "dependencies": { ++ "@ckeditor/ckeditor5-core": "^35.4.0", ++ "@ckeditor/ckeditor5-utils": "^35.4.0", ++ "lodash-es": "^4.17.15" ++ }, ++ "engines": { ++ "node": ">=14.0.0", ++ "npm": ">=5.7.1" ++ } ++ }, ++ "node_modules/@ckeditor/ckeditor5-undo": { ++ "version": "35.4.0", ++ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-undo/-/ckeditor5-undo-35.4.0.tgz", ++ "integrity": "sha512-0RhsK0f/pX/7KB/JXYTLiDOswmUTQ9EKIIuewAwr7LTsBf4Q309FZSFdbeTmc0wIyX33212Xh5xsi3LyG1VJRg==", ++ "dependencies": { ++ "@ckeditor/ckeditor5-core": "^35.4.0", ++ "@ckeditor/ckeditor5-engine": "^35.4.0", ++ "@ckeditor/ckeditor5-ui": "^35.4.0" ++ }, ++ "engines": { ++ "node": ">=14.0.0", ++ "npm": ">=5.7.1" ++ } ++ }, ++ "node_modules/@ckeditor/ckeditor5-upload": { ++ "version": "35.4.0", ++ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-upload/-/ckeditor5-upload-35.4.0.tgz", ++ "integrity": "sha512-+eJAluAc4mAFmx5FNuSGjkCYmbm0V9NpSleubAXEx2e+KNiLarPAnsolwRaAcYXcloNp4C9/l0D+lPEx7VRYtg==", ++ "dependencies": { ++ "@ckeditor/ckeditor5-core": "^35.4.0", ++ "@ckeditor/ckeditor5-ui": "^35.4.0", ++ "@ckeditor/ckeditor5-utils": "^35.4.0" ++ }, ++ "engines": { ++ "node": ">=14.0.0", ++ "npm": ">=5.7.1" ++ } ++ }, ++ "node_modules/@ckeditor/ckeditor5-utils": { ++ "version": "35.4.0", ++ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-utils/-/ckeditor5-utils-35.4.0.tgz", ++ "integrity": "sha512-sFjbb+1VYdLbELDLWVYk86WzVN7Lo3sXHbVhdr8+kc0Ufxdr3mTFHDAkiymFt2fs1FOB5gZyWJlJU+EeJnhKUw==", ++ "dependencies": { ++ "lodash-es": "^4.17.15" ++ }, ++ "engines": { ++ "node": ">=14.0.0", ++ "npm": ">=5.7.1" ++ } ++ }, ++ "node_modules/@ckeditor/ckeditor5-widget": { ++ "version": "35.4.0", ++ "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-widget/-/ckeditor5-widget-35.4.0.tgz", ++ "integrity": "sha512-SNYOXXWu7XV1BZET+ar0Cea25836vzNtUqXlDPwBx/jrmK86b8GMbFR99P2bUG0NvtIsH5cSk7XCmnxb4ZQ6wA==", ++ "dependencies": { ++ "@ckeditor/ckeditor5-core": "^35.4.0", ++ "@ckeditor/ckeditor5-engine": "^35.4.0", ++ "@ckeditor/ckeditor5-enter": "^35.4.0", ++ "@ckeditor/ckeditor5-typing": "^35.4.0", ++ "@ckeditor/ckeditor5-ui": "^35.4.0", ++ "@ckeditor/ckeditor5-utils": "^35.4.0", ++ "lodash-es": "^4.17.15" ++ }, ++ "engines": { ++ "node": ">=14.0.0", ++ "npm": ">=5.7.1" ++ } ++ }, ++ "node_modules/@csstools/selector-specificity": { ++ "version": "2.1.1", ++ "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.1.1.tgz", ++ "integrity": "sha512-jwx+WCqszn53YHOfvFMJJRd/B2GqkCBt+1MJSG6o5/s8+ytHMvDZXsJgUEWLk12UnLd7HYKac4BYU5i/Ron1Cw==", ++ "engines": { ++ "node": "^14 || ^16 || >=18" ++ }, ++ "funding": { ++ "type": "opencollective", ++ "url": "https://opencollective.com/csstools" ++ }, ++ "peerDependencies": { ++ "postcss": "^8.4", ++ "postcss-selector-parser": "^6.0.10" ++ } ++ }, ++ "node_modules/@discoveryjs/json-ext": { ++ "version": "0.5.7", ++ "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", ++ "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", ++ "dev": true, ++ "engines": { ++ "node": ">=10.0.0" ++ } ++ }, ++ "node_modules/@gar/promisify": { ++ "version": "1.1.3", ++ "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", ++ "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==" ++ }, ++ "node_modules/@jridgewell/gen-mapping": { ++ "version": "0.3.2", ++ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", ++ "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", ++ "dependencies": { ++ "@jridgewell/set-array": "^1.0.1", ++ "@jridgewell/sourcemap-codec": "^1.4.10", ++ "@jridgewell/trace-mapping": "^0.3.9" ++ }, ++ "engines": { ++ "node": ">=6.0.0" ++ } ++ }, ++ "node_modules/@jridgewell/resolve-uri": { ++ "version": "3.1.0", ++ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", ++ "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", ++ "engines": { ++ "node": ">=6.0.0" ++ } ++ }, ++ "node_modules/@jridgewell/set-array": { ++ "version": "1.1.2", ++ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", ++ "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", ++ "engines": { ++ "node": ">=6.0.0" ++ } ++ }, ++ "node_modules/@jridgewell/source-map": { ++ "version": "0.3.2", ++ "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz", ++ "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==", ++ "dependencies": { ++ "@jridgewell/gen-mapping": "^0.3.0", ++ "@jridgewell/trace-mapping": "^0.3.9" ++ } ++ }, ++ "node_modules/@jridgewell/sourcemap-codec": { ++ "version": "1.4.14", ++ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", ++ "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" ++ }, ++ "node_modules/@jridgewell/trace-mapping": { ++ "version": "0.3.17", ++ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", ++ "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", ++ "dependencies": { ++ "@jridgewell/resolve-uri": "3.1.0", ++ "@jridgewell/sourcemap-codec": "1.4.14" ++ } ++ }, ++ "node_modules/@nodelib/fs.scandir": { ++ "version": "2.1.5", ++ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", ++ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", ++ "dependencies": { ++ "@nodelib/fs.stat": "2.0.5", ++ "run-parallel": "^1.1.9" ++ }, ++ "engines": { ++ "node": ">= 8" ++ } ++ }, ++ "node_modules/@nodelib/fs.stat": { ++ "version": "2.0.5", ++ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", ++ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", ++ "engines": { ++ "node": ">= 8" ++ } ++ }, ++ "node_modules/@nodelib/fs.walk": { ++ "version": "1.2.8", ++ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", ++ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", ++ "dependencies": { ++ "@nodelib/fs.scandir": "2.1.5", ++ "fastq": "^1.6.0" ++ }, ++ "engines": { ++ "node": ">= 8" ++ } ++ }, ++ "node_modules/@npmcli/fs": { ++ "version": "1.1.1", ++ "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz", ++ "integrity": "sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==", ++ "dependencies": { ++ "@gar/promisify": "^1.0.1", ++ "semver": "^7.3.5" ++ } ++ }, ++ "node_modules/@npmcli/move-file": { ++ "version": "1.1.2", ++ "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz", ++ "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==", ++ "deprecated": "This functionality has been moved to @npmcli/fs", ++ "dependencies": { ++ "mkdirp": "^1.0.4", ++ "rimraf": "^3.0.2" ++ }, ++ "engines": { ++ "node": ">=10" ++ } ++ }, ++ "node_modules/@trysound/sax": { ++ "version": "0.2.0", ++ "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", ++ "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", ++ "engines": { ++ "node": ">=10.13.0" ++ } ++ }, ++ "node_modules/@types/eslint": { ++ "version": "8.21.0", ++ "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.21.0.tgz", ++ "integrity": "sha512-35EhHNOXgxnUgh4XCJsGhE7zdlDhYDN/aMG6UbkByCFFNgQ7b3U+uVoqBpicFydR8JEfgdjCF7SJ7MiJfzuiTA==", ++ "dependencies": { ++ "@types/estree": "*", ++ "@types/json-schema": "*" ++ } ++ }, ++ "node_modules/@types/eslint-scope": { ++ "version": "3.7.4", ++ "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz", ++ "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==", ++ "dependencies": { ++ "@types/eslint": "*", ++ "@types/estree": "*" ++ } ++ }, ++ "node_modules/@types/estree": { ++ "version": "0.0.51", ++ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz", ++ "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==" ++ }, ++ "node_modules/@types/glob": { ++ "version": "7.2.0", ++ "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", ++ "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", ++ "dependencies": { ++ "@types/minimatch": "*", ++ "@types/node": "*" ++ } ++ }, ++ "node_modules/@types/json-schema": { ++ "version": "7.0.11", ++ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", ++ "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==" ++ }, ++ "node_modules/@types/minimatch": { ++ "version": "5.1.2", ++ "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", ++ "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==" ++ }, ++ "node_modules/@types/node": { ++ "version": "18.13.0", ++ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.13.0.tgz", ++ "integrity": "sha512-gC3TazRzGoOnoKAhUx+Q0t8S9Tzs74z7m0ipwGpSqQrleP14hKxP4/JUeEQcD3W1/aIpnWl8pHowI7WokuZpXg==" ++ }, ++ "node_modules/@types/parse-json": { ++ "version": "4.0.0", ++ "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", ++ "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" ++ }, ++ "node_modules/@webassemblyjs/ast": { ++ "version": "1.11.1", ++ "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", ++ "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==", ++ "dependencies": { ++ "@webassemblyjs/helper-numbers": "1.11.1", ++ "@webassemblyjs/helper-wasm-bytecode": "1.11.1" ++ } ++ }, ++ "node_modules/@webassemblyjs/floating-point-hex-parser": { ++ "version": "1.11.1", ++ "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz", ++ "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==" ++ }, ++ "node_modules/@webassemblyjs/helper-api-error": { ++ "version": "1.11.1", ++ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz", ++ "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==" ++ }, ++ "node_modules/@webassemblyjs/helper-buffer": { ++ "version": "1.11.1", ++ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz", ++ "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==" ++ }, ++ "node_modules/@webassemblyjs/helper-numbers": { ++ "version": "1.11.1", ++ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz", ++ "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==", ++ "dependencies": { ++ "@webassemblyjs/floating-point-hex-parser": "1.11.1", ++ "@webassemblyjs/helper-api-error": "1.11.1", ++ "@xtuc/long": "4.2.2" ++ } ++ }, ++ "node_modules/@webassemblyjs/helper-wasm-bytecode": { ++ "version": "1.11.1", ++ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz", ++ "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==" ++ }, ++ "node_modules/@webassemblyjs/helper-wasm-section": { ++ "version": "1.11.1", ++ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz", ++ "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==", ++ "dependencies": { ++ "@webassemblyjs/ast": "1.11.1", ++ "@webassemblyjs/helper-buffer": "1.11.1", ++ "@webassemblyjs/helper-wasm-bytecode": "1.11.1", ++ "@webassemblyjs/wasm-gen": "1.11.1" ++ } ++ }, ++ "node_modules/@webassemblyjs/ieee754": { ++ "version": "1.11.1", ++ "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz", ++ "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==", ++ "dependencies": { ++ "@xtuc/ieee754": "^1.2.0" ++ } ++ }, ++ "node_modules/@webassemblyjs/leb128": { ++ "version": "1.11.1", ++ "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz", ++ "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==", ++ "dependencies": { ++ "@xtuc/long": "4.2.2" ++ } ++ }, ++ "node_modules/@webassemblyjs/utf8": { ++ "version": "1.11.1", ++ "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz", ++ "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==" ++ }, ++ "node_modules/@webassemblyjs/wasm-edit": { ++ "version": "1.11.1", ++ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz", ++ "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==", ++ "dependencies": { ++ "@webassemblyjs/ast": "1.11.1", ++ "@webassemblyjs/helper-buffer": "1.11.1", ++ "@webassemblyjs/helper-wasm-bytecode": "1.11.1", ++ "@webassemblyjs/helper-wasm-section": "1.11.1", ++ "@webassemblyjs/wasm-gen": "1.11.1", ++ "@webassemblyjs/wasm-opt": "1.11.1", ++ "@webassemblyjs/wasm-parser": "1.11.1", ++ "@webassemblyjs/wast-printer": "1.11.1" ++ } ++ }, ++ "node_modules/@webassemblyjs/wasm-gen": { ++ "version": "1.11.1", ++ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz", ++ "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==", ++ "dependencies": { ++ "@webassemblyjs/ast": "1.11.1", ++ "@webassemblyjs/helper-wasm-bytecode": "1.11.1", ++ "@webassemblyjs/ieee754": "1.11.1", ++ "@webassemblyjs/leb128": "1.11.1", ++ "@webassemblyjs/utf8": "1.11.1" ++ } ++ }, ++ "node_modules/@webassemblyjs/wasm-opt": { ++ "version": "1.11.1", ++ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz", ++ "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==", ++ "dependencies": { ++ "@webassemblyjs/ast": "1.11.1", ++ "@webassemblyjs/helper-buffer": "1.11.1", ++ "@webassemblyjs/wasm-gen": "1.11.1", ++ "@webassemblyjs/wasm-parser": "1.11.1" ++ } ++ }, ++ "node_modules/@webassemblyjs/wasm-parser": { ++ "version": "1.11.1", ++ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz", ++ "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==", ++ "dependencies": { ++ "@webassemblyjs/ast": "1.11.1", ++ "@webassemblyjs/helper-api-error": "1.11.1", ++ "@webassemblyjs/helper-wasm-bytecode": "1.11.1", ++ "@webassemblyjs/ieee754": "1.11.1", ++ "@webassemblyjs/leb128": "1.11.1", ++ "@webassemblyjs/utf8": "1.11.1" ++ } ++ }, ++ "node_modules/@webassemblyjs/wast-printer": { ++ "version": "1.11.1", ++ "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz", ++ "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==", ++ "dependencies": { ++ "@webassemblyjs/ast": "1.11.1", ++ "@xtuc/long": "4.2.2" ++ } ++ }, ++ "node_modules/@webpack-cli/configtest": { ++ "version": "2.0.1", ++ "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.0.1.tgz", ++ "integrity": "sha512-njsdJXJSiS2iNbQVS0eT8A/KPnmyH4pv1APj2K0d1wrZcBLw+yppxOy4CGqa0OxDJkzfL/XELDhD8rocnIwB5A==", ++ "dev": true, ++ "engines": { ++ "node": ">=14.15.0" ++ }, ++ "peerDependencies": { ++ "webpack": "5.x.x", ++ "webpack-cli": "5.x.x" ++ } ++ }, ++ "node_modules/@webpack-cli/info": { ++ "version": "2.0.1", ++ "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.1.tgz", ++ "integrity": "sha512-fE1UEWTwsAxRhrJNikE7v4EotYflkEhBL7EbajfkPlf6E37/2QshOy/D48Mw8G5XMFlQtS6YV42vtbG9zBpIQA==", ++ "dev": true, ++ "engines": { ++ "node": ">=14.15.0" ++ }, ++ "peerDependencies": { ++ "webpack": "5.x.x", ++ "webpack-cli": "5.x.x" ++ } ++ }, ++ "node_modules/@webpack-cli/serve": { ++ "version": "2.0.1", ++ "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.1.tgz", ++ "integrity": "sha512-0G7tNyS+yW8TdgHwZKlDWYXFA6OJQnoLCQvYKkQP0Q2X205PSQ6RNUj0M+1OB/9gRQaUZ/ccYfaxd0nhaWKfjw==", ++ "dev": true, ++ "engines": { ++ "node": ">=14.15.0" ++ }, ++ "peerDependencies": { ++ "webpack": "5.x.x", ++ "webpack-cli": "5.x.x" ++ }, ++ "peerDependenciesMeta": { ++ "webpack-dev-server": { ++ "optional": true ++ } ++ } ++ }, ++ "node_modules/@xtuc/ieee754": { ++ "version": "1.2.0", ++ "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", ++ "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" ++ }, ++ "node_modules/@xtuc/long": { ++ "version": "4.2.2", ++ "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", ++ "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" ++ }, ++ "node_modules/acorn": { ++ "version": "8.8.2", ++ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", ++ "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", ++ "bin": { ++ "acorn": "bin/acorn" ++ }, ++ "engines": { ++ "node": ">=0.4.0" ++ } ++ }, ++ "node_modules/acorn-import-assertions": { ++ "version": "1.8.0", ++ "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", ++ "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==", ++ "peerDependencies": { ++ "acorn": "^8" ++ } ++ }, ++ "node_modules/aggregate-error": { ++ "version": "3.1.0", ++ "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", ++ "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", ++ "dependencies": { ++ "clean-stack": "^2.0.0", ++ "indent-string": "^4.0.0" ++ }, ++ "engines": { ++ "node": ">=8" ++ } ++ }, ++ "node_modules/ajv": { ++ "version": "6.12.6", ++ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", ++ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", ++ "dependencies": { ++ "fast-deep-equal": "^3.1.1", ++ "fast-json-stable-stringify": "^2.0.0", ++ "json-schema-traverse": "^0.4.1", ++ "uri-js": "^4.2.2" ++ }, ++ "funding": { ++ "type": "github", ++ "url": "https://github.com/sponsors/epoberezkin" ++ } ++ }, ++ "node_modules/ajv-formats": { ++ "version": "2.1.1", ++ "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", ++ "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", ++ "dependencies": { ++ "ajv": "^8.0.0" ++ }, ++ "peerDependencies": { ++ "ajv": "^8.0.0" ++ }, ++ "peerDependenciesMeta": { ++ "ajv": { ++ "optional": true ++ } ++ } ++ }, ++ "node_modules/ajv-formats/node_modules/ajv": { ++ "version": "8.12.0", ++ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", ++ "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", ++ "dependencies": { ++ "fast-deep-equal": "^3.1.1", ++ "json-schema-traverse": "^1.0.0", ++ "require-from-string": "^2.0.2", ++ "uri-js": "^4.2.2" ++ }, ++ "funding": { ++ "type": "github", ++ "url": "https://github.com/sponsors/epoberezkin" ++ } ++ }, ++ "node_modules/ajv-formats/node_modules/json-schema-traverse": { ++ "version": "1.0.0", ++ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", ++ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" ++ }, ++ "node_modules/ajv-keywords": { ++ "version": "3.5.2", ++ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", ++ "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", ++ "peerDependencies": { ++ "ajv": "^6.9.1" ++ } ++ }, ++ "node_modules/ansi-styles": { ++ "version": "4.3.0", ++ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", ++ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", ++ "dependencies": { ++ "color-convert": "^2.0.1" ++ }, ++ "engines": { ++ "node": ">=8" ++ }, ++ "funding": { ++ "url": "https://github.com/chalk/ansi-styles?sponsor=1" ++ } ++ }, ++ "node_modules/anymatch": { ++ "version": "3.1.3", ++ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", ++ "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", ++ "dependencies": { ++ "normalize-path": "^3.0.0", ++ "picomatch": "^2.0.4" ++ }, ++ "engines": { ++ "node": ">= 8" ++ } ++ }, ++ "node_modules/array-union": { ++ "version": "2.1.0", ++ "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", ++ "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", ++ "engines": { ++ "node": ">=8" ++ } ++ }, ++ "node_modules/balanced-match": { ++ "version": "1.0.2", ++ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", ++ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" ++ }, ++ "node_modules/big.js": { ++ "version": "5.2.2", ++ "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", ++ "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", ++ "engines": { ++ "node": "*" ++ } ++ }, ++ "node_modules/binary-extensions": { ++ "version": "2.2.0", ++ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", ++ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", ++ "engines": { ++ "node": ">=8" ++ } ++ }, ++ "node_modules/boolbase": { ++ "version": "1.0.0", ++ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", ++ "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" ++ }, ++ "node_modules/brace-expansion": { ++ "version": "1.1.11", ++ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", ++ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", ++ "dependencies": { ++ "balanced-match": "^1.0.0", ++ "concat-map": "0.0.1" ++ } ++ }, ++ "node_modules/braces": { ++ "version": "3.0.2", ++ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", ++ "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", ++ "dependencies": { ++ "fill-range": "^7.0.1" ++ }, ++ "engines": { ++ "node": ">=8" ++ } ++ }, ++ "node_modules/browserslist": { ++ "version": "4.21.5", ++ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz", ++ "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==", ++ "funding": [ ++ { ++ "type": "opencollective", ++ "url": "https://opencollective.com/browserslist" ++ }, ++ { ++ "type": "tidelift", ++ "url": "https://tidelift.com/funding/github/npm/browserslist" ++ } ++ ], ++ "dependencies": { ++ "caniuse-lite": "^1.0.30001449", ++ "electron-to-chromium": "^1.4.284", ++ "node-releases": "^2.0.8", ++ "update-browserslist-db": "^1.0.10" ++ }, ++ "bin": { ++ "browserslist": "cli.js" ++ }, ++ "engines": { ++ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" ++ } ++ }, ++ "node_modules/buffer-from": { ++ "version": "1.1.2", ++ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", ++ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" ++ }, ++ "node_modules/cacache": { ++ "version": "15.3.0", ++ "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz", ++ "integrity": "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==", ++ "dependencies": { ++ "@npmcli/fs": "^1.0.0", ++ "@npmcli/move-file": "^1.0.1", ++ "chownr": "^2.0.0", ++ "fs-minipass": "^2.0.0", ++ "glob": "^7.1.4", ++ "infer-owner": "^1.0.4", ++ "lru-cache": "^6.0.0", ++ "minipass": "^3.1.1", ++ "minipass-collect": "^1.0.2", ++ "minipass-flush": "^1.0.5", ++ "minipass-pipeline": "^1.2.2", ++ "mkdirp": "^1.0.3", ++ "p-map": "^4.0.0", ++ "promise-inflight": "^1.0.1", ++ "rimraf": "^3.0.2", ++ "ssri": "^8.0.1", ++ "tar": "^6.0.2", ++ "unique-filename": "^1.1.1" ++ }, ++ "engines": { ++ "node": ">= 10" ++ } ++ }, ++ "node_modules/cacache/node_modules/p-map": { ++ "version": "4.0.0", ++ "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", ++ "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", ++ "dependencies": { ++ "aggregate-error": "^3.0.0" ++ }, ++ "engines": { ++ "node": ">=10" ++ }, ++ "funding": { ++ "url": "https://github.com/sponsors/sindresorhus" ++ } ++ }, ++ "node_modules/callsites": { ++ "version": "3.1.0", ++ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", ++ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", ++ "engines": { ++ "node": ">=6" ++ } ++ }, ++ "node_modules/camelcase-css": { ++ "version": "2.0.1", ++ "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", ++ "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", ++ "engines": { ++ "node": ">= 6" ++ } ++ }, ++ "node_modules/caniuse-api": { ++ "version": "3.0.0", ++ "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", ++ "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", ++ "dependencies": { ++ "browserslist": "^4.0.0", ++ "caniuse-lite": "^1.0.0", ++ "lodash.memoize": "^4.1.2", ++ "lodash.uniq": "^4.5.0" ++ } ++ }, ++ "node_modules/caniuse-lite": { ++ "version": "1.0.30001451", ++ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001451.tgz", ++ "integrity": "sha512-XY7UbUpGRatZzoRft//5xOa69/1iGJRBlrieH6QYrkKLIFn3m7OVEJ81dSrKoy2BnKsdbX5cLrOispZNYo9v2w==", ++ "funding": [ ++ { ++ "type": "opencollective", ++ "url": "https://opencollective.com/browserslist" ++ }, ++ { ++ "type": "tidelift", ++ "url": "https://tidelift.com/funding/github/npm/caniuse-lite" ++ } ++ ] ++ }, ++ "node_modules/chalk": { ++ "version": "3.0.0", ++ "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", ++ "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", ++ "dependencies": { ++ "ansi-styles": "^4.1.0", ++ "supports-color": "^7.1.0" ++ }, ++ "engines": { ++ "node": ">=8" ++ } ++ }, ++ "node_modules/chokidar": { ++ "version": "3.5.3", ++ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", ++ "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", ++ "funding": [ ++ { ++ "type": "individual", ++ "url": "https://paulmillr.com/funding/" ++ } ++ ], ++ "dependencies": { ++ "anymatch": "~3.1.2", ++ "braces": "~3.0.2", ++ "glob-parent": "~5.1.2", ++ "is-binary-path": "~2.1.0", ++ "is-glob": "~4.0.1", ++ "normalize-path": "~3.0.0", ++ "readdirp": "~3.6.0" ++ }, ++ "engines": { ++ "node": ">= 8.10.0" ++ }, ++ "optionalDependencies": { ++ "fsevents": "~2.3.2" ++ } ++ }, ++ "node_modules/chownr": { ++ "version": "2.0.0", ++ "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", ++ "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", ++ "engines": { ++ "node": ">=10" ++ } ++ }, ++ "node_modules/chrome-trace-event": { ++ "version": "1.0.3", ++ "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", ++ "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", ++ "engines": { ++ "node": ">=6.0" ++ } ++ }, ++ "node_modules/ckeditor5": { ++ "version": "35.4.0", ++ "resolved": "https://registry.npmjs.org/ckeditor5/-/ckeditor5-35.4.0.tgz", ++ "integrity": "sha512-vBEQVkFCbjYmEPVkyWsOqU44DOovUio6xBuCwroe4TuJLplqeRasCjFwB0DPknXQU8U0iM3Lh/QSKRyN92pw3Q==", ++ "dependencies": { ++ "@ckeditor/ckeditor5-clipboard": "^35.4.0", ++ "@ckeditor/ckeditor5-core": "^35.4.0", ++ "@ckeditor/ckeditor5-engine": "^35.4.0", ++ "@ckeditor/ckeditor5-enter": "^35.4.0", ++ "@ckeditor/ckeditor5-paragraph": "^35.4.0", ++ "@ckeditor/ckeditor5-select-all": "^35.4.0", ++ "@ckeditor/ckeditor5-typing": "^35.4.0", ++ "@ckeditor/ckeditor5-ui": "^35.4.0", ++ "@ckeditor/ckeditor5-undo": "^35.4.0", ++ "@ckeditor/ckeditor5-upload": "^35.4.0", ++ "@ckeditor/ckeditor5-utils": "^35.4.0", ++ "@ckeditor/ckeditor5-widget": "^35.4.0" ++ }, ++ "engines": { ++ "node": ">=14.0.0", ++ "npm": ">=5.7.1" ++ } ++ }, ++ "node_modules/clean-stack": { ++ "version": "2.2.0", ++ "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", ++ "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", ++ "engines": { ++ "node": ">=6" ++ } ++ }, ++ "node_modules/cli-cursor": { ++ "version": "3.1.0", ++ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", ++ "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", ++ "dependencies": { ++ "restore-cursor": "^3.1.0" ++ }, ++ "engines": { ++ "node": ">=8" ++ } ++ }, ++ "node_modules/cli-spinners": { ++ "version": "2.7.0", ++ "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.7.0.tgz", ++ "integrity": "sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw==", ++ "engines": { ++ "node": ">=6" ++ }, ++ "funding": { ++ "url": "https://github.com/sponsors/sindresorhus" ++ } ++ }, ++ "node_modules/clone-deep": { ++ "version": "4.0.1", ++ "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", ++ "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", ++ "dev": true, ++ "dependencies": { ++ "is-plain-object": "^2.0.4", ++ "kind-of": "^6.0.2", ++ "shallow-clone": "^3.0.0" ++ }, ++ "engines": { ++ "node": ">=6" ++ } ++ }, ++ "node_modules/color-convert": { ++ "version": "2.0.1", ++ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", ++ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", ++ "dependencies": { ++ "color-name": "~1.1.4" ++ }, ++ "engines": { ++ "node": ">=7.0.0" ++ } ++ }, ++ "node_modules/color-name": { ++ "version": "1.1.4", ++ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", ++ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" ++ }, ++ "node_modules/colord": { ++ "version": "2.9.3", ++ "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", ++ "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==" ++ }, ++ "node_modules/colorette": { ++ "version": "2.0.19", ++ "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", ++ "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==", ++ "dev": true ++ }, ++ "node_modules/commander": { ++ "version": "7.2.0", ++ "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", ++ "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", ++ "engines": { ++ "node": ">= 10" ++ } ++ }, ++ "node_modules/commondir": { ++ "version": "1.0.1", ++ "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", ++ "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==" ++ }, ++ "node_modules/concat-map": { ++ "version": "0.0.1", ++ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", ++ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" ++ }, ++ "node_modules/cosmiconfig": { ++ "version": "7.1.0", ++ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", ++ "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", ++ "dependencies": { ++ "@types/parse-json": "^4.0.0", ++ "import-fresh": "^3.2.1", ++ "parse-json": "^5.0.0", ++ "path-type": "^4.0.0", ++ "yaml": "^1.10.0" ++ }, ++ "engines": { ++ "node": ">=10" ++ } ++ }, ++ "node_modules/cross-spawn": { ++ "version": "7.0.3", ++ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", ++ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", ++ "dev": true, ++ "dependencies": { ++ "path-key": "^3.1.0", ++ "shebang-command": "^2.0.0", ++ "which": "^2.0.1" ++ }, ++ "engines": { ++ "node": ">= 8" ++ } ++ }, ++ "node_modules/css-declaration-sorter": { ++ "version": "6.3.1", ++ "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.3.1.tgz", ++ "integrity": "sha512-fBffmak0bPAnyqc/HO8C3n2sHrp9wcqQz6ES9koRF2/mLOVAx9zIQ3Y7R29sYCteTPqMCwns4WYQoCX91Xl3+w==", ++ "engines": { ++ "node": "^10 || ^12 || >=14" ++ }, ++ "peerDependencies": { ++ "postcss": "^8.0.9" ++ } ++ }, ++ "node_modules/css-loader": { ++ "version": "5.2.7", ++ "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-5.2.7.tgz", ++ "integrity": "sha512-Q7mOvpBNBG7YrVGMxRxcBJZFL75o+cH2abNASdibkj/fffYD8qWbInZrD0S9ccI6vZclF3DsHE7njGlLtaHbhg==", ++ "dependencies": { ++ "icss-utils": "^5.1.0", ++ "loader-utils": "^2.0.0", ++ "postcss": "^8.2.15", ++ "postcss-modules-extract-imports": "^3.0.0", ++ "postcss-modules-local-by-default": "^4.0.0", ++ "postcss-modules-scope": "^3.0.0", ++ "postcss-modules-values": "^4.0.0", ++ "postcss-value-parser": "^4.1.0", ++ "schema-utils": "^3.0.0", ++ "semver": "^7.3.5" ++ }, ++ "engines": { ++ "node": ">= 10.13.0" ++ }, ++ "funding": { ++ "type": "opencollective", ++ "url": "https://opencollective.com/webpack" ++ }, ++ "peerDependencies": { ++ "webpack": "^4.27.0 || ^5.0.0" ++ } ++ }, ++ "node_modules/css-select": { ++ "version": "4.3.0", ++ "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", ++ "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", ++ "dependencies": { ++ "boolbase": "^1.0.0", ++ "css-what": "^6.0.1", ++ "domhandler": "^4.3.1", ++ "domutils": "^2.8.0", ++ "nth-check": "^2.0.1" ++ }, ++ "funding": { ++ "url": "https://github.com/sponsors/fb55" ++ } ++ }, ++ "node_modules/css-tree": { ++ "version": "1.1.3", ++ "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", ++ "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", ++ "dependencies": { ++ "mdn-data": "2.0.14", ++ "source-map": "^0.6.1" ++ }, ++ "engines": { ++ "node": ">=8.0.0" ++ } ++ }, ++ "node_modules/css-what": { ++ "version": "6.1.0", ++ "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", ++ "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", ++ "engines": { ++ "node": ">= 6" ++ }, ++ "funding": { ++ "url": "https://github.com/sponsors/fb55" ++ } ++ }, ++ "node_modules/cssesc": { ++ "version": "3.0.0", ++ "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", ++ "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", ++ "bin": { ++ "cssesc": "bin/cssesc" ++ }, ++ "engines": { ++ "node": ">=4" ++ } ++ }, ++ "node_modules/cssnano": { ++ "version": "5.1.14", ++ "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.14.tgz", ++ "integrity": "sha512-Oou7ihiTocbKqi0J1bB+TRJIQX5RMR3JghA8hcWSw9mjBLQ5Y3RWqEDoYG3sRNlAbCIXpqMoZGbq5KDR3vdzgw==", ++ "dependencies": { ++ "cssnano-preset-default": "^5.2.13", ++ "lilconfig": "^2.0.3", ++ "yaml": "^1.10.2" ++ }, ++ "engines": { ++ "node": "^10 || ^12 || >=14.0" ++ }, ++ "funding": { ++ "type": "opencollective", ++ "url": "https://opencollective.com/cssnano" ++ }, ++ "peerDependencies": { ++ "postcss": "^8.2.15" ++ } ++ }, ++ "node_modules/cssnano-preset-default": { ++ "version": "5.2.13", ++ "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.13.tgz", ++ "integrity": "sha512-PX7sQ4Pb+UtOWuz8A1d+Rbi+WimBIxJTRyBdgGp1J75VU0r/HFQeLnMYgHiCAp6AR4rqrc7Y4R+1Rjk3KJz6DQ==", ++ "dependencies": { ++ "css-declaration-sorter": "^6.3.1", ++ "cssnano-utils": "^3.1.0", ++ "postcss-calc": "^8.2.3", ++ "postcss-colormin": "^5.3.0", ++ "postcss-convert-values": "^5.1.3", ++ "postcss-discard-comments": "^5.1.2", ++ "postcss-discard-duplicates": "^5.1.0", ++ "postcss-discard-empty": "^5.1.1", ++ "postcss-discard-overridden": "^5.1.0", ++ "postcss-merge-longhand": "^5.1.7", ++ "postcss-merge-rules": "^5.1.3", ++ "postcss-minify-font-values": "^5.1.0", ++ "postcss-minify-gradients": "^5.1.1", ++ "postcss-minify-params": "^5.1.4", ++ "postcss-minify-selectors": "^5.2.1", ++ "postcss-normalize-charset": "^5.1.0", ++ "postcss-normalize-display-values": "^5.1.0", ++ "postcss-normalize-positions": "^5.1.1", ++ "postcss-normalize-repeat-style": "^5.1.1", ++ "postcss-normalize-string": "^5.1.0", ++ "postcss-normalize-timing-functions": "^5.1.0", ++ "postcss-normalize-unicode": "^5.1.1", ++ "postcss-normalize-url": "^5.1.0", ++ "postcss-normalize-whitespace": "^5.1.1", ++ "postcss-ordered-values": "^5.1.3", ++ "postcss-reduce-initial": "^5.1.1", ++ "postcss-reduce-transforms": "^5.1.0", ++ "postcss-svgo": "^5.1.0", ++ "postcss-unique-selectors": "^5.1.1" ++ }, ++ "engines": { ++ "node": "^10 || ^12 || >=14.0" ++ }, ++ "peerDependencies": { ++ "postcss": "^8.2.15" ++ } ++ }, ++ "node_modules/cssnano-utils": { ++ "version": "3.1.0", ++ "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz", ++ "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==", ++ "engines": { ++ "node": "^10 || ^12 || >=14.0" ++ }, ++ "peerDependencies": { ++ "postcss": "^8.2.15" ++ } ++ }, ++ "node_modules/csso": { ++ "version": "4.2.0", ++ "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", ++ "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", ++ "dependencies": { ++ "css-tree": "^1.1.2" ++ }, ++ "engines": { ++ "node": ">=8.0.0" ++ } ++ }, ++ "node_modules/debug": { ++ "version": "4.3.4", ++ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", ++ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", ++ "dependencies": { ++ "ms": "2.1.2" ++ }, ++ "engines": { ++ "node": ">=6.0" ++ }, ++ "peerDependenciesMeta": { ++ "supports-color": { ++ "optional": true ++ } ++ } ++ }, ++ "node_modules/del": { ++ "version": "5.1.0", ++ "resolved": "https://registry.npmjs.org/del/-/del-5.1.0.tgz", ++ "integrity": "sha512-wH9xOVHnczo9jN2IW68BabcecVPxacIA3g/7z6vhSU/4stOKQzeCRK0yD0A24WiAAUJmmVpWqrERcTxnLo3AnA==", ++ "dependencies": { ++ "globby": "^10.0.1", ++ "graceful-fs": "^4.2.2", ++ "is-glob": "^4.0.1", ++ "is-path-cwd": "^2.2.0", ++ "is-path-inside": "^3.0.1", ++ "p-map": "^3.0.0", ++ "rimraf": "^3.0.0", ++ "slash": "^3.0.0" ++ }, ++ "engines": { ++ "node": ">=8" ++ } ++ }, ++ "node_modules/dir-glob": { ++ "version": "3.0.1", ++ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", ++ "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", ++ "dependencies": { ++ "path-type": "^4.0.0" ++ }, ++ "engines": { ++ "node": ">=8" ++ } ++ }, ++ "node_modules/dom-serializer": { ++ "version": "1.4.1", ++ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", ++ "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", ++ "dependencies": { ++ "domelementtype": "^2.0.1", ++ "domhandler": "^4.2.0", ++ "entities": "^2.0.0" ++ }, ++ "funding": { ++ "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" ++ } ++ }, ++ "node_modules/domelementtype": { ++ "version": "2.3.0", ++ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", ++ "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", ++ "funding": [ ++ { ++ "type": "github", ++ "url": "https://github.com/sponsors/fb55" ++ } ++ ] ++ }, ++ "node_modules/domhandler": { ++ "version": "4.3.1", ++ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", ++ "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", ++ "dependencies": { ++ "domelementtype": "^2.2.0" ++ }, ++ "engines": { ++ "node": ">= 4" ++ }, ++ "funding": { ++ "url": "https://github.com/fb55/domhandler?sponsor=1" ++ } ++ }, ++ "node_modules/domutils": { ++ "version": "2.8.0", ++ "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", ++ "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", ++ "dependencies": { ++ "dom-serializer": "^1.0.1", ++ "domelementtype": "^2.2.0", ++ "domhandler": "^4.2.0" ++ }, ++ "funding": { ++ "url": "https://github.com/fb55/domutils?sponsor=1" ++ } ++ }, ++ "node_modules/electron-to-chromium": { ++ "version": "1.4.295", ++ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.295.tgz", ++ "integrity": "sha512-lEO94zqf1bDA3aepxwnWoHUjA8sZ+2owgcSZjYQy0+uOSEclJX0VieZC+r+wLpSxUHRd6gG32znTWmr+5iGzFw==" ++ }, ++ "node_modules/emojis-list": { ++ "version": "3.0.0", ++ "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", ++ "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", ++ "engines": { ++ "node": ">= 4" ++ } ++ }, ++ "node_modules/enhanced-resolve": { ++ "version": "5.12.0", ++ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz", ++ "integrity": "sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ==", ++ "dependencies": { ++ "graceful-fs": "^4.2.4", ++ "tapable": "^2.2.0" ++ }, ++ "engines": { ++ "node": ">=10.13.0" ++ } ++ }, ++ "node_modules/entities": { ++ "version": "2.2.0", ++ "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", ++ "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", ++ "funding": { ++ "url": "https://github.com/fb55/entities?sponsor=1" ++ } ++ }, ++ "node_modules/envinfo": { ++ "version": "7.8.1", ++ "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", ++ "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==", ++ "dev": true, ++ "bin": { ++ "envinfo": "dist/cli.js" ++ }, ++ "engines": { ++ "node": ">=4" ++ } ++ }, ++ "node_modules/error-ex": { ++ "version": "1.3.2", ++ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", ++ "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", ++ "dependencies": { ++ "is-arrayish": "^0.2.1" ++ } ++ }, ++ "node_modules/es-module-lexer": { ++ "version": "0.9.3", ++ "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz", ++ "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==" ++ }, ++ "node_modules/escalade": { ++ "version": "3.1.1", ++ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", ++ "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", ++ "engines": { ++ "node": ">=6" ++ } ++ }, ++ "node_modules/escape-string-regexp": { ++ "version": "1.0.5", ++ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", ++ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", ++ "engines": { ++ "node": ">=0.8.0" ++ } ++ }, ++ "node_modules/eslint-scope": { ++ "version": "5.1.1", ++ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", ++ "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", ++ "dependencies": { ++ "esrecurse": "^4.3.0", ++ "estraverse": "^4.1.1" ++ }, ++ "engines": { ++ "node": ">=8.0.0" ++ } ++ }, ++ "node_modules/esrecurse": { ++ "version": "4.3.0", ++ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", ++ "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", ++ "dependencies": { ++ "estraverse": "^5.2.0" ++ }, ++ "engines": { ++ "node": ">=4.0" ++ } ++ }, ++ "node_modules/esrecurse/node_modules/estraverse": { ++ "version": "5.3.0", ++ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", ++ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", ++ "engines": { ++ "node": ">=4.0" ++ } ++ }, ++ "node_modules/estraverse": { ++ "version": "4.3.0", ++ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", ++ "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", ++ "engines": { ++ "node": ">=4.0" ++ } ++ }, ++ "node_modules/events": { ++ "version": "3.3.0", ++ "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", ++ "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", ++ "engines": { ++ "node": ">=0.8.x" ++ } ++ }, ++ "node_modules/fast-deep-equal": { ++ "version": "3.1.3", ++ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", ++ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" ++ }, ++ "node_modules/fast-glob": { ++ "version": "3.2.12", ++ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", ++ "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", ++ "dependencies": { ++ "@nodelib/fs.stat": "^2.0.2", ++ "@nodelib/fs.walk": "^1.2.3", ++ "glob-parent": "^5.1.2", ++ "merge2": "^1.3.0", ++ "micromatch": "^4.0.4" ++ }, ++ "engines": { ++ "node": ">=8.6.0" ++ } ++ }, ++ "node_modules/fast-json-stable-stringify": { ++ "version": "2.1.0", ++ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", ++ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" ++ }, ++ "node_modules/fastest-levenshtein": { ++ "version": "1.0.16", ++ "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", ++ "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", ++ "dev": true, ++ "engines": { ++ "node": ">= 4.9.1" ++ } ++ }, ++ "node_modules/fastq": { ++ "version": "1.15.0", ++ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", ++ "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", ++ "dependencies": { ++ "reusify": "^1.0.4" ++ } ++ }, ++ "node_modules/fill-range": { ++ "version": "7.0.1", ++ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", ++ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", ++ "dependencies": { ++ "to-regex-range": "^5.0.1" ++ }, ++ "engines": { ++ "node": ">=8" ++ } ++ }, ++ "node_modules/find-cache-dir": { ++ "version": "3.3.2", ++ "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", ++ "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", ++ "dependencies": { ++ "commondir": "^1.0.1", ++ "make-dir": "^3.0.2", ++ "pkg-dir": "^4.1.0" ++ }, ++ "engines": { ++ "node": ">=8" ++ }, ++ "funding": { ++ "url": "https://github.com/avajs/find-cache-dir?sponsor=1" ++ } ++ }, ++ "node_modules/find-up": { ++ "version": "4.1.0", ++ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", ++ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", ++ "dependencies": { ++ "locate-path": "^5.0.0", ++ "path-exists": "^4.0.0" ++ }, ++ "engines": { ++ "node": ">=8" ++ } ++ }, ++ "node_modules/fs-extra": { ++ "version": "8.1.0", ++ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", ++ "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", ++ "dependencies": { ++ "graceful-fs": "^4.2.0", ++ "jsonfile": "^4.0.0", ++ "universalify": "^0.1.0" ++ }, ++ "engines": { ++ "node": ">=6 <7 || >=8" ++ } ++ }, ++ "node_modules/fs-minipass": { ++ "version": "2.1.0", ++ "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", ++ "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", ++ "dependencies": { ++ "minipass": "^3.0.0" ++ }, ++ "engines": { ++ "node": ">= 8" ++ } ++ }, ++ "node_modules/fs.realpath": { ++ "version": "1.0.0", ++ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", ++ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" ++ }, ++ "node_modules/fsevents": { ++ "version": "2.3.2", ++ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", ++ "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", ++ "hasInstallScript": true, ++ "optional": true, ++ "os": [ ++ "darwin" ++ ], ++ "engines": { ++ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" ++ } ++ }, ++ "node_modules/function-bind": { ++ "version": "1.1.1", ++ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", ++ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" ++ }, ++ "node_modules/glob": { ++ "version": "7.2.3", ++ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", ++ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", ++ "dependencies": { ++ "fs.realpath": "^1.0.0", ++ "inflight": "^1.0.4", ++ "inherits": "2", ++ "minimatch": "^3.1.1", ++ "once": "^1.3.0", ++ "path-is-absolute": "^1.0.0" ++ }, ++ "engines": { ++ "node": "*" ++ }, ++ "funding": { ++ "url": "https://github.com/sponsors/isaacs" ++ } ++ }, ++ "node_modules/glob-parent": { ++ "version": "5.1.2", ++ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", ++ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", ++ "dependencies": { ++ "is-glob": "^4.0.1" ++ }, ++ "engines": { ++ "node": ">= 6" ++ } ++ }, ++ "node_modules/glob-to-regexp": { ++ "version": "0.4.1", ++ "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", ++ "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" ++ }, ++ "node_modules/globals": { ++ "version": "11.12.0", ++ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", ++ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", ++ "engines": { ++ "node": ">=4" ++ } ++ }, ++ "node_modules/globby": { ++ "version": "10.0.2", ++ "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", ++ "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", ++ "dependencies": { ++ "@types/glob": "^7.1.1", ++ "array-union": "^2.1.0", ++ "dir-glob": "^3.0.1", ++ "fast-glob": "^3.0.3", ++ "glob": "^7.1.3", ++ "ignore": "^5.1.1", ++ "merge2": "^1.2.3", ++ "slash": "^3.0.0" ++ }, ++ "engines": { ++ "node": ">=8" ++ } ++ }, ++ "node_modules/graceful-fs": { ++ "version": "4.2.10", ++ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", ++ "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" ++ }, ++ "node_modules/has": { ++ "version": "1.0.3", ++ "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", ++ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", ++ "dependencies": { ++ "function-bind": "^1.1.1" ++ }, ++ "engines": { ++ "node": ">= 0.4.0" ++ } ++ }, ++ "node_modules/has-flag": { ++ "version": "4.0.0", ++ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", ++ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", ++ "engines": { ++ "node": ">=8" ++ } ++ }, ++ "node_modules/icss-utils": { ++ "version": "5.1.0", ++ "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", ++ "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", ++ "engines": { ++ "node": "^10 || ^12 || >= 14" ++ }, ++ "peerDependencies": { ++ "postcss": "^8.1.0" ++ } ++ }, ++ "node_modules/ignore": { ++ "version": "5.2.4", ++ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", ++ "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", ++ "engines": { ++ "node": ">= 4" ++ } ++ }, ++ "node_modules/immutable": { ++ "version": "4.2.4", ++ "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.2.4.tgz", ++ "integrity": "sha512-WDxL3Hheb1JkRN3sQkyujNlL/xRjAo3rJtaU5xeufUauG66JdMr32bLj4gF+vWl84DIA3Zxw7tiAjneYzRRw+w==" ++ }, ++ "node_modules/import-fresh": { ++ "version": "3.3.0", ++ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", ++ "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", ++ "dependencies": { ++ "parent-module": "^1.0.0", ++ "resolve-from": "^4.0.0" ++ }, ++ "engines": { ++ "node": ">=6" ++ }, ++ "funding": { ++ "url": "https://github.com/sponsors/sindresorhus" ++ } ++ }, ++ "node_modules/import-local": { ++ "version": "3.1.0", ++ "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", ++ "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", ++ "dev": true, ++ "dependencies": { ++ "pkg-dir": "^4.2.0", ++ "resolve-cwd": "^3.0.0" ++ }, ++ "bin": { ++ "import-local-fixture": "fixtures/cli.js" ++ }, ++ "engines": { ++ "node": ">=8" ++ }, ++ "funding": { ++ "url": "https://github.com/sponsors/sindresorhus" ++ } ++ }, ++ "node_modules/imurmurhash": { ++ "version": "0.1.4", ++ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", ++ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", ++ "engines": { ++ "node": ">=0.8.19" ++ } ++ }, ++ "node_modules/indent-string": { ++ "version": "4.0.0", ++ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", ++ "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", ++ "engines": { ++ "node": ">=8" ++ } ++ }, ++ "node_modules/infer-owner": { ++ "version": "1.0.4", ++ "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", ++ "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==" ++ }, ++ "node_modules/inflight": { ++ "version": "1.0.6", ++ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", ++ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", ++ "dependencies": { ++ "once": "^1.3.0", ++ "wrappy": "1" ++ } ++ }, ++ "node_modules/inherits": { ++ "version": "2.0.4", ++ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", ++ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" ++ }, ++ "node_modules/interpret": { ++ "version": "1.4.0", ++ "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", ++ "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", ++ "engines": { ++ "node": ">= 0.10" ++ } ++ }, ++ "node_modules/is-arrayish": { ++ "version": "0.2.1", ++ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", ++ "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" ++ }, ++ "node_modules/is-binary-path": { ++ "version": "2.1.0", ++ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", ++ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", ++ "dependencies": { ++ "binary-extensions": "^2.0.0" ++ }, ++ "engines": { ++ "node": ">=8" ++ } ++ }, ++ "node_modules/is-core-module": { ++ "version": "2.11.0", ++ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", ++ "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", ++ "dependencies": { ++ "has": "^1.0.3" ++ }, ++ "funding": { ++ "url": "https://github.com/sponsors/ljharb" ++ } ++ }, ++ "node_modules/is-extglob": { ++ "version": "2.1.1", ++ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", ++ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", ++ "engines": { ++ "node": ">=0.10.0" ++ } ++ }, ++ "node_modules/is-glob": { ++ "version": "4.0.3", ++ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", ++ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", ++ "dependencies": { ++ "is-extglob": "^2.1.1" ++ }, ++ "engines": { ++ "node": ">=0.10.0" ++ } ++ }, ++ "node_modules/is-interactive": { ++ "version": "1.0.0", ++ "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", ++ "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", ++ "engines": { ++ "node": ">=8" ++ } ++ }, ++ "node_modules/is-number": { ++ "version": "7.0.0", ++ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", ++ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", ++ "engines": { ++ "node": ">=0.12.0" ++ } ++ }, ++ "node_modules/is-path-cwd": { ++ "version": "2.2.0", ++ "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", ++ "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", ++ "engines": { ++ "node": ">=6" ++ } ++ }, ++ "node_modules/is-path-inside": { ++ "version": "3.0.3", ++ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", ++ "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", ++ "engines": { ++ "node": ">=8" ++ } ++ }, ++ "node_modules/is-plain-object": { ++ "version": "2.0.4", ++ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", ++ "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", ++ "dev": true, ++ "dependencies": { ++ "isobject": "^3.0.1" ++ }, ++ "engines": { ++ "node": ">=0.10.0" ++ } ++ }, ++ "node_modules/isexe": { ++ "version": "2.0.0", ++ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", ++ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", ++ "dev": true ++ }, ++ "node_modules/isobject": { ++ "version": "3.0.1", ++ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", ++ "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", ++ "dev": true, ++ "engines": { ++ "node": ">=0.10.0" ++ } ++ }, ++ "node_modules/javascript-stringify": { ++ "version": "1.6.0", ++ "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-1.6.0.tgz", ++ "integrity": "sha512-fnjC0up+0SjEJtgmmG+teeel68kutkvzfctO/KxE3qJlbunkJYAshgH3boU++gSBHP8z5/r0ts0qRIrHf0RTQQ==" ++ }, ++ "node_modules/jest-worker": { ++ "version": "27.5.1", ++ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", ++ "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", ++ "dependencies": { ++ "@types/node": "*", ++ "merge-stream": "^2.0.0", ++ "supports-color": "^8.0.0" ++ }, ++ "engines": { ++ "node": ">= 10.13.0" ++ } ++ }, ++ "node_modules/jest-worker/node_modules/supports-color": { ++ "version": "8.1.1", ++ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", ++ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", ++ "dependencies": { ++ "has-flag": "^4.0.0" ++ }, ++ "engines": { ++ "node": ">=10" ++ }, ++ "funding": { ++ "url": "https://github.com/chalk/supports-color?sponsor=1" ++ } ++ }, ++ "node_modules/js-tokens": { ++ "version": "4.0.0", ++ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", ++ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" ++ }, ++ "node_modules/jsesc": { ++ "version": "2.5.2", ++ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", ++ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", ++ "bin": { ++ "jsesc": "bin/jsesc" ++ }, ++ "engines": { ++ "node": ">=4" ++ } ++ }, ++ "node_modules/json-parse-even-better-errors": { ++ "version": "2.3.1", ++ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", ++ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" ++ }, ++ "node_modules/json-schema-traverse": { ++ "version": "0.4.1", ++ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", ++ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" ++ }, ++ "node_modules/json5": { ++ "version": "2.2.3", ++ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", ++ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", ++ "bin": { ++ "json5": "lib/cli.js" ++ }, ++ "engines": { ++ "node": ">=6" ++ } ++ }, ++ "node_modules/jsonfile": { ++ "version": "4.0.0", ++ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", ++ "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", ++ "optionalDependencies": { ++ "graceful-fs": "^4.1.6" ++ } ++ }, ++ "node_modules/kind-of": { ++ "version": "6.0.3", ++ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", ++ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", ++ "dev": true, ++ "engines": { ++ "node": ">=0.10.0" ++ } ++ }, ++ "node_modules/klona": { ++ "version": "2.0.6", ++ "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.6.tgz", ++ "integrity": "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==", ++ "engines": { ++ "node": ">= 8" ++ } ++ }, ++ "node_modules/lilconfig": { ++ "version": "2.0.6", ++ "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.6.tgz", ++ "integrity": "sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==", ++ "engines": { ++ "node": ">=10" ++ } ++ }, ++ "node_modules/lines-and-columns": { ++ "version": "1.2.4", ++ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", ++ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" ++ }, ++ "node_modules/loader-runner": { ++ "version": "4.3.0", ++ "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", ++ "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", ++ "engines": { ++ "node": ">=6.11.5" ++ } ++ }, ++ "node_modules/loader-utils": { ++ "version": "2.0.4", ++ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", ++ "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", ++ "dependencies": { ++ "big.js": "^5.2.2", ++ "emojis-list": "^3.0.0", ++ "json5": "^2.1.2" ++ }, ++ "engines": { ++ "node": ">=8.9.0" ++ } ++ }, ++ "node_modules/locate-path": { ++ "version": "5.0.0", ++ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", ++ "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", ++ "dependencies": { ++ "p-locate": "^4.1.0" ++ }, ++ "engines": { ++ "node": ">=8" ++ } ++ }, ++ "node_modules/lodash-es": { ++ "version": "4.17.21", ++ "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", ++ "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" ++ }, ++ "node_modules/lodash.memoize": { ++ "version": "4.1.2", ++ "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", ++ "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==" ++ }, ++ "node_modules/lodash.uniq": { ++ "version": "4.5.0", ++ "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", ++ "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==" ++ }, ++ "node_modules/lru-cache": { ++ "version": "6.0.0", ++ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", ++ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", ++ "dependencies": { ++ "yallist": "^4.0.0" ++ }, ++ "engines": { ++ "node": ">=10" ++ } ++ }, ++ "node_modules/make-dir": { ++ "version": "3.1.0", ++ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", ++ "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", ++ "dependencies": { ++ "semver": "^6.0.0" ++ }, ++ "engines": { ++ "node": ">=8" ++ }, ++ "funding": { ++ "url": "https://github.com/sponsors/sindresorhus" ++ } ++ }, ++ "node_modules/make-dir/node_modules/semver": { ++ "version": "6.3.0", ++ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", ++ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", ++ "bin": { ++ "semver": "bin/semver.js" ++ } ++ }, ++ "node_modules/mdn-data": { ++ "version": "2.0.14", ++ "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", ++ "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==" ++ }, ++ "node_modules/merge-stream": { ++ "version": "2.0.0", ++ "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", ++ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" ++ }, ++ "node_modules/merge2": { ++ "version": "1.4.1", ++ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", ++ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", ++ "engines": { ++ "node": ">= 8" ++ } ++ }, ++ "node_modules/micromatch": { ++ "version": "4.0.5", ++ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", ++ "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", ++ "dependencies": { ++ "braces": "^3.0.2", ++ "picomatch": "^2.3.1" ++ }, ++ "engines": { ++ "node": ">=8.6" ++ } ++ }, ++ "node_modules/mime-db": { ++ "version": "1.52.0", ++ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", ++ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", ++ "engines": { ++ "node": ">= 0.6" ++ } ++ }, ++ "node_modules/mime-types": { ++ "version": "2.1.35", ++ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", ++ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", ++ "dependencies": { ++ "mime-db": "1.52.0" ++ }, ++ "engines": { ++ "node": ">= 0.6" ++ } ++ }, ++ "node_modules/mimic-fn": { ++ "version": "2.1.0", ++ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", ++ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", ++ "engines": { ++ "node": ">=6" ++ } ++ }, ++ "node_modules/mini-css-extract-plugin": { ++ "version": "2.7.2", ++ "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.2.tgz", ++ "integrity": "sha512-EdlUizq13o0Pd+uCp+WO/JpkLvHRVGt97RqfeGhXqAcorYo1ypJSpkV+WDT0vY/kmh/p7wRdJNJtuyK540PXDw==", ++ "dependencies": { ++ "schema-utils": "^4.0.0" ++ }, ++ "engines": { ++ "node": ">= 12.13.0" ++ }, ++ "funding": { ++ "type": "opencollective", ++ "url": "https://opencollective.com/webpack" ++ }, ++ "peerDependencies": { ++ "webpack": "^5.0.0" ++ } ++ }, ++ "node_modules/mini-css-extract-plugin/node_modules/ajv": { ++ "version": "8.12.0", ++ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", ++ "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", ++ "dependencies": { ++ "fast-deep-equal": "^3.1.1", ++ "json-schema-traverse": "^1.0.0", ++ "require-from-string": "^2.0.2", ++ "uri-js": "^4.2.2" ++ }, ++ "funding": { ++ "type": "github", ++ "url": "https://github.com/sponsors/epoberezkin" ++ } ++ }, ++ "node_modules/mini-css-extract-plugin/node_modules/ajv-keywords": { ++ "version": "5.1.0", ++ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", ++ "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", ++ "dependencies": { ++ "fast-deep-equal": "^3.1.3" ++ }, ++ "peerDependencies": { ++ "ajv": "^8.8.2" ++ } ++ }, ++ "node_modules/mini-css-extract-plugin/node_modules/json-schema-traverse": { ++ "version": "1.0.0", ++ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", ++ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" ++ }, ++ "node_modules/mini-css-extract-plugin/node_modules/schema-utils": { ++ "version": "4.0.0", ++ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", ++ "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", ++ "dependencies": { ++ "@types/json-schema": "^7.0.9", ++ "ajv": "^8.8.0", ++ "ajv-formats": "^2.1.1", ++ "ajv-keywords": "^5.0.0" ++ }, ++ "engines": { ++ "node": ">= 12.13.0" ++ }, ++ "funding": { ++ "type": "opencollective", ++ "url": "https://opencollective.com/webpack" ++ } ++ }, ++ "node_modules/minimatch": { ++ "version": "3.1.2", ++ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", ++ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", ++ "dependencies": { ++ "brace-expansion": "^1.1.7" ++ }, ++ "engines": { ++ "node": "*" ++ } ++ }, ++ "node_modules/minipass": { ++ "version": "3.3.6", ++ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", ++ "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", ++ "dependencies": { ++ "yallist": "^4.0.0" ++ }, ++ "engines": { ++ "node": ">=8" ++ } ++ }, ++ "node_modules/minipass-collect": { ++ "version": "1.0.2", ++ "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", ++ "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", ++ "dependencies": { ++ "minipass": "^3.0.0" ++ }, ++ "engines": { ++ "node": ">= 8" ++ } ++ }, ++ "node_modules/minipass-flush": { ++ "version": "1.0.5", ++ "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", ++ "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", ++ "dependencies": { ++ "minipass": "^3.0.0" ++ }, ++ "engines": { ++ "node": ">= 8" ++ } ++ }, ++ "node_modules/minipass-pipeline": { ++ "version": "1.2.4", ++ "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", ++ "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", ++ "dependencies": { ++ "minipass": "^3.0.0" ++ }, ++ "engines": { ++ "node": ">=8" ++ } ++ }, ++ "node_modules/minizlib": { ++ "version": "2.1.2", ++ "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", ++ "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", ++ "dependencies": { ++ "minipass": "^3.0.0", ++ "yallist": "^4.0.0" ++ }, ++ "engines": { ++ "node": ">= 8" ++ } ++ }, ++ "node_modules/mkdirp": { ++ "version": "1.0.4", ++ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", ++ "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", ++ "bin": { ++ "mkdirp": "bin/cmd.js" ++ }, ++ "engines": { ++ "node": ">=10" ++ } ++ }, ++ "node_modules/ms": { ++ "version": "2.1.2", ++ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", ++ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" ++ }, ++ "node_modules/nanoid": { ++ "version": "3.3.4", ++ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", ++ "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", ++ "bin": { ++ "nanoid": "bin/nanoid.cjs" ++ }, ++ "engines": { ++ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" ++ } ++ }, ++ "node_modules/neo-async": { ++ "version": "2.6.2", ++ "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", ++ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" ++ }, ++ "node_modules/node-releases": { ++ "version": "2.0.10", ++ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz", ++ "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==" ++ }, ++ "node_modules/normalize-path": { ++ "version": "3.0.0", ++ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", ++ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", ++ "engines": { ++ "node": ">=0.10.0" ++ } ++ }, ++ "node_modules/normalize-url": { ++ "version": "6.1.0", ++ "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", ++ "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", ++ "engines": { ++ "node": ">=10" ++ }, ++ "funding": { ++ "url": "https://github.com/sponsors/sindresorhus" ++ } ++ }, ++ "node_modules/nth-check": { ++ "version": "2.1.1", ++ "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", ++ "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", ++ "dependencies": { ++ "boolbase": "^1.0.0" ++ }, ++ "funding": { ++ "url": "https://github.com/fb55/nth-check?sponsor=1" ++ } ++ }, ++ "node_modules/once": { ++ "version": "1.4.0", ++ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", ++ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", ++ "dependencies": { ++ "wrappy": "1" ++ } ++ }, ++ "node_modules/onetime": { ++ "version": "5.1.2", ++ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", ++ "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", ++ "dependencies": { ++ "mimic-fn": "^2.1.0" ++ }, ++ "engines": { ++ "node": ">=6" ++ }, ++ "funding": { ++ "url": "https://github.com/sponsors/sindresorhus" ++ } ++ }, ++ "node_modules/p-limit": { ++ "version": "2.3.0", ++ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", ++ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", ++ "dependencies": { ++ "p-try": "^2.0.0" ++ }, ++ "engines": { ++ "node": ">=6" ++ }, ++ "funding": { ++ "url": "https://github.com/sponsors/sindresorhus" ++ } ++ }, ++ "node_modules/p-locate": { ++ "version": "4.1.0", ++ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", ++ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", ++ "dependencies": { ++ "p-limit": "^2.2.0" ++ }, ++ "engines": { ++ "node": ">=8" ++ } ++ }, ++ "node_modules/p-map": { ++ "version": "3.0.0", ++ "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", ++ "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", ++ "dependencies": { ++ "aggregate-error": "^3.0.0" ++ }, ++ "engines": { ++ "node": ">=8" ++ } ++ }, ++ "node_modules/p-try": { ++ "version": "2.2.0", ++ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", ++ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", ++ "engines": { ++ "node": ">=6" ++ } ++ }, ++ "node_modules/parent-module": { ++ "version": "1.0.1", ++ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", ++ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", ++ "dependencies": { ++ "callsites": "^3.0.0" ++ }, ++ "engines": { ++ "node": ">=6" ++ } ++ }, ++ "node_modules/parse-json": { ++ "version": "5.2.0", ++ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", ++ "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", ++ "dependencies": { ++ "@babel/code-frame": "^7.0.0", ++ "error-ex": "^1.3.1", ++ "json-parse-even-better-errors": "^2.3.0", ++ "lines-and-columns": "^1.1.6" ++ }, ++ "engines": { ++ "node": ">=8" ++ }, ++ "funding": { ++ "url": "https://github.com/sponsors/sindresorhus" ++ } ++ }, ++ "node_modules/path-exists": { ++ "version": "4.0.0", ++ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", ++ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", ++ "engines": { ++ "node": ">=8" ++ } ++ }, ++ "node_modules/path-is-absolute": { ++ "version": "1.0.1", ++ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", ++ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", ++ "engines": { ++ "node": ">=0.10.0" ++ } ++ }, ++ "node_modules/path-key": { ++ "version": "3.1.1", ++ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", ++ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", ++ "dev": true, ++ "engines": { ++ "node": ">=8" ++ } ++ }, ++ "node_modules/path-parse": { ++ "version": "1.0.7", ++ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", ++ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" ++ }, ++ "node_modules/path-type": { ++ "version": "4.0.0", ++ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", ++ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", ++ "engines": { ++ "node": ">=8" ++ } ++ }, ++ "node_modules/picocolors": { ++ "version": "1.0.0", ++ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", ++ "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" ++ }, ++ "node_modules/picomatch": { ++ "version": "2.3.1", ++ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", ++ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", ++ "engines": { ++ "node": ">=8.6" ++ }, ++ "funding": { ++ "url": "https://github.com/sponsors/jonschlinkert" ++ } ++ }, ++ "node_modules/pify": { ++ "version": "2.3.0", ++ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", ++ "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", ++ "engines": { ++ "node": ">=0.10.0" ++ } ++ }, ++ "node_modules/pkg-dir": { ++ "version": "4.2.0", ++ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", ++ "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", ++ "dependencies": { ++ "find-up": "^4.0.0" ++ }, ++ "engines": { ++ "node": ">=8" ++ } ++ }, ++ "node_modules/pofile": { ++ "version": "1.1.4", ++ "resolved": "https://registry.npmjs.org/pofile/-/pofile-1.1.4.tgz", ++ "integrity": "sha512-r6Q21sKsY1AjTVVjOuU02VYKVNQGJNQHjTIvs4dEbeuuYfxgYk/DGD2mqqq4RDaVkwdSq0VEtmQUOPe/wH8X3g==" ++ }, ++ "node_modules/postcss": { ++ "version": "8.4.21", ++ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz", ++ "integrity": "sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==", ++ "funding": [ ++ { ++ "type": "opencollective", ++ "url": "https://opencollective.com/postcss/" ++ }, ++ { ++ "type": "tidelift", ++ "url": "https://tidelift.com/funding/github/npm/postcss" ++ } ++ ], ++ "dependencies": { ++ "nanoid": "^3.3.4", ++ "picocolors": "^1.0.0", ++ "source-map-js": "^1.0.2" ++ }, ++ "engines": { ++ "node": "^10 || ^12 || >=14" ++ } ++ }, ++ "node_modules/postcss-calc": { ++ "version": "8.2.4", ++ "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.2.4.tgz", ++ "integrity": "sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==", ++ "dependencies": { ++ "postcss-selector-parser": "^6.0.9", ++ "postcss-value-parser": "^4.2.0" ++ }, ++ "peerDependencies": { ++ "postcss": "^8.2.2" ++ } ++ }, ++ "node_modules/postcss-colormin": { ++ "version": "5.3.0", ++ "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.3.0.tgz", ++ "integrity": "sha512-WdDO4gOFG2Z8n4P8TWBpshnL3JpmNmJwdnfP2gbk2qBA8PWwOYcmjmI/t3CmMeL72a7Hkd+x/Mg9O2/0rD54Pg==", ++ "dependencies": { ++ "browserslist": "^4.16.6", ++ "caniuse-api": "^3.0.0", ++ "colord": "^2.9.1", ++ "postcss-value-parser": "^4.2.0" ++ }, ++ "engines": { ++ "node": "^10 || ^12 || >=14.0" ++ }, ++ "peerDependencies": { ++ "postcss": "^8.2.15" ++ } ++ }, ++ "node_modules/postcss-convert-values": { ++ "version": "5.1.3", ++ "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.1.3.tgz", ++ "integrity": "sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA==", ++ "dependencies": { ++ "browserslist": "^4.21.4", ++ "postcss-value-parser": "^4.2.0" ++ }, ++ "engines": { ++ "node": "^10 || ^12 || >=14.0" ++ }, ++ "peerDependencies": { ++ "postcss": "^8.2.15" ++ } ++ }, ++ "node_modules/postcss-discard-comments": { ++ "version": "5.1.2", ++ "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz", ++ "integrity": "sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==", ++ "engines": { ++ "node": "^10 || ^12 || >=14.0" ++ }, ++ "peerDependencies": { ++ "postcss": "^8.2.15" ++ } ++ }, ++ "node_modules/postcss-discard-duplicates": { ++ "version": "5.1.0", ++ "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz", ++ "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==", ++ "engines": { ++ "node": "^10 || ^12 || >=14.0" ++ }, ++ "peerDependencies": { ++ "postcss": "^8.2.15" ++ } ++ }, ++ "node_modules/postcss-discard-empty": { ++ "version": "5.1.1", ++ "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz", ++ "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==", ++ "engines": { ++ "node": "^10 || ^12 || >=14.0" ++ }, ++ "peerDependencies": { ++ "postcss": "^8.2.15" ++ } ++ }, ++ "node_modules/postcss-discard-overridden": { ++ "version": "5.1.0", ++ "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz", ++ "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==", ++ "engines": { ++ "node": "^10 || ^12 || >=14.0" ++ }, ++ "peerDependencies": { ++ "postcss": "^8.2.15" ++ } ++ }, ++ "node_modules/postcss-import": { ++ "version": "14.1.0", ++ "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-14.1.0.tgz", ++ "integrity": "sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==", ++ "dependencies": { ++ "postcss-value-parser": "^4.0.0", ++ "read-cache": "^1.0.0", ++ "resolve": "^1.1.7" ++ }, ++ "engines": { ++ "node": ">=10.0.0" ++ }, ++ "peerDependencies": { ++ "postcss": "^8.0.0" ++ } ++ }, ++ "node_modules/postcss-js": { ++ "version": "4.0.1", ++ "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", ++ "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", ++ "dependencies": { ++ "camelcase-css": "^2.0.1" ++ }, ++ "engines": { ++ "node": "^12 || ^14 || >= 16" ++ }, ++ "funding": { ++ "type": "opencollective", ++ "url": "https://opencollective.com/postcss/" ++ }, ++ "peerDependencies": { ++ "postcss": "^8.4.21" ++ } ++ }, ++ "node_modules/postcss-loader": { ++ "version": "4.3.0", ++ "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-4.3.0.tgz", ++ "integrity": "sha512-M/dSoIiNDOo8Rk0mUqoj4kpGq91gcxCfb9PoyZVdZ76/AuhxylHDYZblNE8o+EQ9AMSASeMFEKxZf5aU6wlx1Q==", ++ "dependencies": { ++ "cosmiconfig": "^7.0.0", ++ "klona": "^2.0.4", ++ "loader-utils": "^2.0.0", ++ "schema-utils": "^3.0.0", ++ "semver": "^7.3.4" ++ }, ++ "engines": { ++ "node": ">= 10.13.0" ++ }, ++ "funding": { ++ "type": "opencollective", ++ "url": "https://opencollective.com/webpack" ++ }, ++ "peerDependencies": { ++ "postcss": "^7.0.0 || ^8.0.1", ++ "webpack": "^4.0.0 || ^5.0.0" ++ } ++ }, ++ "node_modules/postcss-merge-longhand": { ++ "version": "5.1.7", ++ "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.1.7.tgz", ++ "integrity": "sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ==", ++ "dependencies": { ++ "postcss-value-parser": "^4.2.0", ++ "stylehacks": "^5.1.1" ++ }, ++ "engines": { ++ "node": "^10 || ^12 || >=14.0" ++ }, ++ "peerDependencies": { ++ "postcss": "^8.2.15" ++ } ++ }, ++ "node_modules/postcss-merge-rules": { ++ "version": "5.1.3", ++ "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.1.3.tgz", ++ "integrity": "sha512-LbLd7uFC00vpOuMvyZop8+vvhnfRGpp2S+IMQKeuOZZapPRY4SMq5ErjQeHbHsjCUgJkRNrlU+LmxsKIqPKQlA==", ++ "dependencies": { ++ "browserslist": "^4.21.4", ++ "caniuse-api": "^3.0.0", ++ "cssnano-utils": "^3.1.0", ++ "postcss-selector-parser": "^6.0.5" ++ }, ++ "engines": { ++ "node": "^10 || ^12 || >=14.0" ++ }, ++ "peerDependencies": { ++ "postcss": "^8.2.15" ++ } ++ }, ++ "node_modules/postcss-minify-font-values": { ++ "version": "5.1.0", ++ "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz", ++ "integrity": "sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==", ++ "dependencies": { ++ "postcss-value-parser": "^4.2.0" ++ }, ++ "engines": { ++ "node": "^10 || ^12 || >=14.0" ++ }, ++ "peerDependencies": { ++ "postcss": "^8.2.15" ++ } ++ }, ++ "node_modules/postcss-minify-gradients": { ++ "version": "5.1.1", ++ "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz", ++ "integrity": "sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==", ++ "dependencies": { ++ "colord": "^2.9.1", ++ "cssnano-utils": "^3.1.0", ++ "postcss-value-parser": "^4.2.0" ++ }, ++ "engines": { ++ "node": "^10 || ^12 || >=14.0" ++ }, ++ "peerDependencies": { ++ "postcss": "^8.2.15" ++ } ++ }, ++ "node_modules/postcss-minify-params": { ++ "version": "5.1.4", ++ "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.1.4.tgz", ++ "integrity": "sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw==", ++ "dependencies": { ++ "browserslist": "^4.21.4", ++ "cssnano-utils": "^3.1.0", ++ "postcss-value-parser": "^4.2.0" ++ }, ++ "engines": { ++ "node": "^10 || ^12 || >=14.0" ++ }, ++ "peerDependencies": { ++ "postcss": "^8.2.15" ++ } ++ }, ++ "node_modules/postcss-minify-selectors": { ++ "version": "5.2.1", ++ "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.2.1.tgz", ++ "integrity": "sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg==", ++ "dependencies": { ++ "postcss-selector-parser": "^6.0.5" ++ }, ++ "engines": { ++ "node": "^10 || ^12 || >=14.0" ++ }, ++ "peerDependencies": { ++ "postcss": "^8.2.15" ++ } ++ }, ++ "node_modules/postcss-mixins": { ++ "version": "9.0.4", ++ "resolved": "https://registry.npmjs.org/postcss-mixins/-/postcss-mixins-9.0.4.tgz", ++ "integrity": "sha512-XVq5jwQJDRu5M1XGkdpgASqLk37OqkH4JCFDXl/Dn7janOJjCTEKL+36cnRVy7bMtoBzALfO7bV7nTIsFnUWLA==", ++ "dependencies": { ++ "fast-glob": "^3.2.11", ++ "postcss-js": "^4.0.0", ++ "postcss-simple-vars": "^7.0.0", ++ "sugarss": "^4.0.1" ++ }, ++ "engines": { ++ "node": ">=14.0" ++ }, ++ "funding": { ++ "type": "opencollective", ++ "url": "https://opencollective.com/postcss/" ++ }, ++ "peerDependencies": { ++ "postcss": "^8.2.14" ++ } ++ }, ++ "node_modules/postcss-modules-extract-imports": { ++ "version": "3.0.0", ++ "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", ++ "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", ++ "engines": { ++ "node": "^10 || ^12 || >= 14" ++ }, ++ "peerDependencies": { ++ "postcss": "^8.1.0" ++ } ++ }, ++ "node_modules/postcss-modules-local-by-default": { ++ "version": "4.0.0", ++ "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz", ++ "integrity": "sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ==", ++ "dependencies": { ++ "icss-utils": "^5.0.0", ++ "postcss-selector-parser": "^6.0.2", ++ "postcss-value-parser": "^4.1.0" ++ }, ++ "engines": { ++ "node": "^10 || ^12 || >= 14" ++ }, ++ "peerDependencies": { ++ "postcss": "^8.1.0" ++ } ++ }, ++ "node_modules/postcss-modules-scope": { ++ "version": "3.0.0", ++ "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz", ++ "integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==", ++ "dependencies": { ++ "postcss-selector-parser": "^6.0.4" ++ }, ++ "engines": { ++ "node": "^10 || ^12 || >= 14" ++ }, ++ "peerDependencies": { ++ "postcss": "^8.1.0" ++ } ++ }, ++ "node_modules/postcss-modules-values": { ++ "version": "4.0.0", ++ "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", ++ "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", ++ "dependencies": { ++ "icss-utils": "^5.0.0" ++ }, ++ "engines": { ++ "node": "^10 || ^12 || >= 14" ++ }, ++ "peerDependencies": { ++ "postcss": "^8.1.0" ++ } ++ }, ++ "node_modules/postcss-nesting": { ++ "version": "10.2.0", ++ "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-10.2.0.tgz", ++ "integrity": "sha512-EwMkYchxiDiKUhlJGzWsD9b2zvq/r2SSubcRrgP+jujMXFzqvANLt16lJANC+5uZ6hjI7lpRmI6O8JIl+8l1KA==", ++ "dependencies": { ++ "@csstools/selector-specificity": "^2.0.0", ++ "postcss-selector-parser": "^6.0.10" ++ }, ++ "engines": { ++ "node": "^12 || ^14 || >=16" ++ }, ++ "funding": { ++ "type": "opencollective", ++ "url": "https://opencollective.com/csstools" ++ }, ++ "peerDependencies": { ++ "postcss": "^8.2" ++ } ++ }, ++ "node_modules/postcss-normalize-charset": { ++ "version": "5.1.0", ++ "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz", ++ "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==", ++ "engines": { ++ "node": "^10 || ^12 || >=14.0" ++ }, ++ "peerDependencies": { ++ "postcss": "^8.2.15" ++ } ++ }, ++ "node_modules/postcss-normalize-display-values": { ++ "version": "5.1.0", ++ "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz", ++ "integrity": "sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==", ++ "dependencies": { ++ "postcss-value-parser": "^4.2.0" ++ }, ++ "engines": { ++ "node": "^10 || ^12 || >=14.0" ++ }, ++ "peerDependencies": { ++ "postcss": "^8.2.15" ++ } ++ }, ++ "node_modules/postcss-normalize-positions": { ++ "version": "5.1.1", ++ "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.1.1.tgz", ++ "integrity": "sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg==", ++ "dependencies": { ++ "postcss-value-parser": "^4.2.0" ++ }, ++ "engines": { ++ "node": "^10 || ^12 || >=14.0" ++ }, ++ "peerDependencies": { ++ "postcss": "^8.2.15" ++ } ++ }, ++ "node_modules/postcss-normalize-repeat-style": { ++ "version": "5.1.1", ++ "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.1.tgz", ++ "integrity": "sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g==", ++ "dependencies": { ++ "postcss-value-parser": "^4.2.0" ++ }, ++ "engines": { ++ "node": "^10 || ^12 || >=14.0" ++ }, ++ "peerDependencies": { ++ "postcss": "^8.2.15" ++ } ++ }, ++ "node_modules/postcss-normalize-string": { ++ "version": "5.1.0", ++ "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz", ++ "integrity": "sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==", ++ "dependencies": { ++ "postcss-value-parser": "^4.2.0" ++ }, ++ "engines": { ++ "node": "^10 || ^12 || >=14.0" ++ }, ++ "peerDependencies": { ++ "postcss": "^8.2.15" ++ } ++ }, ++ "node_modules/postcss-normalize-timing-functions": { ++ "version": "5.1.0", ++ "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz", ++ "integrity": "sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==", ++ "dependencies": { ++ "postcss-value-parser": "^4.2.0" ++ }, ++ "engines": { ++ "node": "^10 || ^12 || >=14.0" ++ }, ++ "peerDependencies": { ++ "postcss": "^8.2.15" ++ } ++ }, ++ "node_modules/postcss-normalize-unicode": { ++ "version": "5.1.1", ++ "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.1.tgz", ++ "integrity": "sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA==", ++ "dependencies": { ++ "browserslist": "^4.21.4", ++ "postcss-value-parser": "^4.2.0" ++ }, ++ "engines": { ++ "node": "^10 || ^12 || >=14.0" ++ }, ++ "peerDependencies": { ++ "postcss": "^8.2.15" ++ } ++ }, ++ "node_modules/postcss-normalize-url": { ++ "version": "5.1.0", ++ "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz", ++ "integrity": "sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==", ++ "dependencies": { ++ "normalize-url": "^6.0.1", ++ "postcss-value-parser": "^4.2.0" ++ }, ++ "engines": { ++ "node": "^10 || ^12 || >=14.0" ++ }, ++ "peerDependencies": { ++ "postcss": "^8.2.15" ++ } ++ }, ++ "node_modules/postcss-normalize-whitespace": { ++ "version": "5.1.1", ++ "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz", ++ "integrity": "sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==", ++ "dependencies": { ++ "postcss-value-parser": "^4.2.0" ++ }, ++ "engines": { ++ "node": "^10 || ^12 || >=14.0" ++ }, ++ "peerDependencies": { ++ "postcss": "^8.2.15" ++ } ++ }, ++ "node_modules/postcss-ordered-values": { ++ "version": "5.1.3", ++ "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.1.3.tgz", ++ "integrity": "sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ==", ++ "dependencies": { ++ "cssnano-utils": "^3.1.0", ++ "postcss-value-parser": "^4.2.0" ++ }, ++ "engines": { ++ "node": "^10 || ^12 || >=14.0" ++ }, ++ "peerDependencies": { ++ "postcss": "^8.2.15" ++ } ++ }, ++ "node_modules/postcss-reduce-initial": { ++ "version": "5.1.1", ++ "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.1.tgz", ++ "integrity": "sha512-//jeDqWcHPuXGZLoolFrUXBDyuEGbr9S2rMo19bkTIjBQ4PqkaO+oI8wua5BOUxpfi97i3PCoInsiFIEBfkm9w==", ++ "dependencies": { ++ "browserslist": "^4.21.4", ++ "caniuse-api": "^3.0.0" ++ }, ++ "engines": { ++ "node": "^10 || ^12 || >=14.0" ++ }, ++ "peerDependencies": { ++ "postcss": "^8.2.15" ++ } ++ }, ++ "node_modules/postcss-reduce-transforms": { ++ "version": "5.1.0", ++ "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz", ++ "integrity": "sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==", ++ "dependencies": { ++ "postcss-value-parser": "^4.2.0" ++ }, ++ "engines": { ++ "node": "^10 || ^12 || >=14.0" ++ }, ++ "peerDependencies": { ++ "postcss": "^8.2.15" ++ } ++ }, ++ "node_modules/postcss-selector-parser": { ++ "version": "6.0.11", ++ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz", ++ "integrity": "sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==", ++ "dependencies": { ++ "cssesc": "^3.0.0", ++ "util-deprecate": "^1.0.2" ++ }, ++ "engines": { ++ "node": ">=4" ++ } ++ }, ++ "node_modules/postcss-simple-vars": { ++ "version": "7.0.1", ++ "resolved": "https://registry.npmjs.org/postcss-simple-vars/-/postcss-simple-vars-7.0.1.tgz", ++ "integrity": "sha512-5GLLXaS8qmzHMOjVxqkk1TZPf1jMqesiI7qLhnlyERalG0sMbHIbJqrcnrpmZdKCLglHnRHoEBB61RtGTsj++A==", ++ "engines": { ++ "node": ">=14.0" ++ }, ++ "funding": { ++ "type": "opencollective", ++ "url": "https://opencollective.com/postcss/" ++ }, ++ "peerDependencies": { ++ "postcss": "^8.2.1" ++ } ++ }, ++ "node_modules/postcss-svgo": { ++ "version": "5.1.0", ++ "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.1.0.tgz", ++ "integrity": "sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==", ++ "dependencies": { ++ "postcss-value-parser": "^4.2.0", ++ "svgo": "^2.7.0" ++ }, ++ "engines": { ++ "node": "^10 || ^12 || >=14.0" ++ }, ++ "peerDependencies": { ++ "postcss": "^8.2.15" ++ } ++ }, ++ "node_modules/postcss-unique-selectors": { ++ "version": "5.1.1", ++ "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz", ++ "integrity": "sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==", ++ "dependencies": { ++ "postcss-selector-parser": "^6.0.5" ++ }, ++ "engines": { ++ "node": "^10 || ^12 || >=14.0" ++ }, ++ "peerDependencies": { ++ "postcss": "^8.2.15" ++ } ++ }, ++ "node_modules/postcss-value-parser": { ++ "version": "4.2.0", ++ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", ++ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" ++ }, ++ "node_modules/promise-inflight": { ++ "version": "1.0.1", ++ "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", ++ "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==" ++ }, ++ "node_modules/punycode": { ++ "version": "2.3.0", ++ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", ++ "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", ++ "engines": { ++ "node": ">=6" ++ } ++ }, ++ "node_modules/queue-microtask": { ++ "version": "1.2.3", ++ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", ++ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", ++ "funding": [ ++ { ++ "type": "github", ++ "url": "https://github.com/sponsors/feross" ++ }, ++ { ++ "type": "patreon", ++ "url": "https://www.patreon.com/feross" ++ }, ++ { ++ "type": "consulting", ++ "url": "https://feross.org/support" ++ } ++ ] ++ }, ++ "node_modules/randombytes": { ++ "version": "2.1.0", ++ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", ++ "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", ++ "dependencies": { ++ "safe-buffer": "^5.1.0" ++ } ++ }, ++ "node_modules/raw-loader": { ++ "version": "4.0.2", ++ "resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-4.0.2.tgz", ++ "integrity": "sha512-ZnScIV3ag9A4wPX/ZayxL/jZH+euYb6FcUinPcgiQW0+UBtEv0O6Q3lGd3cqJ+GHH+rksEv3Pj99oxJ3u3VIKA==", ++ "dependencies": { ++ "loader-utils": "^2.0.0", ++ "schema-utils": "^3.0.0" ++ }, ++ "engines": { ++ "node": ">= 10.13.0" ++ }, ++ "funding": { ++ "type": "opencollective", ++ "url": "https://opencollective.com/webpack" ++ }, ++ "peerDependencies": { ++ "webpack": "^4.0.0 || ^5.0.0" ++ } ++ }, ++ "node_modules/read-cache": { ++ "version": "1.0.0", ++ "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", ++ "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", ++ "dependencies": { ++ "pify": "^2.3.0" ++ } ++ }, ++ "node_modules/readable-stream": { ++ "version": "3.6.0", ++ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", ++ "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", ++ "dependencies": { ++ "inherits": "^2.0.3", ++ "string_decoder": "^1.1.1", ++ "util-deprecate": "^1.0.1" ++ }, ++ "engines": { ++ "node": ">= 6" ++ } ++ }, ++ "node_modules/readdirp": { ++ "version": "3.6.0", ++ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", ++ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", ++ "dependencies": { ++ "picomatch": "^2.2.1" ++ }, ++ "engines": { ++ "node": ">=8.10.0" ++ } ++ }, ++ "node_modules/rechoir": { ++ "version": "0.6.2", ++ "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", ++ "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", ++ "dependencies": { ++ "resolve": "^1.1.6" ++ }, ++ "engines": { ++ "node": ">= 0.10" ++ } ++ }, ++ "node_modules/require-from-string": { ++ "version": "2.0.2", ++ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", ++ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", ++ "engines": { ++ "node": ">=0.10.0" ++ } ++ }, ++ "node_modules/resolve": { ++ "version": "1.22.1", ++ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", ++ "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", ++ "dependencies": { ++ "is-core-module": "^2.9.0", ++ "path-parse": "^1.0.7", ++ "supports-preserve-symlinks-flag": "^1.0.0" ++ }, ++ "bin": { ++ "resolve": "bin/resolve" ++ }, ++ "funding": { ++ "url": "https://github.com/sponsors/ljharb" ++ } ++ }, ++ "node_modules/resolve-cwd": { ++ "version": "3.0.0", ++ "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", ++ "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", ++ "dev": true, ++ "dependencies": { ++ "resolve-from": "^5.0.0" ++ }, ++ "engines": { ++ "node": ">=8" ++ } ++ }, ++ "node_modules/resolve-cwd/node_modules/resolve-from": { ++ "version": "5.0.0", ++ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", ++ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", ++ "dev": true, ++ "engines": { ++ "node": ">=8" ++ } ++ }, ++ "node_modules/resolve-from": { ++ "version": "4.0.0", ++ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", ++ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", ++ "engines": { ++ "node": ">=4" ++ } ++ }, ++ "node_modules/restore-cursor": { ++ "version": "3.1.0", ++ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", ++ "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", ++ "dependencies": { ++ "onetime": "^5.1.0", ++ "signal-exit": "^3.0.2" ++ }, ++ "engines": { ++ "node": ">=8" ++ } ++ }, ++ "node_modules/reusify": { ++ "version": "1.0.4", ++ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", ++ "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", ++ "engines": { ++ "iojs": ">=1.0.0", ++ "node": ">=0.10.0" ++ } ++ }, ++ "node_modules/rimraf": { ++ "version": "3.0.2", ++ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", ++ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", ++ "dependencies": { ++ "glob": "^7.1.3" ++ }, ++ "bin": { ++ "rimraf": "bin.js" ++ }, ++ "funding": { ++ "url": "https://github.com/sponsors/isaacs" ++ } ++ }, ++ "node_modules/run-parallel": { ++ "version": "1.2.0", ++ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", ++ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", ++ "funding": [ ++ { ++ "type": "github", ++ "url": "https://github.com/sponsors/feross" ++ }, ++ { ++ "type": "patreon", ++ "url": "https://www.patreon.com/feross" ++ }, ++ { ++ "type": "consulting", ++ "url": "https://feross.org/support" ++ } ++ ], ++ "dependencies": { ++ "queue-microtask": "^1.2.2" ++ } ++ }, ++ "node_modules/safe-buffer": { ++ "version": "5.2.1", ++ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", ++ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", ++ "funding": [ ++ { ++ "type": "github", ++ "url": "https://github.com/sponsors/feross" ++ }, ++ { ++ "type": "patreon", ++ "url": "https://www.patreon.com/feross" ++ }, ++ { ++ "type": "consulting", ++ "url": "https://feross.org/support" ++ } ++ ] ++ }, ++ "node_modules/sass": { ++ "version": "1.58.0", ++ "resolved": "https://registry.npmjs.org/sass/-/sass-1.58.0.tgz", ++ "integrity": "sha512-PiMJcP33DdKtZ/1jSjjqVIKihoDc6yWmYr9K/4r3fVVIEDAluD0q7XZiRKrNJcPK3qkLRF/79DND1H5q1LBjgg==", ++ "dependencies": { ++ "chokidar": ">=3.0.0 <4.0.0", ++ "immutable": "^4.0.0", ++ "source-map-js": ">=0.6.2 <2.0.0" ++ }, ++ "bin": { ++ "sass": "sass.js" ++ }, ++ "engines": { ++ "node": ">=12.0.0" ++ } ++ }, ++ "node_modules/sass-loader": { ++ "version": "13.2.0", ++ "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-13.2.0.tgz", ++ "integrity": "sha512-JWEp48djQA4nbZxmgC02/Wh0eroSUutulROUusYJO9P9zltRbNN80JCBHqRGzjd4cmZCa/r88xgfkjGD0TXsHg==", ++ "dependencies": { ++ "klona": "^2.0.4", ++ "neo-async": "^2.6.2" ++ }, ++ "engines": { ++ "node": ">= 14.15.0" ++ }, ++ "funding": { ++ "type": "opencollective", ++ "url": "https://opencollective.com/webpack" ++ }, ++ "peerDependencies": { ++ "fibers": ">= 3.1.0", ++ "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0", ++ "sass": "^1.3.0", ++ "sass-embedded": "*", ++ "webpack": "^5.0.0" ++ }, ++ "peerDependenciesMeta": { ++ "fibers": { ++ "optional": true ++ }, ++ "node-sass": { ++ "optional": true ++ }, ++ "sass": { ++ "optional": true ++ }, ++ "sass-embedded": { ++ "optional": true ++ } ++ } ++ }, ++ "node_modules/schema-utils": { ++ "version": "3.1.1", ++ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", ++ "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", ++ "dependencies": { ++ "@types/json-schema": "^7.0.8", ++ "ajv": "^6.12.5", ++ "ajv-keywords": "^3.5.2" ++ }, ++ "engines": { ++ "node": ">= 10.13.0" ++ }, ++ "funding": { ++ "type": "opencollective", ++ "url": "https://opencollective.com/webpack" ++ } ++ }, ++ "node_modules/semver": { ++ "version": "7.3.8", ++ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", ++ "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", ++ "dependencies": { ++ "lru-cache": "^6.0.0" ++ }, ++ "bin": { ++ "semver": "bin/semver.js" ++ }, ++ "engines": { ++ "node": ">=10" ++ } ++ }, ++ "node_modules/serialize-javascript": { ++ "version": "6.0.1", ++ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", ++ "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", ++ "dependencies": { ++ "randombytes": "^2.1.0" ++ } ++ }, ++ "node_modules/shallow-clone": { ++ "version": "3.0.1", ++ "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", ++ "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", ++ "dev": true, ++ "dependencies": { ++ "kind-of": "^6.0.2" ++ }, ++ "engines": { ++ "node": ">=8" ++ } ++ }, ++ "node_modules/shebang-command": { ++ "version": "2.0.0", ++ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", ++ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", ++ "dev": true, ++ "dependencies": { ++ "shebang-regex": "^3.0.0" ++ }, ++ "engines": { ++ "node": ">=8" ++ } ++ }, ++ "node_modules/shebang-regex": { ++ "version": "3.0.0", ++ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", ++ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", ++ "dev": true, ++ "engines": { ++ "node": ">=8" ++ } ++ }, ++ "node_modules/shelljs": { ++ "version": "0.8.5", ++ "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", ++ "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", ++ "dependencies": { ++ "glob": "^7.0.0", ++ "interpret": "^1.0.0", ++ "rechoir": "^0.6.2" ++ }, ++ "bin": { ++ "shjs": "bin/shjs" ++ }, ++ "engines": { ++ "node": ">=4" ++ } ++ }, ++ "node_modules/signal-exit": { ++ "version": "3.0.7", ++ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", ++ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" ++ }, ++ "node_modules/slash": { ++ "version": "3.0.0", ++ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", ++ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", ++ "engines": { ++ "node": ">=8" ++ } ++ }, ++ "node_modules/source-list-map": { ++ "version": "2.0.1", ++ "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", ++ "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==" ++ }, ++ "node_modules/source-map": { ++ "version": "0.6.1", ++ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", ++ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", ++ "engines": { ++ "node": ">=0.10.0" ++ } ++ }, ++ "node_modules/source-map-js": { ++ "version": "1.0.2", ++ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", ++ "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", ++ "engines": { ++ "node": ">=0.10.0" ++ } ++ }, ++ "node_modules/source-map-support": { ++ "version": "0.5.21", ++ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", ++ "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", ++ "dependencies": { ++ "buffer-from": "^1.0.0", ++ "source-map": "^0.6.0" ++ } ++ }, ++ "node_modules/ssri": { ++ "version": "8.0.1", ++ "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", ++ "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", ++ "dependencies": { ++ "minipass": "^3.1.1" ++ }, ++ "engines": { ++ "node": ">= 8" ++ } ++ }, ++ "node_modules/stable": { ++ "version": "0.1.8", ++ "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", ++ "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", ++ "deprecated": "Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility" ++ }, ++ "node_modules/string_decoder": { ++ "version": "1.3.0", ++ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", ++ "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", ++ "dependencies": { ++ "safe-buffer": "~5.2.0" ++ } ++ }, ++ "node_modules/style-loader": { ++ "version": "2.0.0", ++ "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-2.0.0.tgz", ++ "integrity": "sha512-Z0gYUJmzZ6ZdRUqpg1r8GsaFKypE+3xAzuFeMuoHgjc9KZv3wMyCRjQIWEbhoFSq7+7yoHXySDJyyWQaPajeiQ==", ++ "dependencies": { ++ "loader-utils": "^2.0.0", ++ "schema-utils": "^3.0.0" ++ }, ++ "engines": { ++ "node": ">= 10.13.0" ++ }, ++ "funding": { ++ "type": "opencollective", ++ "url": "https://opencollective.com/webpack" ++ }, ++ "peerDependencies": { ++ "webpack": "^4.0.0 || ^5.0.0" ++ } ++ }, ++ "node_modules/stylehacks": { ++ "version": "5.1.1", ++ "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.1.tgz", ++ "integrity": "sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw==", ++ "dependencies": { ++ "browserslist": "^4.21.4", ++ "postcss-selector-parser": "^6.0.4" ++ }, ++ "engines": { ++ "node": "^10 || ^12 || >=14.0" ++ }, ++ "peerDependencies": { ++ "postcss": "^8.2.15" ++ } ++ }, ++ "node_modules/sugarss": { ++ "version": "4.0.1", ++ "resolved": "https://registry.npmjs.org/sugarss/-/sugarss-4.0.1.tgz", ++ "integrity": "sha512-WCjS5NfuVJjkQzK10s8WOBY+hhDxxNt/N6ZaGwxFZ+wN3/lKKFSaaKUNecULcTTvE4urLcKaZFQD8vO0mOZujw==", ++ "engines": { ++ "node": ">=12.0" ++ }, ++ "funding": { ++ "type": "opencollective", ++ "url": "https://opencollective.com/postcss/" ++ }, ++ "peerDependencies": { ++ "postcss": "^8.3.3" ++ } ++ }, ++ "node_modules/supports-color": { ++ "version": "7.2.0", ++ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", ++ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", ++ "dependencies": { ++ "has-flag": "^4.0.0" ++ }, ++ "engines": { ++ "node": ">=8" ++ } ++ }, ++ "node_modules/supports-preserve-symlinks-flag": { ++ "version": "1.0.0", ++ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", ++ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", ++ "engines": { ++ "node": ">= 0.4" ++ }, ++ "funding": { ++ "url": "https://github.com/sponsors/ljharb" ++ } ++ }, ++ "node_modules/svgo": { ++ "version": "2.8.0", ++ "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz", ++ "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==", ++ "dependencies": { ++ "@trysound/sax": "0.2.0", ++ "commander": "^7.2.0", ++ "css-select": "^4.1.3", ++ "css-tree": "^1.1.3", ++ "csso": "^4.2.0", ++ "picocolors": "^1.0.0", ++ "stable": "^0.1.8" ++ }, ++ "bin": { ++ "svgo": "bin/svgo" ++ }, ++ "engines": { ++ "node": ">=10.13.0" ++ } ++ }, ++ "node_modules/tapable": { ++ "version": "2.2.1", ++ "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", ++ "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", ++ "engines": { ++ "node": ">=6" ++ } ++ }, ++ "node_modules/tar": { ++ "version": "6.1.13", ++ "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.13.tgz", ++ "integrity": "sha512-jdIBIN6LTIe2jqzay/2vtYLlBHa3JF42ot3h1dW8Q0PaAG4v8rm0cvpVePtau5C6OKXGGcgO9q2AMNSWxiLqKw==", ++ "dependencies": { ++ "chownr": "^2.0.0", ++ "fs-minipass": "^2.0.0", ++ "minipass": "^4.0.0", ++ "minizlib": "^2.1.1", ++ "mkdirp": "^1.0.3", ++ "yallist": "^4.0.0" ++ }, ++ "engines": { ++ "node": ">=10" ++ } ++ }, ++ "node_modules/tar/node_modules/minipass": { ++ "version": "4.0.3", ++ "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.0.3.tgz", ++ "integrity": "sha512-OW2r4sQ0sI+z5ckEt5c1Tri4xTgZwYDxpE54eqWlQloQRoWtXjqt9udJ5Z4dSv7wK+nfFI7FRXyCpBSft+gpFw==", ++ "engines": { ++ "node": ">=8" ++ } ++ }, ++ "node_modules/terser": { ++ "version": "5.16.3", ++ "resolved": "https://registry.npmjs.org/terser/-/terser-5.16.3.tgz", ++ "integrity": "sha512-v8wWLaS/xt3nE9dgKEWhNUFP6q4kngO5B8eYFUuebsu7Dw/UNAnpUod6UHo04jSSkv8TzKHjZDSd7EXdDQAl8Q==", ++ "dependencies": { ++ "@jridgewell/source-map": "^0.3.2", ++ "acorn": "^8.5.0", ++ "commander": "^2.20.0", ++ "source-map-support": "~0.5.20" ++ }, ++ "bin": { ++ "terser": "bin/terser" ++ }, ++ "engines": { ++ "node": ">=10" ++ } ++ }, ++ "node_modules/terser-webpack-plugin": { ++ "version": "5.3.6", ++ "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.6.tgz", ++ "integrity": "sha512-kfLFk+PoLUQIbLmB1+PZDMRSZS99Mp+/MHqDNmMA6tOItzRt+Npe3E+fsMs5mfcM0wCtrrdU387UnV+vnSffXQ==", ++ "dependencies": { ++ "@jridgewell/trace-mapping": "^0.3.14", ++ "jest-worker": "^27.4.5", ++ "schema-utils": "^3.1.1", ++ "serialize-javascript": "^6.0.0", ++ "terser": "^5.14.1" ++ }, ++ "engines": { ++ "node": ">= 10.13.0" ++ }, ++ "funding": { ++ "type": "opencollective", ++ "url": "https://opencollective.com/webpack" ++ }, ++ "peerDependencies": { ++ "webpack": "^5.1.0" ++ }, ++ "peerDependenciesMeta": { ++ "@swc/core": { ++ "optional": true ++ }, ++ "esbuild": { ++ "optional": true ++ }, ++ "uglify-js": { ++ "optional": true ++ } ++ } ++ }, ++ "node_modules/terser/node_modules/commander": { ++ "version": "2.20.3", ++ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", ++ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" ++ }, ++ "node_modules/through2": { ++ "version": "3.0.2", ++ "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", ++ "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", ++ "dependencies": { ++ "inherits": "^2.0.4", ++ "readable-stream": "2 || 3" ++ } ++ }, ++ "node_modules/to-fast-properties": { ++ "version": "2.0.0", ++ "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", ++ "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", ++ "engines": { ++ "node": ">=4" ++ } ++ }, ++ "node_modules/to-regex-range": { ++ "version": "5.0.1", ++ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", ++ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", ++ "dependencies": { ++ "is-number": "^7.0.0" ++ }, ++ "engines": { ++ "node": ">=8.0" ++ } ++ }, ++ "node_modules/ts-loader": { ++ "version": "9.4.2", ++ "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.4.2.tgz", ++ "integrity": "sha512-OmlC4WVmFv5I0PpaxYb+qGeGOdm5giHU7HwDDUjw59emP2UYMHy9fFSDcYgSNoH8sXcj4hGCSEhlDZ9ULeDraA==", ++ "dependencies": { ++ "chalk": "^4.1.0", ++ "enhanced-resolve": "^5.0.0", ++ "micromatch": "^4.0.0", ++ "semver": "^7.3.4" ++ }, ++ "engines": { ++ "node": ">=12.0.0" ++ }, ++ "peerDependencies": { ++ "typescript": "*", ++ "webpack": "^5.0.0" ++ } ++ }, ++ "node_modules/ts-loader/node_modules/chalk": { ++ "version": "4.1.2", ++ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", ++ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", ++ "dependencies": { ++ "ansi-styles": "^4.1.0", ++ "supports-color": "^7.1.0" ++ }, ++ "engines": { ++ "node": ">=10" ++ }, ++ "funding": { ++ "url": "https://github.com/chalk/chalk?sponsor=1" ++ } ++ }, ++ "node_modules/typescript": { ++ "version": "4.9.5", ++ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", ++ "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", ++ "peer": true, ++ "bin": { ++ "tsc": "bin/tsc", ++ "tsserver": "bin/tsserver" ++ }, ++ "engines": { ++ "node": ">=4.2.0" ++ } ++ }, ++ "node_modules/unique-filename": { ++ "version": "1.1.1", ++ "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", ++ "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", ++ "dependencies": { ++ "unique-slug": "^2.0.0" ++ } ++ }, ++ "node_modules/unique-slug": { ++ "version": "2.0.2", ++ "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", ++ "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", ++ "dependencies": { ++ "imurmurhash": "^0.1.4" ++ } ++ }, ++ "node_modules/universalify": { ++ "version": "0.1.2", ++ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", ++ "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", ++ "engines": { ++ "node": ">= 4.0.0" ++ } ++ }, ++ "node_modules/update-browserslist-db": { ++ "version": "1.0.10", ++ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", ++ "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", ++ "funding": [ ++ { ++ "type": "opencollective", ++ "url": "https://opencollective.com/browserslist" ++ }, ++ { ++ "type": "tidelift", ++ "url": "https://tidelift.com/funding/github/npm/browserslist" ++ } ++ ], ++ "dependencies": { ++ "escalade": "^3.1.1", ++ "picocolors": "^1.0.0" ++ }, ++ "bin": { ++ "browserslist-lint": "cli.js" ++ }, ++ "peerDependencies": { ++ "browserslist": ">= 4.21.0" ++ } ++ }, ++ "node_modules/uri-js": { ++ "version": "4.4.1", ++ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", ++ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", ++ "dependencies": { ++ "punycode": "^2.1.0" ++ } ++ }, ++ "node_modules/util-deprecate": { ++ "version": "1.0.2", ++ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", ++ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" ++ }, ++ "node_modules/watchpack": { ++ "version": "2.4.0", ++ "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", ++ "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", ++ "dependencies": { ++ "glob-to-regexp": "^0.4.1", ++ "graceful-fs": "^4.1.2" ++ }, ++ "engines": { ++ "node": ">=10.13.0" ++ } ++ }, ++ "node_modules/webpack": { ++ "version": "5.75.0", ++ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.75.0.tgz", ++ "integrity": "sha512-piaIaoVJlqMsPtX/+3KTTO6jfvrSYgauFVdt8cr9LTHKmcq/AMd4mhzsiP7ZF/PGRNPGA8336jldh9l2Kt2ogQ==", ++ "dependencies": { ++ "@types/eslint-scope": "^3.7.3", ++ "@types/estree": "^0.0.51", ++ "@webassemblyjs/ast": "1.11.1", ++ "@webassemblyjs/wasm-edit": "1.11.1", ++ "@webassemblyjs/wasm-parser": "1.11.1", ++ "acorn": "^8.7.1", ++ "acorn-import-assertions": "^1.7.6", ++ "browserslist": "^4.14.5", ++ "chrome-trace-event": "^1.0.2", ++ "enhanced-resolve": "^5.10.0", ++ "es-module-lexer": "^0.9.0", ++ "eslint-scope": "5.1.1", ++ "events": "^3.2.0", ++ "glob-to-regexp": "^0.4.1", ++ "graceful-fs": "^4.2.9", ++ "json-parse-even-better-errors": "^2.3.1", ++ "loader-runner": "^4.2.0", ++ "mime-types": "^2.1.27", ++ "neo-async": "^2.6.2", ++ "schema-utils": "^3.1.0", ++ "tapable": "^2.1.1", ++ "terser-webpack-plugin": "^5.1.3", ++ "watchpack": "^2.4.0", ++ "webpack-sources": "^3.2.3" ++ }, ++ "bin": { ++ "webpack": "bin/webpack.js" ++ }, ++ "engines": { ++ "node": ">=10.13.0" ++ }, ++ "funding": { ++ "type": "opencollective", ++ "url": "https://opencollective.com/webpack" ++ }, ++ "peerDependenciesMeta": { ++ "webpack-cli": { ++ "optional": true ++ } ++ } ++ }, ++ "node_modules/webpack-cli": { ++ "version": "5.0.1", ++ "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.0.1.tgz", ++ "integrity": "sha512-S3KVAyfwUqr0Mo/ur3NzIp6jnerNpo7GUO6so51mxLi1spqsA17YcMXy0WOIJtBSnj748lthxC6XLbNKh/ZC+A==", ++ "dev": true, ++ "dependencies": { ++ "@discoveryjs/json-ext": "^0.5.0", ++ "@webpack-cli/configtest": "^2.0.1", ++ "@webpack-cli/info": "^2.0.1", ++ "@webpack-cli/serve": "^2.0.1", ++ "colorette": "^2.0.14", ++ "commander": "^9.4.1", ++ "cross-spawn": "^7.0.3", ++ "envinfo": "^7.7.3", ++ "fastest-levenshtein": "^1.0.12", ++ "import-local": "^3.0.2", ++ "interpret": "^3.1.1", ++ "rechoir": "^0.8.0", ++ "webpack-merge": "^5.7.3" ++ }, ++ "bin": { ++ "webpack-cli": "bin/cli.js" ++ }, ++ "engines": { ++ "node": ">=14.15.0" ++ }, ++ "funding": { ++ "type": "opencollective", ++ "url": "https://opencollective.com/webpack" ++ }, ++ "peerDependencies": { ++ "webpack": "5.x.x" ++ }, ++ "peerDependenciesMeta": { ++ "@webpack-cli/generators": { ++ "optional": true ++ }, ++ "webpack-bundle-analyzer": { ++ "optional": true ++ }, ++ "webpack-dev-server": { ++ "optional": true ++ } ++ } ++ }, ++ "node_modules/webpack-cli/node_modules/commander": { ++ "version": "9.5.0", ++ "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", ++ "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", ++ "dev": true, ++ "engines": { ++ "node": "^12.20.0 || >=14" ++ } ++ }, ++ "node_modules/webpack-cli/node_modules/interpret": { ++ "version": "3.1.1", ++ "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", ++ "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", ++ "dev": true, ++ "engines": { ++ "node": ">=10.13.0" ++ } ++ }, ++ "node_modules/webpack-cli/node_modules/rechoir": { ++ "version": "0.8.0", ++ "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", ++ "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", ++ "dev": true, ++ "dependencies": { ++ "resolve": "^1.20.0" ++ }, ++ "engines": { ++ "node": ">= 10.13.0" ++ } ++ }, ++ "node_modules/webpack-merge": { ++ "version": "5.8.0", ++ "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz", ++ "integrity": "sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==", ++ "dev": true, ++ "dependencies": { ++ "clone-deep": "^4.0.1", ++ "wildcard": "^2.0.0" ++ }, ++ "engines": { ++ "node": ">=10.0.0" ++ } ++ }, ++ "node_modules/webpack-sources": { ++ "version": "2.3.1", ++ "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.3.1.tgz", ++ "integrity": "sha512-y9EI9AO42JjEcrTJFOYmVywVZdKVUfOvDUPsJea5GIr1JOEGFVqwlY2K098fFoIjOkDzHn2AjRvM8dsBZu+gCA==", ++ "dependencies": { ++ "source-list-map": "^2.0.1", ++ "source-map": "^0.6.1" ++ }, ++ "engines": { ++ "node": ">=10.13.0" ++ } ++ }, ++ "node_modules/webpack/node_modules/webpack-sources": { ++ "version": "3.2.3", ++ "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", ++ "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", ++ "engines": { ++ "node": ">=10.13.0" ++ } ++ }, ++ "node_modules/which": { ++ "version": "2.0.2", ++ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", ++ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", ++ "dev": true, ++ "dependencies": { ++ "isexe": "^2.0.0" ++ }, ++ "bin": { ++ "node-which": "bin/node-which" ++ }, ++ "engines": { ++ "node": ">= 8" ++ } ++ }, ++ "node_modules/wildcard": { ++ "version": "2.0.0", ++ "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", ++ "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==", ++ "dev": true ++ }, ++ "node_modules/wrappy": { ++ "version": "1.0.2", ++ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", ++ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" ++ }, ++ "node_modules/yallist": { ++ "version": "4.0.0", ++ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", ++ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" ++ }, ++ "node_modules/yaml": { ++ "version": "1.10.2", ++ "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", ++ "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", ++ "engines": { ++ "node": ">= 6" ++ } ++ }, ++ "node_modules/yocto-queue": { ++ "version": "0.1.0", ++ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", ++ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", ++ "engines": { ++ "node": ">=10" ++ }, ++ "funding": { ++ "url": "https://github.com/sponsors/sindresorhus" ++ } ++ } ++ } ++} +diff --git a/package.json b/package.json +new file mode 100644 +index 0000000..48fe874 +--- /dev/null ++++ b/package.json +@@ -0,0 +1,32 @@ ++{ ++ "name": "ckeditor5-templates", ++ "version": "1.0.0", ++ "description": "CKEditor 5 plugin development.", ++ "scripts": { ++ "start": "webpack --mode development --watch", ++ "build": "webpack" ++ }, ++ "author": "", ++ "license": "GPL-2.0-or-later", ++ "dependencies": { ++ "@ckeditor/ckeditor5-basic-styles": "^35.4.0", ++ "@ckeditor/ckeditor5-dev-utils": "^32.0.2", ++ "@ckeditor/ckeditor5-editor-classic": "^35.4.0", ++ "@ckeditor/ckeditor5-engine": "^35.4.0", ++ "@ckeditor/ckeditor5-essentials": "^35.4.0", ++ "@ckeditor/ckeditor5-html-support": "^35.4.0", ++ "@ckeditor/ckeditor5-paragraph": "^35.4.0", ++ "@ckeditor/ckeditor5-theme-lark": "^35.4.0", ++ "ckeditor5": "^35.4.0", ++ "css-loader": "^5.2.7", ++ "mini-css-extract-plugin": "^2.7.2", ++ "postcss-loader": "^4.3.0", ++ "raw-loader": "^4.0.2", ++ "sass": "^1.58.0", ++ "sass-loader": "^13.2.0", ++ "style-loader": "^2.0.0", ++ "terser-webpack-plugin": "^5.3.6", ++ "webpack": "^5.75.0", ++ "webpack-cli": "^5.0.1" ++ } ++} +diff --git a/sass/dialog.scss b/sass/dialog.scss +new file mode 100644 +index 0000000..8460c4a +--- /dev/null ++++ b/sass/dialog.scss +@@ -0,0 +1,47 @@ ++.ckeditor-templates-widget-modal { ++ .form-radios { ++ margin: 0; ++ padding: 0; ++ ++ .form-type-radio.form-item-templates, ++ .form-type--radio.form-item--templates { ++ margin: 0; ++ padding: 0; ++ ++ input { ++ display: none; ++ } ++ ++ label { ++ display: flex; ++ margin-top: 0.75rem; ++ padding: 0.75rem; ++ border: #bcbcbc 1px solid; ++ align-items: flex-start; ++ user-select: none; ++ ++ &:hover { ++ background-color: #efefef; ++ } ++ ++ img { ++ width: 5rem; ++ margin-right: 0.75rem; ++ } ++ ++ div { ++ line-height: 1.2rem; ++ ++ strong { ++ display: block; ++ } ++ } ++ } ++ ++ input:checked + label { ++ border: #ff9933 1px solid; ++ background-color: #fffacd; ++ } ++ } ++ } ++} +diff --git a/src/CKEditorTemplatesInterface.php b/src/CKEditorTemplatesInterface.php +new file mode 100644 +index 0000000..e66ee54 +--- /dev/null ++++ b/src/CKEditorTemplatesInterface.php +@@ -0,0 +1,12 @@ ++messenger = $messenger; ++ } ++ ++ /** ++ * {@inheritdoc} ++ */ ++ public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type): CKEditorTemplatesListBuilder | EntityListBuilder | EntityHandlerInterface | static { ++ return new static( ++ $entity_type, ++ $container->get('entity_type.manager')->getStorage($entity_type->id()), ++ $container->get('messenger') ++ ); ++ } ++ ++ /** ++ * {@inheritdoc} ++ */ ++ public function getFormId(): string { ++ return 'ckeditor_templates_entity_list'; ++ } ++ ++ /** ++ * {@inheritdoc} ++ */ ++ public function buildHeader(): array { ++ $header['label'] = $this->t('Label'); ++ $header['id'] = $this->t('Machine name'); ++ $header['status'] = $this->t('Status'); ++ $header['formats'] = $this->t('Formats'); ++ ++ return $header + parent::buildHeader(); ++ } ++ ++ /** ++ * {@inheritdoc} ++ */ ++ public function buildRow(EntityInterface $entity): array { ++ $formats = []; ++ $formatOptions = $entity->get('formats'); ++ foreach (filter_formats() as $format) { ++ if (in_array($format->id(), $formatOptions)) { ++ $formats[] = $format->label(); ++ } ++ } ++ ++ $row['label'] = $entity->label(); ++ $row['id']['#markup'] = $entity->id(); ++ $row['status']['#markup'] = $entity->status() ? $this->t('Enabled') : $this->t('Disabled'); ++ $row['formats']['#markup'] = implode(', ', $formats); ++ ++ return $row + parent::buildRow($entity); ++ } ++ ++ /** ++ * {@inheritdoc} ++ */ ++ public function submitForm(array &$form, FormStateInterface $form_state) { ++ parent::submitForm($form, $form_state); ++ $this->messenger->addStatus($this->t('The CKEditor Template Configuration settings have been updated.')); ++ } ++ ++} +diff --git a/src/Entity/CKEditorTemplates.php b/src/Entity/CKEditorTemplates.php +new file mode 100644 +index 0000000..3ed62ec +--- /dev/null ++++ b/src/Entity/CKEditorTemplates.php +@@ -0,0 +1,133 @@ ++weight)) { ++ $templates = $storage->loadMultiple(); ++ if (empty($templates)) { ++ $this->weight = 0; ++ } ++ else { ++ $weights = array_column($templates, 'weight'); ++ $this->weight = max($weights) + 1; ++ } ++ } ++ } ++ ++} +diff --git a/src/Form/CKEditorTemplatesDialogForm.php b/src/Form/CKEditorTemplatesDialogForm.php +new file mode 100644 +index 0000000..b9b5b62 +--- /dev/null ++++ b/src/Form/CKEditorTemplatesDialogForm.php +@@ -0,0 +1,285 @@ ++entityTypeManager = $entity_type_manager; ++ $this->fileUrlGenerator = $file_url_generator; ++ $this->moduleFolder = '/' . $extension_list_module->getPath('ckeditor_templates'); ++ $this->templates = []; ++ ++ // Load the templates. ++ $templates = $this->getTemplates(); ++ foreach ($templates as $format) { ++ $this->templates[$format->id()] = [ ++ 'label' => $format->label(), ++ 'formats' => $format->get('formats') ?? [], ++ 'thumb' => $this->getThumb($format->get('thumb')[0] ?? ''), ++ 'description' => $format->get('description') ?? '', ++ 'code' => $format->get('code') ?? '', ++ ]; ++ } ++ } ++ ++ /** ++ * {@inheritdoc} ++ */ ++ public static function create(ContainerInterface $container): CKEditorTemplatesDialogForm | static { ++ return new static( ++ $container->get('entity_type.manager'), ++ $container->get('file_url_generator'), ++ $container->get('extension.list.module') ++ ); ++ } ++ ++ /** ++ * Loads the CKEditor Templates. ++ * ++ * @return \Drupal\Core\Entity\EntityInterface[] ++ * A list of CKEditor Template entities. ++ * ++ * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException ++ * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException ++ */ ++ private function getTemplates(): array { ++ $storage = $this->entityTypeManager ++ ->getStorage('ckeditor_templates'); ++ ++ $nids = $storage->getQuery() ++ ->condition('status', 1) ++ ->sort('weight', 'ASC') ++ ->execute(); ++ ++ return $storage->loadMultiple($nids); ++ } ++ ++ /** ++ * Gets the thumbnail for an image. ++ * ++ * @param string $thumb ++ * The thumb image id. ++ * ++ * @return string ++ * The thumb image URL. ++ * ++ * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException ++ * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException ++ */ ++ private function getThumb(string $thumb): string { ++ $image = ''; ++ ++ if (!empty($thumb)) { ++ $file = $this->entityTypeManager ++ ->getStorage('file') ++ ->load($thumb); ++ ++ if (isset($file)) { ++ $fileUri = $file->getFileUri(); ++ ++ $style = $this->entityTypeManager ++ ->getStorage('image_style') ++ ->load('thumbnail'); ++ if (isset($style)) { ++ $image = $style->buildUrl($fileUri) ?? ''; ++ } ++ else { ++ $image = $this->fileUrlGenerator->generateAbsoluteString($fileUri) ?? ''; ++ } ++ } ++ } ++ ++ if (empty($image)) { ++ $image = $this->moduleFolder . '/js/plugin/theme/images/placeholder.svg'; ++ } ++ ++ return $image; ++ } ++ ++ /** ++ * {@inheritdoc} ++ */ ++ public function getFormId(): string { ++ return 'ckeditor_templates__dialog_form'; ++ } ++ ++ /** ++ * {@inheritdoc} ++ */ ++ public function buildForm(array $form, FormStateInterface $form_state, string $editor_id = ''): array { ++ $templates = []; ++ ++ // Gets the templates. ++ foreach ($this->templates as $key => $template) { ++ if (in_array($editor_id, $template['formats'])) { ++ $templates[$key] = ' ++ ' . $template['label'] . ' ++
++ ' . $template['label'] . ' ++ ' . $template['description'] . ' ++
++ '; ++ } ++ } ++ ++ // Gets the editor. ++ try { ++ $editor = $this->entityTypeManager ++ ->getStorage('editor') ++ ->load($editor_id); ++ } ++ catch (InvalidPluginDefinitionException | PluginNotFoundException $e) { ++ $this->logger('templates')->critical($e->getMessage()); ++ } ++ ++ // Validate there are templates. ++ if (empty($templates) || !isset($editor)) { ++ $form['warning'] = [ ++ '#type' => 'markup', ++ '#markup' => $this->t('There is no template available for the @formatLabel text format.', [ ++ '@formatLabel' => $editor?->label() ?? $editor_id, ++ ]), ++ ]; ++ ++ return $form; ++ } ++ ++ // List the templates. ++ $form['label'] = [ ++ '#type' => 'html_tag', ++ '#tag' => 'div', ++ '#value' => 'Select the template to open in the editor:', ++ ]; ++ ++ $form['templates'] = [ ++ '#type' => 'radios', ++ '#options' => $templates, ++ ]; ++ ++ $settings = $editor->getSettings(); ++ $replace_content = $settings['plugins']['ckeditor_templates_plugin']['replace_content'] ?? FALSE; ++ $form['replace_content'] = [ ++ '#title' => $this->t('Replace actual contents'), ++ '#type' => 'checkbox', ++ '#default_value' => $replace_content, ++ '#description' => $this->t('Remove the actual contents, keeping only the selected template.'), ++ ]; ++ ++ $form['actions'] = [ ++ '#type' => 'actions', ++ 'submit' => [ ++ '#type' => 'submit', ++ '#value' => $this->t('Insert'), ++ '#ajax' => [ ++ 'callback' => [$this, 'ajaxSubmitForm'], ++ 'wrapper' => $this->ajaxWrapper, ++ ], ++ ], ++ ]; ++ ++ return $form; ++ } ++ ++ /** ++ * AJAX callback function for inserting HTML code into the CKEditor. ++ * ++ * @param array $form ++ * The form. ++ * @param \Drupal\Core\Form\FormStateInterface $form_state ++ * The form state. ++ * ++ * @return \Drupal\Core\Ajax\AjaxResponse|array ++ * AJAX response. ++ */ ++ public function ajaxSubmitForm(array &$form, FormStateInterface $form_state): AjaxResponse | array { ++ $response = new AjaxResponse(); ++ ++ $template = $form_state->getValue('templates'); ++ if (isset($template)) { ++ $htmlCode = $this->templates[$template]['code'] ?? ''; ++ if (!empty($htmlCode)) { ++ $response->addCommand(new EditorDialogSave([ ++ 'htmlCode' => $htmlCode, ++ 'replace' => $form_state->getValue('replace_content'), ++ ])); ++ } ++ } ++ ++ $response->addCommand(new CloseModalDialogCommand()); ++ ++ return $response; ++ } ++ ++ /** ++ * {@inheritdoc} ++ */ ++ public function submitForm(array &$form, FormStateInterface $form_state) { ++ // This function is required by Drupal, but the request is being ++ // handled in the ajaxSubmitForm() function. ++ } ++ ++} +diff --git a/src/Form/CKEditorTemplatesEntityForm.php b/src/Form/CKEditorTemplatesEntityForm.php +new file mode 100644 +index 0000000..21eda65 +--- /dev/null ++++ b/src/Form/CKEditorTemplatesEntityForm.php +@@ -0,0 +1,139 @@ ++fileSystem = $file_system; ++ } ++ ++ /** ++ * {@inheritdoc} ++ */ ++ public static function create(ContainerInterface $container) { ++ return new static( ++ $container->get('file_system') ++ ); ++ } ++ ++ /** ++ * {@inheritdoc} ++ */ ++ public function form(array $form, FormStateInterface $form_state) { ++ $form = parent::form($form, $form_state); ++ ++ // Gets the allowed format options. ++ $allowedFormatOptions = []; ++ foreach (filter_formats() as $format) { ++ $editor = editor_load($format->id()); ++ if (isset($editor) && $editor->getEditor() === 'ckeditor5') { ++ $allowedFormatOptions[$format->id()] = $format->label(); ++ } ++ } ++ ++ $form['label'] = [ ++ '#type' => 'textfield', ++ '#title' => $this->t('Label'), ++ '#maxlength' => 255, ++ '#default_value' => $this->entity->label(), ++ '#required' => TRUE, ++ ]; ++ ++ $form['id'] = [ ++ '#type' => 'machine_name', ++ '#default_value' => $this->entity->id(), ++ '#machine_name' => [ ++ 'exists' => '\Drupal\ckeditor_templates\Entity\CKEditorTemplates::load', ++ ], ++ '#disabled' => !$this->entity->isNew(), ++ '#required' => TRUE, ++ ]; ++ ++ $form['description'] = [ ++ '#type' => 'textarea', ++ '#title' => $this->t('Description'), ++ '#default_value' => $this->entity->get('description'), ++ ]; ++ ++ $form['thumb'] = [ ++ '#type' => 'managed_file', ++ '#title' => $this->t('Illustration Image/Icon'), ++ '#default_value' => $this->entity->get('thumb'), ++ '#description' => $this->t('Allowed types: png jpeg jpg gif'), ++ '#upload_location' => 'public://ckeditor-templates', ++ '#upload_validators' => [ ++ 'file_validate_extensions' => ['gif png jpg jpeg'], ++ ], ++ '#cardinality' => 1, ++ ]; ++ ++ $form['code'] = [ ++ '#type' => 'textarea', ++ '#title' => $this->t('HTML Code'), ++ '#default_value' => $this->entity->get('code'), ++ '#description' => $this->t('The HTML code to be injected into the CKEditor.'), ++ '#required' => TRUE, ++ ]; ++ ++ $form['formats'] = [ ++ '#type' => 'checkboxes', ++ '#title' => $this->t('Available For'), ++ '#default_value' => $this->entity->get('formats') ?? [], ++ '#options' => $allowedFormatOptions, ++ '#required' => TRUE, ++ ]; ++ ++ $form['status'] = [ ++ '#type' => 'checkbox', ++ '#title' => $this->t('Enabled'), ++ '#default_value' => $this->entity->status(), ++ ]; ++ ++ return $form; ++ } ++ ++ /** ++ * {@inheritdoc} ++ */ ++ public function save(array $form, FormStateInterface $form_state) { ++ $template = $this->entity; ++ $status = $template->save(); ++ ++ if ($status) { ++ $this->messenger()->addMessage($this->t('Saved the %label CKEditor Template.', [ ++ '%label' => $template->label(), ++ ])); ++ } ++ else { ++ $this->messenger()->addMessage($this->t('The %label CKEditor Template was not saved.', [ ++ '%label' => $template->label(), ++ ])); ++ } ++ ++ $form_state->setRedirectUrl($this->entity->toUrl('collection')); ++ ++ return $status; ++ } ++ ++} +diff --git a/src/Plugin/CKEditor5Plugin/CKEditorTemplatesDialog.php b/src/Plugin/CKEditor5Plugin/CKEditorTemplatesDialog.php +new file mode 100644 +index 0000000..d504e0a +--- /dev/null ++++ b/src/Plugin/CKEditor5Plugin/CKEditorTemplatesDialog.php +@@ -0,0 +1,68 @@ ++ FALSE]; ++ } ++ ++ /** ++ * {@inheritdoc} ++ */ ++ public function buildConfigurationForm(array $form, FormStateInterface $form_state): array { ++ $form['replace_content'] = [ ++ '#type' => 'checkbox', ++ '#title' => $this->t('Replace content default value'), ++ '#default_value' => $this->configuration['replace_content'] ?? FALSE, ++ '#description' => $this->t('Whether the "Replace actual contents" checkbox is checked by default in the Templates dialog.'), ++ ]; ++ ++ return $form; ++ } ++ ++ /** ++ * {@inheritdoc} ++ */ ++ public function validateConfigurationForm(array &$form, FormStateInterface $form_state) { ++ $form_value = $form_state->getValue('replace_content'); ++ $form_state->setValue('replace_content', (bool) $form_value); ++ } ++ ++ /** ++ * {@inheritdoc} ++ */ ++ public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { ++ $this->configuration['replace_content'] = $form_state->getValue('replace_content'); ++ } ++ ++ /** ++ * {@inheritdoc} ++ */ ++ public function getDynamicPluginConfig(array $static_plugin_config, EditorInterface $editor): array { ++ $dialogUrl = Url::fromRoute('ckeditor_templates.selector', [ ++ 'editor_id' => $editor->id(), ++ ])->toString(); ++ ++ $static_plugin_config['ckeditorTemplates']['dialogUrl'] = $dialogUrl; ++ ++ return $static_plugin_config; ++ } ++ ++} +diff --git a/src/Plugin/CKEditorPlugin/CkeditorTemplates.php b/src/Plugin/CKEditorPlugin/CkeditorTemplates.php +deleted file mode 100644 +index 79e1789..0000000 +--- a/src/Plugin/CKEditorPlugin/CkeditorTemplates.php ++++ /dev/null +@@ -1,183 +0,0 @@ +-get('config.factory') +- ); +- } +- +- /** +- * Constructs a Drupal\Component\Plugin\PluginBase object. +- * +- * @param array $configuration +- * A configuration array containing information about the plugin instance. +- * @param string $plugin_id +- * The plugin_id for the plugin instance. +- * @param mixed $plugin_definition +- * The plugin implementation definition. +- * @param \Drupal\Core\Config\ConfigFactory $configFactoryService +- * Drupal Configuration Factory Service. +- */ +- public function __construct(array $configuration, $plugin_id, $plugin_definition, ConfigFactory $configFactoryService) { +- parent::__construct($configuration, $plugin_id, $plugin_definition); +- +- $this->configFactoryService = $configFactoryService; +- } +- +- /** +- * {@inheritdoc} +- */ +- public function getFile() { +- return $this->getTemplatesPluginPath() . '/plugin.js'; +- } +- +- /** +- * {@inheritdoc} +- */ +- public function getLibraries(Editor $editor) { +- return ['ckeditor_templates/ckeditor.templates.dialog']; +- } +- +- /** +- * {@inheritdoc} +- */ +- public function getButtons() { +- return [ +- 'Templates' => [ +- 'label' => t('Templates'), +- 'image' => $this->getTemplatesPluginPath() . '/icons/templates.png', +- ], +- ]; +- } +- +- /** +- * {@inheritdoc} +- */ +- public function getConfig(Editor $editor) { +- $config = []; +- $settings = $editor->getSettings(); +- // Set replace content default value if set. +- if (isset($settings['plugins']['templates']['replace_content'])) { +- $config['templates_replaceContent'] = $settings['plugins']['templates']['replace_content']; +- } +- // Set template files default value if set. +- if (isset($settings['plugins']['templates']['template_path']) && !empty($settings['plugins']['templates']['template_path'])) { +- $config['templates_files'] = [$settings['plugins']['templates']['template_path']]; +- } +- else { +- // Use templates plugin default file. +- $config['templates_files'] = $this->getTemplatesDefaultPath(); +- } +- return $config; +- } +- +- /** +- * {@inheritdoc} +- */ +- public function settingsForm(array $form, FormStateInterface $form_state, Editor $editor) { +- // Defaults. +- $config = [ +- 'replace_content' => FALSE, +- 'template_path' => '', +- ]; +- +- $settings = $editor->getSettings(); +- +- if (isset($settings['plugins']['templates'])) { +- $config = $settings['plugins']['templates']; +- } +- +- $form['template_path'] = [ +- '#title' => t('Template definition file'), +- '#type' => 'textfield', +- '#default_value' => $config['template_path'], +- '#description' => t('Path to the javascript file defining the templates, relative to drupal root (starting with "/"). By default, it looks in your default theme directory for a file named "templates/ckeditor_templates.js"'), +- ]; +- +- $form['replace_content'] = [ +- '#title' => t('Replace content default value'), +- '#type' => 'checkbox', +- '#default_value' => $config['replace_content'], +- '#description' => t('Whether the "Replace actual contents" checkbox is checked by default in the Templates dialog'), +- ]; +- +- $form['#attached']['library'][] = 'ckeditor_templates/ckeditor.templates.admin'; +- +- return $form; +- } +- +- /** +- * Return ckeditor templates plugin path relative to drupal root. +- * +- * @return string +- * Relative path to the ckeditor plugin folder +- */ +- private function getTemplatesPluginPath() { +- $pluginPath = 'libraries/ckeditor/plugins/templates'; +- +- if (!file_exists(DRUPAL_ROOT . '/' . $pluginPath)) { +- // keep supporting module legacy path to avoid breaking change +- // using this path is deprecated +- $pluginPath = 'libraries/templates'; +- } +- +- return $pluginPath; +- } +- +- /** +- * Generate the path to the template file. +- * +- * The file will be picked from : +- * - the default theme if the file exists +- * - the ckeditor template directory otherwise. +- * +- * @return array +- * List of path to the template file +- */ +- private function getTemplatesDefaultPath() { +- // Default to module folder. +- $defaultPath = base_path() . $this->getTemplatesPluginPath() . '/templates/default.js'; +- +- // Get site default theme name. +- $defaultThemConfig = $this->configFactoryService->get('system.theme'); +- $defaultThemeName = $defaultThemConfig->get('default'); +- +- $defaultThemeFileAbsolutePath = DRUPAL_ROOT . '/' . drupal_get_path('theme', $defaultThemeName) . '/templates/ckeditor_templates.js'; +- if (file_exists($defaultThemeFileAbsolutePath)) { +- $defaultPath = base_path() . drupal_get_path('theme', $defaultThemeName) . '/templates/ckeditor_templates.js'; +- } +- +- return [$defaultPath]; +- } +- +-} +diff --git a/templates/ckeditor_templates.js.example b/templates/ckeditor_templates.js.example +deleted file mode 100644 +index ffafdbc..0000000 +--- a/templates/ckeditor_templates.js.example ++++ /dev/null +@@ -1,83 +0,0 @@ +-// Override the default template set +-CKEDITOR.addTemplates( 'default', { +- // The name of sub folder which hold the shortcut preview images of the +- // templates. Determine base path of drupal installation if any +- // (ckeditor could possibly be loaded w/o drupalSettings). +- imagesPath: ((drupalSettings && drupalSettings.path) ? drupalSettings.path.baseUrl : '/') + 'themes/custom/mytheme/images/ckeditor/', +- +- // The templates definitions. +- templates: [ { +- title: 'Image and Title module', +- image: 'template1.gif', +- description: 'One main image with a title and text that surround the image.', +- html: '

' + +- // Use src=" " so image is not filtered out by the editor as incorrect (src is required). +- '' + +- 'Type the title here' + +- '

' + +- '

' + +- 'Type the text here' + +- '

' +- }, +- { +- title: 'Strange Template', +- image: 'template2.gif', +- description: 'A template that defines two colums, each one with a title, and some text.', +- html: '' + +- '' + +- '' + +- '' + +- '' + +- '' + +- '' + +- '' + +- '' + +- '' + +- '' + +- '
' + +- '

Title 1

' + +- '
' + +- '

Title 2

' + +- '
' + +- 'Text 1' + +- '' + +- 'Text 2' + +- '
' + +- '

' + +- 'More text goes here.' + +- '

' +- }, +- { +- title: 'Text and Table', +- image: 'template3.gif', +- description: 'A title with some text and a table.', +- html: '
' + +- '

' + +- 'Title goes here' + +- '

' + +- '' + +- '' + +- '' + +- '' + +- '' + +- '' + +- '' + +- '' + +- '' + +- '' + +- '' + +- '' + +- '' + +- '' + +- '' + +- '' + +- '' + +- '
' + +- 'Table title' + +- '
   
   
   
' + +- '

' + +- 'Type the text here' + +- '

' + +- '
' +- } ] +-} ); +diff --git a/webpack.config.js b/webpack.config.js +new file mode 100644 +index 0000000..e27ce74 +--- /dev/null ++++ b/webpack.config.js +@@ -0,0 +1,87 @@ ++const path = require('path'); ++const webpack = require('webpack'); ++const { styles } = require('@ckeditor/ckeditor5-dev-utils'); ++const TerserPlugin = require('terser-webpack-plugin'); ++const MiniCssExtractPlugin = require('mini-css-extract-plugin'); ++ ++const pluginName = 'ckeditorTemplates'; ++ ++module.exports = [ ++ { ++ mode: 'production', ++ optimization: { ++ minimize: true, ++ minimizer: [ ++ new TerserPlugin({ ++ terserOptions: { ++ format: { ++ comments: false ++ } ++ }, ++ test: /\.js(\?.*)?$/i, ++ extractComments: false ++ }) ++ ], ++ moduleIds: 'named' ++ }, ++ entry: { ++ path: path.resolve(__dirname, 'js/plugin/src/app.js') ++ }, ++ output: { ++ path: path.resolve(__dirname, 'js/dist'), ++ filename: `${pluginName}.js`, ++ library: ['CKEditor5', pluginName], ++ libraryTarget: 'umd', ++ libraryExport: 'default' ++ }, ++ plugins: [ ++ new webpack.DllReferencePlugin({ ++ manifest: require('./node_modules/ckeditor5/build/ckeditor5-dll.manifest.json'), ++ scope: 'ckeditor5/src', ++ name: 'CKEditor5.dll' ++ }), ++ new MiniCssExtractPlugin({ ++ filename: '../../css/cke_templates.dialog.css' ++ }) ++ ], ++ module: { ++ rules: [ ++ { ++ test: /js[/\\]plugin[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/, ++ use: ['raw-loader'] ++ }, ++ { ++ test: /js[/\\]plugin[/\\]theme[/\\][^/\\]+\.css$/, ++ use: [ ++ { ++ loader: 'style-loader', ++ options: { ++ injectType: 'singletonStyleTag', ++ attributes: { ++ 'data-cke': true ++ } ++ } ++ }, ++ { ++ loader: 'postcss-loader', ++ options: styles.getPostCssConfig({ ++ themeImporter: { ++ themePath: require.resolve('@ckeditor/ckeditor5-theme-lark') ++ }, ++ minify: true ++ }) ++ } ++ ] ++ }, ++ { ++ test: /sass[/\\][^/\\]+\.s[ac]ss$/, ++ use: [ ++ MiniCssExtractPlugin.loader, ++ 'css-loader', ++ 'sass-loader' ++ ] ++ } ++ ] ++ } ++ } ++]; +-- +GitLab + + +From 0c57ea2b14d6d737a5182820368f9cbd5dcaa656 Mon Sep 17 00:00:00 2001 +From: Marcelo Hespanhol <61546-mhespanhol@users.noreply.drupalcode.org> +Date: Tue, 7 Mar 2023 18:37:22 +0000 +Subject: [PATCH 02/11] Sets the image as permanent + +--- + src/Form/CKEditorTemplatesEntityForm.php | 61 ++++++++++++++++++++++-- + 1 file changed, 56 insertions(+), 5 deletions(-) + +diff --git a/src/Form/CKEditorTemplatesEntityForm.php b/src/Form/CKEditorTemplatesEntityForm.php +index 21eda65..6682d35 100644 +--- a/src/Form/CKEditorTemplatesEntityForm.php ++++ b/src/Form/CKEditorTemplatesEntityForm.php +@@ -3,8 +3,12 @@ + namespace Drupal\ckeditor_templates\Form; + + use Drupal\Core\Entity\EntityForm; +-use Drupal\Core\Form\FormStateInterface; ++use Drupal\Core\Entity\EntityTypeManagerInterface; + use Drupal\Core\File\FileSystemInterface; ++use Drupal\file\FileUsage\FileUsageInterface; ++use Drupal\Core\Form\FormStateInterface; ++use Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException; ++use Drupal\Component\Plugin\Exception\PluginNotFoundException; + use Psr\Container\ContainerInterface; + + /** +@@ -19,13 +23,36 @@ class CKEditorTemplatesEntityForm extends EntityForm { + * + * @var \Drupal\Core\File\FileSystemInterface + */ +- protected $fileSystem; ++ protected FileSystemInterface $fileSystem; + + /** +- * {@inheritdoc} ++ * Entity Type Manager. ++ * ++ * @var \Drupal\Core\Entity\EntityTypeManagerInterface ++ */ ++ protected $entityTypeManager; ++ ++ /** ++ * The file usage service. ++ * ++ * @var \Drupal\file\FileUsage\FileUsageInterface + */ +- public function __construct(FileSystemInterface $file_system) { ++ protected FileUsageInterface $fileUsage; ++ ++ /** ++ * Constructs a new entity form. ++ * ++ * @param \Drupal\Core\File\FileSystemInterface $file_system ++ * The file system service. ++ * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager ++ * The Entity type manager. ++ * @param \Drupal\file\FileUsage\FileUsageInterface $file_usage ++ * The file usage service. ++ */ ++ public function __construct(FileSystemInterface $file_system, EntityTypeManagerInterface $entity_type_manager, FileUsageInterface $file_usage) { + $this->fileSystem = $file_system; ++ $this->entityTypeManager = $entity_type_manager; ++ $this->fileUsage = $file_usage; + } + + /** +@@ -33,7 +60,9 @@ class CKEditorTemplatesEntityForm extends EntityForm { + */ + public static function create(ContainerInterface $container) { + return new static( +- $container->get('file_system') ++ $container->get('file_system'), ++ $container->get('entity_type.manager'), ++ $container->get('file.usage') + ); + } + +@@ -121,6 +150,28 @@ class CKEditorTemplatesEntityForm extends EntityForm { + $status = $template->save(); + + if ($status) { ++ ++ // Sets the image as permanent. ++ try { ++ $thumb = $form_state->getValue('thumb'); ++ if (!empty($thumb)) { ++ $thumb = reset($thumb); ++ ++ /** @var Drupal\file\Entity\File $file */ ++ $file = $this->entityTypeManager->getStorage('file')->load($thumb); ++ if (isset($file)) { ++ $file->setPermanent(); ++ $file->save(); ++ ++ // Add the file to the usage calculation. ++ $this->fileUsage->add($file, 'ckeditor_templates', 'media', $file->id()); ++ } ++ } ++ } ++ catch (InvalidPluginDefinitionException | PluginNotFoundException $e) { ++ $this->logger('templates')->critical($e->getMessage()); ++ } ++ + $this->messenger()->addMessage($this->t('Saved the %label CKEditor Template.', [ + '%label' => $template->label(), + ])); +-- +GitLab + + +From 47a0f901cb16846c02cd37197fc5596a3847540e Mon Sep 17 00:00:00 2001 +From: Gordon Heydon +Date: Mon, 13 Mar 2023 11:28:45 +1100 +Subject: [PATCH 03/11] Remove LICENSE.txt + +--- + LICENSE.txt | 339 ---------------------------------------------------- + 1 file changed, 339 deletions(-) + delete mode 100644 LICENSE.txt + +diff --git a/LICENSE.txt b/LICENSE.txt +deleted file mode 100644 +index d159169..0000000 +--- a/LICENSE.txt ++++ /dev/null +@@ -1,339 +0,0 @@ +- GNU GENERAL PUBLIC LICENSE +- Version 2, June 1991 +- +- Copyright (C) 1989, 1991 Free Software Foundation, Inc., +- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- Everyone is permitted to copy and distribute verbatim copies +- of this license document, but changing it is not allowed. +- +- Preamble +- +- The licenses for most software are designed to take away your +-freedom to share and change it. By contrast, the GNU General Public +-License is intended to guarantee your freedom to share and change free +-software--to make sure the software is free for all its users. This +-General Public License applies to most of the Free Software +-Foundation's software and to any other program whose authors commit to +-using it. (Some other Free Software Foundation software is covered by +-the GNU Lesser General Public License instead.) You can apply it to +-your programs, too. +- +- When we speak of free software, we are referring to freedom, not +-price. Our General Public Licenses are designed to make sure that you +-have the freedom to distribute copies of free software (and charge for +-this service if you wish), that you receive source code or can get it +-if you want it, that you can change the software or use pieces of it +-in new free programs; and that you know you can do these things. +- +- To protect your rights, we need to make restrictions that forbid +-anyone to deny you these rights or to ask you to surrender the rights. +-These restrictions translate to certain responsibilities for you if you +-distribute copies of the software, or if you modify it. +- +- For example, if you distribute copies of such a program, whether +-gratis or for a fee, you must give the recipients all the rights that +-you have. You must make sure that they, too, receive or can get the +-source code. And you must show them these terms so they know their +-rights. +- +- We protect your rights with two steps: (1) copyright the software, and +-(2) offer you this license which gives you legal permission to copy, +-distribute and/or modify the software. +- +- Also, for each author's protection and ours, we want to make certain +-that everyone understands that there is no warranty for this free +-software. If the software is modified by someone else and passed on, we +-want its recipients to know that what they have is not the original, so +-that any problems introduced by others will not reflect on the original +-authors' reputations. +- +- Finally, any free program is threatened constantly by software +-patents. We wish to avoid the danger that redistributors of a free +-program will individually obtain patent licenses, in effect making the +-program proprietary. To prevent this, we have made it clear that any +-patent must be licensed for everyone's free use or not licensed at all. +- +- The precise terms and conditions for copying, distribution and +-modification follow. +- +- GNU GENERAL PUBLIC LICENSE +- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION +- +- 0. This License applies to any program or other work which contains +-a notice placed by the copyright holder saying it may be distributed +-under the terms of this General Public License. The "Program", below, +-refers to any such program or work, and a "work based on the Program" +-means either the Program or any derivative work under copyright law: +-that is to say, a work containing the Program or a portion of it, +-either verbatim or with modifications and/or translated into another +-language. (Hereinafter, translation is included without limitation in +-the term "modification".) Each licensee is addressed as "you". +- +-Activities other than copying, distribution and modification are not +-covered by this License; they are outside its scope. The act of +-running the Program is not restricted, and the output from the Program +-is covered only if its contents constitute a work based on the +-Program (independent of having been made by running the Program). +-Whether that is true depends on what the Program does. +- +- 1. You may copy and distribute verbatim copies of the Program's +-source code as you receive it, in any medium, provided that you +-conspicuously and appropriately publish on each copy an appropriate +-copyright notice and disclaimer of warranty; keep intact all the +-notices that refer to this License and to the absence of any warranty; +-and give any other recipients of the Program a copy of this License +-along with the Program. +- +-You may charge a fee for the physical act of transferring a copy, and +-you may at your option offer warranty protection in exchange for a fee. +- +- 2. You may modify your copy or copies of the Program or any portion +-of it, thus forming a work based on the Program, and copy and +-distribute such modifications or work under the terms of Section 1 +-above, provided that you also meet all of these conditions: +- +- a) You must cause the modified files to carry prominent notices +- stating that you changed the files and the date of any change. +- +- b) You must cause any work that you distribute or publish, that in +- whole or in part contains or is derived from the Program or any +- part thereof, to be licensed as a whole at no charge to all third +- parties under the terms of this License. +- +- c) If the modified program normally reads commands interactively +- when run, you must cause it, when started running for such +- interactive use in the most ordinary way, to print or display an +- announcement including an appropriate copyright notice and a +- notice that there is no warranty (or else, saying that you provide +- a warranty) and that users may redistribute the program under +- these conditions, and telling the user how to view a copy of this +- License. (Exception: if the Program itself is interactive but +- does not normally print such an announcement, your work based on +- the Program is not required to print an announcement.) +- +-These requirements apply to the modified work as a whole. If +-identifiable sections of that work are not derived from the Program, +-and can be reasonably considered independent and separate works in +-themselves, then this License, and its terms, do not apply to those +-sections when you distribute them as separate works. But when you +-distribute the same sections as part of a whole which is a work based +-on the Program, the distribution of the whole must be on the terms of +-this License, whose permissions for other licensees extend to the +-entire whole, and thus to each and every part regardless of who wrote it. +- +-Thus, it is not the intent of this section to claim rights or contest +-your rights to work written entirely by you; rather, the intent is to +-exercise the right to control the distribution of derivative or +-collective works based on the Program. +- +-In addition, mere aggregation of another work not based on the Program +-with the Program (or with a work based on the Program) on a volume of +-a storage or distribution medium does not bring the other work under +-the scope of this License. +- +- 3. You may copy and distribute the Program (or a work based on it, +-under Section 2) in object code or executable form under the terms of +-Sections 1 and 2 above provided that you also do one of the following: +- +- a) Accompany it with the complete corresponding machine-readable +- source code, which must be distributed under the terms of Sections +- 1 and 2 above on a medium customarily used for software interchange; or, +- +- b) Accompany it with a written offer, valid for at least three +- years, to give any third party, for a charge no more than your +- cost of physically performing source distribution, a complete +- machine-readable copy of the corresponding source code, to be +- distributed under the terms of Sections 1 and 2 above on a medium +- customarily used for software interchange; or, +- +- c) Accompany it with the information you received as to the offer +- to distribute corresponding source code. (This alternative is +- allowed only for noncommercial distribution and only if you +- received the program in object code or executable form with such +- an offer, in accord with Subsection b above.) +- +-The source code for a work means the preferred form of the work for +-making modifications to it. For an executable work, complete source +-code means all the source code for all modules it contains, plus any +-associated interface definition files, plus the scripts used to +-control compilation and installation of the executable. However, as a +-special exception, the source code distributed need not include +-anything that is normally distributed (in either source or binary +-form) with the major components (compiler, kernel, and so on) of the +-operating system on which the executable runs, unless that component +-itself accompanies the executable. +- +-If distribution of executable or object code is made by offering +-access to copy from a designated place, then offering equivalent +-access to copy the source code from the same place counts as +-distribution of the source code, even though third parties are not +-compelled to copy the source along with the object code. +- +- 4. You may not copy, modify, sublicense, or distribute the Program +-except as expressly provided under this License. Any attempt +-otherwise to copy, modify, sublicense or distribute the Program is +-void, and will automatically terminate your rights under this License. +-However, parties who have received copies, or rights, from you under +-this License will not have their licenses terminated so long as such +-parties remain in full compliance. +- +- 5. You are not required to accept this License, since you have not +-signed it. However, nothing else grants you permission to modify or +-distribute the Program or its derivative works. These actions are +-prohibited by law if you do not accept this License. Therefore, by +-modifying or distributing the Program (or any work based on the +-Program), you indicate your acceptance of this License to do so, and +-all its terms and conditions for copying, distributing or modifying +-the Program or works based on it. +- +- 6. Each time you redistribute the Program (or any work based on the +-Program), the recipient automatically receives a license from the +-original licensor to copy, distribute or modify the Program subject to +-these terms and conditions. You may not impose any further +-restrictions on the recipients' exercise of the rights granted herein. +-You are not responsible for enforcing compliance by third parties to +-this License. +- +- 7. If, as a consequence of a court judgment or allegation of patent +-infringement or for any other reason (not limited to patent issues), +-conditions are imposed on you (whether by court order, agreement or +-otherwise) that contradict the conditions of this License, they do not +-excuse you from the conditions of this License. If you cannot +-distribute so as to satisfy simultaneously your obligations under this +-License and any other pertinent obligations, then as a consequence you +-may not distribute the Program at all. For example, if a patent +-license would not permit royalty-free redistribution of the Program by +-all those who receive copies directly or indirectly through you, then +-the only way you could satisfy both it and this License would be to +-refrain entirely from distribution of the Program. +- +-If any portion of this section is held invalid or unenforceable under +-any particular circumstance, the balance of the section is intended to +-apply and the section as a whole is intended to apply in other +-circumstances. +- +-It is not the purpose of this section to induce you to infringe any +-patents or other property right claims or to contest validity of any +-such claims; this section has the sole purpose of protecting the +-integrity of the free software distribution system, which is +-implemented by public license practices. Many people have made +-generous contributions to the wide range of software distributed +-through that system in reliance on consistent application of that +-system; it is up to the author/donor to decide if he or she is willing +-to distribute software through any other system and a licensee cannot +-impose that choice. +- +-This section is intended to make thoroughly clear what is believed to +-be a consequence of the rest of this License. +- +- 8. If the distribution and/or use of the Program is restricted in +-certain countries either by patents or by copyrighted interfaces, the +-original copyright holder who places the Program under this License +-may add an explicit geographical distribution limitation excluding +-those countries, so that distribution is permitted only in or among +-countries not thus excluded. In such case, this License incorporates +-the limitation as if written in the body of this License. +- +- 9. The Free Software Foundation may publish revised and/or new versions +-of the General Public License from time to time. Such new versions will +-be similar in spirit to the present version, but may differ in detail to +-address new problems or concerns. +- +-Each version is given a distinguishing version number. If the Program +-specifies a version number of this License which applies to it and "any +-later version", you have the option of following the terms and conditions +-either of that version or of any later version published by the Free +-Software Foundation. If the Program does not specify a version number of +-this License, you may choose any version ever published by the Free Software +-Foundation. +- +- 10. If you wish to incorporate parts of the Program into other free +-programs whose distribution conditions are different, write to the author +-to ask for permission. For software which is copyrighted by the Free +-Software Foundation, write to the Free Software Foundation; we sometimes +-make exceptions for this. Our decision will be guided by the two goals +-of preserving the free status of all derivatives of our free software and +-of promoting the sharing and reuse of software generally. +- +- NO WARRANTY +- +- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +-REPAIR OR CORRECTION. +- +- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +-POSSIBILITY OF SUCH DAMAGES. +- +- END OF TERMS AND CONDITIONS +- +- How to Apply These Terms to Your New Programs +- +- If you develop a new program, and you want it to be of the greatest +-possible use to the public, the best way to achieve this is to make it +-free software which everyone can redistribute and change under these terms. +- +- To do so, attach the following notices to the program. It is safest +-to attach them to the start of each source file to most effectively +-convey the exclusion of warranty; and each file should have at least +-the "copyright" line and a pointer to where the full notice is found. +- +- +- Copyright (C) +- +- This program is free software; you can redistribute it and/or modify +- it under the terms of the GNU General Public License as published by +- the Free Software Foundation; either version 2 of the License, or +- (at your option) any later version. +- +- This program is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- GNU General Public License for more details. +- +- You should have received a copy of the GNU General Public License along +- with this program; if not, write to the Free Software Foundation, Inc., +- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +- +-Also add information on how to contact you by electronic and paper mail. +- +-If the program is interactive, make it output a short notice like this +-when it starts in an interactive mode: +- +- Gnomovision version 69, Copyright (C) year name of author +- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. +- This is free software, and you are welcome to redistribute it +- under certain conditions; type `show c' for details. +- +-The hypothetical commands `show w' and `show c' should show the appropriate +-parts of the General Public License. Of course, the commands you use may +-be called something other than `show w' and `show c'; they could even be +-mouse-clicks or menu items--whatever suits your program. +- +-You should also get your employer (if you work as a programmer) or your +-school, if any, to sign a "copyright disclaimer" for the program, if +-necessary. Here is a sample; alter the names: +- +- Yoyodyne, Inc., hereby disclaims all copyright interest in the program +- `Gnomovision' (which makes passes at compilers) written by James Hacker. +- +- , 1 April 1989 +- Ty Coon, President of Vice +- +-This General Public License does not permit incorporating your program into +-proprietary programs. If your program is a subroutine library, you may +-consider it more useful to permit linking proprietary applications with the +-library. If this is what you want to do, use the GNU Lesser General +-Public License instead of this License. +-- +GitLab + + +From d56fa512410bda7c11c2f445e25aaa570addb940 Mon Sep 17 00:00:00 2001 +From: Gordon Heydon +Date: Mon, 13 Mar 2023 12:12:25 +1100 +Subject: [PATCH 04/11] Restore ckeditor 4 version and organise ckeditor5 + version to be in line with other project. + +--- + ckeditor_templates.ckeditor5.yml | 4 +- + ckeditor_templates.info.yml | 4 +- + ckeditor_templates.libraries.yml | 21 +- + css/cke5_templates.admin.css | 1 + + ...s.dialog.css => cke5_templates.dialog.css} | 0 + css/cke_templates.admin.css | 1 - + css/ckeditor_templates.css | 8 + + .../ckeditor_templates/sass}/dialog.scss | 0 + .../ckeditor_templates}/src/app.js | 2 +- + .../src/ckeditorTemplates.js | 0 + .../src/ckeditorTemplatesCommand.js | 0 + .../src/ckeditorTemplatesEditing.js | 0 + .../src/ckeditorTemplatesUI.js | 0 + .../theme/icons/templates.svg | 0 + .../theme/images/placeholder.svg | 0 + js/ckeditor_templates.admin.js | 32 +++ + js/ckeditor_templates.dialog.js | 22 +++ + js/dist/ckeditorTemplates.js | 2 +- + .../CKEditorPlugin/CkeditorTemplates.php | 183 ++++++++++++++++++ + templates/ckeditor_templates.js.example | 83 ++++++++ + webpack.config.js | 8 +- + 21 files changed, 354 insertions(+), 17 deletions(-) + create mode 100644 css/cke5_templates.admin.css + rename css/{cke_templates.dialog.css => cke5_templates.dialog.css} (100%) + delete mode 100644 css/cke_templates.admin.css + create mode 100644 css/ckeditor_templates.css + rename {sass => js/ckeditor5_plugins/ckeditor_templates/sass}/dialog.scss (100%) + rename js/{plugin => ckeditor5_plugins/ckeditor_templates}/src/app.js (71%) + rename js/{plugin => ckeditor5_plugins/ckeditor_templates}/src/ckeditorTemplates.js (100%) + rename js/{plugin => ckeditor5_plugins/ckeditor_templates}/src/ckeditorTemplatesCommand.js (100%) + rename js/{plugin => ckeditor5_plugins/ckeditor_templates}/src/ckeditorTemplatesEditing.js (100%) + rename js/{plugin => ckeditor5_plugins/ckeditor_templates}/src/ckeditorTemplatesUI.js (100%) + rename js/{plugin => ckeditor5_plugins/ckeditor_templates}/theme/icons/templates.svg (100%) + rename js/{plugin => ckeditor5_plugins/ckeditor_templates}/theme/images/placeholder.svg (100%) + create mode 100644 js/ckeditor_templates.admin.js + create mode 100644 js/ckeditor_templates.dialog.js + create mode 100644 src/Plugin/CKEditorPlugin/CkeditorTemplates.php + create mode 100644 templates/ckeditor_templates.js.example + +diff --git a/ckeditor_templates.ckeditor5.yml b/ckeditor_templates.ckeditor5.yml +index a387b3c..f5caec4 100644 +--- a/ckeditor_templates.ckeditor5.yml ++++ b/ckeditor_templates.ckeditor5.yml +@@ -15,8 +15,8 @@ ckeditor_templates_plugin: + drupal: + label: Templates + elements: false +- library: ckeditor_templates/ckeditor.templates.dialog +- admin_library: ckeditor_templates/ckeditor.templates.admin ++ library: ckeditor_templates/ckeditor5.templates.dialog ++ admin_library: ckeditor_templates/ckeditor5.templates.admin + class: Drupal\ckeditor_templates\Plugin\CKEditor5Plugin\CKEditorTemplatesDialog + toolbar_items: + ckeditorTemplates: +diff --git a/ckeditor_templates.info.yml b/ckeditor_templates.info.yml +index 6975f55..b34cca3 100644 +--- a/ckeditor_templates.info.yml ++++ b/ckeditor_templates.info.yml +@@ -2,6 +2,4 @@ name: CKEditor Templates + description: 'Integrates the CKEditor templates plugin.' + package: CKEditor + type: module +-core_version_requirement: ^9.3 || ^10 +-dependencies: +-- drupal:ckeditor5 ++core_version_requirement: ^8 || ^9 || ^10 +diff --git a/ckeditor_templates.libraries.yml b/ckeditor_templates.libraries.yml +index b5ea02b..ef128b5 100644 +--- a/ckeditor_templates.libraries.yml ++++ b/ckeditor_templates.libraries.yml +@@ -1,16 +1,27 @@ + ckeditor.templates.dialog: +- version: 2.x ++ version: 1.x + css: + theme: +- css/cke_templates.dialog.css: {minified: true} ++ css/ckeditor_templates.css: {} ++ js: ++ js/ckeditor_templates.dialog.js: {} ++ ++ckeditor.templates.admin: ++ version: 1.x ++ js: ++ js/ckeditor_templates.admin.js: {} ++ ++ckeditor5.templates.dialog: ++ css: ++ theme: ++ css/cke5_templates.dialog.css: {minified: true} + js: + js/dist/ckeditorTemplates.js: {} + dependencies: + - ckeditor5/ckeditor5 + - editor/drupal.editor.dialog + +-ckeditor.templates.admin: +- version: 2.x ++ckeditor5.templates.admin: + css: + theme: +- css/cke_templates.admin.css: {} ++ css/cke5_templates.admin.css: {} +\ No newline at end of file +diff --git a/css/cke5_templates.admin.css b/css/cke5_templates.admin.css +new file mode 100644 +index 0000000..850f058 +--- /dev/null ++++ b/css/cke5_templates.admin.css +@@ -0,0 +1 @@ ++.ckeditor5-toolbar-button-ckeditorTemplates {background-image: url(../js/ckeditor5_plugins/ckeditor_templates/theme/icons/templates.svg)} +diff --git a/css/cke_templates.dialog.css b/css/cke5_templates.dialog.css +similarity index 100% +rename from css/cke_templates.dialog.css +rename to css/cke5_templates.dialog.css +diff --git a/css/cke_templates.admin.css b/css/cke_templates.admin.css +deleted file mode 100644 +index cd52fb2..0000000 +--- a/css/cke_templates.admin.css ++++ /dev/null +@@ -1 +0,0 @@ +-.ckeditor5-toolbar-button-ckeditorTemplates {background-image: url(../js/plugin/theme/icons/templates.svg)} +diff --git a/css/ckeditor_templates.css b/css/ckeditor_templates.css +new file mode 100644 +index 0000000..70a2f30 +--- /dev/null ++++ b/css/ckeditor_templates.css +@@ -0,0 +1,8 @@ ++.cke_templates_dialog .cke_dialog_ui_checkbox input { ++ vertical-align: middle; ++} ++ ++/* Set correct alignment for the "Replace actual content" checkbox */ ++.cke_reset_all .cke_templates_dialog .cke_dialog_ui_checkbox label { ++ display: inline-block; ++} +diff --git a/sass/dialog.scss b/js/ckeditor5_plugins/ckeditor_templates/sass/dialog.scss +similarity index 100% +rename from sass/dialog.scss +rename to js/ckeditor5_plugins/ckeditor_templates/sass/dialog.scss +diff --git a/js/plugin/src/app.js b/js/ckeditor5_plugins/ckeditor_templates/src/app.js +similarity index 71% +rename from js/plugin/src/app.js +rename to js/ckeditor5_plugins/ckeditor_templates/src/app.js +index 8634917..520fecb 100644 +--- a/js/plugin/src/app.js ++++ b/js/ckeditor5_plugins/ckeditor_templates/src/app.js +@@ -1,5 +1,5 @@ + import CKEditorTemplates from './ckeditorTemplates'; +-import './../../../sass/dialog.scss'; ++import './../sass/dialog.scss'; + + export default { + CKEditorTemplates +diff --git a/js/plugin/src/ckeditorTemplates.js b/js/ckeditor5_plugins/ckeditor_templates/src/ckeditorTemplates.js +similarity index 100% +rename from js/plugin/src/ckeditorTemplates.js +rename to js/ckeditor5_plugins/ckeditor_templates/src/ckeditorTemplates.js +diff --git a/js/plugin/src/ckeditorTemplatesCommand.js b/js/ckeditor5_plugins/ckeditor_templates/src/ckeditorTemplatesCommand.js +similarity index 100% +rename from js/plugin/src/ckeditorTemplatesCommand.js +rename to js/ckeditor5_plugins/ckeditor_templates/src/ckeditorTemplatesCommand.js +diff --git a/js/plugin/src/ckeditorTemplatesEditing.js b/js/ckeditor5_plugins/ckeditor_templates/src/ckeditorTemplatesEditing.js +similarity index 100% +rename from js/plugin/src/ckeditorTemplatesEditing.js +rename to js/ckeditor5_plugins/ckeditor_templates/src/ckeditorTemplatesEditing.js +diff --git a/js/plugin/src/ckeditorTemplatesUI.js b/js/ckeditor5_plugins/ckeditor_templates/src/ckeditorTemplatesUI.js +similarity index 100% +rename from js/plugin/src/ckeditorTemplatesUI.js +rename to js/ckeditor5_plugins/ckeditor_templates/src/ckeditorTemplatesUI.js +diff --git a/js/plugin/theme/icons/templates.svg b/js/ckeditor5_plugins/ckeditor_templates/theme/icons/templates.svg +similarity index 100% +rename from js/plugin/theme/icons/templates.svg +rename to js/ckeditor5_plugins/ckeditor_templates/theme/icons/templates.svg +diff --git a/js/plugin/theme/images/placeholder.svg b/js/ckeditor5_plugins/ckeditor_templates/theme/images/placeholder.svg +similarity index 100% +rename from js/plugin/theme/images/placeholder.svg +rename to js/ckeditor5_plugins/ckeditor_templates/theme/images/placeholder.svg +diff --git a/js/ckeditor_templates.admin.js b/js/ckeditor_templates.admin.js +new file mode 100644 +index 0000000..372e6d8 +--- /dev/null ++++ b/js/ckeditor_templates.admin.js +@@ -0,0 +1,32 @@ ++/** ++ * @file ++ * CKEditor 'templates' plugin admin behavior. ++ */ ++ ++(function ($, Drupal, drupalSettings) { ++ ++ 'use strict'; ++ ++ /** ++ * Provides the summary for the "templates" plugin settings vertical tab. ++ * ++ * @type {Drupal~behavior} ++ * ++ * @prop {Drupal~behaviorAttach} attach ++ * Attaches summary behaviour to the "templates" settings vertical tab. ++ */ ++ Drupal.behaviors.ckeditorTemplatesSettingsSummary = { ++ attach: function () { ++ $('[data-ckeditor-plugin-id="templates"]').drupalSetSummary(function (context) { ++ var templatePathValue = $('input[name="editor[settings][plugins][templates][template_path]').val(); ++ var replaceContentValue = $('input[name="editor[settings][plugins][templates][replace_content]').is(':checked'); ++ ++ var templatePathOutput = templatePathValue ? 'Template file overridden.' : 'Default or theme template file.'; ++ var replaceContentOutput = replaceContentValue ? '"Replace content" checked' : '"Replace content" unchecked'; ++ ++ return templatePathOutput + '
' + replaceContentOutput; ++ }); ++ } ++ }; ++ ++})(jQuery, Drupal, drupalSettings); +diff --git a/js/ckeditor_templates.dialog.js b/js/ckeditor_templates.dialog.js +new file mode 100644 +index 0000000..58cfa0c +--- /dev/null ++++ b/js/ckeditor_templates.dialog.js +@@ -0,0 +1,22 @@ ++/** ++ * @file ++ * Override ckeditor template dialog style. ++ */ ++ ++(function (CKEDITOR) { ++ ++ 'use strict'; ++ ++ CKEDITOR.on('dialogDefinition', function (ev) { ++ var dialogName = ev.data.name; ++ var dialog = ev.data.definition.dialog; ++ ++ if (dialogName === 'templates') { ++ dialog.on('show', function () { ++ var dialogElement = dialog.getElement().getFirst(); ++ dialogElement.addClass('cke_templates_dialog'); ++ }); ++ } ++ }); ++ ++})(CKEDITOR); +diff --git a/js/dist/ckeditorTemplates.js b/js/dist/ckeditorTemplates.js +index d56d71c..fb6ebc3 100644 +--- a/js/dist/ckeditorTemplates.js ++++ b/js/dist/ckeditorTemplates.js +@@ -1 +1 @@ +-!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.CKEditor5=t():(e.CKEditor5=e.CKEditor5||{},e.CKEditor5.ckeditorTemplates=t())}(self,(()=>(()=>{var e={"ckeditor5/src/core.js":(e,t,o)=>{e.exports=o("dll-reference CKEditor5.dll")("./src/core.js")},"ckeditor5/src/ui.js":(e,t,o)=>{e.exports=o("dll-reference CKEditor5.dll")("./src/ui.js")},"dll-reference CKEditor5.dll":e=>{"use strict";e.exports=CKEditor5.dll}},t={};function o(r){var s=t[r];if(void 0!==s)return s.exports;var i=t[r]={exports:{}};return e[r](i,i.exports,o),i.exports}o.d=(e,t)=>{for(var r in t)o.o(t,r)&&!o.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},o.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t);var r={};return(()=>{"use strict";o.d(r,{default:()=>d});var e=o("ckeditor5/src/core.js"),t=o("ckeditor5/src/ui.js");class s extends e.Plugin{init(){const e=this.editor,o=this.editor.config.get("ckeditorTemplates");o&&o.openDialog&&o.dialogSettings&&o.dialogUrl&&e.ui.componentFactory.add("ckeditorTemplates",(r=>{const s=new t.ButtonView(r);s.set({label:Drupal.t("Templates"),icon:'\n',tooltip:!0});const i=e.commands.get("ckeditorTemplates");return s.bind("isOn","isEnabled").to(i,"value","isEnabled"),this.listenTo(s,"execute",(()=>{const t=o.dialogUrl,r=o.dialogSettings;o.openDialog(t,(({htmlCode:t,replace:o})=>{e.execute("ckeditorTemplates",t,o)}),r)})),s}))}}class i extends e.Command{refresh(){const e=this.editor.model,t=e.document.selection,o=e.schema.findAllowedParent(t.getFirstPosition(),"ckeditorTemplates");this.isEnabled=!!o}execute(e,t){const o=this.editor,r=o.data;if(t)r.set(e);else{const t=o.model;t.change((()=>{const o=r.processor.toView(e),s=r.toModel(o);t.insertContent(s)}))}}}class n extends e.Plugin{static get requires(){return[i]}init(){const e=this.editor,t="ckeditorTemplates";this.editor.model.schema.register(t,{allowWhere:"$block",isObject:!0,isContent:!0,isBlock:!0}),this.editor.commands.add(t,new i(e))}static get pluginName(){return"ckeditorTemplatesEditing"}}class l extends e.Plugin{static get requires(){return[s,n]}static get pluginName(){return"ckeditorTemplates"}}const d={CKEditorTemplates:l}})(),r=r.default})())); +\ No newline at end of file ++!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.CKEditor5=t():(e.CKEditor5=e.CKEditor5||{},e.CKEditor5.ckeditorTemplates=t())}(self,(()=>(()=>{var e={"ckeditor5/src/core.js":(e,t,o)=>{e.exports=o("dll-reference CKEditor5.dll")("./src/core.js")},"ckeditor5/src/ui.js":(e,t,o)=>{e.exports=o("dll-reference CKEditor5.dll")("./src/ui.js")},"dll-reference CKEditor5.dll":e=>{"use strict";e.exports=CKEditor5.dll}},t={};function o(r){var s=t[r];if(void 0!==s)return s.exports;var i=t[r]={exports:{}};return e[r](i,i.exports,o),i.exports}o.d=(e,t)=>{for(var r in t)o.o(t,r)&&!o.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},o.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t);var r={};return(()=>{"use strict";o.d(r,{default:()=>d});var e=o("ckeditor5/src/core.js"),t=o("ckeditor5/src/ui.js");class s extends e.Plugin{init(){const e=this.editor,o=this.editor.config.get("ckeditorTemplates");o&&o.openDialog&&o.dialogSettings&&o.dialogUrl&&e.ui.componentFactory.add("ckeditorTemplates",(r=>{const s=new t.ButtonView(r);s.set({label:Drupal.t("Templates"),icon:'\r\n',tooltip:!0});const i=e.commands.get("ckeditorTemplates");return s.bind("isOn","isEnabled").to(i,"value","isEnabled"),this.listenTo(s,"execute",(()=>{const t=o.dialogUrl,r=o.dialogSettings;o.openDialog(t,(({htmlCode:t,replace:o})=>{e.execute("ckeditorTemplates",t,o)}),r)})),s}))}}class i extends e.Command{refresh(){const e=this.editor.model,t=e.document.selection,o=e.schema.findAllowedParent(t.getFirstPosition(),"ckeditorTemplates");this.isEnabled=!!o}execute(e,t){const o=this.editor,r=o.data;if(t)r.set(e);else{const t=o.model;t.change((()=>{const o=r.processor.toView(e),s=r.toModel(o);t.insertContent(s)}))}}}class n extends e.Plugin{static get requires(){return[i]}init(){const e=this.editor,t="ckeditorTemplates";this.editor.model.schema.register(t,{allowWhere:"$block",isObject:!0,isContent:!0,isBlock:!0}),this.editor.commands.add(t,new i(e))}static get pluginName(){return"ckeditorTemplatesEditing"}}class l extends e.Plugin{static get requires(){return[s,n]}static get pluginName(){return"ckeditorTemplates"}}const d={CKEditorTemplates:l}})(),r=r.default})())); +\ No newline at end of file +diff --git a/src/Plugin/CKEditorPlugin/CkeditorTemplates.php b/src/Plugin/CKEditorPlugin/CkeditorTemplates.php +new file mode 100644 +index 0000000..79e1789 +--- /dev/null ++++ b/src/Plugin/CKEditorPlugin/CkeditorTemplates.php +@@ -0,0 +1,183 @@ ++get('config.factory') ++ ); ++ } ++ ++ /** ++ * Constructs a Drupal\Component\Plugin\PluginBase object. ++ * ++ * @param array $configuration ++ * A configuration array containing information about the plugin instance. ++ * @param string $plugin_id ++ * The plugin_id for the plugin instance. ++ * @param mixed $plugin_definition ++ * The plugin implementation definition. ++ * @param \Drupal\Core\Config\ConfigFactory $configFactoryService ++ * Drupal Configuration Factory Service. ++ */ ++ public function __construct(array $configuration, $plugin_id, $plugin_definition, ConfigFactory $configFactoryService) { ++ parent::__construct($configuration, $plugin_id, $plugin_definition); ++ ++ $this->configFactoryService = $configFactoryService; ++ } ++ ++ /** ++ * {@inheritdoc} ++ */ ++ public function getFile() { ++ return $this->getTemplatesPluginPath() . '/plugin.js'; ++ } ++ ++ /** ++ * {@inheritdoc} ++ */ ++ public function getLibraries(Editor $editor) { ++ return ['ckeditor_templates/ckeditor.templates.dialog']; ++ } ++ ++ /** ++ * {@inheritdoc} ++ */ ++ public function getButtons() { ++ return [ ++ 'Templates' => [ ++ 'label' => t('Templates'), ++ 'image' => $this->getTemplatesPluginPath() . '/icons/templates.png', ++ ], ++ ]; ++ } ++ ++ /** ++ * {@inheritdoc} ++ */ ++ public function getConfig(Editor $editor) { ++ $config = []; ++ $settings = $editor->getSettings(); ++ // Set replace content default value if set. ++ if (isset($settings['plugins']['templates']['replace_content'])) { ++ $config['templates_replaceContent'] = $settings['plugins']['templates']['replace_content']; ++ } ++ // Set template files default value if set. ++ if (isset($settings['plugins']['templates']['template_path']) && !empty($settings['plugins']['templates']['template_path'])) { ++ $config['templates_files'] = [$settings['plugins']['templates']['template_path']]; ++ } ++ else { ++ // Use templates plugin default file. ++ $config['templates_files'] = $this->getTemplatesDefaultPath(); ++ } ++ return $config; ++ } ++ ++ /** ++ * {@inheritdoc} ++ */ ++ public function settingsForm(array $form, FormStateInterface $form_state, Editor $editor) { ++ // Defaults. ++ $config = [ ++ 'replace_content' => FALSE, ++ 'template_path' => '', ++ ]; ++ ++ $settings = $editor->getSettings(); ++ ++ if (isset($settings['plugins']['templates'])) { ++ $config = $settings['plugins']['templates']; ++ } ++ ++ $form['template_path'] = [ ++ '#title' => t('Template definition file'), ++ '#type' => 'textfield', ++ '#default_value' => $config['template_path'], ++ '#description' => t('Path to the javascript file defining the templates, relative to drupal root (starting with "/"). By default, it looks in your default theme directory for a file named "templates/ckeditor_templates.js"'), ++ ]; ++ ++ $form['replace_content'] = [ ++ '#title' => t('Replace content default value'), ++ '#type' => 'checkbox', ++ '#default_value' => $config['replace_content'], ++ '#description' => t('Whether the "Replace actual contents" checkbox is checked by default in the Templates dialog'), ++ ]; ++ ++ $form['#attached']['library'][] = 'ckeditor_templates/ckeditor.templates.admin'; ++ ++ return $form; ++ } ++ ++ /** ++ * Return ckeditor templates plugin path relative to drupal root. ++ * ++ * @return string ++ * Relative path to the ckeditor plugin folder ++ */ ++ private function getTemplatesPluginPath() { ++ $pluginPath = 'libraries/ckeditor/plugins/templates'; ++ ++ if (!file_exists(DRUPAL_ROOT . '/' . $pluginPath)) { ++ // keep supporting module legacy path to avoid breaking change ++ // using this path is deprecated ++ $pluginPath = 'libraries/templates'; ++ } ++ ++ return $pluginPath; ++ } ++ ++ /** ++ * Generate the path to the template file. ++ * ++ * The file will be picked from : ++ * - the default theme if the file exists ++ * - the ckeditor template directory otherwise. ++ * ++ * @return array ++ * List of path to the template file ++ */ ++ private function getTemplatesDefaultPath() { ++ // Default to module folder. ++ $defaultPath = base_path() . $this->getTemplatesPluginPath() . '/templates/default.js'; ++ ++ // Get site default theme name. ++ $defaultThemConfig = $this->configFactoryService->get('system.theme'); ++ $defaultThemeName = $defaultThemConfig->get('default'); ++ ++ $defaultThemeFileAbsolutePath = DRUPAL_ROOT . '/' . drupal_get_path('theme', $defaultThemeName) . '/templates/ckeditor_templates.js'; ++ if (file_exists($defaultThemeFileAbsolutePath)) { ++ $defaultPath = base_path() . drupal_get_path('theme', $defaultThemeName) . '/templates/ckeditor_templates.js'; ++ } ++ ++ return [$defaultPath]; ++ } ++ ++} +diff --git a/templates/ckeditor_templates.js.example b/templates/ckeditor_templates.js.example +new file mode 100644 +index 0000000..ffafdbc +--- /dev/null ++++ b/templates/ckeditor_templates.js.example +@@ -0,0 +1,83 @@ ++// Override the default template set ++CKEDITOR.addTemplates( 'default', { ++ // The name of sub folder which hold the shortcut preview images of the ++ // templates. Determine base path of drupal installation if any ++ // (ckeditor could possibly be loaded w/o drupalSettings). ++ imagesPath: ((drupalSettings && drupalSettings.path) ? drupalSettings.path.baseUrl : '/') + 'themes/custom/mytheme/images/ckeditor/', ++ ++ // The templates definitions. ++ templates: [ { ++ title: 'Image and Title module', ++ image: 'template1.gif', ++ description: 'One main image with a title and text that surround the image.', ++ html: '

' + ++ // Use src=" " so image is not filtered out by the editor as incorrect (src is required). ++ '' + ++ 'Type the title here' + ++ '

' + ++ '

' + ++ 'Type the text here' + ++ '

' ++ }, ++ { ++ title: 'Strange Template', ++ image: 'template2.gif', ++ description: 'A template that defines two colums, each one with a title, and some text.', ++ html: '' + ++ '' + ++ '' + ++ '' + ++ '' + ++ '' + ++ '' + ++ '' + ++ '' + ++ '' + ++ '' + ++ '
' + ++ '

Title 1

' + ++ '
' + ++ '

Title 2

' + ++ '
' + ++ 'Text 1' + ++ '' + ++ 'Text 2' + ++ '
' + ++ '

' + ++ 'More text goes here.' + ++ '

' ++ }, ++ { ++ title: 'Text and Table', ++ image: 'template3.gif', ++ description: 'A title with some text and a table.', ++ html: '
' + ++ '

' + ++ 'Title goes here' + ++ '

' + ++ '' + ++ '' + ++ '' + ++ '' + ++ '' + ++ '' + ++ '' + ++ '' + ++ '' + ++ '' + ++ '' + ++ '' + ++ '' + ++ '' + ++ '' + ++ '' + ++ '' + ++ '
' + ++ 'Table title' + ++ '
   
   
   
' + ++ '

' + ++ 'Type the text here' + ++ '

' + ++ '
' ++ } ] ++} ); +diff --git a/webpack.config.js b/webpack.config.js +index e27ce74..ababa70 100644 +--- a/webpack.config.js ++++ b/webpack.config.js +@@ -25,7 +25,7 @@ module.exports = [ + moduleIds: 'named' + }, + entry: { +- path: path.resolve(__dirname, 'js/plugin/src/app.js') ++ path: path.resolve(__dirname, 'js/ckeditor5_plugins/ckeditor_templates/src/app.js') + }, + output: { + path: path.resolve(__dirname, 'js/dist'), +@@ -41,17 +41,17 @@ module.exports = [ + name: 'CKEditor5.dll' + }), + new MiniCssExtractPlugin({ +- filename: '../../css/cke_templates.dialog.css' ++ filename: '../../css/cke5_templates.dialog.css' + }) + ], + module: { + rules: [ + { +- test: /js[/\\]plugin[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/, ++ test: /js[/\\]ckeditor5_plugins[/\\].*?[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/, + use: ['raw-loader'] + }, + { +- test: /js[/\\]plugin[/\\]theme[/\\][^/\\]+\.css$/, ++ test: /js[/\\]ckeditor5_plugins[/\\].*?[/\\]theme[/\\][^/\\]+\.css$/, + use: [ + { + loader: 'style-loader', +-- +GitLab + + +From 92f3d832c65f1a9631cf2f9a07ae15172e0bbe6e Mon Sep 17 00:00:00 2001 +From: Gordon Heydon +Date: Mon, 13 Mar 2023 15:25:39 +1100 +Subject: [PATCH 05/11] Fix up path to the placeholder image. + +--- + src/Form/CKEditorTemplatesDialogForm.php | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/Form/CKEditorTemplatesDialogForm.php b/src/Form/CKEditorTemplatesDialogForm.php +index b9b5b62..f2ca7e3 100644 +--- a/src/Form/CKEditorTemplatesDialogForm.php ++++ b/src/Form/CKEditorTemplatesDialogForm.php +@@ -154,7 +154,7 @@ class CKEditorTemplatesDialogForm extends FormBase { + } + + if (empty($image)) { +- $image = $this->moduleFolder . '/js/plugin/theme/images/placeholder.svg'; ++ $image = $this->moduleFolder . '/js/ckeditor5_plugins/ckeditor_templates/theme/images/placeholder.svg'; + } + + return $image; +-- +GitLab + + +From 67e724f165837b2f153427a15f72d2d7d810df4a Mon Sep 17 00:00:00 2001 +From: Gordon Heydon +Date: Mon, 13 Mar 2023 16:35:24 +1100 +Subject: [PATCH 06/11] Add conversion object to allow upgrade from CKEditor 4 + to 5 + +--- + .../CKEditorTemplatesDialog.php | 63 +++++++++++++++++++ + 1 file changed, 63 insertions(+) + create mode 100644 src/Plugin/CKEditor4To5Upgrade/CKEditorTemplatesDialog.php + +diff --git a/src/Plugin/CKEditor4To5Upgrade/CKEditorTemplatesDialog.php b/src/Plugin/CKEditor4To5Upgrade/CKEditorTemplatesDialog.php +new file mode 100644 +index 0000000..bbe7600 +--- /dev/null ++++ b/src/Plugin/CKEditor4To5Upgrade/CKEditorTemplatesDialog.php +@@ -0,0 +1,63 @@ ++ $sanitized]; ++ break; ++ ++ default: ++ throw new \OutOfBoundsException(); ++ } ++ } ++ ++ /** ++ * @inheritDoc ++ */ ++ public function computeCKEditor5PluginSubsetConfiguration(string $cke5_plugin_id, FilterFormatInterface $text_format): ?array { ++ throw new \OutOfBoundsException(); ++ } ++ ++} +-- +GitLab + + +From 9008e302e5c694aae1d50d79f79c835497a75ac0 Mon Sep 17 00:00:00 2001 +From: Dylan Donkersgoed <12239-DylanDonkersgoed@users.noreply.drupalcode.org> +Date: Wed, 22 Mar 2023 18:42:54 +0000 +Subject: [PATCH 07/11] Remove D10 compatibility change from .info.yml + +--- + ckeditor_templates.info.yml | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/ckeditor_templates.info.yml b/ckeditor_templates.info.yml +index b34cca3..91e3d1e 100644 +--- a/ckeditor_templates.info.yml ++++ b/ckeditor_templates.info.yml +@@ -2,4 +2,5 @@ name: CKEditor Templates + description: 'Integrates the CKEditor templates plugin.' + package: CKEditor + type: module +-core_version_requirement: ^8 || ^9 || ^10 ++core: 8.x ++core_version_requirement: ^8 || ^9 +-- +GitLab + + +From 67da69513518cd680c83a61c6232d798e6becfaa Mon Sep 17 00:00:00 2001 +From: Marcelo Hespanhol +Date: Mon, 24 Apr 2023 13:36:34 -0400 +Subject: [PATCH 08/11] Include an alternative thumb field + +--- + src/Entity/CKEditorTemplates.php | 8 ++++++++ + src/Form/CKEditorTemplatesDialogForm.php | 11 ++++++++--- + src/Form/CKEditorTemplatesEntityForm.php | 11 ++++++++++- + 3 files changed, 26 insertions(+), 4 deletions(-) + +diff --git a/src/Entity/CKEditorTemplates.php b/src/Entity/CKEditorTemplates.php +index 3ed62ec..d8930a8 100644 +--- a/src/Entity/CKEditorTemplates.php ++++ b/src/Entity/CKEditorTemplates.php +@@ -48,6 +48,7 @@ use Drupal\Core\Entity\EntityStorageInterface; + * "status", + * "description", + * "thumb", ++ * "thumb_alternative", + * "code", + * "formats", + * "weight" +@@ -91,6 +92,13 @@ class CKEditorTemplates extends ConfigEntityBase implements CKEditorTemplatesInt + */ + protected $thumb; + ++ /** ++ * The template thumb_alternative. ++ * ++ * @var string ++ */ ++ protected $thumb_alternative; ++ + /** + * The template HTML code. + * +diff --git a/src/Form/CKEditorTemplatesDialogForm.php b/src/Form/CKEditorTemplatesDialogForm.php +index f2ca7e3..ac863c0 100644 +--- a/src/Form/CKEditorTemplatesDialogForm.php ++++ b/src/Form/CKEditorTemplatesDialogForm.php +@@ -79,7 +79,7 @@ class CKEditorTemplatesDialogForm extends FormBase { + $this->templates[$format->id()] = [ + 'label' => $format->label(), + 'formats' => $format->get('formats') ?? [], +- 'thumb' => $this->getThumb($format->get('thumb')[0] ?? ''), ++ 'thumb' => $this->getThumb($format->get('thumb')[0] ?? '', $format->get('thumb_alternative')), + 'description' => $format->get('description') ?? '', + 'code' => $format->get('code') ?? '', + ]; +@@ -124,13 +124,16 @@ class CKEditorTemplatesDialogForm extends FormBase { + * @param string $thumb + * The thumb image id. + * ++ * @param string $thumb_alternative ++ * The alternative thumb image url. ++ * + * @return string + * The thumb image URL. + * + * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException + * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException + */ +- private function getThumb(string $thumb): string { ++ private function getThumb(string $thumb, string $thumb_alternative): string { + $image = ''; + + if (!empty($thumb)) { +@@ -154,7 +157,9 @@ class CKEditorTemplatesDialogForm extends FormBase { + } + + if (empty($image)) { +- $image = $this->moduleFolder . '/js/ckeditor5_plugins/ckeditor_templates/theme/images/placeholder.svg'; ++ $image = empty($thumb_alternative) ++ ? $this->moduleFolder . '/js/ckeditor5_plugins/ckeditor_templates/theme/images/placeholder.svg' ++ : $thumb_alternative; + } + + return $image; +diff --git a/src/Form/CKEditorTemplatesEntityForm.php b/src/Form/CKEditorTemplatesEntityForm.php +index 6682d35..bae938c 100644 +--- a/src/Form/CKEditorTemplatesEntityForm.php ++++ b/src/Form/CKEditorTemplatesEntityForm.php +@@ -107,7 +107,7 @@ class CKEditorTemplatesEntityForm extends EntityForm { + + $form['thumb'] = [ + '#type' => 'managed_file', +- '#title' => $this->t('Illustration Image/Icon'), ++ '#title' => $this->t('Illustrative Image/Icon'), + '#default_value' => $this->entity->get('thumb'), + '#description' => $this->t('Allowed types: png jpeg jpg gif'), + '#upload_location' => 'public://ckeditor-templates', +@@ -117,6 +117,15 @@ class CKEditorTemplatesEntityForm extends EntityForm { + '#cardinality' => 1, + ]; + ++ $form['thumb_alternative'] = [ ++ '#type' => 'textfield', ++ '#title' => $this->t('Alternative Image/Icon'), ++ '#maxlength' => 255, ++ '#default_value' => $this->entity->get('thumb_alternative'), ++ '#description' => $this->t('Use this field as an alternative to uploading an illustrative image/icon. You can provide a URL or path to an image file (i.e., //domain.com/icon.png, public://icon.png, /modules/my_module/icon.png, /themes/my_theme/icon.png, etc.).'), ++ '#required' => FALSE, ++ ]; ++ + $form['code'] = [ + '#type' => 'textarea', + '#title' => $this->t('HTML Code'), +-- +GitLab + + +From d8262219ead37319e9ba455fb7e8c7e7fe898cb0 Mon Sep 17 00:00:00 2001 +From: Harlor +Date: Tue, 25 Apr 2023 18:47:19 +0200 +Subject: [PATCH 09/11] Add gordons changes from 3273358-46 - 3273358-48 + +--- + ckeditor_templates.libraries.yml | 6 ++++-- + ckeditor_templates.module | 28 ++++++++++++++++++++++++ + css/cke5_templates.dialog.css | 37 +++++++++++++++++++++++++++++++- + 3 files changed, 68 insertions(+), 3 deletions(-) + create mode 100644 ckeditor_templates.module + +diff --git a/ckeditor_templates.libraries.yml b/ckeditor_templates.libraries.yml +index ef128b5..a81ef89 100644 +--- a/ckeditor_templates.libraries.yml ++++ b/ckeditor_templates.libraries.yml +@@ -12,9 +12,10 @@ ckeditor.templates.admin: + js/ckeditor_templates.admin.js: {} + + ckeditor5.templates.dialog: ++ version: 2.x + css: + theme: +- css/cke5_templates.dialog.css: {minified: true} ++ css/cke5_templates.dialog.css: {} + js: + js/dist/ckeditorTemplates.js: {} + dependencies: +@@ -22,6 +23,7 @@ ckeditor5.templates.dialog: + - editor/drupal.editor.dialog + + ckeditor5.templates.admin: ++ version: 2.x + css: + theme: +- css/cke5_templates.admin.css: {} +\ No newline at end of file ++ css/cke5_templates.admin.css: {} +diff --git a/ckeditor_templates.module b/ckeditor_templates.module +new file mode 100644 +index 0000000..4e6c40a +--- /dev/null ++++ b/ckeditor_templates.module +@@ -0,0 +1,28 @@ ++ $value) { ++ if (!isset($variables['attributes'][$delta])) { ++ $variables['attributes'][$delta] = $value; ++ } ++ elseif (is_array($value)) { ++ $variables['attributes'][$delta] = array_merge($variables['attributes'][$delta], $value); ++ } ++ } ++ } ++} +diff --git a/css/cke5_templates.dialog.css b/css/cke5_templates.dialog.css +index d2bfc0f..fc08941 100644 +--- a/css/cke5_templates.dialog.css ++++ b/css/cke5_templates.dialog.css +@@ -1 +1,36 @@ +-.ckeditor-templates-widget-modal .form-radios{margin:0;padding:0}.ckeditor-templates-widget-modal .form-radios .form-type-radio.form-item-templates,.ckeditor-templates-widget-modal .form-radios .form-type--radio.form-item--templates{margin:0;padding:0}.ckeditor-templates-widget-modal .form-radios .form-type-radio.form-item-templates input,.ckeditor-templates-widget-modal .form-radios .form-type--radio.form-item--templates input{display:none}.ckeditor-templates-widget-modal .form-radios .form-type-radio.form-item-templates label,.ckeditor-templates-widget-modal .form-radios .form-type--radio.form-item--templates label{display:flex;margin-top:.75rem;padding:.75rem;border:#bcbcbc 1px solid;align-items:flex-start;user-select:none}.ckeditor-templates-widget-modal .form-radios .form-type-radio.form-item-templates label:hover,.ckeditor-templates-widget-modal .form-radios .form-type--radio.form-item--templates label:hover{background-color:#efefef}.ckeditor-templates-widget-modal .form-radios .form-type-radio.form-item-templates label img,.ckeditor-templates-widget-modal .form-radios .form-type--radio.form-item--templates label img{width:5rem;margin-right:.75rem}.ckeditor-templates-widget-modal .form-radios .form-type-radio.form-item-templates label div,.ckeditor-templates-widget-modal .form-radios .form-type--radio.form-item--templates label div{line-height:1.2rem}.ckeditor-templates-widget-modal .form-radios .form-type-radio.form-item-templates label div strong,.ckeditor-templates-widget-modal .form-radios .form-type--radio.form-item--templates label div strong{display:block}.ckeditor-templates-widget-modal .form-radios .form-type-radio.form-item-templates input:checked+label,.ckeditor-templates-widget-modal .form-radios .form-type--radio.form-item--templates input:checked+label{border:#f93 1px solid;background-color:#fffacd} ++.ckeditor-templates-widget-modal .form-radios--templates { ++ margin: 0; ++ padding: 0; ++} ++.ckeditor-templates-widget-modal .form-radios--templates .js-form-type-radio.js-form-item-templates { ++ margin: 0; ++ padding: 0; ++} ++.ckeditor-templates-widget-modal .form-radios--templates .js-form-type-radio.js-form-item-templates input { ++ display: none; ++} ++.ckeditor-templates-widget-modal .form-radios--templates .js-form-type-radio.js-form-item-templates label { ++ display: flex; ++ margin-top: 0.75rem; ++ padding: 0.75rem; ++ border: #bcbcbc 1px solid; ++ align-items: flex-start; ++ user-select: none; ++} ++.ckeditor-templates-widget-modal .form-radios--templates .js-form-type-radio.js-form-item-templates label:hover { ++ background-color: #efefef; ++} ++.ckeditor-templates-widget-modal .form-radios--templates .js-form-type-radio.js-form-item-templates label img { ++ width: 5rem; ++ margin-right: 0.75rem; ++} ++.ckeditor-templates-widget-modal .form-radios--templates .js-form-type-radio.js-form-item-templates label div { ++ line-height: 1.2rem; ++} ++.ckeditor-templates-widget-modal .form-radios--templates .js-form-type-radio.js-form-item-templates label div strong { ++ display: block; ++} ++.ckeditor-templates-widget-modal .form-radios--templates .js-form-type-radio.js-form-item-templates input:checked+label { ++ border: #f93 1px solid; ++ background-color: #fffacd; ++} +-- +GitLab + + +From a8ec97f4412f8654003a690a27528f654a4b26c8 Mon Sep 17 00:00:00 2001 +From: Harlor +Date: Wed, 26 Apr 2023 17:17:43 +0200 +Subject: [PATCH 10/11] Introduce CkeditorTemplate annotation plugin + +--- + ckeditor_templates.routing.yml | 5 +- + ckeditor_templates.services.yml | 4 + + src/Annotation/CkeditorTemplate.php | 48 +++++ + src/CkeditorTemplateInterface.php | 50 +++++ + src/CkeditorTemplatePluginBase.php | 62 +++++++ + src/CkeditorTemplatePluginManager.php | 54 ++++++ + src/Entity/CKEditorTemplates.php | 8 + + src/Form/CKEditorTemplatesDialogForm.php | 175 ++++-------------- + .../CKEditorTemplatesDialog.php | 6 +- + .../CkeditorTemplate/ConfigTemplate.php | 140 ++++++++++++++ + .../Derivative/ConfigTemplateDeriver.php | 78 ++++++++ + 11 files changed, 484 insertions(+), 146 deletions(-) + create mode 100644 ckeditor_templates.services.yml + create mode 100644 src/Annotation/CkeditorTemplate.php + create mode 100644 src/CkeditorTemplateInterface.php + create mode 100644 src/CkeditorTemplatePluginBase.php + create mode 100644 src/CkeditorTemplatePluginManager.php + create mode 100644 src/Plugin/CkeditorTemplate/ConfigTemplate.php + create mode 100644 src/Plugin/Derivative/ConfigTemplateDeriver.php + +diff --git a/ckeditor_templates.routing.yml b/ckeditor_templates.routing.yml +index 1e41357..558b854 100644 +--- a/ckeditor_templates.routing.yml ++++ b/ckeditor_templates.routing.yml +@@ -1,9 +1,12 @@ + ckeditor_templates.selector: +- path: '/admin/config/content/ckeditor-templates/template-selector/{editor_id}' ++ path: '/admin/config/content/ckeditor-templates/template-selector/{editor}' + defaults: + _form: '\Drupal\ckeditor_templates\Form\CKEditorTemplatesDialogForm' + requirements: + _permission: 'use text format advanced' ++ parameters: ++ editor: ++ type: entity:editor + + entity.ckeditor_templates.collection: + path: '/admin/config/content/ckeditor-templates' +diff --git a/ckeditor_templates.services.yml b/ckeditor_templates.services.yml +new file mode 100644 +index 0000000..f129b74 +--- /dev/null ++++ b/ckeditor_templates.services.yml +@@ -0,0 +1,4 @@ ++services: ++ plugin.manager.ckeditor_template: ++ class: Drupal\ckeditor_templates\CkeditorTemplatePluginManager ++ parent: default_plugin_manager +diff --git a/src/Annotation/CkeditorTemplate.php b/src/Annotation/CkeditorTemplate.php +new file mode 100644 +index 0000000..83ca5aa +--- /dev/null ++++ b/src/Annotation/CkeditorTemplate.php +@@ -0,0 +1,48 @@ ++moduleFolder = '/' . $extension_list_module->getPath('ckeditor_templates'); ++ } ++ ++ /** ++ * {@inheritdoc} ++ */ ++ public function label(): string { ++ // Cast the label to a string since it is a TranslatableMarkup object. ++ return (string) $this->pluginDefinition['label']; ++ } ++ ++ /** ++ * Gets the thumbnail for an image. ++ * ++ * @return string ++ * The thumb image URL. ++ */ ++ public function getThumb(): string { ++ return $this->moduleFolder . '/js/ckeditor5_plugins/ckeditor_templates/theme/images/placeholder.svg'; ++ } ++ ++ /** ++ * {@inheritdoc} ++ */ ++ public function getDescription(): string { ++ return $this->pluginDefinition['description']; ++ } ++ ++} +diff --git a/src/CkeditorTemplatePluginManager.php b/src/CkeditorTemplatePluginManager.php +new file mode 100644 +index 0000000..edfde5c +--- /dev/null ++++ b/src/CkeditorTemplatePluginManager.php +@@ -0,0 +1,54 @@ ++alterInfo('ckeditor_template_info'); ++ $this->setCacheBackend($cache_backend, 'ckeditor_template_plugins'); ++ } ++ ++ /** ++ * Get all available templates. ++ * ++ * @return CkeditorTemplateInterface[] ++ */ ++ public function getTemplates() { ++ $templates = []; ++ $template_definitions = $this->getDefinitions(); ++ uasort($template_definitions, [\Drupal\Component\Utility\SortArray::class, 'sortByWeightElement']); ++ ++ foreach ($template_definitions as $id => $definition) { ++ $templates[$id] = $this->createInstance($id); ++ } ++ ++ return $templates; ++ } ++ ++} +diff --git a/src/Entity/CKEditorTemplates.php b/src/Entity/CKEditorTemplates.php +index d8930a8..3ea0d4b 100644 +--- a/src/Entity/CKEditorTemplates.php ++++ b/src/Entity/CKEditorTemplates.php +@@ -138,4 +138,12 @@ class CKEditorTemplates extends ConfigEntityBase implements CKEditorTemplatesInt + } + } + ++ /** ++ * {@inheritdoc} ++ */ ++ public function save() { ++ parent::save(); ++ \Drupal::service('plugin.manager.ckeditor_template')->clearCachedDefinitions(); ++ } ++ + } +diff --git a/src/Form/CKEditorTemplatesDialogForm.php b/src/Form/CKEditorTemplatesDialogForm.php +index ac863c0..00f5bfe 100644 +--- a/src/Form/CKEditorTemplatesDialogForm.php ++++ b/src/Form/CKEditorTemplatesDialogForm.php +@@ -2,16 +2,13 @@ + + namespace Drupal\ckeditor_templates\Form; + +-use Drupal\Core\Ajax\AjaxResponse; +-use Drupal\Core\Ajax\CloseModalDialogCommand; +-use Drupal\Core\Entity\EntityTypeManagerInterface; +-use Drupal\Core\Extension\ModuleExtensionList; + use Drupal\Core\Form\FormBase; ++use Drupal\Core\Ajax\AjaxResponse; ++use Drupal\editor\EditorInterface; + use Drupal\Core\Form\FormStateInterface; +-use Drupal\Core\File\FileUrlGeneratorInterface; + use Drupal\editor\Ajax\EditorDialogSave; +-use Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException; +-use Drupal\Component\Plugin\Exception\PluginNotFoundException; ++use Drupal\Core\Ajax\CloseModalDialogCommand; ++use Drupal\Component\Plugin\PluginManagerInterface; + use Symfony\Component\DependencyInjection\ContainerInterface; + + /** +@@ -20,25 +17,11 @@ use Symfony\Component\DependencyInjection\ContainerInterface; + class CKEditorTemplatesDialogForm extends FormBase { + + /** +- * The entity type manager instance. ++ * The template plugin manager. + * +- * @var \Drupal\Core\Entity\EntityTypeManagerInterface +- */ +- protected EntityTypeManagerInterface $entityTypeManager; +- +- /** +- * The file url generator instance. +- * +- * @var \Drupal\Core\File\FileUrlGeneratorInterface +- */ +- protected FileUrlGeneratorInterface $fileUrlGenerator; +- +- /** +- * The path for the current module folder. +- * +- * @var string ++ * @var PluginManagerInterface + */ +- protected string $moduleFolder; ++ protected $ckeditorTemplateManager; + + /** + * The available templates. +@@ -47,6 +30,13 @@ class CKEditorTemplatesDialogForm extends FormBase { + */ + protected array $templates; + ++ /** ++ * Determines wheter the available templates need to beloaded. ++ * ++ * @var boolean ++ */ ++ protected bool $templatesLoaded = FALSE; ++ + /** + * The AJAX wrapper id. + * +@@ -57,33 +47,11 @@ class CKEditorTemplatesDialogForm extends FormBase { + /** + * Create a new dialog instance. + * +- * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager +- * The entity type manager instance. +- * @param \Drupal\Core\File\FileUrlGeneratorInterface $file_url_generator +- * The file url generator instance. +- * @param \Drupal\Core\Extension\ModuleExtensionList $extension_list_module +- * The provider for a list of available modules. +- * + * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException + * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException + */ +- public function __construct(EntityTypeManagerInterface $entity_type_manager, FileUrlGeneratorInterface $file_url_generator, ModuleExtensionList $extension_list_module) { +- $this->entityTypeManager = $entity_type_manager; +- $this->fileUrlGenerator = $file_url_generator; +- $this->moduleFolder = '/' . $extension_list_module->getPath('ckeditor_templates'); +- $this->templates = []; +- +- // Load the templates. +- $templates = $this->getTemplates(); +- foreach ($templates as $format) { +- $this->templates[$format->id()] = [ +- 'label' => $format->label(), +- 'formats' => $format->get('formats') ?? [], +- 'thumb' => $this->getThumb($format->get('thumb')[0] ?? '', $format->get('thumb_alternative')), +- 'description' => $format->get('description') ?? '', +- 'code' => $format->get('code') ?? '', +- ]; +- } ++ public function __construct(PluginManagerInterface $ckeditor_template_plugin_manager) { ++ $this->ckeditorTemplateManager = $ckeditor_template_plugin_manager; + } + + /** +@@ -91,80 +59,10 @@ class CKEditorTemplatesDialogForm extends FormBase { + */ + public static function create(ContainerInterface $container): CKEditorTemplatesDialogForm | static { + return new static( +- $container->get('entity_type.manager'), +- $container->get('file_url_generator'), +- $container->get('extension.list.module') ++ $container->get('plugin.manager.ckeditor_template') + ); + } + +- /** +- * Loads the CKEditor Templates. +- * +- * @return \Drupal\Core\Entity\EntityInterface[] +- * A list of CKEditor Template entities. +- * +- * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException +- * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException +- */ +- private function getTemplates(): array { +- $storage = $this->entityTypeManager +- ->getStorage('ckeditor_templates'); +- +- $nids = $storage->getQuery() +- ->condition('status', 1) +- ->sort('weight', 'ASC') +- ->execute(); +- +- return $storage->loadMultiple($nids); +- } +- +- /** +- * Gets the thumbnail for an image. +- * +- * @param string $thumb +- * The thumb image id. +- * +- * @param string $thumb_alternative +- * The alternative thumb image url. +- * +- * @return string +- * The thumb image URL. +- * +- * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException +- * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException +- */ +- private function getThumb(string $thumb, string $thumb_alternative): string { +- $image = ''; +- +- if (!empty($thumb)) { +- $file = $this->entityTypeManager +- ->getStorage('file') +- ->load($thumb); +- +- if (isset($file)) { +- $fileUri = $file->getFileUri(); +- +- $style = $this->entityTypeManager +- ->getStorage('image_style') +- ->load('thumbnail'); +- if (isset($style)) { +- $image = $style->buildUrl($fileUri) ?? ''; +- } +- else { +- $image = $this->fileUrlGenerator->generateAbsoluteString($fileUri) ?? ''; +- } +- } +- } +- +- if (empty($image)) { +- $image = empty($thumb_alternative) +- ? $this->moduleFolder . '/js/ckeditor5_plugins/ckeditor_templates/theme/images/placeholder.svg' +- : $thumb_alternative; +- } +- +- return $image; +- } +- + /** + * {@inheritdoc} + */ +@@ -175,38 +73,28 @@ class CKEditorTemplatesDialogForm extends FormBase { + /** + * {@inheritdoc} + */ +- public function buildForm(array $form, FormStateInterface $form_state, string $editor_id = ''): array { ++ public function buildForm(array $form, FormStateInterface $form_state, EditorInterface $editor = NULL): array { + $templates = []; + + // Gets the templates. +- foreach ($this->templates as $key => $template) { +- if (in_array($editor_id, $template['formats'])) { ++ foreach ($this->ckeditorTemplateManager->getTemplates() as $key => $template) { ++ if (in_array($editor->id(), $template->allowedFormats())) { + $templates[$key] = ' +- ' . $template['label'] . ' ++ ' . $template->label() . ' +
+- ' . $template['label'] . ' +- ' . $template['description'] . ' ++ ' . $template->label() . ' ++ ' . $template->getDescription() . ' +
+ '; + } + } + +- // Gets the editor. +- try { +- $editor = $this->entityTypeManager +- ->getStorage('editor') +- ->load($editor_id); +- } +- catch (InvalidPluginDefinitionException | PluginNotFoundException $e) { +- $this->logger('templates')->critical($e->getMessage()); +- } +- + // Validate there are templates. +- if (empty($templates) || !isset($editor)) { ++ if (empty($templates)) { + $form['warning'] = [ + '#type' => 'markup', + '#markup' => $this->t('There is no template available for the @formatLabel text format.', [ +- '@formatLabel' => $editor?->label() ?? $editor_id, ++ '@formatLabel' => $editor->label(), + ]), + ]; + +@@ -223,6 +111,9 @@ class CKEditorTemplatesDialogForm extends FormBase { + $form['templates'] = [ + '#type' => 'radios', + '#options' => $templates, ++ '#wrapper_attributes' => [ ++ 'class' => ['form-radios--templates'], ++ ], + ]; + + $settings = $editor->getSettings(); +@@ -263,12 +154,12 @@ class CKEditorTemplatesDialogForm extends FormBase { + public function ajaxSubmitForm(array &$form, FormStateInterface $form_state): AjaxResponse | array { + $response = new AjaxResponse(); + +- $template = $form_state->getValue('templates'); +- if (isset($template)) { +- $htmlCode = $this->templates[$template]['code'] ?? ''; +- if (!empty($htmlCode)) { ++ $template_id = $form_state->getValue('templates'); ++ if (isset($template_id)) { ++ $html_code = $this->ckeditorTemplateManager->createInstance($template_id)->getHtml(); ++ if (!empty($html_code)) { + $response->addCommand(new EditorDialogSave([ +- 'htmlCode' => $htmlCode, ++ 'htmlCode' => $html_code, + 'replace' => $form_state->getValue('replace_content'), + ])); + } +diff --git a/src/Plugin/CKEditor5Plugin/CKEditorTemplatesDialog.php b/src/Plugin/CKEditor5Plugin/CKEditorTemplatesDialog.php +index d504e0a..a8fd29c 100644 +--- a/src/Plugin/CKEditor5Plugin/CKEditorTemplatesDialog.php ++++ b/src/Plugin/CKEditor5Plugin/CKEditorTemplatesDialog.php +@@ -56,11 +56,11 @@ class CKEditorTemplatesDialog extends CKEditor5PluginDefault implements CKEditor + * {@inheritdoc} + */ + public function getDynamicPluginConfig(array $static_plugin_config, EditorInterface $editor): array { +- $dialogUrl = Url::fromRoute('ckeditor_templates.selector', [ +- 'editor_id' => $editor->id(), ++ $dialog_url = Url::fromRoute('ckeditor_templates.selector', [ ++ 'editor' => $editor->id(), + ])->toString(); + +- $static_plugin_config['ckeditorTemplates']['dialogUrl'] = $dialogUrl; ++ $static_plugin_config['ckeditorTemplates']['dialogUrl'] = $dialog_url; + + return $static_plugin_config; + } +diff --git a/src/Plugin/CkeditorTemplate/ConfigTemplate.php b/src/Plugin/CkeditorTemplate/ConfigTemplate.php +new file mode 100644 +index 0000000..3c684fd +--- /dev/null ++++ b/src/Plugin/CkeditorTemplate/ConfigTemplate.php +@@ -0,0 +1,140 @@ ++entityTypeManager = $entity_type_manager; ++ $this->fileUrlGenerator = $file_url_generator; ++ $this->ckeditorTemplateConfig = $entity_type_manager ++ ->getStorage('ckeditor_templates') ++ ->load($plugin_definition['ckeditor_template_id']); ++ } ++ ++ /** ++ * {@inheritdoc} ++ */ ++ public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { ++ return new static( ++ $configuration, ++ $plugin_id, ++ $plugin_definition, ++ $container->get('extension.list.module'), ++ $container->get('entity_type.manager'), ++ $container->get('file_url_generator') ++ ); ++ } ++ ++ /** ++ * {@inheritdoc} ++ */ ++ public function getThumb(): string { ++ $image = ''; ++ $thumb = $this->ckeditorTemplateConfig->get('thumb')[0]; ++ $thumb_alternative = $this->ckeditorTemplateConfig->get('thumb_alternative'); ++ ++ if (!empty($thumb)) { ++ $file = $this->entityTypeManager ++ ->getStorage('file') ++ ->load($thumb); ++ ++ if (isset($file)) { ++ $fileUri = $file->getFileUri(); ++ ++ $style = $this->entityTypeManager ++ ->getStorage('image_style') ++ ->load('thumbnail'); ++ if (isset($style)) { ++ $image = $style->buildUrl($fileUri) ?? ''; ++ } ++ else { ++ $image = $this->fileUrlGenerator->generateAbsoluteString($fileUri) ?? ''; ++ } ++ } ++ } ++ ++ if (empty($image)) { ++ $image = empty($thumb_alternative) ++ ? parent::getThumb() ++ : $thumb_alternative; ++ } ++ ++ return $image; ++ } ++ ++ /** ++ * {@inheritdoc} ++ */ ++ public function allowedFormats(): array { ++ return $this->ckeditorTemplateConfig->get('formats'); ++ } ++ ++ /** ++ * {@inheritdoc} ++ */ ++ public function getHtml(): string { ++ return $this->ckeditorTemplateConfig->get('code'); ++ } ++} +diff --git a/src/Plugin/Derivative/ConfigTemplateDeriver.php b/src/Plugin/Derivative/ConfigTemplateDeriver.php +new file mode 100644 +index 0000000..65e3de8 +--- /dev/null ++++ b/src/Plugin/Derivative/ConfigTemplateDeriver.php +@@ -0,0 +1,78 @@ ++entityTypeManager = $entity_type_manager; ++ } ++ ++ /** ++ * {@inheritdoc} ++ */ ++ public static function create(ContainerInterface $container, $base_plugin_id) { ++ return new static( ++ $container->get('entity_type.manager') ++ ); ++ } ++ ++ /** ++ * {@inheritdoc} ++ */ ++ public function getDerivativeDefinitions($base_plugin_definition) { ++ foreach ($this->getTemplates() as $ckeditor_template) { ++ $derivative = $base_plugin_definition; ++ $derivative['ckeditor_template_id'] = $ckeditor_template->id(); ++ $derivative['label'] = $ckeditor_template->label(); ++ $derivative['description'] = $ckeditor_template->get('description') ?? ''; ++ $derivative['weight'] = $ckeditor_template->get('weight'); ++ $this->derivatives[$ckeditor_template->id()] = $derivative; ++ } ++ ++ return $this->derivatives; ++ } ++ ++ /** ++ * Loads the CKEditor Templates. ++ * ++ * @return \Drupal\ckeditor_templates\CKEditorTemplatesInterface[] ++ * A list of CKEditor Template entities. ++ * ++ * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException ++ * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException ++ */ ++ private function getTemplates(): array { ++ $storage = $this->entityTypeManager ++ ->getStorage('ckeditor_templates'); ++ ++ $ids = $storage->getQuery() ++ ->condition('status', 1) ++ ->sort('weight', 'ASC') ++ ->execute(); ++ ++ return $storage->loadMultiple($ids); ++ } ++ ++} +-- +GitLab + + +From f569e353a5943caa31c2aa0e47dd97ececdf65f5 Mon Sep 17 00:00:00 2001 +From: Harlor +Date: Wed, 26 Apr 2023 18:14:17 +0200 +Subject: [PATCH 11/11] Minor cleanups to make patch work + +--- + src/CkeditorTemplateInterface.php | 2 +- + src/Form/CKEditorTemplatesDialogForm.php | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/CkeditorTemplateInterface.php b/src/CkeditorTemplateInterface.php +index 478ca86..a235902 100644 +--- a/src/CkeditorTemplateInterface.php ++++ b/src/CkeditorTemplateInterface.php +@@ -25,7 +25,7 @@ interface CkeditorTemplateInterface { + + /** + * Gets the thumbnail for an image. +- * ++ * + * @return string + * The thumb image URL. + */ +diff --git a/src/Form/CKEditorTemplatesDialogForm.php b/src/Form/CKEditorTemplatesDialogForm.php +index 00f5bfe..a88c6ab 100644 +--- a/src/Form/CKEditorTemplatesDialogForm.php ++++ b/src/Form/CKEditorTemplatesDialogForm.php +@@ -36,7 +36,7 @@ class CKEditorTemplatesDialogForm extends FormBase { + * @var boolean + */ + protected bool $templatesLoaded = FALSE; +- ++ + /** + * The AJAX wrapper id. + * +-- +GitLab +