diff --git a/.github/workflows/auto-pr.yml b/.github/workflows/auto-pr.yml
index 6babf87b5e..084b0977d0 100644
--- a/.github/workflows/auto-pr.yml
+++ b/.github/workflows/auto-pr.yml
@@ -1,10 +1,10 @@
-name: Merge branch dev with rel-5.2
+name: Merge branch dev with rel-5.3
on:
push:
branches:
- - rel-5.2
+ - rel-5.3
jobs:
- merge-dev-with-rel-5-2:
+ merge-rel-5-3-with-rel-5-2:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
@@ -12,13 +12,13 @@ jobs:
ref: dev
- name: Reset promotion branch
run: |
- git fetch origin rel-5.2:rel-5.2
- git reset --hard rel-5.2
+ git fetch origin rel-5.3:rel-5.3
+ git reset --hard rel-5.3
- name: Create Pull Request
uses: peter-evans/create-pull-request@v3
with:
- branch: auto-merge/rel-5-2/${{github.run_number}}
- title: Merge branch dev with rel-5.2
- body: This PR generated automatically to merge dev with rel-5.2. Please review the changed files before merging to prevent any errors that may occur.
+ branch: auto-merge/rel-5-3/${{github.run_number}}
+ title: Merge branch dev with rel-5.3
+ body: This PR generated automatically to merge dev with rel-5.3. Please review the changed files before merging to prevent any errors that may occur.
reviewers: ${{github.actor}}
token: ${{ github.token }}
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json
index 89b7d03f5b..1dc0d7c1f7 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json
@@ -384,6 +384,15 @@
"ShowBetweenDayCount": "Show Between Days",
"PurchaseOrder": "Purchase Order",
"ShowCreateInvoiceOfOrganization": "Create Invoice",
- "ShowCreateQuotationOfOrganization": "Create Quotation"
+ "ShowCreateQuotationOfOrganization": "Create Quotation",
+ "BookDiscounts": "Book Discounts",
+ "Permission:BookDiscount": "Book Discount",
+ "Menu:BookDiscounts": "Book Discounts",
+ "BookType": "Book Type",
+ "PurchasePlatform": "Purchase Platform",
+ "StartTime": "Start Time",
+ "EndTime": "End Time",
+ "CreateABookDiscount": "Create a book discount",
+ "BookDiscountDeletionConfirmationMessage": "Are you sure you want to delete this book discount?"
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json
index 5d6e081085..e898619b64 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json
@@ -121,6 +121,10 @@
"MasteringAbpFrameworkBook": "Book: Mastering ABP Framework",
"ABPIO-CommonPreferenceDefinition": "Get the latest news about ABP Platform like new posts, events and more.",
"BuiltOn": "Built-on",
- "AbpFramework": "ABP Framework"
+ "AbpFramework": "ABP Framework",
+ "Volo.AbpIo.Domain:080001": "Start Time can not be greater than End Time",
+ "Enum:BookType:0": "Mastering ABP Framework",
+ "Enum:PurchasePlatform:0": "Amazon",
+ "Enum:PurchasePlatform:1": "Packt"
}
}
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json
index baaa28edb0..5a63ea7869 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json
@@ -49,7 +49,7 @@
"IndexPageHeroSection": "A complete web development platformbuilt-on framework",
"AbpCommercialShortDescription": "ABP Commercial provides pre-built application modules, rapid application development tooling, professional UI themes, premium support and more.",
"LiveDemo": "Live Demo",
- "GetLicence": "Get a Licence",
+ "GetLicence": "Get a License",
"Application": "Application",
"StartupTemplates": "Startup Templates",
"Startup": "Startup",
@@ -199,6 +199,7 @@
"WhatHappensWhenLicenseEndsExplanation5": "You can not use the ABP Suite.",
"WhatHappensWhenLicenseEndsExplanation6": "You can not get the premium support anymore.",
"WhatHappensWhenLicenseEndsExplanation7": "You can extend (renew) your license if you want to continue getting these benefits. If you extend your license within 1 month after your license expires, the following discounts will be applied: Team License {0}% discount, Business License {1}% discount, Enterprise License {2}% discount.",
+ "WhatHappensWhenLicenseEndsExplanation8": "The ABP projects you generated are not stored on our servers. Therefore, it is your responsibility to keep the source code you download. When your license expires, there's no way to get your generated ABP project source code.",
"WhenShouldIRenewMyLicense": "When should I renew my license?",
"WhenShouldIRenewMyLicenseExplanation": "If you renew your license within 1 month after your license expires, the following discounts will be applied: Team License {0}% discount, Business License {1}% discount, Enterprise License {2}% discount. However, if you renew your license after 1 month since the expiry date of your license, the renewal price will be the same as the license purchase price and there will be no discount on your renewal.",
"TrialPlan": "Do you have a trial plan?",
@@ -271,7 +272,7 @@
"Enterprise": "Enterprise",
"Custom": "Custom",
"IncludedDeveloperLicenses": "Included developer licenses",
- "CustomLicenceOrAdditionalServices": "Need custom licence or additional services?",
+ "CustomLicenceOrAdditionalServices": "Need custom license or additional services?",
"CustomOrVolumeLicense": "Custom or volume license",
"LiveTrainingSupport": "Live training & support",
"AndMore": "and more",
@@ -506,6 +507,7 @@
"OnboardingTrainingFaqTitle": "Do you have ABP onboarding training?",
"OnboardingTrainingFaqExplanation": "Yes, we have ABP Training Services to help you get your ABP project started fast. You will learn about ABP from an ABP core team member and you will get the skills to begin your ABP project. In the onboarding training, we will explain how to set up your development environment, install the required tools, create a fully functional CRUD page. The training will be live and the Zoom application will be used, and we are open to using other online meeting platforms. The language of the training will be English. You can also ask your questions about ABP during the sessions. A convenient time and date will be planned for both parties. To get more information, contact us at info@abp.io.",
"AddBasket": "Add to Basket",
- "SendTrainingRequest": "Send Training Request"
+ "SendTrainingRequest": "Send Training Request",
+ "OnlyEnglishVersionOfThisDocumentIsTheRecentAndValid": "* The English version of this document is the most up-to-date and the English version will prevail in any dispute."
}
}
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en-GB.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en-GB.json
index e4112a4900..0283b963bc 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en-GB.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en-GB.json
@@ -102,6 +102,7 @@
"PostRequestMessageBody": "Here is the list of the requested posts by the Community. Do you want to write a requested post? Please click on the request and join the discussion.",
"Language": "Language",
"CreatePostLanguageInfo": "Language of the post",
- "SeeMore": "See More"
+ "SeeMore": "See More",
+ "MemberNotPublishedPostYet": "This member hasn't published any posts yet."
}
}
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json
index 54cf7e10fe..de04b36283 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json
@@ -165,6 +165,7 @@
"SortBy": "Sort by",
"NoPublishedEventsYet": "No published events yet.",
"SubscribeYoutubeChannel": "Subscribe to the Youtube Channel",
- "Enum:EventType:0": "Talks"
+ "Enum:EventType:0": "Talks",
+ "MemberNotPublishedPostYet": "This member hasn't published any posts yet."
}
}
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/tr.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/tr.json
index 72d6c5e28d..0b118ed73d 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/tr.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/tr.json
@@ -142,6 +142,7 @@
"MinimumSearchContent": "En az 3 karakter girmelisiniz!",
"Volo.AbpIo.Domain:060001": "Kaynak URL (\"{PostUrl}\") Github URL'si değil",
"Volo.AbpIo.Domain:060002": "Makale İçeriği Github(\"{PostUrl}\") kaynağında mevcut değil.",
- "Volo.AbpIo.Domain:060003": "Makale içeriği bulunamadı!"
+ "Volo.AbpIo.Domain:060003": "Makale içeriği bulunamadı!",
+ "MemberNotPublishedPostYet": "Bu üye henüz bir gönderi yayınlamadı."
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/en.json
index 35b755e8c3..d17259241c 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/en.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/en.json
@@ -174,6 +174,7 @@
"CreateProjectWizard": "This wizard creates a new project from the startup template which is properly configured to jump start your project.",
"TieredOption": "Creates a tiered solution where Web and Http API layers are physically separated. If not checked, creates a layered solution which is less complex and suitable for most scenarios.",
"SeparateIdentityServerOption": "Separates the server side into two applications: The first one is for the identity server and the second one is for your server side HTTP API.",
+ "ProgressiveWebApplicationOption": "Specifies the project as Progressive Web Application",
"UseslatestPreVersion": "Uses the latest pre-release version",
"ReadTheDocumentation": "Read The Documentation",
"Documentation": "Documentation",
@@ -296,6 +297,7 @@
"EnterYouEmailToGetNews": "Enter your email to get the latest news about the ABP Framework",
"Tiered": "Tiered",
"SeparateIdentityServer": "Separate Identity Server",
+ "ProgressiveWebApplication": "Progressive Web Application",
"Preview": "Preview",
"CreateANewSolution": "Create a new solution",
"ABPFrameworkFeatures": "ABP Framework Features",
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/tr.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/tr.json
index ad8393fab3..01fe9f8b7b 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/tr.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/tr.json
@@ -174,6 +174,8 @@
"CreateProjectWizard": "Bu sihirbaz, projenize atlamak için uygun şekilde yapılandırılmış başlangıç şablonundan yeni bir proje oluşturur.",
"TieredOption": "Web ve Http API katmanlarının fiziksel olarak ayrıldığı katmanlı bir çözüm oluşturur. İşaretlenmezse, daha az karmaşık olan ve çoğu senaryo için uygun olan katmanlı bir çözüm oluşturur.",
"SeparateIdentityServerOption": "Sunucu tarafını iki uygulamaya ayırır: Birincisi kimlik sunucusu için, ikincisi ise sunucu tarafı HTTP API'niz içindir.",
+ "ProgressiveWebApplicationOption": "Projeyi Progresif Web Uygulaması olarak ayarlayın.",
+ "ProgressiveWebApplication": "Progresif Web Uygulaması",
"UseslatestPreVersion": "En son yayın öncesi sürümünü kullanır",
"ReadTheDocumentation": "Belgeleri okuyun",
"Documentation": "belgeler",
diff --git a/build/common.ps1 b/build/common.ps1
index d9ebc2f87c..01a7565fba 100644
--- a/build/common.ps1
+++ b/build/common.ps1
@@ -14,6 +14,7 @@ $solutionPaths = @(
"../modules/feature-management",
"../modules/identity",
"../modules/identityserver",
+ "../modules/openiddict",
"../modules/tenant-management",
"../modules/audit-logging",
"../modules/background-jobs",
diff --git a/common.props b/common.props
index facc92f0bc..35dd3cfe40 100644
--- a/common.props
+++ b/common.props
@@ -1,7 +1,7 @@
latest
- 5.3.0
+ 5.4.0$(NoWarn);CS1591;CS0436https://abp.io/assets/abp_nupkg.pnghttps://abp.io/
diff --git a/docs/en/Background-Jobs.md b/docs/en/Background-Jobs.md
index 2e0b5d3f65..84e746f73d 100644
--- a/docs/en/Background-Jobs.md
+++ b/docs/en/Background-Jobs.md
@@ -155,8 +155,6 @@ public class MyModule : AbpModule
}
````
-> Default background manager (see below) does not support multiple processes execute the same job queue. So, if you have multiple running instance of your application and you are using the default background job manager, you should only enable one application instance process the job queue.
-
## Default Background Job Manager
ABP framework includes a simple `IBackgroundJobManager` implementation that;
@@ -189,12 +187,23 @@ public class MyModule : AbpModule
### Data Store
-The default background job manager needs a data store to save and read jobs. It defines `IBackgroundJobStore` as an abstraction. So, you can replace the implementation if you want.
+The default background job manager needs a data store to save and read jobs. It defines `IBackgroundJobStore` as an abstraction to store the jobs.
-Background Jobs module implements `IBackgroundJobStore` using various data access providers. See its own [documentation](Modules/Background-Jobs.md).
+Background Jobs module implements `IBackgroundJobStore` using various data access providers. See its own [documentation](Modules/Background-Jobs.md). If you don't want to use this module, you should implement the `IBackgroundJobStore` interface yourself.
> Background Jobs module is already installed to the startup templates by default and it works based on your ORM/data access choice.
+### Clustered Deployment
+
+The default background job manager is compatible with [clustered environments](Deployment/Clustered-Environment.md) (where multiple instances of your application run concurrently). It uses a [distributed lock](Distributed-Locking.md) to ensure that the jobs are executed only in a single application instance at a time.
+
+However, the distributed lock system works in-process by default. That means it is not distributed actually, unless you configure a distributed lock provider. So, **please follow the [distributed lock](Distributed-Locking.md) document to configure a provider for your application**, if it is not already configured.
+
+If you don't want to use a distributed lock provider, you may go with the following options:
+
+* Stop the background job manager (set `AbpBackgroundJobOptions.IsJobExecutionEnabled` to `false` as explained in the *Disable Job Execution* section) in all application instances except one of them, so only the single instance executes the jobs (while other application instances can still queue jobs).
+* Stop the background job manager (set `AbpBackgroundJobOptions.IsJobExecutionEnabled` to `false` as explained in the *Disable Job Execution* section) in all application instances and create a dedicated application (maybe a console application running in its own container or a Windows Service running in the background) to execute all the background jobs. This can be a good option if your background jobs consume high system resources (CPU, RAM or Disk), so you can deploy that background application to a dedicated server and your background jobs don't affect your application's performance.
+
## Integrations
Background job system is extensible and you can change the default background job manager with your own implementation or on of the pre-built integrations.
diff --git a/docs/en/Background-Workers.md b/docs/en/Background-Workers.md
index 726a8817ab..e1cce6ae28 100644
--- a/docs/en/Background-Workers.md
+++ b/docs/en/Background-Workers.md
@@ -126,10 +126,11 @@ Background workers only work if your application is running. If you host the bac
Be careful if you run multiple instances of your application simultaneously in a clustered environment. In that case, every application runs the same worker which may create conflicts if your workers are running on the same resources (processing the same data, for example).
-If that's a problem for your workers, you have two options;
+If that's a problem for your workers, you have the following options:
-* Disable the background worker system using the `AbpBackgroundWorkerOptions` described above, for all the application instances, except one of them.
-* Disable the background worker system for all the application instances and create another special application that runs on a single server and execute the workers.
+* Implement your background workers so that they work in a clustered environment without any problem. Using the [distributed lock](../Distributed-Locking.md) to ensure concurrency control is a way of doing that. A background worker in an application instance may handle a distributed lock, so the workers in other application instances will wait for the lock. In this way, only one worker does the actual work, while others wait in idle. If you implement this, your workers run safely without caring about how the application is deployed.
+* Stop the background workers (set `AbpBackgroundWorkerOptions.IsEnabled` to `false`) in all application instances except one of them, so only the single instance runs the workers.
+* Stop the background workers (set `AbpBackgroundWorkerOptions.IsEnabled` to `false`) in all application instances and create a dedicated application (maybe a console application running in its own container or a Windows Service running in the background) to execute all the background tasks. This can be a good option if your background workers consume high system resources (CPU, RAM or Disk), so you can deploy that background application to a dedicated server and your background tasks don't affect your application's performance.
## Integrations
diff --git a/docs/en/Blog-Posts/2022-05-09 v5_3_Preview/POST.md b/docs/en/Blog-Posts/2022-05-09 v5_3_Preview/POST.md
new file mode 100644
index 0000000000..b23dab0cd1
--- /dev/null
+++ b/docs/en/Blog-Posts/2022-05-09 v5_3_Preview/POST.md
@@ -0,0 +1,258 @@
+# ABP.IO Platform 5.3 RC Has Been Released
+
+Today, we are happy to release the [ABP Framework](https://abp.io/) and [ABP Commercial](https://commercial.abp.io/) version **5.3 RC** (Release Candidate). This blog post introduces the new features and important changes in this new version.
+
+> **The planned release date for the [5.3.0 Stable](https://github.com/abpframework/abp/milestone/69) version is May 31, 2022**.
+
+Please try this version and provide feedback for a more stable ABP version 5.3! Thank you all.
+
+## Get Started with the 5.3 RC
+
+Follow the steps below to try version 5.3.0 RC today:
+
+1) **Upgrade** the ABP CLI to version `5.3.0-rc.1` using a command line terminal:
+
+````bash
+dotnet tool update Volo.Abp.Cli -g --version 5.3.0-rc.1
+````
+
+**or install** it if you haven't before:
+
+````bash
+dotnet tool install Volo.Abp.Cli -g --version 5.3.0-rc.1
+````
+
+2) Create a **new application** with the `--preview` option:
+
+````bash
+abp new BookStore --preview
+````
+
+See the [ABP CLI documentation](https://docs.abp.io/en/abp/latest/CLI) for all the available options.
+
+> You can also use the *Direct Download* tab on the [Get Started](https://abp.io/get-started) page by selecting the **Preview checkbox**.
+
+You can use any IDE that supports .NET 6.x, like **[Visual Studio 2022](https://visualstudio.microsoft.com/downloads/)**.
+
+## Migration Notes
+
+There is a change in this version that may effect your applications:
+
+* Upgraded the [AutoMapper](https://github.com/AutoMapper/AutoMapper) library to **v11.0.1**. So, you need to change your project's target SDK that use the **AutoMapper** library (typically your `*.Application` project). You can change it from `netstandard2.0` to `netstandard2.1` or `net6` if needed. You can write to [#12189](https://github.com/abpframework/abp/pull/12189) if you need any help.
+
+## What's New with ABP Framework 5.3?
+
+In this section, I will introduce some major features released with this version. Here is a brief list of titles explained in the next sections:
+
+* Single-layer option added to the [*Get Started*](https://abp.io/get-started) page
+* PWA Support for Startup Templates
+* Introduced the `Volo.Abp.Gdpr.Abstractions` package
+* Batch Publish Events from Outbox to the Event Bus
+* Improvements on **eShopOnAbp** Project & E-Book Announcement
+* LeptonX Lite Documentations & Project Status & Roadmap
+* OpenIddict Module & Keycloack Integration
+* Deployment Documentations
+* Other News
+
+### Single-layer Option on *Get Started* Page
+
+We've created a new startup template named `app-nolayers` and [announced](https://blog.abp.io/abp/ABP.IO-Platform-5-2-RC-Has-Been-Published) it in the previous version. In this version, we've also added this startup template option to the *Get Started* page.
+
+*You can examine the screenshot below to see how to create an `app-nolayers` template from the ["Get Started"](https://abp.io/get-started) page:*
+
+
+
+### PWA Support for Startup Templates
+
+ABP v5.3 application startup template now supports PWA for Blazor WASM & Angular UIs. To create a startup template with the PWA support, you can use the `--pwa` parameter.
+
+Example:
+
+```bash
+abp new MyProgressiveWebApp -t app -u blazor --pwa
+```
+
+### Introducing the `Volo.Abp.Gdpr.Abstractions` Package
+
+A new `Volo.Abp.Gdpr.Abstractions` package has been added to the framework. This is an abstraction package, so doesn't contain any actual GDPR implementation. It defines some classes and interfaces to put a standard for who want to implement a GDPR module that can run in a modular or microservice system.
+
+At that point, we are introducing the **GDPR Module** for the ABP Commercial customers and this module does the GDPR-related operations on behalf of you, such as *"Download/Delete Personal Data"*. I'll describe the **GDPR Module** later in this blog post.
+
+> Please see the **GDPR Module** section below to learn more about this module.
+
+### Batch Publish Events from Outbox to the Event Bus
+
+We introduced the "Transactional Outbox & Inbox Patterns" in [**ABP v5.0**](https://blog.abp.io/abp/ABP-IO-Platform-5.0-RC-1-Has-Been-Released), it was one of the most awaited features by several software developers.
+
+We've made some optimizations for the **Batch Event Publishing** in this version, you can examine the related development from [here](https://github.com/abpframework/abp/pull/11243). After the optimization, the results are impressive. It is enabled by default (if you have configured [event outbox](https://docs.abp.io/en/abp/latest/Distributed-Event-Bus#outbox-inbox-for-transactional-events)), so you don't need to any manual configuration.
+
+### Improvements on eShopOnAbp Project & E-Book Announcement
+
+There are some developments on the [eShopOnAbp project](https://github.com/abpframework/eShopOnAbp) made in this version. You can see the brief descriptions of some of the improvements below:
+
+* Local certificates have been created to use while working in Kubernetes and also Helm Charts have been updated. See [#107](https://github.com/abpframework/eShopOnAbp/pull/107).
+* The Order Management page has been created. See [#92](https://github.com/abpframework/eShopOnAbp/pull/92).
+* Database migration event handlers have been removed and "Distributed Locking" is now used for database migrations. See [#85](https://github.com/abpframework/eShopOnAbp/pull/85) and [#102](https://github.com/abpframework/eShopOnAbp/pull/102).
+* Switched from Ocelot to YARP as the gateway. See [#97](https://github.com/abpframework/eShopOnAbp/pull/97).
+
+We have exciting news to share with the community, we're working on an "ABP Microservice Development" e-book. In this book, we're using the eShopOnAbp project as a reference microservice solution and we're trying to explain our experiences during the microservice application development process through this project.
+
+We're planning to create this book in nine chapters and make it available after the third chapter is written. After that, you will be able to download this free e-book from the [abp.io](https://abp.io/) website.
+
+### LeptonX Lite Documentations & Project Status & Roadmap
+
+It is finally here, we've released the **1.0.0-beta.1** version for the **LeptonX Lite**.
+
+
+
+Lepton X Lite documents have been written for the three UI types within this version. You can see the related documentation from the screenshot above. You can follow these documents and try the new **LeptonX Lite Theme**.
+
+We don't suggest using the **beta.1** version on production, we highly demand you to test **LeptonX Lite** and provide feedback to us. It's really important for us to be able to release a more stable version. Thanks in advance.
+
+For the following versions (beta.2 and RC versions), we will focus on:
+
+* Fixing the reported bugs from the community
+* Providing documentations as much as possible
+* Adding new custom pages to the demo
+
+### OpenIddict Module & Keycloack Integration
+
+We have [announced the plan of replacing the IdentityServer](https://github.com/abpframework/abp/issues/11989). ABP currently uses **IdentityServer4** to add **OAuth** features as built-in on the server-side. However, since *IdentityServer4's support ends at the end of the year 2022*. Its replacement is Duende IdentityServer, which is not a free software anymore. (see [more](https://blog.duendesoftware.com/posts/20220111_fair_trade/))
+
+Therefore, we've decided to completely drop the **IdentityServer4** from the ABP platform and implement the [OpenIddict](https://github.com/openiddict/openiddict-core) and install onto the startup templates.
+
+We've implemented both open source and commercial OpenIddict modules, we plan to remove Identity Server and replace it with OpenIddict for template projects in **ABP v5.4**. Please check [#12084](https://github.com/abpframework/abp/pull/12084) to see the development made on the open-source side.
+
+We're creating the documentation for the OpenIddict Module, if you want to have general knowledge about this module, you can check the documentation from [here](https://github.com/abpframework/abp/blob/dev/docs/en/Modules/OpenIddict.md). Currently, this is a draft documentation but it gives overall knowledge about the OpenIddict Module, we'll complete this documentation in ABP v5.4 and you'll be able to read it completely.
+
+Currently, we are also working on Keycloak integration possibilities in parallel to the OpenIddict integration research and we've prepared some samples that you can examine. You can see [#154](https://github.com/abpframework/abp-samples/pull/154) and [#158](https://github.com/abpframework/abp-samples/pull/158).
+
+### Deployment Documentations
+
+Deploying an ABP-based application is not so different than deploying any .NET or ASP.NET Core application. You can deploy it to a cloud provider (e.g. Azure, AWS, Google Could) or on-premise server, IIS or any other web server. However, we wanted to prepare a "Deployment Guide" to mention the important points and considerations.
+
+
+
+In the [Deploying to a Clustered Environment](https://docs.abp.io/en/abp/5.3/Deployment/Clustered-Environment) documentation, we've documented the topics that you should consider when you are developing your application to a clustered environment and explained how you can deal with these topics in your ABP-based application.
+
+### Other News
+
+* Global Features were only accessible from the C# code. From this version and on, Global Features can be also provided from application configurations. See [#12043](https://github.com/abpframework/abp/pull/12043).
+* Getting the user's detailed information (name, surname and phone number) from external login. See [#12085](https://github.com/abpframework/abp/pull/12085).
+* Date Pipes for Angular. See [#11909](https://github.com/abpframework/abp/issues/11909).
+
+If you want to see more details, you can check [the release on GitHub](https://github.com/abpframework/abp/releases/tag/5.3.0-rc.1), which contains a list of all the issues and pull requests closed with this version.
+
+## What's New with ABP Commercial 5.3?
+
+### GDPR Module
+
+> **GDPR (General Data Protection Regulation)** is a regulation in EU law on data protection and known as the toughest privacy and security law in the world. GDPR applies to any organization operating within the EU, as well as any organizations outside of the EU which offer goods or services to customers or businesses in the EU.
+
+With this version, we are introducing the new **GDPR Module**. This was one of the most awaited features, so we've prioritized it and implemented it in this version.
+
+The GDPR Module is pre-installed in the [startup templates](https://docs.abp.io/en/commercial/5.3/startup-templates/index) for MVC. So, no need to manually install it. When you create a new startup template, you can directly use this module. We'll also implement this module for the other UI types as soon as possible and also add extra functionality such as "Cookie Consent" and more.
+
+Currently, there are two main functions of this module and they are "Download Personal Data" and "Delete Personal Data".
+
+
+
+There is a "Personal Data" section in the user menu as in the screenshot above and when you click on this section, you'll be redirected to the "Personal Data" page. On that page, you can either request to "Download Personal Data" or "Delete Personal Data".
+
+
+
+After you've requested to download "Personal Data", you need to wait for 1 hour by default (you can configure the related option). Because the GDPR module is developed by considering the distributed systems and therefore a specific time should be passed to ensure all the published events are handled and all personal data is collected.
+
+### CMS Kit Pro - Polling Feature
+
+We've added a **Polling** feature to the **CMS Kit Pro** module. This feature allows you to use a questionnaire/voting system in your application easily. You can create a question, define some options for it and the poll will be created for you. You can see the example poll in the screenshot below:
+
+
+
+Also, there is an admin side of the Polling Feature. You can easily manage your polls in your admin (back-office) project. You can create, update, delete and show the results of the poll on the Polls page:
+
+
+
+### OAuth Resource Owner Password as External Login Provider
+
+> The Resource Owner Password flow allows for the exchanging of the username and password of a user for an access token. When using the resource owner password credentials grant, the user provides the credentials (username and password) directly to the application.
+
+Now, you can login by entering a username and password from an OAuth server.
+
+Example: Use OAuth external login provider with Keycloak:
+
+
+
+### Suite New Features & Enhancements
+
+In this version, there are some enhancements and new features in **Suite** and they are listed briefly below:
+
+* It's now possible to create an **app-nolayers (Application - single layer)** template via Suite and also code-generation is supported for the **app-nolayers** template with this version.
+* Suite now allows users to see and download its logs.
+* Suite now allows generating code via CLI. If you have a JSON file that contains code blocks, like entity configurations, you can use the `abp suite generate` command to generate CRUD pages based on it.
+
+Example:
+
+```bash
+abp suite generate -e C:\Users\.suite\entities\Country.json -s C:\Users\my-proj\SuiteProj\SuiteProj.sln
+```
+
+### Suite Webinar: Take a closer look at the code generation
+
+
+
+We've organized a webinar for Suite and in this webinar, we've talked about ABP Suite's capabilities, important features and more...
+
+You can watch the event from [here](https://www.youtube.com/watch?v=RFArBh60RSA&t=3s), if you haven't watched it yet.
+
+### Docker Compose Configurations for Single Layer Startup Template
+
+Dockerfiles, docker-compose files and build script files have been added to the Single Layer Startup Template (app-nolayers) with this version.
+
+And this way, applications created with this template now can be deployed more easily.
+
+### Microservice Solution Enhancements
+
+There are some enhancements made in the Microservice Solution. You can see the list of these enhancements:
+
+* Initial migration on the template has been updated with the small improvement that was made in the **Language Management** module.
+* Database migration event handlers have been removed and "Distributed Locking" is now used for the database migrations.
+
+### PWA Support for the Application Pro Template
+
+Application Pro template also supports the PWA for Blazor WASM & Angular UIS. To create a startup template with the PWA support, you can use the `--pwa` parameter.
+Example:
+
+```bash
+abp new MyProgressiveWebApp -t app-pro -u blazor --pwa
+```
+
+## Community News
+
+### New ABP Community Posts
+
+* [Anto Subash](https://twitter.com/antosubash) created a series named ["Microservice with ABP"](https://blog.antosubash.com/posts/abp-microservice-series) and shared a couple of video posts about the ABP Microservice solution.
+* [Francisco Kadzi](https://github.com/CiscoNinja) has created his first ABP Community article that shows how to ["Customize ABP Angular Application UI with AdminLTE"](https://community.abp.io/posts/customize-abp-angular-application-ui-with-adminlte.-7qu1m67s).
+* [Jack Fistelmann](https://github.com/nebula2) has created an article to introduce a helpful project extension to speed up development on Visual Studio. You can read the article [here](https://community.abp.io/posts/using-switch-startup-project-extension-for-visual-studio-52yyw27v).
+* [Jack Fistelmann](https://github.com/nebula2) has also created an article to show how you can generate PDF files with the `Sycyber.Core` package in ABP-based applications. You can read it [here](https://community.abp.io/posts/generate-pdfs-in-an-abp-framework-project-using-scryber.core-x9yh1vfa).
+* [Halil Ibrahim Kalkan](https://twitter.com/hibrahimkalkan) has created an article to show ["Dealing with Multiple Implementations of a Service in ASP.NET Core & ABP Dependency Injection"](https://community.abp.io/posts/dealing-with-multiple-implementations-of-a-service-in-asp.net-core-abp-dependency-injection-ysfp4ho2) with examples.
+* [Manoj Kumar](https://community.abp.io/members/manojkumar.t@shloklabs.com) submitted a new article about how to use "ABP authentication in a Flutter application". It was a frequently asked topic, which you can read [here](https://community.abp.io/posts/flutter-web-authentication-from-abp-mp6l2ehx).
+* [Engincan Veske](https://twitter.com/EngincanVeske) created a new Community Article to show "Concurrency Check/Control in ABP". You can read it [here](https://community.abp.io/posts/handle-concurrency-with-ef-core-in-an-abp-framework-project-with-asp.net-core-mvc-jlkc3w8f).
+
+### ABP Community Talks 2022.4: How can you contribute to the open source ABP Framework? (May 10, 2022 - 17:00 UTC)
+
+
+
+We've [asked you to pick the topic of the next Community Talks](https://twitter.com/abpframework/status/1514567683072745474?s=20&t=rJfHrB3DYDNsk2EXS8zBBQ) and you've chosen the "How to contribute to open source ABP Framework?" for the next talk topic. So, in this Community Talk, we will be talking about "How to contribute to ABP Framework" with one of the top contributors of the ABP Framework, [Ismail Yılmaz](https://github.com/iyilm4z). The event will be on **May 10, 2022, at 17:00 (UTC)** on YouTube.
+
+> You can register for the event from [here](https://kommunity.com/volosoft/events/abp-community-talks-20224-how-to-contribute-to-the-open-source-abp-framework-d9b50664), if you haven't registered yet.
+
+You can also [subscribe to the Volosoft channel](https://www.youtube.com/channel/UCO3XKlpvq8CA5MQNVS6b3dQ) to be informed about future ABP events and videos.
+
+### Discord Server
+
+We've created an official ABP Discord server so the ABP Community can interact with each other and created a blog-post to introduce it. You can read the [ABP Discord Server announcement post](https://blog.abp.io/abp/Official-ABP-Discord-Server-is-Here) to learn more about the ABP Discord Server.
+
+Thanks to the ABP Community, **700+** people joined our Discord Server so far and it grows every day.
+
+You can join our Discord Server from [here](https://discord.gg/abp), if you haven't yet.
\ No newline at end of file
diff --git a/docs/en/Blog-Posts/2022-05-09 v5_3_Preview/app-nolayers-get-started.png b/docs/en/Blog-Posts/2022-05-09 v5_3_Preview/app-nolayers-get-started.png
new file mode 100644
index 0000000000..e030dc50b9
Binary files /dev/null and b/docs/en/Blog-Posts/2022-05-09 v5_3_Preview/app-nolayers-get-started.png differ
diff --git a/docs/en/Blog-Posts/2022-05-09 v5_3_Preview/community-talks-2022.4.png b/docs/en/Blog-Posts/2022-05-09 v5_3_Preview/community-talks-2022.4.png
new file mode 100644
index 0000000000..ee5f374ff4
Binary files /dev/null and b/docs/en/Blog-Posts/2022-05-09 v5_3_Preview/community-talks-2022.4.png differ
diff --git a/docs/en/Blog-Posts/2022-05-09 v5_3_Preview/cover-53.png b/docs/en/Blog-Posts/2022-05-09 v5_3_Preview/cover-53.png
new file mode 100644
index 0000000000..d30f63b3a4
Binary files /dev/null and b/docs/en/Blog-Posts/2022-05-09 v5_3_Preview/cover-53.png differ
diff --git a/docs/en/Blog-Posts/2022-05-09 v5_3_Preview/deployment-documentation.png b/docs/en/Blog-Posts/2022-05-09 v5_3_Preview/deployment-documentation.png
new file mode 100644
index 0000000000..3dde546b15
Binary files /dev/null and b/docs/en/Blog-Posts/2022-05-09 v5_3_Preview/deployment-documentation.png differ
diff --git a/docs/en/Blog-Posts/2022-05-09 v5_3_Preview/gdpr-personal-data-page.png b/docs/en/Blog-Posts/2022-05-09 v5_3_Preview/gdpr-personal-data-page.png
new file mode 100644
index 0000000000..2a85dade63
Binary files /dev/null and b/docs/en/Blog-Posts/2022-05-09 v5_3_Preview/gdpr-personal-data-page.png differ
diff --git a/docs/en/Blog-Posts/2022-05-09 v5_3_Preview/gdpr-user-menu.png b/docs/en/Blog-Posts/2022-05-09 v5_3_Preview/gdpr-user-menu.png
new file mode 100644
index 0000000000..5366014b0c
Binary files /dev/null and b/docs/en/Blog-Posts/2022-05-09 v5_3_Preview/gdpr-user-menu.png differ
diff --git a/docs/en/Blog-Posts/2022-05-09 v5_3_Preview/leptonx-lite-documentations.png b/docs/en/Blog-Posts/2022-05-09 v5_3_Preview/leptonx-lite-documentations.png
new file mode 100644
index 0000000000..4186dc99a1
Binary files /dev/null and b/docs/en/Blog-Posts/2022-05-09 v5_3_Preview/leptonx-lite-documentations.png differ
diff --git a/docs/en/Blog-Posts/2022-05-09 v5_3_Preview/oauth-external-provider.gif b/docs/en/Blog-Posts/2022-05-09 v5_3_Preview/oauth-external-provider.gif
new file mode 100644
index 0000000000..8f301559ee
Binary files /dev/null and b/docs/en/Blog-Posts/2022-05-09 v5_3_Preview/oauth-external-provider.gif differ
diff --git a/docs/en/Blog-Posts/2022-05-09 v5_3_Preview/poll-new-question.png b/docs/en/Blog-Posts/2022-05-09 v5_3_Preview/poll-new-question.png
new file mode 100644
index 0000000000..aeec85e5ee
Binary files /dev/null and b/docs/en/Blog-Posts/2022-05-09 v5_3_Preview/poll-new-question.png differ
diff --git a/docs/en/Blog-Posts/2022-05-09 v5_3_Preview/poll-question-example.png b/docs/en/Blog-Posts/2022-05-09 v5_3_Preview/poll-question-example.png
new file mode 100644
index 0000000000..130586ab29
Binary files /dev/null and b/docs/en/Blog-Posts/2022-05-09 v5_3_Preview/poll-question-example.png differ
diff --git a/docs/en/Blog-Posts/2022-05-09 v5_3_Preview/poll-questions.png b/docs/en/Blog-Posts/2022-05-09 v5_3_Preview/poll-questions.png
new file mode 100644
index 0000000000..969ffd6fdb
Binary files /dev/null and b/docs/en/Blog-Posts/2022-05-09 v5_3_Preview/poll-questions.png differ
diff --git a/docs/en/Blog-Posts/2022-05-09 v5_3_Preview/webinar.png b/docs/en/Blog-Posts/2022-05-09 v5_3_Preview/webinar.png
new file mode 100644
index 0000000000..9126215031
Binary files /dev/null and b/docs/en/Blog-Posts/2022-05-09 v5_3_Preview/webinar.png differ
diff --git a/docs/en/CLI.md b/docs/en/CLI.md
index 8931220705..01f7a92b2f 100644
--- a/docs/en/CLI.md
+++ b/docs/en/CLI.md
@@ -92,8 +92,10 @@ For more samples, go to [ABP CLI Create Solution Samples](CLI-New-Command-Sample
* `--tiered`: Creates a tiered solution where Web and Http API layers are physically separated. If not specified, it creates a layered solution which is less complex and suitable for most scenarios.
* `angular`: Angular UI. There are some additional options for this template:
* `--separate-identity-server`: The Identity Server project comes as a separate project and runs at a different endpoint. It separates the Identity Server from the API Host application. If not specified, you will have a single endpoint in the server side.
+ * `--pwa`: Specifies the project as Progressive Web Application.
* `blazor`: Blazor UI. There are some additional options for this template:
* `--separate-identity-server`The Identity Server project comes as a separate project and runs at a different endpoint. It separates the Identity Server from the API Host application. If not specified, you will have a single endpoint in the server side.
+ * `--pwa`: Specifies the project as Progressive Web Application.
* `blazor-server`: Blazor Server UI. There are some additional options for this template:
* `--tiered`: The Identity Server and the API Host project comes as separate projects and run at different endpoints. It has 3 startup projects: *HttpApi.Host*, *IdentityServer* and *Blazor* and and each runs on different endpoints. If not specified, you will have a single endpoint for your web project.
* `none`: Without UI. No front-end layer will be created. There are some additional options for this template:
@@ -115,7 +117,6 @@ For more samples, go to [ABP CLI Create Solution Samples](CLI-New-Command-Sample
* `--database-provider` or `-d`: Specifies the database provider. Default provider is `ef`. Available providers:
* `ef`: Entity Framework Core.
* `mongodb`: MongoDB.
- * `--pwa`: Specifies to Configure Angular or Blazor WebAssembly project as Progressive Web Application.
* `--output-folder` or `-o`: Specifies the output folder. Default value is the current directory.
* `--version` or `-v`: Specifies the ABP & template version. It can be a [release tag](https://github.com/abpframework/abp/releases) or a [branch name](https://github.com/abpframework/abp/branches). Uses the latest release if not specified. Most of the times, you will want to use the latest version.
* `--preview`: Use latest preview version.
diff --git a/docs/en/Caching.md b/docs/en/Caching.md
index 074d6d951f..8fafd725be 100644
--- a/docs/en/Caching.md
+++ b/docs/en/Caching.md
@@ -1,7 +1,9 @@
-# Caching
+# Distributed Caching
ABP Framework extends the [ASP.NET Core distributed cache](https://docs.microsoft.com/en-us/aspnet/core/performance/caching/distributed).
+> **Default implementation of the `IDistributedCache` interface is` MemoryDistributedCache` which works in-memory.** See [ASP.NET Core's documentation](https://docs.microsoft.com/en-us/aspnet/core/performance/caching/distributed) to see how to switch to Redis or another cache provider. Also, see the [Redis Cache](Redis-Cache.md) document if you want to use Redis as the distributed cache server.
+
## Installation
> This package is already installed by default with the [application startup template](Startup-Templates/Application.md). So, most of the time, you don't need to install it manually.
@@ -27,8 +29,6 @@ ASP.NET Core defines the `IDistributedCache` interface to get/set the cache valu
> `IDistributedCache` is defined in the `Microsoft.Extensions.Caching.Abstractions` package. That means it is not only usable for ASP.NET Core applications, but also available to **any type of applications**.
-> Default implementation of the `IDistributedCache` interface is the `MemoryDistributedCache` which works **in-memory**. See [ASP.NET Core's documentation](https://docs.microsoft.com/en-us/aspnet/core/performance/caching/distributed) to see how to switch to Redis or another cache provider. Also, see the [Redis Cache](Redis-Cache.md) document if you want to use the Redis as the distributed cache server.
-
See [ASP.NET Core's distributed caching document](https://docs.microsoft.com/en-us/aspnet/core/performance/caching/distributed) for more information.
### `IDistributedCache` Interface
diff --git a/docs/en/Contribution/How-to-Contribute-abp.io-as-a-frontend-developer.md b/docs/en/Contribution/How-to-Contribute-abp.io-as-a-frontend-developer.md
new file mode 100644
index 0000000000..2d9cd64065
--- /dev/null
+++ b/docs/en/Contribution/How-to-Contribute-abp.io-as-a-frontend-developer.md
@@ -0,0 +1,54 @@
+# How to contribute to abp.io as a frontend developer
+
+## How to setup development environment
+
+### Pre-requirements
+
+- Dotnet core SDK https://dotnet.microsoft.com/en-us/download
+- Nodejs LTS https://nodejs.org/en/
+- Docker https://docs.docker.com/engine/install
+- Angular CLI. https://angular.io/guide/what-is-angular#angular-cli
+- Abp CLI https://docs.abp.io/en/abp/latest/cli
+- A code editor
+
+Note: This arcticle prepare Windows OS. You may change the path type of your OS. an Example
+
+Windows: `templates\app\aspnet-core\src\MyCompanyName.MyProjectName.DbMigrator\appsettings.json`
+
+Unix: `templates/app/aspnet-core/src/MyCompanyName.MyProjectName.DbMigrator/appsettings.json`
+
+### Sample docker commands
+
+You need to install SQL Server and Redis. You can install these programs without docker, but my example uses docker containers. Your computer should have Docker Engine. Then open the terminal en execute the commands one by one.
+For the Sql Server
+
+docker run -v sqlvolume:/var/opt/mssql -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=yourpassword -p 1433:1433 -d mcr.microsoft.com/mssql/server:2019-CU3-ubuntu-18.04
+
+For the Redis
+
+docker run -p 6379:6379 -d redis
+
+Then we are ready to download and execute the code.
+
+## Folder Structure
+
+The app has a backend written in .net core (c#) and an angular app. It would help if you ran both of them.
+
+### Running Backend App
+
+The path of the Backend app is “templates\app\aspnet-core.” If you want to work with dockerized SQL Server, you should change connection strings for running with docker. The path of the connection string is
+`templates\app\aspnet-core\src\MyCompanyName.MyProjectName.DbMigrator\appsettings.json`.
+
+Before running the backend, you should run the Db migrator project. The DbMigrator created initial tables and values. The path of DbMigrator is `templates\app\aspnet-core\src\MyCompanyName.MyProjectName.DbMigrator`. Open a terminal in the path and execute the command `dotnet run` in terminal
+
+One last step before the running the backend is installing client-side libraries. Go to `templates\app\aspnet-core`. Open a terminal in the path and execute the command `abp install-libs` in terminal
+
+Next step you should go to path of backend host project. The path is `templates\app\aspnet-core\src\MyCompanyName.MyProjectName.HttpApi.HostWithIds`. Open a terminal in the path and execute the command `dotnet run` in terminal
+
+Your backend should be running successfully
+
+### Running Frontend App
+
+There is a demo app. The path of the demo app is `npm\ng-packs\apps\dev-app`. The demo app is connected to the packages with local references. Open the terminal in `npm\ng-packs\apps\dev-app` and execute `yarn` or `npm i` in terminal. After the package installed run `npm start` or `yarn start`.
+
+The repo uses Nx and packages connected with `local references`. The packages path is `”npm\ng-packs\packages`
diff --git a/docs/en/Contribution/Index.md b/docs/en/Contribution/Index.md
index d2525ae191..6160aa3273 100644
--- a/docs/en/Contribution/Index.md
+++ b/docs/en/Contribution/Index.md
@@ -70,3 +70,7 @@ If you want to make a change on a specific resource file, you can find the file
## Bug Report
If you find any bug, please [create an issue on the Github repository](https://github.com/abpframework/abp/issues/new).
+
+## Setup Frontend Development Environment
+
+[How to contribute to abp.io as a frontend developer](How-to-Contribute-abp.io-as-a-frontend-developer.md)
diff --git a/docs/en/Dependency-Injection.md b/docs/en/Dependency-Injection.md
index 019366b3be..668eac6644 100644
--- a/docs/en/Dependency-Injection.md
+++ b/docs/en/Dependency-Injection.md
@@ -131,7 +131,7 @@ public class TaxCalculator: ICalculator, ITaxCalculator, ICanCalculate, ITransie
If you do not specify which services to expose, ABP expose services by convention. So taking the ``TaxCalculator`` defined above:
* The class itself is exposed by default. That means you can inject it by ``TaxCalculator`` class.
-* Default interfaces are exposed by default. Default interfaces are determined by naming convention. In this example, ``ICalculator`` and ``ITaxCalculator`` are default interfaces of ``TaxCalculator``, but ``ICanCalculate`` is not.
+* Default interfaces are exposed by default. Default interfaces are determined by naming convention. In this example, ``ICalculator`` and ``ITaxCalculator`` are default interfaces of ``TaxCalculator``, but ``ICanCalculate`` is not. A generic interface (e.g. `ICalculator`) is also considered as a default interface if the naming convention is satisfied.
### Combining All Together
diff --git a/docs/en/Deployment/Clustered-Environment.md b/docs/en/Deployment/Clustered-Environment.md
new file mode 100644
index 0000000000..d76a199518
--- /dev/null
+++ b/docs/en/Deployment/Clustered-Environment.md
@@ -0,0 +1,99 @@
+# Deploying to a Clustered Environment
+
+This document introduces the topics that you should consider when you are deploying your application to a clustered environment where **multiple instances of your application run concurrently**, and explains how you can deal with these topics in your ABP based application.
+
+> This document is valid regardless you have a monolith application or a microservice solution. The Application term is used for a process. An application can be a monolith web application, a service in a microservice solution, a console application, or another kind of an executable process.
+>
+> For example, if you are deploying your application to Kubernetes and configure your application or service to run in multiple pods, then your application or service runs in a clustered environment.
+
+## Understanding the Clustered Environment
+
+> You can skip this section if you are already familiar with clustered deployment and load balancers.
+
+### Single Instance Deployment
+
+Consider an application deployed as a **single instance**, as illustrated in the following figure:
+
+
+
+Browsers and other client applications can directly make HTTP requests to your application. You can put a web server (e.g. IIS or NGINX) between the clients and your application, but you still have a single application instance running in a single server or container. Single-instance configuration is **limited to scale** since it runs in a single server and you are limited with the server's capacity.
+
+### Clustered Deployment
+
+**Clustered deployment** is the way of running **multiple instances** of your application **concurrently** in a single or multiple servers. In this way, different instances can serve different requests and you can scale by adding new servers to the system. The following figure shows a typical implementation of clustering using a **load balancer**:
+
+
+
+### Load Balancers
+
+[Load balancers](https://en.wikipedia.org/wiki/Load_balancing_(computing)) have a lot of features, but they fundamentally **forward an incoming HTTP request** to an instance of your application and return your response back to the client application.
+
+Load balancers can use different algorithms for selecting the application instance while determining the application instance that is used to deliver the incoming request. **Round Robin** is one of the simplest and most used algorithms. Requests are delivered to the application instances in rotation. First instance gets the first request, second instance gets the second, and so on. It returns to the first instance after all the instances are used, and the algorithm goes like that for the next requests.
+
+### Potential Problems
+
+Once multiple instances of your application run in parallel, you should carefully consider the following topics:
+
+* Any **state (data) stored in memory** of your application will become a problem when you have multiple instances. A state stored in memory of an application instance may not be available in the next request since the next request will be handled by a different application instance. While there are some solutions (like sticky sessions) to overcome this problem user-basis, it is a **best practice to design your application as stateless** if you want to run it in a cluster, container or/and cloud.
+* **In-memory caching** is a kind of in-memory state and should not be used in a clustered application. You should use **distributed caching** instead.
+* You shouldn't store data in the **local file system**. It should be available to all instances of your application. Different application instance may run in different containers or servers and they may not be able to have access to the same file system. You can use a **cloud or external storage provider** as a solution.
+* If you have **background workers** or **job queue managers**, you should be careful since multiple instances may try to execute the same job or perform the same work concurrently. As a result, you may have the same work done multiple times or you may get a lot of errors while trying to access and change the same resources.
+
+You may have more problems with clustered deployment, but these are the most common ones. ABP has been designed to be compatible with the clustered deployment scenario. The following sections explain what you should do when you are deploying your ABP based application to a clustered environment.
+
+## Switching to a Distributed Cache
+
+ASP.NET Core provides different kind of caching features. [In-memory cache](https://docs.microsoft.com/en-us/aspnet/core/performance/caching/memory) stores your objects in the memory of the local server and is only available to the application that stored the object. Non-sticky sessions in a clustered environment should use the [distributed caching](https://docs.microsoft.com/en-us/aspnet/core/performance/caching/distributed) except some specific scenarios (for example, you can cache a local CSS file into memory. It is read-only data and it is the same in all application instances. You can cache it in memory for performance reasons without any problem).
+
+[ABP's Distributed Cache](../Caching.md) extends [ASP.NET Core's distributed cache](https://docs.microsoft.com/en-us/aspnet/core/performance/caching/distributed) infrastructure. It works in-memory by default. You should configure an actual distributed cache provider when you want to deploy your application to a clustered environment.
+
+> You should configure the cache provider for clustered deployment, even if your application doesn't directly use `IDistributedCache`. Because the ABP Framework and the pre-built [application modules](../Modules/Index.md) are using distributed cache.
+
+ASP.NET Core provides multiple integrations to use as your distributed cache provider, like [Redis](https://redis.io/) and [NCache](https://www.alachisoft.com/ncache/). You can follow [Microsoft's documentation](https://docs.microsoft.com/en-us/aspnet/core/performance/caching/distributed) to learn how to use them in your applications.
+
+If you decided to use Redis as your distributed cache provider, **follow [ABP's Redis Cache Integration document](../Redis-Cache.md)** for the steps you need to follow to install it into your application and setup your Redis configuration.
+
+> Based on your preferences while creating a new ABP solution, Redis cache might be pre-installed in your solution. For example, if you have selected the *Tiered* option with the MVC UI, Redis cache comes as pre-installed. Because, in this case, you have two applications in your solution and they should use the same cache source to be consistent.
+
+## Using a Proper BLOB Storage Provider
+
+If you have used ABP's [BLOB Storing](../Blob-Storing.md) feature with the [File System provider](../Blob-Storing-File-System.md), you should use another provider in your clustered environment since the File System provider uses the application's local file system.
+
+The [Database BLOB provider](../Blob-Storing-Database) is the easiest way since it uses your application's main database (or another database if you configure) to store BLOBs. However, you should remember that BLOBs are large objects and may quickly increase your database's size.
+
+> [ABP Commercial](https://commercial.abp.io/) startup solution templates come with the database BLOB provider as pre-installed, and stores BLOBs in the application's database.
+
+Check the [BLOB Storing](../Blob-Storing.md) document to see all the available BLOG storage providers.
+
+## Configuring Background Jobs
+
+ABP's [background job system](../Background-Jobs.md) is used to queue tasks to be executed in the background. Background job queue is persistent and a queued task is guaranteed to be executed (it is re-tried if it fails).
+
+ABP's default background job manager is compatible with clustered environments. It uses a [distributed lock](../Distributed-Locking.md) to ensure that the jobs are executed only in a single application instance at a time. See the *Configuring a Distributed Lock Provider* section below to learn how to configure a distributed lock provider for your application, so the default background job manager properly works in a clustered environment.
+
+If you don't want to use a distributed lock provider, you may go with the following options:
+
+* Stop the background job manager (set `AbpBackgroundJobOptions.IsJobExecutionEnabled` to `false`) in all application instances except one of them, so only the single instance executes the jobs (while other application instances can still queue jobs).
+* Stop the background job manager (set `AbpBackgroundJobOptions.IsJobExecutionEnabled` to `false`) in all application instances and create a dedicated application (maybe a console application running in its own container or a Windows Service running in the background) to execute all the background jobs. This can be a good option if your background jobs consume high system resources (CPU, RAM or Disk), so you can deploy that background application to a dedicated server and your background jobs don't affect your application's performance.
+
+> If you are using an external background job integration (e.g. [Hangfire](../Background-Workers-Hangfire.md) or [Quartz](../Background-Workers-Quartz.md)) instead of the default background job manager, then please refer to your provider's documentation to learn how it should be configured for a clustered environment.
+
+## Configuring a Distributed Lock Provider
+
+ABP provides a distributed locking abstraction with an implementation made with the [DistributedLock](https://github.com/madelson/DistributedLock) library. A distributed lock is used to control concurrent access to a shared resource by multiple applications to prevent corruption of the resource because of concurrent writes. The ABP Framework and some pre-built [application modules](../Modules/Index.md) are using distributed locking for several reasons.
+
+However, the distributed lock system works in-process by default. That means it is not distributed actually, unless you configure a distributed lock provider. So, please follow the [distributed lock](../Distributed-Locking.md) document to configure a provider for your application, if it is not already configured.
+
+## Implementing Background Workers
+
+ASP.NET Core provides [hosted services](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services) and ABP provides [background workers](../Background-Workers.md) to perform tasks in background threads in your application.
+
+If your application has tasks running in the background, you should consider how they will behave in a clustered environment, especially if your background tasks are using the same resources. You should design your background tasks so that they continue to work properly in the clustered environment.
+
+Assume that your background worker in your SaaS application checks user subscriptions and sends emails if their subscription renewal date approaches. If the background task runs in multiple application instances, it is probable to send the same email many times to some users, which will disturb them.
+
+We suggest you to use one of the following approaches to overcome the problem:
+
+* Implement your background workers so that they work in a clustered environment without any problem. Using the [distributed lock](../Distributed-Locking.md) to ensure concurrency control is a way of doing that. A background worker in an application instance may handle a distributed lock, so the workers in other application instances will wait for the lock. In this way, only one worker does the actual work, while others wait in idle. If you implement this, your workers run safely without caring about how the application is deployed.
+* Stop the background workers (set `AbpBackgroundWorkerOptions.IsEnabled` to `false`) in all application instances except one of them, so only the single instance runs the workers.
+* Stop the background workers (set `AbpBackgroundWorkerOptions.IsEnabled` to `false`) in all application instances and create a dedicated application (maybe a console application running in its own container or a Windows Service running in the background) to execute all the background tasks. This can be a good option if your background workers consume high system resources (CPU, RAM or Disk), so you can deploy that background application to a dedicated server and your background tasks don't affect your application's performance.
\ No newline at end of file
diff --git a/docs/en/Deployment/Index.md b/docs/en/Deployment/Index.md
new file mode 100644
index 0000000000..dc1cca300e
--- /dev/null
+++ b/docs/en/Deployment/Index.md
@@ -0,0 +1,9 @@
+# Deployment
+
+Deploying an ABP application is not different than deploying any .NET or ASP.NET Core application. You can deploy it to a cloud provider (e.g. Azure, AWS, Google Could) or on-premise server, IIS or any other web server. ABP's documentation doesn't contain much information on deployment. You can refer to your provider's documentation.
+
+However, there are some topics that you should care about when you are deploying your applications. Most of them are general software deployment considerations, but you should understand how to handle them within your ABP based applications. We've prepared guides for this purpose and we suggest you to read these guides carefully before designing your deployment configuration.
+
+## Guides
+
+* [Deploying to a clustered environment](Clustered-Environment.md): Explains how to configure your application when you want to run multiple instances of your application concurrently.
\ No newline at end of file
diff --git a/docs/en/Distributed-Event-Bus.md b/docs/en/Distributed-Event-Bus.md
index 387fece078..17dd69072a 100644
--- a/docs/en/Distributed-Event-Bus.md
+++ b/docs/en/Distributed-Event-Bus.md
@@ -20,7 +20,7 @@ For example, [pre-built application modules](Modules/Index.md) is designed to wo
There are two ways of publishing distributed events explained in the following sections.
-### IDistributedEventBus
+### Using IDistributedEventBus to Publish Events
`IDistributedEventBus` can be [injected](Dependency-Injection.md) and used to publish a distributed event.
@@ -57,7 +57,7 @@ namespace AbpDemo
}
````
-`PublishAsync` method gets a single parameter: the event object, which is responsible to hold the data related to the event. It is a simple plain class:
+`PublishAsync` method gets the event object, which is responsible to hold the data related to the event. It is a simple plain class:
````csharp
using System;
@@ -80,15 +80,15 @@ Even if you don't need to transfer any data, you need to create a class (which i
#### Event Name
-`EventName` attribute is optional, but suggested. If you don't declare it, the event name will be the full name of the event class, `AbpDemo.StockCountChangedEto` in this case.
+`EventName` attribute is optional, but suggested. If you don't declare it for an event type (ETO class), the event name will be the full name of the event class, `AbpDemo.StockCountChangedEto` in this case.
#### About Serialization for the Event Objects
-Event transfer objects **must be serializable** since they will be serialized/deserialized to JSON or other format when it is transferred to out of the process.
+Event transfer objects (ETOs) **must be serializable** since they will be serialized/deserialized to JSON or other format when it is transferred to out of the process.
Avoid circular references, polymorphism, private setters and provide default (empty) constructors if you have any other constructor as a good practice (while some serializers may tolerate it), just like the DTOs.
-### Inside Entity / Aggregate Root Classes
+### Publishing Events Inside Entity / Aggregate Root Classes
[Entities](Entities.md) can not inject services via dependency injection, but it is very common to publish distributed events inside entity / aggregate root classes.
@@ -294,4 +294,211 @@ This example;
* Adds a selector to allow to publish the create, update and delete events for the `Product` entity.
* Configure to use the `ProductEto` as the event transfer object to publish for the `Product` related events.
-> Distributed event system use the [object to object mapping](Object-To-Object-Mapping.md) system to map `Product` objects to `ProductEto` objects. So, you need to configure the object mapping (`Product` -> `ProductEto`) too. You can check the [object to object mapping document](Object-To-Object-Mapping.md) to learn how to do it.
\ No newline at end of file
+> Distributed event system use the [object to object mapping](Object-To-Object-Mapping.md) system to map `Product` objects to `ProductEto` objects. So, you need to configure the object mapping (`Product` -> `ProductEto`) too. You can check the [object to object mapping document](Object-To-Object-Mapping.md) to learn how to do it.
+
+## Transaction and Exception Handling
+
+Distributed event bus works in-process (since default implementation is `LocalDistributedEventBus`) unless you configure an actual provider (e.g. [Kafka](Distributed-Event-Bus-Kafka-Integration.md) or [Redis](Distributed-Event-Bus-RabbitMQ-Integration.md)). In-process event bus always executes event handlers in the same [unit of work](Unit-Of-Work.md) scope that you publishes the events in. That means, if an event handler throws an exception, then the related unit of work (the database transaction) is rolled back. In this way, your application logic and event handling logic becomes transactional (atomic) and consistent. If you want to ignore errors in an event handler, you must use a `try-catch` block in your handler and shouldn't re-throw the exception.
+
+When you switch to an actual distributed event bus provider (e.g. [Kafka](Distributed-Event-Bus-Kafka-Integration.md) or [Redis](Distributed-Event-Bus-RabbitMQ-Integration.md)), then the event handlers will be executed in different processes/applications as their purpose is to create distributed systems. In this case, the only way to implement transactional event publishing is to use the outbox/inbox patterns as explained in the *Outbox / Inbox for Transactional Events* section.
+
+If you don't configure outbox/inbox pattern or use the `LocalDistributedEventBus`, then events are published at the end of the unit of work by default, just before the unit of work is completed (that means throwing exception in an event handler still rollbacks the unit of work), even if you publish them in the middle of unit of work. If you want to immediately publish the event, you can set `onUnitOfWorkComplete` to `false` while using `IDistributedEventBus.PublishAsync` method.
+
+> Keeping the default behavior is recommended unless you don't have a unique requirement. `onUnitOfWorkComplete` option is not available when you publish events inside entity / aggregate root classes (see the *Publishing Events Inside Entity / Aggregate Root Classes* section).
+
+## Outbox / Inbox for Transactional Events
+
+The **[transactional outbox pattern](https://microservices.io/patterns/data/transactional-outbox.html)** is used to publishing distributed events within the **same transaction** that manipulates the application's database. When you enable outbox, distributed events are saved into the database inside the same transaction with your data changes, then sent to the actual message broker by a separate [background worker](Background-Workers.md) with a re-try system. In this way, it ensures the consistency between your database state and the published events.
+
+The **transactional inbox pattern**, on the other hand, saves incoming events into database first. Then (in a [background worker](Background-Workers.md)) executes the event handler in a transactional manner and removes the event from the inbox queue in the same transaction. It ensures that the event is only executed one time by keeping the processed messages for a while and discarding the duplicate events received from the message broker.
+
+Enabling the event outbox and inbox systems require a few manual steps for your application. Please apply the instructions in the following sections to make them running.
+
+> Outbox and Inbox can be separately enabled and configured, so you may only use one of them if you want.
+
+### Pre-requirements
+
+* The outbox/inbox system uses the distributed lock system to handle concurrency when you run multiple instances of your application/service. So, you should **configure the distributed lock system** with one of the providers as [explained in this document](Distributed-Locking.md).
+* The outbox/inbox system supports [Entity Framework Core](Entity-Framework-Core.md) (EF Core) and [MongoDB](MongoDB.md) **database providers** out of the box. So, your applications should use one of these database providers. For other database providers, see the *Implementing a Custom Database Provider* section.
+
+> If you are using MongoDB, be sure that you enabled multi-document database transactions that was introduced in MongoDB version 4.0. See the *Transactions* section of the [MongoDB](MongoDB.md) document.
+
+### Enabling event outbox
+
+Open your `DbContext` class (EF Core or MongoDB), implement the `IHasEventOutbox` interface. You should end up by adding a `DbSet` property into your `DbContext` class:
+
+```csharp
+public DbSet OutgoingEvents { get; set; }
+```
+
+Add the following lines inside the `OnModelCreating` method of your `DbContext` class (only for EF Core):
+
+```csharp
+builder.ConfigureEventOutbox();
+```
+
+For EF Core, use the standard `Add-Migration` and `Update-Database` commands to apply changes into your database (you can skip this step for MongoDB). If you want to use the command-line terminal, run the following commands in the root directory of the database integration project:
+
+```bash
+dotnet ef migrations add "Added_Event_Outbox"
+dotnet ef database update
+```
+
+Finally, write the following configuration code inside the `ConfigureServices` method of your [module class](Module-Development-Basics.md) (replace `YourDbContext` with your own `DbContext` class):
+
+````csharp
+Configure(options =>
+{
+ options.Outboxes.Configure(config =>
+ {
+ config.UseDbContext();
+ });
+});
+````
+
+### Enabling event inbox
+
+Open your `DbContext` class (EF Core or MongoDB), implement the `IHasEventInbox` interface. You should end up by adding a `DbSet` property into your `DbContext` class:
+
+```csharp
+public DbSet IncomingEvents { get; set; }
+```
+
+Add the following lines inside the `OnModelCreating` method of your `DbContext` class (only for EF Core):
+
+```csharp
+builder.ConfigureEventInbox();
+```
+
+For EF Core, use the standard `Add-Migration` and `Update-Database` commands to apply changes into your database (you can skip this step for MongoDB). If you want to use the command-line terminal, run the following commands in the root directory of the database integration project:
+
+```bash
+dotnet ef migrations add "Added_Event_Inbox"
+dotnet ef database update
+```
+
+Finally, write the following configuration code inside the `ConfigureServices` method of your [module class](Module-Development-Basics.md) (replace `YourDbContext` with your own `DbContext` class):
+
+````csharp
+Configure(options =>
+{
+ options.Inboxes.Configure(config =>
+ {
+ config.UseDbContext();
+ });
+});
+````
+
+### Additional Configuration
+
+> The default configuration will be enough for most cases. However, there are some options you may want to set for outbox and inbox.
+
+#### Outbox configuration
+
+Remember how outboxes are configured:
+
+````csharp
+Configure(options =>
+{
+ options.Outboxes.Configure(config =>
+ {
+ // TODO: Set options
+ });
+});
+````
+
+Here, the following properties are available on the `config` object:
+
+* `IsSendingEnabled` (default: `true`): You can set to `false` to disable sending outbox events to the actual event bus. If you disable this, events can still be added to outbox, but not sent. This can be helpful if you have multiple applications (or application instances) writing to outbox, but use one of them to send the events.
+* `Selector`: A predicate to filter the event (ETO) types to be used for this configuration. Should return `true` to select the event. It selects all the events by default. This is especially useful if you want to ignore some ETO types from the outbox, or want to define named outbox configurations and group events within these configurations. See the *Named Configurations* section.
+* `ImplementationType`: Type of the class that implements the database operations for the outbox. This is normally set when you call `UseDbContext` as shown before. See *Implementing a Custom Outbox/Inbox Database Provider* section for advanced usages.
+
+#### Inbox configuration
+
+Remember how inboxes are configured:
+
+````csharp
+Configure(options =>
+{
+ options.Inboxes.Configure(config =>
+ {
+ // TODO: Set options
+ });
+});
+````
+
+Here, the following properties are available on the `config` object:
+
+* `IsProcessingEnabled` (default: `true`): You can set to `false` to disable processing (handling) events in the inbox. If you disable this, events can still be received, but not executed. This can be helpful if you have multiple applications (or application instances), but use one of them to execute the event handlers.
+* `EventSelector`: A predicate to filter the event (ETO) types to be used for this configuration. This is especially useful if you want to ignore some ETO types from the inbox, or want to define named inbox configurations and group events within these configurations. See the *Named Configurations* section.
+* `HandlerSelector`: A predicate to filter the event handled types (classes implementing the `IDistributedEventHandler` interface) to be used for this configuration. This is especially useful if you want to ignore some event handler types from inbox processing, or want to define named inbox configurations and group event handlers within these configurations. See the *Named Configurations* section.
+* `ImplementationType`: Type of the class that implements the database operations for the inbox. This is normally set when you call `UseDbContext` as shown before. See *Implementing a Custom Outbox/Inbox Database Provider* section for advanced usages.
+
+### Skipping Outbox
+
+`IDistributedEventBus.PublishAsync` method provides an optional parameter, `useOutbox`, which is set to `true` by default. If you bypass outbox and immediately publish an event, you can set it to `false` for a specific event publishing operation.
+
+### Advanced Topics
+
+#### Named Configurations
+
+> All the concepts explained in this section is also valid for inbox configurations. We will show examples only for outbox to keep the document shorter.
+
+See the following outbox configuration code:
+
+````csharp
+Configure(options =>
+{
+ options.Outboxes.Configure(config =>
+ {
+ //TODO
+ });
+});
+````
+
+This is equivalent of the following code:
+
+````csharp
+Configure(options =>
+{
+ options.Outboxes.Configure("Default", config =>
+ {
+ //TODO
+ });
+});
+````
+
+`Default` is this code indicates the configuration name. If you don't specify it (like in the previous code block), `Default` is used as the configuration name.
+
+That means you can define more than one configuration for outbox (also for inbox) with different names. ABP runs all the configured outboxes.
+
+Multiple outboxes can be needed if your application have more than one database and you want to run different outbox queues for different databases. In this case, you can use the `Selector` option to decide the events should be handled by an outbox. See the *Additional Configurations* section above.
+
+#### Implementing a Custom Outbox/Inbox Database Provider
+
+If your application or service is using a database provider other than [EF Core](Entity-Framework-Core.md) and [MongoDB](MongoDB.md), you should manually integrate outbox/inbox system with your database provider.
+
+> Outbox and Inbox table/data must be stored in the same database with your application's data (since we want to create a single database transaction that includes application's database operations and outbox/inbox table operations). Otherwise, you should care about distributed (multi-database) transaction support which is not provided by most of the vendors and may require additional configuration.
+
+ABP provides `IEventOutbox` and `IEventInbox` abstractions as extension point for the outbox/inbox system. You can create classes by implementing these interfaces and register them to [dependency injection](Dependency-Injection.md).
+
+Once you implement your custom event boxes, you can configure `AbpDistributedEventBusOptions` to use your event box classes:
+
+````csharp
+Configure(options =>
+{
+ options.Outboxes.Configure(config =>
+ {
+ config.ImplementationType = typeof(MyOutbox); //Your Outbox class
+ });
+
+ options.Inboxes.Configure(config =>
+ {
+ config.ImplementationType = typeof(MyInbox); //Your Inbox class
+ });
+});
+````
+
+## See Also
+
+* [Local Event Bus](Local-Event-Bus.md)
\ No newline at end of file
diff --git a/docs/en/Distributed-Locking.md b/docs/en/Distributed-Locking.md
index d57fd45c83..d29b60ad04 100644
--- a/docs/en/Distributed-Locking.md
+++ b/docs/en/Distributed-Locking.md
@@ -1,7 +1,5 @@
# Distributed Locking
-Distributed locking is a technique to manage many applications that try to access the same resource.
-The main purpose is to allow only one of many applications to access the same resource at the same time.
-Otherwise, accessing the same object from various applications may corrupt the value of resources.
+Distributed locking is a technique to manage many applications that try to access the same resource. The main purpose is to allow only one of many applications to access the same resource at the same time. Otherwise, accessing the same object from various applications may corrupt the value of the resources.
> ABP's current distributed locking implementation is based on the [DistributedLock](https://github.com/madelson/DistributedLock) library.
@@ -15,7 +13,7 @@ abp add-package Volo.Abp.DistributedLocking
This package provides the necessary API to use the distributed locking system, however, you should configure a provider before using it.
-### Configuring a provider
+### Configuring a Provider
The [DistributedLock](https://github.com/madelson/DistributedLock) library provides [various of implementations](https://github.com/madelson/DistributedLock#implementations) for the locking, like [Redis](https://github.com/madelson/DistributedLock/blob/master/docs/DistributedLock.Redis.md) and [ZooKeeper](https://github.com/madelson/DistributedLock/blob/master/docs/DistributedLock.ZooKeeper.md).
@@ -61,7 +59,7 @@ This code gets the Redis connection string from the [configuration](Configuratio
There are two ways to use the distributed locking API: ABP's `IAbpDistributedLock` abstraction and [DistributedLock](https://github.com/madelson/DistributedLock) library's API.
-### Using the IAbpDistributedLock service
+### Using the IAbpDistributedLock Service
`IAbpDistributedLock` is a simple service provided by the ABP framework for simple usage of distributed locking.
@@ -103,6 +101,10 @@ namespace AbpDemo
* `timeout` (`TimeSpan`): A timeout value to wait to obtain the lock. Default value is `TimeSpan.Zero`, which means it doesn't wait if the lock is already owned by another application.
* `cancellationToken`: A cancellation token that can be triggered later to cancel the operation.
-### Using DistributedLock library's API
+### Using DistributedLock Library's API
ABP's `IAbpDistributedLock` service is very limited and mainly designed to be internally used by the ABP Framework. For your own applications, you can use the DistributedLock library's own API. See its [own documentation](https://github.com/madelson/DistributedLock) for details.
+
+## The Volo.Abp.DistributedLocking.Abstractions Package
+
+If you are building a reusable library or an application module, then you may not want to bring an additional dependency to your module for simple applications that run as a single instance. In this case, your library can depend on the [Volo.Abp.DistributedLocking.Abstractions](https://nuget.org/packages/Volo.Abp.DistributedLocking.Abstractions) package which defines the `IAbpDistributedLock` service and implements it as in-process (not distributed actually). In this way, your library can run properly (without a distributed lock provider dependency) in an application that runs as a single instance. If the application is deployed to a [clustered environment](Deployment/Clustered-Environment.md), then the application developer should install a real distributed provider as explained in the *Installation* section.
diff --git a/docs/en/Getting-Started-Running-Solution.md b/docs/en/Getting-Started-Running-Solution.md
index 281add1e2a..fe1d0de246 100644
--- a/docs/en/Getting-Started-Running-Solution.md
+++ b/docs/en/Getting-Started-Running-Solution.md
@@ -91,10 +91,10 @@ Right click to the `.DbMigrator` project and select **Set as StartUp Project**
## Run the Application
-> Please execute the `abp install-libs` command to restore the libs required by the web project before running the application.
-
{{ if UI == "MVC" || UI == "BlazorServer" }}
+> Before starting the application, run `abp install-libs` command in your Web directory to restore the client-side libraries. This will populate the `libs` folder.
+
{{ if Tiered == "Yes" }}
> Tiered solutions use **Redis** as the distributed cache. Ensure that it is installed and running in your local computer. If you are using a remote Redis Server, set the configuration in the `appsettings.json` files of the projects below.
diff --git a/docs/en/Local-Event-Bus.md b/docs/en/Local-Event-Bus.md
index 90e11c3baf..57c12d4c3b 100644
--- a/docs/en/Local-Event-Bus.md
+++ b/docs/en/Local-Event-Bus.md
@@ -6,7 +6,7 @@ The Local Event Bus allows services to publish and subscribe to **in-process eve
There are two ways of publishing local events explained in the following sections.
-### ILocalEventBus
+### Publishing Events Using the ILocalEventBus
`ILocalEventBus` can be [injected](Dependency-Injection.md) and used to publish a local event.
@@ -64,7 +64,7 @@ namespace AbpDemo
Even if you don't need to transfer any data, you need to create a class (which is an empty class in this case).
-### Inside Entity / Aggregate Root Classes
+### Publishing Events Inside Entity / Aggregate Root Classes
[Entities](Entities.md) can not inject services via dependency injection, but it is very common to publish local events inside entity / aggregate root classes.
@@ -109,7 +109,7 @@ namespace AbpDemo
`AggregateRoot` class defines the `AddLocalEvent` to add a new local event, that is published when the aggregate root object is saved (created, updated or deleted) into the database.
-> If an entity publishes such an event, it is a good practice to change the related properties in a controlled manner, just like the example above - `StockCount` can only be changed by the `ChangeStockCount` method which guarantees publishing the event.
+> Tip: If an entity publishes such an event, it is a good practice to change the related properties in a controlled manner, just like the example above - `StockCount` can only be changed by the `ChangeStockCount` method which guarantees publishing the event.
#### IGeneratesDomainEvents Interface
@@ -149,10 +149,10 @@ namespace AbpDemo
}
````
-That's all. `MyHandler` is **automatically discovered** by the ABP Framework and `HandleEventAsync` is called whenever a `StockCountChangedEvent` occurs. You can inject any service and perform any required logic here.
+That's all. `MyHandler` is **automatically discovered** by the ABP Framework and `HandleEventAsync` is called whenever a `StockCountChangedEvent` occurs. You can inject any service and perform any required logic in your handler class.
-* **Zero or more handlers** can subscribe to the same event.
-* A single event handler class can **subscribe to multiple events** but implementing the `ILocalEventHandler` interface for each event type.
+* **One or more handlers** can subscribe to the same event.
+* A single event handler class can **subscribe to multiple events** by implementing the `ILocalEventHandler` interface for each event type.
If you perform **database operations** and use the [repositories](Repositories.md) inside the event handler, you may need to create a [unit of work](Unit-Of-Work.md), because some repository methods need to work inside an **active unit of work**. Make the handle method `virtual` and add a `[UnitOfWork]` attribute for the method, or manually use the `IUnitOfWorkManager` to create a unit of work scope.
@@ -160,10 +160,11 @@ If you perform **database operations** and use the [repositories](Repositories.m
### Transaction & Exception Behavior
-When an event published, subscribed event handlers are immediately executed. So;
+Event handlers are always executed in the same [unit of work](Unit-Of-Work.md) scope, that means in the same database transaction with the code that published the event. If an event handler throws an exception, the unit of work (database transaction) is rolled back. So, **use try-catch yourself** in the event handler if you want to hide the error.
-* If a handler **throws an exception**, it effects the code that published the event. That means it gets the exception on the `PublishAsync` call. So, **use try-catch yourself** in the event handler if you want to hide the error.
-* If the event publishing code is being executed inside a [Unit Of Work](Unit-Of-Work.md) scope, the event handlers also covered by the unit of work. That means if your UOW is transactional and a handler throws an exception, the transaction is rolled back.
+When you call `ILocalEventBus.PublishAsync`, the event handlers are not immediately executed. Instead, they are executed just before the current unit of work completed (an unhandled exception in the handler still rollbacks the current unit of work). If you want to immediately execute the handlers, set the optional `onUnitOfWorkComplete` parameter to `false`.
+
+> Keeping the default behavior is recommended unless you don't have a unique requirement. `onUnitOfWorkComplete` option is not available when you publish events inside entity / aggregate root classes (see the *Publishing Events Inside Entity / Aggregate Root Classes* section).
## Pre-Built Events
@@ -195,35 +196,22 @@ namespace AbpDemo
}
````
-This class subscribes to the `EntityCreatedEventData`, which is published just after a user was created. You may want to send a "Welcome" email to the new user.
-
-There are two types of these events: events with past tense and events with continuous tense.
-
-### Events with Past Tense
+This class subscribes to the `EntityCreatedEventData`, which is published just after a user was created (but before the current transaction is completed). For example, you may want to send a "Welcome" email to the new user.
-Events with past tense are published when the related unit of work completed and the entity change successfully saved to the database. If you throw an exception on these event handlers, it **can not rollback** the transaction since it was already committed.
-
-The event types are;
+The pre-built event types are;
* `EntityCreatedEventData` is published just after an entity was successfully created.
* `EntityUpdatedEventData` is published just after an entity was successfully updated.
* `EntityDeletedEventData` is published just after an entity was successfully deleted.
* `EntityChangedEventData` is published just after an entity was successfully created, updated or deleted. It can be a shortcut if you need to listen any type of change - instead of subscribing to the individual events.
-### Events with Continuous Tense
-
-Events with continuous tense are published before completing the transaction (if database transaction is supported by the database provider being used). If you throw an exception on these event handlers, it **can rollback** the transaction since it is not completed yet and the change is not saved to the database.
-
-The event types are;
-
-* `EntityCreatingEventData` is published just before saving a new entity to the database.
-* `EntityUpdatingEventData` is published just before an existing entity is being updated.
-* `EntityDeletingEventData` is published just before an entity is being deleted.
-* `EntityChangingEventData` is published just before an entity is being created, updated or deleted. It can be a shortcut if you need to listen any type of change - instead of subscribing to the individual events.
-
#### How It Was Implemented?
Pre-build events are published when you save changes to the database;
* For EF Core, they are published on `DbContext.SaveChanges`.
* For MongoDB, they are published when you call repository's `InsertAsync`, `UpdateAsync` or `DeleteAsync` methods (since MongoDB has not a change tracking system).
+
+## See Also
+
+* [Distributed Event Bus](Distributed-Event-Bus.md)
diff --git a/docs/en/Migration-Guides/Abp-5-0-Blazor.md b/docs/en/Migration-Guides/Abp-5-0-Blazor.md
index 326bac55d5..09d0f8e682 100644
--- a/docs/en/Migration-Guides/Abp-5-0-Blazor.md
+++ b/docs/en/Migration-Guides/Abp-5-0-Blazor.md
@@ -1,6 +1,6 @@
# ABP Blazor UI v4.x to v5.0 Migration Guide
-> This document is for the ABP MVC / Razor Pages UI. See also [the main migration guide](Abp-5_0.md).
+> This document is for the Blazor UI. See also [the main migration guide](Abp-5_0.md).
## Upgrading to the latest Blazorise
@@ -16,4 +16,4 @@ Replace `AddBootstrapProviders()` with `AddBootstrap5Providers()`.
## Update Bundle
-Use `abp bundle` command to update bundles if you are using Blazor WebAssembly.
\ No newline at end of file
+Use `abp bundle` command to update bundles if you are using Blazor WebAssembly.
diff --git a/docs/en/Migration-Guides/Abp-5_0-Angular.md b/docs/en/Migration-Guides/Abp-5_0-Angular.md
index 8099c8acd4..b7e55dad38 100644
--- a/docs/en/Migration-Guides/Abp-5_0-Angular.md
+++ b/docs/en/Migration-Guides/Abp-5_0-Angular.md
@@ -1,6 +1,6 @@
# Angular UI v4.x to v5.0 Migration Guide
-This document is for the ABP MVC / Razor Pages UI. See also [the main migration guide](Abp-5_0.md).
+> This document is for the Angular UI. See also [the main migration guide](Abp-5_0.md).
## Overall
diff --git a/docs/en/Migration-Guides/Abp-5_3.md b/docs/en/Migration-Guides/Abp-5_3.md
new file mode 100644
index 0000000000..acc69504f0
--- /dev/null
+++ b/docs/en/Migration-Guides/Abp-5_3.md
@@ -0,0 +1,11 @@
+# ABP Version 5.3 Migration Guide
+
+This document is a guide for upgrading ABP v5.2 solutions to ABP v5.3. There is a change in this version that may effect your applications, please read it carefully and apply the necessary changes to your application.
+
+## AutoMapper Upgraded to v11.0.1
+
+AutoMapper library upgraded to **v11.0.1** in this version. So, you need to change your project's target SDK that use the **AutoMapper** library (typically your `*.Application` project). You can change it from `netstandard2.0` to `netstandard2.1` or `net6` if needed. Please see [#12189](https://github.com/abpframework/abp/pull/12189) for more info.
+
+## See Also
+
+* [Official blog post for the 5.3 release](https://blog.abp.io/abp/ABP.IO-Platform-5.3-RC-Has-Been-Published)
diff --git a/docs/en/Migration-Guides/Index.md b/docs/en/Migration-Guides/Index.md
index 17e4d70dd8..c24ac09eee 100644
--- a/docs/en/Migration-Guides/Index.md
+++ b/docs/en/Migration-Guides/Index.md
@@ -2,6 +2,7 @@
The following documents explain how to migrate your existing ABP applications. We write migration documents only if you need to take an action while upgrading your solution. Otherwise, you can easily upgrade your solution using the [abp update command](../Upgrading.md).
+- [5.2 to 5.3](Abp-5_3.md)
- [5.1 to 5.2](Abp-5_2.md)
- [4.x to 5.0](Abp-5_0.md)
- [4.2 to 4.3](Abp-4_3.md)
diff --git a/docs/en/Modules/OpenIddict.md b/docs/en/Modules/OpenIddict.md
new file mode 100644
index 0000000000..6df46dfcd2
--- /dev/null
+++ b/docs/en/Modules/OpenIddict.md
@@ -0,0 +1,240 @@
+## ABP OpenIddict Modules
+
+## How to Install
+
+TODO:
+
+## User Interface
+
+This module implements the domain logic and database integrations, but not provides any UI. Management UI is useful if you need to add applications and scopes on the fly. In this case, you may build the management UI yourself or consider to purchase the [ABP Commercial](https://commercial.abp.io/) which provides the management UI for this module.
+
+## Relations to Other Modules
+
+This module is based on the [Identity Module](Identity.md) and have an [integration package](https://www.nuget.org/packages/Volo.Abp.Account.Web.IdentityServer) with the [Account Module](Account.md).
+
+## The module
+
+### Demo projects
+
+In the module's `app` directory there are six projects(including `angular`)
+
+* `OpenIddict.Demo.Server`: An abp application with integrated modules (has two `clients` and a `scope`).
+* `OpenIddict.Demo.API`: ASP NET Core API application using JwtBearer authentication
+* `OpenIddict.Demo.Client.Mvc`: ASP NET Core MVC application using `OpenIdConnect` for authentication
+* `OpenIddict.Demo.Client.Console`: Use `IdentityModel` to test OpenIddict's various endpoints, and call the api of `OpenIddict.Demo.API`
+* `OpenIddict.Demo.Client.BlazorWASM:` ASP NET Core Blazor application using `OidcAuthentication` for authentication
+* `angular`: An angular application that integrates the abp ng modules and uses oauth for authentication
+
+#### How to run?
+
+Confirm the connection string of `appsettings.json` in the `OpenIddict.Demo.Server` project. Running the project will automatically create the database and initialize the data.
+After running the `OpenIddict.Demo.API` project, then you can run the rest of the projects to test.
+
+### Domain module
+
+There are four main entities included in this module.
+
+* OpenIddictApplication: **Represents applications(client)**
+* OpenIddictScope: **Represents scopes**
+* OpenIddictAuthorization: **Represents authorizations, Track of logical chains of tokens and user consent..**
+* OpenIddictToken: **Represents various tokens.**
+
+Domain also implements four store interfaces in OpenIddict, OpenIddict uses store to manage entities, corresponding to the above four entities, Custom entity repository is used in the store.
+
+
+```cs
+//Manager
+OpenIddictApplicationManager
+OpenIddictScopeManager
+OpenIddictAuthorizationManager
+OpenIddictTokenManager
+
+//Store
+IOpenIddictApplicationStore
+IOpenIddictScopeStore
+IOpenIddictAuthorizationStore
+IOpenIddictTokenStore
+
+//Repository
+IOpenIddictApplicationRepository
+IOpenIddictScopeRepository
+IOpenIddictAuthorizationRepository
+IOpenIddictTokenRepository
+```
+
+We enabled most of OpenIddict's features in the `AddOpenIddict` method, You can change OpenIddict's related builder options via `PreConfigure`.
+
+```cs
+PreConfigure(builder =>
+{
+ //builder
+});
+
+PreConfigure(builder =>
+{
+ //builder
+});
+
+PreConfigure(builder =>
+{
+ //builder
+});
+```
+
+#### AbpOpenIddictOptions
+
+`UpdateAbpClaimTypes(default: true)`: Updates AbpClaimTypes to be compatible with identity server claims.
+`AddDevelopmentEncryptionAndSigningCertificate(default: true)`: Registers (and generates if necessary) a user-specific development encryption/development signing certificate.
+
+You can also change this options via `PreConfigure`.
+
+#### Automatically removing orphaned tokens/authorizations
+
+There is a background task in the `Domain` module (`enabled by default`) that automatically removes orphaned tokens/authorizations, you can configure `TokenCleanupOptions` to manage it.
+
+### ASP NET Core module
+
+This module integrates ASP NET Core, with built-in MVC controllers for four protocols. It uses OpenIddict's [Pass-through mode](https://documentation.openiddict.com/guides/index.html#pass-through-mode).
+
+```cs
+AuthorizeController -> connect/authorize
+TokenController -> connect/token
+LogoutController -> connect/logout
+UserInfoController -> connect/userinfo
+```
+
+> We will implement the related functions of **device flow** in the PRO module..
+
+#### How to control claims in access_token and id_token
+
+You can use the [Claims Principal Factory](https://docs.abp.io/en/abp/latest/Authorization#claims-principal-factory) to add/remove claims to the `ClaimsPrincipal`.
+
+The `AbpDefaultOpenIddictClaimDestinationsProvider` service will add `Name`, `Email` and `Role` types of Claims to `access_token` and `id_token`, other claims are only added to `access_token` by default, and remove the `SecurityStampClaimType` secret claim of `Identity`.
+
+You can create a service that inherits from `IAbpOpenIddictClaimDestinationsProvider` and add it to DI to fully control the destinations of claims
+
+```cs
+public class MyClaimDestinationsProvider : IAbpOpenIddictClaimDestinationsProvider, ITransientDependency
+{
+ public virtual Task SetDestinationsAsync(AbpOpenIddictClaimDestinationsProviderContext context)
+ {
+ // ...
+ return Task.CompletedTask;
+ }
+}
+
+Configure(options =>
+{
+ options.ClaimDestinationsProvider.Add();
+});
+```
+
+For detailed information, please refer to: [OpenIddict claim destinations](https://documentation.openiddict.com/configuration/claim-destinations.html)
+
+#### About Validation
+
+The `OpenIddict.Validation.AspNetCore` and `OpenIddict.Validation` are not integrated in the module, we use the authentication component provided by Microsoft. If you are more familiar with it, you can use it in your project.
+
+
+### EF Core module
+
+Implements the above four repository interfaces.
+
+### MongoDB module
+
+Implements the above four repository interfaces.
+
+
+## OpenIddict
+
+### Documentation
+
+For more details about OpenIddict, please refer to its official documentation and Github.
+
+https://documentation.openiddict.com
+
+https://github.com/openiddict/openiddict-core#resources
+
+### Token encryption
+
+https://documentation.openiddict.com/configuration/encryption-and-signing-credentials.html
+
+> By default, OpenIddict enforces encryption for all the token types it supports. While this enforcement cannot be disabled for authorization codes, refresh tokens and device codes for security reasons, it can be relaxed for access tokens when integration with third-party APIs/resource servers is desired. Access token encryption can also be disabled if the resource servers receiving the access tokens don't fully support JSON Web Encryption.
+
+```cs
+PreConfigure(builder =>
+{
+ builder.DisableAccessTokenEncryption();
+});
+```
+
+An example of using `SecurityKey`
+
+> In production, it is recommended to use two RSA certificates, distinct from the certificate(s) used for HTTPS: one for encryption, one for signing.
+
+```cs
+// In OpenIddict Server
+PreConfigure(builder =>
+{
+ builder.AddSigningKey(new SymmetricSecurityKey(Encoding.UTF8.GetBytes("Abp_OpenIddict_Demo_C40DBB176E78")));
+ builder.AddEncryptionKey(new SymmetricSecurityKey(Encoding.UTF8.GetBytes("Abp_OpenIddict_Demo_87E33FC57D80")));
+});
+
+//In Client AddJwtBearer
+builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
+ .AddJwtBearer(options =>
+ {
+ //Other configuration
+
+ options.TokenValidationParameters.IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("Abp_OpenIddict_Demo_C40DBB176E78"));
+ options.TokenValidationParameters.TokenDecryptionKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("Abp_OpenIddict_Demo_87E33FC57D80"));
+ });
+```
+
+
+### PKCE
+
+https://documentation.openiddict.com/configuration/proof-key-for-code-exchange.html
+
+### Request/Response process
+
+I will briefly introduce the principle of OpenIddict so that everyone can quickly understand it.
+
+The `OpenIddict.Server.AspNetCore` adds an authentication scheme(`Name: OpenIddict.Server.AspNetCore, handler: OpenIddictServerAspNetCoreHandler`) and implements the `IAuthenticationRequestHandler` interface.
+
+It will be executed first in `AuthenticationMiddleware` and can short-circuit the current request. Otherwise, `DefaultAuthenticateScheme` will be called and continue to execute the pipeline.
+
+`OpenIddictServerAspNetCoreHandler` will call various built-in handlers(Handling requests and responses), And the handler will process according to the context or skip logic that has nothing to do with it.
+
+Example a token request:
+
+```
+POST /connect/token HTTP/1.1
+Content-Type: application/x-www-form-urlencoded
+
+ grant_type=password&
+ client_id=AbpApp&
+ client_secret=1q2w3e*&
+ username=admin&
+ password=1q2w3E*&
+ scope=AbpAPI offline_access
+```
+
+This request will be processed by various handlers. They will confirm the endpoint type of the request, check `http/https`, verify that the request parameters (`client. scope etc`) are valid and exist in the database, etc. Various protocol checks. And build a `OpenIddictRequest` object, If there are any errors, the response content may be set and directly short-circuit the current request.
+
+If everything is ok, the request will go to our processing controller(eg `TokenController`), we can get an `OpenIddictRequest` from the http request at this time. The rest of our work will be based on this object.
+
+We may check the `username` and `password` in the request. If it is correct we create a `ClaimsPrincipal` object and return a `SignInResult`, which uses the `OpenIddict.Validation.AspNetCore` authentication scheme name, will calls `OpenIddictServerAspNetCoreHandler` for processing.
+
+`OpenIddictServerAspNetCoreHandler` do some checks to generate json and replace the http response content.
+
+The `ForbidResult` `ChallengeResult` are all the above types of processing.
+
+If you need to customize OpenIddict, you need to replace/delete/add new handlers and make it execute in the correct order.
+
+Please refer to:
+https://documentation.openiddict.com/guides/index.html#events-model
+
+## Sponsor
+
+Please consider sponsoring this project: https://github.com/sponsors/kevinchalet
diff --git a/docs/en/Redis-Cache.md b/docs/en/Redis-Cache.md
index 3e11584bce..9fe8efdb27 100644
--- a/docs/en/Redis-Cache.md
+++ b/docs/en/Redis-Cache.md
@@ -21,7 +21,7 @@ abp add-package Volo.Abp.Caching.StackExchangeRedis
## Configuration
-Volo.Abp.Caching.StackExchangeRedis package automatically gets the redis [configuration](Configuration.md) from the `IConfiguration`. So, for example, you can set your configuration inside the `appsettings.json`:
+Volo.Abp.Caching.StackExchangeRedis package automatically gets the Redis [configuration](Configuration.md) from the `IConfiguration`. So, for example, you can set your configuration inside the `appsettings.json`:
````js
"Redis": {
diff --git a/docs/en/Repositories.md b/docs/en/Repositories.md
index dc82876efb..a1a5ac5cce 100644
--- a/docs/en/Repositories.md
+++ b/docs/en/Repositories.md
@@ -164,6 +164,10 @@ If your entity is a soft-delete entity, you can use the `HardDeleteAsync` method
> See the [Data Filtering](Data-Filtering.md) documentation for more about soft-delete.
+### Ensure Entities Exists
+
+The `EnsureExistsAsync` extension method accepts entity id or entities query expression to ensure entities exist, otherwise, it will throw `EntityNotFoundException`.
+
## Other Generic Repository Types
Standard `IRepository` interface exposes the standard `IQueryable` and you can freely query using the standard LINQ methods. This is fine for most of the applications. However, some ORM providers or database systems may not support standard `IQueryable` interface. If you want to use such providers, you can't rely on the `IQueryable`.
diff --git a/docs/en/Themes/LeptonXLite/angular.md b/docs/en/Themes/LeptonXLite/angular.md
new file mode 100644
index 0000000000..6e4cbef317
--- /dev/null
+++ b/docs/en/Themes/LeptonXLite/angular.md
@@ -0,0 +1,82 @@
+# LeptonX Lite Angular UI
+LeptonX Lite has implementation for the ABP Framework Angular Client. It's a simplified variation of the [LeptonX Theme](https://x.leptontheme.com/).
+
+> If you are looking for a professional, enterprise ready theme, you can check the [LeptonX Theme](https://x.leptontheme.com/), which is a part of [ABP Commercial](https://commercial.abp.io/).
+
+> See the [Theming document](https://docs.abp.io/en/abp/latest/UI/AspNetCore/Theming) to learn about themes.
+
+## Installation
+
+To add `LeptonX-lite` into your project,
+
+* Install `@abp/ng.theme.lepton-x`
+
+`yarn add @abp/ng.theme.lepton-x@preview`
+
+* Install `bootstrap-icons`
+
+`yarn add bootstrap-icons`
+
+
+* Then, we need to edit the styles array in `angular.json` to replace the existing style with the new one.
+
+Add the following style
+
+```json
+"node_modules/bootstrap-icons/font/bootstrap-icons.css",
+```
+
+* Finally, remove `ThemeBasicModule` from `app.module.ts`, and import the related modules in `app.module.ts`
+
+```js
+import { ThemeLeptonXModule } from '@abp/ng.theme.lepton-x';
+import { SideMenuLayoutModule } from '@abp/ng.theme.lepton-x/layouts';
+
+@NgModule({
+ imports: [
+ // ...
+
+ // do not forget to remove ThemeBasicModule
+ // ThemeBasicModule.forRoot(),
+ ThemeLeptonXModule.forRoot(),
+ SideMenuLayoutModule.forRoot(),
+ ],
+ // ...
+})
+export class AppModule {}
+```
+
+Note: If you employ [Resource Owner Password Flow](https://docs.abp.io/en/abp/latest/UI/Angular/Authorization#resource-owner-password-flow) for authorization, you should import the following module as well:
+
+```js
+import { AccountLayoutModule } from '@abp/ng.theme.lepton-x/account';
+
+@NgModule({
+ // ...
+ imports: [
+ // ...
+ AccountLayoutModule.forRoot(),
+ // ...
+ ],
+ // ...
+})
+export class AppModule {}
+```
+
+To change the logos and brand color of `LeptonX`, simply add the following CSS to the `styles.scss`
+
+```css
+:root {
+ --lpx-logo: url('/assets/images/logo.png');
+ --lpx-logo-icon: url('/assets/images/logo-icon.png');
+ --lpx-brand: #edae53;
+}
+```
+
+- `--lpx-logo` is used to place the logo in the menu.
+- `--lpx-logo-icon` is a square icon used when the menu is collapsed.
+- `--lpx-brand` is a color used throughout the application, especially on active elements.
+
+### Server Side
+
+In order to migrate to LeptonX on your server side projects (Host and/or IdentityServer projects), please follow the [Server Side Migration](mvc.md) document.
diff --git a/docs/en/Themes/LeptonXLite/blazor.md b/docs/en/Themes/LeptonXLite/blazor.md
new file mode 100644
index 0000000000..7bc374746a
--- /dev/null
+++ b/docs/en/Themes/LeptonXLite/blazor.md
@@ -0,0 +1,147 @@
+# LeptonX Lite Blazor UI
+
+````json
+//[doc-params]
+{
+ "UI": ["Blazor", "BlazorServer"]
+}
+````
+
+LeptonX Lite has implementation for the ABP Framework Blazor WebAssembly & Blazor Server. It's a simplified variation of the [LeptonX Theme](https://x.leptontheme.com/).
+
+> If you are looking for a professional, enterprise ready theme, you can check the [LeptonX Theme](https://x.leptontheme.com/), which is a part of [ABP Commercial](https://commercial.abp.io/).
+
+> See the [Theming document](https://docs.abp.io/en/abp/latest/UI/AspNetCore/Theming) to learn about themes.
+
+## Installation
+
+{{if UI == "Blazor"}}
+- Complete the [MVC Razor Pages Installation](mvc.md#installation) for the **HttpApi.Host** application first. _If the solution is tiered/micro-service, complete the MVC steps for all MVC applications such as **HttpApi.Host** and if identity server is separated, install to the **IdentityServer**_.
+
+- Add **Volo.Abp.AspNetCore.Components.WebAssembly.LeptonXLiteTheme** package to your **Blazor WebAssembly** application.
+ ```bash
+ dotnet add package Volo.Abp.AspNetCore.Components.WebAssembly.LeptonXLiteTheme
+ ```
+
+- Remove **Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme** reference from the project since it's not necessary after switching to LeptonX Lite.
+
+- Remove the old theme from the **DependsOn** attribute in your module class and add the **AbpAspNetCoreComponentsWebAssemblyLeptonXLiteThemeModule** type to the **DependsOn** attribute.
+
+```diff
+[DependsOn(
+ // Remove BasicTheme module from DependsOn attribute
+- typeof(AbpAspNetCoreComponentsWebAssemblyBasicThemeModule),
+
+ // Add LeptonX Lite module to DependsOn attribute
++ typeof(AbpAspNetCoreComponentsWebAssemblyLeptonXLiteThemeModule),
+)]
+```
+
+- Change startup App component with the LeptonX one.
+
+```csharp
+// Make sure the 'App' comes from 'Volo.Abp.AspNetCore.Components.Web.LeptonXLiteTheme.Themes.LeptonXLite' namespace.
+builder.RootComponents.Add("#ApplicationContainer");
+```
+
+- Run the `abp bundle` command in your **Blazor** application folder.
+
+{{end}}
+
+
+{{if UI == "BlazorServer"}}
+
+- Complete the [MVC Razor Pages Installation](mvc.md#installation) first. _If the solution is tiered/micro-service, complete the MVC steps for all MVC applications such as **HttpApi.Host** and **IdentityServer**_.
+
+- Add **Volo.Abp.AspNetCore.Components.Server.LeptonXLiteTheme** package to your **Blazor server** application.
+ ```bash
+ dotnet add package Volo.Abp.AspNetCore.Components.Server.LeptonXLiteTheme
+ ```
+
+- Remove **Volo.Abp.AspNetCore.Components.Server.BasicTheme** reference from the project since it's not necessary after switching to LeptonX Lite.
+
+
+- Remove old theme from the **DependsOn** attribute in your module class and add the **AbpAspNetCoreComponentsServerLeptonXLiteThemeModule** type to the **DependsOn** attribute.
+
+ ```diff
+ [DependsOn(
+ // Remove BasicTheme module from DependsOn attribute
+ - typeof(AbpAspNetCoreComponentsServerBasicThemeModule),
+
+ // Add LeptonX Lite module to DependsOn attribute
+ + typeof(AbpAspNetCoreComponentsServerLeptonXLiteThemeModule)
+ )]
+ ```
+
+- Replace `BlazorBasicThemeBundles` with `BlazorLeptonXLiteThemeBundles` in `AbpBundlingOptions`:
+ ```diff
+ options.StyleBundles.Configure(
+ // Remove following line
+ - BlazorBasicThemeBundles.Styles.Global,
+ // Add following line instead
+ + BlazorLeptonXLiteThemeBundles.Styles.Global,
+ bundle =>
+ {
+ bundle.AddFiles("/blazor-global-styles.css");
+ //You can remove the following line if you don't use Blazor CSS isolation for components
+ bundle.AddFiles("/MyProjectName.Blazor.styles.css");
+ });
+ ```
+
+- Update `_Host.cshtml` file. _(located under **Pages** folder by default.)_
+
+ - Add following usings to Locate **App** and **BlazorLeptonXLiteThemeBundles** classes.
+ ```csharp
+ @using Volo.Abp.AspNetCore.Components.Web.LeptonXLiteTheme.Themes.LeptonXLite
+ @using Volo.Abp.AspNetCore.Components.Server.LeptonXLiteTheme.Bundling
+ ```
+ - Then replace script & style bundles as following:
+ ```diff
+ // Remove following line
+ -
+ // Add following line instead
+ +
+ ```
+
+ ```diff
+ // Remove following line
+ -
+ // Add following line instead
+ +
+ ```
+
+{{end}}
+
+
+---
+
+## Customization
+
+### Toolbars
+LeptonX Lite includes separeted toolbars for desktop & mobile. You can manage toolbars independently. Toolbar names can be accessible in the **LeptonXLiteToolbars** class.
+
+- `LeptonXLiteToolbars.Main`
+- `LeptonXLiteToolbars.MainMobile`
+
+```csharp
+public async Task ConfigureToolbarAsync(IToolbarConfigurationContext context)
+{
+ if (context.Toolbar.Name == LeptonXLiteToolbars.Main)
+ {
+ context.Toolbar.Items.Add(new ToolbarItem(typeof(MyDesktopComponent)));
+ }
+
+ if (context.Toolbar.Name == LeptonXLiteToolbars.MainMobile)
+ {
+ context.Toolbar.Items.Add(new ToolbarItem(typeof(MyMobileComponent)));
+ }
+
+ return Task.CompletedTask;
+}
+```
+
+{{if UI == "BlazorServer"}}
+
+> _You can visit the [Toolbars Documentation](https://docs.abp.io/en/abp/latest/UI/Blazor/Toolbars) for better understanding._
+
+{{end}}
diff --git a/docs/en/Themes/LeptonXLite/mvc.md b/docs/en/Themes/LeptonXLite/mvc.md
new file mode 100644
index 0000000000..5c2c515613
--- /dev/null
+++ b/docs/en/Themes/LeptonXLite/mvc.md
@@ -0,0 +1,74 @@
+# LeptonX Lite MVC UI
+LeptonX Lite has implementation for the ABP Framework Razor Pages. It's a simplified variation of the [LeptonX Theme](https://x.leptontheme.com/).
+
+> If you are looking for a professional, enterprise ready theme, you can check the [LeptonX Theme](https://x.leptontheme.com/), which is a part of [ABP Commercial](https://commercial.abp.io/).
+
+> See the [Theming document](https://docs.abp.io/en/abp/latest/UI/AspNetCore/Theming) to learn about themes.
+
+## Installation
+
+- Add **Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonXLite** package to your **Web** application.
+
+```bash
+dotnet add package Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonXLite --prerelease
+```
+
+- Remove **Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic** reference from the project since it's not necessary after switching to LeptonX Lite.
+
+- Make sure the old theme is removed and LeptonX is added in your Module class.
+
+```diff
+[DependsOn(
+ // Remove BasicTheme module from DependsOn attribute
+- typeof(AbpAspNetCoreMvcUiBasicThemeModule),
+
+ // Add LeptonX Lite module to DependsOn attribute
++ typeof(AbpAspNetCoreMvcUiLeptonXLiteThemeModule),
+)]
+```
+
+- Replace `BasicThemeBundles` with `LeptonXLiteThemeBundles` in AbpBundlingOptions
+
+```diff
+Configure(options =>
+{
+ options.StyleBundles.Configure(
+ // Remove following line
+- BasicThemeBundles.Styles.Global,
+ // Add following line instead
++ LeptonXLiteThemeBundles.Styles.Global
+ bundle =>
+ {
+ bundle.AddFiles("/global-styles.css");
+ }
+ );
+});
+```
+
+---
+
+## Customization
+
+### Toolbars
+LeptonX Lite includes separeted toolbars for desktop & mobile. You can manage toolbars independently. Toolbar names can be accessible in the **LeptonXLiteToolbars** class.
+
+- `LeptonXLiteToolbars.Main`
+- `LeptonXLiteToolbars.MainMobile`
+
+```csharp
+public class MyProjectNameMainToolbarContributor : IToolbarContributor
+{
+ public async Task ConfigureToolbarAsync(IToolbarConfigurationContext context)
+ {
+ if (context.Toolbar.Name == LeptonXLiteToolbars.Main)
+ {
+ context.Toolbar.Items.Add(new ToolbarItem(typeof(MyDesktopComponent)));
+ }
+
+ if (context.Toolbar.Name == LeptonXLiteToolbars.MainMobile)
+ {
+ context.Toolbar.Items.Add(new ToolbarItem(typeof(MyMobileComponent)));
+ }
+ }
+}
+```
diff --git a/docs/en/UI/Angular/DateTime-Format-Pipe.md b/docs/en/UI/Angular/DateTime-Format-Pipe.md
new file mode 100644
index 0000000000..4841ffe665
--- /dev/null
+++ b/docs/en/UI/Angular/DateTime-Format-Pipe.md
@@ -0,0 +1,29 @@
+# DateTime Format Pipes
+
+You can format date by Date pipe of angular.
+
+Example
+
+```html
+ {{today | date 'dd/mm/yy'}}
+```
+
+ShortDate, ShortTime and ShortDateTime format data like angular's data pipe but easier. Also the pipes get format from config service by culture.
+
+# ShortDate Pipe
+
+```html
+ {{today | shortDatePipe }}
+```
+
+# ShortTime Pipe
+
+```html
+ {{today | shortTimePipe }}
+```
+
+# ShortDateTime Pipe
+
+```html
+ {{today | shortDateTimePipe }}
+```
diff --git a/docs/en/UI/Angular/Page-Toolbar-Extensions.md b/docs/en/UI/Angular/Page-Toolbar-Extensions.md
index 7e63950224..1edc9594fb 100644
--- a/docs/en/UI/Angular/Page-Toolbar-Extensions.md
+++ b/docs/en/UI/Angular/Page-Toolbar-Extensions.md
@@ -21,9 +21,9 @@ The following code prepares a constant named `identityToolbarActionContributors`
import {
eIdentityComponents,
- IdentityToolbarActionContributors,
- IdentityUserDto,
+ IdentityToolbarActionContributors
} from '@abp/ng.identity';
+import { IdentityUserDto } from '@abp/ng.identity/proxy';
import { ToolbarAction, ToolbarActionList } from '@abp/ng.theme.shared/extensions';
const logUserNames = new ToolbarAction({
@@ -93,7 +93,7 @@ We need to have a component before we can pass it to the toolbar action contribu
```js
// src/app/click-me-button.component.ts
-import { IdentityUserDto } from '@abp/ng.identity';
+import { IdentityUserDto } from '@abp/ng.identity/proxy';
import { ActionData, EXTENSIONS_ACTION_DATA } from '@abp/ng.theme.shared/extensions';
import { Component, Inject } from '@angular/core';
@@ -127,9 +127,9 @@ The following code prepares a constant named `identityToolbarActionContributors`
import {
eIdentityComponents,
- IdentityToolbarActionContributors,
- IdentityUserDto,
+ IdentityToolbarActionContributors
} from '@abp/ng.identity';
+import { IdentityUserDto } from '@abp/ng.identity/proxy';
import { ToolbarActionList, ToolbarComponent } from '@abp/ng.theme.shared/extensions';
import { ClickMeButtonComponent } from './click-me-button.component';
@@ -362,7 +362,7 @@ export function reorderUserContributors(
) {
// drop "New User" button
const newUserActionNode = actionList.dropByValue(
- 'AbpIdentity::NewUser',
+ 'AbpIdentity::NewUser',
(action, text) => action['text'] === text,
);
diff --git a/docs/en/_resources/Diagrams.pptx b/docs/en/_resources/Diagrams.pptx
new file mode 100644
index 0000000000..05edf2ced7
Binary files /dev/null and b/docs/en/_resources/Diagrams.pptx differ
diff --git a/docs/en/docs-nav.json b/docs/en/docs-nav.json
index b2061920a8..66910b683d 100644
--- a/docs/en/docs-nav.json
+++ b/docs/en/docs-nav.json
@@ -704,6 +704,10 @@
{
"text": "The Basic Theme",
"path": "UI/AspNetCore/Basic-Theme.md"
+ },
+ {
+ "text": "LeptonX Lite",
+ "path": "Themes/LeptonXLite/mvc.md"
}
]
},
@@ -817,6 +821,10 @@
"text": "The Basic Theme",
"path": "UI/Blazor/Basic-Theme.md"
},
+ {
+ "text": "LeptonX Lite",
+ "path": "Themes/LeptonXLite/blazor.md"
+ },
{
"text": "Branding",
"path": "UI/Blazor/Branding.md"
@@ -1071,6 +1079,10 @@
{
"text": "The Basic Theme",
"path": "UI/Angular/Basic-Theme.md"
+ },
+ {
+ "text": "LeptonX Lite",
+ "path": "Themes/LeptonXLite/angular.md"
}
]
},
@@ -1085,10 +1097,10 @@
{
"text": "Extensions",
"items": [
- {
+ {
"text": "Overall",
"path": "UI/Angular/Extensions-Overall.md"
- },
+ },
{
"text": "Entity Action Extensions",
"path": "UI/Angular/Entity-Action-Extensions.md"
@@ -1104,6 +1116,10 @@
{
"text": "Dynamic Form Extensions",
"path": "UI/Angular/Dynamic-Form-Extensions.md"
+ },
+ {
+ "text": "Date, time and datetime format pipes",
+ "path": "UI/Angular/DateTime-Format-Pipe.md"
}
]
}
@@ -1226,15 +1242,12 @@
"path": "Testing.md"
},
{
- "text": "Samples",
+ "text": "Deployment",
+ "path": "Deployment/Index.md",
"items": [
{
- "text": "All Samples",
- "path": "Samples/Index.md"
- },
- {
- "text": "Microservice Demo",
- "path": "Samples/Microservice-Demo.md"
+ "text": "Deploying to a Clustered Environment",
+ "path": "Deployment/Clustered-Environment.md"
}
]
},
@@ -1276,6 +1289,10 @@
{
"text": "IdentityServer",
"path": "Modules/IdentityServer.md"
+ },
+ {
+ "text": "OpenIddict",
+ "path": "Modules/OpenIddict.md"
},
{
"text": "Permission Management",
@@ -1295,6 +1312,19 @@
}
]
},
+ {
+ "text": "Samples",
+ "items": [
+ {
+ "text": "All Samples",
+ "path": "Samples/Index.md"
+ },
+ {
+ "text": "Microservice Demo",
+ "path": "Samples/Microservice-Demo.md"
+ }
+ ]
+ },
{
"text": "Release Information",
"items": [
diff --git a/docs/en/images/deployment-clustered.png b/docs/en/images/deployment-clustered.png
new file mode 100644
index 0000000000..74177482c5
Binary files /dev/null and b/docs/en/images/deployment-clustered.png differ
diff --git a/docs/en/images/deployment-single-instance.png b/docs/en/images/deployment-single-instance.png
new file mode 100644
index 0000000000..8c3f8719b2
Binary files /dev/null and b/docs/en/images/deployment-single-instance.png differ
diff --git a/docs/zh-Hans/CLI-New-Command-Samples.md b/docs/zh-Hans/CLI-New-Command-Samples.md
new file mode 100644
index 0000000000..3adfa472ed
--- /dev/null
+++ b/docs/zh-Hans/CLI-New-Command-Samples.md
@@ -0,0 +1,248 @@
+# ABP CLI - 新解决方案命令示例
+
+`abp new`命令基于abp模板创建abp解决方案或其他组件. [ABP CLI](CLI.md)有一些参数可以用于创建新的ABP解决方案. 在本文档中, 我们将向你展示一些创建新的解决方案的命令示例. 所有的项目名称都是`Acme.BookStore`. 目前, 唯一可用的移动端项目是`React Native`移动端应用程序. 可用的数据库提供程序有`Entity Framework Core`和`MongoDB`. 所有命令都以`abp new`开头.
+
+## Angular
+
+以下命令用于创建Angular UI项目:
+
+* 在新文件夹中创建项目, **Entity Framework Core**, 非移动端应用程序:
+
+ ````bash
+ abp new Acme.BookStore -u angular --mobile none --database-provider ef -csf
+ ````
+
+* 在新文件夹中创建项目, **Entity Framework Core**, 默认应用程序模板, **拆分Identity Server**:
+
+ ```bash
+ abp new Acme.BookStore -t app -u angular -m none --separate-identity-server --database-provider ef -csf
+ ```
+
+* 在新文件夹中创建项目, **Entity Framework Core**, **自定义连接字符串**:
+
+ ```bash
+ abp new Acme.BookStore -u angular -csf --connection-string Server=localhost;Database=MyDatabase;Trusted_Connection=True
+ ```
+
+* 在`C:\MyProjects\Acme.BookStore`中创建解决方案, **MongoDB**, 默认应用程序模板, 包含移动端项目:
+
+ ```bash
+ abp new Acme.BookStore -u angular --database-provider mongodb --output-folder C:\MyProjects\Acme.BookStore
+ ```
+
+* 在新文件夹中创建项目, **MongoDB**, 默认应用程序模板, 不创建移动端应用程序, **拆分Identity Server**:
+
+ ```bash
+ abp new Acme.BookStore -t app -u angular -m none --separate-identity-server --database-provider mongodb -csf
+ ```
+
+## MVC
+
+以下命令用于创建MVC UI项目:
+
+* 在新文件夹中创建项目, **Entity Framework Core**, 不创建移动端应用程序:
+
+ ```bash
+ abp new Acme.BookStore -t app -u mvc --mobile none --database-provider ef -csf
+ ```
+
+* 在新文件夹中创建项目, **Entity Framework Core**, **分层结构** (*Web和HTTP API层是分开的*), 不创建移动端应用程序:
+
+ ```bash
+ abp new Acme.BookStore -u mvc --mobile none --tiered --database-provider ef -csf
+ ```
+
+* 在新文件夹中创建项目, **MongoDB**, 不创建移动端应用程序:
+
+ ```bash
+ abp new Acme.BookStore -t app -u mvc --mobile none --database-provider mongodb -csf
+ ```
+
+* 在新文件夹中创建项目, **MongoDB**, **分层结构**:
+
+ ```bash
+ abp new Acme.BookStore -u mvc --tiered --database-provider mongodb -csf
+ ```
+
+
+## Blazor
+
+以下命令用于创建Blazor项目:
+
+* **Entity Framework Core**, 不创建移动端应用程序:
+
+ ```bash
+ abp new Acme.BookStore -t app -u blazor --mobile none
+ ```
+
+* **Entity Framework Core**, **拆分Identity Server**, 包含移动端应用程序:
+
+ ```bash
+ abp new Acme.BookStore -u blazor --separate-identity-server
+ ```
+
+* 在新文件夹中创建项目, **MongoDB**, 不创建移动端应用程序:
+
+ ```bash
+ abp new Acme.BookStore -u blazor --database-provider mongodb --mobile none -csf
+ ```
+
+## Blazor Server
+
+以下命令用于创建Blazor项目:
+
+* **Entity Framework Core**, 不创建移动端应用程序:
+
+ ```bash
+ abp new Acme.BookStore -t app -u blazor-server --mobile none
+ ```
+
+* **Entity Framework Core**, **拆分Identity Server**, **拆分API Host**, 包含移动端应用程序:
+
+ ```bash
+ abp new Acme.BookStore -u blazor-server --tiered
+ ```
+
+* 在新文件夹中创建项目, **MongoDB**, 不创建移动端应用程序:
+
+ ```bash
+ abp new Acme.BookStore -u blazor --database-provider mongodb --mobile none -csf
+ ```
+
+## 无UI
+
+在默认应用程序模板中, 始终有一个前端项目. 在这个选项中没有前端项目. 它有一个`HttpApi.Host`项目为你的HTTP WebAPI提供服务. 这个选项适合在你想创建一个WebAPI服务时使用.
+
+* 在新文件夹中创建项目, **Entity Framework Core**, 拆分Identity Server:
+
+ ```bash
+ abp new Acme.BookStore -u none --separate-identity-server -csf
+ ```
+* **MongoDB**, 不创建移动端应用程序:
+
+ ```bash
+ abp new Acme.BookStore -u none --mobile none --database-provider mongodb
+ ```
+
+
+
+## 控制台应用程序
+
+这是一个基于.NET控制台应用程序的模板, 集成了ABP模块架构. 要创建控制台应用程序, 请使用以下命令:
+
+* 项目由以下文件组成: `Acme.BookStore.csproj`, `appsettings.json`, `BookStoreHostedService.cs`, `BookStoreModule.cs`, `HelloWorldService.cs` 和 `Program.cs`.
+
+ ```bash
+ abp new Acme.BookStore -t console -csf
+ ```
+
+## 模块
+
+模块是主项目使用的可重用子应用程序. 如果你正在构建微服务解决方案, 使用ABP模块是最佳方案. 由于模块不是最终的应用程序, 每个模块都有前端UI项目和数据库提供程序. 模块模板带有MVC UI, 可以在没有最终解决方案的情况下进行开发. 但是, 如果要在最终解决方案下开发模块, 可以添加`--no-ui`参数来去除MVC UI项目.
+
+* 包含前端: `MVC`, `Angular`, `Blazor`. 包含数据库提供程序: `Entity Framework Core`, `MongoDB`. 包含MVC启动项目.
+
+ ```bash
+ abp new Acme.IssueManagement -t module
+ ```
+* 与上面相同, 但不包括MVC启动项目.
+
+ ```bash
+ abp new Acme.IssueManagement -t module --no-ui
+ ```
+
+* 创建模块并将其添加到解决方案中
+
+ ```bash
+ abp new Acme.IssueManagement -t module --add-to-solution-file
+ ```
+
+## 从特定版本创建解决方案
+
+创建解决方案时, 它总是使用最新版本创建. 要从旧版本创建项目, 可以使用`--version`参数.
+
+* 使用v3.3.0版本创建解决方案, 包含Angular UI和Entity Framework Core.
+
+ ```bash
+ abp new Acme.BookStore -t app -u angular -m none --database-provider ef -csf --version 3.3.0
+ ```
+
+要获取ABP版本列表, 请查看以下链接: https://www.nuget.org/packages/Volo.Abp.Core/
+
+## 从自定义模板创建
+
+ABP CLI使用默认的[应用程序模板](https://github.com/abpframework/abp/tree/dev/templates/app)创建项目. 如果要从自定义模板创建新的解决方案, 可以使用参数`--template-source`.
+
+* 在`c:\MyProjects\templates\app`目录中使用模板, MVC UI, Entity Framework Core, 不创建移动端应用程序.
+
+ ```bash
+ abp new Acme.BookStore -t app -u mvc --mobile none --database-provider ef --template-source "c:\MyProjects\templates\app"
+ ```
+
+* 除了此命令从URL `https://myabp.com/app-template.zip` 检索模板之外, 与上一个命令相同.
+
+ ```bash
+ abp new Acme.BookStore -t app -u mvc --mobile none --database-provider ef --template-source https://myabp.com/app-template.zip
+ ```
+
+## 创建预览版本
+
+ABP CLI始终使用最新版本. 要从预览(RC)版本创建解决方案, 请添加`--preview`参数.
+
+* 在新文件夹中创建项目, Blazor UI, Entity Framework Core, 不创建移动端应用程序, **使用最新版本**:
+
+ ```bash
+ abp new Acme.BookStore -t app -u blazor --mobile none -csf --preview
+ ```
+
+## 选择数据库管理系统
+
+默认的数据库管理系统是 `Entity Framework Core` / ` SQL Server`. 你可以通过使用`--database-management-system`参数选择DBMS. [可用的值](https://github.com/abpframework/abp/blob/dev/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/DatabaseManagementSystem.cs) 包括 `SqlServer`, `MySQL`, `SQLite`, `Oracle`, `Oracle-Devart`, `PostgreSQL`. 默认值是 `SqlServer`.
+
+* 在新文件夹中创建项目, Angular UI, **PostgreSQL** 数据库:
+
+ ```bash
+ abp new Acme.BookStore -u angular --database-management-system PostgreSQL -csf
+ ```
+
+## 使用静态HTTP端口
+
+ABP CLI始终为项目分配随机端口. 如果需要保留默认端口并且创建解决方案始终使用相同的HTTP端口, 请添加参数`--no-random-port`.
+
+* 在新文件夹中创建项目, MVC UI, Entity Framework Core, **静态端口**:
+
+ ```bash
+ abp new Acme.BookStore --no-random-port -csf
+ ```
+
+## 引用本地ABP框架
+
+在ABP解决方案中, 默认情况下从NuGet引用ABP库. 有时, 你需要在本地将ABP库引用到你的解决方案中. 这利于调试框架本身. 本地ABP框架的根目录必须有`Volo.Abp.sln`文件. 你可以将以下目录的内容复制到你的文件系统中
+
+* MVC UI, Entity Framework Core, **引用本地的ABP库**:
+
+本地路径必须是ABP存储库的根目录.
+如果`C:\source\abp\framework\Volo.Abp.sln`是你的框架解决方案的路径, 那么你必须设置`--abp-path`参数值为`C:\source\abp`.
+
+ ```bash
+ abp new Acme.BookStore --local-framework-ref --abp-path C:\source\abp
+ ```
+
+**输出**:
+
+如下所示, 引用本地ABP框架库项目.
+
+```xml
+
+
+
+
+
+
+
+
+```
+
+## 另请参阅
+
+* [ABP CLI文档](CLI.md)
diff --git a/docs/zh-Hans/CLI.md b/docs/zh-Hans/CLI.md
index 5ff00c5501..bef5a7220e 100644
--- a/docs/zh-Hans/CLI.md
+++ b/docs/zh-Hans/CLI.md
@@ -78,6 +78,8 @@ abp new Acme.BookStore
* Acme.BookStore是解决方案的名称.
* 常见的命名方式类似于 *YourCompany.YourProject*. 不过你可以使用自己喜欢的方式,如 *YourProject* (单级命名空间) 或 *YourCompany.YourProduct.YourModule* (三级命名空间).
+参阅[ABP CLI 创建新解决方案示例](CLI-New-Command-Samples.md)查看更多示例.
+
#### Options
* `--template` 或者 `-t`: 指定模板. 默认的模板是 `app`,会生成web项目.可用的模板有:
@@ -407,4 +409,4 @@ abp install-libs [options]
#### Options
-* ```--working-directory``` 或 ```-wd```: 指定工作目录, 当执行目录不包含项目文件时会很有用.
\ No newline at end of file
+* ```--working-directory``` 或 ```-wd```: 指定工作目录, 当执行目录不包含项目文件时会很有用.
diff --git a/docs/zh-Hans/Connection-Strings.md b/docs/zh-Hans/Connection-Strings.md
index cf3aed11fa..290cce0436 100644
--- a/docs/zh-Hans/Connection-Strings.md
+++ b/docs/zh-Hans/Connection-Strings.md
@@ -7,7 +7,7 @@ ABP框架的设计是[模块化](Module-Development-Basics.md), [微服务兼容
它还支持混合场景;
-* 允许将模块分组到数据库 (所有的模块分组到一个共享数据库, 两个模块使用数据库A, 3个模块使用数据库B, 一个数据库使用数据库C其余的数据库使用数据库D...等.)
+* 允许将模块分组到数据库 (所有的模块分组到一个共享数据库, 两个模块使用数据库A, 三个模块使用数据库B, 一个模块使用数据库C其余的模块使用数据库D...等.)
* 允许将租户分组到数据库中,像模块一样.
* 允许为每个租户每个模块分离数据库 (数据库过多会增加维护成本,但ABP框架支持这种需求).
diff --git a/docs/zh-Hans/Deployment/Clustered-Environment.md b/docs/zh-Hans/Deployment/Clustered-Environment.md
new file mode 100644
index 0000000000..34547709d1
--- /dev/null
+++ b/docs/zh-Hans/Deployment/Clustered-Environment.md
@@ -0,0 +1,99 @@
+# 部署到群集环境
+
+本文档介绍了在将应用程序部署到**多个应用程序实例同时运行**的集群环境中时应注意的内容, 并解释了如何在基于ABP的应用程序中处理这些内容.
+
+> 无论你使用的是单体式应用程序还是微服务解决方案, 本文档均有效. 适用于一个流程. 应用程序可以是单体式web应用程序、微服务解决方案中的服务、控制台应用程序或其他类型的可执行进程.
+>
+> 例如, 如果你将应用程序部署到Kubernetes并把应用程序或服务在多个POD中运行, 那么应用程序或服务将在集群环境中运行.
+
+## 了解集群环境
+
+> 如果你已经熟悉集群部署和负载均衡器, 可以跳过本节.
+
+### 单实例部署
+
+考虑作为**单个实例**部署的应用程序, 如下图所示:
+
+
+
+浏览器和其他客户端应用程序可以直接向应用程序发出HTTP请求. 你可以在客户端和应用程序之间放置一个web服务器(例如IIS或NGINX), 但仍有一个应用程序实例在单个服务器或容器中运行. 单实例的配置**限于规模**, 因为它在一台服务器上运行, 并且你受到服务器容量的限制.
+
+### 集群部署
+
+**集群部署**是在一台或多台服务器上**同时运行**应用程序**多个实例**的方式. 通过这种方式, 不同的实例可以满足不同的请求, 并且可以通过在系统中添加新服务器来扩展. 下图显示了集群使用**负载均衡器**的典型实现:
+
+
+
+### 负载均衡器
+
+[负载均衡器](https://en.wikipedia.org/wiki/Load_balancing_(computing)) 有很多特性, 但它们基本上会将**传入的HTTP请求转发**给应用程序的实例, 并将响应返回给客户端应用程序.
+
+负载平衡器可以使用不同的算法来选择应用程序实例, 同时确定用于传递传入请求的应用程序实例. **循环**是最简单、最常用的算法之一. 请求被轮流传递到应用程序实例. 第一个实例得到第一个请求, 第二个实例得到第二个请求, 依此类推. 在所有实例都被使用之后, 它返回到第一个实例, 并且下一个请求的算法也是类似的.
+
+### 潜在问题
+
+一旦应用程序的多个实例并行运行, 你应该仔细考虑以下内容:
+
+* 当你有多个实例时, 存储在应用程序 **内存中的任何状态(数据)** 都将成为问题. 存储在应用程序实例内存中的状态可能在下一个请求中不可用, 因为下一个请求将由不同的应用程序实例处理. 虽然有一些解决方案(比如粘性会话)可以解决这个问题, 但如果你想在集群、容器或云中运行应用程序, **最好将其设计为无状态**.
+* **内存缓存** 是一种内存状态, 不应在集群应用程序中使用. 你应该使用**分布式缓存**.
+* 你不应该在**本地文件系统**中存储应用程序所有实例都可以使用的数据. 不同的应用程序实例可能在不同的容器或服务器中运行, 并且它们可能无法访问同一个文件系统. 你可以使用**云或外部存储提供商**作为解决方案.
+* 如果你有**后台工作者**或**作业队列管理器**, 则应小心, 因为多个实例可能会尝试执行同一作业或同时执行同一工作. 因此, 你可能会多次完成相同的工作, 或者在尝试访问和更改相同的资源时可能会出现很多错误.
+
+集群部署可能会有更多问题, 但这些是最常见的问题. ABP被设计为与集群部署场景兼容. 以下各节介绍了将基于ABP的应用程序部署到集群环境时应执行的操作.
+
+## 切换分布式缓存
+
+ASP.NET Core提供了不同类型的缓存功能. [内存缓存](https://docs.microsoft.com/en-us/aspnet/core/performance/caching/memory)将对象存储在本地服务器的内存中, 并且仅对存储该对象的应用程序可用. 集群环境中的非粘性会话应使用[分布式缓存](https://docs.microsoft.com/en-us/aspnet/core/performance/caching/distributed), 除了一些特定场景(例如, 你可以将本地CSS文件缓存到内存中. 它是只读数据, 在所有应用程序实例中都是相同的. 出于性能原因, 你可以将其缓存到内存中, 而不会出现任何问题).
+
+[ABP的分布式缓存](../Caching.md)扩展了[ASP.NET Core的分布式缓存](https://docs.microsoft.com/en-us/aspnet/core/performance/caching/distributed)的基础设施. 默认情况下, 它在内存中工作. 当你要将应用程序部署到集群环境时, 应该配置实际的分布式缓存提供程序.
+
+> 即使应用程序不直接使用`IDistributedCache`, 也应该为集群部署配置缓存提供程序. 因为ABP框架和预构建的[应用程序模块](../Modules/Index.md)正在使用分布式缓存.
+
+ASP.NET Core提供了可以用作分布式缓存提供程序的多种集成, 如[Redis](https://redis.io/)和[NCache](https://www.alachisoft.com/ncache/). 你可以按照[微软文档](https://docs.microsoft.com/en-us/aspnet/core/performance/caching/distributed)了解如何在应用程序中使用它们.
+
+如果你决定使用Redis作为分布式缓存提供程序, **请遵循[ABP的Redis缓存集成文档](../Redis-Cache.md)** 了解将其安装到应用程序并配置Redis所需遵循的步骤.
+
+> 根据你在创建新ABP解决方案时的偏好, Redis缓存可能会预先安装在你的解决方案中. 例如, 如果你在MVC UI中选择了*Tiered*选项, Redis缓存将进行预装. 因为, 在这种情况下, 解决方案中有两个应用程序, 它们应该使用相同的缓存源来保持一致.
+
+## 使用合适的BLOB存储提供程序
+
+如果你在[文件系统提供程序](../Blob-Storing-File-System.md)中使用了ABP的[BLOB存储](../Blob-Storing.md)功能, 则应该在集群环境中使用另一个提供程序, 因为文件系统提供程序使用应用程序的本地文件系统.
+
+[数据库BLOB提供程序](../Blob-Storing-Database)是最简单的方法, 因为它使用应用程序的主数据库(或另一个数据库, 如果你配置的话)来存储BLOB. 但是, 你应该记住, BLOB是大型对象, 可能会迅速增加数据库的大小.
+
+> [ABP商业版](https://commercial.abp.io/)启动解决方案模板预装了数据库BLOB提供程序, 并将BLOB存储在应用程序的数据库中.
+
+查看[BLOB Storing](../Blob-Storing.md)文档以查看所有可用的BLOB存储提供程序.
+
+## 配置后台作业
+
+ABP的[后台作业系统](../Background-Jobs.md)将要在后台执行的任务进行排队. 后台作业队列是持久性的, 排队的任务能够保证执行(如果失败, 将重新尝试).
+
+ABP的默认后台作业管理器与集群环境兼容. 它使用[分布式锁](../Distributed-Locking.md)来确保一次只能在单个应用程序实例中执行作业. 请参阅下面的*配置分布式锁提供程序*部分, 了解如何为应用程序配置分布式锁提供程序, 以便默认后台作业管理器在集群环境中正常工作.
+
+如果不想使用分布式锁提供程序, 可以使用以下选项:
+
+* 停止所有应用程序实例中的后台作业管理器(将`AbpBackgroundJobOptions.IsJobExecutionEnabled`设置为`false`)只保留其中一个应用程序实例, 以便只有单个实例执行作业(而其他应用程序实例仍可以对作业进行排队).
+* 在所有应用程序实例中停止后台作业管理器(将`AbpBackgroundJobOptions.IsJobExecutionEnabled`设置为`false`), 并创建一个专用的应用程序(可能是在自己的容器中运行的控制台应用程序或在后台运行的Windows服务)来执行所有后台作业. 如果你的后台作业占用大量系统资源(CPU、RAM或磁盘), 那么这是一个不错的选择, 这样你就可以将该后台应用程序部署到专用服务器上, 并且后台作业不会影响应用程序的性能.
+
+> 如果你使用的是外部后台作业集成(例如[Hangfire](../Background-Workers-Hangfire.md)或[Quartz](../Background-Workers-Quartz.md))而不是默认的后台作业管理器, 请参阅提供程序的文档, 了解如何为集群环境配置它.
+
+## 配置分布式锁提供程序
+
+ABP通过[分布式锁](https://github.com/madelson/DistributedLock)库实现了一个抽象的分布式锁. 分布式锁用于控制多个应用程序对共享资源的并发访问, 以防止由于并发写入而导致资源损坏. ABP框架和一些预构建的[应用程序模块](../Modules/Index.md)出于一些原因正在使用分布式锁.
+
+但是, 分布式锁系统默认在进程中工作. 这意味着它实际上不是分布式的, 除非配置分布式锁提供程序. 因此, 如果尚未配置应用程序的提供程序, 请按照[分布式锁](../Distributed-Locking.md)文档为其配置提供程序.
+
+## 实现后台工作者
+
+ASP.NET Core[托管服务](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services), ABP提供[后台工作者](../Background-Workers.md)在应用程序的后台线程中执行任务.
+
+如果你的应用程序有在后台运行的任务, 你应该注意它们在集群环境中的行为, 尤其是在后台任务使用相同资源的情况下. 你应该设计后台任务, 以便它们在集群环境中继续正常工作.
+
+假设SaaS应用程序中的后台工作者检查用户订阅, 并在订阅续订日期临近时发送电子邮件. 如果后台任务在多个应用程序实例中运行, 可能会多次向某些用户发送同一封电子邮件, 这会影响他们.
+
+我们建议你使用以下方法之一来解决此问题:
+
+* 实现你的后台工作者, 以便他们在集群环境中工作时不会出现任何问题. 使用[分布式锁](../Distributed-Locking.md)来确保并发控制是一种方法. 应用程序实例中的后台工作者可能会处理分布式锁, 因此其他应用程序实例中的工作者将等待该锁. 这样, 只有一个工作者在实际工作, 而其他的则在等待. 如果你实现了这一点, 你的后台工作者就可以安全地运行, 不必关心应用程序是如何部署的.
+* 停止所有应用程序实例中的后台工作者(将`AbpBackgroundWorkerOptions.IsEnabled`设置为`false`), 只保留其中一个应用程序实例, 因此只有单个实例运行这些后台工作者.
+* 停止所有应用程序实例中的后台工作者(将`AbpBackgroundWorkerOptions.IsEnabled`设置为`false`), 并创建一个专用的应用程序(可能是在自己的容器中运行的控制台应用程序或在后台运行的Windows服务)来执行所有后台任务. 如果你的后台工作者消耗大量系统资源(CPU、RAM或磁盘), 那么这是一个不错的选择, 这样你就可以将该后台应用程序部署到专用服务器上, 并且你的后台任务不会影响应用程序的性能.
diff --git a/docs/zh-Hans/Deployment/Index.md b/docs/zh-Hans/Deployment/Index.md
new file mode 100644
index 0000000000..9df24e56f0
--- /dev/null
+++ b/docs/zh-Hans/Deployment/Index.md
@@ -0,0 +1,9 @@
+# 部署
+
+部署ABP应用程序与部署其他.NET或ASP.NET Core应用程序并没有什么不同. 你可以将其部署到云服务提供商(例如Azure、AWS、Google)或内部部署服务器、IIS或任何其他web服务器. ABP的文档中没有太多关于部署的信息. 你可以参考提供商的文档.
+
+但是, 在部署应用程序时, 有些主题是你应该注意的. 其中大多数是一般的软件部署注意事项, 但你应该了解如何在基于ABP的应用程序中处理它们. 我们为此准备了指南, 建议你在设计部署配置之前仔细阅读这些指南.
+
+## 指南
+
+* [部署到群集环境](Clustered-Environment.md): 讲解了当你希望同时运行应用程序的多个实例时, 如何来配置应用程序.
diff --git a/docs/zh-Hans/Distributed-Event-Bus-Kafka-Integration.md b/docs/zh-Hans/Distributed-Event-Bus-Kafka-Integration.md
index 171fe3c23b..79e65db414 100644
--- a/docs/zh-Hans/Distributed-Event-Bus-Kafka-Integration.md
+++ b/docs/zh-Hans/Distributed-Event-Bus-Kafka-Integration.md
@@ -20,7 +20,7 @@
这是配置Kafka设置最简单的方法. 它也非常强大,因为你可以使用[由AspNet Core支持](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/)的任何其他配置源(如环境变量).
-**示例:最小化配置与默认配置连接到本地的Kafka服务器**
+**示例:使用默认配置连接到本地Kafka服务器的最小配置**
````json
diff --git a/docs/zh-Hans/Distributed-Event-Bus-Rebus-Integration.md b/docs/zh-Hans/Distributed-Event-Bus-Rebus-Integration.md
index 64fce06d1b..72806038b3 100644
--- a/docs/zh-Hans/Distributed-Event-Bus-Rebus-Integration.md
+++ b/docs/zh-Hans/Distributed-Event-Bus-Rebus-Integration.md
@@ -1,7 +1,9 @@
# 分布式事件总线Rebus集成
+
> 本文解释了 **如何配置[Rebus](http://mookid.dk/category/rebus/)** 做为分布式总线提供程序. 参阅[分布式事件总线文档](Distributed-Event-Bus.md)了解如何使用分布式事件总线系统.
+
## 安装
使用ABP CLI添加[Volo.Abp.EventBus.Rebus](https://www.nuget.org/packages/Volo.Abp.EventBus.Rebus)NuGet包到你的项目:
diff --git a/docs/zh-Hans/Distributed-Locking.md b/docs/zh-Hans/Distributed-Locking.md
new file mode 100644
index 0000000000..2176230403
--- /dev/null
+++ b/docs/zh-Hans/Distributed-Locking.md
@@ -0,0 +1,110 @@
+# 分布式锁
+分布式锁是一种管理多个应用程序访问同一资源的技术. 主要目的是同一时间只允许多个应用程序中的一个访问资源. 否则, 从不同的应用程序访问同一对象可能会破坏资源.
+
+> ABP当前的分布式锁实现基于[DistributedLock](https://github.com/madelson/DistributedLock)库.
+
+## 安装
+
+你可以打开一个命令行终端并输入以下命令来安装[Volo.Abp.DistributedLocking](https://www.nuget.org/packages/Volo.Abp.DistributedLocking)到你的项目中:
+
+````bash
+abp add-package Volo.Abp.DistributedLocking
+````
+
+这个库提供了使用分布式锁系统所需的API, 但是, 在使用它之前, 你应该配置一个提供程序.
+
+### 配置一个提供程序
+
+[DistributedLock](https://github.com/madelson/DistributedLock)库对[Redis](https://github.com/madelson/DistributedLock/blob/master/docs/DistributedLock.Redis.md)和[ZooKeeper](https://github.com/madelson/DistributedLock/blob/master/docs/DistributedLock.ZooKeeper.md)提供[多种实现](https://github.com/madelson/DistributedLock#implementations).
+
+例如, 如果你想使用[Redis provider](https://github.com/madelson/DistributedLock/blob/master/docs/DistributedLock.Redis.md), 你应该将[DistributedLock.Redis](https://www.nuget.org/packages/DistributedLock.Redis) NuGet包添加到项目中, 然后将以下代码添加到ABP[模块](Module-Development-Basics.md)类的`ConfigureServices`方法中:
+
+````csharp
+using Medallion.Threading;
+using Medallion.Threading.Redis;
+
+namespace AbpDemo
+{
+ [DependsOn(
+ typeof(AbpDistributedLockingModule)
+ //If you have the other dependencies, you should do here
+ )]
+ public class MyModule : AbpModule
+ {
+ public override void ConfigureServices(ServiceConfigurationContext context)
+ {
+ var configuration = context.Services.GetConfiguration();
+
+ context.Services.AddSingleton(sp =>
+ {
+ var connection = ConnectionMultiplexer
+ .Connect(configuration["Redis:Configuration"]);
+ return new
+ RedisDistributedSynchronizationProvider(connection.GetDatabase());
+ });
+ }
+ }
+}
+````
+
+此代码从[配置](Configuration.md)获取Redis连接字符串, 因此你可以将以下行添加到`appsettings.json`文件:
+
+````json
+"Redis": {
+ "Configuration": "127.0.0.1"
+}
+````
+
+## 使用
+
+有两种方法可以使用分布式锁API: ABP的`IAbpDistributedLock`抽象和[DistributedLock](https://github.com/madelson/DistributedLock)库的API.
+
+### 使用IAbpDistributedLock服务
+
+`IAbpDistributedLock`是ABP框架提供的一个用于简单使用分布式锁的服务.
+
+**实例: 使用`IAbpDistributedLock.TryAcquireAsync`方法**
+
+````csharp
+using Volo.Abp.DistributedLocking;
+
+namespace AbpDemo
+{
+ public class MyService : ITransientDependency
+ {
+ private readonly IAbpDistributedLock _distributedLock;
+ public MyService(IAbpDistributedLock distributedLock)
+ {
+ _distributedLock = distributedLock;
+ }
+
+ public async Task MyMethodAsync()
+ {
+ await using (var handle =
+ await _distributedLock.TryAcquireAsync("MyLockName"))
+ {
+ if (handle != null)
+ {
+ // your code that access the shared resource
+ }
+ }
+ }
+ }
+}
+````
+
+`TryAcquireAsync`可能无法获取锁. 如果无法获取锁, 则返回`null`. 在这种情况下, 你不应该访问资源. 如果句柄不为`null`, 则表示你已获得锁, 并且可以安全地访问资源.
+
+`TryAcquireAsync`方法拥有以下参数:
+
+* `name` (`string`, 必须): 锁的唯一名称. 不同的锁命名用于访问不同的资源.
+* `timeout` (`TimeSpan`): 等待获取锁的超时值. 默认值为`TimeSpan.Zero`, 这意味着如果锁已经被另一个应用程序拥有, 它不会等待.
+* `cancellationToken`: 取消令牌可在触发后取消操作.
+
+### 使用DistributedLock库的API
+
+ABP的`IAbpDistributedLock`服务非常有限, 主要用于ABP框架的内部使用. 对于你自己的应用程序, 可以使用DistributedLock库自己的API. 参见[文档](https://github.com/madelson/DistributedLock)详细信息.
+
+## Volo.Abp.DistributedLocking.Abstractions库
+
+如果你正在构建一个可重用的库或应用程序模块, 那么对于作为单个实例运行的简单应用程序, 你可能不希望为模块带来额外的依赖关系. 在这种情况下, 你的库可以依赖于[Volo.Abp.DistributedLocking.Abstractions](https://nuget.org/packages/Volo.Abp.DistributedLocking.Abstractions)库, 它定义了`IAbpDistributedLock`服务, 并将其在进程内实现(实际上不是分布式的). 通过这种方式, 你的库可以在作为单个实例运行的应用程序中正常运行(没有分布式锁提供程序依赖项). 如果应用程序部署到[集群环境](Deployment/Clustered-Environment.md), 那么应用程序开发人员应该安装一个真正的分布式提供程序, 如*安装*部分所述.
diff --git a/docs/zh-Hans/Emailing.md b/docs/zh-Hans/Emailing.md
index 22edc50301..2ca01b5cb3 100644
--- a/docs/zh-Hans/Emailing.md
+++ b/docs/zh-Hans/Emailing.md
@@ -22,8 +22,9 @@ abp add-package Volo.Abp.Emailing
### IEmailSender
-[Inject](Dependency-Injection.md) 将 `IEmailSender` 注入任何服务并使用 `SendAsync` 方法发送电子邮件。
-**Example**
+[注入](Dependency-Injection.md) `IEmailSender` 到任何服务并使用 `SendAsync` 方法发送电子邮件。
+
+**示例**
````csharp
using System.Threading.Tasks;
diff --git a/docs/zh-Hans/Entities.md b/docs/zh-Hans/Entities.md
index e54258d61f..7cd96b2820 100644
--- a/docs/zh-Hans/Entities.md
+++ b/docs/zh-Hans/Entities.md
@@ -28,7 +28,7 @@ public class Book : Entity
* 创建一个构造函数,获取ID作为参数传递给基类.
* 如果没有为GUID Id赋值,**ABP框架会在保存时设置它**,但是在将实体保存到数据库之前最好在实体上有一个有效的Id.
* 如果使用带参数的构造函数创建实体,那么还要创建一个 `private` 或 `protected` 构造函数. 当数据库提供程序从数据库读取你的实体时(反序列化时)将使用它.
-* 不要使用 `Guid.NewGuid()` 来设置Id! 在创建实体的代码中**使用[`IGuidGenerator`服务](Guid-Generation.md)**传递Id参数. `IGuidGenerator`经过优化可以产生连续的GUID.这对于关系数据库中的聚集索引非常重要.
+* 不要使用 `Guid.NewGuid()` 来设置Id! 在创建实体的代码中**使用[`IGuidGenerator`服务](Guid-Generation.md)** 传递Id参数. `IGuidGenerator`经过优化可以产生连续的GUID.这对于关系数据库中的聚集索引非常重要.
示例实体:
diff --git a/docs/zh-Hans/Settings.md b/docs/zh-Hans/Settings.md
index a4d84c91b7..73d3115b19 100644
--- a/docs/zh-Hans/Settings.md
+++ b/docs/zh-Hans/Settings.md
@@ -65,7 +65,7 @@ public class MySettingDefinitionProvider : SettingDefinitionProvider
}
````
-> 使用常量作为设置名称是一种好习惯,ABP的包就是这样做的. `Abp.Mailing.Smtp`设置名称是在`EmailSettingNames`类(在Volo.Abp.Emailing名称空间中)定义的常量.
+> 使用常量作为设置名称是一种好习惯,ABP的包就是这样做的. `Abp.Mailing.Smtp.Host`设置名称是在`EmailSettingNames`类(在Volo.Abp.Emailing命名空间中)定义的常量.
## 读取设置值
@@ -141,7 +141,7 @@ var requireDigit = abp.setting.getBoolean('Abp.Identity.Password.RequireDigit');
* `TenantSettingValueProvider`: 获取当前租户的设置值(参阅 [多租户](Multi-Tenancy.md)文档).
* `UserSettingValueProvider`: 获取当前用户的设置值(参阅 [当前用户](CurrentUser.md) 文档).
-> 设置回退系统从底部 (用户) 到 (默认) 方向起用用.
+> 设置回退系统从底部 (用户) 到 顶部(默认) 方向起作用.
全局,租户和用户设置值提供程序使用 `ISettingStore` 从数据源读取值(参见下面的小节).
@@ -222,7 +222,7 @@ Configure(options =>
`ISettingEncryptionService` 用于在设置定义的 `isencryption` 属性设置为 `true` 时加密/解密设置值.
-你可以在依赖项入系统中替换此服务,自定义实现加密/解密过程. 默认实现 `StringEncryptionService` 使用AES算法(参见字符串[加密文档](String-Encryption.md)学习更多).
+你可以在依赖注入系统中替换此服务,自定义实现加密/解密过程. 默认实现 `StringEncryptionService` 使用AES算法(参见字符串[加密文档](String-Encryption.md)学习更多).
## 设置管理模块
diff --git a/docs/zh-Hans/docs-nav.json b/docs/zh-Hans/docs-nav.json
index fa38a203d0..d66d11b3cf 100644
--- a/docs/zh-Hans/docs-nav.json
+++ b/docs/zh-Hans/docs-nav.json
@@ -262,6 +262,10 @@
"text": "种子数据",
"path": "Data-Seeding.md"
},
+ {
+ "text": "分布式锁",
+ "path": "Distributed-Locking.md"
+ },
{
"text": "虚拟文件系统",
"path": "Virtual-File-System.md"
@@ -405,14 +409,16 @@
"path": "Entities.md"
},
{
- "text": "值对象"
+ "text": "值对象",
+ "path": "Value-Objects.md"
},
{
"text": "仓储",
"path": "Repositories.md"
},
{
- "text": "领域服务"
+ "text": "领域服务",
+ "path": "Domain-Services.md"
},
{
"text": "规约",
@@ -694,6 +700,16 @@
"text": "测试",
"path": "Testing.md"
},
+ {
+ "text": "部署",
+ "path": "Deployment/Index.md",
+ "items": [
+ {
+ "text": "部署到群集环境",
+ "path": "Deployment/Clustered-Environment.md"
+ }
+ ]
+ },
{
"text": "示例",
"items": [
@@ -794,7 +810,13 @@
"items": [
{
"text": "CLI",
- "path": "CLI.md"
+ "path": "CLI.md",
+ "items": [
+ {
+ "text": "新命令示例",
+ "path": "CLI-New-Command-Samples.md"
+ }
+ ]
},
{
"text": "API文档",
diff --git a/docs/zh-Hans/images/deployment-clustered.png b/docs/zh-Hans/images/deployment-clustered.png
new file mode 100644
index 0000000000..74177482c5
Binary files /dev/null and b/docs/zh-Hans/images/deployment-clustered.png differ
diff --git a/docs/zh-Hans/images/deployment-single-instance.png b/docs/zh-Hans/images/deployment-single-instance.png
new file mode 100644
index 0000000000..8c3f8719b2
Binary files /dev/null and b/docs/zh-Hans/images/deployment-single-instance.png differ
diff --git a/docs/zh-Hans/images/email-settings.png b/docs/zh-Hans/images/email-settings.png
new file mode 100644
index 0000000000..6aa77da312
Binary files /dev/null and b/docs/zh-Hans/images/email-settings.png differ
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs
index 92bfc9ddb3..749f1fc935 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs
@@ -113,7 +113,7 @@ public class AbpInputTagHelperService : AbpTagHelperService
protected virtual TagHelper GetInputTagHelper(TagHelperContext context, TagHelperOutput output)
{
- if (TagHelper.AspFor.ModelExplorer.GetAttribute
diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/CreateMigrationAndRunMigratorCommand.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/CreateMigrationAndRunMigratorCommand.cs
index 6519ea70f9..05abd4940c 100644
--- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/CreateMigrationAndRunMigratorCommand.cs
+++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/CreateMigrationAndRunMigratorCommand.cs
@@ -5,6 +5,7 @@ using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Volo.Abp.Cli.Args;
+using Volo.Abp.Cli.Commands.Services;
using Volo.Abp.Cli.Utils;
using Volo.Abp.DependencyInjection;
@@ -12,14 +13,18 @@ namespace Volo.Abp.Cli.Commands;
public class CreateMigrationAndRunMigratorCommand : IConsoleCommand, ITransientDependency
{
+ private readonly InitialMigrationCreator _initialMigrationCreator;
public const string Name = "create-migration-and-run-migrator";
public ICmdHelper CmdHelper { get; }
+ public DotnetEfToolManager DotnetEfToolManager { get; }
public ILogger Logger { get; set; }
- public CreateMigrationAndRunMigratorCommand(ICmdHelper cmdHelper)
+ public CreateMigrationAndRunMigratorCommand(ICmdHelper cmdHelper, InitialMigrationCreator initialMigrationCreator, DotnetEfToolManager dotnetEfToolManager)
{
+ _initialMigrationCreator = initialMigrationCreator;
CmdHelper = cmdHelper;
+ DotnetEfToolManager = dotnetEfToolManager;
Logger = NullLogger.Instance;
}
@@ -39,110 +44,31 @@ public class CreateMigrationAndRunMigratorCommand : IConsoleCommand, ITransientD
throw new Exception("DbMigrator is not found!");
}
- if (!IsDotNetEfToolInstalled())
- {
- InstallDotnetEfTool();
- }
+ await DotnetEfToolManager.BeSureInstalledAsync();
- var tenantDbContextName = FindTenantDbContextName(dbMigrationsFolder);
- var dbContextName = tenantDbContextName != null ?
- FindDbContextName(dbMigrationsFolder)
- : null;
+ var migrationsCreatedSuccessfully = await _initialMigrationCreator.CreateAsync(commandLineArgs.Target, !nolayers);
- var migrationOutput = AddMigrationAndGetOutput(dbMigrationsFolder, dbContextName, "Migrations");
- var tenantMigrationOutput = tenantDbContextName != null ?
- AddMigrationAndGetOutput(dbMigrationsFolder, tenantDbContextName, "TenantMigrations")
- : null;
-
- if (CheckMigrationOutput(migrationOutput) && CheckMigrationOutput(tenantMigrationOutput))
+ if (migrationsCreatedSuccessfully)
{
if (nolayers)
{
- // Migration added successfully
- CmdHelper.RunCmd("cd \"" + Path.GetDirectoryName(Path.Combine(dbMigrationsFolder, "MyCompanyName.MyProjectName")) + "\" && dotnet run --migrate-database");
+ CmdHelper.RunCmd("dotnet run --migrate-database", Path.GetDirectoryName(Path.Combine(dbMigrationsFolder, "MyCompanyName.MyProjectName")));
}
else
{
- // Migration added successfully
- CmdHelper.RunCmd("cd \"" + Path.GetDirectoryName(dbMigratorProjectPath) + "\" && dotnet run");
+ CmdHelper.RunCmd("dotnet run", Path.GetDirectoryName(dbMigratorProjectPath));
}
await Task.CompletedTask;
}
else
{
- var exceptionMsg = "Migrations failed! A migration command didn't run successfully:" +
- Environment.NewLine +
- Environment.NewLine + migrationOutput +
- Environment.NewLine +
- Environment.NewLine + tenantMigrationOutput;
+ var exceptionMsg = "Migrations failed! A migration command didn't run successfully.";
Logger.LogError(exceptionMsg);
throw new Exception(exceptionMsg);
}
}
-
- private string FindTenantDbContextName(string dbMigrationsFolder)
- {
- var tenantDbContext = Directory.GetFiles(dbMigrationsFolder, "*TenantMigrationsDbContext.cs", SearchOption.AllDirectories)
- .FirstOrDefault() ??
- Directory.GetFiles(dbMigrationsFolder, "*TenantDbContext.cs", SearchOption.AllDirectories)
- .FirstOrDefault();
-
- if (tenantDbContext == null)
- {
- return null;
- }
-
- return Path.GetFileName(tenantDbContext).RemovePostFix(".cs");
- }
-
- private string FindDbContextName(string dbMigrationsFolder)
- {
- var dbContext = Directory.GetFiles(dbMigrationsFolder, "*MigrationsDbContext.cs", SearchOption.AllDirectories)
- .FirstOrDefault(fp => !fp.EndsWith("TenantMigrationsDbContext.cs")) ??
- Directory.GetFiles(dbMigrationsFolder, "*DbContext.cs", SearchOption.AllDirectories)
- .FirstOrDefault(fp => !fp.EndsWith("TenantDbContext.cs"));
-
- if (dbContext == null)
- {
- return null;
- }
-
- return Path.GetFileName(dbContext).RemovePostFix(".cs");
- }
-
- private string AddMigrationAndGetOutput(string dbMigrationsFolder, string dbContext, string outputDirectory)
- {
- var dbContextOption = string.IsNullOrWhiteSpace(dbContext)
- ? string.Empty
- : $"--context {dbContext}";
-
- var addMigrationCmd = $"cd \"{dbMigrationsFolder}\" && " +
- $"dotnet ef migrations add Initial --output-dir {outputDirectory} {dbContextOption}";
-
- return CmdHelper.RunCmdAndGetOutput(addMigrationCmd, out int exitCode);
- }
-
- private bool IsDotNetEfToolInstalled()
- {
- var output = CmdHelper.RunCmdAndGetOutput("dotnet tool list -g", out int exitCode);
- return output.Contains("dotnet-ef");
- }
-
- private static bool CheckMigrationOutput(string output)
- {
- return output == null || (output.Contains("Done.") &&
- output.Contains("To undo this action") &&
- output.Contains("ef migrations remove"));
- }
-
- private void InstallDotnetEfTool()
- {
- Logger.LogInformation("Installing dotnet-ef tool...");
- CmdHelper.RunCmd("dotnet tool install --global dotnet-ef");
- Logger.LogInformation("dotnet-ef tool is installed.");
- }
-
+
private static string GetDbMigratorProjectPath(string dbMigrationsFolderPath)
{
var srcFolder = Directory.GetParent(dbMigrationsFolderPath);
diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs
index 526ae77363..2974e01fd4 100644
--- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs
+++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs
@@ -32,8 +32,9 @@ public class NewCommand : ProjectCreationCommandBase, IConsoleCommand, ITransien
SolutionPackageVersionFinder solutionPackageVersionFinder,
ICmdHelper cmdHelper,
IInstallLibsService installLibsService,
- AngularPwaSupportAdder angularPwaSupportAdder)
- : base(connectionStringProvider, solutionPackageVersionFinder, cmdHelper, installLibsService, angularPwaSupportAdder)
+ AngularPwaSupportAdder angularPwaSupportAdder,
+ InitialMigrationCreator ınitialMigrationCreator)
+ : base(connectionStringProvider, solutionPackageVersionFinder, cmdHelper, installLibsService, angularPwaSupportAdder, ınitialMigrationCreator)
{
TemplateProjectBuilder = templateProjectBuilder;
TemplateInfoProvider = templateInfoProvider;
@@ -79,6 +80,7 @@ public class NewCommand : ProjectCreationCommandBase, IConsoleCommand, ITransien
Logger.LogInformation($"'{projectName}' has been successfully created to '{projectArgs.OutputFolder}'");
RunGraphBuildForMicroserviceServiceTemplate(projectArgs);
+ await CreateInitialMigrationsAsync(projectArgs);
await RunInstallLibsForWebTemplateAsync(projectArgs);
ConfigurePwaSupportForAngular(projectArgs);
diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/ProjectCreationCommandBase.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/ProjectCreationCommandBase.cs
index 6e280d7dc3..40d902fb0e 100644
--- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/ProjectCreationCommandBase.cs
+++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/ProjectCreationCommandBase.cs
@@ -6,6 +6,7 @@ using ICSharpCode.SharpZipLib.Core;
using ICSharpCode.SharpZipLib.Zip;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
+using NUglify.Helpers;
using Volo.Abp.Cli.ProjectModification;
using Volo.Abp.Cli.Args;
using Volo.Abp.Cli.Commands.Services;
@@ -26,6 +27,7 @@ public abstract class ProjectCreationCommandBase
public ICmdHelper CmdHelper { get; }
public IInstallLibsService InstallLibsService { get; }
public AngularPwaSupportAdder AngularPwaSupportAdder { get; }
+ public InitialMigrationCreator InitialMigrationCreator { get; }
public ILogger Logger { get; set; }
public ProjectCreationCommandBase(
@@ -33,13 +35,15 @@ public abstract class ProjectCreationCommandBase
SolutionPackageVersionFinder solutionPackageVersionFinder,
ICmdHelper cmdHelper,
IInstallLibsService installLibsService,
- AngularPwaSupportAdder angularPwaSupportAdder)
+ AngularPwaSupportAdder angularPwaSupportAdder,
+ InitialMigrationCreator ınitialMigrationCreator)
{
ConnectionStringProvider = connectionStringProvider;
SolutionPackageVersionFinder = solutionPackageVersionFinder;
CmdHelper = cmdHelper;
InstallLibsService = installLibsService;
AngularPwaSupportAdder = angularPwaSupportAdder;
+ InitialMigrationCreator = ınitialMigrationCreator;
Logger = NullLogger.Instance;
}
@@ -337,6 +341,41 @@ public abstract class ProjectCreationCommandBase
}
}
+ protected async Task CreateInitialMigrationsAsync(ProjectBuildArgs projectArgs)
+ {
+ if (projectArgs.DatabaseProvider == DatabaseProvider.MongoDb)
+ {
+ return;
+ }
+
+ var efCoreProjectPath = string.Empty;
+ bool isLayeredTemplate;
+
+ switch (projectArgs.TemplateName)
+ {
+ case AppTemplate.TemplateName:
+ case AppProTemplate.TemplateName:
+ efCoreProjectPath = Directory.GetFiles(projectArgs.OutputFolder, "*EntityFrameworkCore.csproj", SearchOption.AllDirectories).FirstOrDefault();
+ isLayeredTemplate = true;
+ break;
+ case AppNoLayersTemplate.TemplateName:
+ case AppNoLayersProTemplate.TemplateName:
+ efCoreProjectPath = Directory.GetFiles(projectArgs.OutputFolder, "*.csproj", SearchOption.AllDirectories).FirstOrDefault();
+ isLayeredTemplate = false;
+ break;
+ default:
+ return;
+ }
+
+ if (string.IsNullOrWhiteSpace(efCoreProjectPath))
+ {
+ Logger.LogWarning("Couldn't find the project to create initial migrations!");
+ return;
+ }
+
+ await InitialMigrationCreator.CreateAsync(Path.GetDirectoryName(efCoreProjectPath), isLayeredTemplate);
+ }
+
protected void ConfigurePwaSupportForAngular(ProjectBuildArgs projectArgs)
{
var isAngular = projectArgs.UiFramework == UiFramework.Angular;
diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/Services/DotnetEfToolManager.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/Services/DotnetEfToolManager.cs
new file mode 100644
index 0000000000..cbeb6ee9d4
--- /dev/null
+++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/Services/DotnetEfToolManager.cs
@@ -0,0 +1,43 @@
+using System.Threading.Tasks;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Logging.Abstractions;
+using Volo.Abp.Cli.Utils;
+using Volo.Abp.DependencyInjection;
+
+namespace Volo.Abp.Cli.Commands.Services;
+
+public class DotnetEfToolManager : ISingletonDependency
+{
+ public ICmdHelper CmdHelper { get; }
+ public ILogger Logger { get; set; }
+
+ public DotnetEfToolManager(ICmdHelper cmdHelper)
+ {
+ CmdHelper = cmdHelper;
+
+ Logger = NullLogger.Instance;
+ }
+
+ public async Task BeSureInstalledAsync()
+ {
+ if (IsDotNetEfToolInstalled())
+ {
+ return;
+ }
+
+ InstallDotnetEfTool();
+ }
+
+ private bool IsDotNetEfToolInstalled()
+ {
+ var output = CmdHelper.RunCmdAndGetOutput("dotnet tool list -g");
+ return output.Contains("dotnet-ef");
+ }
+
+ private void InstallDotnetEfTool()
+ {
+ Logger.LogInformation("Installing dotnet-ef tool...");
+ CmdHelper.RunCmd("dotnet tool install --global dotnet-ef");
+ Logger.LogInformation("dotnet-ef tool is installed.");
+ }
+}
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/Services/InitialMigrationCreator.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/Services/InitialMigrationCreator.cs
new file mode 100644
index 0000000000..860fcef60f
--- /dev/null
+++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/Services/InitialMigrationCreator.cs
@@ -0,0 +1,111 @@
+using System;
+using System.IO;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Logging.Abstractions;
+using Volo.Abp.Cli.Utils;
+using Volo.Abp.DependencyInjection;
+
+namespace Volo.Abp.Cli.Commands.Services;
+
+public class InitialMigrationCreator : ITransientDependency
+{
+ public ICmdHelper CmdHelper { get; }
+ public DotnetEfToolManager DotnetEfToolManager { get; }
+ public ILogger Logger { get; set; }
+
+ public InitialMigrationCreator(ICmdHelper cmdHelper, DotnetEfToolManager dotnetEfToolManager)
+ {
+ CmdHelper = cmdHelper;
+ DotnetEfToolManager = dotnetEfToolManager;
+
+ Logger = NullLogger.Instance;
+ }
+
+ public async Task CreateAsync(string targetProjectFolder, bool layeredTemplate = true)
+ {
+ if (targetProjectFolder == null || !Directory.Exists(targetProjectFolder))
+ {
+ Logger.LogError($"This path doesn't exist: {targetProjectFolder}");
+ return false;
+ }
+
+ Logger.LogInformation("Creating initial migrations...");
+
+ await DotnetEfToolManager.BeSureInstalledAsync();
+
+ var tenantDbContextName = FindTenantDbContextName(targetProjectFolder);
+ var dbContextName = tenantDbContextName != null ?
+ FindDbContextName(targetProjectFolder)
+ : null;
+
+ var migrationOutput = AddMigrationAndGetOutput(targetProjectFolder, dbContextName, "Migrations");
+ var tenantMigrationOutput = tenantDbContextName != null ?
+ AddMigrationAndGetOutput(targetProjectFolder, tenantDbContextName, "TenantMigrations")
+ : null;
+
+ var migrationSuccess = CheckMigrationOutput(migrationOutput) && CheckMigrationOutput(tenantMigrationOutput);
+
+ if (migrationSuccess)
+ {
+ Logger.LogInformation("Initial migrations are created.");
+ }
+ else
+ {
+ Logger.LogError("Creating initial migrations process is failed! Details:" + Environment.NewLine
+ + migrationOutput + Environment.NewLine
+ + tenantMigrationOutput + Environment.NewLine);
+ }
+
+ return migrationSuccess;
+ }
+
+ private string FindTenantDbContextName(string projectFolder)
+ {
+ var tenantDbContext = Directory.GetFiles(projectFolder, "*TenantMigrationsDbContext.cs", SearchOption.AllDirectories)
+ .FirstOrDefault() ??
+ Directory.GetFiles(projectFolder, "*TenantDbContext.cs", SearchOption.AllDirectories)
+ .FirstOrDefault();
+
+ if (tenantDbContext == null)
+ {
+ return null;
+ }
+
+ return Path.GetFileName(tenantDbContext).RemovePostFix(".cs");
+ }
+
+ private string FindDbContextName(string projectFolder)
+ {
+ var dbContext = Directory.GetFiles(projectFolder, "*MigrationsDbContext.cs", SearchOption.AllDirectories)
+ .FirstOrDefault(fp => !fp.EndsWith("TenantMigrationsDbContext.cs")) ??
+ Directory.GetFiles(projectFolder, "*DbContext.cs", SearchOption.AllDirectories)
+ .FirstOrDefault(fp => !fp.EndsWith("TenantDbContext.cs"));
+
+ if (dbContext == null)
+ {
+ return null;
+ }
+
+ return Path.GetFileName(dbContext).RemovePostFix(".cs");
+ }
+
+ private string AddMigrationAndGetOutput(string dbMigrationsFolder, string dbContext, string outputDirectory)
+ {
+ var dbContextOption = string.IsNullOrWhiteSpace(dbContext)
+ ? string.Empty
+ : $"--context {dbContext}";
+
+ var addMigrationCmd = $"dotnet ef migrations add Initial --output-dir {outputDirectory} {dbContextOption}";
+
+ return CmdHelper.RunCmdAndGetOutput(addMigrationCmd, out int exitCode, dbMigrationsFolder);
+ }
+
+ private static bool CheckMigrationOutput(string output)
+ {
+ return output == null || (output.Contains("Done.") &&
+ output.Contains("To undo this action") &&
+ output.Contains("ef migrations remove"));
+ }
+}
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/MoveFileStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/MoveFileStep.cs
new file mode 100644
index 0000000000..4c36197f76
--- /dev/null
+++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/MoveFileStep.cs
@@ -0,0 +1,28 @@
+using System.Linq;
+
+namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps;
+
+public class MoveFileStep : ProjectBuildPipelineStep
+{
+ private readonly string _filePath;
+ private readonly string _newPath;
+
+ public MoveFileStep(string filePath, string newPath)
+ {
+ _filePath = filePath;
+ _newPath = newPath;
+ }
+
+ public override void Execute(ProjectBuildContext context)
+ {
+ var fileToMove = context.Files.Find(x => x.Name == _filePath);
+ var newFileExist = context.Files.Any(x => x.Name == _newPath);
+
+ if (fileToMove == null || newFileExist)
+ {
+ return;
+ }
+
+ fileToMove.SetName(_newPath);
+ }
+}
diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveFileStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveFileStep.cs
index 203a927536..8e66d26547 100644
--- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveFileStep.cs
+++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveFileStep.cs
@@ -12,7 +12,7 @@ public class RemoveFileStep : ProjectBuildPipelineStep
public override void Execute(ProjectBuildContext context)
{
- var fileToRemove = context.Files.Find(x => x.Name.EndsWith(_filePath));
+ var fileToRemove = context.Files.Find(x => x.Name == _filePath);;
if (fileToRemove != null)
{
context.Files.Remove(fileToRemove);
diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/TemplateCodeDeleteStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/TemplateCodeDeleteStep.cs
index 8115182b04..c7a30ab2e4 100644
--- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/TemplateCodeDeleteStep.cs
+++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/TemplateCodeDeleteStep.cs
@@ -13,6 +13,8 @@ public class TemplateCodeDeleteStep : ProjectBuildPipelineStep
file.Name.EndsWith(".cshtml") ||
file.Name.EndsWith(".json") ||
file.Name.EndsWith(".gitignore") ||
+ file.Name.EndsWith(".yml") ||
+ file.Name.EndsWith(".ps1") ||
file.Name.EndsWith(".html"))
{
file.RemoveTemplateCode(context.Symbols);
diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/App/AppNoLayersTemplateBase.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/App/AppNoLayersTemplateBase.cs
index 312181e721..e151646988 100644
--- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/App/AppNoLayersTemplateBase.cs
+++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/App/AppNoLayersTemplateBase.cs
@@ -81,19 +81,12 @@ public abstract class AppNoLayersTemplateBase : AppTemplateBase
break;
}
- //ConfigureTenantSchema(context, steps);
- //SwitchDatabaseProvider(context, steps);
- //DeleteUnrelatedProjects(context, steps);
steps.Add(new RemoveFolderStep("/aspnet-core/MyCompanyName.MyProjectName/Migrations"));
- //RemoveMigrations(context, steps);
- //ConfigureTieredArchitecture(context, steps);
- //ConfigurePublicWebSite(context, steps);
- //RemoveUnnecessaryPorts(context, steps);
RandomizeSslPorts(context, steps);
RandomizeStringEncryption(context, steps);
UpdateNuGetConfig(context, steps);
ChangeConnectionString(context, steps);
- //CleanupFolderHierarchy(context, steps);
+ ConfigureDockerFiles(context, steps);
if (context.BuildArgs.UiFramework != UiFramework.Angular)
{
@@ -102,4 +95,35 @@ public abstract class AppNoLayersTemplateBase : AppTemplateBase
return steps;
}
+
+ protected void ConfigureDockerFiles(ProjectBuildContext context, List steps)
+ {
+ switch (context.BuildArgs.UiFramework)
+ {
+ case UiFramework.None:
+ steps.Add(new RemoveFileStep("/aspnet-core/etc/docker/docker-compose.Blazor.Server.yml"));
+ steps.Add(new RemoveFileStep("/aspnet-core/etc/docker/docker-compose.Mvc.yml"));
+ steps.Add(new RemoveFileStep("/aspnet-core/etc/docker/dynamic-env.json"));
+ steps.Add(new MoveFileStep("/aspnet-core/etc/docker/docker-compose.Host.yml", "/aspnet-core/etc/docker/docker-compose.yml"));
+ break;
+ case UiFramework.Angular:
+ steps.Add(new RemoveFileStep("/aspnet-core/etc/docker/docker-compose.Blazor.Server.yml"));
+ steps.Add(new RemoveFileStep("/aspnet-core/etc/docker/docker-compose.Mvc.yml"));
+ steps.Add(new MoveFileStep("/aspnet-core/etc/docker/docker-compose.Host.yml", "/aspnet-core/etc/docker/docker-compose.yml"));
+ break;
+ case UiFramework.BlazorServer:
+ steps.Add(new RemoveFileStep("/aspnet-core/etc/docker/docker-compose.Host.yml"));
+ steps.Add(new RemoveFileStep("/aspnet-core/etc/docker/docker-compose.Mvc.yml"));
+ steps.Add(new RemoveFileStep("/aspnet-core/etc/docker/dynamic-env.json"));
+ steps.Add(new MoveFileStep("/aspnet-core/etc/docker/docker-compose.Blazor.Server.yml", "/aspnet-core/etc/docker/docker-compose.yml"));
+ break;
+ case UiFramework.NotSpecified:
+ case UiFramework.Mvc:
+ steps.Add(new RemoveFileStep("/aspnet-core/etc/docker/docker-compose.Blazor.Server.yml"));
+ steps.Add(new RemoveFileStep("/aspnet-core/etc/docker/docker-compose.Host.yml"));
+ steps.Add(new RemoveFileStep("/aspnet-core/etc/docker/dynamic-env.json"));
+ steps.Add(new MoveFileStep("/aspnet-core/etc/docker/docker-compose.Mvc.yml", "/aspnet-core/etc/docker/docker-compose.yml"));
+ break;
+ }
+ }
}
diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/App/AppTemplateBase.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/App/AppTemplateBase.cs
index 3dd6ece476..6a0b532135 100644
--- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/App/AppTemplateBase.cs
+++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/App/AppTemplateBase.cs
@@ -466,4 +466,36 @@ public abstract class AppTemplateBase : TemplateInfo
steps.Add(new MoveFolderStep("/aspnet-core/", "/"));
}
}
+
+ private void ConfigureDockerFiles(ProjectBuildContext context, List steps)
+ {
+ switch (context.BuildArgs.UiFramework)
+ {
+ case UiFramework.None:
+ steps.Add(new RemoveFileStep("/aspnet-core/etc/docker/docker-compose.Blazor.yml"));
+ steps.Add(new RemoveFileStep("/aspnet-core/etc/docker/docker-compose.Mvc.yml"));
+ steps.Add(new RemoveFileStep("/aspnet-core/etc/docker/dynamic-env.json"));
+ steps.Add(new MoveFileStep("/aspnet-core/etc/docker/docker-compose.Angular.yml", "/aspnet-core/etc/docker/docker-compose.yml"));
+ break;
+ case UiFramework.Angular:
+ steps.Add(new RemoveFileStep("/aspnet-core/etc/docker/docker-compose.Blazor.yml"));
+ steps.Add(new RemoveFileStep("/aspnet-core/etc/docker/docker-compose.Mvc.yml"));
+ steps.Add(new MoveFileStep("/aspnet-core/etc/docker/docker-compose.Angular.yml", "/aspnet-core/etc/docker/docker-compose.yml"));
+ break;
+ case UiFramework.Blazor:
+ case UiFramework.BlazorServer:
+ steps.Add(new RemoveFileStep("/aspnet-core/etc/docker/docker-compose.Angular.yml"));
+ steps.Add(new RemoveFileStep("/aspnet-core/etc/docker/docker-compose.Mvc.yml"));
+ steps.Add(new RemoveFileStep("/aspnet-core/etc/docker/dynamic-env.json"));
+ steps.Add(new MoveFileStep("/aspnet-core/etc/docker/docker-compose.Blazor.yml", "/aspnet-core/etc/docker/docker-compose.yml"));
+ break;
+ case UiFramework.NotSpecified:
+ case UiFramework.Mvc:
+ steps.Add(new RemoveFileStep("/aspnet-core/etc/docker/docker-compose.Blazor.yml"));
+ steps.Add(new RemoveFileStep("/aspnet-core/etc/docker/docker-compose.Angular.yml"));
+ steps.Add(new RemoveFileStep("/aspnet-core/etc/docker/dynamic-env.json"));
+ steps.Add(new MoveFileStep("/aspnet-core/etc/docker/docker-compose.Mvc.yml", "/aspnet-core/etc/docker/docker-compose.yml"));
+ break;
+ }
+ }
}
diff --git a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ExtensibleAuditedEntityDto.cs b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ExtensibleAuditedEntityDto.cs
index aa03b8da1d..775f629c3c 100644
--- a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ExtensibleAuditedEntityDto.cs
+++ b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ExtensibleAuditedEntityDto.cs
@@ -1,5 +1,6 @@
using System;
using Volo.Abp.Auditing;
+using Volo.Abp.Data;
namespace Volo.Abp.Application.Dtos;
@@ -16,6 +17,18 @@ public abstract class ExtensibleAuditedEntityDto : ExtensibleCreati
///
public Guid? LastModifierId { get; set; }
+
+ protected ExtensibleAuditedEntityDto()
+ : this(true)
+ {
+
+ }
+
+ protected ExtensibleAuditedEntityDto(bool setDefaultsForExtraProperties)
+ : base(setDefaultsForExtraProperties)
+ {
+
+ }
}
///
@@ -30,4 +43,16 @@ public abstract class ExtensibleAuditedEntityDto : ExtensibleCreationAuditedEnti
///
public Guid? LastModifierId { get; set; }
+
+ protected ExtensibleAuditedEntityDto()
+ : this(true)
+ {
+
+ }
+
+ protected ExtensibleAuditedEntityDto(bool setDefaultsForExtraProperties)
+ : base(setDefaultsForExtraProperties)
+ {
+
+ }
}
diff --git a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ExtensibleAuditedEntityWithUserDto.cs b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ExtensibleAuditedEntityWithUserDto.cs
index 05193efc4a..5f6fd28628 100644
--- a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ExtensibleAuditedEntityWithUserDto.cs
+++ b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ExtensibleAuditedEntityWithUserDto.cs
@@ -1,5 +1,6 @@
using System;
using Volo.Abp.Auditing;
+using Volo.Abp.Data;
namespace Volo.Abp.Application.Dtos;
@@ -18,6 +19,18 @@ public abstract class ExtensibleAuditedEntityWithUserDto
///
public TUserDto LastModifier { get; set; }
+
+ protected ExtensibleAuditedEntityWithUserDto()
+ : this(true)
+ {
+
+ }
+
+ protected ExtensibleAuditedEntityWithUserDto(bool setDefaultsForExtraProperties)
+ : base(setDefaultsForExtraProperties)
+ {
+
+ }
}
///
@@ -35,4 +48,16 @@ public abstract class ExtensibleAuditedEntityWithUserDto : ExtensibleA
///
public TUserDto LastModifier { get; set; }
+
+ protected ExtensibleAuditedEntityWithUserDto()
+ : this(true)
+ {
+
+ }
+
+ protected ExtensibleAuditedEntityWithUserDto(bool setDefaultsForExtraProperties)
+ : base(setDefaultsForExtraProperties)
+ {
+
+ }
}
diff --git a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ExtensibleCreationAuditedEntityDto.cs b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ExtensibleCreationAuditedEntityDto.cs
index ba3bec655d..9230759052 100644
--- a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ExtensibleCreationAuditedEntityDto.cs
+++ b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ExtensibleCreationAuditedEntityDto.cs
@@ -1,5 +1,6 @@
using System;
using Volo.Abp.Auditing;
+using Volo.Abp.Data;
namespace Volo.Abp.Application.Dtos;
@@ -16,6 +17,18 @@ public abstract class ExtensibleCreationAuditedEntityDto : Extensib
///
public Guid? CreatorId { get; set; }
+
+ protected ExtensibleCreationAuditedEntityDto()
+ : this(true)
+ {
+
+ }
+
+ protected ExtensibleCreationAuditedEntityDto(bool setDefaultsForExtraProperties)
+ : base(setDefaultsForExtraProperties)
+ {
+
+ }
}
///
@@ -30,4 +43,16 @@ public abstract class ExtensibleCreationAuditedEntityDto : ExtensibleEntityDto,
///
public Guid? CreatorId { get; set; }
+
+ protected ExtensibleCreationAuditedEntityDto()
+ : this(true)
+ {
+
+ }
+
+ protected ExtensibleCreationAuditedEntityDto(bool setDefaultsForExtraProperties)
+ : base(setDefaultsForExtraProperties)
+ {
+
+ }
}
diff --git a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ExtensibleCreationAuditedEntityWithUserDto.cs b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ExtensibleCreationAuditedEntityWithUserDto.cs
index e6a31b4a68..3ea1be97ab 100644
--- a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ExtensibleCreationAuditedEntityWithUserDto.cs
+++ b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ExtensibleCreationAuditedEntityWithUserDto.cs
@@ -1,5 +1,6 @@
using System;
using Volo.Abp.Auditing;
+using Volo.Abp.Data;
namespace Volo.Abp.Application.Dtos;
@@ -14,6 +15,18 @@ namespace Volo.Abp.Application.Dtos;
public abstract class ExtensibleCreationAuditedEntityWithUserDto : ExtensibleCreationAuditedEntityDto, ICreationAuditedObject
{
public TUserDto Creator { get; set; }
+
+ protected ExtensibleCreationAuditedEntityWithUserDto()
+ : this(true)
+ {
+
+ }
+
+ protected ExtensibleCreationAuditedEntityWithUserDto(bool setDefaultsForExtraProperties)
+ : base(setDefaultsForExtraProperties)
+ {
+
+ }
}
///
@@ -27,4 +40,16 @@ public abstract class ExtensibleCreationAuditedEntityWithUserDto : Ext
ICreationAuditedObject
{
public TUserDto Creator { get; set; }
+
+ protected ExtensibleCreationAuditedEntityWithUserDto()
+ : this(true)
+ {
+
+ }
+
+ protected ExtensibleCreationAuditedEntityWithUserDto(bool setDefaultsForExtraProperties)
+ : base(setDefaultsForExtraProperties)
+ {
+
+ }
}
diff --git a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ExtensibleEntityDto.cs b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ExtensibleEntityDto.cs
index 788825e842..1af46a3287 100644
--- a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ExtensibleEntityDto.cs
+++ b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ExtensibleEntityDto.cs
@@ -11,6 +11,18 @@ public abstract class ExtensibleEntityDto : ExtensibleObject, IEntityDto
public TKey Id { get; set; }
+ protected ExtensibleEntityDto()
+ : this(true)
+ {
+
+ }
+
+ protected ExtensibleEntityDto(bool setDefaultsForExtraProperties)
+ : base(setDefaultsForExtraProperties)
+ {
+
+ }
+
public override string ToString()
{
return $"[DTO: {GetType().Name}] Id = {Id}";
@@ -20,6 +32,18 @@ public abstract class ExtensibleEntityDto : ExtensibleObject, IEntityDto : ExtensibleAu
///
public DateTime? DeletionTime { get; set; }
+
+ protected ExtensibleFullAuditedEntityDto()
+ : this(true)
+ {
+
+ }
+
+ protected ExtensibleFullAuditedEntityDto(bool setDefaultsForExtraProperties)
+ : base(setDefaultsForExtraProperties)
+ {
+
+ }
}
///
@@ -36,4 +49,16 @@ public abstract class ExtensibleFullAuditedEntityDto : ExtensibleAuditedEntityDt
///
public DateTime? DeletionTime { get; set; }
+
+ protected ExtensibleFullAuditedEntityDto()
+ : this(true)
+ {
+
+ }
+
+ protected ExtensibleFullAuditedEntityDto(bool setDefaultsForExtraProperties)
+ : base(setDefaultsForExtraProperties)
+ {
+
+ }
}
diff --git a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ExtensibleFullAuditedEntityWithUserDto.cs b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ExtensibleFullAuditedEntityWithUserDto.cs
index bd1ee89bcb..018a84cd7a 100644
--- a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ExtensibleFullAuditedEntityWithUserDto.cs
+++ b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Dtos/ExtensibleFullAuditedEntityWithUserDto.cs
@@ -1,5 +1,6 @@
using System;
using Volo.Abp.Auditing;
+using Volo.Abp.Data;
namespace Volo.Abp.Application.Dtos;
@@ -21,6 +22,18 @@ public abstract class ExtensibleFullAuditedEntityWithUserDto
public TUserDto Deleter { get; set; }
+
+ protected ExtensibleFullAuditedEntityWithUserDto()
+ : this(true)
+ {
+
+ }
+
+ protected ExtensibleFullAuditedEntityWithUserDto(bool setDefaultsForExtraProperties)
+ : base(setDefaultsForExtraProperties)
+ {
+
+ }
}
///
@@ -41,4 +54,16 @@ public abstract class ExtensibleFullAuditedEntityWithUserDto : Extensi
///
public TUserDto Deleter { get; set; }
+
+ protected ExtensibleFullAuditedEntityWithUserDto()
+ : this(true)
+ {
+
+ }
+
+ protected ExtensibleFullAuditedEntityWithUserDto(bool setDefaultsForExtraProperties)
+ : base(setDefaultsForExtraProperties)
+ {
+
+ }
}
diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryExtensions.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryExtensions.cs
index 2b4dd70e62..379203f46a 100644
--- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryExtensions.cs
+++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryExtensions.cs
@@ -15,7 +15,7 @@ namespace Volo.Abp.Domain.Repositories;
public static class RepositoryExtensions
{
- public static async Task EnsureCollectionLoadedAsync(
+ public async static Task EnsureCollectionLoadedAsync(
this IBasicRepository repository,
TEntity entity,
Expression>> propertyExpression,
@@ -31,7 +31,7 @@ public static class RepositoryExtensions
}
}
- public static async Task EnsurePropertyLoadedAsync(
+ public async static Task EnsurePropertyLoadedAsync(
this IBasicRepository repository,
TEntity entity,
Expression> propertyExpression,
@@ -47,7 +47,33 @@ public static class RepositoryExtensions
}
}
- public static async Task HardDeleteAsync(
+ public async static Task EnsureExistsAsync(
+ this IRepository repository,
+ TKey id,
+ CancellationToken cancellationToken = default
+ )
+ where TEntity : class, IEntity
+ {
+ if (!await repository.AnyAsync(x => x.Id.Equals(id), cancellationToken))
+ {
+ throw new EntityNotFoundException(typeof(TEntity), id);
+ }
+ }
+
+ public async static Task EnsureExistsAsync(
+ this IRepository repository,
+ Expression> expression,
+ CancellationToken cancellationToken = default
+ )
+ where TEntity : class, IEntity
+ {
+ if (!await repository.AnyAsync(expression, cancellationToken))
+ {
+ throw new EntityNotFoundException(typeof(TEntity));
+ }
+ }
+
+ public async static Task HardDeleteAsync(
this IRepository repository,
Expression> predicate,
bool autoSave = false,
@@ -71,7 +97,7 @@ public static class RepositoryExtensions
}
}
- public static async Task HardDeleteAsync(
+ public async static Task HardDeleteAsync(
this IBasicRepository repository,
IEnumerable entities,
bool autoSave = false,
@@ -95,7 +121,7 @@ public static class RepositoryExtensions
}
}
- public static async Task HardDeleteAsync(
+ public async static Task HardDeleteAsync(
this IBasicRepository repository,
TEntity entity,
bool autoSave = false,
@@ -139,7 +165,7 @@ public static class RepositoryExtensions
return unitOfWorkManagerAccessor.UnitOfWorkManager;
}
- private static async Task HardDeleteWithUnitOfWorkAsync(
+ private async static Task HardDeleteWithUnitOfWorkAsync(
IRepository repository,
Expression> predicate,
bool autoSave,
@@ -155,7 +181,7 @@ public static class RepositoryExtensions
}
}
- private static async Task HardDeleteWithUnitOfWorkAsync(
+ private async static Task HardDeleteWithUnitOfWorkAsync(
IBasicRepository repository,
IEnumerable entities,
bool autoSave,
@@ -173,7 +199,7 @@ public static class RepositoryExtensions
await repository.DeleteManyAsync(entities, autoSave, cancellationToken);
}
- private static async Task HardDeleteWithUnitOfWorkAsync(
+ private async static Task HardDeleteWithUnitOfWorkAsync(
IBasicRepository repository,
TEntity entity,
bool autoSave,
diff --git a/framework/src/Volo.Abp.EntityFrameworkCore.PostgreSql/Volo/Abp/EntityFrameworkCore/DistributedEvents/PostgreSqlDbContextEventOutbox.cs b/framework/src/Volo.Abp.EntityFrameworkCore.PostgreSql/Volo/Abp/EntityFrameworkCore/DistributedEvents/PostgreSqlDbContextEventOutbox.cs
index e5f2e0c4b6..7c5ef12fa7 100644
--- a/framework/src/Volo.Abp.EntityFrameworkCore.PostgreSql/Volo/Abp/EntityFrameworkCore/DistributedEvents/PostgreSqlDbContextEventOutbox.cs
+++ b/framework/src/Volo.Abp.EntityFrameworkCore.PostgreSql/Volo/Abp/EntityFrameworkCore/DistributedEvents/PostgreSqlDbContextEventOutbox.cs
@@ -13,7 +13,7 @@ public class PostgreSqlDbContextEventOutbox : DbContextEventOutbox : IDbContextEventOutbox ids)
+ {
+ var dbContext = (IHasEventOutbox)await DbContextProvider.GetDbContextAsync();
+ var outgoingEvents = await dbContext.OutgoingEvents.Where(x => ids.Contains(x.Id)).ToListAsync();
+ if (outgoingEvents.Any())
+ {
+ dbContext.RemoveRange(outgoingEvents);
+ }
+ }
}
diff --git a/framework/src/Volo.Abp.EventBus.Azure/Volo/Abp/EventBus/Azure/AzureDistributedEventBus.cs b/framework/src/Volo.Abp.EventBus.Azure/Volo/Abp/EventBus/Azure/AzureDistributedEventBus.cs
index d8a3d1341a..86500cf434 100644
--- a/framework/src/Volo.Abp.EventBus.Azure/Volo/Abp/EventBus/Azure/AzureDistributedEventBus.cs
+++ b/framework/src/Volo.Abp.EventBus.Azure/Volo/Abp/EventBus/Azure/AzureDistributedEventBus.cs
@@ -71,6 +71,10 @@ public class AzureDistributedEventBus : DistributedEventBusBase, ISingletonDepen
private async Task ProcessEventAsync(ServiceBusReceivedMessage message)
{
var eventName = message.Subject;
+ if (eventName == null)
+ {
+ return;
+ }
var eventType = _eventTypes.GetOrDefault(eventName);
if (eventType == null)
{
@@ -87,12 +91,33 @@ public class AzureDistributedEventBus : DistributedEventBusBase, ISingletonDepen
await TriggerHandlersAsync(eventType, eventData);
}
- public override async Task PublishFromOutboxAsync(OutgoingEventInfo outgoingEvent, OutboxConfig outboxConfig)
+ public async override Task PublishFromOutboxAsync(OutgoingEventInfo outgoingEvent, OutboxConfig outboxConfig)
{
await PublishAsync(outgoingEvent.EventName, outgoingEvent.EventData, outgoingEvent.Id);
}
- public override async Task ProcessFromInboxAsync(IncomingEventInfo incomingEvent, InboxConfig inboxConfig)
+ public async override Task PublishManyFromOutboxAsync(IEnumerable outgoingEvents, OutboxConfig outboxConfig)
+ {
+ var outgoingEventArray = outgoingEvents.ToArray();
+
+ var publisher = await _publisherPool.GetAsync(
+ _options.TopicName,
+ _options.ConnectionName);
+
+ using var messageBatch = await publisher.CreateMessageBatchAsync();
+
+ foreach (var outgoingEvent in outgoingEventArray)
+ {
+ if (!messageBatch.TryAddMessage(new ServiceBusMessage(outgoingEvent.EventData) { Subject = outgoingEvent.EventName }))
+ {
+ throw new AbpException("The message is too large to fit in the batch. Set AbpEventBusBoxesOptions.OutboxWaitingEventMaxCount to reduce the number");
+ }
+ }
+
+ await publisher.SendMessagesAsync(messageBatch);
+ }
+
+ public async override Task ProcessFromInboxAsync(IncomingEventInfo incomingEvent, InboxConfig inboxConfig)
{
var eventType = _eventTypes.GetOrDefault(incomingEvent.EventName);
if (eventType == null)
@@ -180,7 +205,7 @@ public class AzureDistributedEventBus : DistributedEventBusBase, ISingletonDepen
.Locking(factories => factories.Clear());
}
- protected override async Task PublishToEventBusAsync(Type eventType, object eventData)
+ protected async override Task PublishToEventBusAsync(Type eventType, object eventData)
{
await PublishAsync(EventNameAttribute.GetNameOrDefault(eventType), eventData);
}
diff --git a/framework/src/Volo.Abp.EventBus.Kafka/Volo/Abp/EventBus/Kafka/KafkaDistributedEventBus.cs b/framework/src/Volo.Abp.EventBus.Kafka/Volo/Abp/EventBus/Kafka/KafkaDistributedEventBus.cs
index a19b01311c..4dba728c51 100644
--- a/framework/src/Volo.Abp.EventBus.Kafka/Volo/Abp/EventBus/Kafka/KafkaDistributedEventBus.cs
+++ b/framework/src/Volo.Abp.EventBus.Kafka/Volo/Abp/EventBus/Kafka/KafkaDistributedEventBus.cs
@@ -79,12 +79,7 @@ public class KafkaDistributedEventBus : DistributedEventBusBase, ISingletonDepen
return;
}
- string messageId = null;
-
- if (message.Headers.TryGetLastBytes("messageId", out var messageIdBytes))
- {
- messageId = System.Text.Encoding.UTF8.GetString(messageIdBytes);
- }
+ var messageId = message.GetMessageId();
if (await AddToInboxAsync(messageId, eventName, eventType, message.Value))
{
@@ -164,7 +159,7 @@ public class KafkaDistributedEventBus : DistributedEventBusBase, ISingletonDepen
GetOrCreateHandlerFactories(eventType).Locking(factories => factories.Clear());
}
- protected override async Task PublishToEventBusAsync(Type eventType, object eventData)
+ protected async override Task PublishToEventBusAsync(Type eventType, object eventData)
{
await PublishAsync(
eventType,
@@ -198,7 +193,43 @@ public class KafkaDistributedEventBus : DistributedEventBusBase, ISingletonDepen
);
}
- public override async Task ProcessFromInboxAsync(
+ public override Task PublishManyFromOutboxAsync(IEnumerable outgoingEvents, OutboxConfig outboxConfig)
+ {
+ var producer = ProducerPool.Get();
+ var outgoingEventArray = outgoingEvents.ToArray();
+ producer.BeginTransaction();
+ try
+ {
+ foreach (var outgoingEvent in outgoingEventArray)
+ {
+ var messageId = outgoingEvent.Id.ToString("N");
+ var headers = new Headers
+ {
+ { "messageId", System.Text.Encoding.UTF8.GetBytes(messageId)}
+ };
+
+ producer.Produce(
+ AbpKafkaEventBusOptions.TopicName,
+ new Message
+ {
+ Key = outgoingEvent.EventName,
+ Value = outgoingEvent.EventData,
+ Headers = headers
+ });
+ }
+
+ producer.CommitTransaction();
+ }
+ catch (Exception e)
+ {
+ producer.AbortTransaction();
+ throw;
+ }
+
+ return Task.CompletedTask;
+ }
+
+ public async override Task ProcessFromInboxAsync(
IncomingEventInfo incomingEvent,
InboxConfig inboxConfig)
{
@@ -241,13 +272,29 @@ public class KafkaDistributedEventBus : DistributedEventBusBase, ISingletonDepen
return PublishAsync(topicName, eventName, body, headers, headersArguments);
}
- private async Task PublishAsync(string topicName, string eventName, byte[] body, Headers headers, Dictionary headersArguments)
+ private Task> PublishAsync(
+ string topicName,
+ string eventName,
+ byte[] body,
+ Headers headers,
+ Dictionary headersArguments)
{
var producer = ProducerPool.Get(AbpKafkaEventBusOptions.ConnectionName);
+ return PublishAsync(producer, topicName, eventName, body, headers, headersArguments);
+ }
+
+ private Task> PublishAsync(
+ IProducer producer,
+ string topicName,
+ string eventName,
+ byte[] body,
+ Headers headers,
+ Dictionary headersArguments)
+ {
SetEventMessageHeaders(headers, headersArguments);
- await producer.ProduceAsync(
+ return producer.ProduceAsync(
topicName,
new Message
{
diff --git a/framework/src/Volo.Abp.EventBus.Kafka/Volo/Abp/EventBus/Kafka/MessageExtensions.cs b/framework/src/Volo.Abp.EventBus.Kafka/Volo/Abp/EventBus/Kafka/MessageExtensions.cs
new file mode 100644
index 0000000000..17a80ec87c
--- /dev/null
+++ b/framework/src/Volo.Abp.EventBus.Kafka/Volo/Abp/EventBus/Kafka/MessageExtensions.cs
@@ -0,0 +1,18 @@
+using Confluent.Kafka;
+
+namespace Volo.Abp.EventBus.Kafka;
+
+public static class MessageExtensions
+{
+ public static string GetMessageId(this Message message)
+ {
+ string messageId = null;
+
+ if (message.Headers.TryGetLastBytes("messageId", out var messageIdBytes))
+ {
+ messageId = System.Text.Encoding.UTF8.GetString(messageIdBytes);
+ }
+
+ return messageId;
+ }
+}
diff --git a/framework/src/Volo.Abp.EventBus.RabbitMQ/Volo/Abp/EventBus/RabbitMq/RabbitMqDistributedEventBus.cs b/framework/src/Volo.Abp.EventBus.RabbitMQ/Volo/Abp/EventBus/RabbitMq/RabbitMqDistributedEventBus.cs
index a2932de52e..c9ec49bc7e 100644
--- a/framework/src/Volo.Abp.EventBus.RabbitMQ/Volo/Abp/EventBus/RabbitMq/RabbitMqDistributedEventBus.cs
+++ b/framework/src/Volo.Abp.EventBus.RabbitMQ/Volo/Abp/EventBus/RabbitMq/RabbitMqDistributedEventBus.cs
@@ -34,6 +34,8 @@ public class RabbitMqDistributedEventBus : DistributedEventBusBase, ISingletonDe
protected IRabbitMqMessageConsumerFactory MessageConsumerFactory { get; }
protected IRabbitMqMessageConsumer Consumer { get; private set; }
+ private bool _exchangeCreated;
+
public RabbitMqDistributedEventBus(
IOptions options,
IConnectionPool connectionPool,
@@ -180,7 +182,7 @@ public class RabbitMqDistributedEventBus : DistributedEventBusBase, ISingletonDe
GetOrCreateHandlerFactories(eventType).Locking(factories => factories.Clear());
}
- protected override async Task PublishToEventBusAsync(Type eventType, object eventData)
+ protected async override Task PublishToEventBusAsync(Type eventType, object eventData)
{
await PublishAsync(eventType, eventData, null);
}
@@ -197,7 +199,30 @@ public class RabbitMqDistributedEventBus : DistributedEventBusBase, ISingletonDe
return PublishAsync(outgoingEvent.EventName, outgoingEvent.EventData, null, eventId: outgoingEvent.Id);
}
- public override async Task ProcessFromInboxAsync(
+ public async override Task PublishManyFromOutboxAsync(
+ IEnumerable outgoingEvents,
+ OutboxConfig outboxConfig)
+ {
+ using (var channel = ConnectionPool.Get(AbpRabbitMqEventBusOptions.ConnectionName).CreateModel())
+ {
+ var outgoingEventArray = outgoingEvents.ToArray();
+ channel.ConfirmSelect();
+
+ foreach (var outgoingEvent in outgoingEventArray)
+ {
+ await PublishAsync(
+ channel,
+ outgoingEvent.EventName,
+ outgoingEvent.EventData,
+ properties: null,
+ eventId: outgoingEvent.Id);
+ }
+
+ channel.WaitForConfirmsOrDie();
+ }
+ }
+
+ public async override Task ProcessFromInboxAsync(
IncomingEventInfo incomingEvent,
InboxConfig inboxConfig)
{
@@ -233,7 +258,7 @@ public class RabbitMqDistributedEventBus : DistributedEventBusBase, ISingletonDe
return PublishAsync(eventName, body, properties, headersArguments);
}
- protected Task PublishAsync(
+ protected virtual Task PublishAsync(
string eventName,
byte[] body,
IBasicProperties properties,
@@ -242,37 +267,66 @@ public class RabbitMqDistributedEventBus : DistributedEventBusBase, ISingletonDe
{
using (var channel = ConnectionPool.Get(AbpRabbitMqEventBusOptions.ConnectionName).CreateModel())
{
- channel.ExchangeDeclare(
- AbpRabbitMqEventBusOptions.ExchangeName,
- AbpRabbitMqEventBusOptions.GetExchangeTypeOrDefault(),
- durable: true
- );
-
- if (properties == null)
- {
- properties = channel.CreateBasicProperties();
- properties.DeliveryMode = RabbitMqConsts.DeliveryModes.Persistent;
- }
+ return PublishAsync(channel, eventName, body, properties, headersArguments, eventId);
+ }
+ }
- if (properties.MessageId.IsNullOrEmpty())
- {
- properties.MessageId = (eventId ?? GuidGenerator.Create()).ToString("N");
- }
+ protected virtual Task PublishAsync(
+ IModel channel,
+ string eventName,
+ byte[] body,
+ IBasicProperties properties,
+ Dictionary headersArguments = null,
+ Guid? eventId = null)
+ {
+ EnsureExchangeExists(channel);
- SetEventMessageHeaders(properties, headersArguments);
+ if (properties == null)
+ {
+ properties = channel.CreateBasicProperties();
+ properties.DeliveryMode = RabbitMqConsts.DeliveryModes.Persistent;
+ }
- channel.BasicPublish(
- exchange: AbpRabbitMqEventBusOptions.ExchangeName,
- routingKey: eventName,
- mandatory: true,
- basicProperties: properties,
- body: body
- );
+ if (properties.MessageId.IsNullOrEmpty())
+ {
+ properties.MessageId = (eventId ?? GuidGenerator.Create()).ToString("N");
}
+ SetEventMessageHeaders(properties, headersArguments);
+
+ channel.BasicPublish(
+ exchange: AbpRabbitMqEventBusOptions.ExchangeName,
+ routingKey: eventName,
+ mandatory: true,
+ basicProperties: properties,
+ body: body
+ );
+
return Task.CompletedTask;
}
+ private void EnsureExchangeExists(IModel channel)
+ {
+ if (_exchangeCreated)
+ {
+ return;
+ }
+
+ try
+ {
+ channel.ExchangeDeclarePassive(AbpRabbitMqEventBusOptions.ExchangeName);
+ }
+ catch (Exception)
+ {
+ channel.ExchangeDeclare(
+ AbpRabbitMqEventBusOptions.ExchangeName,
+ AbpRabbitMqEventBusOptions.GetExchangeTypeOrDefault(),
+ durable: true
+ );
+ }
+ _exchangeCreated = true;
+ }
+
private void SetEventMessageHeaders(IBasicProperties properties, Dictionary headersArguments)
{
if (headersArguments == null)
@@ -306,7 +360,7 @@ public class RabbitMqDistributedEventBus : DistributedEventBusBase, ISingletonDe
var handlerFactoryList = new List();
foreach (var handlerFactory in
- HandlerFactories.Where(hf => ShouldTriggerEventForHandler(eventType, hf.Key)))
+ HandlerFactories.Where(hf => ShouldTriggerEventForHandler(eventType, hf.Key)))
{
handlerFactoryList.Add(
new EventTypeWithEventHandlerFactories(handlerFactory.Key, handlerFactory.Value));
diff --git a/framework/src/Volo.Abp.EventBus.Rebus/Volo/Abp/EventBus/Rebus/RebusDistributedEventBus.cs b/framework/src/Volo.Abp.EventBus.Rebus/Volo/Abp/EventBus/Rebus/RebusDistributedEventBus.cs
index cf6c1d6b0f..4ccd72ba15 100644
--- a/framework/src/Volo.Abp.EventBus.Rebus/Volo/Abp/EventBus/Rebus/RebusDistributedEventBus.cs
+++ b/framework/src/Volo.Abp.EventBus.Rebus/Volo/Abp/EventBus/Rebus/RebusDistributedEventBus.cs
@@ -7,6 +7,7 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Rebus.Bus;
using Rebus.Pipeline;
+using Rebus.Transport;
using Volo.Abp.DependencyInjection;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.Guids;
@@ -149,6 +150,11 @@ public class RebusDistributedEventBus : DistributedEventBusBase, ISingletonDepen
}
protected async override Task PublishToEventBusAsync(Type eventType, object eventData)
+ {
+ await PublishAsync(eventType, eventData);
+ }
+
+ protected virtual async Task PublishAsync(Type eventType, object eventData)
{
if (AbpRebusEventBusOptions.Publish != null)
{
@@ -218,7 +224,22 @@ public class RebusDistributedEventBus : DistributedEventBusBase, ISingletonDepen
return PublishToEventBusAsync(eventType, eventData);
}
- public override async Task ProcessFromInboxAsync(
+ public async override Task PublishManyFromOutboxAsync(IEnumerable outgoingEvents, OutboxConfig outboxConfig)
+ {
+ var outgoingEventArray = outgoingEvents.ToArray();
+
+ using (var scope = new RebusTransactionScope())
+ {
+ foreach (var outgoingEvent in outgoingEventArray)
+ {
+ await PublishFromOutboxAsync(outgoingEvent, outboxConfig);
+ }
+
+ await scope.CompleteAsync();
+ }
+ }
+
+ public async override Task ProcessFromInboxAsync(
IncomingEventInfo incomingEvent,
InboxConfig inboxConfig)
{
diff --git a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/AbpEventBusBoxesOptions.cs b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/AbpEventBusBoxesOptions.cs
index a46fc76238..d92c48db3a 100644
--- a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/AbpEventBusBoxesOptions.cs
+++ b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/AbpEventBusBoxesOptions.cs
@@ -34,6 +34,11 @@ public class AbpEventBusBoxesOptions
/// Default: 2 hours
///
public TimeSpan WaitTimeToDeleteProcessedInboxEvents { get; set; }
+
+ ///
+ /// Default: true
+ ///
+ public bool BatchPublishOutboxEvents { get; set; }
public AbpEventBusBoxesOptions()
{
@@ -43,5 +48,6 @@ public class AbpEventBusBoxesOptions
PeriodTimeSpan = TimeSpan.FromSeconds(2);
DistributedLockWaitDuration = TimeSpan.FromSeconds(15);
WaitTimeToDeleteProcessedInboxEvents = TimeSpan.FromHours(2);
+ BatchPublishOutboxEvents = true;
}
}
diff --git a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/DistributedEventBusBase.cs b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/DistributedEventBusBase.cs
index 6547c1686c..69ae91505d 100644
--- a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/DistributedEventBusBase.cs
+++ b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/DistributedEventBusBase.cs
@@ -85,6 +85,11 @@ public abstract class DistributedEventBusBase : EventBusBase, IDistributedEventB
OutboxConfig outboxConfig
);
+ public abstract Task PublishManyFromOutboxAsync(
+ IEnumerable outgoingEvents,
+ OutboxConfig outboxConfig
+ );
+
public abstract Task ProcessFromInboxAsync(
IncomingEventInfo incomingEvent,
InboxConfig inboxConfig);
@@ -101,7 +106,8 @@ public abstract class DistributedEventBusBase : EventBusBase, IDistributedEventB
{
if (outboxConfig.Selector == null || outboxConfig.Selector(eventType))
{
- var eventOutbox = (IEventOutbox)unitOfWork.ServiceProvider.GetRequiredService(outboxConfig.ImplementationType);
+ var eventOutbox =
+ (IEventOutbox)unitOfWork.ServiceProvider.GetRequiredService(outboxConfig.ImplementationType);
var eventName = EventNameAttribute.GetNameOrDefault(eventType);
await eventOutbox.EnqueueAsync(
new OutgoingEventInfo(
@@ -135,7 +141,8 @@ public abstract class DistributedEventBusBase : EventBusBase, IDistributedEventB
{
if (inboxConfig.EventSelector == null || inboxConfig.EventSelector(eventType))
{
- var eventInbox = (IEventInbox)scope.ServiceProvider.GetRequiredService(inboxConfig.ImplementationType);
+ var eventInbox =
+ (IEventInbox)scope.ServiceProvider.GetRequiredService(inboxConfig.ImplementationType);
if (!messageId.IsNullOrEmpty())
{
diff --git a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/IEventOutbox.cs b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/IEventOutbox.cs
index 6ecefcf002..018747945c 100644
--- a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/IEventOutbox.cs
+++ b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/IEventOutbox.cs
@@ -12,4 +12,6 @@ public interface IEventOutbox
Task> GetWaitingEventsAsync(int maxCount, CancellationToken cancellationToken = default);
Task DeleteAsync(Guid id);
+
+ Task DeleteManyAsync(IEnumerable ids);
}
diff --git a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/ISupportsEventBoxes.cs b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/ISupportsEventBoxes.cs
index 37405fb58a..73f74a68ad 100644
--- a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/ISupportsEventBoxes.cs
+++ b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/ISupportsEventBoxes.cs
@@ -1,3 +1,4 @@
+using System.Collections.Generic;
using System.Threading.Tasks;
namespace Volo.Abp.EventBus.Distributed;
@@ -9,6 +10,11 @@ public interface ISupportsEventBoxes
OutboxConfig outboxConfig
);
+ Task PublishManyFromOutboxAsync(
+ IEnumerable outgoingEvents,
+ OutboxConfig outboxConfig
+ );
+
Task ProcessFromInboxAsync(
IncomingEventInfo incomingEvent,
InboxConfig inboxConfig
diff --git a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/OutboxSender.cs b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/OutboxSender.cs
index 6ed60ba34c..851ddf3da1 100644
--- a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/OutboxSender.cs
+++ b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/OutboxSender.cs
@@ -1,4 +1,7 @@
using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
@@ -82,18 +85,14 @@ public class OutboxSender : IOutboxSender, ITransientDependency
}
Logger.LogInformation($"Found {waitingEvents.Count} events in the outbox.");
-
- foreach (var waitingEvent in waitingEvents)
+
+ if (EventBusBoxesOptions.BatchPublishOutboxEvents)
{
- await DistributedEventBus
- .AsSupportsEventBoxes()
- .PublishFromOutboxAsync(
- waitingEvent,
- OutboxConfig
- );
-
- await Outbox.DeleteAsync(waitingEvent.Id);
- Logger.LogInformation($"Sent the event to the message broker with id = {waitingEvent.Id:N}");
+ await PublishOutgoingMessagesInBatchAsync(waitingEvents);
+ }
+ else
+ {
+ await PublishOutgoingMessagesAsync(waitingEvents);
}
}
}
@@ -108,4 +107,32 @@ public class OutboxSender : IOutboxSender, ITransientDependency
}
}
}
+
+ protected virtual async Task PublishOutgoingMessagesAsync(List waitingEvents)
+ {
+ foreach (var waitingEvent in waitingEvents)
+ {
+ await DistributedEventBus
+ .AsSupportsEventBoxes()
+ .PublishFromOutboxAsync(
+ waitingEvent,
+ OutboxConfig
+ );
+
+ await Outbox.DeleteAsync(waitingEvent.Id);
+
+ Logger.LogInformation($"Sent the event to the message broker with id = {waitingEvent.Id:N}");
+ }
+ }
+
+ protected virtual async Task PublishOutgoingMessagesInBatchAsync(List waitingEvents)
+ {
+ await DistributedEventBus
+ .AsSupportsEventBoxes()
+ .PublishManyFromOutboxAsync(waitingEvents, OutboxConfig);
+
+ await Outbox.DeleteManyAsync(waitingEvents.Select(x => x.Id).ToArray());
+
+ Logger.LogInformation($"Sent {waitingEvents.Count} events to message broker");
+ }
}
diff --git a/framework/src/Volo.Abp.Http.Client.Web/Volo/Abp/Http/Client/Web/Conventions/AbpHttpClientProxyServiceConvention.cs b/framework/src/Volo.Abp.Http.Client.Web/Volo/Abp/Http/Client/Web/Conventions/AbpHttpClientProxyServiceConvention.cs
index 9650377580..08dab1fc82 100644
--- a/framework/src/Volo.Abp.Http.Client.Web/Volo/Abp/Http/Client/Web/Conventions/AbpHttpClientProxyServiceConvention.cs
+++ b/framework/src/Volo.Abp.Http.Client.Web/Volo/Abp/Http/Client/Web/Conventions/AbpHttpClientProxyServiceConvention.cs
@@ -6,6 +6,7 @@ using System.Reflection;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ActionConstraints;
using Microsoft.AspNetCore.Mvc.ApplicationModels;
+using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Volo.Abp.Application.Services;
using Volo.Abp.AspNetCore.Mvc;
@@ -122,6 +123,7 @@ public class AbpHttpClientProxyServiceConvention : AbpServiceConvention
var actionApiDescriptionModel = FindActionApiDescriptionModel(controller, action);
if (actionApiDescriptionModel == null)
{
+ Logger.LogWarning($"Could not find ApiDescriptionModel for action: {action.ActionName} in controller: {controller.ControllerName}, May be the generate-proxy.json is not up to date.");
return;;
}
diff --git a/framework/src/Volo.Abp.IdentityModel/Volo.Abp.IdentityModel.csproj b/framework/src/Volo.Abp.IdentityModel/Volo.Abp.IdentityModel.csproj
index e835e24e99..8bc6b1b5de 100644
--- a/framework/src/Volo.Abp.IdentityModel/Volo.Abp.IdentityModel.csproj
+++ b/framework/src/Volo.Abp.IdentityModel/Volo.Abp.IdentityModel.csproj
@@ -15,7 +15,7 @@
-
+
diff --git a/framework/src/Volo.Abp.Kafka/Volo/Abp/Kafka/ConsumerPool.cs b/framework/src/Volo.Abp.Kafka/Volo/Abp/Kafka/ConsumerPool.cs
index 81a5c195c1..7147c81271 100644
--- a/framework/src/Volo.Abp.Kafka/Volo/Abp/Kafka/ConsumerPool.cs
+++ b/framework/src/Volo.Abp.Kafka/Volo/Abp/Kafka/ConsumerPool.cs
@@ -76,6 +76,7 @@ public class ConsumerPool : IConsumerPool, ISingletonDependency
try
{
+ consumer.Value.Unsubscribe();
consumer.Value.Close();
consumer.Value.Dispose();
}
diff --git a/framework/src/Volo.Abp.Kafka/Volo/Abp/Kafka/KafkaMessageConsumer.cs b/framework/src/Volo.Abp.Kafka/Volo/Abp/Kafka/KafkaMessageConsumer.cs
index da21f48883..704c15845f 100644
--- a/framework/src/Volo.Abp.Kafka/Volo/Abp/Kafka/KafkaMessageConsumer.cs
+++ b/framework/src/Volo.Abp.Kafka/Volo/Abp/Kafka/KafkaMessageConsumer.cs
@@ -80,9 +80,11 @@ public class KafkaMessageConsumer : IKafkaMessageConsumer, ITransientDependency,
protected virtual async Task Timer_Elapsed(AbpAsyncTimer timer)
{
- await CreateTopicAsync();
- Consume();
- Timer.Stop();
+ if (Consumer == null)
+ {
+ await CreateTopicAsync();
+ Consume();
+ }
}
protected virtual async Task CreateTopicAsync()
@@ -164,12 +166,21 @@ public class KafkaMessageConsumer : IKafkaMessageConsumer, ITransientDependency,
public virtual void Dispose()
{
+ Timer.Stop();
if (Consumer == null)
{
return;
}
- Consumer.Close();
- Consumer.Dispose();
+ try
+ {
+ Consumer.Unsubscribe();
+ Consumer.Close();
+ Consumer.Dispose();
+ Consumer = null;
+ }
+ catch (ObjectDisposedException)
+ {
+ }
}
}
diff --git a/framework/src/Volo.Abp.Kafka/Volo/Abp/Kafka/ProducerPool.cs b/framework/src/Volo.Abp.Kafka/Volo/Abp/Kafka/ProducerPool.cs
index 49287a20e9..0a31a3483a 100644
--- a/framework/src/Volo.Abp.Kafka/Volo/Abp/Kafka/ProducerPool.cs
+++ b/framework/src/Volo.Abp.Kafka/Volo/Abp/Kafka/ProducerPool.cs
@@ -17,6 +17,8 @@ public class ProducerPool : IProducerPool, ISingletonDependency
protected ConcurrentDictionary>> Producers { get; }
protected TimeSpan TotalDisposeWaitDuration { get; set; } = TimeSpan.FromSeconds(10);
+
+ protected TimeSpan DefaultTransactionsWaitDuration { get; set; } = TimeSpan.FromSeconds(30);
public ILogger Logger { get; set; }
@@ -37,11 +39,18 @@ public class ProducerPool : IProducerPool, ISingletonDependency
return Producers.GetOrAdd(
connectionName, connection => new Lazy>(() =>
{
- var config = Options.Connections.GetOrDefault(connection);
-
- Options.ConfigureProducer?.Invoke(new ProducerConfig(config));
-
- return new ProducerBuilder(config).Build();
+ var producerConfig = new ProducerConfig(Options.Connections.GetOrDefault(connection));
+ Options.ConfigureProducer?.Invoke(producerConfig);
+
+ if (producerConfig.TransactionalId.IsNullOrWhiteSpace())
+ {
+ producerConfig.TransactionalId = Guid.NewGuid().ToString();
+ }
+
+ var producer = new ProducerBuilder(producerConfig).Build();
+ producer.InitTransactions(DefaultTransactionsWaitDuration);
+
+ return producer;
})).Value;
}
@@ -69,7 +78,7 @@ public class ProducerPool : IProducerPool, ISingletonDependency
foreach (var producer in Producers.Values)
{
var poolItemDisposeStopwatch = Stopwatch.StartNew();
-
+
try
{
producer.Value.Dispose();
@@ -77,19 +86,19 @@ public class ProducerPool : IProducerPool, ISingletonDependency
catch
{
}
-
+
poolItemDisposeStopwatch.Stop();
-
+
remainingWaitDuration = remainingWaitDuration > poolItemDisposeStopwatch.Elapsed
? remainingWaitDuration.Subtract(poolItemDisposeStopwatch.Elapsed)
: TimeSpan.Zero;
}
-
+
poolDisposeStopwatch.Stop();
-
+
Logger.LogInformation(
$"Disposed Kafka Producer Pool ({Producers.Count} producers in {poolDisposeStopwatch.Elapsed.TotalMilliseconds:0.00} ms).");
-
+
if (poolDisposeStopwatch.Elapsed.TotalSeconds > 5.0)
{
Logger.LogWarning(
diff --git a/framework/src/Volo.Abp.MongoDB/Volo.Abp.MongoDB.csproj b/framework/src/Volo.Abp.MongoDB/Volo.Abp.MongoDB.csproj
index d72f308510..7adca7867f 100644
--- a/framework/src/Volo.Abp.MongoDB/Volo.Abp.MongoDB.csproj
+++ b/framework/src/Volo.Abp.MongoDB/Volo.Abp.MongoDB.csproj
@@ -15,7 +15,7 @@
-
+
diff --git a/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/DistributedEvents/MongoDbContextEventOutbox.cs b/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/DistributedEvents/MongoDbContextEventOutbox.cs
index 1f3ae999b0..cc6c4d42df 100644
--- a/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/DistributedEvents/MongoDbContextEventOutbox.cs
+++ b/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/DistributedEvents/MongoDbContextEventOutbox.cs
@@ -68,4 +68,18 @@ public class MongoDbContextEventOutbox : IMongoDbContextEventOu
await dbContext.OutgoingEvents.DeleteOneAsync(x => x.Id.Equals(id));
}
}
+
+ [UnitOfWork]
+ public virtual async Task DeleteManyAsync(IEnumerable ids)
+ {
+ var dbContext = (IHasEventOutbox)await MongoDbContextProvider.GetDbContextAsync();
+ if (dbContext.SessionHandle != null)
+ {
+ await dbContext.OutgoingEvents.DeleteManyAsync(dbContext.SessionHandle, x => ids.Contains(x.Id));
+ }
+ else
+ {
+ await dbContext.OutgoingEvents.DeleteManyAsync(x => ids.Contains(x.Id));
+ }
+ }
}
diff --git a/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/RabbitMqMessageConsumer.cs b/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/RabbitMqMessageConsumer.cs
index 049e8da712..8ce184295a 100644
--- a/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/RabbitMqMessageConsumer.cs
+++ b/framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/RabbitMqMessageConsumer.cs
@@ -176,14 +176,6 @@ public class RabbitMqMessageConsumer : IRabbitMqMessageConsumer, ITransientDepen
}
catch (Exception ex)
{
- if (ex is OperationInterruptedException operationInterruptedException &&
- operationInterruptedException.ShutdownReason.ReplyCode == 406 &&
- operationInterruptedException.Message.Contains("arg 'x-dead-letter-exchange'"))
- {
- Logger.LogException(ex, LogLevel.Warning);
- await ExceptionNotifier.NotifyAsync(ex, logLevel: LogLevel.Warning);
- }
-
Logger.LogException(ex, LogLevel.Warning);
await ExceptionNotifier.NotifyAsync(ex, logLevel: LogLevel.Warning);
}
diff --git a/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/Repositories/RepositoryExtensions_Tests.cs b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/Repositories/RepositoryExtensions_Tests.cs
new file mode 100644
index 0000000000..70f99ac26a
--- /dev/null
+++ b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/Repositories/RepositoryExtensions_Tests.cs
@@ -0,0 +1,8 @@
+using Volo.Abp.TestApp.Testing;
+
+namespace Volo.Abp.EntityFrameworkCore.Repositories;
+
+public class RepositoryExtensions_Tests : RepositoryExtensions_Tests
+{
+
+}
diff --git a/framework/test/Volo.Abp.MemoryDb.Tests/Volo/Abp/MemoryDb/Repositories/RepositoryExtensions_Tests.cs b/framework/test/Volo.Abp.MemoryDb.Tests/Volo/Abp/MemoryDb/Repositories/RepositoryExtensions_Tests.cs
new file mode 100644
index 0000000000..dbb37bb71e
--- /dev/null
+++ b/framework/test/Volo.Abp.MemoryDb.Tests/Volo/Abp/MemoryDb/Repositories/RepositoryExtensions_Tests.cs
@@ -0,0 +1,8 @@
+using Volo.Abp.TestApp.Testing;
+
+namespace Volo.Abp.MemoryDb.Repositories;
+
+public class RepositoryExtensions_Tests : RepositoryExtensions_Tests
+{
+
+}
diff --git a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Repositories/RepositoryExtensions_Tests.cs b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Repositories/RepositoryExtensions_Tests.cs
new file mode 100644
index 0000000000..dd653878b8
--- /dev/null
+++ b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Repositories/RepositoryExtensions_Tests.cs
@@ -0,0 +1,10 @@
+using Volo.Abp.TestApp.Testing;
+using Xunit;
+
+namespace Volo.Abp.MongoDB.Repositories;
+
+[Collection(MongoTestCollection.Name)]
+public class RepositoryExtensions_Tests : RepositoryExtensions_Tests
+{
+
+}
diff --git a/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/RepositoryExtensions_Tests.cs b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/RepositoryExtensions_Tests.cs
new file mode 100644
index 0000000000..747c53e333
--- /dev/null
+++ b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/RepositoryExtensions_Tests.cs
@@ -0,0 +1,38 @@
+using System;
+using System.Threading.Tasks;
+using Volo.Abp.Domain.Entities;
+using Volo.Abp.Domain.Repositories;
+using Volo.Abp.Modularity;
+using Volo.Abp.TestApp.Domain;
+using Xunit;
+
+namespace Volo.Abp.TestApp.Testing;
+
+public abstract class RepositoryExtensions_Tests : TestAppTestBase
+ where TStartupModule : IAbpModule
+{
+ protected readonly IRepository PersonRepository;
+
+ protected RepositoryExtensions_Tests()
+ {
+ PersonRepository = GetRequiredService>();
+ }
+
+ [Fact]
+ public async Task EnsureExistsAsync_Test()
+ {
+ await WithUnitOfWorkAsync(async () =>
+ {
+ var id = Guid.NewGuid();
+ await Assert.ThrowsAsync(async () =>
+ await PersonRepository.EnsureExistsAsync(Guid.NewGuid())
+ );
+ await Assert.ThrowsAsync(async () =>
+ await PersonRepository.EnsureExistsAsync(x => x.Id == id)
+ );
+
+ await PersonRepository.EnsureExistsAsync(TestDataBuilder.UserDouglasId);
+ await PersonRepository.EnsureExistsAsync(x => x.Id == TestDataBuilder.UserDouglasId);
+ });
+ }
+}
diff --git a/modules/account/Volo.Abp.Account.sln b/modules/account/Volo.Abp.Account.sln
index 019ed12315..3fe56c6f53 100644
--- a/modules/account/Volo.Abp.Account.sln
+++ b/modules/account/Volo.Abp.Account.sln
@@ -25,6 +25,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Account.Blazor", "
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Account.Installer", "src\Volo.Abp.Account.Installer\Volo.Abp.Account.Installer.csproj", "{EAAB416C-9113-486D-9B54-4DCF78FDC6AB}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Account.Web.OpenIddict", "src\Volo.Abp.Account.Web.OpenIddict\Volo.Abp.Account.Web.OpenIddict.csproj", "{53DA9051-4C76-4264-A1E1-2810DC685CB2}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -67,6 +69,10 @@ Global
{EAAB416C-9113-486D-9B54-4DCF78FDC6AB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EAAB416C-9113-486D-9B54-4DCF78FDC6AB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EAAB416C-9113-486D-9B54-4DCF78FDC6AB}.Release|Any CPU.Build.0 = Release|Any CPU
+ {53DA9051-4C76-4264-A1E1-2810DC685CB2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {53DA9051-4C76-4264-A1E1-2810DC685CB2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {53DA9051-4C76-4264-A1E1-2810DC685CB2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {53DA9051-4C76-4264-A1E1-2810DC685CB2}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -81,6 +87,7 @@ Global
{356EAC51-5D55-4852-A8A5-2F90EAC8DAE3} = {12FAE513-7575-4235-89DF-277BA1A3B098}
{EE8858B3-A638-481B-8EB9-74F5E7D43D80} = {B5881429-EFF7-4F30-8C0B-0AC41E36B74E}
{EAAB416C-9113-486D-9B54-4DCF78FDC6AB} = {B5881429-EFF7-4F30-8C0B-0AC41E36B74E}
+ {53DA9051-4C76-4264-A1E1-2810DC685CB2} = {B5881429-EFF7-4F30-8C0B-0AC41E36B74E}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {2B054393-D2B2-4EA8-8A15-D60CBCF3E7A9}
diff --git a/modules/account/src/Volo.Abp.Account.Web.IdentityServer/Properties/launchSettings.json b/modules/account/src/Volo.Abp.Account.Web.IdentityServer/Properties/launchSettings.json
deleted file mode 100644
index b25b2e4e3d..0000000000
--- a/modules/account/src/Volo.Abp.Account.Web.IdentityServer/Properties/launchSettings.json
+++ /dev/null
@@ -1,27 +0,0 @@
-{
- "iisSettings": {
- "windowsAuthentication": false,
- "anonymousAuthentication": true,
- "iisExpress": {
- "applicationUrl": "http://localhost:2922/",
- "sslPort": 44394
- }
- },
- "profiles": {
- "IIS Express": {
- "commandName": "IISExpress",
- "launchBrowser": true,
- "environmentVariables": {
- "ASPNETCORE_ENVIRONMENT": "Development"
- }
- },
- "Volo.Abp.Account.Web.IdentityServer": {
- "commandName": "Project",
- "launchBrowser": true,
- "environmentVariables": {
- "ASPNETCORE_ENVIRONMENT": "Development"
- },
- "applicationUrl": "https://localhost:5001;http://localhost:5000"
- }
- }
-}
\ No newline at end of file
diff --git a/modules/account/src/Volo.Abp.Account.Web.OpenIddict/AbpAccountWebOpenIddictModule.cs b/modules/account/src/Volo.Abp.Account.Web.OpenIddict/AbpAccountWebOpenIddictModule.cs
new file mode 100644
index 0000000000..7a81943dd3
--- /dev/null
+++ b/modules/account/src/Volo.Abp.Account.Web.OpenIddict/AbpAccountWebOpenIddictModule.cs
@@ -0,0 +1,29 @@
+using Microsoft.Extensions.DependencyInjection;
+using Volo.Abp.Modularity;
+using Volo.Abp.OpenIddict;
+using Volo.Abp.VirtualFileSystem;
+
+namespace Volo.Abp.Account.Web;
+
+[DependsOn(
+ typeof(AbpAccountWebModule),
+ typeof(AbpOpenIddictAspNetCoreModule)
+)]
+public class AbpAccountWebOpenIddictModule : AbpModule
+{
+ public override void PreConfigureServices(ServiceConfigurationContext context)
+ {
+ PreConfigure(mvcBuilder =>
+ {
+ mvcBuilder.AddApplicationPartIfNotExists(typeof(AbpAccountWebOpenIddictModule).Assembly);
+ });
+ }
+
+ public override void ConfigureServices(ServiceConfigurationContext context)
+ {
+ Configure(options =>
+ {
+ options.FileSets.AddEmbedded();
+ });
+ }
+}
diff --git a/modules/account/src/Volo.Abp.Account.Web.OpenIddict/FodyWeavers.xml b/modules/account/src/Volo.Abp.Account.Web.OpenIddict/FodyWeavers.xml
new file mode 100644
index 0000000000..be0de3a908
--- /dev/null
+++ b/modules/account/src/Volo.Abp.Account.Web.OpenIddict/FodyWeavers.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/modules/account/src/Volo.Abp.Account.Web.OpenIddict/FodyWeavers.xsd b/modules/account/src/Volo.Abp.Account.Web.OpenIddict/FodyWeavers.xsd
new file mode 100644
index 0000000000..3f3946e282
--- /dev/null
+++ b/modules/account/src/Volo.Abp.Account.Web.OpenIddict/FodyWeavers.xsd
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.
+
+
+
+
+ A comma-separated list of error codes that can be safely ignored in assembly verification.
+
+
+
+
+ 'false' to turn off automatic generation of the XML Schema file.
+
+
+
+
+
\ No newline at end of file
diff --git a/modules/account/src/Volo.Abp.Account.Web.OpenIddict/Pages/Account/OpenIddictSupportedLoginModel.cs b/modules/account/src/Volo.Abp.Account.Web.OpenIddict/Pages/Account/OpenIddictSupportedLoginModel.cs
new file mode 100644
index 0000000000..61b170c612
--- /dev/null
+++ b/modules/account/src/Volo.Abp.Account.Web.OpenIddict/Pages/Account/OpenIddictSupportedLoginModel.cs
@@ -0,0 +1,114 @@
+using System;
+using System.Security.Claims;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Authentication;
+using Microsoft.Extensions.Options;
+using Microsoft.AspNetCore.Identity;
+using Microsoft.AspNetCore.Mvc;
+using OpenIddict.Server;
+using OpenIddict.Server.AspNetCore;
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.MultiTenancy;
+using Volo.Abp.OpenIddict;
+
+namespace Volo.Abp.Account.Web.Pages.Account;
+
+[ExposeServices(typeof(LoginModel))]
+public class OpenIddictSupportedLoginModel : LoginModel
+{
+ protected AbpOpenIddictRequestHelper OpenIddictRequestHelper { get; }
+ public OpenIddictSupportedLoginModel(
+ IAuthenticationSchemeProvider schemeProvider,
+ IOptions accountOptions,
+ IOptions identityOptions,
+ AbpOpenIddictRequestHelper openIddictRequestHelper)
+ : base(schemeProvider, accountOptions, identityOptions)
+ {
+ OpenIddictRequestHelper = openIddictRequestHelper;
+ }
+
+ public async override Task OnGetAsync()
+ {
+ LoginInput = new LoginInputModel();
+
+ var request = await OpenIddictRequestHelper.GetFromReturnUrlAsync(ReturnUrl);
+ if (request?.ClientId != null)
+ {
+ ShowCancelButton = true;
+
+ LoginInput.UserNameOrEmailAddress = request.LoginHint;
+
+ //TODO: Reference AspNetCore MultiTenancy module and use options to get the tenant key!
+ var tenant = request.GetParameter(TenantResolverConsts.DefaultTenantKey)?.ToString();
+ if (!string.IsNullOrEmpty(tenant))
+ {
+ CurrentTenant.Change(Guid.Parse(tenant));
+ Response.Cookies.Append(TenantResolverConsts.DefaultTenantKey, tenant);
+ }
+ }
+
+ return await base.OnGetAsync();
+ }
+
+ public async override Task OnPostAsync(string action)
+ {
+ if (action == "Cancel")
+ {
+ var request = await OpenIddictRequestHelper.GetFromReturnUrlAsync(ReturnUrl);
+
+ var transaction = HttpContext.GetOpenIddictServerTransaction();
+ if (request?.ClientId != null && transaction != null)
+ {
+ transaction.EndpointType = OpenIddictServerEndpointType.Authorization;
+ transaction.Request = request;
+
+ var notification = new OpenIddictServerEvents.ValidateAuthorizationRequestContext(transaction);
+ transaction.SetProperty(typeof(OpenIddictServerEvents.ValidateAuthorizationRequestContext).FullName!, notification);
+
+ return Forbid(OpenIddictServerAspNetCoreDefaults.AuthenticationScheme);
+ }
+
+ return Redirect("~/");
+ }
+
+ return await base.OnPostAsync(action);
+ }
+
+ public async override Task OnPostExternalLogin(string provider)
+ {
+ if (AccountOptions.WindowsAuthenticationSchemeName == provider)
+ {
+ return await ProcessWindowsLoginAsync();
+ }
+
+ return await base.OnPostExternalLogin(provider);
+ }
+
+ protected virtual async Task ProcessWindowsLoginAsync()
+ {
+ var result = await HttpContext.AuthenticateAsync(AccountOptions.WindowsAuthenticationSchemeName);
+ if (result.Succeeded)
+ {
+ var props = new AuthenticationProperties()
+ {
+ RedirectUri = Url.Page("./Login", pageHandler: "ExternalLoginCallback", values: new { ReturnUrl, ReturnUrlHash }),
+ Items =
+ {
+ {
+ "LoginProvider", AccountOptions.WindowsAuthenticationSchemeName
+ }
+ }
+ };
+
+ var id = new ClaimsIdentity(AccountOptions.WindowsAuthenticationSchemeName);
+ id.AddClaim(new Claim(ClaimTypes.NameIdentifier, result.Principal.FindFirstValue(ClaimTypes.PrimarySid)));
+ id.AddClaim(new Claim(ClaimTypes.Name, result.Principal.FindFirstValue(ClaimTypes.Name)));
+
+ await HttpContext.SignInAsync(IdentityConstants.ExternalScheme, new ClaimsPrincipal(id), props);
+
+ return Redirect(props.RedirectUri!);
+ }
+
+ return Challenge(AccountOptions.WindowsAuthenticationSchemeName);
+ }
+}
diff --git a/modules/account/src/Volo.Abp.Account.Web.OpenIddict/Pages/_ViewImports.cshtml b/modules/account/src/Volo.Abp.Account.Web.OpenIddict/Pages/_ViewImports.cshtml
new file mode 100644
index 0000000000..c1da1f5f10
--- /dev/null
+++ b/modules/account/src/Volo.Abp.Account.Web.OpenIddict/Pages/_ViewImports.cshtml
@@ -0,0 +1,4 @@
+@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
+@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI
+@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bootstrap
+@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bundling
\ No newline at end of file
diff --git a/modules/account/src/Volo.Abp.Account.Web.OpenIddict/Volo.Abp.Account.Web.OpenIddict.csproj b/modules/account/src/Volo.Abp.Account.Web.OpenIddict/Volo.Abp.Account.Web.OpenIddict.csproj
new file mode 100644
index 0000000000..1d801d5f6e
--- /dev/null
+++ b/modules/account/src/Volo.Abp.Account.Web.OpenIddict/Volo.Abp.Account.Web.OpenIddict.csproj
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+ net6.0
+ Volo.Abp.Account.Web.OpenIddict
+ Volo.Abp.Account.Web.OpenIddict
+ true
+ $(AssetTargetFallback);portable-net45+win8+wp8+wpa81;
+ false
+ false
+ false
+ true
+ Volo.Abp.Account.Web
+ Library
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Login.cshtml.cs b/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Login.cshtml.cs
index 5ec85d4078..9d6e2d8b9b 100644
--- a/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Login.cshtml.cs
+++ b/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Login.cshtml.cs
@@ -75,8 +75,7 @@ public class LoginModel : AccountPageModel
if (IsExternalLoginOnly)
{
- //return await ExternalLogin(vm.ExternalLoginScheme, returnUrl);
- throw new NotImplementedException();
+ return await OnPostExternalLogin(ExternalProviders.First().AuthenticationScheme);
}
return Page();
@@ -277,7 +276,7 @@ public class LoginModel : AccountPageModel
CheckIdentityErrors(await UserManager.SetEmailAsync(user, emailAddress));
CheckIdentityErrors(await UserManager.AddLoginAsync(user, info));
CheckIdentityErrors(await UserManager.AddDefaultRolesAsync(user));
-
+
user.Name = info.Principal.FindFirstValue(AbpClaimTypes.Name);
user.Surname = info.Principal.FindFirstValue(AbpClaimTypes.SurName);
diff --git a/modules/basic-theme/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/package.json b/modules/basic-theme/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/package.json
index dc7f6f50d0..9948a950e9 100644
--- a/modules/basic-theme/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/package.json
+++ b/modules/basic-theme/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/package.json
@@ -3,7 +3,7 @@
"name": "asp.net",
"private": true,
"dependencies": {
- "@abp/aspnetcore.mvc.ui.theme.shared": "^5.2.1",
+ "@abp/aspnetcore.mvc.ui.theme.shared": "^5.3.0-rc.1",
"highlight.js": "^9.13.1"
},
"devDependencies": {}
diff --git a/modules/basic-theme/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/yarn.lock b/modules/basic-theme/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/yarn.lock
index e40aac01d8..1fc849849a 100644
--- a/modules/basic-theme/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/yarn.lock
+++ b/modules/basic-theme/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/yarn.lock
@@ -2,30 +2,30 @@
# yarn lockfile v1
-"@abp/aspnetcore.mvc.ui.theme.shared@^5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-5.2.1.tgz#dc291fe9c7100cc796068e19abf7579bd5e54b44"
- integrity sha512-/1C5RyPIRPZT5ir8Len2EnSt1KfWcRdPyn/avAG+9JKBZ8FoUL8mO2/ffESOvikh/wItZZgxJ5VEJVGwHNjgdQ==
- dependencies:
- "@abp/aspnetcore.mvc.ui" "~5.2.1"
- "@abp/bootstrap" "~5.2.1"
- "@abp/bootstrap-datepicker" "~5.2.1"
- "@abp/datatables.net-bs5" "~5.2.1"
- "@abp/font-awesome" "~5.2.1"
- "@abp/jquery-form" "~5.2.1"
- "@abp/jquery-validation-unobtrusive" "~5.2.1"
- "@abp/lodash" "~5.2.1"
- "@abp/luxon" "~5.2.1"
- "@abp/malihu-custom-scrollbar-plugin" "~5.2.1"
- "@abp/select2" "~5.2.1"
- "@abp/sweetalert2" "~5.2.1"
- "@abp/timeago" "~5.2.1"
- "@abp/toastr" "~5.2.1"
-
-"@abp/aspnetcore.mvc.ui@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-5.2.1.tgz#239ceeec332cebe2fedec0bb0cdec09089b499d3"
- integrity sha512-VUSPOKjBSF+NxfwdsEVQte8u7mGP1t7jd1+ej2ND8JEKYJ1Vh7z2mfsT+lQaEJg0JWggU1AxkIMOOfHDNTU3Kg==
+"@abp/aspnetcore.mvc.ui.theme.shared@^5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-5.3.0-rc.1.tgz#ed993befe99682baee55ea8771f983980ba8f93f"
+ integrity sha512-kL4CXe0YoZ4wJ4XvutqLPkv4fMuFeRJFzdix6lx4dPAArnPu69n3P4qFhokPkcoGpB2KTRqyn9fHQs8g2FCGQw==
+ dependencies:
+ "@abp/aspnetcore.mvc.ui" "~5.3.0-rc.1"
+ "@abp/bootstrap" "~5.3.0-rc.1"
+ "@abp/bootstrap-datepicker" "~5.3.0-rc.1"
+ "@abp/datatables.net-bs5" "~5.3.0-rc.1"
+ "@abp/font-awesome" "~5.3.0-rc.1"
+ "@abp/jquery-form" "~5.3.0-rc.1"
+ "@abp/jquery-validation-unobtrusive" "~5.3.0-rc.1"
+ "@abp/lodash" "~5.3.0-rc.1"
+ "@abp/luxon" "~5.3.0-rc.1"
+ "@abp/malihu-custom-scrollbar-plugin" "~5.3.0-rc.1"
+ "@abp/select2" "~5.3.0-rc.1"
+ "@abp/sweetalert2" "~5.3.0-rc.1"
+ "@abp/timeago" "~5.3.0-rc.1"
+ "@abp/toastr" "~5.3.0-rc.1"
+
+"@abp/aspnetcore.mvc.ui@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-5.3.0-rc.1.tgz#5205d3a5ea500ff3b8d525dcc11a2ce4cfccdfd3"
+ integrity sha512-mIefq3QSVtP7heNl0ocHiSKLU+DwN5/TDvvPj2L3IZkCzuOrDxoBUIBIciea4k10HIQzqo6gmm1YOw0CEfzNHg==
dependencies:
ansi-colors "^4.1.1"
extend-object "^1.0.0"
@@ -34,144 +34,144 @@
merge-stream "^2.0.0"
micromatch "^4.0.2"
-"@abp/bootstrap-datepicker@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-5.2.1.tgz#20d565211d05ca184f8e3ef4db840dbd98a58fbd"
- integrity sha512-UPdVu9t7XybINSfonQN0DB9Lpz1r5vCz7F8CMpbjQprvPmsFmkAZyY0p6MS3kGO5eu5rlpGAGPBGOTeSfEp9ww==
+"@abp/bootstrap-datepicker@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-5.3.0-rc.1.tgz#1a5a29d7f9904e8d99c7085bc4545ad2665195cb"
+ integrity sha512-Y5QLLNd2UpbzbWSh+5nKdpAdz2i3V8+feTHTpAxnPgYRabPGqAFiOrty8KZ1MJEgjQFWC1ypGHYII7GWVyIS6Q==
dependencies:
bootstrap-datepicker "^1.9.0"
-"@abp/bootstrap@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-5.2.1.tgz#fe15144d7136a26be44be23fd2470cdef0bd28b9"
- integrity sha512-vFW8OxfRhiDkIrDVIn3TyGkGyiCLLFmPMjSOmMg3o2XPdRk5uhwSBzWYpk/m+kmPpP6cEsJMxaHpCsirSlPE+A==
+"@abp/bootstrap@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-5.3.0-rc.1.tgz#977d579f59e18b1eb2c9b43612d525a859a575a4"
+ integrity sha512-dpY0bPHdhUI5yL23+EsR6w/KjoPyehaEgHLLKQDERdubX1Zk/SDWrhrYXnXxtJ0fvxG2aRVOEBMULmHD3m/PoA==
dependencies:
- "@abp/core" "~5.2.1"
+ "@abp/core" "~5.3.0-rc.1"
bootstrap "^5.1.3"
-"@abp/core@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/core/-/core-5.2.1.tgz#9cd7f25dec0b4e654f7998f89c19f3d73169c74a"
- integrity sha512-FDOhIPjig3oGxkbadJZzFSC1ZHzgQV4R75fsDNH56lQ9mTyRUPQdg0Y54eCtY7yOSjiJOctOUUWHaxoFG7frGQ==
+"@abp/core@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/core/-/core-5.3.0-rc.1.tgz#4ede309ccfab440deb66fecb091273027483676a"
+ integrity sha512-cTw9xaWMkRDQjXRtkB5zx4Za0CPx7yvCRnTngIJs7xO86lRMVnuiwVGjP66vYTmiiu2ulGFgCeuw1AaK5t+g4Q==
dependencies:
- "@abp/utils" "~5.2.1"
+ "@abp/utils" "~5.3.0-rc.1"
-"@abp/datatables.net-bs5@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs5/-/datatables.net-bs5-5.2.1.tgz#fafc65295d00d5b351404740702f7e56ff1341fe"
- integrity sha512-B8lSAeMM9qOwYbDK/Dhp7BX5lFaCpao4RCPcSqgFrye8vlH8bcobmp4tMD23r24y/gRIEuQBcKzp0Lf0OUpLhA==
+"@abp/datatables.net-bs5@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs5/-/datatables.net-bs5-5.3.0-rc.1.tgz#ca624d788acdcc547d0bdf1f76ba3ffc105dfd52"
+ integrity sha512-uyFBkD9rM3wGve0ZKrr7bEbC0Z/ywi8S/EYL6GwLzGNtogSsVj5HGtSvifKjCBn7KmAvo54skKoVgVEn77dlWQ==
dependencies:
- "@abp/datatables.net" "~5.2.1"
+ "@abp/datatables.net" "~5.3.0-rc.1"
datatables.net-bs5 "^1.11.4"
-"@abp/datatables.net@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-5.2.1.tgz#397a3e7db2017c20c082598214478c277b2abec6"
- integrity sha512-6Q3+W+d8e4TMAkZr/IdPDQuL1v+tjbS50ChLvrJX/BLb4fBhu1LGJWWKzKJFj721DwIsuQQiM4uq9xX/TjiS0w==
+"@abp/datatables.net@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-5.3.0-rc.1.tgz#38c0f6323f7e6305a50f7de9885b8a3f440cdf15"
+ integrity sha512-lecJ9Yelgey/nfSscsUHET0gyB6pZgkhnJXu3u8d9XhV2M5sc/WSnnCO3bgVBqMDImprR4GFPFw2cUlWkb8QBg==
dependencies:
- "@abp/jquery" "~5.2.1"
+ "@abp/jquery" "~5.3.0-rc.1"
datatables.net "^1.11.4"
-"@abp/font-awesome@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-5.2.1.tgz#357785a0366f555b72f76e2b8ee8a2d607aed6fb"
- integrity sha512-9fAUdA9QeNRMjp6v8i6EOR480bjB4OzqzriFCKUu4k6VwbA6PxUsJIRFyKIt5UpC12Zqdhpkyj0iG6tE0nRekQ==
+"@abp/font-awesome@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-5.3.0-rc.1.tgz#de14dca2b33fdc098d2325c5047e030a3927bfa9"
+ integrity sha512-tIuDwo+L5CuLpQ+ARsaTYmxuqpSJLqcaXuoFfk6JAC20bw881t7y8w4xWy1PUs0+SEQwTT7diZjQrcA/xxlMUQ==
dependencies:
- "@abp/core" "~5.2.1"
+ "@abp/core" "~5.3.0-rc.1"
"@fortawesome/fontawesome-free" "^5.15.4"
-"@abp/jquery-form@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-5.2.1.tgz#c9cc6ad3997f7fa036d5cd8e0d15923ad7fff790"
- integrity sha512-L7uKs7vReOQEETG9xIDq5aXjshbaPa+ZZQcCbn2uwY813e0ErS7Rb1mnowEt/LNEB02AtLet1B4TDVwZUl1uXQ==
+"@abp/jquery-form@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-5.3.0-rc.1.tgz#0a363d8e4814651e0c46e2109d19dcc84fc884b0"
+ integrity sha512-IWazO6BW5rHJ+ODk4haEqWzfzHvbxtW2+T1o534Lr7d+LI9yabNiQmRZ24yzNDb6SmRvDUVsumZ+lxPn2WBhIw==
dependencies:
- "@abp/jquery" "~5.2.1"
+ "@abp/jquery" "~5.3.0-rc.1"
jquery-form "^4.3.0"
-"@abp/jquery-validation-unobtrusive@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-5.2.1.tgz#7fdfa3867f61f862ee575114560f79b505649093"
- integrity sha512-uZ36D1FfoLdBb6h44fQ3kZuTk4gJ5yzhyOprkgMsGAJDVakX7w/W4V3ThpiEO+iUpNKTboVIhW2QQ0AXK9rrsg==
+"@abp/jquery-validation-unobtrusive@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-5.3.0-rc.1.tgz#0aa2a5535acd79b5288ef04a0dc1b83a7a57b4b9"
+ integrity sha512-Qv/+nrd+ZeUs/2mCMahpQFqEguMOcmHrLg7hcw0LgcHr+MmEcG4WDcijTY6suFyekaf0DZD6vsFZjdvZmhsVYQ==
dependencies:
- "@abp/jquery-validation" "~5.2.1"
+ "@abp/jquery-validation" "~5.3.0-rc.1"
jquery-validation-unobtrusive "^3.2.12"
-"@abp/jquery-validation@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-5.2.1.tgz#e7fbaa1715af5667559e3b6f0fcb916766b28244"
- integrity sha512-Rr/+SWGlXJ53jfysMB/HVNZqsJKCF3rg23ip2Kg6Q+kQTvWVRE3tpkpoBJczOii5tPUk/A/lsJKgRlcsnP0ASw==
+"@abp/jquery-validation@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-5.3.0-rc.1.tgz#d05afbe0209c0815afe3a7cb0cf811256e9905fc"
+ integrity sha512-3DoRX6c8duRx1/g7MFuPAO/qesJCFqbVbw+x0+QnKmCkVZmz5VFAqdO9yFMxDFRbBAtyp7faaarc0lOtAcBsoA==
dependencies:
- "@abp/jquery" "~5.2.1"
+ "@abp/jquery" "~5.3.0-rc.1"
jquery-validation "^1.19.3"
-"@abp/jquery@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-5.2.1.tgz#6b88af5c22fb25d953d38847bcddcf591aeb3228"
- integrity sha512-FiIRnDx/gm6JR8QljiulwCc5d8+YC123X0qxMIBI8IY9vznEX+Jk48jYG8fLABnRqKEIYfV8UsYSK8IJx3mcSg==
+"@abp/jquery@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-5.3.0-rc.1.tgz#26e5d5761f2629d02b2534ad964080221d536308"
+ integrity sha512-//bqInarV6XOs8+I5GW1q/c05sjnCq/Z0vuzFW1i1NDrQ2Q5kqF5leMV9hhGEZmfR+yG1T0MsbVvueieRkV/cA==
dependencies:
- "@abp/core" "~5.2.1"
+ "@abp/core" "~5.3.0-rc.1"
jquery "~3.6.0"
-"@abp/lodash@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-5.2.1.tgz#87601162025a4a376e3c335d418636ef2079ad2d"
- integrity sha512-ILg3X5tTH2HhJMRmg7BP/r+Kstm/nf+0aNQ2exsJoMMnKE7CC0eYQjpSgrze6GwG3a13eamyTlrz+RrlIm5IBA==
+"@abp/lodash@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-5.3.0-rc.1.tgz#c53304fbd9b1c885a9a812c681c3698dd8ecea47"
+ integrity sha512-yBvUB05z/SSEEbZ79nFfb0cKwWVFbrt9OtUkQHy9ER7ip0R9escG2n1djFtAA33yZr/NLzSUh+vVBYsEhk8MOA==
dependencies:
- "@abp/core" "~5.2.1"
+ "@abp/core" "~5.3.0-rc.1"
lodash "^4.17.21"
-"@abp/luxon@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-5.2.1.tgz#72a9e9bb0e7f3a688662c8e9ad52016b9cfa3a17"
- integrity sha512-D3KVsba969UBYktdbCxq1JQp4kYZ1S7rIMymDJMBoHByXxwwdeXMkvuphAifBmSYTt3K6bNoZdR0VxtnNlPn2A==
+"@abp/luxon@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-5.3.0-rc.1.tgz#bcb4de01b20a8e4da8db186e88fdebfcde47fb8f"
+ integrity sha512-SLozcDvCL/2jyvG2ZU+DHjzbfHYdmwiRjWu7gWyNjaY2e6D3NraHHjpMQ7ubObXZRlhhvfcp0i6eeKKoZNJtEQ==
dependencies:
- "@abp/core" "~5.2.1"
+ "@abp/core" "~5.3.0-rc.1"
luxon "^2.3.0"
-"@abp/malihu-custom-scrollbar-plugin@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-5.2.1.tgz#8d1b600552607e28a274775ad3bb68ac7cfbba09"
- integrity sha512-5mvABMCT7tiwPl1vUK8kriN/SRi2gC4VqkEuxghT7uBQG9Cqh5jhJrl80M9ZK/oQFind3r6+SF8OlfwF8yvxHQ==
+"@abp/malihu-custom-scrollbar-plugin@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-5.3.0-rc.1.tgz#398181c7c6cc1805544e7a1ccd0423ed96005e0b"
+ integrity sha512-KZar881wtotKc+1bqDlBWo2vLUEeeqEpMBg8+BiXsGofp5ovudifVPM6mHZ9Gi29U9LAMyI0VEGwLJctgB/UoA==
dependencies:
- "@abp/core" "~5.2.1"
+ "@abp/core" "~5.3.0-rc.1"
malihu-custom-scrollbar-plugin "^3.1.5"
-"@abp/select2@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-5.2.1.tgz#f52a3c88da52bbfc4b135671064326aebb98b332"
- integrity sha512-JH/PqOxhTY05sUyN7of6TNai0W4M3N3OF3Hlwmr8i7hNdYfFwJvQnQzKeKrk/vt8Hv44/JTQDlNKU02BmSBfOQ==
+"@abp/select2@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-5.3.0-rc.1.tgz#b2ce00b6545674d6bccc10fdfe4626a4598a0cdc"
+ integrity sha512-frE5jia7bBdZinW4LqD5JR+wknWu2ARX3L3pPiQ080ulB+P58gRj07ZPd1BWgRcvutnuANYyP9rZtDA18Ls+9Q==
dependencies:
- "@abp/core" "~5.2.1"
+ "@abp/core" "~5.3.0-rc.1"
select2 "^4.0.13"
-"@abp/sweetalert2@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/sweetalert2/-/sweetalert2-5.2.1.tgz#f5ff712b4f7a4cb5a75a754aa4642f099f382e51"
- integrity sha512-laaF/5WhYw+hNJRTfMzO93fVhaYqnnOcQTUlkGgsZMe2gwebyX73VI8O8Xw7zXmN1Tu/JwqRI46qiafDrPFTLg==
+"@abp/sweetalert2@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/sweetalert2/-/sweetalert2-5.3.0-rc.1.tgz#6eb10b257e7f256da64ff6fe248a370671a26920"
+ integrity sha512-g9nddGcDGaG6EmjX7qpRcLzy3F38BTtFc0RBWApH7Da1o/LMYFYa6xGfS7ouIynZBM9j/BRP12CVTR+Y9qqbGg==
dependencies:
- "@abp/core" "~5.2.1"
+ "@abp/core" "~5.3.0-rc.1"
sweetalert2 "^11.3.6"
-"@abp/timeago@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-5.2.1.tgz#a410dbf652c0f78f86384e116111aa613458b6de"
- integrity sha512-xmgqKEKusB6pcqFhMaz8RTi886ad8RrRMYgMWSw4Zjk1Lr9EqQwKtcE43Ve5XWJamh2Wpk8H7IKLQKHfrV12oA==
+"@abp/timeago@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-5.3.0-rc.1.tgz#2702a0f22db52dbf4c0717e4abcd317c56d10563"
+ integrity sha512-XRc4D98FIZR0YTXIoV0+OxVJTdixtNDiwatZRffopHT4Kpptmpj6O9KMcB4SngCH99/TrUFdEUnA2CgszxiEOA==
dependencies:
- "@abp/jquery" "~5.2.1"
+ "@abp/jquery" "~5.3.0-rc.1"
timeago "^1.6.7"
-"@abp/toastr@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/toastr/-/toastr-5.2.1.tgz#4ed96a7967d028b8e849ff79b8a0a8a041bb20e4"
- integrity sha512-HrnIzvM9LgQdzlmLmvHUVSG4PmWfx9YuozxkFTv+AGa2FAPby5W9hbQ025ry3bPkU9lGWSu/w7JSDqoiL16bPA==
+"@abp/toastr@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/toastr/-/toastr-5.3.0-rc.1.tgz#ec3a3d302ac91d5393c3caeb8b4884ad811b6edb"
+ integrity sha512-InZweYuBkrNZNBQKp6A+6gxGdO/lB0XsrXaa+CIVe55p8aNJPzE0mnvSfKWhN5G273wR08AD9RjR22kYS+bgFA==
dependencies:
- "@abp/jquery" "~5.2.1"
+ "@abp/jquery" "~5.3.0-rc.1"
toastr "^2.1.4"
-"@abp/utils@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-5.2.1.tgz#7c2d20f1bcc8cf9f90c060ed31ed3a114a463064"
- integrity sha512-9hxI24aRZCnxCP+WsOoCltSg4YqG9WtW06t9/f6hFO9B0udXIKyV+95Ndipca/R1G94Snx81ifSwAa+DHbFfvQ==
+"@abp/utils@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-5.3.0-rc.1.tgz#3fa758944e7325e7b3f528141e03bb71f8e04d24"
+ integrity sha512-/8BTYZomNMdy+RpYXWLp5dg0lRhmfiguciZEVWo4qRw1lCXm/JR+0842XT1XYE1dQ4orNNJ3/H86eRX8Ab6Yfg==
dependencies:
just-compare "^1.3.0"
diff --git a/modules/basic-theme/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/package.json b/modules/basic-theme/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/package.json
index 4caf5c1672..302de41fa4 100644
--- a/modules/basic-theme/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/package.json
+++ b/modules/basic-theme/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/package.json
@@ -3,8 +3,8 @@
"name": "asp.net",
"private": true,
"dependencies": {
- "@abp/aspnetcore.mvc.ui.theme.basic": "^5.2.1",
- "@abp/prismjs": "^5.2.1"
+ "@abp/aspnetcore.mvc.ui.theme.basic": "^5.3.0-rc.1",
+ "@abp/prismjs": "^5.3.0-rc.1"
},
"devDependencies": {}
}
diff --git a/modules/basic-theme/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/yarn.lock b/modules/basic-theme/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/yarn.lock
index 407c79dba3..b06a3e49a6 100644
--- a/modules/basic-theme/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/yarn.lock
+++ b/modules/basic-theme/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/yarn.lock
@@ -2,37 +2,37 @@
# yarn lockfile v1
-"@abp/aspnetcore.mvc.ui.theme.basic@^5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-5.2.1.tgz#25bd7116b9b0e72ba45f0f5246343343de8561b2"
- integrity sha512-DYr9ROcTPfCRHxD1QSWqLZ9+ARbO5p9I6SRo893NtJ39aHacAa9RIAwZmP0JLG0C4hLXfJLKXJ2DpNcwY+ubXA==
- dependencies:
- "@abp/aspnetcore.mvc.ui.theme.shared" "~5.2.1"
-
-"@abp/aspnetcore.mvc.ui.theme.shared@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-5.2.1.tgz#dc291fe9c7100cc796068e19abf7579bd5e54b44"
- integrity sha512-/1C5RyPIRPZT5ir8Len2EnSt1KfWcRdPyn/avAG+9JKBZ8FoUL8mO2/ffESOvikh/wItZZgxJ5VEJVGwHNjgdQ==
- dependencies:
- "@abp/aspnetcore.mvc.ui" "~5.2.1"
- "@abp/bootstrap" "~5.2.1"
- "@abp/bootstrap-datepicker" "~5.2.1"
- "@abp/datatables.net-bs5" "~5.2.1"
- "@abp/font-awesome" "~5.2.1"
- "@abp/jquery-form" "~5.2.1"
- "@abp/jquery-validation-unobtrusive" "~5.2.1"
- "@abp/lodash" "~5.2.1"
- "@abp/luxon" "~5.2.1"
- "@abp/malihu-custom-scrollbar-plugin" "~5.2.1"
- "@abp/select2" "~5.2.1"
- "@abp/sweetalert2" "~5.2.1"
- "@abp/timeago" "~5.2.1"
- "@abp/toastr" "~5.2.1"
-
-"@abp/aspnetcore.mvc.ui@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-5.2.1.tgz#239ceeec332cebe2fedec0bb0cdec09089b499d3"
- integrity sha512-VUSPOKjBSF+NxfwdsEVQte8u7mGP1t7jd1+ej2ND8JEKYJ1Vh7z2mfsT+lQaEJg0JWggU1AxkIMOOfHDNTU3Kg==
+"@abp/aspnetcore.mvc.ui.theme.basic@^5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-5.3.0-rc.1.tgz#dc27eb79ba7353eb6b16e4a2f50d17c3cfc9157d"
+ integrity sha512-TEbz/ISsGhfTec66XSeivQjCOCpTidufdpZmj8JRyrbQvhXOYohJs3ImrGJOIxUwo6nuzagGpotqXryjIF+jrg==
+ dependencies:
+ "@abp/aspnetcore.mvc.ui.theme.shared" "~5.3.0-rc.1"
+
+"@abp/aspnetcore.mvc.ui.theme.shared@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-5.3.0-rc.1.tgz#ed993befe99682baee55ea8771f983980ba8f93f"
+ integrity sha512-kL4CXe0YoZ4wJ4XvutqLPkv4fMuFeRJFzdix6lx4dPAArnPu69n3P4qFhokPkcoGpB2KTRqyn9fHQs8g2FCGQw==
+ dependencies:
+ "@abp/aspnetcore.mvc.ui" "~5.3.0-rc.1"
+ "@abp/bootstrap" "~5.3.0-rc.1"
+ "@abp/bootstrap-datepicker" "~5.3.0-rc.1"
+ "@abp/datatables.net-bs5" "~5.3.0-rc.1"
+ "@abp/font-awesome" "~5.3.0-rc.1"
+ "@abp/jquery-form" "~5.3.0-rc.1"
+ "@abp/jquery-validation-unobtrusive" "~5.3.0-rc.1"
+ "@abp/lodash" "~5.3.0-rc.1"
+ "@abp/luxon" "~5.3.0-rc.1"
+ "@abp/malihu-custom-scrollbar-plugin" "~5.3.0-rc.1"
+ "@abp/select2" "~5.3.0-rc.1"
+ "@abp/sweetalert2" "~5.3.0-rc.1"
+ "@abp/timeago" "~5.3.0-rc.1"
+ "@abp/toastr" "~5.3.0-rc.1"
+
+"@abp/aspnetcore.mvc.ui@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-5.3.0-rc.1.tgz#5205d3a5ea500ff3b8d525dcc11a2ce4cfccdfd3"
+ integrity sha512-mIefq3QSVtP7heNl0ocHiSKLU+DwN5/TDvvPj2L3IZkCzuOrDxoBUIBIciea4k10HIQzqo6gmm1YOw0CEfzNHg==
dependencies:
ansi-colors "^4.1.1"
extend-object "^1.0.0"
@@ -41,161 +41,161 @@
merge-stream "^2.0.0"
micromatch "^4.0.2"
-"@abp/bootstrap-datepicker@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-5.2.1.tgz#20d565211d05ca184f8e3ef4db840dbd98a58fbd"
- integrity sha512-UPdVu9t7XybINSfonQN0DB9Lpz1r5vCz7F8CMpbjQprvPmsFmkAZyY0p6MS3kGO5eu5rlpGAGPBGOTeSfEp9ww==
+"@abp/bootstrap-datepicker@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-5.3.0-rc.1.tgz#1a5a29d7f9904e8d99c7085bc4545ad2665195cb"
+ integrity sha512-Y5QLLNd2UpbzbWSh+5nKdpAdz2i3V8+feTHTpAxnPgYRabPGqAFiOrty8KZ1MJEgjQFWC1ypGHYII7GWVyIS6Q==
dependencies:
bootstrap-datepicker "^1.9.0"
-"@abp/bootstrap@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-5.2.1.tgz#fe15144d7136a26be44be23fd2470cdef0bd28b9"
- integrity sha512-vFW8OxfRhiDkIrDVIn3TyGkGyiCLLFmPMjSOmMg3o2XPdRk5uhwSBzWYpk/m+kmPpP6cEsJMxaHpCsirSlPE+A==
+"@abp/bootstrap@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-5.3.0-rc.1.tgz#977d579f59e18b1eb2c9b43612d525a859a575a4"
+ integrity sha512-dpY0bPHdhUI5yL23+EsR6w/KjoPyehaEgHLLKQDERdubX1Zk/SDWrhrYXnXxtJ0fvxG2aRVOEBMULmHD3m/PoA==
dependencies:
- "@abp/core" "~5.2.1"
+ "@abp/core" "~5.3.0-rc.1"
bootstrap "^5.1.3"
-"@abp/clipboard@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/clipboard/-/clipboard-5.2.1.tgz#c6bddd279b37e9b2bd27b027d5686411c9ae942b"
- integrity sha512-aouNTDz8t+8M4O2a+UsEdtABRsyhvzGpXqCG2+LYE1vA3I+CKhglkvEFp+GyIgWsipEHY1U1w6V3qZtcRINn+A==
+"@abp/clipboard@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/clipboard/-/clipboard-5.3.0-rc.1.tgz#da893847d2d86f53f99dfefc8898d14410d45600"
+ integrity sha512-Eqkgd3ZJXHE5xovfb+2SzGxzISCjzLsGYSV/uZs2BYVfyIZ0+D2Jx0jOT8j8oVPAlRTCCMAbvoxMKZJZr/WC0Q==
dependencies:
- "@abp/core" "~5.2.1"
+ "@abp/core" "~5.3.0-rc.1"
clipboard "^2.0.8"
-"@abp/core@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/core/-/core-5.2.1.tgz#9cd7f25dec0b4e654f7998f89c19f3d73169c74a"
- integrity sha512-FDOhIPjig3oGxkbadJZzFSC1ZHzgQV4R75fsDNH56lQ9mTyRUPQdg0Y54eCtY7yOSjiJOctOUUWHaxoFG7frGQ==
+"@abp/core@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/core/-/core-5.3.0-rc.1.tgz#4ede309ccfab440deb66fecb091273027483676a"
+ integrity sha512-cTw9xaWMkRDQjXRtkB5zx4Za0CPx7yvCRnTngIJs7xO86lRMVnuiwVGjP66vYTmiiu2ulGFgCeuw1AaK5t+g4Q==
dependencies:
- "@abp/utils" "~5.2.1"
+ "@abp/utils" "~5.3.0-rc.1"
-"@abp/datatables.net-bs5@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs5/-/datatables.net-bs5-5.2.1.tgz#fafc65295d00d5b351404740702f7e56ff1341fe"
- integrity sha512-B8lSAeMM9qOwYbDK/Dhp7BX5lFaCpao4RCPcSqgFrye8vlH8bcobmp4tMD23r24y/gRIEuQBcKzp0Lf0OUpLhA==
+"@abp/datatables.net-bs5@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs5/-/datatables.net-bs5-5.3.0-rc.1.tgz#ca624d788acdcc547d0bdf1f76ba3ffc105dfd52"
+ integrity sha512-uyFBkD9rM3wGve0ZKrr7bEbC0Z/ywi8S/EYL6GwLzGNtogSsVj5HGtSvifKjCBn7KmAvo54skKoVgVEn77dlWQ==
dependencies:
- "@abp/datatables.net" "~5.2.1"
+ "@abp/datatables.net" "~5.3.0-rc.1"
datatables.net-bs5 "^1.11.4"
-"@abp/datatables.net@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-5.2.1.tgz#397a3e7db2017c20c082598214478c277b2abec6"
- integrity sha512-6Q3+W+d8e4TMAkZr/IdPDQuL1v+tjbS50ChLvrJX/BLb4fBhu1LGJWWKzKJFj721DwIsuQQiM4uq9xX/TjiS0w==
+"@abp/datatables.net@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-5.3.0-rc.1.tgz#38c0f6323f7e6305a50f7de9885b8a3f440cdf15"
+ integrity sha512-lecJ9Yelgey/nfSscsUHET0gyB6pZgkhnJXu3u8d9XhV2M5sc/WSnnCO3bgVBqMDImprR4GFPFw2cUlWkb8QBg==
dependencies:
- "@abp/jquery" "~5.2.1"
+ "@abp/jquery" "~5.3.0-rc.1"
datatables.net "^1.11.4"
-"@abp/font-awesome@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-5.2.1.tgz#357785a0366f555b72f76e2b8ee8a2d607aed6fb"
- integrity sha512-9fAUdA9QeNRMjp6v8i6EOR480bjB4OzqzriFCKUu4k6VwbA6PxUsJIRFyKIt5UpC12Zqdhpkyj0iG6tE0nRekQ==
+"@abp/font-awesome@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-5.3.0-rc.1.tgz#de14dca2b33fdc098d2325c5047e030a3927bfa9"
+ integrity sha512-tIuDwo+L5CuLpQ+ARsaTYmxuqpSJLqcaXuoFfk6JAC20bw881t7y8w4xWy1PUs0+SEQwTT7diZjQrcA/xxlMUQ==
dependencies:
- "@abp/core" "~5.2.1"
+ "@abp/core" "~5.3.0-rc.1"
"@fortawesome/fontawesome-free" "^5.15.4"
-"@abp/jquery-form@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-5.2.1.tgz#c9cc6ad3997f7fa036d5cd8e0d15923ad7fff790"
- integrity sha512-L7uKs7vReOQEETG9xIDq5aXjshbaPa+ZZQcCbn2uwY813e0ErS7Rb1mnowEt/LNEB02AtLet1B4TDVwZUl1uXQ==
+"@abp/jquery-form@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-5.3.0-rc.1.tgz#0a363d8e4814651e0c46e2109d19dcc84fc884b0"
+ integrity sha512-IWazO6BW5rHJ+ODk4haEqWzfzHvbxtW2+T1o534Lr7d+LI9yabNiQmRZ24yzNDb6SmRvDUVsumZ+lxPn2WBhIw==
dependencies:
- "@abp/jquery" "~5.2.1"
+ "@abp/jquery" "~5.3.0-rc.1"
jquery-form "^4.3.0"
-"@abp/jquery-validation-unobtrusive@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-5.2.1.tgz#7fdfa3867f61f862ee575114560f79b505649093"
- integrity sha512-uZ36D1FfoLdBb6h44fQ3kZuTk4gJ5yzhyOprkgMsGAJDVakX7w/W4V3ThpiEO+iUpNKTboVIhW2QQ0AXK9rrsg==
+"@abp/jquery-validation-unobtrusive@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-5.3.0-rc.1.tgz#0aa2a5535acd79b5288ef04a0dc1b83a7a57b4b9"
+ integrity sha512-Qv/+nrd+ZeUs/2mCMahpQFqEguMOcmHrLg7hcw0LgcHr+MmEcG4WDcijTY6suFyekaf0DZD6vsFZjdvZmhsVYQ==
dependencies:
- "@abp/jquery-validation" "~5.2.1"
+ "@abp/jquery-validation" "~5.3.0-rc.1"
jquery-validation-unobtrusive "^3.2.12"
-"@abp/jquery-validation@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-5.2.1.tgz#e7fbaa1715af5667559e3b6f0fcb916766b28244"
- integrity sha512-Rr/+SWGlXJ53jfysMB/HVNZqsJKCF3rg23ip2Kg6Q+kQTvWVRE3tpkpoBJczOii5tPUk/A/lsJKgRlcsnP0ASw==
+"@abp/jquery-validation@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-5.3.0-rc.1.tgz#d05afbe0209c0815afe3a7cb0cf811256e9905fc"
+ integrity sha512-3DoRX6c8duRx1/g7MFuPAO/qesJCFqbVbw+x0+QnKmCkVZmz5VFAqdO9yFMxDFRbBAtyp7faaarc0lOtAcBsoA==
dependencies:
- "@abp/jquery" "~5.2.1"
+ "@abp/jquery" "~5.3.0-rc.1"
jquery-validation "^1.19.3"
-"@abp/jquery@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-5.2.1.tgz#6b88af5c22fb25d953d38847bcddcf591aeb3228"
- integrity sha512-FiIRnDx/gm6JR8QljiulwCc5d8+YC123X0qxMIBI8IY9vznEX+Jk48jYG8fLABnRqKEIYfV8UsYSK8IJx3mcSg==
+"@abp/jquery@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-5.3.0-rc.1.tgz#26e5d5761f2629d02b2534ad964080221d536308"
+ integrity sha512-//bqInarV6XOs8+I5GW1q/c05sjnCq/Z0vuzFW1i1NDrQ2Q5kqF5leMV9hhGEZmfR+yG1T0MsbVvueieRkV/cA==
dependencies:
- "@abp/core" "~5.2.1"
+ "@abp/core" "~5.3.0-rc.1"
jquery "~3.6.0"
-"@abp/lodash@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-5.2.1.tgz#87601162025a4a376e3c335d418636ef2079ad2d"
- integrity sha512-ILg3X5tTH2HhJMRmg7BP/r+Kstm/nf+0aNQ2exsJoMMnKE7CC0eYQjpSgrze6GwG3a13eamyTlrz+RrlIm5IBA==
+"@abp/lodash@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-5.3.0-rc.1.tgz#c53304fbd9b1c885a9a812c681c3698dd8ecea47"
+ integrity sha512-yBvUB05z/SSEEbZ79nFfb0cKwWVFbrt9OtUkQHy9ER7ip0R9escG2n1djFtAA33yZr/NLzSUh+vVBYsEhk8MOA==
dependencies:
- "@abp/core" "~5.2.1"
+ "@abp/core" "~5.3.0-rc.1"
lodash "^4.17.21"
-"@abp/luxon@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-5.2.1.tgz#72a9e9bb0e7f3a688662c8e9ad52016b9cfa3a17"
- integrity sha512-D3KVsba969UBYktdbCxq1JQp4kYZ1S7rIMymDJMBoHByXxwwdeXMkvuphAifBmSYTt3K6bNoZdR0VxtnNlPn2A==
+"@abp/luxon@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-5.3.0-rc.1.tgz#bcb4de01b20a8e4da8db186e88fdebfcde47fb8f"
+ integrity sha512-SLozcDvCL/2jyvG2ZU+DHjzbfHYdmwiRjWu7gWyNjaY2e6D3NraHHjpMQ7ubObXZRlhhvfcp0i6eeKKoZNJtEQ==
dependencies:
- "@abp/core" "~5.2.1"
+ "@abp/core" "~5.3.0-rc.1"
luxon "^2.3.0"
-"@abp/malihu-custom-scrollbar-plugin@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-5.2.1.tgz#8d1b600552607e28a274775ad3bb68ac7cfbba09"
- integrity sha512-5mvABMCT7tiwPl1vUK8kriN/SRi2gC4VqkEuxghT7uBQG9Cqh5jhJrl80M9ZK/oQFind3r6+SF8OlfwF8yvxHQ==
+"@abp/malihu-custom-scrollbar-plugin@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-5.3.0-rc.1.tgz#398181c7c6cc1805544e7a1ccd0423ed96005e0b"
+ integrity sha512-KZar881wtotKc+1bqDlBWo2vLUEeeqEpMBg8+BiXsGofp5ovudifVPM6mHZ9Gi29U9LAMyI0VEGwLJctgB/UoA==
dependencies:
- "@abp/core" "~5.2.1"
+ "@abp/core" "~5.3.0-rc.1"
malihu-custom-scrollbar-plugin "^3.1.5"
-"@abp/prismjs@^5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/prismjs/-/prismjs-5.2.1.tgz#86aae6ee4529401da75744f1e43c7cd3c0b494a0"
- integrity sha512-YNgcM7Kvmu3hGXJh4B8gl7rLzC28VuZYYP7AVptVSbTz/n6usCo21evG/st8L3vXixuQkvnNpBFgacJnHdSJZQ==
+"@abp/prismjs@^5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/prismjs/-/prismjs-5.3.0-rc.1.tgz#ee1a49b8bd0af2a29aa7bfb93d22ce07a4edbe70"
+ integrity sha512-oOnzwUtI6q2u7iE/YWQEULm1I+f7Bo+0tQ9rYlzIoalBRnqN57Zw0VMf5AHq8qjn6GiInehPtU9wsaVTPqXmtw==
dependencies:
- "@abp/clipboard" "~5.2.1"
- "@abp/core" "~5.2.1"
+ "@abp/clipboard" "~5.3.0-rc.1"
+ "@abp/core" "~5.3.0-rc.1"
prismjs "^1.26.0"
-"@abp/select2@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-5.2.1.tgz#f52a3c88da52bbfc4b135671064326aebb98b332"
- integrity sha512-JH/PqOxhTY05sUyN7of6TNai0W4M3N3OF3Hlwmr8i7hNdYfFwJvQnQzKeKrk/vt8Hv44/JTQDlNKU02BmSBfOQ==
+"@abp/select2@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-5.3.0-rc.1.tgz#b2ce00b6545674d6bccc10fdfe4626a4598a0cdc"
+ integrity sha512-frE5jia7bBdZinW4LqD5JR+wknWu2ARX3L3pPiQ080ulB+P58gRj07ZPd1BWgRcvutnuANYyP9rZtDA18Ls+9Q==
dependencies:
- "@abp/core" "~5.2.1"
+ "@abp/core" "~5.3.0-rc.1"
select2 "^4.0.13"
-"@abp/sweetalert2@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/sweetalert2/-/sweetalert2-5.2.1.tgz#f5ff712b4f7a4cb5a75a754aa4642f099f382e51"
- integrity sha512-laaF/5WhYw+hNJRTfMzO93fVhaYqnnOcQTUlkGgsZMe2gwebyX73VI8O8Xw7zXmN1Tu/JwqRI46qiafDrPFTLg==
+"@abp/sweetalert2@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/sweetalert2/-/sweetalert2-5.3.0-rc.1.tgz#6eb10b257e7f256da64ff6fe248a370671a26920"
+ integrity sha512-g9nddGcDGaG6EmjX7qpRcLzy3F38BTtFc0RBWApH7Da1o/LMYFYa6xGfS7ouIynZBM9j/BRP12CVTR+Y9qqbGg==
dependencies:
- "@abp/core" "~5.2.1"
+ "@abp/core" "~5.3.0-rc.1"
sweetalert2 "^11.3.6"
-"@abp/timeago@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-5.2.1.tgz#a410dbf652c0f78f86384e116111aa613458b6de"
- integrity sha512-xmgqKEKusB6pcqFhMaz8RTi886ad8RrRMYgMWSw4Zjk1Lr9EqQwKtcE43Ve5XWJamh2Wpk8H7IKLQKHfrV12oA==
+"@abp/timeago@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-5.3.0-rc.1.tgz#2702a0f22db52dbf4c0717e4abcd317c56d10563"
+ integrity sha512-XRc4D98FIZR0YTXIoV0+OxVJTdixtNDiwatZRffopHT4Kpptmpj6O9KMcB4SngCH99/TrUFdEUnA2CgszxiEOA==
dependencies:
- "@abp/jquery" "~5.2.1"
+ "@abp/jquery" "~5.3.0-rc.1"
timeago "^1.6.7"
-"@abp/toastr@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/toastr/-/toastr-5.2.1.tgz#4ed96a7967d028b8e849ff79b8a0a8a041bb20e4"
- integrity sha512-HrnIzvM9LgQdzlmLmvHUVSG4PmWfx9YuozxkFTv+AGa2FAPby5W9hbQ025ry3bPkU9lGWSu/w7JSDqoiL16bPA==
+"@abp/toastr@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/toastr/-/toastr-5.3.0-rc.1.tgz#ec3a3d302ac91d5393c3caeb8b4884ad811b6edb"
+ integrity sha512-InZweYuBkrNZNBQKp6A+6gxGdO/lB0XsrXaa+CIVe55p8aNJPzE0mnvSfKWhN5G273wR08AD9RjR22kYS+bgFA==
dependencies:
- "@abp/jquery" "~5.2.1"
+ "@abp/jquery" "~5.3.0-rc.1"
toastr "^2.1.4"
-"@abp/utils@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-5.2.1.tgz#7c2d20f1bcc8cf9f90c060ed31ed3a114a463064"
- integrity sha512-9hxI24aRZCnxCP+WsOoCltSg4YqG9WtW06t9/f6hFO9B0udXIKyV+95Ndipca/R1G94Snx81ifSwAa+DHbFfvQ==
+"@abp/utils@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-5.3.0-rc.1.tgz#3fa758944e7325e7b3f528141e03bb71f8e04d24"
+ integrity sha512-/8BTYZomNMdy+RpYXWLp5dg0lRhmfiguciZEVWo4qRw1lCXm/JR+0842XT1XYE1dQ4orNNJ3/H86eRX8Ab6Yfg==
dependencies:
just-compare "^1.3.0"
diff --git a/modules/blogging/app/Volo.BloggingTestApp/package.json b/modules/blogging/app/Volo.BloggingTestApp/package.json
index 1d0e320c39..d25e7b6f31 100644
--- a/modules/blogging/app/Volo.BloggingTestApp/package.json
+++ b/modules/blogging/app/Volo.BloggingTestApp/package.json
@@ -3,7 +3,7 @@
"name": "volo.blogtestapp",
"private": true,
"dependencies": {
- "@abp/aspnetcore.mvc.ui.theme.basic": "^5.2.1",
- "@abp/blogging": "^5.2.1"
+ "@abp/aspnetcore.mvc.ui.theme.basic": "^5.3.0-rc.1",
+ "@abp/blogging": "^5.3.0-rc.1"
}
}
\ No newline at end of file
diff --git a/modules/blogging/app/Volo.BloggingTestApp/yarn.lock b/modules/blogging/app/Volo.BloggingTestApp/yarn.lock
index 08c5aba314..003c3aa68d 100644
--- a/modules/blogging/app/Volo.BloggingTestApp/yarn.lock
+++ b/modules/blogging/app/Volo.BloggingTestApp/yarn.lock
@@ -2,37 +2,37 @@
# yarn lockfile v1
-"@abp/aspnetcore.mvc.ui.theme.basic@^5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-5.2.1.tgz#25bd7116b9b0e72ba45f0f5246343343de8561b2"
- integrity sha512-DYr9ROcTPfCRHxD1QSWqLZ9+ARbO5p9I6SRo893NtJ39aHacAa9RIAwZmP0JLG0C4hLXfJLKXJ2DpNcwY+ubXA==
- dependencies:
- "@abp/aspnetcore.mvc.ui.theme.shared" "~5.2.1"
-
-"@abp/aspnetcore.mvc.ui.theme.shared@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-5.2.1.tgz#dc291fe9c7100cc796068e19abf7579bd5e54b44"
- integrity sha512-/1C5RyPIRPZT5ir8Len2EnSt1KfWcRdPyn/avAG+9JKBZ8FoUL8mO2/ffESOvikh/wItZZgxJ5VEJVGwHNjgdQ==
- dependencies:
- "@abp/aspnetcore.mvc.ui" "~5.2.1"
- "@abp/bootstrap" "~5.2.1"
- "@abp/bootstrap-datepicker" "~5.2.1"
- "@abp/datatables.net-bs5" "~5.2.1"
- "@abp/font-awesome" "~5.2.1"
- "@abp/jquery-form" "~5.2.1"
- "@abp/jquery-validation-unobtrusive" "~5.2.1"
- "@abp/lodash" "~5.2.1"
- "@abp/luxon" "~5.2.1"
- "@abp/malihu-custom-scrollbar-plugin" "~5.2.1"
- "@abp/select2" "~5.2.1"
- "@abp/sweetalert2" "~5.2.1"
- "@abp/timeago" "~5.2.1"
- "@abp/toastr" "~5.2.1"
-
-"@abp/aspnetcore.mvc.ui@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-5.2.1.tgz#239ceeec332cebe2fedec0bb0cdec09089b499d3"
- integrity sha512-VUSPOKjBSF+NxfwdsEVQte8u7mGP1t7jd1+ej2ND8JEKYJ1Vh7z2mfsT+lQaEJg0JWggU1AxkIMOOfHDNTU3Kg==
+"@abp/aspnetcore.mvc.ui.theme.basic@^5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-5.3.0-rc.1.tgz#dc27eb79ba7353eb6b16e4a2f50d17c3cfc9157d"
+ integrity sha512-TEbz/ISsGhfTec66XSeivQjCOCpTidufdpZmj8JRyrbQvhXOYohJs3ImrGJOIxUwo6nuzagGpotqXryjIF+jrg==
+ dependencies:
+ "@abp/aspnetcore.mvc.ui.theme.shared" "~5.3.0-rc.1"
+
+"@abp/aspnetcore.mvc.ui.theme.shared@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-5.3.0-rc.1.tgz#ed993befe99682baee55ea8771f983980ba8f93f"
+ integrity sha512-kL4CXe0YoZ4wJ4XvutqLPkv4fMuFeRJFzdix6lx4dPAArnPu69n3P4qFhokPkcoGpB2KTRqyn9fHQs8g2FCGQw==
+ dependencies:
+ "@abp/aspnetcore.mvc.ui" "~5.3.0-rc.1"
+ "@abp/bootstrap" "~5.3.0-rc.1"
+ "@abp/bootstrap-datepicker" "~5.3.0-rc.1"
+ "@abp/datatables.net-bs5" "~5.3.0-rc.1"
+ "@abp/font-awesome" "~5.3.0-rc.1"
+ "@abp/jquery-form" "~5.3.0-rc.1"
+ "@abp/jquery-validation-unobtrusive" "~5.3.0-rc.1"
+ "@abp/lodash" "~5.3.0-rc.1"
+ "@abp/luxon" "~5.3.0-rc.1"
+ "@abp/malihu-custom-scrollbar-plugin" "~5.3.0-rc.1"
+ "@abp/select2" "~5.3.0-rc.1"
+ "@abp/sweetalert2" "~5.3.0-rc.1"
+ "@abp/timeago" "~5.3.0-rc.1"
+ "@abp/toastr" "~5.3.0-rc.1"
+
+"@abp/aspnetcore.mvc.ui@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-5.3.0-rc.1.tgz#5205d3a5ea500ff3b8d525dcc11a2ce4cfccdfd3"
+ integrity sha512-mIefq3QSVtP7heNl0ocHiSKLU+DwN5/TDvvPj2L3IZkCzuOrDxoBUIBIciea4k10HIQzqo6gmm1YOw0CEfzNHg==
dependencies:
ansi-colors "^4.1.1"
extend-object "^1.0.0"
@@ -41,187 +41,187 @@
merge-stream "^2.0.0"
micromatch "^4.0.2"
-"@abp/blogging@^5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/blogging/-/blogging-5.2.1.tgz#5b9c98d120293a835c0a0cb27b1764be849140d9"
- integrity sha512-p2AamTCbBZkbqJKZ341JXYnzvJm4vCkT1gTZPNY49tMNa5brl2oFloI+tk491JHHaNz4lpHGFpPzQftjLPdTew==
+"@abp/blogging@^5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/blogging/-/blogging-5.3.0-rc.1.tgz#a5c7cea988c167d477e858d9488e7e4f12d26d34"
+ integrity sha512-ABMBP+oqyWwndHdqsorQaclMd2EmKTb6uT1KKWYmsv/Q+mmGEIhGUH2vIT+HrYoFvyj5o3Bedw+rPzqxjL3H9w==
dependencies:
- "@abp/aspnetcore.mvc.ui.theme.shared" "~5.2.1"
- "@abp/owl.carousel" "~5.2.1"
- "@abp/prismjs" "~5.2.1"
- "@abp/tui-editor" "~5.2.1"
+ "@abp/aspnetcore.mvc.ui.theme.shared" "~5.3.0-rc.1"
+ "@abp/owl.carousel" "~5.3.0-rc.1"
+ "@abp/prismjs" "~5.3.0-rc.1"
+ "@abp/tui-editor" "~5.3.0-rc.1"
-"@abp/bootstrap-datepicker@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-5.2.1.tgz#20d565211d05ca184f8e3ef4db840dbd98a58fbd"
- integrity sha512-UPdVu9t7XybINSfonQN0DB9Lpz1r5vCz7F8CMpbjQprvPmsFmkAZyY0p6MS3kGO5eu5rlpGAGPBGOTeSfEp9ww==
+"@abp/bootstrap-datepicker@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-5.3.0-rc.1.tgz#1a5a29d7f9904e8d99c7085bc4545ad2665195cb"
+ integrity sha512-Y5QLLNd2UpbzbWSh+5nKdpAdz2i3V8+feTHTpAxnPgYRabPGqAFiOrty8KZ1MJEgjQFWC1ypGHYII7GWVyIS6Q==
dependencies:
bootstrap-datepicker "^1.9.0"
-"@abp/bootstrap@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-5.2.1.tgz#fe15144d7136a26be44be23fd2470cdef0bd28b9"
- integrity sha512-vFW8OxfRhiDkIrDVIn3TyGkGyiCLLFmPMjSOmMg3o2XPdRk5uhwSBzWYpk/m+kmPpP6cEsJMxaHpCsirSlPE+A==
+"@abp/bootstrap@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-5.3.0-rc.1.tgz#977d579f59e18b1eb2c9b43612d525a859a575a4"
+ integrity sha512-dpY0bPHdhUI5yL23+EsR6w/KjoPyehaEgHLLKQDERdubX1Zk/SDWrhrYXnXxtJ0fvxG2aRVOEBMULmHD3m/PoA==
dependencies:
- "@abp/core" "~5.2.1"
+ "@abp/core" "~5.3.0-rc.1"
bootstrap "^5.1.3"
-"@abp/clipboard@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/clipboard/-/clipboard-5.2.1.tgz#c6bddd279b37e9b2bd27b027d5686411c9ae942b"
- integrity sha512-aouNTDz8t+8M4O2a+UsEdtABRsyhvzGpXqCG2+LYE1vA3I+CKhglkvEFp+GyIgWsipEHY1U1w6V3qZtcRINn+A==
+"@abp/clipboard@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/clipboard/-/clipboard-5.3.0-rc.1.tgz#da893847d2d86f53f99dfefc8898d14410d45600"
+ integrity sha512-Eqkgd3ZJXHE5xovfb+2SzGxzISCjzLsGYSV/uZs2BYVfyIZ0+D2Jx0jOT8j8oVPAlRTCCMAbvoxMKZJZr/WC0Q==
dependencies:
- "@abp/core" "~5.2.1"
+ "@abp/core" "~5.3.0-rc.1"
clipboard "^2.0.8"
-"@abp/core@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/core/-/core-5.2.1.tgz#9cd7f25dec0b4e654f7998f89c19f3d73169c74a"
- integrity sha512-FDOhIPjig3oGxkbadJZzFSC1ZHzgQV4R75fsDNH56lQ9mTyRUPQdg0Y54eCtY7yOSjiJOctOUUWHaxoFG7frGQ==
+"@abp/core@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/core/-/core-5.3.0-rc.1.tgz#4ede309ccfab440deb66fecb091273027483676a"
+ integrity sha512-cTw9xaWMkRDQjXRtkB5zx4Za0CPx7yvCRnTngIJs7xO86lRMVnuiwVGjP66vYTmiiu2ulGFgCeuw1AaK5t+g4Q==
dependencies:
- "@abp/utils" "~5.2.1"
+ "@abp/utils" "~5.3.0-rc.1"
-"@abp/datatables.net-bs5@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs5/-/datatables.net-bs5-5.2.1.tgz#fafc65295d00d5b351404740702f7e56ff1341fe"
- integrity sha512-B8lSAeMM9qOwYbDK/Dhp7BX5lFaCpao4RCPcSqgFrye8vlH8bcobmp4tMD23r24y/gRIEuQBcKzp0Lf0OUpLhA==
+"@abp/datatables.net-bs5@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs5/-/datatables.net-bs5-5.3.0-rc.1.tgz#ca624d788acdcc547d0bdf1f76ba3ffc105dfd52"
+ integrity sha512-uyFBkD9rM3wGve0ZKrr7bEbC0Z/ywi8S/EYL6GwLzGNtogSsVj5HGtSvifKjCBn7KmAvo54skKoVgVEn77dlWQ==
dependencies:
- "@abp/datatables.net" "~5.2.1"
+ "@abp/datatables.net" "~5.3.0-rc.1"
datatables.net-bs5 "^1.11.4"
-"@abp/datatables.net@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-5.2.1.tgz#397a3e7db2017c20c082598214478c277b2abec6"
- integrity sha512-6Q3+W+d8e4TMAkZr/IdPDQuL1v+tjbS50ChLvrJX/BLb4fBhu1LGJWWKzKJFj721DwIsuQQiM4uq9xX/TjiS0w==
+"@abp/datatables.net@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-5.3.0-rc.1.tgz#38c0f6323f7e6305a50f7de9885b8a3f440cdf15"
+ integrity sha512-lecJ9Yelgey/nfSscsUHET0gyB6pZgkhnJXu3u8d9XhV2M5sc/WSnnCO3bgVBqMDImprR4GFPFw2cUlWkb8QBg==
dependencies:
- "@abp/jquery" "~5.2.1"
+ "@abp/jquery" "~5.3.0-rc.1"
datatables.net "^1.11.4"
-"@abp/font-awesome@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-5.2.1.tgz#357785a0366f555b72f76e2b8ee8a2d607aed6fb"
- integrity sha512-9fAUdA9QeNRMjp6v8i6EOR480bjB4OzqzriFCKUu4k6VwbA6PxUsJIRFyKIt5UpC12Zqdhpkyj0iG6tE0nRekQ==
+"@abp/font-awesome@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-5.3.0-rc.1.tgz#de14dca2b33fdc098d2325c5047e030a3927bfa9"
+ integrity sha512-tIuDwo+L5CuLpQ+ARsaTYmxuqpSJLqcaXuoFfk6JAC20bw881t7y8w4xWy1PUs0+SEQwTT7diZjQrcA/xxlMUQ==
dependencies:
- "@abp/core" "~5.2.1"
+ "@abp/core" "~5.3.0-rc.1"
"@fortawesome/fontawesome-free" "^5.15.4"
-"@abp/jquery-form@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-5.2.1.tgz#c9cc6ad3997f7fa036d5cd8e0d15923ad7fff790"
- integrity sha512-L7uKs7vReOQEETG9xIDq5aXjshbaPa+ZZQcCbn2uwY813e0ErS7Rb1mnowEt/LNEB02AtLet1B4TDVwZUl1uXQ==
+"@abp/jquery-form@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-5.3.0-rc.1.tgz#0a363d8e4814651e0c46e2109d19dcc84fc884b0"
+ integrity sha512-IWazO6BW5rHJ+ODk4haEqWzfzHvbxtW2+T1o534Lr7d+LI9yabNiQmRZ24yzNDb6SmRvDUVsumZ+lxPn2WBhIw==
dependencies:
- "@abp/jquery" "~5.2.1"
+ "@abp/jquery" "~5.3.0-rc.1"
jquery-form "^4.3.0"
-"@abp/jquery-validation-unobtrusive@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-5.2.1.tgz#7fdfa3867f61f862ee575114560f79b505649093"
- integrity sha512-uZ36D1FfoLdBb6h44fQ3kZuTk4gJ5yzhyOprkgMsGAJDVakX7w/W4V3ThpiEO+iUpNKTboVIhW2QQ0AXK9rrsg==
+"@abp/jquery-validation-unobtrusive@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-5.3.0-rc.1.tgz#0aa2a5535acd79b5288ef04a0dc1b83a7a57b4b9"
+ integrity sha512-Qv/+nrd+ZeUs/2mCMahpQFqEguMOcmHrLg7hcw0LgcHr+MmEcG4WDcijTY6suFyekaf0DZD6vsFZjdvZmhsVYQ==
dependencies:
- "@abp/jquery-validation" "~5.2.1"
+ "@abp/jquery-validation" "~5.3.0-rc.1"
jquery-validation-unobtrusive "^3.2.12"
-"@abp/jquery-validation@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-5.2.1.tgz#e7fbaa1715af5667559e3b6f0fcb916766b28244"
- integrity sha512-Rr/+SWGlXJ53jfysMB/HVNZqsJKCF3rg23ip2Kg6Q+kQTvWVRE3tpkpoBJczOii5tPUk/A/lsJKgRlcsnP0ASw==
+"@abp/jquery-validation@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-5.3.0-rc.1.tgz#d05afbe0209c0815afe3a7cb0cf811256e9905fc"
+ integrity sha512-3DoRX6c8duRx1/g7MFuPAO/qesJCFqbVbw+x0+QnKmCkVZmz5VFAqdO9yFMxDFRbBAtyp7faaarc0lOtAcBsoA==
dependencies:
- "@abp/jquery" "~5.2.1"
+ "@abp/jquery" "~5.3.0-rc.1"
jquery-validation "^1.19.3"
-"@abp/jquery@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-5.2.1.tgz#6b88af5c22fb25d953d38847bcddcf591aeb3228"
- integrity sha512-FiIRnDx/gm6JR8QljiulwCc5d8+YC123X0qxMIBI8IY9vznEX+Jk48jYG8fLABnRqKEIYfV8UsYSK8IJx3mcSg==
+"@abp/jquery@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-5.3.0-rc.1.tgz#26e5d5761f2629d02b2534ad964080221d536308"
+ integrity sha512-//bqInarV6XOs8+I5GW1q/c05sjnCq/Z0vuzFW1i1NDrQ2Q5kqF5leMV9hhGEZmfR+yG1T0MsbVvueieRkV/cA==
dependencies:
- "@abp/core" "~5.2.1"
+ "@abp/core" "~5.3.0-rc.1"
jquery "~3.6.0"
-"@abp/lodash@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-5.2.1.tgz#87601162025a4a376e3c335d418636ef2079ad2d"
- integrity sha512-ILg3X5tTH2HhJMRmg7BP/r+Kstm/nf+0aNQ2exsJoMMnKE7CC0eYQjpSgrze6GwG3a13eamyTlrz+RrlIm5IBA==
+"@abp/lodash@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-5.3.0-rc.1.tgz#c53304fbd9b1c885a9a812c681c3698dd8ecea47"
+ integrity sha512-yBvUB05z/SSEEbZ79nFfb0cKwWVFbrt9OtUkQHy9ER7ip0R9escG2n1djFtAA33yZr/NLzSUh+vVBYsEhk8MOA==
dependencies:
- "@abp/core" "~5.2.1"
+ "@abp/core" "~5.3.0-rc.1"
lodash "^4.17.21"
-"@abp/luxon@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-5.2.1.tgz#72a9e9bb0e7f3a688662c8e9ad52016b9cfa3a17"
- integrity sha512-D3KVsba969UBYktdbCxq1JQp4kYZ1S7rIMymDJMBoHByXxwwdeXMkvuphAifBmSYTt3K6bNoZdR0VxtnNlPn2A==
+"@abp/luxon@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-5.3.0-rc.1.tgz#bcb4de01b20a8e4da8db186e88fdebfcde47fb8f"
+ integrity sha512-SLozcDvCL/2jyvG2ZU+DHjzbfHYdmwiRjWu7gWyNjaY2e6D3NraHHjpMQ7ubObXZRlhhvfcp0i6eeKKoZNJtEQ==
dependencies:
- "@abp/core" "~5.2.1"
+ "@abp/core" "~5.3.0-rc.1"
luxon "^2.3.0"
-"@abp/malihu-custom-scrollbar-plugin@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-5.2.1.tgz#8d1b600552607e28a274775ad3bb68ac7cfbba09"
- integrity sha512-5mvABMCT7tiwPl1vUK8kriN/SRi2gC4VqkEuxghT7uBQG9Cqh5jhJrl80M9ZK/oQFind3r6+SF8OlfwF8yvxHQ==
+"@abp/malihu-custom-scrollbar-plugin@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-5.3.0-rc.1.tgz#398181c7c6cc1805544e7a1ccd0423ed96005e0b"
+ integrity sha512-KZar881wtotKc+1bqDlBWo2vLUEeeqEpMBg8+BiXsGofp5ovudifVPM6mHZ9Gi29U9LAMyI0VEGwLJctgB/UoA==
dependencies:
- "@abp/core" "~5.2.1"
+ "@abp/core" "~5.3.0-rc.1"
malihu-custom-scrollbar-plugin "^3.1.5"
-"@abp/owl.carousel@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/owl.carousel/-/owl.carousel-5.2.1.tgz#f58d28c98ccb8ff0f9cbcf612519648032fa4399"
- integrity sha512-LYDSKrHlrzB5mD33m39olc1V96NJnNPTv3+VefKNnZvUCRHGwwCfow4pwWgjmn2uvHBKW5qiBX9c2EbwLFplQA==
+"@abp/owl.carousel@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/owl.carousel/-/owl.carousel-5.3.0-rc.1.tgz#504fa6d37553810969cd4e3b3b323744a7ec13bc"
+ integrity sha512-GPX+McoItf8EvZ6p7cbb1t2LovOSfDemzUXFgOLD0pCTPXiriNYknIoi/ZsvL3U/syQHpAuEbkt2C/fVVjbSnQ==
dependencies:
- "@abp/core" "~5.2.1"
+ "@abp/core" "~5.3.0-rc.1"
owl.carousel "^2.3.4"
-"@abp/prismjs@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/prismjs/-/prismjs-5.2.1.tgz#86aae6ee4529401da75744f1e43c7cd3c0b494a0"
- integrity sha512-YNgcM7Kvmu3hGXJh4B8gl7rLzC28VuZYYP7AVptVSbTz/n6usCo21evG/st8L3vXixuQkvnNpBFgacJnHdSJZQ==
+"@abp/prismjs@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/prismjs/-/prismjs-5.3.0-rc.1.tgz#ee1a49b8bd0af2a29aa7bfb93d22ce07a4edbe70"
+ integrity sha512-oOnzwUtI6q2u7iE/YWQEULm1I+f7Bo+0tQ9rYlzIoalBRnqN57Zw0VMf5AHq8qjn6GiInehPtU9wsaVTPqXmtw==
dependencies:
- "@abp/clipboard" "~5.2.1"
- "@abp/core" "~5.2.1"
+ "@abp/clipboard" "~5.3.0-rc.1"
+ "@abp/core" "~5.3.0-rc.1"
prismjs "^1.26.0"
-"@abp/select2@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-5.2.1.tgz#f52a3c88da52bbfc4b135671064326aebb98b332"
- integrity sha512-JH/PqOxhTY05sUyN7of6TNai0W4M3N3OF3Hlwmr8i7hNdYfFwJvQnQzKeKrk/vt8Hv44/JTQDlNKU02BmSBfOQ==
+"@abp/select2@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-5.3.0-rc.1.tgz#b2ce00b6545674d6bccc10fdfe4626a4598a0cdc"
+ integrity sha512-frE5jia7bBdZinW4LqD5JR+wknWu2ARX3L3pPiQ080ulB+P58gRj07ZPd1BWgRcvutnuANYyP9rZtDA18Ls+9Q==
dependencies:
- "@abp/core" "~5.2.1"
+ "@abp/core" "~5.3.0-rc.1"
select2 "^4.0.13"
-"@abp/sweetalert2@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/sweetalert2/-/sweetalert2-5.2.1.tgz#f5ff712b4f7a4cb5a75a754aa4642f099f382e51"
- integrity sha512-laaF/5WhYw+hNJRTfMzO93fVhaYqnnOcQTUlkGgsZMe2gwebyX73VI8O8Xw7zXmN1Tu/JwqRI46qiafDrPFTLg==
+"@abp/sweetalert2@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/sweetalert2/-/sweetalert2-5.3.0-rc.1.tgz#6eb10b257e7f256da64ff6fe248a370671a26920"
+ integrity sha512-g9nddGcDGaG6EmjX7qpRcLzy3F38BTtFc0RBWApH7Da1o/LMYFYa6xGfS7ouIynZBM9j/BRP12CVTR+Y9qqbGg==
dependencies:
- "@abp/core" "~5.2.1"
+ "@abp/core" "~5.3.0-rc.1"
sweetalert2 "^11.3.6"
-"@abp/timeago@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-5.2.1.tgz#a410dbf652c0f78f86384e116111aa613458b6de"
- integrity sha512-xmgqKEKusB6pcqFhMaz8RTi886ad8RrRMYgMWSw4Zjk1Lr9EqQwKtcE43Ve5XWJamh2Wpk8H7IKLQKHfrV12oA==
+"@abp/timeago@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-5.3.0-rc.1.tgz#2702a0f22db52dbf4c0717e4abcd317c56d10563"
+ integrity sha512-XRc4D98FIZR0YTXIoV0+OxVJTdixtNDiwatZRffopHT4Kpptmpj6O9KMcB4SngCH99/TrUFdEUnA2CgszxiEOA==
dependencies:
- "@abp/jquery" "~5.2.1"
+ "@abp/jquery" "~5.3.0-rc.1"
timeago "^1.6.7"
-"@abp/toastr@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/toastr/-/toastr-5.2.1.tgz#4ed96a7967d028b8e849ff79b8a0a8a041bb20e4"
- integrity sha512-HrnIzvM9LgQdzlmLmvHUVSG4PmWfx9YuozxkFTv+AGa2FAPby5W9hbQ025ry3bPkU9lGWSu/w7JSDqoiL16bPA==
+"@abp/toastr@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/toastr/-/toastr-5.3.0-rc.1.tgz#ec3a3d302ac91d5393c3caeb8b4884ad811b6edb"
+ integrity sha512-InZweYuBkrNZNBQKp6A+6gxGdO/lB0XsrXaa+CIVe55p8aNJPzE0mnvSfKWhN5G273wR08AD9RjR22kYS+bgFA==
dependencies:
- "@abp/jquery" "~5.2.1"
+ "@abp/jquery" "~5.3.0-rc.1"
toastr "^2.1.4"
-"@abp/tui-editor@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/tui-editor/-/tui-editor-5.2.1.tgz#06be1a029de754868fa11ce3479be3fbc90ba103"
- integrity sha512-Mi3preBkGEU1hrtSNCkOjeXPc9c74DFt8BL82sPIVDglYcVrVLXbnNTWE/CHP0spmKWh33ek4FoH1Pt0TePMuw==
+"@abp/tui-editor@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/tui-editor/-/tui-editor-5.3.0-rc.1.tgz#d5b6e46c922e9743216395bc055ed8208c2ead0b"
+ integrity sha512-wMEph23kwGJyAGweivKn2EDTRQQD0UG0X23qMd4Cv285qdu4AoYL2/shBDFKiXfhN0Q7EZ06mhOyTuhJmTnNUg==
dependencies:
- "@abp/jquery" "~5.2.1"
- "@abp/prismjs" "~5.2.1"
+ "@abp/jquery" "~5.3.0-rc.1"
+ "@abp/prismjs" "~5.3.0-rc.1"
-"@abp/utils@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-5.2.1.tgz#7c2d20f1bcc8cf9f90c060ed31ed3a114a463064"
- integrity sha512-9hxI24aRZCnxCP+WsOoCltSg4YqG9WtW06t9/f6hFO9B0udXIKyV+95Ndipca/R1G94Snx81ifSwAa+DHbFfvQ==
+"@abp/utils@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-5.3.0-rc.1.tgz#3fa758944e7325e7b3f528141e03bb71f8e04d24"
+ integrity sha512-/8BTYZomNMdy+RpYXWLp5dg0lRhmfiguciZEVWo4qRw1lCXm/JR+0842XT1XYE1dQ4orNNJ3/H86eRX8Ab6Yfg==
dependencies:
just-compare "^1.3.0"
diff --git a/modules/blogging/src/Volo.Blogging.Web/Pages/Blogs/Posts/Detail.cshtml b/modules/blogging/src/Volo.Blogging.Web/Pages/Blogs/Posts/Detail.cshtml
index 66d2bf89c9..5912e4e6c9 100644
--- a/modules/blogging/src/Volo.Blogging.Web/Pages/Blogs/Posts/Detail.cshtml
+++ b/modules/blogging/src/Volo.Blogging.Web/Pages/Blogs/Posts/Detail.cshtml
@@ -56,9 +56,7 @@
+-------------------------------------------------------------------
+Tue Oct 18 13:58:40 UTC 2011 - misterx@example.com
+
+- Update to r60.3
+- Fixes bug in the reflect package
+ * disallow Interface method on Value obtained via unexported name
+
+-------------------------------------------------------------------
+Thu Oct 6 08:14:24 UTC 2011 - misterx@example.com
+
+- Update to r60.2
+- Fixes memory leak in certain map types
+
+-------------------------------------------------------------------
+Wed Oct 5 14:34:10 UTC 2011 - misterx@example.com
+
+- Tweaks for gdb debugging
+- go.spec changes:
+ - move %go_arch definition to %prep section
+ - pass correct location of go specific gdb pretty printer and
+ functions to cpp as HOST_EXTRA_CFLAGS macro
+ - install go gdb functions & printer
+- gdb-printer.patch
+ - patch linker (src/cmd/ld/dwarf.c) to emit correct location of go
+ gdb functions and pretty printer
+
+
+
+
MIME types defined:text/x-rpm-changes.
+
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/rpm/rpm.js b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/rpm/rpm.js
new file mode 100644
index 0000000000..bb9ec9ffad
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/rpm/rpm.js
@@ -0,0 +1,109 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: https://codemirror.net/LICENSE
+
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
+ mod(require("../../lib/codemirror"));
+ else if (typeof define == "function" && define.amd) // AMD
+ define(["../../lib/codemirror"], mod);
+ else // Plain browser env
+ mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("rpm-changes", function() {
+ var headerSeparator = /^-+$/;
+ var headerLine = /^(Mon|Tue|Wed|Thu|Fri|Sat|Sun) (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) ?\d{1,2} \d{2}:\d{2}(:\d{2})? [A-Z]{3,4} \d{4} - /;
+ var simpleEmail = /^[\w+.-]+@[\w.-]+/;
+
+ return {
+ token: function(stream) {
+ if (stream.sol()) {
+ if (stream.match(headerSeparator)) { return 'tag'; }
+ if (stream.match(headerLine)) { return 'tag'; }
+ }
+ if (stream.match(simpleEmail)) { return 'string'; }
+ stream.next();
+ return null;
+ }
+ };
+});
+
+CodeMirror.defineMIME("text/x-rpm-changes", "rpm-changes");
+
+// Quick and dirty spec file highlighting
+
+CodeMirror.defineMode("rpm-spec", function() {
+ var arch = /^(i386|i586|i686|x86_64|ppc64le|ppc64|ppc|ia64|s390x|s390|sparc64|sparcv9|sparc|noarch|alphaev6|alpha|hppa|mipsel)/;
+
+ var preamble = /^[a-zA-Z0-9()]+:/;
+ var section = /^%(debug_package|package|description|prep|build|install|files|clean|changelog|preinstall|preun|postinstall|postun|pretrans|posttrans|pre|post|triggerin|triggerun|verifyscript|check|triggerpostun|triggerprein|trigger)/;
+ var control_flow_complex = /^%(ifnarch|ifarch|if)/; // rpm control flow macros
+ var control_flow_simple = /^%(else|endif)/; // rpm control flow macros
+ var operators = /^(\!|\?|\<\=|\<|\>\=|\>|\=\=|\&\&|\|\|)/; // operators in control flow macros
+
+ return {
+ startState: function () {
+ return {
+ controlFlow: false,
+ macroParameters: false,
+ section: false
+ };
+ },
+ token: function (stream, state) {
+ var ch = stream.peek();
+ if (ch == "#") { stream.skipToEnd(); return "comment"; }
+
+ if (stream.sol()) {
+ if (stream.match(preamble)) { return "header"; }
+ if (stream.match(section)) { return "atom"; }
+ }
+
+ if (stream.match(/^\$\w+/)) { return "def"; } // Variables like '$RPM_BUILD_ROOT'
+ if (stream.match(/^\$\{\w+\}/)) { return "def"; } // Variables like '${RPM_BUILD_ROOT}'
+
+ if (stream.match(control_flow_simple)) { return "keyword"; }
+ if (stream.match(control_flow_complex)) {
+ state.controlFlow = true;
+ return "keyword";
+ }
+ if (state.controlFlow) {
+ if (stream.match(operators)) { return "operator"; }
+ if (stream.match(/^(\d+)/)) { return "number"; }
+ if (stream.eol()) { state.controlFlow = false; }
+ }
+
+ if (stream.match(arch)) {
+ if (stream.eol()) { state.controlFlow = false; }
+ return "number";
+ }
+
+ // Macros like '%make_install' or '%attr(0775,root,root)'
+ if (stream.match(/^%[\w]+/)) {
+ if (stream.match('(')) { state.macroParameters = true; }
+ return "keyword";
+ }
+ if (state.macroParameters) {
+ if (stream.match(/^\d+/)) { return "number";}
+ if (stream.match(')')) {
+ state.macroParameters = false;
+ return "keyword";
+ }
+ }
+
+ // Macros like '%{defined fedora}'
+ if (stream.match(/^%\{\??[\w \-\:\!]+\}/)) {
+ if (stream.eol()) { state.controlFlow = false; }
+ return "def";
+ }
+
+ //TODO: Include bash script sub-parser (CodeMirror supports that)
+ stream.next();
+ return null;
+ }
+ };
+});
+
+CodeMirror.defineMIME("text/x-rpm-spec", "rpm-spec");
+
+});
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/rst/rst.js b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/rst/rst.js
new file mode 100644
index 0000000000..f14eb270f9
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/rst/rst.js
@@ -0,0 +1,557 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: https://codemirror.net/LICENSE
+
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
+ mod(require("../../lib/codemirror"), require("../python/python"), require("../stex/stex"), require("../../addon/mode/overlay"));
+ else if (typeof define == "function" && define.amd) // AMD
+ define(["../../lib/codemirror", "../python/python", "../stex/stex", "../../addon/mode/overlay"], mod);
+ else // Plain browser env
+ mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode('rst', function (config, options) {
+
+ var rx_strong = /^\*\*[^\*\s](?:[^\*]*[^\*\s])?\*\*/;
+ var rx_emphasis = /^\*[^\*\s](?:[^\*]*[^\*\s])?\*/;
+ var rx_literal = /^``[^`\s](?:[^`]*[^`\s])``/;
+
+ var rx_number = /^(?:[\d]+(?:[\.,]\d+)*)/;
+ var rx_positive = /^(?:\s\+[\d]+(?:[\.,]\d+)*)/;
+ var rx_negative = /^(?:\s\-[\d]+(?:[\.,]\d+)*)/;
+
+ var rx_uri_protocol = "[Hh][Tt][Tt][Pp][Ss]?://";
+ var rx_uri_domain = "(?:[\\d\\w.-]+)\\.(?:\\w{2,6})";
+ var rx_uri_path = "(?:/[\\d\\w\\#\\%\\&\\-\\.\\,\\/\\:\\=\\?\\~]+)*";
+ var rx_uri = new RegExp("^" + rx_uri_protocol + rx_uri_domain + rx_uri_path);
+
+ var overlay = {
+ token: function (stream) {
+
+ if (stream.match(rx_strong) && stream.match (/\W+|$/, false))
+ return 'strong';
+ if (stream.match(rx_emphasis) && stream.match (/\W+|$/, false))
+ return 'em';
+ if (stream.match(rx_literal) && stream.match (/\W+|$/, false))
+ return 'string-2';
+ if (stream.match(rx_number))
+ return 'number';
+ if (stream.match(rx_positive))
+ return 'positive';
+ if (stream.match(rx_negative))
+ return 'negative';
+ if (stream.match(rx_uri))
+ return 'link';
+
+ while (stream.next() != null) {
+ if (stream.match(rx_strong, false)) break;
+ if (stream.match(rx_emphasis, false)) break;
+ if (stream.match(rx_literal, false)) break;
+ if (stream.match(rx_number, false)) break;
+ if (stream.match(rx_positive, false)) break;
+ if (stream.match(rx_negative, false)) break;
+ if (stream.match(rx_uri, false)) break;
+ }
+
+ return null;
+ }
+ };
+
+ var mode = CodeMirror.getMode(
+ config, options.backdrop || 'rst-base'
+ );
+
+ return CodeMirror.overlayMode(mode, overlay, true); // combine
+}, 'python', 'stex');
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+CodeMirror.defineMode('rst-base', function (config) {
+
+ ///////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////////
+
+ function format(string) {
+ var args = Array.prototype.slice.call(arguments, 1);
+ return string.replace(/{(\d+)}/g, function (match, n) {
+ return typeof args[n] != 'undefined' ? args[n] : match;
+ });
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////////
+
+ var mode_python = CodeMirror.getMode(config, 'python');
+ var mode_stex = CodeMirror.getMode(config, 'stex');
+
+ ///////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////////
+
+ var SEPA = "\\s+";
+ var TAIL = "(?:\\s*|\\W|$)",
+ rx_TAIL = new RegExp(format('^{0}', TAIL));
+
+ var NAME =
+ "(?:[^\\W\\d_](?:[\\w!\"#$%&'()\\*\\+,\\-\\.\/:;<=>\\?]*[^\\W_])?)",
+ rx_NAME = new RegExp(format('^{0}', NAME));
+ var NAME_WWS =
+ "(?:[^\\W\\d_](?:[\\w\\s!\"#$%&'()\\*\\+,\\-\\.\/:;<=>\\?]*[^\\W_])?)";
+ var REF_NAME = format('(?:{0}|`{1}`)', NAME, NAME_WWS);
+
+ var TEXT1 = "(?:[^\\s\\|](?:[^\\|]*[^\\s\\|])?)";
+ var TEXT2 = "(?:[^\\`]+)",
+ rx_TEXT2 = new RegExp(format('^{0}', TEXT2));
+
+ var rx_section = new RegExp(
+ "^([!'#$%&\"()*+,-./:;<=>?@\\[\\\\\\]^_`{|}~])\\1{3,}\\s*$");
+ var rx_explicit = new RegExp(
+ format('^\\.\\.{0}', SEPA));
+ var rx_link = new RegExp(
+ format('^_{0}:{1}|^__:{1}', REF_NAME, TAIL));
+ var rx_directive = new RegExp(
+ format('^{0}::{1}', REF_NAME, TAIL));
+ var rx_substitution = new RegExp(
+ format('^\\|{0}\\|{1}{2}::{3}', TEXT1, SEPA, REF_NAME, TAIL));
+ var rx_footnote = new RegExp(
+ format('^\\[(?:\\d+|#{0}?|\\*)]{1}', REF_NAME, TAIL));
+ var rx_citation = new RegExp(
+ format('^\\[{0}\\]{1}', REF_NAME, TAIL));
+
+ var rx_substitution_ref = new RegExp(
+ format('^\\|{0}\\|', TEXT1));
+ var rx_footnote_ref = new RegExp(
+ format('^\\[(?:\\d+|#{0}?|\\*)]_', REF_NAME));
+ var rx_citation_ref = new RegExp(
+ format('^\\[{0}\\]_', REF_NAME));
+ var rx_link_ref1 = new RegExp(
+ format('^{0}__?', REF_NAME));
+ var rx_link_ref2 = new RegExp(
+ format('^`{0}`_', TEXT2));
+
+ var rx_role_pre = new RegExp(
+ format('^:{0}:`{1}`{2}', NAME, TEXT2, TAIL));
+ var rx_role_suf = new RegExp(
+ format('^`{1}`:{0}:{2}', NAME, TEXT2, TAIL));
+ var rx_role = new RegExp(
+ format('^:{0}:{1}', NAME, TAIL));
+
+ var rx_directive_name = new RegExp(format('^{0}', REF_NAME));
+ var rx_directive_tail = new RegExp(format('^::{0}', TAIL));
+ var rx_substitution_text = new RegExp(format('^\\|{0}\\|', TEXT1));
+ var rx_substitution_sepa = new RegExp(format('^{0}', SEPA));
+ var rx_substitution_name = new RegExp(format('^{0}', REF_NAME));
+ var rx_substitution_tail = new RegExp(format('^::{0}', TAIL));
+ var rx_link_head = new RegExp("^_");
+ var rx_link_name = new RegExp(format('^{0}|_', REF_NAME));
+ var rx_link_tail = new RegExp(format('^:{0}', TAIL));
+
+ var rx_verbatim = new RegExp('^::\\s*$');
+ var rx_examples = new RegExp('^\\s+(?:>>>|In \\[\\d+\\]:)\\s');
+
+ ///////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////////
+
+ function to_normal(stream, state) {
+ var token = null;
+
+ if (stream.sol() && stream.match(rx_examples, false)) {
+ change(state, to_mode, {
+ mode: mode_python, local: CodeMirror.startState(mode_python)
+ });
+ } else if (stream.sol() && stream.match(rx_explicit)) {
+ change(state, to_explicit);
+ token = 'meta';
+ } else if (stream.sol() && stream.match(rx_section)) {
+ change(state, to_normal);
+ token = 'header';
+ } else if (phase(state) == rx_role_pre ||
+ stream.match(rx_role_pre, false)) {
+
+ switch (stage(state)) {
+ case 0:
+ change(state, to_normal, context(rx_role_pre, 1));
+ stream.match(/^:/);
+ token = 'meta';
+ break;
+ case 1:
+ change(state, to_normal, context(rx_role_pre, 2));
+ stream.match(rx_NAME);
+ token = 'keyword';
+
+ if (stream.current().match(/^(?:math|latex)/)) {
+ state.tmp_stex = true;
+ }
+ break;
+ case 2:
+ change(state, to_normal, context(rx_role_pre, 3));
+ stream.match(/^:`/);
+ token = 'meta';
+ break;
+ case 3:
+ if (state.tmp_stex) {
+ state.tmp_stex = undefined; state.tmp = {
+ mode: mode_stex, local: CodeMirror.startState(mode_stex)
+ };
+ }
+
+ if (state.tmp) {
+ if (stream.peek() == '`') {
+ change(state, to_normal, context(rx_role_pre, 4));
+ state.tmp = undefined;
+ break;
+ }
+
+ token = state.tmp.mode.token(stream, state.tmp.local);
+ break;
+ }
+
+ change(state, to_normal, context(rx_role_pre, 4));
+ stream.match(rx_TEXT2);
+ token = 'string';
+ break;
+ case 4:
+ change(state, to_normal, context(rx_role_pre, 5));
+ stream.match(/^`/);
+ token = 'meta';
+ break;
+ case 5:
+ change(state, to_normal, context(rx_role_pre, 6));
+ stream.match(rx_TAIL);
+ break;
+ default:
+ change(state, to_normal);
+ }
+ } else if (phase(state) == rx_role_suf ||
+ stream.match(rx_role_suf, false)) {
+
+ switch (stage(state)) {
+ case 0:
+ change(state, to_normal, context(rx_role_suf, 1));
+ stream.match(/^`/);
+ token = 'meta';
+ break;
+ case 1:
+ change(state, to_normal, context(rx_role_suf, 2));
+ stream.match(rx_TEXT2);
+ token = 'string';
+ break;
+ case 2:
+ change(state, to_normal, context(rx_role_suf, 3));
+ stream.match(/^`:/);
+ token = 'meta';
+ break;
+ case 3:
+ change(state, to_normal, context(rx_role_suf, 4));
+ stream.match(rx_NAME);
+ token = 'keyword';
+ break;
+ case 4:
+ change(state, to_normal, context(rx_role_suf, 5));
+ stream.match(/^:/);
+ token = 'meta';
+ break;
+ case 5:
+ change(state, to_normal, context(rx_role_suf, 6));
+ stream.match(rx_TAIL);
+ break;
+ default:
+ change(state, to_normal);
+ }
+ } else if (phase(state) == rx_role || stream.match(rx_role, false)) {
+
+ switch (stage(state)) {
+ case 0:
+ change(state, to_normal, context(rx_role, 1));
+ stream.match(/^:/);
+ token = 'meta';
+ break;
+ case 1:
+ change(state, to_normal, context(rx_role, 2));
+ stream.match(rx_NAME);
+ token = 'keyword';
+ break;
+ case 2:
+ change(state, to_normal, context(rx_role, 3));
+ stream.match(/^:/);
+ token = 'meta';
+ break;
+ case 3:
+ change(state, to_normal, context(rx_role, 4));
+ stream.match(rx_TAIL);
+ break;
+ default:
+ change(state, to_normal);
+ }
+ } else if (phase(state) == rx_substitution_ref ||
+ stream.match(rx_substitution_ref, false)) {
+
+ switch (stage(state)) {
+ case 0:
+ change(state, to_normal, context(rx_substitution_ref, 1));
+ stream.match(rx_substitution_text);
+ token = 'variable-2';
+ break;
+ case 1:
+ change(state, to_normal, context(rx_substitution_ref, 2));
+ if (stream.match(/^_?_?/)) token = 'link';
+ break;
+ default:
+ change(state, to_normal);
+ }
+ } else if (stream.match(rx_footnote_ref)) {
+ change(state, to_normal);
+ token = 'quote';
+ } else if (stream.match(rx_citation_ref)) {
+ change(state, to_normal);
+ token = 'quote';
+ } else if (stream.match(rx_link_ref1)) {
+ change(state, to_normal);
+ if (!stream.peek() || stream.peek().match(/^\W$/)) {
+ token = 'link';
+ }
+ } else if (phase(state) == rx_link_ref2 ||
+ stream.match(rx_link_ref2, false)) {
+
+ switch (stage(state)) {
+ case 0:
+ if (!stream.peek() || stream.peek().match(/^\W$/)) {
+ change(state, to_normal, context(rx_link_ref2, 1));
+ } else {
+ stream.match(rx_link_ref2);
+ }
+ break;
+ case 1:
+ change(state, to_normal, context(rx_link_ref2, 2));
+ stream.match(/^`/);
+ token = 'link';
+ break;
+ case 2:
+ change(state, to_normal, context(rx_link_ref2, 3));
+ stream.match(rx_TEXT2);
+ break;
+ case 3:
+ change(state, to_normal, context(rx_link_ref2, 4));
+ stream.match(/^`_/);
+ token = 'link';
+ break;
+ default:
+ change(state, to_normal);
+ }
+ } else if (stream.match(rx_verbatim)) {
+ change(state, to_verbatim);
+ }
+
+ else {
+ if (stream.next()) change(state, to_normal);
+ }
+
+ return token;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////////
+
+ function to_explicit(stream, state) {
+ var token = null;
+
+ if (phase(state) == rx_substitution ||
+ stream.match(rx_substitution, false)) {
+
+ switch (stage(state)) {
+ case 0:
+ change(state, to_explicit, context(rx_substitution, 1));
+ stream.match(rx_substitution_text);
+ token = 'variable-2';
+ break;
+ case 1:
+ change(state, to_explicit, context(rx_substitution, 2));
+ stream.match(rx_substitution_sepa);
+ break;
+ case 2:
+ change(state, to_explicit, context(rx_substitution, 3));
+ stream.match(rx_substitution_name);
+ token = 'keyword';
+ break;
+ case 3:
+ change(state, to_explicit, context(rx_substitution, 4));
+ stream.match(rx_substitution_tail);
+ token = 'meta';
+ break;
+ default:
+ change(state, to_normal);
+ }
+ } else if (phase(state) == rx_directive ||
+ stream.match(rx_directive, false)) {
+
+ switch (stage(state)) {
+ case 0:
+ change(state, to_explicit, context(rx_directive, 1));
+ stream.match(rx_directive_name);
+ token = 'keyword';
+
+ if (stream.current().match(/^(?:math|latex)/))
+ state.tmp_stex = true;
+ else if (stream.current().match(/^python/))
+ state.tmp_py = true;
+ break;
+ case 1:
+ change(state, to_explicit, context(rx_directive, 2));
+ stream.match(rx_directive_tail);
+ token = 'meta';
+
+ if (stream.match(/^latex\s*$/) || state.tmp_stex) {
+ state.tmp_stex = undefined; change(state, to_mode, {
+ mode: mode_stex, local: CodeMirror.startState(mode_stex)
+ });
+ }
+ break;
+ case 2:
+ change(state, to_explicit, context(rx_directive, 3));
+ if (stream.match(/^python\s*$/) || state.tmp_py) {
+ state.tmp_py = undefined; change(state, to_mode, {
+ mode: mode_python, local: CodeMirror.startState(mode_python)
+ });
+ }
+ break;
+ default:
+ change(state, to_normal);
+ }
+ } else if (phase(state) == rx_link || stream.match(rx_link, false)) {
+
+ switch (stage(state)) {
+ case 0:
+ change(state, to_explicit, context(rx_link, 1));
+ stream.match(rx_link_head);
+ stream.match(rx_link_name);
+ token = 'link';
+ break;
+ case 1:
+ change(state, to_explicit, context(rx_link, 2));
+ stream.match(rx_link_tail);
+ token = 'meta';
+ break;
+ default:
+ change(state, to_normal);
+ }
+ } else if (stream.match(rx_footnote)) {
+ change(state, to_normal);
+ token = 'quote';
+ } else if (stream.match(rx_citation)) {
+ change(state, to_normal);
+ token = 'quote';
+ }
+
+ else {
+ stream.eatSpace();
+ if (stream.eol()) {
+ change(state, to_normal);
+ } else {
+ stream.skipToEnd();
+ change(state, to_comment);
+ token = 'comment';
+ }
+ }
+
+ return token;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////////
+
+ function to_comment(stream, state) {
+ return as_block(stream, state, 'comment');
+ }
+
+ function to_verbatim(stream, state) {
+ return as_block(stream, state, 'meta');
+ }
+
+ function as_block(stream, state, token) {
+ if (stream.eol() || stream.eatSpace()) {
+ stream.skipToEnd();
+ return token;
+ } else {
+ change(state, to_normal);
+ return null;
+ }
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////////
+
+ function to_mode(stream, state) {
+
+ if (state.ctx.mode && state.ctx.local) {
+
+ if (stream.sol()) {
+ if (!stream.eatSpace()) change(state, to_normal);
+ return null;
+ }
+
+ return state.ctx.mode.token(stream, state.ctx.local);
+ }
+
+ change(state, to_normal);
+ return null;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////////
+
+ function context(phase, stage, mode, local) {
+ return {phase: phase, stage: stage, mode: mode, local: local};
+ }
+
+ function change(state, tok, ctx) {
+ state.tok = tok;
+ state.ctx = ctx || {};
+ }
+
+ function stage(state) {
+ return state.ctx.stage || 0;
+ }
+
+ function phase(state) {
+ return state.ctx.phase;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////////
+
+ return {
+ startState: function () {
+ return {tok: to_normal, ctx: context(undefined, 0)};
+ },
+
+ copyState: function (state) {
+ var ctx = state.ctx, tmp = state.tmp;
+ if (ctx.local)
+ ctx = {mode: ctx.mode, local: CodeMirror.copyState(ctx.mode, ctx.local)};
+ if (tmp)
+ tmp = {mode: tmp.mode, local: CodeMirror.copyState(tmp.mode, tmp.local)};
+ return {tok: state.tok, ctx: ctx, tmp: tmp};
+ },
+
+ innerMode: function (state) {
+ return state.tmp ? {state: state.tmp.local, mode: state.tmp.mode}
+ : state.ctx.mode ? {state: state.ctx.local, mode: state.ctx.mode}
+ : null;
+ },
+
+ token: function (stream, state) {
+ return state.tok(stream, state);
+ }
+ };
+}, 'python', 'stex');
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+CodeMirror.defineMIME('text/x-rst', 'rst');
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+});
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/ruby/ruby.js b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/ruby/ruby.js
new file mode 100644
index 0000000000..85bbfc657f
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/ruby/ruby.js
@@ -0,0 +1,303 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: https://codemirror.net/LICENSE
+
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
+ mod(require("../../lib/codemirror"));
+ else if (typeof define == "function" && define.amd) // AMD
+ define(["../../lib/codemirror"], mod);
+ else // Plain browser env
+ mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+function wordObj(words) {
+ var o = {};
+ for (var i = 0, e = words.length; i < e; ++i) o[words[i]] = true;
+ return o;
+}
+
+var keywordList = [
+ "alias", "and", "BEGIN", "begin", "break", "case", "class", "def", "defined?", "do", "else",
+ "elsif", "END", "end", "ensure", "false", "for", "if", "in", "module", "next", "not", "or",
+ "redo", "rescue", "retry", "return", "self", "super", "then", "true", "undef", "unless",
+ "until", "when", "while", "yield", "nil", "raise", "throw", "catch", "fail", "loop", "callcc",
+ "caller", "lambda", "proc", "public", "protected", "private", "require", "load",
+ "require_relative", "extend", "autoload", "__END__", "__FILE__", "__LINE__", "__dir__"
+], keywords = wordObj(keywordList);
+
+var indentWords = wordObj(["def", "class", "case", "for", "while", "until", "module", "then",
+ "catch", "loop", "proc", "begin"]);
+var dedentWords = wordObj(["end", "until"]);
+var opening = {"[": "]", "{": "}", "(": ")"};
+var closing = {"]": "[", "}": "{", ")": "("};
+
+CodeMirror.defineMode("ruby", function(config) {
+ var curPunc;
+
+ function chain(newtok, stream, state) {
+ state.tokenize.push(newtok);
+ return newtok(stream, state);
+ }
+
+ function tokenBase(stream, state) {
+ if (stream.sol() && stream.match("=begin") && stream.eol()) {
+ state.tokenize.push(readBlockComment);
+ return "comment";
+ }
+ if (stream.eatSpace()) return null;
+ var ch = stream.next(), m;
+ if (ch == "`" || ch == "'" || ch == '"') {
+ return chain(readQuoted(ch, "string", ch == '"' || ch == "`"), stream, state);
+ } else if (ch == "/") {
+ if (regexpAhead(stream))
+ return chain(readQuoted(ch, "string-2", true), stream, state);
+ else
+ return "operator";
+ } else if (ch == "%") {
+ var style = "string", embed = true;
+ if (stream.eat("s")) style = "atom";
+ else if (stream.eat(/[WQ]/)) style = "string";
+ else if (stream.eat(/[r]/)) style = "string-2";
+ else if (stream.eat(/[wxq]/)) { style = "string"; embed = false; }
+ var delim = stream.eat(/[^\w\s=]/);
+ if (!delim) return "operator";
+ if (opening.propertyIsEnumerable(delim)) delim = opening[delim];
+ return chain(readQuoted(delim, style, embed, true), stream, state);
+ } else if (ch == "#") {
+ stream.skipToEnd();
+ return "comment";
+ } else if (ch == "<" && (m = stream.match(/^<([-~])[\`\"\']?([a-zA-Z_?]\w*)[\`\"\']?(?:;|$)/))) {
+ return chain(readHereDoc(m[2], m[1]), stream, state);
+ } else if (ch == "0") {
+ if (stream.eat("x")) stream.eatWhile(/[\da-fA-F]/);
+ else if (stream.eat("b")) stream.eatWhile(/[01]/);
+ else stream.eatWhile(/[0-7]/);
+ return "number";
+ } else if (/\d/.test(ch)) {
+ stream.match(/^[\d_]*(?:\.[\d_]+)?(?:[eE][+\-]?[\d_]+)?/);
+ return "number";
+ } else if (ch == "?") {
+ while (stream.match(/^\\[CM]-/)) {}
+ if (stream.eat("\\")) stream.eatWhile(/\w/);
+ else stream.next();
+ return "string";
+ } else if (ch == ":") {
+ if (stream.eat("'")) return chain(readQuoted("'", "atom", false), stream, state);
+ if (stream.eat('"')) return chain(readQuoted('"', "atom", true), stream, state);
+
+ // :> :>> :< :<< are valid symbols
+ if (stream.eat(/[\<\>]/)) {
+ stream.eat(/[\<\>]/);
+ return "atom";
+ }
+
+ // :+ :- :/ :* :| :& :! are valid symbols
+ if (stream.eat(/[\+\-\*\/\&\|\:\!]/)) {
+ return "atom";
+ }
+
+ // Symbols can't start by a digit
+ if (stream.eat(/[a-zA-Z$@_\xa1-\uffff]/)) {
+ stream.eatWhile(/[\w$\xa1-\uffff]/);
+ // Only one ? ! = is allowed and only as the last character
+ stream.eat(/[\?\!\=]/);
+ return "atom";
+ }
+ return "operator";
+ } else if (ch == "@" && stream.match(/^@?[a-zA-Z_\xa1-\uffff]/)) {
+ stream.eat("@");
+ stream.eatWhile(/[\w\xa1-\uffff]/);
+ return "variable-2";
+ } else if (ch == "$") {
+ if (stream.eat(/[a-zA-Z_]/)) {
+ stream.eatWhile(/[\w]/);
+ } else if (stream.eat(/\d/)) {
+ stream.eat(/\d/);
+ } else {
+ stream.next(); // Must be a special global like $: or $!
+ }
+ return "variable-3";
+ } else if (/[a-zA-Z_\xa1-\uffff]/.test(ch)) {
+ stream.eatWhile(/[\w\xa1-\uffff]/);
+ stream.eat(/[\?\!]/);
+ if (stream.eat(":")) return "atom";
+ return "ident";
+ } else if (ch == "|" && (state.varList || state.lastTok == "{" || state.lastTok == "do")) {
+ curPunc = "|";
+ return null;
+ } else if (/[\(\)\[\]{}\\;]/.test(ch)) {
+ curPunc = ch;
+ return null;
+ } else if (ch == "-" && stream.eat(">")) {
+ return "arrow";
+ } else if (/[=+\-\/*:\.^%<>~|]/.test(ch)) {
+ var more = stream.eatWhile(/[=+\-\/*:\.^%<>~|]/);
+ if (ch == "." && !more) curPunc = ".";
+ return "operator";
+ } else {
+ return null;
+ }
+ }
+
+ function regexpAhead(stream) {
+ var start = stream.pos, depth = 0, next, found = false, escaped = false
+ while ((next = stream.next()) != null) {
+ if (!escaped) {
+ if ("[{(".indexOf(next) > -1) {
+ depth++
+ } else if ("]})".indexOf(next) > -1) {
+ depth--
+ if (depth < 0) break
+ } else if (next == "/" && depth == 0) {
+ found = true
+ break
+ }
+ escaped = next == "\\"
+ } else {
+ escaped = false
+ }
+ }
+ stream.backUp(stream.pos - start)
+ return found
+ }
+
+ function tokenBaseUntilBrace(depth) {
+ if (!depth) depth = 1;
+ return function(stream, state) {
+ if (stream.peek() == "}") {
+ if (depth == 1) {
+ state.tokenize.pop();
+ return state.tokenize[state.tokenize.length-1](stream, state);
+ } else {
+ state.tokenize[state.tokenize.length - 1] = tokenBaseUntilBrace(depth - 1);
+ }
+ } else if (stream.peek() == "{") {
+ state.tokenize[state.tokenize.length - 1] = tokenBaseUntilBrace(depth + 1);
+ }
+ return tokenBase(stream, state);
+ };
+ }
+ function tokenBaseOnce() {
+ var alreadyCalled = false;
+ return function(stream, state) {
+ if (alreadyCalled) {
+ state.tokenize.pop();
+ return state.tokenize[state.tokenize.length-1](stream, state);
+ }
+ alreadyCalled = true;
+ return tokenBase(stream, state);
+ };
+ }
+ function readQuoted(quote, style, embed, unescaped) {
+ return function(stream, state) {
+ var escaped = false, ch;
+
+ if (state.context.type === 'read-quoted-paused') {
+ state.context = state.context.prev;
+ stream.eat("}");
+ }
+
+ while ((ch = stream.next()) != null) {
+ if (ch == quote && (unescaped || !escaped)) {
+ state.tokenize.pop();
+ break;
+ }
+ if (embed && ch == "#" && !escaped) {
+ if (stream.eat("{")) {
+ if (quote == "}") {
+ state.context = {prev: state.context, type: 'read-quoted-paused'};
+ }
+ state.tokenize.push(tokenBaseUntilBrace());
+ break;
+ } else if (/[@\$]/.test(stream.peek())) {
+ state.tokenize.push(tokenBaseOnce());
+ break;
+ }
+ }
+ escaped = !escaped && ch == "\\";
+ }
+ return style;
+ };
+ }
+ function readHereDoc(phrase, mayIndent) {
+ return function(stream, state) {
+ if (mayIndent) stream.eatSpace()
+ if (stream.match(phrase)) state.tokenize.pop();
+ else stream.skipToEnd();
+ return "string";
+ };
+ }
+ function readBlockComment(stream, state) {
+ if (stream.sol() && stream.match("=end") && stream.eol())
+ state.tokenize.pop();
+ stream.skipToEnd();
+ return "comment";
+ }
+
+ return {
+ startState: function() {
+ return {tokenize: [tokenBase],
+ indented: 0,
+ context: {type: "top", indented: -config.indentUnit},
+ continuedLine: false,
+ lastTok: null,
+ varList: false};
+ },
+
+ token: function(stream, state) {
+ curPunc = null;
+ if (stream.sol()) state.indented = stream.indentation();
+ var style = state.tokenize[state.tokenize.length-1](stream, state), kwtype;
+ var thisTok = curPunc;
+ if (style == "ident") {
+ var word = stream.current();
+ style = state.lastTok == "." ? "property"
+ : keywords.propertyIsEnumerable(stream.current()) ? "keyword"
+ : /^[A-Z]/.test(word) ? "tag"
+ : (state.lastTok == "def" || state.lastTok == "class" || state.varList) ? "def"
+ : "variable";
+ if (style == "keyword") {
+ thisTok = word;
+ if (indentWords.propertyIsEnumerable(word)) kwtype = "indent";
+ else if (dedentWords.propertyIsEnumerable(word)) kwtype = "dedent";
+ else if ((word == "if" || word == "unless") && stream.column() == stream.indentation())
+ kwtype = "indent";
+ else if (word == "do" && state.context.indented < state.indented)
+ kwtype = "indent";
+ }
+ }
+ if (curPunc || (style && style != "comment")) state.lastTok = thisTok;
+ if (curPunc == "|") state.varList = !state.varList;
+
+ if (kwtype == "indent" || /[\(\[\{]/.test(curPunc))
+ state.context = {prev: state.context, type: curPunc || style, indented: state.indented};
+ else if ((kwtype == "dedent" || /[\)\]\}]/.test(curPunc)) && state.context.prev)
+ state.context = state.context.prev;
+
+ if (stream.eol())
+ state.continuedLine = (curPunc == "\\" || style == "operator");
+ return style;
+ },
+
+ indent: function(state, textAfter) {
+ if (state.tokenize[state.tokenize.length-1] != tokenBase) return CodeMirror.Pass;
+ var firstChar = textAfter && textAfter.charAt(0);
+ var ct = state.context;
+ var closed = ct.type == closing[firstChar] ||
+ ct.type == "keyword" && /^(?:end|until|else|elsif|when|rescue)\b/.test(textAfter);
+ return ct.indented + (closed ? 0 : config.indentUnit) +
+ (state.continuedLine ? config.indentUnit : 0);
+ },
+
+ electricInput: /^\s*(?:end|rescue|elsif|else|\})$/,
+ lineComment: "#",
+ fold: "indent"
+ };
+});
+
+CodeMirror.defineMIME("text/x-ruby", "ruby");
+
+CodeMirror.registerHelper("hintWords", "ruby", keywordList);
+
+});
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/rust/rust.js b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/rust/rust.js
new file mode 100644
index 0000000000..f95f320d08
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/rust/rust.js
@@ -0,0 +1,72 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: https://codemirror.net/LICENSE
+
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
+ mod(require("../../lib/codemirror"), require("../../addon/mode/simple"));
+ else if (typeof define == "function" && define.amd) // AMD
+ define(["../../lib/codemirror", "../../addon/mode/simple"], mod);
+ else // Plain browser env
+ mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineSimpleMode("rust",{
+ start: [
+ // string and byte string
+ {regex: /b?"/, token: "string", next: "string"},
+ // raw string and raw byte string
+ {regex: /b?r"/, token: "string", next: "string_raw"},
+ {regex: /b?r#+"/, token: "string", next: "string_raw_hash"},
+ // character
+ {regex: /'(?:[^'\\]|\\(?:[nrt0'"]|x[\da-fA-F]{2}|u\{[\da-fA-F]{6}\}))'/, token: "string-2"},
+ // byte
+ {regex: /b'(?:[^']|\\(?:['\\nrt0]|x[\da-fA-F]{2}))'/, token: "string-2"},
+
+ {regex: /(?:(?:[0-9][0-9_]*)(?:(?:[Ee][+-]?[0-9_]+)|\.[0-9_]+(?:[Ee][+-]?[0-9_]+)?)(?:f32|f64)?)|(?:0(?:b[01_]+|(?:o[0-7_]+)|(?:x[0-9a-fA-F_]+))|(?:[0-9][0-9_]*))(?:u8|u16|u32|u64|i8|i16|i32|i64|isize|usize)?/,
+ token: "number"},
+ {regex: /(let(?:\s+mut)?|fn|enum|mod|struct|type|union)(\s+)([a-zA-Z_][a-zA-Z0-9_]*)/, token: ["keyword", null, "def"]},
+ {regex: /(?:abstract|alignof|as|async|await|box|break|continue|const|crate|do|dyn|else|enum|extern|fn|for|final|if|impl|in|loop|macro|match|mod|move|offsetof|override|priv|proc|pub|pure|ref|return|self|sizeof|static|struct|super|trait|type|typeof|union|unsafe|unsized|use|virtual|where|while|yield)\b/, token: "keyword"},
+ {regex: /\b(?:Self|isize|usize|char|bool|u8|u16|u32|u64|f16|f32|f64|i8|i16|i32|i64|str|Option)\b/, token: "atom"},
+ {regex: /\b(?:true|false|Some|None|Ok|Err)\b/, token: "builtin"},
+ {regex: /\b(fn)(\s+)([a-zA-Z_][a-zA-Z0-9_]*)/,
+ token: ["keyword", null ,"def"]},
+ {regex: /#!?\[.*\]/, token: "meta"},
+ {regex: /\/\/.*/, token: "comment"},
+ {regex: /\/\*/, token: "comment", next: "comment"},
+ {regex: /[-+\/*=<>!]+/, token: "operator"},
+ {regex: /[a-zA-Z_]\w*!/,token: "variable-3"},
+ {regex: /[a-zA-Z_]\w*/, token: "variable"},
+ {regex: /[\{\[\(]/, indent: true},
+ {regex: /[\}\]\)]/, dedent: true}
+ ],
+ string: [
+ {regex: /"/, token: "string", next: "start"},
+ {regex: /(?:[^\\"]|\\(?:.|$))*/, token: "string"}
+ ],
+ string_raw: [
+ {regex: /"/, token: "string", next: "start"},
+ {regex: /[^"]*/, token: "string"}
+ ],
+ string_raw_hash: [
+ {regex: /"#+/, token: "string", next: "start"},
+ {regex: /(?:[^"]|"(?!#))*/, token: "string"}
+ ],
+ comment: [
+ {regex: /.*?\*\//, token: "comment", next: "start"},
+ {regex: /.*/, token: "comment"}
+ ],
+ meta: {
+ dontIndentStates: ["comment"],
+ electricInput: /^\s*\}$/,
+ blockCommentStart: "/*",
+ blockCommentEnd: "*/",
+ lineComment: "//",
+ fold: "brace"
+ }
+});
+
+
+CodeMirror.defineMIME("text/x-rustsrc", "rust");
+CodeMirror.defineMIME("text/rust", "rust");
+});
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/sas/sas.js b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/sas/sas.js
new file mode 100644
index 0000000000..49b96b66de
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/sas/sas.js
@@ -0,0 +1,303 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: https://codemirror.net/LICENSE
+
+
+// SAS mode copyright (c) 2016 Jared Dean, SAS Institute
+// Created by Jared Dean
+
+// TODO
+// indent and de-indent
+// identify macro variables
+
+
+//Definitions
+// comment -- text within * ; or /* */
+// keyword -- SAS language variable
+// variable -- macro variables starts with '&' or variable formats
+// variable-2 -- DATA Step, proc, or macro names
+// string -- text within ' ' or " "
+// operator -- numeric operator + / - * ** le eq ge ... and so on
+// builtin -- proc %macro data run mend
+// atom
+// def
+
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
+ mod(require("../../lib/codemirror"));
+ else if (typeof define == "function" && define.amd) // AMD
+ define(["../../lib/codemirror"], mod);
+ else // Plain browser env
+ mod(CodeMirror);
+})(function(CodeMirror) {
+ "use strict";
+
+ CodeMirror.defineMode("sas", function () {
+ var words = {};
+ var isDoubleOperatorSym = {
+ eq: 'operator',
+ lt: 'operator',
+ le: 'operator',
+ gt: 'operator',
+ ge: 'operator',
+ "in": 'operator',
+ ne: 'operator',
+ or: 'operator'
+ };
+ var isDoubleOperatorChar = /(<=|>=|!=|<>)/;
+ var isSingleOperatorChar = /[=\(:\),{}.*<>+\-\/^\[\]]/;
+
+ // Takes a string of words separated by spaces and adds them as
+ // keys with the value of the first argument 'style'
+ function define(style, string, context) {
+ if (context) {
+ var split = string.split(' ');
+ for (var i = 0; i < split.length; i++) {
+ words[split[i]] = {style: style, state: context};
+ }
+ }
+ }
+ //datastep
+ define('def', 'stack pgm view source debug nesting nolist', ['inDataStep']);
+ define('def', 'if while until for do do; end end; then else cancel', ['inDataStep']);
+ define('def', 'label format _n_ _error_', ['inDataStep']);
+ define('def', 'ALTER BUFNO BUFSIZE CNTLLEV COMPRESS DLDMGACTION ENCRYPT ENCRYPTKEY EXTENDOBSCOUNTER GENMAX GENNUM INDEX LABEL OBSBUF OUTREP PW PWREQ READ REPEMPTY REPLACE REUSE ROLE SORTEDBY SPILL TOBSNO TYPE WRITE FILECLOSE FIRSTOBS IN OBS POINTOBS WHERE WHEREUP IDXNAME IDXWHERE DROP KEEP RENAME', ['inDataStep']);
+ define('def', 'filevar finfo finv fipname fipnamel fipstate first firstobs floor', ['inDataStep']);
+ define('def', 'varfmt varinfmt varlabel varlen varname varnum varray varrayx vartype verify vformat vformatd vformatdx vformatn vformatnx vformatw vformatwx vformatx vinarray vinarrayx vinformat vinformatd vinformatdx vinformatn vinformatnx vinformatw vinformatwx vinformatx vlabel vlabelx vlength vlengthx vname vnamex vnferr vtype vtypex weekday', ['inDataStep']);
+ define('def', 'zipfips zipname zipnamel zipstate', ['inDataStep']);
+ define('def', 'put putc putn', ['inDataStep']);
+ define('builtin', 'data run', ['inDataStep']);
+
+
+ //proc
+ define('def', 'data', ['inProc']);
+
+ // flow control for macros
+ define('def', '%if %end %end; %else %else; %do %do; %then', ['inMacro']);
+
+ //everywhere
+ define('builtin', 'proc run; quit; libname filename %macro %mend option options', ['ALL']);
+
+ define('def', 'footnote title libname ods', ['ALL']);
+ define('def', '%let %put %global %sysfunc %eval ', ['ALL']);
+ // automatic macro variables http://support.sas.com/documentation/cdl/en/mcrolref/61885/HTML/default/viewer.htm#a003167023.htm
+ define('variable', '&sysbuffr &syscc &syscharwidth &syscmd &sysdate &sysdate9 &sysday &sysdevic &sysdmg &sysdsn &sysencoding &sysenv &syserr &syserrortext &sysfilrc &syshostname &sysindex &sysinfo &sysjobid &syslast &syslckrc &syslibrc &syslogapplname &sysmacroname &sysmenv &sysmsg &sysncpu &sysodspath &sysparm &syspbuff &sysprocessid &sysprocessname &sysprocname &sysrc &sysscp &sysscpl &sysscpl &syssite &sysstartid &sysstartname &systcpiphostname &systime &sysuserid &sysver &sysvlong &sysvlong4 &syswarningtext', ['ALL']);
+
+ //footnote[1-9]? title[1-9]?
+
+ //options statement
+ define('def', 'source2 nosource2 page pageno pagesize', ['ALL']);
+
+ //proc and datastep
+ define('def', '_all_ _character_ _cmd_ _freq_ _i_ _infile_ _last_ _msg_ _null_ _numeric_ _temporary_ _type_ abort abs addr adjrsq airy alpha alter altlog altprint and arcos array arsin as atan attrc attrib attrn authserver autoexec awscontrol awsdef awsmenu awsmenumerge awstitle backward band base betainv between blocksize blshift bnot bor brshift bufno bufsize bxor by byerr byline byte calculated call cards cards4 catcache cbufno cdf ceil center cexist change chisq cinv class cleanup close cnonct cntllev coalesce codegen col collate collin column comamid comaux1 comaux2 comdef compbl compound compress config continue convert cos cosh cpuid create cross crosstab css curobs cv daccdb daccdbsl daccsl daccsyd dacctab dairy datalines datalines4 datejul datepart datetime day dbcslang dbcstype dclose ddfm ddm delete delimiter depdb depdbsl depsl depsyd deptab dequote descending descript design= device dflang dhms dif digamma dim dinfo display distinct dkricond dkrocond dlm dnum do dopen doptname doptnum dread drop dropnote dsname dsnferr echo else emaildlg emailid emailpw emailserver emailsys encrypt end endsas engine eof eov erf erfc error errorcheck errors exist exp fappend fclose fcol fdelete feedback fetch fetchobs fexist fget file fileclose fileexist filefmt filename fileref fmterr fmtsearch fnonct fnote font fontalias fopen foptname foptnum force formatted formchar formdelim formdlim forward fpoint fpos fput fread frewind frlen from fsep fuzz fwrite gaminv gamma getoption getvarc getvarn go goto group gwindow hbar hbound helpenv helploc hms honorappearance hosthelp hostprint hour hpct html hvar ibessel ibr id if index indexc indexw initcmd initstmt inner input inputc inputn inr insert int intck intnx into intrr invaliddata irr is jbessel join juldate keep kentb kurtosis label lag last lbound leave left length levels lgamma lib library libref line linesize link list log log10 log2 logpdf logpmf logsdf lostcard lowcase lrecl ls macro macrogen maps mautosource max maxdec maxr mdy mean measures median memtype merge merror min minute missing missover mlogic mod mode model modify month mopen mort mprint mrecall msglevel msymtabmax mvarsize myy n nest netpv new news nmiss no nobatch nobs nocaps nocardimage nocenter nocharcode nocmdmac nocol nocum nodate nodbcs nodetails nodmr nodms nodmsbatch nodup nodupkey noduplicates noechoauto noequals noerrorabend noexitwindows nofullstimer noicon noimplmac noint nolist noloadlist nomiss nomlogic nomprint nomrecall nomsgcase nomstored nomultenvappl nonotes nonumber noobs noovp nopad nopercent noprint noprintinit normal norow norsasuser nosetinit nosplash nosymbolgen note notes notitle notitles notsorted noverbose noxsync noxwait npv null number numkeys nummousekeys nway obs on open order ordinal otherwise out outer outp= output over ovp p(1 5 10 25 50 75 90 95 99) pad pad2 paired parm parmcards path pathdll pathname pdf peek peekc pfkey pmf point poisson poke position printer probbeta probbnml probchi probf probgam probhypr probit probnegb probnorm probsig probt procleave prt ps pw pwreq qtr quote r ranbin rancau random ranexp rangam range ranks rannor ranpoi rantbl rantri ranuni rcorr read recfm register regr remote remove rename repeat repeated replace resolve retain return reuse reverse rewind right round rsquare rtf rtrace rtraceloc s s2 samploc sasautos sascontrol sasfrscr sasmsg sasmstore sasscript sasuser saving scan sdf second select selection separated seq serror set setcomm setot sign simple sin sinh siteinfo skewness skip sle sls sortedby sortpgm sortseq sortsize soundex spedis splashlocation split spool sqrt start std stderr stdin stfips stimer stname stnamel stop stopover sub subgroup subpopn substr sum sumwgt symbol symbolgen symget symput sysget sysin sysleave sysmsg sysparm sysprint sysprintfont sysprod sysrc system t table tables tan tanh tapeclose tbufsize terminal test then timepart tinv tnonct to today tol tooldef totper transformout translate trantab tranwrd trigamma trim trimn trunc truncover type unformatted uniform union until upcase update user usericon uss validate value var weight when where while wincharset window work workinit workterm write wsum xsync xwait yearcutoff yes yyq min max', ['inDataStep', 'inProc']);
+ define('operator', 'and not ', ['inDataStep', 'inProc']);
+
+ // Main function
+ function tokenize(stream, state) {
+ // Finally advance the stream
+ var ch = stream.next();
+
+ // BLOCKCOMMENT
+ if (ch === '/' && stream.eat('*')) {
+ state.continueComment = true;
+ return "comment";
+ } else if (state.continueComment === true) { // in comment block
+ //comment ends at the beginning of the line
+ if (ch === '*' && stream.peek() === '/') {
+ stream.next();
+ state.continueComment = false;
+ } else if (stream.skipTo('*')) { //comment is potentially later in line
+ stream.skipTo('*');
+ stream.next();
+ if (stream.eat('/'))
+ state.continueComment = false;
+ } else {
+ stream.skipToEnd();
+ }
+ return "comment";
+ }
+
+ if (ch == "*" && stream.column() == stream.indentation()) {
+ stream.skipToEnd()
+ return "comment"
+ }
+
+ // DoubleOperator match
+ var doubleOperator = ch + stream.peek();
+
+ if ((ch === '"' || ch === "'") && !state.continueString) {
+ state.continueString = ch
+ return "string"
+ } else if (state.continueString) {
+ if (state.continueString == ch) {
+ state.continueString = null;
+ } else if (stream.skipTo(state.continueString)) {
+ // quote found on this line
+ stream.next();
+ state.continueString = null;
+ } else {
+ stream.skipToEnd();
+ }
+ return "string";
+ } else if (state.continueString !== null && stream.eol()) {
+ stream.skipTo(state.continueString) || stream.skipToEnd();
+ return "string";
+ } else if (/[\d\.]/.test(ch)) { //find numbers
+ if (ch === ".")
+ stream.match(/^[0-9]+([eE][\-+]?[0-9]+)?/);
+ else if (ch === "0")
+ stream.match(/^[xX][0-9a-fA-F]+/) || stream.match(/^0[0-7]+/);
+ else
+ stream.match(/^[0-9]*\.?[0-9]*([eE][\-+]?[0-9]+)?/);
+ return "number";
+ } else if (isDoubleOperatorChar.test(ch + stream.peek())) { // TWO SYMBOL TOKENS
+ stream.next();
+ return "operator";
+ } else if (isDoubleOperatorSym.hasOwnProperty(doubleOperator)) {
+ stream.next();
+ if (stream.peek() === ' ')
+ return isDoubleOperatorSym[doubleOperator.toLowerCase()];
+ } else if (isSingleOperatorChar.test(ch)) { // SINGLE SYMBOL TOKENS
+ return "operator";
+ }
+
+ // Matches one whole word -- even if the word is a character
+ var word;
+ if (stream.match(/[%&;\w]+/, false) != null) {
+ word = ch + stream.match(/[%&;\w]+/, true);
+ if (/&/.test(word)) return 'variable'
+ } else {
+ word = ch;
+ }
+ // the word after DATA PROC or MACRO
+ if (state.nextword) {
+ stream.match(/[\w]+/);
+ // match memname.libname
+ if (stream.peek() === '.') stream.skipTo(' ');
+ state.nextword = false;
+ return 'variable-2';
+ }
+
+ word = word.toLowerCase()
+ // Are we in a DATA Step?
+ if (state.inDataStep) {
+ if (word === 'run;' || stream.match(/run\s;/)) {
+ state.inDataStep = false;
+ return 'builtin';
+ }
+ // variable formats
+ if ((word) && stream.next() === '.') {
+ //either a format or libname.memname
+ if (/\w/.test(stream.peek())) return 'variable-2';
+ else return 'variable';
+ }
+ // do we have a DATA Step keyword
+ if (word && words.hasOwnProperty(word) &&
+ (words[word].state.indexOf("inDataStep") !== -1 ||
+ words[word].state.indexOf("ALL") !== -1)) {
+ //backup to the start of the word
+ if (stream.start < stream.pos)
+ stream.backUp(stream.pos - stream.start);
+ //advance the length of the word and return
+ for (var i = 0; i < word.length; ++i) stream.next();
+ return words[word].style;
+ }
+ }
+ // Are we in an Proc statement?
+ if (state.inProc) {
+ if (word === 'run;' || word === 'quit;') {
+ state.inProc = false;
+ return 'builtin';
+ }
+ // do we have a proc keyword
+ if (word && words.hasOwnProperty(word) &&
+ (words[word].state.indexOf("inProc") !== -1 ||
+ words[word].state.indexOf("ALL") !== -1)) {
+ stream.match(/[\w]+/);
+ return words[word].style;
+ }
+ }
+ // Are we in a Macro statement?
+ if (state.inMacro) {
+ if (word === '%mend') {
+ if (stream.peek() === ';') stream.next();
+ state.inMacro = false;
+ return 'builtin';
+ }
+ if (word && words.hasOwnProperty(word) &&
+ (words[word].state.indexOf("inMacro") !== -1 ||
+ words[word].state.indexOf("ALL") !== -1)) {
+ stream.match(/[\w]+/);
+ return words[word].style;
+ }
+
+ return 'atom';
+ }
+ // Do we have Keywords specific words?
+ if (word && words.hasOwnProperty(word)) {
+ // Negates the initial next()
+ stream.backUp(1);
+ // Actually move the stream
+ stream.match(/[\w]+/);
+ if (word === 'data' && /=/.test(stream.peek()) === false) {
+ state.inDataStep = true;
+ state.nextword = true;
+ return 'builtin';
+ }
+ if (word === 'proc') {
+ state.inProc = true;
+ state.nextword = true;
+ return 'builtin';
+ }
+ if (word === '%macro') {
+ state.inMacro = true;
+ state.nextword = true;
+ return 'builtin';
+ }
+ if (/title[1-9]/.test(word)) return 'def';
+
+ if (word === 'footnote') {
+ stream.eat(/[1-9]/);
+ return 'def';
+ }
+
+ // Returns their value as state in the prior define methods
+ if (state.inDataStep === true && words[word].state.indexOf("inDataStep") !== -1)
+ return words[word].style;
+ if (state.inProc === true && words[word].state.indexOf("inProc") !== -1)
+ return words[word].style;
+ if (state.inMacro === true && words[word].state.indexOf("inMacro") !== -1)
+ return words[word].style;
+ if (words[word].state.indexOf("ALL") !== -1)
+ return words[word].style;
+ return null;
+ }
+ // Unrecognized syntax
+ return null;
+ }
+
+ return {
+ startState: function () {
+ return {
+ inDataStep: false,
+ inProc: false,
+ inMacro: false,
+ nextword: false,
+ continueString: null,
+ continueComment: false
+ };
+ },
+ token: function (stream, state) {
+ // Strip the spaces, but regex will account for them either way
+ if (stream.eatSpace()) return null;
+ // Go through the main process
+ return tokenize(stream, state);
+ },
+
+ blockCommentStart: "/*",
+ blockCommentEnd: "*/"
+ };
+
+ });
+
+ CodeMirror.defineMIME("text/x-sas", "sas");
+});
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/sass/sass.js b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/sass/sass.js
new file mode 100644
index 0000000000..d8427bff57
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/sass/sass.js
@@ -0,0 +1,459 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: https://codemirror.net/LICENSE
+
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
+ mod(require("../../lib/codemirror"), require("../css/css"));
+ else if (typeof define == "function" && define.amd) // AMD
+ define(["../../lib/codemirror", "../css/css"], mod);
+ else // Plain browser env
+ mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("sass", function(config) {
+ var cssMode = CodeMirror.mimeModes["text/css"];
+ var propertyKeywords = cssMode.propertyKeywords || {},
+ colorKeywords = cssMode.colorKeywords || {},
+ valueKeywords = cssMode.valueKeywords || {},
+ fontProperties = cssMode.fontProperties || {};
+
+ function tokenRegexp(words) {
+ return new RegExp("^" + words.join("|"));
+ }
+
+ var keywords = ["true", "false", "null", "auto"];
+ var keywordsRegexp = new RegExp("^" + keywords.join("|"));
+
+ var operators = ["\\(", "\\)", "=", ">", "<", "==", ">=", "<=", "\\+", "-",
+ "\\!=", "/", "\\*", "%", "and", "or", "not", ";","\\{","\\}",":"];
+ var opRegexp = tokenRegexp(operators);
+
+ var pseudoElementsRegexp = /^::?[a-zA-Z_][\w\-]*/;
+
+ var word;
+
+ function isEndLine(stream) {
+ return !stream.peek() || stream.match(/\s+$/, false);
+ }
+
+ function urlTokens(stream, state) {
+ var ch = stream.peek();
+
+ if (ch === ")") {
+ stream.next();
+ state.tokenizer = tokenBase;
+ return "operator";
+ } else if (ch === "(") {
+ stream.next();
+ stream.eatSpace();
+
+ return "operator";
+ } else if (ch === "'" || ch === '"') {
+ state.tokenizer = buildStringTokenizer(stream.next());
+ return "string";
+ } else {
+ state.tokenizer = buildStringTokenizer(")", false);
+ return "string";
+ }
+ }
+ function comment(indentation, multiLine) {
+ return function(stream, state) {
+ if (stream.sol() && stream.indentation() <= indentation) {
+ state.tokenizer = tokenBase;
+ return tokenBase(stream, state);
+ }
+
+ if (multiLine && stream.skipTo("*/")) {
+ stream.next();
+ stream.next();
+ state.tokenizer = tokenBase;
+ } else {
+ stream.skipToEnd();
+ }
+
+ return "comment";
+ };
+ }
+
+ function buildStringTokenizer(quote, greedy) {
+ if (greedy == null) { greedy = true; }
+
+ function stringTokenizer(stream, state) {
+ var nextChar = stream.next();
+ var peekChar = stream.peek();
+ var previousChar = stream.string.charAt(stream.pos-2);
+
+ var endingString = ((nextChar !== "\\" && peekChar === quote) || (nextChar === quote && previousChar !== "\\"));
+
+ if (endingString) {
+ if (nextChar !== quote && greedy) { stream.next(); }
+ if (isEndLine(stream)) {
+ state.cursorHalf = 0;
+ }
+ state.tokenizer = tokenBase;
+ return "string";
+ } else if (nextChar === "#" && peekChar === "{") {
+ state.tokenizer = buildInterpolationTokenizer(stringTokenizer);
+ stream.next();
+ return "operator";
+ } else {
+ return "string";
+ }
+ }
+
+ return stringTokenizer;
+ }
+
+ function buildInterpolationTokenizer(currentTokenizer) {
+ return function(stream, state) {
+ if (stream.peek() === "}") {
+ stream.next();
+ state.tokenizer = currentTokenizer;
+ return "operator";
+ } else {
+ return tokenBase(stream, state);
+ }
+ };
+ }
+
+ function indent(state) {
+ if (state.indentCount == 0) {
+ state.indentCount++;
+ var lastScopeOffset = state.scopes[0].offset;
+ var currentOffset = lastScopeOffset + config.indentUnit;
+ state.scopes.unshift({ offset:currentOffset });
+ }
+ }
+
+ function dedent(state) {
+ if (state.scopes.length == 1) return;
+
+ state.scopes.shift();
+ }
+
+ function tokenBase(stream, state) {
+ var ch = stream.peek();
+
+ // Comment
+ if (stream.match("/*")) {
+ state.tokenizer = comment(stream.indentation(), true);
+ return state.tokenizer(stream, state);
+ }
+ if (stream.match("//")) {
+ state.tokenizer = comment(stream.indentation(), false);
+ return state.tokenizer(stream, state);
+ }
+
+ // Interpolation
+ if (stream.match("#{")) {
+ state.tokenizer = buildInterpolationTokenizer(tokenBase);
+ return "operator";
+ }
+
+ // Strings
+ if (ch === '"' || ch === "'") {
+ stream.next();
+ state.tokenizer = buildStringTokenizer(ch);
+ return "string";
+ }
+
+ if(!state.cursorHalf){// state.cursorHalf === 0
+ // first half i.e. before : for key-value pairs
+ // including selectors
+
+ if (ch === "-") {
+ if (stream.match(/^-\w+-/)) {
+ return "meta";
+ }
+ }
+
+ if (ch === ".") {
+ stream.next();
+ if (stream.match(/^[\w-]+/)) {
+ indent(state);
+ return "qualifier";
+ } else if (stream.peek() === "#") {
+ indent(state);
+ return "tag";
+ }
+ }
+
+ if (ch === "#") {
+ stream.next();
+ // ID selectors
+ if (stream.match(/^[\w-]+/)) {
+ indent(state);
+ return "builtin";
+ }
+ if (stream.peek() === "#") {
+ indent(state);
+ return "tag";
+ }
+ }
+
+ // Variables
+ if (ch === "$") {
+ stream.next();
+ stream.eatWhile(/[\w-]/);
+ return "variable-2";
+ }
+
+ // Numbers
+ if (stream.match(/^-?[0-9\.]+/))
+ return "number";
+
+ // Units
+ if (stream.match(/^(px|em|in)\b/))
+ return "unit";
+
+ if (stream.match(keywordsRegexp))
+ return "keyword";
+
+ if (stream.match(/^url/) && stream.peek() === "(") {
+ state.tokenizer = urlTokens;
+ return "atom";
+ }
+
+ if (ch === "=") {
+ // Match shortcut mixin definition
+ if (stream.match(/^=[\w-]+/)) {
+ indent(state);
+ return "meta";
+ }
+ }
+
+ if (ch === "+") {
+ // Match shortcut mixin definition
+ if (stream.match(/^\+[\w-]+/)){
+ return "variable-3";
+ }
+ }
+
+ if(ch === "@"){
+ if(stream.match('@extend')){
+ if(!stream.match(/\s*[\w]/))
+ dedent(state);
+ }
+ }
+
+
+ // Indent Directives
+ if (stream.match(/^@(else if|if|media|else|for|each|while|mixin|function)/)) {
+ indent(state);
+ return "def";
+ }
+
+ // Other Directives
+ if (ch === "@") {
+ stream.next();
+ stream.eatWhile(/[\w-]/);
+ return "def";
+ }
+
+ if (stream.eatWhile(/[\w-]/)){
+ if(stream.match(/ *: *[\w-\+\$#!\("']/,false)){
+ word = stream.current().toLowerCase();
+ var prop = state.prevProp + "-" + word;
+ if (propertyKeywords.hasOwnProperty(prop)) {
+ return "property";
+ } else if (propertyKeywords.hasOwnProperty(word)) {
+ state.prevProp = word;
+ return "property";
+ } else if (fontProperties.hasOwnProperty(word)) {
+ return "property";
+ }
+ return "tag";
+ }
+ else if(stream.match(/ *:/,false)){
+ indent(state);
+ state.cursorHalf = 1;
+ state.prevProp = stream.current().toLowerCase();
+ return "property";
+ }
+ else if(stream.match(/ *,/,false)){
+ return "tag";
+ }
+ else{
+ indent(state);
+ return "tag";
+ }
+ }
+
+ if(ch === ":"){
+ if (stream.match(pseudoElementsRegexp)){ // could be a pseudo-element
+ return "variable-3";
+ }
+ stream.next();
+ state.cursorHalf=1;
+ return "operator";
+ }
+
+ } // cursorHalf===0 ends here
+ else{
+
+ if (ch === "#") {
+ stream.next();
+ // Hex numbers
+ if (stream.match(/[0-9a-fA-F]{6}|[0-9a-fA-F]{3}/)){
+ if (isEndLine(stream)) {
+ state.cursorHalf = 0;
+ }
+ return "number";
+ }
+ }
+
+ // Numbers
+ if (stream.match(/^-?[0-9\.]+/)){
+ if (isEndLine(stream)) {
+ state.cursorHalf = 0;
+ }
+ return "number";
+ }
+
+ // Units
+ if (stream.match(/^(px|em|in)\b/)){
+ if (isEndLine(stream)) {
+ state.cursorHalf = 0;
+ }
+ return "unit";
+ }
+
+ if (stream.match(keywordsRegexp)){
+ if (isEndLine(stream)) {
+ state.cursorHalf = 0;
+ }
+ return "keyword";
+ }
+
+ if (stream.match(/^url/) && stream.peek() === "(") {
+ state.tokenizer = urlTokens;
+ if (isEndLine(stream)) {
+ state.cursorHalf = 0;
+ }
+ return "atom";
+ }
+
+ // Variables
+ if (ch === "$") {
+ stream.next();
+ stream.eatWhile(/[\w-]/);
+ if (isEndLine(stream)) {
+ state.cursorHalf = 0;
+ }
+ return "variable-2";
+ }
+
+ // bang character for !important, !default, etc.
+ if (ch === "!") {
+ stream.next();
+ state.cursorHalf = 0;
+ return stream.match(/^[\w]+/) ? "keyword": "operator";
+ }
+
+ if (stream.match(opRegexp)){
+ if (isEndLine(stream)) {
+ state.cursorHalf = 0;
+ }
+ return "operator";
+ }
+
+ // attributes
+ if (stream.eatWhile(/[\w-]/)) {
+ if (isEndLine(stream)) {
+ state.cursorHalf = 0;
+ }
+ word = stream.current().toLowerCase();
+ if (valueKeywords.hasOwnProperty(word)) {
+ return "atom";
+ } else if (colorKeywords.hasOwnProperty(word)) {
+ return "keyword";
+ } else if (propertyKeywords.hasOwnProperty(word)) {
+ state.prevProp = stream.current().toLowerCase();
+ return "property";
+ } else {
+ return "tag";
+ }
+ }
+
+ //stream.eatSpace();
+ if (isEndLine(stream)) {
+ state.cursorHalf = 0;
+ return null;
+ }
+
+ } // else ends here
+
+ if (stream.match(opRegexp))
+ return "operator";
+
+ // If we haven't returned by now, we move 1 character
+ // and return an error
+ stream.next();
+ return null;
+ }
+
+ function tokenLexer(stream, state) {
+ if (stream.sol()) state.indentCount = 0;
+ var style = state.tokenizer(stream, state);
+ var current = stream.current();
+
+ if (current === "@return" || current === "}"){
+ dedent(state);
+ }
+
+ if (style !== null) {
+ var startOfToken = stream.pos - current.length;
+
+ var withCurrentIndent = startOfToken + (config.indentUnit * state.indentCount);
+
+ var newScopes = [];
+
+ for (var i = 0; i < state.scopes.length; i++) {
+ var scope = state.scopes[i];
+
+ if (scope.offset <= withCurrentIndent)
+ newScopes.push(scope);
+ }
+
+ state.scopes = newScopes;
+ }
+
+
+ return style;
+ }
+
+ return {
+ startState: function() {
+ return {
+ tokenizer: tokenBase,
+ scopes: [{offset: 0, type: "sass"}],
+ indentCount: 0,
+ cursorHalf: 0, // cursor half tells us if cursor lies after (1)
+ // or before (0) colon (well... more or less)
+ definedVars: [],
+ definedMixins: []
+ };
+ },
+ token: function(stream, state) {
+ var style = tokenLexer(stream, state);
+
+ state.lastToken = { style: style, content: stream.current() };
+
+ return style;
+ },
+
+ indent: function(state) {
+ return state.scopes[0].offset;
+ },
+
+ blockCommentStart: "/*",
+ blockCommentEnd: "*/",
+ lineComment: "//",
+ fold: "indent"
+ };
+}, "css");
+
+CodeMirror.defineMIME("text/x-sass", "sass");
+
+});
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/scheme/scheme.js b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/scheme/scheme.js
new file mode 100644
index 0000000000..d11a132df3
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/scheme/scheme.js
@@ -0,0 +1,284 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: https://codemirror.net/LICENSE
+
+/**
+ * Author: Koh Zi Han, based on implementation by Koh Zi Chun
+ * Improved by: Jakub T. Jankiewicz
+ */
+
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
+ mod(require("../../lib/codemirror"));
+ else if (typeof define == "function" && define.amd) // AMD
+ define(["../../lib/codemirror"], mod);
+ else // Plain browser env
+ mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("scheme", function () {
+ var BUILTIN = "builtin", COMMENT = "comment", STRING = "string",
+ SYMBOL = "symbol", ATOM = "atom", NUMBER = "number", BRACKET = "bracket";
+ var INDENT_WORD_SKIP = 2;
+
+ function makeKeywords(str) {
+ var obj = {}, words = str.split(" ");
+ for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
+ return obj;
+ }
+
+ var keywords = makeKeywords("λ case-lambda call/cc class cond-expand define-class define-values exit-handler field import inherit init-field interface let*-values let-values let/ec mixin opt-lambda override protect provide public rename require require-for-syntax syntax syntax-case syntax-error unit/sig unless when with-syntax and begin call-with-current-continuation call-with-input-file call-with-output-file case cond define define-syntax define-macro defmacro delay do dynamic-wind else for-each if lambda let let* let-syntax letrec letrec-syntax map or syntax-rules abs acos angle append apply asin assoc assq assv atan boolean? caar cadr call-with-input-file call-with-output-file call-with-values car cdddar cddddr cdr ceiling char->integer char-alphabetic? char-ci<=? char-ci char-ci=? char-ci>=? char-ci>? char-downcase char-lower-case? char-numeric? char-ready? char-upcase char-upper-case? char-whitespace? char<=? char char=? char>=? char>? char? close-input-port close-output-port complex? cons cos current-input-port current-output-port denominator display eof-object? eq? equal? eqv? eval even? exact->inexact exact? exp expt #f floor force gcd imag-part inexact->exact inexact? input-port? integer->char integer? interaction-environment lcm length list list->string list->vector list-ref list-tail list? load log magnitude make-polar make-rectangular make-string make-vector max member memq memv min modulo negative? newline not null-environment null? number->string number? numerator odd? open-input-file open-output-file output-port? pair? peek-char port? positive? procedure? quasiquote quote quotient rational? rationalize read read-char real-part real? remainder reverse round scheme-report-environment set! set-car! set-cdr! sin sqrt string string->list string->number string->symbol string-append string-ci<=? string-ci string-ci=? string-ci>=? string-ci>? string-copy string-fill! string-length string-ref string-set! string<=? string string=? string>=? string>? string? substring symbol->string symbol? #t tan transcript-off transcript-on truncate values vector vector->list vector-fill! vector-length vector-ref vector-set! with-input-from-file with-output-to-file write write-char zero?");
+ var indentKeys = makeKeywords("define let letrec let* lambda define-macro defmacro let-syntax letrec-syntax let-values let*-values define-syntax syntax-rules define-values when unless");
+
+ function stateStack(indent, type, prev) { // represents a state stack object
+ this.indent = indent;
+ this.type = type;
+ this.prev = prev;
+ }
+
+ function pushStack(state, indent, type) {
+ state.indentStack = new stateStack(indent, type, state.indentStack);
+ }
+
+ function popStack(state) {
+ state.indentStack = state.indentStack.prev;
+ }
+
+ var binaryMatcher = new RegExp(/^(?:[-+]i|[-+][01]+#*(?:\/[01]+#*)?i|[-+]?[01]+#*(?:\/[01]+#*)?@[-+]?[01]+#*(?:\/[01]+#*)?|[-+]?[01]+#*(?:\/[01]+#*)?[-+](?:[01]+#*(?:\/[01]+#*)?)?i|[-+]?[01]+#*(?:\/[01]+#*)?)(?=[()\s;"]|$)/i);
+ var octalMatcher = new RegExp(/^(?:[-+]i|[-+][0-7]+#*(?:\/[0-7]+#*)?i|[-+]?[0-7]+#*(?:\/[0-7]+#*)?@[-+]?[0-7]+#*(?:\/[0-7]+#*)?|[-+]?[0-7]+#*(?:\/[0-7]+#*)?[-+](?:[0-7]+#*(?:\/[0-7]+#*)?)?i|[-+]?[0-7]+#*(?:\/[0-7]+#*)?)(?=[()\s;"]|$)/i);
+ var hexMatcher = new RegExp(/^(?:[-+]i|[-+][\da-f]+#*(?:\/[\da-f]+#*)?i|[-+]?[\da-f]+#*(?:\/[\da-f]+#*)?@[-+]?[\da-f]+#*(?:\/[\da-f]+#*)?|[-+]?[\da-f]+#*(?:\/[\da-f]+#*)?[-+](?:[\da-f]+#*(?:\/[\da-f]+#*)?)?i|[-+]?[\da-f]+#*(?:\/[\da-f]+#*)?)(?=[()\s;"]|$)/i);
+ var decimalMatcher = new RegExp(/^(?:[-+]i|[-+](?:(?:(?:\d+#+\.?#*|\d+\.\d*#*|\.\d+#*|\d+)(?:[esfdl][-+]?\d+)?)|\d+#*\/\d+#*)i|[-+]?(?:(?:(?:\d+#+\.?#*|\d+\.\d*#*|\.\d+#*|\d+)(?:[esfdl][-+]?\d+)?)|\d+#*\/\d+#*)@[-+]?(?:(?:(?:\d+#+\.?#*|\d+\.\d*#*|\.\d+#*|\d+)(?:[esfdl][-+]?\d+)?)|\d+#*\/\d+#*)|[-+]?(?:(?:(?:\d+#+\.?#*|\d+\.\d*#*|\.\d+#*|\d+)(?:[esfdl][-+]?\d+)?)|\d+#*\/\d+#*)[-+](?:(?:(?:\d+#+\.?#*|\d+\.\d*#*|\.\d+#*|\d+)(?:[esfdl][-+]?\d+)?)|\d+#*\/\d+#*)?i|(?:(?:(?:\d+#+\.?#*|\d+\.\d*#*|\.\d+#*|\d+)(?:[esfdl][-+]?\d+)?)|\d+#*\/\d+#*))(?=[()\s;"]|$)/i);
+
+ function isBinaryNumber (stream) {
+ return stream.match(binaryMatcher);
+ }
+
+ function isOctalNumber (stream) {
+ return stream.match(octalMatcher);
+ }
+
+ function isDecimalNumber (stream, backup) {
+ if (backup === true) {
+ stream.backUp(1);
+ }
+ return stream.match(decimalMatcher);
+ }
+
+ function isHexNumber (stream) {
+ return stream.match(hexMatcher);
+ }
+
+ function processEscapedSequence(stream, options) {
+ var next, escaped = false;
+ while ((next = stream.next()) != null) {
+ if (next == options.token && !escaped) {
+
+ options.state.mode = false;
+ break;
+ }
+ escaped = !escaped && next == "\\";
+ }
+ }
+
+ return {
+ startState: function () {
+ return {
+ indentStack: null,
+ indentation: 0,
+ mode: false,
+ sExprComment: false,
+ sExprQuote: false
+ };
+ },
+
+ token: function (stream, state) {
+ if (state.indentStack == null && stream.sol()) {
+ // update indentation, but only if indentStack is empty
+ state.indentation = stream.indentation();
+ }
+
+ // skip spaces
+ if (stream.eatSpace()) {
+ return null;
+ }
+ var returnType = null;
+
+ switch(state.mode){
+ case "string": // multi-line string parsing mode
+ processEscapedSequence(stream, {
+ token: "\"",
+ state: state
+ });
+ returnType = STRING; // continue on in scheme-string mode
+ break;
+ case "symbol": // escape symbol
+ processEscapedSequence(stream, {
+ token: "|",
+ state: state
+ });
+ returnType = SYMBOL; // continue on in scheme-symbol mode
+ break;
+ case "comment": // comment parsing mode
+ var next, maybeEnd = false;
+ while ((next = stream.next()) != null) {
+ if (next == "#" && maybeEnd) {
+
+ state.mode = false;
+ break;
+ }
+ maybeEnd = (next == "|");
+ }
+ returnType = COMMENT;
+ break;
+ case "s-expr-comment": // s-expr commenting mode
+ state.mode = false;
+ if(stream.peek() == "(" || stream.peek() == "["){
+ // actually start scheme s-expr commenting mode
+ state.sExprComment = 0;
+ }else{
+ // if not we just comment the entire of the next token
+ stream.eatWhile(/[^\s\(\)\[\]]/); // eat symbol atom
+ returnType = COMMENT;
+ break;
+ }
+ default: // default parsing mode
+ var ch = stream.next();
+
+ if (ch == "\"") {
+ state.mode = "string";
+ returnType = STRING;
+
+ } else if (ch == "'") {
+ if (stream.peek() == "(" || stream.peek() == "["){
+ if (typeof state.sExprQuote != "number") {
+ state.sExprQuote = 0;
+ } // else already in a quoted expression
+ returnType = ATOM;
+ } else {
+ stream.eatWhile(/[\w_\-!$%&*+\.\/:<=>?@\^~]/);
+ returnType = ATOM;
+ }
+ } else if (ch == '|') {
+ state.mode = "symbol";
+ returnType = SYMBOL;
+ } else if (ch == '#') {
+ if (stream.eat("|")) { // Multi-line comment
+ state.mode = "comment"; // toggle to comment mode
+ returnType = COMMENT;
+ } else if (stream.eat(/[tf]/i)) { // #t/#f (atom)
+ returnType = ATOM;
+ } else if (stream.eat(';')) { // S-Expr comment
+ state.mode = "s-expr-comment";
+ returnType = COMMENT;
+ } else {
+ var numTest = null, hasExactness = false, hasRadix = true;
+ if (stream.eat(/[ei]/i)) {
+ hasExactness = true;
+ } else {
+ stream.backUp(1); // must be radix specifier
+ }
+ if (stream.match(/^#b/i)) {
+ numTest = isBinaryNumber;
+ } else if (stream.match(/^#o/i)) {
+ numTest = isOctalNumber;
+ } else if (stream.match(/^#x/i)) {
+ numTest = isHexNumber;
+ } else if (stream.match(/^#d/i)) {
+ numTest = isDecimalNumber;
+ } else if (stream.match(/^[-+0-9.]/, false)) {
+ hasRadix = false;
+ numTest = isDecimalNumber;
+ // re-consume the initial # if all matches failed
+ } else if (!hasExactness) {
+ stream.eat('#');
+ }
+ if (numTest != null) {
+ if (hasRadix && !hasExactness) {
+ // consume optional exactness after radix
+ stream.match(/^#[ei]/i);
+ }
+ if (numTest(stream))
+ returnType = NUMBER;
+ }
+ }
+ } else if (/^[-+0-9.]/.test(ch) && isDecimalNumber(stream, true)) { // match non-prefixed number, must be decimal
+ returnType = NUMBER;
+ } else if (ch == ";") { // comment
+ stream.skipToEnd(); // rest of the line is a comment
+ returnType = COMMENT;
+ } else if (ch == "(" || ch == "[") {
+ var keyWord = ''; var indentTemp = stream.column(), letter;
+ /**
+ Either
+ (indent-word ..
+ (non-indent-word ..
+ (;something else, bracket, etc.
+ */
+
+ while ((letter = stream.eat(/[^\s\(\[\;\)\]]/)) != null) {
+ keyWord += letter;
+ }
+
+ if (keyWord.length > 0 && indentKeys.propertyIsEnumerable(keyWord)) { // indent-word
+
+ pushStack(state, indentTemp + INDENT_WORD_SKIP, ch);
+ } else { // non-indent word
+ // we continue eating the spaces
+ stream.eatSpace();
+ if (stream.eol() || stream.peek() == ";") {
+ // nothing significant after
+ // we restart indentation 1 space after
+ pushStack(state, indentTemp + 1, ch);
+ } else {
+ pushStack(state, indentTemp + stream.current().length, ch); // else we match
+ }
+ }
+ stream.backUp(stream.current().length - 1); // undo all the eating
+
+ if(typeof state.sExprComment == "number") state.sExprComment++;
+ if(typeof state.sExprQuote == "number") state.sExprQuote++;
+
+ returnType = BRACKET;
+ } else if (ch == ")" || ch == "]") {
+ returnType = BRACKET;
+ if (state.indentStack != null && state.indentStack.type == (ch == ")" ? "(" : "[")) {
+ popStack(state);
+
+ if(typeof state.sExprComment == "number"){
+ if(--state.sExprComment == 0){
+ returnType = COMMENT; // final closing bracket
+ state.sExprComment = false; // turn off s-expr commenting mode
+ }
+ }
+ if(typeof state.sExprQuote == "number"){
+ if(--state.sExprQuote == 0){
+ returnType = ATOM; // final closing bracket
+ state.sExprQuote = false; // turn off s-expr quote mode
+ }
+ }
+ }
+ } else {
+ stream.eatWhile(/[\w_\-!$%&*+\.\/:<=>?@\^~]/);
+
+ if (keywords && keywords.propertyIsEnumerable(stream.current())) {
+ returnType = BUILTIN;
+ } else returnType = "variable";
+ }
+ }
+ return (typeof state.sExprComment == "number") ? COMMENT : ((typeof state.sExprQuote == "number") ? ATOM : returnType);
+ },
+
+ indent: function (state) {
+ if (state.indentStack == null) return state.indentation;
+ return state.indentStack.indent;
+ },
+
+ fold: "brace-paren",
+ closeBrackets: {pairs: "()[]{}\"\""},
+ lineComment: ";;"
+ };
+});
+
+CodeMirror.defineMIME("text/x-scheme", "scheme");
+
+});
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/shell/shell.js b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/shell/shell.js
new file mode 100644
index 0000000000..8271485f5f
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/shell/shell.js
@@ -0,0 +1,168 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: https://codemirror.net/LICENSE
+
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
+ mod(require("../../lib/codemirror"));
+ else if (typeof define == "function" && define.amd) // AMD
+ define(["../../lib/codemirror"], mod);
+ else // Plain browser env
+ mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode('shell', function() {
+
+ var words = {};
+ function define(style, dict) {
+ for(var i = 0; i < dict.length; i++) {
+ words[dict[i]] = style;
+ }
+ };
+
+ var commonAtoms = ["true", "false"];
+ var commonKeywords = ["if", "then", "do", "else", "elif", "while", "until", "for", "in", "esac", "fi",
+ "fin", "fil", "done", "exit", "set", "unset", "export", "function"];
+ var commonCommands = ["ab", "awk", "bash", "beep", "cat", "cc", "cd", "chown", "chmod", "chroot", "clear",
+ "cp", "curl", "cut", "diff", "echo", "find", "gawk", "gcc", "get", "git", "grep", "hg", "kill", "killall",
+ "ln", "ls", "make", "mkdir", "openssl", "mv", "nc", "nl", "node", "npm", "ping", "ps", "restart", "rm",
+ "rmdir", "sed", "service", "sh", "shopt", "shred", "source", "sort", "sleep", "ssh", "start", "stop",
+ "su", "sudo", "svn", "tee", "telnet", "top", "touch", "vi", "vim", "wall", "wc", "wget", "who", "write",
+ "yes", "zsh"];
+
+ CodeMirror.registerHelper("hintWords", "shell", commonAtoms.concat(commonKeywords, commonCommands));
+
+ define('atom', commonAtoms);
+ define('keyword', commonKeywords);
+ define('builtin', commonCommands);
+
+ function tokenBase(stream, state) {
+ if (stream.eatSpace()) return null;
+
+ var sol = stream.sol();
+ var ch = stream.next();
+
+ if (ch === '\\') {
+ stream.next();
+ return null;
+ }
+ if (ch === '\'' || ch === '"' || ch === '`') {
+ state.tokens.unshift(tokenString(ch, ch === "`" ? "quote" : "string"));
+ return tokenize(stream, state);
+ }
+ if (ch === '#') {
+ if (sol && stream.eat('!')) {
+ stream.skipToEnd();
+ return 'meta'; // 'comment'?
+ }
+ stream.skipToEnd();
+ return 'comment';
+ }
+ if (ch === '$') {
+ state.tokens.unshift(tokenDollar);
+ return tokenize(stream, state);
+ }
+ if (ch === '+' || ch === '=') {
+ return 'operator';
+ }
+ if (ch === '-') {
+ stream.eat('-');
+ stream.eatWhile(/\w/);
+ return 'attribute';
+ }
+ if (ch == "<") {
+ if (stream.match("<<")) return "operator"
+ var heredoc = stream.match(/^<-?\s*['"]?([^'"]*)['"]?/)
+ if (heredoc) {
+ state.tokens.unshift(tokenHeredoc(heredoc[1]))
+ return 'string-2'
+ }
+ }
+ if (/\d/.test(ch)) {
+ stream.eatWhile(/\d/);
+ if(stream.eol() || !/\w/.test(stream.peek())) {
+ return 'number';
+ }
+ }
+ stream.eatWhile(/[\w-]/);
+ var cur = stream.current();
+ if (stream.peek() === '=' && /\w+/.test(cur)) return 'def';
+ return words.hasOwnProperty(cur) ? words[cur] : null;
+ }
+
+ function tokenString(quote, style) {
+ var close = quote == "(" ? ")" : quote == "{" ? "}" : quote
+ return function(stream, state) {
+ var next, escaped = false;
+ while ((next = stream.next()) != null) {
+ if (next === close && !escaped) {
+ state.tokens.shift();
+ break;
+ } else if (next === '$' && !escaped && quote !== "'" && stream.peek() != close) {
+ escaped = true;
+ stream.backUp(1);
+ state.tokens.unshift(tokenDollar);
+ break;
+ } else if (!escaped && quote !== close && next === quote) {
+ state.tokens.unshift(tokenString(quote, style))
+ return tokenize(stream, state)
+ } else if (!escaped && /['"]/.test(next) && !/['"]/.test(quote)) {
+ state.tokens.unshift(tokenStringStart(next, "string"));
+ stream.backUp(1);
+ break;
+ }
+ escaped = !escaped && next === '\\';
+ }
+ return style;
+ };
+ };
+
+ function tokenStringStart(quote, style) {
+ return function(stream, state) {
+ state.tokens[0] = tokenString(quote, style)
+ stream.next()
+ return tokenize(stream, state)
+ }
+ }
+
+ var tokenDollar = function(stream, state) {
+ if (state.tokens.length > 1) stream.eat('$');
+ var ch = stream.next()
+ if (/['"({]/.test(ch)) {
+ state.tokens[0] = tokenString(ch, ch == "(" ? "quote" : ch == "{" ? "def" : "string");
+ return tokenize(stream, state);
+ }
+ if (!/\d/.test(ch)) stream.eatWhile(/\w/);
+ state.tokens.shift();
+ return 'def';
+ };
+
+ function tokenHeredoc(delim) {
+ return function(stream, state) {
+ if (stream.sol() && stream.string == delim) state.tokens.shift()
+ stream.skipToEnd()
+ return "string-2"
+ }
+ }
+
+ function tokenize(stream, state) {
+ return (state.tokens[0] || tokenBase) (stream, state);
+ };
+
+ return {
+ startState: function() {return {tokens:[]};},
+ token: function(stream, state) {
+ return tokenize(stream, state);
+ },
+ closeBrackets: "()[]{}''\"\"``",
+ lineComment: '#',
+ fold: "brace"
+ };
+});
+
+CodeMirror.defineMIME('text/x-sh', 'shell');
+// Apache uses a slightly different Media Type for Shell scripts
+// http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types
+CodeMirror.defineMIME('application/x-sh', 'shell');
+
+});
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/sieve/sieve.js b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/sieve/sieve.js
new file mode 100644
index 0000000000..b7236401a7
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/sieve/sieve.js
@@ -0,0 +1,193 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: https://codemirror.net/LICENSE
+
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
+ mod(require("../../lib/codemirror"));
+ else if (typeof define == "function" && define.amd) // AMD
+ define(["../../lib/codemirror"], mod);
+ else // Plain browser env
+ mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("sieve", function(config) {
+ function words(str) {
+ var obj = {}, words = str.split(" ");
+ for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
+ return obj;
+ }
+
+ var keywords = words("if elsif else stop require");
+ var atoms = words("true false not");
+ var indentUnit = config.indentUnit;
+
+ function tokenBase(stream, state) {
+
+ var ch = stream.next();
+ if (ch == "/" && stream.eat("*")) {
+ state.tokenize = tokenCComment;
+ return tokenCComment(stream, state);
+ }
+
+ if (ch === '#') {
+ stream.skipToEnd();
+ return "comment";
+ }
+
+ if (ch == "\"") {
+ state.tokenize = tokenString(ch);
+ return state.tokenize(stream, state);
+ }
+
+ if (ch == "(") {
+ state._indent.push("(");
+ // add virtual angel wings so that editor behaves...
+ // ...more sane in case of broken brackets
+ state._indent.push("{");
+ return null;
+ }
+
+ if (ch === "{") {
+ state._indent.push("{");
+ return null;
+ }
+
+ if (ch == ")") {
+ state._indent.pop();
+ state._indent.pop();
+ }
+
+ if (ch === "}") {
+ state._indent.pop();
+ return null;
+ }
+
+ if (ch == ",")
+ return null;
+
+ if (ch == ";")
+ return null;
+
+
+ if (/[{}\(\),;]/.test(ch))
+ return null;
+
+ // 1*DIGIT "K" / "M" / "G"
+ if (/\d/.test(ch)) {
+ stream.eatWhile(/[\d]/);
+ stream.eat(/[KkMmGg]/);
+ return "number";
+ }
+
+ // ":" (ALPHA / "_") *(ALPHA / DIGIT / "_")
+ if (ch == ":") {
+ stream.eatWhile(/[a-zA-Z_]/);
+ stream.eatWhile(/[a-zA-Z0-9_]/);
+
+ return "operator";
+ }
+
+ stream.eatWhile(/\w/);
+ var cur = stream.current();
+
+ // "text:" *(SP / HTAB) (hash-comment / CRLF)
+ // *(multiline-literal / multiline-dotstart)
+ // "." CRLF
+ if ((cur == "text") && stream.eat(":"))
+ {
+ state.tokenize = tokenMultiLineString;
+ return "string";
+ }
+
+ if (keywords.propertyIsEnumerable(cur))
+ return "keyword";
+
+ if (atoms.propertyIsEnumerable(cur))
+ return "atom";
+
+ return null;
+ }
+
+ function tokenMultiLineString(stream, state)
+ {
+ state._multiLineString = true;
+ // the first line is special it may contain a comment
+ if (!stream.sol()) {
+ stream.eatSpace();
+
+ if (stream.peek() == "#") {
+ stream.skipToEnd();
+ return "comment";
+ }
+
+ stream.skipToEnd();
+ return "string";
+ }
+
+ if ((stream.next() == ".") && (stream.eol()))
+ {
+ state._multiLineString = false;
+ state.tokenize = tokenBase;
+ }
+
+ return "string";
+ }
+
+ function tokenCComment(stream, state) {
+ var maybeEnd = false, ch;
+ while ((ch = stream.next()) != null) {
+ if (maybeEnd && ch == "/") {
+ state.tokenize = tokenBase;
+ break;
+ }
+ maybeEnd = (ch == "*");
+ }
+ return "comment";
+ }
+
+ function tokenString(quote) {
+ return function(stream, state) {
+ var escaped = false, ch;
+ while ((ch = stream.next()) != null) {
+ if (ch == quote && !escaped)
+ break;
+ escaped = !escaped && ch == "\\";
+ }
+ if (!escaped) state.tokenize = tokenBase;
+ return "string";
+ };
+ }
+
+ return {
+ startState: function(base) {
+ return {tokenize: tokenBase,
+ baseIndent: base || 0,
+ _indent: []};
+ },
+
+ token: function(stream, state) {
+ if (stream.eatSpace())
+ return null;
+
+ return (state.tokenize || tokenBase)(stream, state);
+ },
+
+ indent: function(state, _textAfter) {
+ var length = state._indent.length;
+ if (_textAfter && (_textAfter[0] == "}"))
+ length--;
+
+ if (length <0)
+ length = 0;
+
+ return length * indentUnit;
+ },
+
+ electricChars: "}"
+ };
+});
+
+CodeMirror.defineMIME("application/sieve", "sieve");
+
+});
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/slim/slim.js b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/slim/slim.js
new file mode 100644
index 0000000000..b8ccb1381f
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/slim/slim.js
@@ -0,0 +1,575 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: https://codemirror.net/LICENSE
+
+// Slim Highlighting for CodeMirror copyright (c) HicknHack Software Gmbh
+
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
+ mod(require("../../lib/codemirror"), require("../htmlmixed/htmlmixed"), require("../ruby/ruby"));
+ else if (typeof define == "function" && define.amd) // AMD
+ define(["../../lib/codemirror", "../htmlmixed/htmlmixed", "../ruby/ruby"], mod);
+ else // Plain browser env
+ mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+ CodeMirror.defineMode("slim", function(config) {
+ var htmlMode = CodeMirror.getMode(config, {name: "htmlmixed"});
+ var rubyMode = CodeMirror.getMode(config, "ruby");
+ var modes = { html: htmlMode, ruby: rubyMode };
+ var embedded = {
+ ruby: "ruby",
+ javascript: "javascript",
+ css: "text/css",
+ sass: "text/x-sass",
+ scss: "text/x-scss",
+ less: "text/x-less",
+ styl: "text/x-styl", // no highlighting so far
+ coffee: "coffeescript",
+ asciidoc: "text/x-asciidoc",
+ markdown: "text/x-markdown",
+ textile: "text/x-textile", // no highlighting so far
+ creole: "text/x-creole", // no highlighting so far
+ wiki: "text/x-wiki", // no highlighting so far
+ mediawiki: "text/x-mediawiki", // no highlighting so far
+ rdoc: "text/x-rdoc", // no highlighting so far
+ builder: "text/x-builder", // no highlighting so far
+ nokogiri: "text/x-nokogiri", // no highlighting so far
+ erb: "application/x-erb"
+ };
+ var embeddedRegexp = function(map){
+ var arr = [];
+ for(var key in map) arr.push(key);
+ return new RegExp("^("+arr.join('|')+"):");
+ }(embedded);
+
+ var styleMap = {
+ "commentLine": "comment",
+ "slimSwitch": "operator special",
+ "slimTag": "tag",
+ "slimId": "attribute def",
+ "slimClass": "attribute qualifier",
+ "slimAttribute": "attribute",
+ "slimSubmode": "keyword special",
+ "closeAttributeTag": null,
+ "slimDoctype": null,
+ "lineContinuation": null
+ };
+ var closing = {
+ "{": "}",
+ "[": "]",
+ "(": ")"
+ };
+
+ var nameStartChar = "_a-zA-Z\xC0-\xD6\xD8-\xF6\xF8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD";
+ var nameChar = nameStartChar + "\\-0-9\xB7\u0300-\u036F\u203F-\u2040";
+ var nameRegexp = new RegExp("^[:"+nameStartChar+"](?::["+nameChar+"]|["+nameChar+"]*)");
+ var attributeNameRegexp = new RegExp("^[:"+nameStartChar+"][:\\."+nameChar+"]*(?=\\s*=)");
+ var wrappedAttributeNameRegexp = new RegExp("^[:"+nameStartChar+"][:\\."+nameChar+"]*");
+ var classNameRegexp = /^\.-?[_a-zA-Z]+[\w\-]*/;
+ var classIdRegexp = /^#[_a-zA-Z]+[\w\-]*/;
+
+ function backup(pos, tokenize, style) {
+ var restore = function(stream, state) {
+ state.tokenize = tokenize;
+ if (stream.pos < pos) {
+ stream.pos = pos;
+ return style;
+ }
+ return state.tokenize(stream, state);
+ };
+ return function(stream, state) {
+ state.tokenize = restore;
+ return tokenize(stream, state);
+ };
+ }
+
+ function maybeBackup(stream, state, pat, offset, style) {
+ var cur = stream.current();
+ var idx = cur.search(pat);
+ if (idx > -1) {
+ state.tokenize = backup(stream.pos, state.tokenize, style);
+ stream.backUp(cur.length - idx - offset);
+ }
+ return style;
+ }
+
+ function continueLine(state, column) {
+ state.stack = {
+ parent: state.stack,
+ style: "continuation",
+ indented: column,
+ tokenize: state.line
+ };
+ state.line = state.tokenize;
+ }
+ function finishContinue(state) {
+ if (state.line == state.tokenize) {
+ state.line = state.stack.tokenize;
+ state.stack = state.stack.parent;
+ }
+ }
+
+ function lineContinuable(column, tokenize) {
+ return function(stream, state) {
+ finishContinue(state);
+ if (stream.match(/^\\$/)) {
+ continueLine(state, column);
+ return "lineContinuation";
+ }
+ var style = tokenize(stream, state);
+ if (stream.eol() && stream.current().match(/(?:^|[^\\])(?:\\\\)*\\$/)) {
+ stream.backUp(1);
+ }
+ return style;
+ };
+ }
+ function commaContinuable(column, tokenize) {
+ return function(stream, state) {
+ finishContinue(state);
+ var style = tokenize(stream, state);
+ if (stream.eol() && stream.current().match(/,$/)) {
+ continueLine(state, column);
+ }
+ return style;
+ };
+ }
+
+ function rubyInQuote(endQuote, tokenize) {
+ // TODO: add multi line support
+ return function(stream, state) {
+ var ch = stream.peek();
+ if (ch == endQuote && state.rubyState.tokenize.length == 1) {
+ // step out of ruby context as it seems to complete processing all the braces
+ stream.next();
+ state.tokenize = tokenize;
+ return "closeAttributeTag";
+ } else {
+ return ruby(stream, state);
+ }
+ };
+ }
+ function startRubySplat(tokenize) {
+ var rubyState;
+ var runSplat = function(stream, state) {
+ if (state.rubyState.tokenize.length == 1 && !state.rubyState.context.prev) {
+ stream.backUp(1);
+ if (stream.eatSpace()) {
+ state.rubyState = rubyState;
+ state.tokenize = tokenize;
+ return tokenize(stream, state);
+ }
+ stream.next();
+ }
+ return ruby(stream, state);
+ };
+ return function(stream, state) {
+ rubyState = state.rubyState;
+ state.rubyState = CodeMirror.startState(rubyMode);
+ state.tokenize = runSplat;
+ return ruby(stream, state);
+ };
+ }
+
+ function ruby(stream, state) {
+ return rubyMode.token(stream, state.rubyState);
+ }
+
+ function htmlLine(stream, state) {
+ if (stream.match(/^\\$/)) {
+ return "lineContinuation";
+ }
+ return html(stream, state);
+ }
+ function html(stream, state) {
+ if (stream.match(/^#\{/)) {
+ state.tokenize = rubyInQuote("}", state.tokenize);
+ return null;
+ }
+ return maybeBackup(stream, state, /[^\\]#\{/, 1, htmlMode.token(stream, state.htmlState));
+ }
+
+ function startHtmlLine(lastTokenize) {
+ return function(stream, state) {
+ var style = htmlLine(stream, state);
+ if (stream.eol()) state.tokenize = lastTokenize;
+ return style;
+ };
+ }
+
+ function startHtmlMode(stream, state, offset) {
+ state.stack = {
+ parent: state.stack,
+ style: "html",
+ indented: stream.column() + offset, // pipe + space
+ tokenize: state.line
+ };
+ state.line = state.tokenize = html;
+ return null;
+ }
+
+ function comment(stream, state) {
+ stream.skipToEnd();
+ return state.stack.style;
+ }
+
+ function commentMode(stream, state) {
+ state.stack = {
+ parent: state.stack,
+ style: "comment",
+ indented: state.indented + 1,
+ tokenize: state.line
+ };
+ state.line = comment;
+ return comment(stream, state);
+ }
+
+ function attributeWrapper(stream, state) {
+ if (stream.eat(state.stack.endQuote)) {
+ state.line = state.stack.line;
+ state.tokenize = state.stack.tokenize;
+ state.stack = state.stack.parent;
+ return null;
+ }
+ if (stream.match(wrappedAttributeNameRegexp)) {
+ state.tokenize = attributeWrapperAssign;
+ return "slimAttribute";
+ }
+ stream.next();
+ return null;
+ }
+ function attributeWrapperAssign(stream, state) {
+ if (stream.match(/^==?/)) {
+ state.tokenize = attributeWrapperValue;
+ return null;
+ }
+ return attributeWrapper(stream, state);
+ }
+ function attributeWrapperValue(stream, state) {
+ var ch = stream.peek();
+ if (ch == '"' || ch == "\'") {
+ state.tokenize = readQuoted(ch, "string", true, false, attributeWrapper);
+ stream.next();
+ return state.tokenize(stream, state);
+ }
+ if (ch == '[') {
+ return startRubySplat(attributeWrapper)(stream, state);
+ }
+ if (stream.match(/^(true|false|nil)\b/)) {
+ state.tokenize = attributeWrapper;
+ return "keyword";
+ }
+ return startRubySplat(attributeWrapper)(stream, state);
+ }
+
+ function startAttributeWrapperMode(state, endQuote, tokenize) {
+ state.stack = {
+ parent: state.stack,
+ style: "wrapper",
+ indented: state.indented + 1,
+ tokenize: tokenize,
+ line: state.line,
+ endQuote: endQuote
+ };
+ state.line = state.tokenize = attributeWrapper;
+ return null;
+ }
+
+ function sub(stream, state) {
+ if (stream.match(/^#\{/)) {
+ state.tokenize = rubyInQuote("}", state.tokenize);
+ return null;
+ }
+ var subStream = new CodeMirror.StringStream(stream.string.slice(state.stack.indented), stream.tabSize);
+ subStream.pos = stream.pos - state.stack.indented;
+ subStream.start = stream.start - state.stack.indented;
+ subStream.lastColumnPos = stream.lastColumnPos - state.stack.indented;
+ subStream.lastColumnValue = stream.lastColumnValue - state.stack.indented;
+ var style = state.subMode.token(subStream, state.subState);
+ stream.pos = subStream.pos + state.stack.indented;
+ return style;
+ }
+ function firstSub(stream, state) {
+ state.stack.indented = stream.column();
+ state.line = state.tokenize = sub;
+ return state.tokenize(stream, state);
+ }
+
+ function createMode(mode) {
+ var query = embedded[mode];
+ var spec = CodeMirror.mimeModes[query];
+ if (spec) {
+ return CodeMirror.getMode(config, spec);
+ }
+ var factory = CodeMirror.modes[query];
+ if (factory) {
+ return factory(config, {name: query});
+ }
+ return CodeMirror.getMode(config, "null");
+ }
+
+ function getMode(mode) {
+ if (!modes.hasOwnProperty(mode)) {
+ return modes[mode] = createMode(mode);
+ }
+ return modes[mode];
+ }
+
+ function startSubMode(mode, state) {
+ var subMode = getMode(mode);
+ var subState = CodeMirror.startState(subMode);
+
+ state.subMode = subMode;
+ state.subState = subState;
+
+ state.stack = {
+ parent: state.stack,
+ style: "sub",
+ indented: state.indented + 1,
+ tokenize: state.line
+ };
+ state.line = state.tokenize = firstSub;
+ return "slimSubmode";
+ }
+
+ function doctypeLine(stream, _state) {
+ stream.skipToEnd();
+ return "slimDoctype";
+ }
+
+ function startLine(stream, state) {
+ var ch = stream.peek();
+ if (ch == '<') {
+ return (state.tokenize = startHtmlLine(state.tokenize))(stream, state);
+ }
+ if (stream.match(/^[|']/)) {
+ return startHtmlMode(stream, state, 1);
+ }
+ if (stream.match(/^\/(!|\[\w+])?/)) {
+ return commentMode(stream, state);
+ }
+ if (stream.match(/^(-|==?[<>]?)/)) {
+ state.tokenize = lineContinuable(stream.column(), commaContinuable(stream.column(), ruby));
+ return "slimSwitch";
+ }
+ if (stream.match(/^doctype\b/)) {
+ state.tokenize = doctypeLine;
+ return "keyword";
+ }
+
+ var m = stream.match(embeddedRegexp);
+ if (m) {
+ return startSubMode(m[1], state);
+ }
+
+ return slimTag(stream, state);
+ }
+
+ function slim(stream, state) {
+ if (state.startOfLine) {
+ return startLine(stream, state);
+ }
+ return slimTag(stream, state);
+ }
+
+ function slimTag(stream, state) {
+ if (stream.eat('*')) {
+ state.tokenize = startRubySplat(slimTagExtras);
+ return null;
+ }
+ if (stream.match(nameRegexp)) {
+ state.tokenize = slimTagExtras;
+ return "slimTag";
+ }
+ return slimClass(stream, state);
+ }
+ function slimTagExtras(stream, state) {
+ if (stream.match(/^(<>?|>)/)) {
+ state.tokenize = slimClass;
+ return null;
+ }
+ return slimClass(stream, state);
+ }
+ function slimClass(stream, state) {
+ if (stream.match(classIdRegexp)) {
+ state.tokenize = slimClass;
+ return "slimId";
+ }
+ if (stream.match(classNameRegexp)) {
+ state.tokenize = slimClass;
+ return "slimClass";
+ }
+ return slimAttribute(stream, state);
+ }
+ function slimAttribute(stream, state) {
+ if (stream.match(/^([\[\{\(])/)) {
+ return startAttributeWrapperMode(state, closing[RegExp.$1], slimAttribute);
+ }
+ if (stream.match(attributeNameRegexp)) {
+ state.tokenize = slimAttributeAssign;
+ return "slimAttribute";
+ }
+ if (stream.peek() == '*') {
+ stream.next();
+ state.tokenize = startRubySplat(slimContent);
+ return null;
+ }
+ return slimContent(stream, state);
+ }
+ function slimAttributeAssign(stream, state) {
+ if (stream.match(/^==?/)) {
+ state.tokenize = slimAttributeValue;
+ return null;
+ }
+ // should never happen, because of forward lookup
+ return slimAttribute(stream, state);
+ }
+
+ function slimAttributeValue(stream, state) {
+ var ch = stream.peek();
+ if (ch == '"' || ch == "\'") {
+ state.tokenize = readQuoted(ch, "string", true, false, slimAttribute);
+ stream.next();
+ return state.tokenize(stream, state);
+ }
+ if (ch == '[') {
+ return startRubySplat(slimAttribute)(stream, state);
+ }
+ if (ch == ':') {
+ return startRubySplat(slimAttributeSymbols)(stream, state);
+ }
+ if (stream.match(/^(true|false|nil)\b/)) {
+ state.tokenize = slimAttribute;
+ return "keyword";
+ }
+ return startRubySplat(slimAttribute)(stream, state);
+ }
+ function slimAttributeSymbols(stream, state) {
+ stream.backUp(1);
+ if (stream.match(/^[^\s],(?=:)/)) {
+ state.tokenize = startRubySplat(slimAttributeSymbols);
+ return null;
+ }
+ stream.next();
+ return slimAttribute(stream, state);
+ }
+ function readQuoted(quote, style, embed, unescaped, nextTokenize) {
+ return function(stream, state) {
+ finishContinue(state);
+ var fresh = stream.current().length == 0;
+ if (stream.match(/^\\$/, fresh)) {
+ if (!fresh) return style;
+ continueLine(state, state.indented);
+ return "lineContinuation";
+ }
+ if (stream.match(/^#\{/, fresh)) {
+ if (!fresh) return style;
+ state.tokenize = rubyInQuote("}", state.tokenize);
+ return null;
+ }
+ var escaped = false, ch;
+ while ((ch = stream.next()) != null) {
+ if (ch == quote && (unescaped || !escaped)) {
+ state.tokenize = nextTokenize;
+ break;
+ }
+ if (embed && ch == "#" && !escaped) {
+ if (stream.eat("{")) {
+ stream.backUp(2);
+ break;
+ }
+ }
+ escaped = !escaped && ch == "\\";
+ }
+ if (stream.eol() && escaped) {
+ stream.backUp(1);
+ }
+ return style;
+ };
+ }
+ function slimContent(stream, state) {
+ if (stream.match(/^==?/)) {
+ state.tokenize = ruby;
+ return "slimSwitch";
+ }
+ if (stream.match(/^\/$/)) { // tag close hint
+ state.tokenize = slim;
+ return null;
+ }
+ if (stream.match(/^:/)) { // inline tag
+ state.tokenize = slimTag;
+ return "slimSwitch";
+ }
+ startHtmlMode(stream, state, 0);
+ return state.tokenize(stream, state);
+ }
+
+ var mode = {
+ // default to html mode
+ startState: function() {
+ var htmlState = CodeMirror.startState(htmlMode);
+ var rubyState = CodeMirror.startState(rubyMode);
+ return {
+ htmlState: htmlState,
+ rubyState: rubyState,
+ stack: null,
+ last: null,
+ tokenize: slim,
+ line: slim,
+ indented: 0
+ };
+ },
+
+ copyState: function(state) {
+ return {
+ htmlState : CodeMirror.copyState(htmlMode, state.htmlState),
+ rubyState: CodeMirror.copyState(rubyMode, state.rubyState),
+ subMode: state.subMode,
+ subState: state.subMode && CodeMirror.copyState(state.subMode, state.subState),
+ stack: state.stack,
+ last: state.last,
+ tokenize: state.tokenize,
+ line: state.line
+ };
+ },
+
+ token: function(stream, state) {
+ if (stream.sol()) {
+ state.indented = stream.indentation();
+ state.startOfLine = true;
+ state.tokenize = state.line;
+ while (state.stack && state.stack.indented > state.indented && state.last != "slimSubmode") {
+ state.line = state.tokenize = state.stack.tokenize;
+ state.stack = state.stack.parent;
+ state.subMode = null;
+ state.subState = null;
+ }
+ }
+ if (stream.eatSpace()) return null;
+ var style = state.tokenize(stream, state);
+ state.startOfLine = false;
+ if (style) state.last = style;
+ return styleMap.hasOwnProperty(style) ? styleMap[style] : style;
+ },
+
+ blankLine: function(state) {
+ if (state.subMode && state.subMode.blankLine) {
+ return state.subMode.blankLine(state.subState);
+ }
+ },
+
+ innerMode: function(state) {
+ if (state.subMode) return {state: state.subState, mode: state.subMode};
+ return {state: state, mode: mode};
+ }
+
+ //indent: function(state) {
+ // return state.indented;
+ //}
+ };
+ return mode;
+ }, "htmlmixed", "ruby");
+
+ CodeMirror.defineMIME("text/x-slim", "slim");
+ CodeMirror.defineMIME("application/x-slim", "slim");
+});
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/smalltalk/smalltalk.js b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/smalltalk/smalltalk.js
new file mode 100644
index 0000000000..5039fe2d15
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/smalltalk/smalltalk.js
@@ -0,0 +1,168 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: https://codemirror.net/LICENSE
+
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
+ mod(require("../../lib/codemirror"));
+ else if (typeof define == "function" && define.amd) // AMD
+ define(["../../lib/codemirror"], mod);
+ else // Plain browser env
+ mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode('smalltalk', function(config) {
+
+ var specialChars = /[+\-\/\\*~<>=@%|&?!.,:;^]/;
+ var keywords = /true|false|nil|self|super|thisContext/;
+
+ var Context = function(tokenizer, parent) {
+ this.next = tokenizer;
+ this.parent = parent;
+ };
+
+ var Token = function(name, context, eos) {
+ this.name = name;
+ this.context = context;
+ this.eos = eos;
+ };
+
+ var State = function() {
+ this.context = new Context(next, null);
+ this.expectVariable = true;
+ this.indentation = 0;
+ this.userIndentationDelta = 0;
+ };
+
+ State.prototype.userIndent = function(indentation) {
+ this.userIndentationDelta = indentation > 0 ? (indentation / config.indentUnit - this.indentation) : 0;
+ };
+
+ var next = function(stream, context, state) {
+ var token = new Token(null, context, false);
+ var aChar = stream.next();
+
+ if (aChar === '"') {
+ token = nextComment(stream, new Context(nextComment, context));
+
+ } else if (aChar === '\'') {
+ token = nextString(stream, new Context(nextString, context));
+
+ } else if (aChar === '#') {
+ if (stream.peek() === '\'') {
+ stream.next();
+ token = nextSymbol(stream, new Context(nextSymbol, context));
+ } else {
+ if (stream.eatWhile(/[^\s.{}\[\]()]/))
+ token.name = 'string-2';
+ else
+ token.name = 'meta';
+ }
+
+ } else if (aChar === '$') {
+ if (stream.next() === '<') {
+ stream.eatWhile(/[^\s>]/);
+ stream.next();
+ }
+ token.name = 'string-2';
+
+ } else if (aChar === '|' && state.expectVariable) {
+ token.context = new Context(nextTemporaries, context);
+
+ } else if (/[\[\]{}()]/.test(aChar)) {
+ token.name = 'bracket';
+ token.eos = /[\[{(]/.test(aChar);
+
+ if (aChar === '[') {
+ state.indentation++;
+ } else if (aChar === ']') {
+ state.indentation = Math.max(0, state.indentation - 1);
+ }
+
+ } else if (specialChars.test(aChar)) {
+ stream.eatWhile(specialChars);
+ token.name = 'operator';
+ token.eos = aChar !== ';'; // ; cascaded message expression
+
+ } else if (/\d/.test(aChar)) {
+ stream.eatWhile(/[\w\d]/);
+ token.name = 'number';
+
+ } else if (/[\w_]/.test(aChar)) {
+ stream.eatWhile(/[\w\d_]/);
+ token.name = state.expectVariable ? (keywords.test(stream.current()) ? 'keyword' : 'variable') : null;
+
+ } else {
+ token.eos = state.expectVariable;
+ }
+
+ return token;
+ };
+
+ var nextComment = function(stream, context) {
+ stream.eatWhile(/[^"]/);
+ return new Token('comment', stream.eat('"') ? context.parent : context, true);
+ };
+
+ var nextString = function(stream, context) {
+ stream.eatWhile(/[^']/);
+ return new Token('string', stream.eat('\'') ? context.parent : context, false);
+ };
+
+ var nextSymbol = function(stream, context) {
+ stream.eatWhile(/[^']/);
+ return new Token('string-2', stream.eat('\'') ? context.parent : context, false);
+ };
+
+ var nextTemporaries = function(stream, context) {
+ var token = new Token(null, context, false);
+ var aChar = stream.next();
+
+ if (aChar === '|') {
+ token.context = context.parent;
+ token.eos = true;
+
+ } else {
+ stream.eatWhile(/[^|]/);
+ token.name = 'variable';
+ }
+
+ return token;
+ };
+
+ return {
+ startState: function() {
+ return new State;
+ },
+
+ token: function(stream, state) {
+ state.userIndent(stream.indentation());
+
+ if (stream.eatSpace()) {
+ return null;
+ }
+
+ var token = state.context.next(stream, state.context, state);
+ state.context = token.context;
+ state.expectVariable = token.eos;
+
+ return token.name;
+ },
+
+ blankLine: function(state) {
+ state.userIndent(0);
+ },
+
+ indent: function(state, textAfter) {
+ var i = state.context.next === next && textAfter && textAfter.charAt(0) === ']' ? -1 : state.userIndentationDelta;
+ return (state.indentation + i) * config.indentUnit;
+ },
+
+ electricChars: ']'
+ };
+
+});
+
+CodeMirror.defineMIME('text/x-stsrc', {name: 'smalltalk'});
+
+});
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/smarty/smarty.js b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/smarty/smarty.js
new file mode 100644
index 0000000000..57852feb0e
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/smarty/smarty.js
@@ -0,0 +1,225 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: https://codemirror.net/LICENSE
+
+/**
+ * Smarty 2 and 3 mode.
+ */
+
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
+ mod(require("../../lib/codemirror"));
+ else if (typeof define == "function" && define.amd) // AMD
+ define(["../../lib/codemirror"], mod);
+ else // Plain browser env
+ mod(CodeMirror);
+})(function(CodeMirror) {
+ "use strict";
+
+ CodeMirror.defineMode("smarty", function(config, parserConf) {
+ var rightDelimiter = parserConf.rightDelimiter || "}";
+ var leftDelimiter = parserConf.leftDelimiter || "{";
+ var version = parserConf.version || 2;
+ var baseMode = CodeMirror.getMode(config, parserConf.baseMode || "null");
+
+ var keyFunctions = ["debug", "extends", "function", "include", "literal"];
+ var regs = {
+ operatorChars: /[+\-*&%=<>!?]/,
+ validIdentifier: /[a-zA-Z0-9_]/,
+ stringChar: /['"]/
+ };
+
+ var last;
+ function cont(style, lastType) {
+ last = lastType;
+ return style;
+ }
+
+ function chain(stream, state, parser) {
+ state.tokenize = parser;
+ return parser(stream, state);
+ }
+
+ // Smarty 3 allows { and } surrounded by whitespace to NOT slip into Smarty mode
+ function doesNotCount(stream, pos) {
+ if (pos == null) pos = stream.pos;
+ return version === 3 && leftDelimiter == "{" &&
+ (pos == stream.string.length || /\s/.test(stream.string.charAt(pos)));
+ }
+
+ function tokenTop(stream, state) {
+ var string = stream.string;
+ for (var scan = stream.pos;;) {
+ var nextMatch = string.indexOf(leftDelimiter, scan);
+ scan = nextMatch + leftDelimiter.length;
+ if (nextMatch == -1 || !doesNotCount(stream, nextMatch + leftDelimiter.length)) break;
+ }
+ if (nextMatch == stream.pos) {
+ stream.match(leftDelimiter);
+ if (stream.eat("*")) {
+ return chain(stream, state, tokenBlock("comment", "*" + rightDelimiter));
+ } else {
+ state.depth++;
+ state.tokenize = tokenSmarty;
+ last = "startTag";
+ return "tag";
+ }
+ }
+
+ if (nextMatch > -1) stream.string = string.slice(0, nextMatch);
+ var token = baseMode.token(stream, state.base);
+ if (nextMatch > -1) stream.string = string;
+ return token;
+ }
+
+ // parsing Smarty content
+ function tokenSmarty(stream, state) {
+ if (stream.match(rightDelimiter, true)) {
+ if (version === 3) {
+ state.depth--;
+ if (state.depth <= 0) {
+ state.tokenize = tokenTop;
+ }
+ } else {
+ state.tokenize = tokenTop;
+ }
+ return cont("tag", null);
+ }
+
+ if (stream.match(leftDelimiter, true)) {
+ state.depth++;
+ return cont("tag", "startTag");
+ }
+
+ var ch = stream.next();
+ if (ch == "$") {
+ stream.eatWhile(regs.validIdentifier);
+ return cont("variable-2", "variable");
+ } else if (ch == "|") {
+ return cont("operator", "pipe");
+ } else if (ch == ".") {
+ return cont("operator", "property");
+ } else if (regs.stringChar.test(ch)) {
+ state.tokenize = tokenAttribute(ch);
+ return cont("string", "string");
+ } else if (regs.operatorChars.test(ch)) {
+ stream.eatWhile(regs.operatorChars);
+ return cont("operator", "operator");
+ } else if (ch == "[" || ch == "]") {
+ return cont("bracket", "bracket");
+ } else if (ch == "(" || ch == ")") {
+ return cont("bracket", "operator");
+ } else if (/\d/.test(ch)) {
+ stream.eatWhile(/\d/);
+ return cont("number", "number");
+ } else {
+
+ if (state.last == "variable") {
+ if (ch == "@") {
+ stream.eatWhile(regs.validIdentifier);
+ return cont("property", "property");
+ } else if (ch == "|") {
+ stream.eatWhile(regs.validIdentifier);
+ return cont("qualifier", "modifier");
+ }
+ } else if (state.last == "pipe") {
+ stream.eatWhile(regs.validIdentifier);
+ return cont("qualifier", "modifier");
+ } else if (state.last == "whitespace") {
+ stream.eatWhile(regs.validIdentifier);
+ return cont("attribute", "modifier");
+ } if (state.last == "property") {
+ stream.eatWhile(regs.validIdentifier);
+ return cont("property", null);
+ } else if (/\s/.test(ch)) {
+ last = "whitespace";
+ return null;
+ }
+
+ var str = "";
+ if (ch != "/") {
+ str += ch;
+ }
+ var c = null;
+ while (c = stream.eat(regs.validIdentifier)) {
+ str += c;
+ }
+ for (var i=0, j=keyFunctions.length; i]=?)/)) {
+ // Tokenize filter, binary, null propagator, and equality operators.
+ return "operator";
+ } else if (match = stream.match(/^\$([\w]+)/)) {
+ return ref(state.variables, match[1], !state.lookupVariables);
+ } else if (match = stream.match(/^\w+/)) {
+ return /^(?:as|and|or|not|in|if)$/.test(match[0]) ? "keyword" : null;
+ }
+
+ stream.next();
+ return null;
+ }
+
+ return {
+ startState: function() {
+ return {
+ soyState: [],
+ variables: prepend(null, 'ij'),
+ scopes: null,
+ indent: 0,
+ quoteKind: null,
+ context: null,
+ lookupVariables: true, // Is unknown variables considered an error
+ localStates: [{
+ mode: modes.html,
+ state: CodeMirror.startState(modes.html)
+ }]
+ };
+ },
+
+ copyState: function(state) {
+ return {
+ tag: state.tag, // Last seen Soy tag.
+ soyState: state.soyState.concat([]),
+ variables: state.variables,
+ context: state.context,
+ indent: state.indent, // Indentation of the following line.
+ quoteKind: state.quoteKind,
+ lookupVariables: state.lookupVariables,
+ localStates: state.localStates.map(function(localState) {
+ return {
+ mode: localState.mode,
+ state: CodeMirror.copyState(localState.mode, localState.state)
+ };
+ })
+ };
+ },
+
+ token: function(stream, state) {
+ var match;
+
+ switch (last(state.soyState)) {
+ case "comment":
+ if (stream.match(/^.*?\*\//)) {
+ state.soyState.pop();
+ } else {
+ stream.skipToEnd();
+ }
+ if (!state.context || !state.context.scope) {
+ var paramRe = /@param\??\s+(\S+)/g;
+ var current = stream.current();
+ for (var match; (match = paramRe.exec(current)); ) {
+ state.variables = prepend(state.variables, match[1]);
+ }
+ }
+ return "comment";
+
+ case "string":
+ var match = stream.match(/^.*?(["']|\\[\s\S])/);
+ if (!match) {
+ stream.skipToEnd();
+ } else if (match[1] == state.quoteKind) {
+ state.quoteKind = null;
+ state.soyState.pop();
+ }
+ return "string";
+ }
+
+ if (!state.soyState.length || last(state.soyState) != "literal") {
+ if (stream.match(/^\/\*/)) {
+ state.soyState.push("comment");
+ return "comment";
+ } else if (stream.match(stream.sol() ? /^\s*\/\/.*/ : /^\s+\/\/.*/)) {
+ return "comment";
+ }
+ }
+
+ switch (last(state.soyState)) {
+ case "templ-def":
+ if (match = stream.match(/^\.?([\w]+(?!\.[\w]+)*)/)) {
+ state.soyState.pop();
+ return "def";
+ }
+ stream.next();
+ return null;
+
+ case "templ-ref":
+ if (match = stream.match(/(\.?[a-zA-Z_][a-zA-Z_0-9]+)+/)) {
+ state.soyState.pop();
+ // If the first character is '.', it can only be a local template.
+ if (match[0][0] == '.') {
+ return "variable-2"
+ }
+ // Otherwise
+ return "variable";
+ }
+ if (match = stream.match(/^\$([\w]+)/)) {
+ state.soyState.pop();
+ return ref(state.variables, match[1], !state.lookupVariables);
+ }
+
+ stream.next();
+ return null;
+
+ case "namespace-def":
+ if (match = stream.match(/^\.?([\w\.]+)/)) {
+ state.soyState.pop();
+ return "variable";
+ }
+ stream.next();
+ return null;
+
+ case "param-def":
+ if (match = stream.match(/^\*/)) {
+ state.soyState.pop();
+ state.soyState.push("param-type");
+ return "type";
+ }
+ if (match = stream.match(/^\w+/)) {
+ state.variables = prepend(state.variables, match[0]);
+ state.soyState.pop();
+ state.soyState.push("param-type");
+ return "def";
+ }
+ stream.next();
+ return null;
+
+ case "param-ref":
+ if (match = stream.match(/^\w+/)) {
+ state.soyState.pop();
+ return "property";
+ }
+ stream.next();
+ return null;
+
+ case "open-parentheses":
+ if (stream.match(/[)]/)) {
+ state.soyState.pop();
+ return null;
+ }
+ return expression(stream, state);
+
+ case "param-type":
+ var peekChar = stream.peek();
+ if ("}]=>,".indexOf(peekChar) != -1) {
+ state.soyState.pop();
+ return null;
+ } else if (peekChar == "[") {
+ state.soyState.push('param-type-record');
+ return null;
+ } else if (peekChar == "(") {
+ state.soyState.push('param-type-template');
+ return null;
+ } else if (peekChar == "<") {
+ state.soyState.push('param-type-parameter');
+ return null;
+ } else if (match = stream.match(/^([\w]+|[?])/)) {
+ return "type";
+ }
+ stream.next();
+ return null;
+
+ case "param-type-record":
+ var peekChar = stream.peek();
+ if (peekChar == "]") {
+ state.soyState.pop();
+ return null;
+ }
+ if (stream.match(/^\w+/)) {
+ state.soyState.push('param-type');
+ return "property";
+ }
+ stream.next();
+ return null;
+
+ case "param-type-parameter":
+ if (stream.match(/^[>]/)) {
+ state.soyState.pop();
+ return null;
+ }
+ if (stream.match(/^[<,]/)) {
+ state.soyState.push('param-type');
+ return null;
+ }
+ stream.next();
+ return null;
+
+ case "param-type-template":
+ if (stream.match(/[>]/)) {
+ state.soyState.pop();
+ state.soyState.push('param-type');
+ return null;
+ }
+ if (stream.match(/^\w+/)) {
+ state.soyState.push('param-type');
+ return "def";
+ }
+ stream.next();
+ return null;
+
+ case "var-def":
+ if (match = stream.match(/^\$([\w]+)/)) {
+ state.variables = prepend(state.variables, match[1]);
+ state.soyState.pop();
+ return "def";
+ }
+ stream.next();
+ return null;
+
+ case "for-loop":
+ if (stream.match(/\bin\b/)) {
+ state.soyState.pop();
+ return "keyword";
+ }
+ if (stream.peek() == "$") {
+ state.soyState.push('var-def');
+ return null;
+ }
+ stream.next();
+ return null;
+
+ case "record-literal":
+ if (stream.match(/^[)]/)) {
+ state.soyState.pop();
+ return null;
+ }
+ if (stream.match(/[(,]/)) {
+ state.soyState.push("map-value")
+ state.soyState.push("record-key")
+ return null;
+ }
+ stream.next()
+ return null;
+
+ case "map-literal":
+ if (stream.match(/^[)]/)) {
+ state.soyState.pop();
+ return null;
+ }
+ if (stream.match(/[(,]/)) {
+ state.soyState.push("map-value")
+ state.soyState.push("map-value")
+ return null;
+ }
+ stream.next()
+ return null;
+
+ case "list-literal":
+ if (stream.match(']')) {
+ state.soyState.pop();
+ state.lookupVariables = true;
+ popcontext(state);
+ return null;
+ }
+ if (stream.match(/\bfor\b/)) {
+ state.lookupVariables = true;
+ state.soyState.push('for-loop');
+ return "keyword";
+ }
+ return expression(stream, state);
+
+ case "record-key":
+ if (stream.match(/[\w]+/)) {
+ return "property";
+ }
+ if (stream.match(/^[:]/)) {
+ state.soyState.pop();
+ return null;
+ }
+ stream.next();
+ return null;
+
+ case "map-value":
+ if (stream.peek() == ")" || stream.peek() == "," || stream.match(/^[:)]/)) {
+ state.soyState.pop();
+ return null;
+ }
+ return expression(stream, state);
+
+ case "import":
+ if (stream.eat(";")) {
+ state.soyState.pop();
+ state.indent -= 2 * config.indentUnit;
+ return null;
+ }
+ if (stream.match(/\w+(?=\s+as\b)/)) {
+ return "variable";
+ }
+ if (match = stream.match(/\w+/)) {
+ return /\b(from|as)\b/.test(match[0]) ? "keyword" : "def";
+ }
+ if (match = stream.match(/^["']/)) {
+ state.soyState.push("string");
+ state.quoteKind = match[0];
+ return "string";
+ }
+ stream.next();
+ return null;
+
+ case "tag":
+ var endTag;
+ var tagName;
+ if (state.tag === undefined) {
+ endTag = true;
+ tagName = '';
+ } else {
+ endTag = state.tag[0] == "/";
+ tagName = endTag ? state.tag.substring(1) : state.tag;
+ }
+ var tag = tags[tagName];
+ if (stream.match(/^\/?}/)) {
+ var selfClosed = stream.current() == "/}";
+ if (selfClosed && !endTag) {
+ popcontext(state);
+ }
+ if (state.tag == "/template" || state.tag == "/deltemplate") {
+ state.variables = prepend(null, 'ij');
+ state.indent = 0;
+ } else {
+ state.indent -= config.indentUnit *
+ (selfClosed || indentingTags.indexOf(state.tag) == -1 ? 2 : 1);
+ }
+ state.soyState.pop();
+ return "keyword";
+ } else if (stream.match(/^([\w?]+)(?==)/)) {
+ if (state.context && state.context.tag == tagName && stream.current() == "kind" && (match = stream.match(/^="([^"]+)/, false))) {
+ var kind = match[1];
+ state.context.kind = kind;
+ var mode = modes[kind] || modes.html;
+ var localState = last(state.localStates);
+ if (localState.mode.indent) {
+ state.indent += localState.mode.indent(localState.state, "", "");
+ }
+ state.localStates.push({
+ mode: mode,
+ state: CodeMirror.startState(mode)
+ });
+ }
+ return "attribute";
+ }
+ return expression(stream, state);
+
+ case "template-call-expression":
+ if (stream.match(/^([\w-?]+)(?==)/)) {
+ return "attribute";
+ } else if (stream.eat('>')) {
+ state.soyState.pop();
+ return "keyword";
+ } else if (stream.eat('/>')) {
+ state.soyState.pop();
+ return "keyword";
+ }
+ return expression(stream, state);
+ case "literal":
+ if (stream.match('{/literal}', false)) {
+ state.soyState.pop();
+ return this.token(stream, state);
+ }
+ return tokenUntil(stream, state, /\{\/literal}/);
+ case "export":
+ if (match = stream.match(/\w+/)) {
+ state.soyState.pop();
+ if (match == "const") {
+ state.soyState.push("const-def")
+ return "keyword";
+ } else if (match == "extern") {
+ state.soyState.push("param-def")
+ return "keyword";
+ }
+ } else {
+ stream.next();
+ }
+ return null;
+ case "const-def":
+ if (stream.match(/^\w+/)) {
+ state.soyState.pop();
+ return "def";
+ }
+ stream.next();
+ return null;
+ }
+
+ if (stream.match('{literal}')) {
+ state.indent += config.indentUnit;
+ state.soyState.push("literal");
+ state.context = new Context(state.context, "literal", state.variables);
+ return "keyword";
+
+ // A tag-keyword must be followed by whitespace, comment or a closing tag.
+ } else if (match = stream.match(/^\{([/@\\]?\w+\??)(?=$|[\s}]|\/[/*])/)) {
+ var prevTag = state.tag;
+ state.tag = match[1];
+ var endTag = state.tag[0] == "/";
+ var indentingTag = !!tags[state.tag];
+ var tagName = endTag ? state.tag.substring(1) : state.tag;
+ var tag = tags[tagName];
+ if (state.tag != "/switch")
+ state.indent += ((endTag || tag && tag.reduceIndent) && prevTag != "switch" ? 1 : 2) * config.indentUnit;
+
+ state.soyState.push("tag");
+ var tagError = false;
+ if (tag) {
+ if (!endTag) {
+ if (tag.soyState) state.soyState.push(tag.soyState);
+ }
+ // If a new tag, open a new context.
+ if (!tag.noEndTag && (indentingTag || !endTag)) {
+ state.context = new Context(state.context, state.tag, tag.variableScope ? state.variables : null);
+ // Otherwise close the current context.
+ } else if (endTag) {
+ var isBalancedForExtern = tagName == 'extern' && (state.context && state.context.tag == 'export');
+ if (!state.context || ((state.context.tag != tagName) && !isBalancedForExtern)) {
+ tagError = true;
+ } else if (state.context) {
+ if (state.context.kind) {
+ state.localStates.pop();
+ var localState = last(state.localStates);
+ if (localState.mode.indent) {
+ state.indent -= localState.mode.indent(localState.state, "", "");
+ }
+ }
+ popcontext(state);
+ }
+ }
+ } else if (endTag) {
+ // Assume all tags with a closing tag are defined in the config.
+ tagError = true;
+ }
+ return (tagError ? "error " : "") + "keyword";
+
+ // Not a tag-keyword; it's an implicit print tag.
+ } else if (stream.eat('{')) {
+ state.tag = "print";
+ state.indent += 2 * config.indentUnit;
+ state.soyState.push("tag");
+ return "keyword";
+ } else if (!state.context && stream.sol() && stream.match(/import\b/)) {
+ state.soyState.push("import");
+ state.indent += 2 * config.indentUnit;
+ return "keyword";
+ } else if (match = stream.match('<{')) {
+ state.soyState.push("template-call-expression");
+ state.indent += 2 * config.indentUnit;
+ state.soyState.push("tag");
+ return "keyword";
+ } else if (match = stream.match('>')) {
+ state.indent -= 1 * config.indentUnit;
+ return "keyword";
+ }
+
+ return tokenUntil(stream, state, /\{|\s+\/\/|\/\*/);
+ },
+
+ indent: function(state, textAfter, line) {
+ var indent = state.indent, top = last(state.soyState);
+ if (top == "comment") return CodeMirror.Pass;
+
+ if (top == "literal") {
+ if (/^\{\/literal}/.test(textAfter)) indent -= config.indentUnit;
+ } else {
+ if (/^\s*\{\/(template|deltemplate)\b/.test(textAfter)) return 0;
+ if (/^\{(\/|(fallbackmsg|elseif|else|ifempty)\b)/.test(textAfter)) indent -= config.indentUnit;
+ if (state.tag != "switch" && /^\{(case|default)\b/.test(textAfter)) indent -= config.indentUnit;
+ if (/^\{\/switch\b/.test(textAfter)) indent -= config.indentUnit;
+ }
+ var localState = last(state.localStates);
+ if (indent && localState.mode.indent) {
+ indent += localState.mode.indent(localState.state, textAfter, line);
+ }
+ return indent;
+ },
+
+ innerMode: function(state) {
+ if (state.soyState.length && last(state.soyState) != "literal") return null;
+ else return last(state.localStates);
+ },
+
+ electricInput: /^\s*\{(\/|\/template|\/deltemplate|\/switch|fallbackmsg|elseif|else|case|default|ifempty|\/literal\})$/,
+ lineComment: "//",
+ blockCommentStart: "/*",
+ blockCommentEnd: "*/",
+ blockCommentContinue: " * ",
+ useInnerComments: false,
+ fold: "indent"
+ };
+ }, "htmlmixed");
+
+ CodeMirror.registerHelper("wordChars", "soy", /[\w$]/);
+
+ CodeMirror.registerHelper("hintWords", "soy", Object.keys(tags).concat(
+ ["css", "debugger"]));
+
+ CodeMirror.defineMIME("text/x-soy", "soy");
+});
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/sparql/sparql.js b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/sparql/sparql.js
new file mode 100644
index 0000000000..6d1d24464b
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/sparql/sparql.js
@@ -0,0 +1,190 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: https://codemirror.net/LICENSE
+
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
+ mod(require("../../lib/codemirror"));
+ else if (typeof define == "function" && define.amd) // AMD
+ define(["../../lib/codemirror"], mod);
+ else // Plain browser env
+ mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("sparql", function(config) {
+ var indentUnit = config.indentUnit;
+ var curPunc;
+
+ function wordRegexp(words) {
+ return new RegExp("^(?:" + words.join("|") + ")$", "i");
+ }
+ var ops = wordRegexp(["str", "lang", "langmatches", "datatype", "bound", "sameterm", "isiri", "isuri",
+ "iri", "uri", "bnode", "count", "sum", "min", "max", "avg", "sample",
+ "group_concat", "rand", "abs", "ceil", "floor", "round", "concat", "substr", "strlen",
+ "replace", "ucase", "lcase", "encode_for_uri", "contains", "strstarts", "strends",
+ "strbefore", "strafter", "year", "month", "day", "hours", "minutes", "seconds",
+ "timezone", "tz", "now", "uuid", "struuid", "md5", "sha1", "sha256", "sha384",
+ "sha512", "coalesce", "if", "strlang", "strdt", "isnumeric", "regex", "exists",
+ "isblank", "isliteral", "a", "bind"]);
+ var keywords = wordRegexp(["base", "prefix", "select", "distinct", "reduced", "construct", "describe",
+ "ask", "from", "named", "where", "order", "limit", "offset", "filter", "optional",
+ "graph", "by", "asc", "desc", "as", "having", "undef", "values", "group",
+ "minus", "in", "not", "service", "silent", "using", "insert", "delete", "union",
+ "true", "false", "with",
+ "data", "copy", "to", "move", "add", "create", "drop", "clear", "load"]);
+ var operatorChars = /[*+\-<>=&|\^\/!\?]/;
+
+ function tokenBase(stream, state) {
+ var ch = stream.next();
+ curPunc = null;
+ if (ch == "$" || ch == "?") {
+ if(ch == "?" && stream.match(/\s/, false)){
+ return "operator";
+ }
+ stream.match(/^[A-Za-z0-9_\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][A-Za-z0-9_\u00B7\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u037D\u037F-\u1FFF\u200C-\u200D\u203F-\u2040\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]*/);
+ return "variable-2";
+ }
+ else if (ch == "<" && !stream.match(/^[\s\u00a0=]/, false)) {
+ stream.match(/^[^\s\u00a0>]*>?/);
+ return "atom";
+ }
+ else if (ch == "\"" || ch == "'") {
+ state.tokenize = tokenLiteral(ch);
+ return state.tokenize(stream, state);
+ }
+ else if (/[{}\(\),\.;\[\]]/.test(ch)) {
+ curPunc = ch;
+ return "bracket";
+ }
+ else if (ch == "#") {
+ stream.skipToEnd();
+ return "comment";
+ }
+ else if (ch === "^") {
+ ch = stream.peek();
+ if (ch === "^") stream.eat("^");
+ else stream.eatWhile(operatorChars);
+ return "operator";
+ }
+ else if (operatorChars.test(ch)) {
+ stream.eatWhile(operatorChars);
+ return "operator";
+ }
+ else if (ch == ":") {
+ eatPnLocal(stream);
+ return "atom";
+ }
+ else if (ch == "@") {
+ stream.eatWhile(/[a-z\d\-]/i);
+ return "meta";
+ }
+ else {
+ stream.eatWhile(/[_\w\d]/);
+ if (stream.eat(":")) {
+ eatPnLocal(stream);
+ return "atom";
+ }
+ var word = stream.current();
+ if (ops.test(word))
+ return "builtin";
+ else if (keywords.test(word))
+ return "keyword";
+ else
+ return "variable";
+ }
+ }
+
+ function eatPnLocal(stream) {
+ stream.match(/(\.(?=[\w_\-\\%])|[:\w_-]|\\[-\\_~.!$&'()*+,;=/?#@%]|%[a-f\d][a-f\d])+/i);
+ }
+
+ function tokenLiteral(quote) {
+ return function(stream, state) {
+ var escaped = false, ch;
+ while ((ch = stream.next()) != null) {
+ if (ch == quote && !escaped) {
+ state.tokenize = tokenBase;
+ break;
+ }
+ escaped = !escaped && ch == "\\";
+ }
+ return "string";
+ };
+ }
+
+ function pushContext(state, type, col) {
+ state.context = {prev: state.context, indent: state.indent, col: col, type: type};
+ }
+ function popContext(state) {
+ state.indent = state.context.indent;
+ state.context = state.context.prev;
+ }
+
+ return {
+ startState: function() {
+ return {tokenize: tokenBase,
+ context: null,
+ indent: 0,
+ col: 0};
+ },
+
+ token: function(stream, state) {
+ if (stream.sol()) {
+ if (state.context && state.context.align == null) state.context.align = false;
+ state.indent = stream.indentation();
+ }
+ if (stream.eatSpace()) return null;
+ var style = state.tokenize(stream, state);
+
+ if (style != "comment" && state.context && state.context.align == null && state.context.type != "pattern") {
+ state.context.align = true;
+ }
+
+ if (curPunc == "(") pushContext(state, ")", stream.column());
+ else if (curPunc == "[") pushContext(state, "]", stream.column());
+ else if (curPunc == "{") pushContext(state, "}", stream.column());
+ else if (/[\]\}\)]/.test(curPunc)) {
+ while (state.context && state.context.type == "pattern") popContext(state);
+ if (state.context && curPunc == state.context.type) {
+ popContext(state);
+ if (curPunc == "}" && state.context && state.context.type == "pattern")
+ popContext(state);
+ }
+ }
+ else if (curPunc == "." && state.context && state.context.type == "pattern") popContext(state);
+ else if (/atom|string|variable/.test(style) && state.context) {
+ if (/[\}\]]/.test(state.context.type))
+ pushContext(state, "pattern", stream.column());
+ else if (state.context.type == "pattern" && !state.context.align) {
+ state.context.align = true;
+ state.context.col = stream.column();
+ }
+ }
+
+ return style;
+ },
+
+ indent: function(state, textAfter) {
+ var firstChar = textAfter && textAfter.charAt(0);
+ var context = state.context;
+ if (/[\]\}]/.test(firstChar))
+ while (context && context.type == "pattern") context = context.prev;
+
+ var closing = context && firstChar == context.type;
+ if (!context)
+ return 0;
+ else if (context.type == "pattern")
+ return context.col;
+ else if (context.align)
+ return context.col + (closing ? 0 : 1);
+ else
+ return context.indent + (closing ? 0 : indentUnit);
+ },
+
+ lineComment: "#"
+ };
+});
+
+CodeMirror.defineMIME("application/sparql-query", "sparql");
+
+});
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/spreadsheet/spreadsheet.js b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/spreadsheet/spreadsheet.js
new file mode 100644
index 0000000000..d87f988d35
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/spreadsheet/spreadsheet.js
@@ -0,0 +1,112 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: https://codemirror.net/LICENSE
+
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
+ mod(require("../../lib/codemirror"));
+ else if (typeof define == "function" && define.amd) // AMD
+ define(["../../lib/codemirror"], mod);
+ else // Plain browser env
+ mod(CodeMirror);
+})(function(CodeMirror) {
+ "use strict";
+
+ CodeMirror.defineMode("spreadsheet", function () {
+ return {
+ startState: function () {
+ return {
+ stringType: null,
+ stack: []
+ };
+ },
+ token: function (stream, state) {
+ if (!stream) return;
+
+ //check for state changes
+ if (state.stack.length === 0) {
+ //strings
+ if ((stream.peek() == '"') || (stream.peek() == "'")) {
+ state.stringType = stream.peek();
+ stream.next(); // Skip quote
+ state.stack.unshift("string");
+ }
+ }
+
+ //return state
+ //stack has
+ switch (state.stack[0]) {
+ case "string":
+ while (state.stack[0] === "string" && !stream.eol()) {
+ if (stream.peek() === state.stringType) {
+ stream.next(); // Skip quote
+ state.stack.shift(); // Clear flag
+ } else if (stream.peek() === "\\") {
+ stream.next();
+ stream.next();
+ } else {
+ stream.match(/^.[^\\\"\']*/);
+ }
+ }
+ return "string";
+
+ case "characterClass":
+ while (state.stack[0] === "characterClass" && !stream.eol()) {
+ if (!(stream.match(/^[^\]\\]+/) || stream.match(/^\\./)))
+ state.stack.shift();
+ }
+ return "operator";
+ }
+
+ var peek = stream.peek();
+
+ //no stack
+ switch (peek) {
+ case "[":
+ stream.next();
+ state.stack.unshift("characterClass");
+ return "bracket";
+ case ":":
+ stream.next();
+ return "operator";
+ case "\\":
+ if (stream.match(/\\[a-z]+/)) return "string-2";
+ else {
+ stream.next();
+ return "atom";
+ }
+ case ".":
+ case ",":
+ case ";":
+ case "*":
+ case "-":
+ case "+":
+ case "^":
+ case "<":
+ case "/":
+ case "=":
+ stream.next();
+ return "atom";
+ case "$":
+ stream.next();
+ return "builtin";
+ }
+
+ if (stream.match(/\d+/)) {
+ if (stream.match(/^\w+/)) return "error";
+ return "number";
+ } else if (stream.match(/^[a-zA-Z_]\w*/)) {
+ if (stream.match(/(?=[\(.])/, false)) return "keyword";
+ return "variable-2";
+ } else if (["[", "]", "(", ")", "{", "}"].indexOf(peek) != -1) {
+ stream.next();
+ return "bracket";
+ } else if (!stream.eatSpace()) {
+ stream.next();
+ }
+ return null;
+ }
+ };
+ });
+
+ CodeMirror.defineMIME("text/x-spreadsheet", "spreadsheet");
+});
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/sql/sql.js b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/sql/sql.js
new file mode 100644
index 0000000000..cd8b757bb6
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/sql/sql.js
@@ -0,0 +1,503 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: https://codemirror.net/LICENSE
+
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
+ mod(require("../../lib/codemirror"));
+ else if (typeof define == "function" && define.amd) // AMD
+ define(["../../lib/codemirror"], mod);
+ else // Plain browser env
+ mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("sql", function(config, parserConfig) {
+ var client = parserConfig.client || {},
+ atoms = parserConfig.atoms || {"false": true, "true": true, "null": true},
+ builtin = parserConfig.builtin || set(defaultBuiltin),
+ keywords = parserConfig.keywords || set(sqlKeywords),
+ operatorChars = parserConfig.operatorChars || /^[*+\-%<>!=&|~^\/]/,
+ support = parserConfig.support || {},
+ hooks = parserConfig.hooks || {},
+ dateSQL = parserConfig.dateSQL || {"date" : true, "time" : true, "timestamp" : true},
+ backslashStringEscapes = parserConfig.backslashStringEscapes !== false,
+ brackets = parserConfig.brackets || /^[\{}\(\)\[\]]/,
+ punctuation = parserConfig.punctuation || /^[;.,:]/
+
+ function tokenBase(stream, state) {
+ var ch = stream.next();
+
+ // call hooks from the mime type
+ if (hooks[ch]) {
+ var result = hooks[ch](stream, state);
+ if (result !== false) return result;
+ }
+
+ if (support.hexNumber &&
+ ((ch == "0" && stream.match(/^[xX][0-9a-fA-F]+/))
+ || (ch == "x" || ch == "X") && stream.match(/^'[0-9a-fA-F]+'/))) {
+ // hex
+ // ref: http://dev.mysql.com/doc/refman/5.5/en/hexadecimal-literals.html
+ return "number";
+ } else if (support.binaryNumber &&
+ (((ch == "b" || ch == "B") && stream.match(/^'[01]+'/))
+ || (ch == "0" && stream.match(/^b[01]+/)))) {
+ // bitstring
+ // ref: http://dev.mysql.com/doc/refman/5.5/en/bit-field-literals.html
+ return "number";
+ } else if (ch.charCodeAt(0) > 47 && ch.charCodeAt(0) < 58) {
+ // numbers
+ // ref: http://dev.mysql.com/doc/refman/5.5/en/number-literals.html
+ stream.match(/^[0-9]*(\.[0-9]+)?([eE][-+]?[0-9]+)?/);
+ support.decimallessFloat && stream.match(/^\.(?!\.)/);
+ return "number";
+ } else if (ch == "?" && (stream.eatSpace() || stream.eol() || stream.eat(";"))) {
+ // placeholders
+ return "variable-3";
+ } else if (ch == "'" || (ch == '"' && support.doubleQuote)) {
+ // strings
+ // ref: http://dev.mysql.com/doc/refman/5.5/en/string-literals.html
+ state.tokenize = tokenLiteral(ch);
+ return state.tokenize(stream, state);
+ } else if ((((support.nCharCast && (ch == "n" || ch == "N"))
+ || (support.charsetCast && ch == "_" && stream.match(/[a-z][a-z0-9]*/i)))
+ && (stream.peek() == "'" || stream.peek() == '"'))) {
+ // charset casting: _utf8'str', N'str', n'str'
+ // ref: http://dev.mysql.com/doc/refman/5.5/en/string-literals.html
+ return "keyword";
+ } else if (support.escapeConstant && (ch == "e" || ch == "E")
+ && (stream.peek() == "'" || (stream.peek() == '"' && support.doubleQuote))) {
+ // escape constant: E'str', e'str'
+ // ref: https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-SYNTAX-STRINGS-ESCAPE
+ state.tokenize = function(stream, state) {
+ return (state.tokenize = tokenLiteral(stream.next(), true))(stream, state);
+ }
+ return "keyword";
+ } else if (support.commentSlashSlash && ch == "/" && stream.eat("/")) {
+ // 1-line comment
+ stream.skipToEnd();
+ return "comment";
+ } else if ((support.commentHash && ch == "#")
+ || (ch == "-" && stream.eat("-") && (!support.commentSpaceRequired || stream.eat(" ")))) {
+ // 1-line comments
+ // ref: https://kb.askmonty.org/en/comment-syntax/
+ stream.skipToEnd();
+ return "comment";
+ } else if (ch == "/" && stream.eat("*")) {
+ // multi-line comments
+ // ref: https://kb.askmonty.org/en/comment-syntax/
+ state.tokenize = tokenComment(1);
+ return state.tokenize(stream, state);
+ } else if (ch == ".") {
+ // .1 for 0.1
+ if (support.zerolessFloat && stream.match(/^(?:\d+(?:e[+-]?\d+)?)/i))
+ return "number";
+ if (stream.match(/^\.+/))
+ return null
+ // .table_name (ODBC)
+ // // ref: http://dev.mysql.com/doc/refman/5.6/en/identifier-qualifiers.html
+ if (support.ODBCdotTable && stream.match(/^[\w\d_$#]+/))
+ return "variable-2";
+ } else if (operatorChars.test(ch)) {
+ // operators
+ stream.eatWhile(operatorChars);
+ return "operator";
+ } else if (brackets.test(ch)) {
+ // brackets
+ return "bracket";
+ } else if (punctuation.test(ch)) {
+ // punctuation
+ stream.eatWhile(punctuation);
+ return "punctuation";
+ } else if (ch == '{' &&
+ (stream.match(/^( )*(d|D|t|T|ts|TS)( )*'[^']*'( )*}/) || stream.match(/^( )*(d|D|t|T|ts|TS)( )*"[^"]*"( )*}/))) {
+ // dates (weird ODBC syntax)
+ // ref: http://dev.mysql.com/doc/refman/5.5/en/date-and-time-literals.html
+ return "number";
+ } else {
+ stream.eatWhile(/^[_\w\d]/);
+ var word = stream.current().toLowerCase();
+ // dates (standard SQL syntax)
+ // ref: http://dev.mysql.com/doc/refman/5.5/en/date-and-time-literals.html
+ if (dateSQL.hasOwnProperty(word) && (stream.match(/^( )+'[^']*'/) || stream.match(/^( )+"[^"]*"/)))
+ return "number";
+ if (atoms.hasOwnProperty(word)) return "atom";
+ if (builtin.hasOwnProperty(word)) return "type";
+ if (keywords.hasOwnProperty(word)) return "keyword";
+ if (client.hasOwnProperty(word)) return "builtin";
+ return null;
+ }
+ }
+
+ // 'string', with char specified in quote escaped by '\'
+ function tokenLiteral(quote, backslashEscapes) {
+ return function(stream, state) {
+ var escaped = false, ch;
+ while ((ch = stream.next()) != null) {
+ if (ch == quote && !escaped) {
+ state.tokenize = tokenBase;
+ break;
+ }
+ escaped = (backslashStringEscapes || backslashEscapes) && !escaped && ch == "\\";
+ }
+ return "string";
+ };
+ }
+ function tokenComment(depth) {
+ return function(stream, state) {
+ var m = stream.match(/^.*?(\/\*|\*\/)/)
+ if (!m) stream.skipToEnd()
+ else if (m[1] == "/*") state.tokenize = tokenComment(depth + 1)
+ else if (depth > 1) state.tokenize = tokenComment(depth - 1)
+ else state.tokenize = tokenBase
+ return "comment"
+ }
+ }
+
+ function pushContext(stream, state, type) {
+ state.context = {
+ prev: state.context,
+ indent: stream.indentation(),
+ col: stream.column(),
+ type: type
+ };
+ }
+
+ function popContext(state) {
+ state.indent = state.context.indent;
+ state.context = state.context.prev;
+ }
+
+ return {
+ startState: function() {
+ return {tokenize: tokenBase, context: null};
+ },
+
+ token: function(stream, state) {
+ if (stream.sol()) {
+ if (state.context && state.context.align == null)
+ state.context.align = false;
+ }
+ if (state.tokenize == tokenBase && stream.eatSpace()) return null;
+
+ var style = state.tokenize(stream, state);
+ if (style == "comment") return style;
+
+ if (state.context && state.context.align == null)
+ state.context.align = true;
+
+ var tok = stream.current();
+ if (tok == "(")
+ pushContext(stream, state, ")");
+ else if (tok == "[")
+ pushContext(stream, state, "]");
+ else if (state.context && state.context.type == tok)
+ popContext(state);
+ return style;
+ },
+
+ indent: function(state, textAfter) {
+ var cx = state.context;
+ if (!cx) return CodeMirror.Pass;
+ var closing = textAfter.charAt(0) == cx.type;
+ if (cx.align) return cx.col + (closing ? 0 : 1);
+ else return cx.indent + (closing ? 0 : config.indentUnit);
+ },
+
+ blockCommentStart: "/*",
+ blockCommentEnd: "*/",
+ lineComment: support.commentSlashSlash ? "//" : support.commentHash ? "#" : "--",
+ closeBrackets: "()[]{}''\"\"``"
+ };
+});
+
+ // `identifier`
+ function hookIdentifier(stream) {
+ // MySQL/MariaDB identifiers
+ // ref: http://dev.mysql.com/doc/refman/5.6/en/identifier-qualifiers.html
+ var ch;
+ while ((ch = stream.next()) != null) {
+ if (ch == "`" && !stream.eat("`")) return "variable-2";
+ }
+ stream.backUp(stream.current().length - 1);
+ return stream.eatWhile(/\w/) ? "variable-2" : null;
+ }
+
+ // "identifier"
+ function hookIdentifierDoublequote(stream) {
+ // Standard SQL /SQLite identifiers
+ // ref: http://web.archive.org/web/20160813185132/http://savage.net.au/SQL/sql-99.bnf.html#delimited%20identifier
+ // ref: http://sqlite.org/lang_keywords.html
+ var ch;
+ while ((ch = stream.next()) != null) {
+ if (ch == "\"" && !stream.eat("\"")) return "variable-2";
+ }
+ stream.backUp(stream.current().length - 1);
+ return stream.eatWhile(/\w/) ? "variable-2" : null;
+ }
+
+ // variable token
+ function hookVar(stream) {
+ // variables
+ // @@prefix.varName @varName
+ // varName can be quoted with ` or ' or "
+ // ref: http://dev.mysql.com/doc/refman/5.5/en/user-variables.html
+ if (stream.eat("@")) {
+ stream.match('session.');
+ stream.match('local.');
+ stream.match('global.');
+ }
+
+ if (stream.eat("'")) {
+ stream.match(/^.*'/);
+ return "variable-2";
+ } else if (stream.eat('"')) {
+ stream.match(/^.*"/);
+ return "variable-2";
+ } else if (stream.eat("`")) {
+ stream.match(/^.*`/);
+ return "variable-2";
+ } else if (stream.match(/^[0-9a-zA-Z$\.\_]+/)) {
+ return "variable-2";
+ }
+ return null;
+ };
+
+ // short client keyword token
+ function hookClient(stream) {
+ // \N means NULL
+ // ref: http://dev.mysql.com/doc/refman/5.5/en/null-values.html
+ if (stream.eat("N")) {
+ return "atom";
+ }
+ // \g, etc
+ // ref: http://dev.mysql.com/doc/refman/5.5/en/mysql-commands.html
+ return stream.match(/^[a-zA-Z.#!?]/) ? "variable-2" : null;
+ }
+
+ // these keywords are used by all SQL dialects (however, a mode can still overwrite it)
+ var sqlKeywords = "alter and as asc between by count create delete desc distinct drop from group having in insert into is join like not on or order select set table union update values where limit ";
+
+ // turn a space-separated list into an array
+ function set(str) {
+ var obj = {}, words = str.split(" ");
+ for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
+ return obj;
+ }
+
+ var defaultBuiltin = "bool boolean bit blob enum long longblob longtext medium mediumblob mediumint mediumtext time timestamp tinyblob tinyint tinytext text bigint int int1 int2 int3 int4 int8 integer float float4 float8 double char varbinary varchar varcharacter precision real date datetime year unsigned signed decimal numeric"
+
+ // A generic SQL Mode. It's not a standard, it just try to support what is generally supported
+ CodeMirror.defineMIME("text/x-sql", {
+ name: "sql",
+ keywords: set(sqlKeywords + "begin"),
+ builtin: set(defaultBuiltin),
+ atoms: set("false true null unknown"),
+ dateSQL: set("date time timestamp"),
+ support: set("ODBCdotTable doubleQuote binaryNumber hexNumber")
+ });
+
+ CodeMirror.defineMIME("text/x-mssql", {
+ name: "sql",
+ client: set("$partition binary_checksum checksum connectionproperty context_info current_request_id error_line error_message error_number error_procedure error_severity error_state formatmessage get_filestream_transaction_context getansinull host_id host_name isnull isnumeric min_active_rowversion newid newsequentialid rowcount_big xact_state object_id"),
+ keywords: set(sqlKeywords + "begin trigger proc view index for add constraint key primary foreign collate clustered nonclustered declare exec go if use index holdlock nolock nowait paglock readcommitted readcommittedlock readpast readuncommitted repeatableread rowlock serializable snapshot tablock tablockx updlock with"),
+ builtin: set("bigint numeric bit smallint decimal smallmoney int tinyint money float real char varchar text nchar nvarchar ntext binary varbinary image cursor timestamp hierarchyid uniqueidentifier sql_variant xml table "),
+ atoms: set("is not null like and or in left right between inner outer join all any some cross unpivot pivot exists"),
+ operatorChars: /^[*+\-%<>!=^\&|\/]/,
+ brackets: /^[\{}\(\)]/,
+ punctuation: /^[;.,:/]/,
+ backslashStringEscapes: false,
+ dateSQL: set("date datetimeoffset datetime2 smalldatetime datetime time"),
+ hooks: {
+ "@": hookVar
+ }
+ });
+
+ CodeMirror.defineMIME("text/x-mysql", {
+ name: "sql",
+ client: set("charset clear connect edit ego exit go help nopager notee nowarning pager print prompt quit rehash source status system tee"),
+ keywords: set(sqlKeywords + "accessible action add after algorithm all analyze asensitive at authors auto_increment autocommit avg avg_row_length before binary binlog both btree cache call cascade cascaded case catalog_name chain change changed character check checkpoint checksum class_origin client_statistics close coalesce code collate collation collations column columns comment commit committed completion concurrent condition connection consistent constraint contains continue contributors convert cross current current_date current_time current_timestamp current_user cursor data database databases day_hour day_microsecond day_minute day_second deallocate dec declare default delay_key_write delayed delimiter des_key_file describe deterministic dev_pop dev_samp deviance diagnostics directory disable discard distinctrow div dual dumpfile each elseif enable enclosed end ends engine engines enum errors escape escaped even event events every execute exists exit explain extended fast fetch field fields first flush for force foreign found_rows full fulltext function general get global grant grants group group_concat handler hash help high_priority hosts hour_microsecond hour_minute hour_second if ignore ignore_server_ids import index index_statistics infile inner innodb inout insensitive insert_method install interval invoker isolation iterate key keys kill language last leading leave left level limit linear lines list load local localtime localtimestamp lock logs low_priority master master_heartbeat_period master_ssl_verify_server_cert masters match max max_rows maxvalue message_text middleint migrate min min_rows minute_microsecond minute_second mod mode modifies modify mutex mysql_errno natural next no no_write_to_binlog offline offset one online open optimize option optionally out outer outfile pack_keys parser partition partitions password phase plugin plugins prepare preserve prev primary privileges procedure processlist profile profiles purge query quick range read read_write reads real rebuild recover references regexp relaylog release remove rename reorganize repair repeatable replace require resignal restrict resume return returns revoke right rlike rollback rollup row row_format rtree savepoint schedule schema schema_name schemas second_microsecond security sensitive separator serializable server session share show signal slave slow smallint snapshot soname spatial specific sql sql_big_result sql_buffer_result sql_cache sql_calc_found_rows sql_no_cache sql_small_result sqlexception sqlstate sqlwarning ssl start starting starts status std stddev stddev_pop stddev_samp storage straight_join subclass_origin sum suspend table_name table_statistics tables tablespace temporary terminated to trailing transaction trigger triggers truncate uncommitted undo uninstall unique unlock upgrade usage use use_frm user user_resources user_statistics using utc_date utc_time utc_timestamp value variables varying view views warnings when while with work write xa xor year_month zerofill begin do then else loop repeat"),
+ builtin: set("bool boolean bit blob decimal double float long longblob longtext medium mediumblob mediumint mediumtext time timestamp tinyblob tinyint tinytext text bigint int int1 int2 int3 int4 int8 integer float float4 float8 double char varbinary varchar varcharacter precision date datetime year unsigned signed numeric"),
+ atoms: set("false true null unknown"),
+ operatorChars: /^[*+\-%<>!=&|^]/,
+ dateSQL: set("date time timestamp"),
+ support: set("ODBCdotTable decimallessFloat zerolessFloat binaryNumber hexNumber doubleQuote nCharCast charsetCast commentHash commentSpaceRequired"),
+ hooks: {
+ "@": hookVar,
+ "`": hookIdentifier,
+ "\\": hookClient
+ }
+ });
+
+ CodeMirror.defineMIME("text/x-mariadb", {
+ name: "sql",
+ client: set("charset clear connect edit ego exit go help nopager notee nowarning pager print prompt quit rehash source status system tee"),
+ keywords: set(sqlKeywords + "accessible action add after algorithm all always analyze asensitive at authors auto_increment autocommit avg avg_row_length before binary binlog both btree cache call cascade cascaded case catalog_name chain change changed character check checkpoint checksum class_origin client_statistics close coalesce code collate collation collations column columns comment commit committed completion concurrent condition connection consistent constraint contains continue contributors convert cross current current_date current_time current_timestamp current_user cursor data database databases day_hour day_microsecond day_minute day_second deallocate dec declare default delay_key_write delayed delimiter des_key_file describe deterministic dev_pop dev_samp deviance diagnostics directory disable discard distinctrow div dual dumpfile each elseif enable enclosed end ends engine engines enum errors escape escaped even event events every execute exists exit explain extended fast fetch field fields first flush for force foreign found_rows full fulltext function general generated get global grant grants group group_concat handler hard hash help high_priority hosts hour_microsecond hour_minute hour_second if ignore ignore_server_ids import index index_statistics infile inner innodb inout insensitive insert_method install interval invoker isolation iterate key keys kill language last leading leave left level limit linear lines list load local localtime localtimestamp lock logs low_priority master master_heartbeat_period master_ssl_verify_server_cert masters match max max_rows maxvalue message_text middleint migrate min min_rows minute_microsecond minute_second mod mode modifies modify mutex mysql_errno natural next no no_write_to_binlog offline offset one online open optimize option optionally out outer outfile pack_keys parser partition partitions password persistent phase plugin plugins prepare preserve prev primary privileges procedure processlist profile profiles purge query quick range read read_write reads real rebuild recover references regexp relaylog release remove rename reorganize repair repeatable replace require resignal restrict resume return returns revoke right rlike rollback rollup row row_format rtree savepoint schedule schema schema_name schemas second_microsecond security sensitive separator serializable server session share show shutdown signal slave slow smallint snapshot soft soname spatial specific sql sql_big_result sql_buffer_result sql_cache sql_calc_found_rows sql_no_cache sql_small_result sqlexception sqlstate sqlwarning ssl start starting starts status std stddev stddev_pop stddev_samp storage straight_join subclass_origin sum suspend table_name table_statistics tables tablespace temporary terminated to trailing transaction trigger triggers truncate uncommitted undo uninstall unique unlock upgrade usage use use_frm user user_resources user_statistics using utc_date utc_time utc_timestamp value variables varying view views virtual warnings when while with work write xa xor year_month zerofill begin do then else loop repeat"),
+ builtin: set("bool boolean bit blob decimal double float long longblob longtext medium mediumblob mediumint mediumtext time timestamp tinyblob tinyint tinytext text bigint int int1 int2 int3 int4 int8 integer float float4 float8 double char varbinary varchar varcharacter precision date datetime year unsigned signed numeric"),
+ atoms: set("false true null unknown"),
+ operatorChars: /^[*+\-%<>!=&|^]/,
+ dateSQL: set("date time timestamp"),
+ support: set("ODBCdotTable decimallessFloat zerolessFloat binaryNumber hexNumber doubleQuote nCharCast charsetCast commentHash commentSpaceRequired"),
+ hooks: {
+ "@": hookVar,
+ "`": hookIdentifier,
+ "\\": hookClient
+ }
+ });
+
+ // provided by the phpLiteAdmin project - phpliteadmin.org
+ CodeMirror.defineMIME("text/x-sqlite", {
+ name: "sql",
+ // commands of the official SQLite client, ref: https://www.sqlite.org/cli.html#dotcmd
+ client: set("auth backup bail binary changes check clone databases dbinfo dump echo eqp exit explain fullschema headers help import imposter indexes iotrace limit lint load log mode nullvalue once open output print prompt quit read restore save scanstats schema separator session shell show stats system tables testcase timeout timer trace vfsinfo vfslist vfsname width"),
+ // ref: http://sqlite.org/lang_keywords.html
+ keywords: set(sqlKeywords + "abort action add after all analyze attach autoincrement before begin cascade case cast check collate column commit conflict constraint cross current_date current_time current_timestamp database default deferrable deferred detach each else end escape except exclusive exists explain fail for foreign full glob if ignore immediate index indexed initially inner instead intersect isnull key left limit match natural no notnull null of offset outer plan pragma primary query raise recursive references regexp reindex release rename replace restrict right rollback row savepoint temp temporary then to transaction trigger unique using vacuum view virtual when with without"),
+ // SQLite is weakly typed, ref: http://sqlite.org/datatype3.html. This is just a list of some common types.
+ builtin: set("bool boolean bit blob decimal double float long longblob longtext medium mediumblob mediumint mediumtext time timestamp tinyblob tinyint tinytext text clob bigint int int2 int8 integer float double char varchar date datetime year unsigned signed numeric real"),
+ // ref: http://sqlite.org/syntax/literal-value.html
+ atoms: set("null current_date current_time current_timestamp"),
+ // ref: http://sqlite.org/lang_expr.html#binaryops
+ operatorChars: /^[*+\-%<>!=&|/~]/,
+ // SQLite is weakly typed, ref: http://sqlite.org/datatype3.html. This is just a list of some common types.
+ dateSQL: set("date time timestamp datetime"),
+ support: set("decimallessFloat zerolessFloat"),
+ identifierQuote: "\"", //ref: http://sqlite.org/lang_keywords.html
+ hooks: {
+ // bind-parameters ref:http://sqlite.org/lang_expr.html#varparam
+ "@": hookVar,
+ ":": hookVar,
+ "?": hookVar,
+ "$": hookVar,
+ // The preferred way to escape Identifiers is using double quotes, ref: http://sqlite.org/lang_keywords.html
+ "\"": hookIdentifierDoublequote,
+ // there is also support for backticks, ref: http://sqlite.org/lang_keywords.html
+ "`": hookIdentifier
+ }
+ });
+
+ // the query language used by Apache Cassandra is called CQL, but this mime type
+ // is called Cassandra to avoid confusion with Contextual Query Language
+ CodeMirror.defineMIME("text/x-cassandra", {
+ name: "sql",
+ client: { },
+ keywords: set("add all allow alter and any apply as asc authorize batch begin by clustering columnfamily compact consistency count create custom delete desc distinct drop each_quorum exists filtering from grant if in index insert into key keyspace keyspaces level limit local_one local_quorum modify nan norecursive nosuperuser not of on one order password permission permissions primary quorum rename revoke schema select set storage superuser table three to token truncate ttl two type unlogged update use user users using values where with writetime"),
+ builtin: set("ascii bigint blob boolean counter decimal double float frozen inet int list map static text timestamp timeuuid tuple uuid varchar varint"),
+ atoms: set("false true infinity NaN"),
+ operatorChars: /^[<>=]/,
+ dateSQL: { },
+ support: set("commentSlashSlash decimallessFloat"),
+ hooks: { }
+ });
+
+ // this is based on Peter Raganitsch's 'plsql' mode
+ CodeMirror.defineMIME("text/x-plsql", {
+ name: "sql",
+ client: set("appinfo arraysize autocommit autoprint autorecovery autotrace blockterminator break btitle cmdsep colsep compatibility compute concat copycommit copytypecheck define describe echo editfile embedded escape exec execute feedback flagger flush heading headsep instance linesize lno loboffset logsource long longchunksize markup native newpage numformat numwidth pagesize pause pno recsep recsepchar release repfooter repheader serveroutput shiftinout show showmode size spool sqlblanklines sqlcase sqlcode sqlcontinue sqlnumber sqlpluscompatibility sqlprefix sqlprompt sqlterminator suffix tab term termout time timing trimout trimspool ttitle underline verify version wrap"),
+ keywords: set("abort accept access add all alter and any array arraylen as asc assert assign at attributes audit authorization avg base_table begin between binary_integer body boolean by case cast char char_base check close cluster clusters colauth column comment commit compress connect connected constant constraint crash create current currval cursor data_base database date dba deallocate debugoff debugon decimal declare default definition delay delete desc digits dispose distinct do drop else elseif elsif enable end entry escape exception exception_init exchange exclusive exists exit external fast fetch file for force form from function generic goto grant group having identified if immediate in increment index indexes indicator initial initrans insert interface intersect into is key level library like limited local lock log logging long loop master maxextents maxtrans member minextents minus mislabel mode modify multiset new next no noaudit nocompress nologging noparallel not nowait number_base object of off offline on online only open option or order out package parallel partition pctfree pctincrease pctused pls_integer positive positiven pragma primary prior private privileges procedure public raise range raw read rebuild record ref references refresh release rename replace resource restrict return returning returns reverse revoke rollback row rowid rowlabel rownum rows run savepoint schema segment select separate session set share snapshot some space split sql start statement storage subtype successful synonym tabauth table tables tablespace task terminate then to trigger truncate type union unique unlimited unrecoverable unusable update use using validate value values variable view views when whenever where while with work"),
+ builtin: set("abs acos add_months ascii asin atan atan2 average bfile bfilename bigserial bit blob ceil character chartorowid chr clob concat convert cos cosh count dec decode deref dual dump dup_val_on_index empty error exp false float floor found glb greatest hextoraw initcap instr instrb int integer isopen last_day least length lengthb ln lower lpad ltrim lub make_ref max min mlslabel mod months_between natural naturaln nchar nclob new_time next_day nextval nls_charset_decl_len nls_charset_id nls_charset_name nls_initcap nls_lower nls_sort nls_upper nlssort no_data_found notfound null number numeric nvarchar2 nvl others power rawtohex real reftohex round rowcount rowidtochar rowtype rpad rtrim serial sign signtype sin sinh smallint soundex sqlcode sqlerrm sqrt stddev string substr substrb sum sysdate tan tanh to_char text to_date to_label to_multi_byte to_number to_single_byte translate true trunc uid unlogged upper user userenv varchar varchar2 variance varying vsize xml"),
+ operatorChars: /^[*\/+\-%<>!=~]/,
+ dateSQL: set("date time timestamp"),
+ support: set("doubleQuote nCharCast zerolessFloat binaryNumber hexNumber")
+ });
+
+ // Created to support specific hive keywords
+ CodeMirror.defineMIME("text/x-hive", {
+ name: "sql",
+ keywords: set("select alter $elem$ $key$ $value$ add after all analyze and archive as asc before between binary both bucket buckets by cascade case cast change cluster clustered clusterstatus collection column columns comment compute concatenate continue create cross cursor data database databases dbproperties deferred delete delimited desc describe directory disable distinct distribute drop else enable end escaped exclusive exists explain export extended external fetch fields fileformat first format formatted from full function functions grant group having hold_ddltime idxproperties if import in index indexes inpath inputdriver inputformat insert intersect into is items join keys lateral left like limit lines load local location lock locks mapjoin materialized minus msck no_drop nocompress not of offline on option or order out outer outputdriver outputformat overwrite partition partitioned partitions percent plus preserve procedure purge range rcfile read readonly reads rebuild recordreader recordwriter recover reduce regexp rename repair replace restrict revoke right rlike row schema schemas semi sequencefile serde serdeproperties set shared show show_database sort sorted ssl statistics stored streamtable table tables tablesample tblproperties temporary terminated textfile then tmp to touch transform trigger unarchive undo union uniquejoin unlock update use using utc utc_tmestamp view when where while with admin authorization char compact compactions conf cube current current_date current_timestamp day decimal defined dependency directories elem_type exchange file following for grouping hour ignore inner interval jar less logical macro minute month more none noscan over owner partialscan preceding pretty principals protection reload rewrite role roles rollup rows second server sets skewed transactions truncate unbounded unset uri user values window year"),
+ builtin: set("bool boolean long timestamp tinyint smallint bigint int float double date datetime unsigned string array struct map uniontype key_type utctimestamp value_type varchar"),
+ atoms: set("false true null unknown"),
+ operatorChars: /^[*+\-%<>!=]/,
+ dateSQL: set("date timestamp"),
+ support: set("ODBCdotTable doubleQuote binaryNumber hexNumber")
+ });
+
+ CodeMirror.defineMIME("text/x-pgsql", {
+ name: "sql",
+ client: set("source"),
+ // For PostgreSQL - https://www.postgresql.org/docs/11/sql-keywords-appendix.html
+ // For pl/pgsql lang - https://github.com/postgres/postgres/blob/REL_11_2/src/pl/plpgsql/src/pl_scanner.c
+ keywords: set(sqlKeywords + "a abort abs absent absolute access according action ada add admin after aggregate alias all allocate also alter always analyse analyze and any are array array_agg array_max_cardinality as asc asensitive assert assertion assignment asymmetric at atomic attach attribute attributes authorization avg backward base64 before begin begin_frame begin_partition bernoulli between bigint binary bit bit_length blob blocked bom boolean both breadth by c cache call called cardinality cascade cascaded case cast catalog catalog_name ceil ceiling chain char char_length character character_length character_set_catalog character_set_name character_set_schema characteristics characters check checkpoint class class_origin clob close cluster coalesce cobol collate collation collation_catalog collation_name collation_schema collect column column_name columns command_function command_function_code comment comments commit committed concurrently condition condition_number configuration conflict connect connection connection_name constant constraint constraint_catalog constraint_name constraint_schema constraints constructor contains content continue control conversion convert copy corr corresponding cost count covar_pop covar_samp create cross csv cube cume_dist current current_catalog current_date current_default_transform_group current_path current_role current_row current_schema current_time current_timestamp current_transform_group_for_type current_user cursor cursor_name cycle data database datalink datatype date datetime_interval_code datetime_interval_precision day db deallocate debug dec decimal declare default defaults deferrable deferred defined definer degree delete delimiter delimiters dense_rank depends depth deref derived desc describe descriptor detach detail deterministic diagnostics dictionary disable discard disconnect dispatch distinct dlnewcopy dlpreviouscopy dlurlcomplete dlurlcompleteonly dlurlcompletewrite dlurlpath dlurlpathonly dlurlpathwrite dlurlscheme dlurlserver dlvalue do document domain double drop dump dynamic dynamic_function dynamic_function_code each element else elseif elsif empty enable encoding encrypted end end_frame end_partition endexec enforced enum equals errcode error escape event every except exception exclude excluding exclusive exec execute exists exit exp explain expression extension external extract false family fetch file filter final first first_value flag float floor following for force foreach foreign fortran forward found frame_row free freeze from fs full function functions fusion g general generated get global go goto grant granted greatest group grouping groups handler having header hex hierarchy hint hold hour id identity if ignore ilike immediate immediately immutable implementation implicit import in include including increment indent index indexes indicator info inherit inherits initially inline inner inout input insensitive insert instance instantiable instead int integer integrity intersect intersection interval into invoker is isnull isolation join k key key_member key_type label lag language large last last_value lateral lead leading leakproof least left length level library like like_regex limit link listen ln load local localtime localtimestamp location locator lock locked log logged loop lower m map mapping match matched materialized max max_cardinality maxvalue member merge message message_length message_octet_length message_text method min minute minvalue mod mode modifies module month more move multiset mumps name names namespace national natural nchar nclob nesting new next nfc nfd nfkc nfkd nil no none normalize normalized not nothing notice notify notnull nowait nth_value ntile null nullable nullif nulls number numeric object occurrences_regex octet_length octets of off offset oids old on only open operator option options or order ordering ordinality others out outer output over overlaps overlay overriding owned owner p pad parallel parameter parameter_mode parameter_name parameter_ordinal_position parameter_specific_catalog parameter_specific_name parameter_specific_schema parser partial partition pascal passing passthrough password path percent percent_rank percentile_cont percentile_disc perform period permission pg_context pg_datatype_name pg_exception_context pg_exception_detail pg_exception_hint placing plans pli policy portion position position_regex power precedes preceding precision prepare prepared preserve primary print_strict_params prior privileges procedural procedure procedures program public publication query quote raise range rank read reads real reassign recheck recovery recursive ref references referencing refresh regr_avgx regr_avgy regr_count regr_intercept regr_r2 regr_slope regr_sxx regr_sxy regr_syy reindex relative release rename repeatable replace replica requiring reset respect restart restore restrict result result_oid return returned_cardinality returned_length returned_octet_length returned_sqlstate returning returns reverse revoke right role rollback rollup routine routine_catalog routine_name routine_schema routines row row_count row_number rows rowtype rule savepoint scale schema schema_name schemas scope scope_catalog scope_name scope_schema scroll search second section security select selective self sensitive sequence sequences serializable server server_name session session_user set setof sets share show similar simple size skip slice smallint snapshot some source space specific specific_name specifictype sql sqlcode sqlerror sqlexception sqlstate sqlwarning sqrt stable stacked standalone start state statement static statistics stddev_pop stddev_samp stdin stdout storage strict strip structure style subclass_origin submultiset subscription substring substring_regex succeeds sum symmetric sysid system system_time system_user t table table_name tables tablesample tablespace temp template temporary text then ties time timestamp timezone_hour timezone_minute to token top_level_count trailing transaction transaction_active transactions_committed transactions_rolled_back transform transforms translate translate_regex translation treat trigger trigger_catalog trigger_name trigger_schema trim trim_array true truncate trusted type types uescape unbounded uncommitted under unencrypted union unique unknown unlink unlisten unlogged unnamed unnest until untyped update upper uri usage use_column use_variable user user_defined_type_catalog user_defined_type_code user_defined_type_name user_defined_type_schema using vacuum valid validate validator value value_of values var_pop var_samp varbinary varchar variable_conflict variadic varying verbose version versioning view views volatile warning when whenever where while whitespace width_bucket window with within without work wrapper write xml xmlagg xmlattributes xmlbinary xmlcast xmlcomment xmlconcat xmldeclaration xmldocument xmlelement xmlexists xmlforest xmliterate xmlnamespaces xmlparse xmlpi xmlquery xmlroot xmlschema xmlserialize xmltable xmltext xmlvalidate year yes zone"),
+ // https://www.postgresql.org/docs/11/datatype.html
+ builtin: set("bigint int8 bigserial serial8 bit varying varbit boolean bool box bytea character char varchar cidr circle date double precision float8 inet integer int int4 interval json jsonb line lseg macaddr macaddr8 money numeric decimal path pg_lsn point polygon real float4 smallint int2 smallserial serial2 serial serial4 text time without zone with timetz timestamp timestamptz tsquery tsvector txid_snapshot uuid xml"),
+ atoms: set("false true null unknown"),
+ operatorChars: /^[*\/+\-%<>!=&|^\/#@?~]/,
+ backslashStringEscapes: false,
+ dateSQL: set("date time timestamp"),
+ support: set("ODBCdotTable decimallessFloat zerolessFloat binaryNumber hexNumber nCharCast charsetCast escapeConstant")
+ });
+
+ // Google's SQL-like query language, GQL
+ CodeMirror.defineMIME("text/x-gql", {
+ name: "sql",
+ keywords: set("ancestor and asc by contains desc descendant distinct from group has in is limit offset on order select superset where"),
+ atoms: set("false true"),
+ builtin: set("blob datetime first key __key__ string integer double boolean null"),
+ operatorChars: /^[*+\-%<>!=]/
+ });
+
+ // Greenplum
+ CodeMirror.defineMIME("text/x-gpsql", {
+ name: "sql",
+ client: set("source"),
+ //https://github.com/greenplum-db/gpdb/blob/master/src/include/parser/kwlist.h
+ keywords: set("abort absolute access action active add admin after aggregate all also alter always analyse analyze and any array as asc assertion assignment asymmetric at authorization backward before begin between bigint binary bit boolean both by cache called cascade cascaded case cast chain char character characteristics check checkpoint class close cluster coalesce codegen collate column comment commit committed concurrency concurrently configuration connection constraint constraints contains content continue conversion copy cost cpu_rate_limit create createdb createexttable createrole createuser cross csv cube current current_catalog current_date current_role current_schema current_time current_timestamp current_user cursor cycle data database day deallocate dec decimal declare decode default defaults deferrable deferred definer delete delimiter delimiters deny desc dictionary disable discard distinct distributed do document domain double drop dxl each else enable encoding encrypted end enum errors escape every except exchange exclude excluding exclusive execute exists explain extension external extract false family fetch fields filespace fill filter first float following for force foreign format forward freeze from full function global grant granted greatest group group_id grouping handler hash having header hold host hour identity if ignore ilike immediate immutable implicit in including inclusive increment index indexes inherit inherits initially inline inner inout input insensitive insert instead int integer intersect interval into invoker is isnull isolation join key language large last leading least left level like limit list listen load local localtime localtimestamp location lock log login mapping master match maxvalue median merge minute minvalue missing mode modifies modify month move name names national natural nchar new newline next no nocreatedb nocreateexttable nocreaterole nocreateuser noinherit nologin none noovercommit nosuperuser not nothing notify notnull nowait null nullif nulls numeric object of off offset oids old on only operator option options or order ordered others out outer over overcommit overlaps overlay owned owner parser partial partition partitions passing password percent percentile_cont percentile_disc placing plans position preceding precision prepare prepared preserve primary prior privileges procedural procedure protocol queue quote randomly range read readable reads real reassign recheck recursive ref references reindex reject relative release rename repeatable replace replica reset resource restart restrict returning returns revoke right role rollback rollup rootpartition row rows rule savepoint scatter schema scroll search second security segment select sequence serializable session session_user set setof sets share show similar simple smallint some split sql stable standalone start statement statistics stdin stdout storage strict strip subpartition subpartitions substring superuser symmetric sysid system table tablespace temp template temporary text then threshold ties time timestamp to trailing transaction treat trigger trim true truncate trusted type unbounded uncommitted unencrypted union unique unknown unlisten until update user using vacuum valid validation validator value values varchar variadic varying verbose version view volatile web when where whitespace window with within without work writable write xml xmlattributes xmlconcat xmlelement xmlexists xmlforest xmlparse xmlpi xmlroot xmlserialize year yes zone"),
+ builtin: set("bigint int8 bigserial serial8 bit varying varbit boolean bool box bytea character char varchar cidr circle date double precision float float8 inet integer int int4 interval json jsonb line lseg macaddr macaddr8 money numeric decimal path pg_lsn point polygon real float4 smallint int2 smallserial serial2 serial serial4 text time without zone with timetz timestamp timestamptz tsquery tsvector txid_snapshot uuid xml"),
+ atoms: set("false true null unknown"),
+ operatorChars: /^[*+\-%<>!=&|^\/#@?~]/,
+ dateSQL: set("date time timestamp"),
+ support: set("ODBCdotTable decimallessFloat zerolessFloat binaryNumber hexNumber nCharCast charsetCast")
+ });
+
+ // Spark SQL
+ CodeMirror.defineMIME("text/x-sparksql", {
+ name: "sql",
+ keywords: set("add after all alter analyze and anti archive array as asc at between bucket buckets by cache cascade case cast change clear cluster clustered codegen collection column columns comment commit compact compactions compute concatenate cost create cross cube current current_date current_timestamp database databases data dbproperties defined delete delimited deny desc describe dfs directories distinct distribute drop else end escaped except exchange exists explain export extended external false fields fileformat first following for format formatted from full function functions global grant group grouping having if ignore import in index indexes inner inpath inputformat insert intersect interval into is items join keys last lateral lazy left like limit lines list load local location lock locks logical macro map minus msck natural no not null nulls of on optimize option options or order out outer outputformat over overwrite partition partitioned partitions percent preceding principals purge range recordreader recordwriter recover reduce refresh regexp rename repair replace reset restrict revoke right rlike role roles rollback rollup row rows schema schemas select semi separated serde serdeproperties set sets show skewed sort sorted start statistics stored stratify struct table tables tablesample tblproperties temp temporary terminated then to touch transaction transactions transform true truncate unarchive unbounded uncache union unlock unset use using values view when where window with"),
+ builtin: set("abs acos acosh add_months aggregate and any approx_count_distinct approx_percentile array array_contains array_distinct array_except array_intersect array_join array_max array_min array_position array_remove array_repeat array_sort array_union arrays_overlap arrays_zip ascii asin asinh assert_true atan atan2 atanh avg base64 between bigint bin binary bit_and bit_count bit_get bit_length bit_or bit_xor bool_and bool_or boolean bround btrim cardinality case cast cbrt ceil ceiling char char_length character_length chr coalesce collect_list collect_set concat concat_ws conv corr cos cosh cot count count_if count_min_sketch covar_pop covar_samp crc32 cume_dist current_catalog current_database current_date current_timestamp current_timezone current_user date date_add date_format date_from_unix_date date_part date_sub date_trunc datediff day dayofmonth dayofweek dayofyear decimal decode degrees delimited dense_rank div double e element_at elt encode every exists exp explode explode_outer expm1 extract factorial filter find_in_set first first_value flatten float floor forall format_number format_string from_csv from_json from_unixtime from_utc_timestamp get_json_object getbit greatest grouping grouping_id hash hex hour hypot if ifnull in initcap inline inline_outer input_file_block_length input_file_block_start input_file_name inputformat instr int isnan isnotnull isnull java_method json_array_length json_object_keys json_tuple kurtosis lag last last_day last_value lcase lead least left length levenshtein like ln locate log log10 log1p log2 lower lpad ltrim make_date make_dt_interval make_interval make_timestamp make_ym_interval map map_concat map_entries map_filter map_from_arrays map_from_entries map_keys map_values map_zip_with max max_by md5 mean min min_by minute mod monotonically_increasing_id month months_between named_struct nanvl negative next_day not now nth_value ntile nullif nvl nvl2 octet_length or outputformat overlay parse_url percent_rank percentile percentile_approx pi pmod posexplode posexplode_outer position positive pow power printf quarter radians raise_error rand randn random rank rcfile reflect regexp regexp_extract regexp_extract_all regexp_like regexp_replace repeat replace reverse right rint rlike round row_number rpad rtrim schema_of_csv schema_of_json second sentences sequence sequencefile serde session_window sha sha1 sha2 shiftleft shiftright shiftrightunsigned shuffle sign signum sin sinh size skewness slice smallint some sort_array soundex space spark_partition_id split sqrt stack std stddev stddev_pop stddev_samp str_to_map string struct substr substring substring_index sum tan tanh textfile timestamp timestamp_micros timestamp_millis timestamp_seconds tinyint to_csv to_date to_json to_timestamp to_unix_timestamp to_utc_timestamp transform transform_keys transform_values translate trim trunc try_add try_divide typeof ucase unbase64 unhex uniontype unix_date unix_micros unix_millis unix_seconds unix_timestamp upper uuid var_pop var_samp variance version weekday weekofyear when width_bucket window xpath xpath_boolean xpath_double xpath_float xpath_int xpath_long xpath_number xpath_short xpath_string xxhash64 year zip_with"),
+ atoms: set("false true null"),
+ operatorChars: /^[*\/+\-%<>!=~&|^]/,
+ dateSQL: set("date time timestamp"),
+ support: set("ODBCdotTable doubleQuote zerolessFloat")
+ });
+
+ // Esper
+ CodeMirror.defineMIME("text/x-esper", {
+ name: "sql",
+ client: set("source"),
+ // http://www.espertech.com/esper/release-5.5.0/esper-reference/html/appendix_keywords.html
+ keywords: set("alter and as asc between by count create delete desc distinct drop from group having in insert into is join like not on or order select set table union update values where limit after all and as at asc avedev avg between by case cast coalesce count create current_timestamp day days delete define desc distinct else end escape events every exists false first from full group having hour hours in inner insert instanceof into irstream is istream join last lastweekday left limit like max match_recognize matches median measures metadatasql min minute minutes msec millisecond milliseconds not null offset on or order outer output partition pattern prev prior regexp retain-union retain-intersection right rstream sec second seconds select set some snapshot sql stddev sum then true unidirectional until update variable weekday when where window"),
+ builtin: {},
+ atoms: set("false true null"),
+ operatorChars: /^[*+\-%<>!=&|^\/#@?~]/,
+ dateSQL: set("time"),
+ support: set("decimallessFloat zerolessFloat binaryNumber hexNumber")
+ });
+});
+
+/*
+ How Properties of Mime Types are used by SQL Mode
+ =================================================
+
+ keywords:
+ A list of keywords you want to be highlighted.
+ builtin:
+ A list of builtin types you want to be highlighted (if you want types to be of class "builtin" instead of "keyword").
+ operatorChars:
+ All characters that must be handled as operators.
+ client:
+ Commands parsed and executed by the client (not the server).
+ support:
+ A list of supported syntaxes which are not common, but are supported by more than 1 DBMS.
+ * ODBCdotTable: .tableName
+ * zerolessFloat: .1
+ * doubleQuote
+ * nCharCast: N'string'
+ * charsetCast: _utf8'string'
+ * commentHash: use # char for comments
+ * commentSlashSlash: use // for comments
+ * commentSpaceRequired: require a space after -- for comments
+ atoms:
+ Keywords that must be highlighted as atoms,. Some DBMS's support more atoms than others:
+ UNKNOWN, INFINITY, UNDERFLOW, NaN...
+ dateSQL:
+ Used for date/time SQL standard syntax, because not all DBMS's support same temporal types.
+*/
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/stex/stex.js b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/stex/stex.js
new file mode 100644
index 0000000000..20c3bc7a18
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/stex/stex.js
@@ -0,0 +1,264 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: https://codemirror.net/LICENSE
+
+/*
+ * Author: Constantin Jucovschi (c.jucovschi@jacobs-university.de)
+ * Licence: MIT
+ */
+
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
+ mod(require("../../lib/codemirror"));
+ else if (typeof define == "function" && define.amd) // AMD
+ define(["../../lib/codemirror"], mod);
+ else // Plain browser env
+ mod(CodeMirror);
+})(function(CodeMirror) {
+ "use strict";
+
+ CodeMirror.defineMode("stex", function(_config, parserConfig) {
+ "use strict";
+
+ function pushCommand(state, command) {
+ state.cmdState.push(command);
+ }
+
+ function peekCommand(state) {
+ if (state.cmdState.length > 0) {
+ return state.cmdState[state.cmdState.length - 1];
+ } else {
+ return null;
+ }
+ }
+
+ function popCommand(state) {
+ var plug = state.cmdState.pop();
+ if (plug) {
+ plug.closeBracket();
+ }
+ }
+
+ // returns the non-default plugin closest to the end of the list
+ function getMostPowerful(state) {
+ var context = state.cmdState;
+ for (var i = context.length - 1; i >= 0; i--) {
+ var plug = context[i];
+ if (plug.name == "DEFAULT") {
+ continue;
+ }
+ return plug;
+ }
+ return { styleIdentifier: function() { return null; } };
+ }
+
+ function addPluginPattern(pluginName, cmdStyle, styles) {
+ return function () {
+ this.name = pluginName;
+ this.bracketNo = 0;
+ this.style = cmdStyle;
+ this.styles = styles;
+ this.argument = null; // \begin and \end have arguments that follow. These are stored in the plugin
+
+ this.styleIdentifier = function() {
+ return this.styles[this.bracketNo - 1] || null;
+ };
+ this.openBracket = function() {
+ this.bracketNo++;
+ return "bracket";
+ };
+ this.closeBracket = function() {};
+ };
+ }
+
+ var plugins = {};
+
+ plugins["importmodule"] = addPluginPattern("importmodule", "tag", ["string", "builtin"]);
+ plugins["documentclass"] = addPluginPattern("documentclass", "tag", ["", "atom"]);
+ plugins["usepackage"] = addPluginPattern("usepackage", "tag", ["atom"]);
+ plugins["begin"] = addPluginPattern("begin", "tag", ["atom"]);
+ plugins["end"] = addPluginPattern("end", "tag", ["atom"]);
+
+ plugins["label" ] = addPluginPattern("label" , "tag", ["atom"]);
+ plugins["ref" ] = addPluginPattern("ref" , "tag", ["atom"]);
+ plugins["eqref" ] = addPluginPattern("eqref" , "tag", ["atom"]);
+ plugins["cite" ] = addPluginPattern("cite" , "tag", ["atom"]);
+ plugins["bibitem" ] = addPluginPattern("bibitem" , "tag", ["atom"]);
+ plugins["Bibitem" ] = addPluginPattern("Bibitem" , "tag", ["atom"]);
+ plugins["RBibitem" ] = addPluginPattern("RBibitem" , "tag", ["atom"]);
+
+ plugins["DEFAULT"] = function () {
+ this.name = "DEFAULT";
+ this.style = "tag";
+
+ this.styleIdentifier = this.openBracket = this.closeBracket = function() {};
+ };
+
+ function setState(state, f) {
+ state.f = f;
+ }
+
+ // called when in a normal (no environment) context
+ function normal(source, state) {
+ var plug;
+ // Do we look like '\command' ? If so, attempt to apply the plugin 'command'
+ if (source.match(/^\\[a-zA-Z@]+/)) {
+ var cmdName = source.current().slice(1);
+ plug = plugins.hasOwnProperty(cmdName) ? plugins[cmdName] : plugins["DEFAULT"];
+ plug = new plug();
+ pushCommand(state, plug);
+ setState(state, beginParams);
+ return plug.style;
+ }
+
+ // escape characters
+ if (source.match(/^\\[$&%#{}_]/)) {
+ return "tag";
+ }
+
+ // white space control characters
+ if (source.match(/^\\[,;!\/\\]/)) {
+ return "tag";
+ }
+
+ // find if we're starting various math modes
+ if (source.match("\\[")) {
+ setState(state, function(source, state){ return inMathMode(source, state, "\\]"); });
+ return "keyword";
+ }
+ if (source.match("\\(")) {
+ setState(state, function(source, state){ return inMathMode(source, state, "\\)"); });
+ return "keyword";
+ }
+ if (source.match("$$")) {
+ setState(state, function(source, state){ return inMathMode(source, state, "$$"); });
+ return "keyword";
+ }
+ if (source.match("$")) {
+ setState(state, function(source, state){ return inMathMode(source, state, "$"); });
+ return "keyword";
+ }
+
+ var ch = source.next();
+ if (ch == "%") {
+ source.skipToEnd();
+ return "comment";
+ } else if (ch == '}' || ch == ']') {
+ plug = peekCommand(state);
+ if (plug) {
+ plug.closeBracket(ch);
+ setState(state, beginParams);
+ } else {
+ return "error";
+ }
+ return "bracket";
+ } else if (ch == '{' || ch == '[') {
+ plug = plugins["DEFAULT"];
+ plug = new plug();
+ pushCommand(state, plug);
+ return "bracket";
+ } else if (/\d/.test(ch)) {
+ source.eatWhile(/[\w.%]/);
+ return "atom";
+ } else {
+ source.eatWhile(/[\w\-_]/);
+ plug = getMostPowerful(state);
+ if (plug.name == 'begin') {
+ plug.argument = source.current();
+ }
+ return plug.styleIdentifier();
+ }
+ }
+
+ function inMathMode(source, state, endModeSeq) {
+ if (source.eatSpace()) {
+ return null;
+ }
+ if (endModeSeq && source.match(endModeSeq)) {
+ setState(state, normal);
+ return "keyword";
+ }
+ if (source.match(/^\\[a-zA-Z@]+/)) {
+ return "tag";
+ }
+ if (source.match(/^[a-zA-Z]+/)) {
+ return "variable-2";
+ }
+ // escape characters
+ if (source.match(/^\\[$&%#{}_]/)) {
+ return "tag";
+ }
+ // white space control characters
+ if (source.match(/^\\[,;!\/]/)) {
+ return "tag";
+ }
+ // special math-mode characters
+ if (source.match(/^[\^_&]/)) {
+ return "tag";
+ }
+ // non-special characters
+ if (source.match(/^[+\-<>|=,\/@!*:;'"`~#?]/)) {
+ return null;
+ }
+ if (source.match(/^(\d+\.\d*|\d*\.\d+|\d+)/)) {
+ return "number";
+ }
+ var ch = source.next();
+ if (ch == "{" || ch == "}" || ch == "[" || ch == "]" || ch == "(" || ch == ")") {
+ return "bracket";
+ }
+
+ if (ch == "%") {
+ source.skipToEnd();
+ return "comment";
+ }
+ return "error";
+ }
+
+ function beginParams(source, state) {
+ var ch = source.peek(), lastPlug;
+ if (ch == '{' || ch == '[') {
+ lastPlug = peekCommand(state);
+ lastPlug.openBracket(ch);
+ source.eat(ch);
+ setState(state, normal);
+ return "bracket";
+ }
+ if (/[ \t\r]/.test(ch)) {
+ source.eat(ch);
+ return null;
+ }
+ setState(state, normal);
+ popCommand(state);
+
+ return normal(source, state);
+ }
+
+ return {
+ startState: function() {
+ var f = parserConfig.inMathMode ? function(source, state){ return inMathMode(source, state); } : normal;
+ return {
+ cmdState: [],
+ f: f
+ };
+ },
+ copyState: function(s) {
+ return {
+ cmdState: s.cmdState.slice(),
+ f: s.f
+ };
+ },
+ token: function(stream, state) {
+ return state.f(stream, state);
+ },
+ blankLine: function(state) {
+ state.f = normal;
+ state.cmdState.length = 0;
+ },
+ lineComment: "%"
+ };
+ });
+
+ CodeMirror.defineMIME("text/x-stex", "stex");
+ CodeMirror.defineMIME("text/x-latex", "stex");
+
+});
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/stylus/stylus.js b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/stylus/stylus.js
new file mode 100644
index 0000000000..978696bddd
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/stylus/stylus.js
@@ -0,0 +1,775 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: https://codemirror.net/LICENSE
+
+// Stylus mode created by Dmitry Kiselyov http://git.io/AaRB
+
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
+ mod(require("../../lib/codemirror"));
+ else if (typeof define == "function" && define.amd) // AMD
+ define(["../../lib/codemirror"], mod);
+ else // Plain browser env
+ mod(CodeMirror);
+})(function(CodeMirror) {
+ "use strict";
+
+ CodeMirror.defineMode("stylus", function(config) {
+ var indentUnit = config.indentUnit,
+ indentUnitString = '',
+ tagKeywords = keySet(tagKeywords_),
+ tagVariablesRegexp = /^(a|b|i|s|col|em)$/i,
+ propertyKeywords = keySet(propertyKeywords_),
+ nonStandardPropertyKeywords = keySet(nonStandardPropertyKeywords_),
+ valueKeywords = keySet(valueKeywords_),
+ colorKeywords = keySet(colorKeywords_),
+ documentTypes = keySet(documentTypes_),
+ documentTypesRegexp = wordRegexp(documentTypes_),
+ mediaFeatures = keySet(mediaFeatures_),
+ mediaTypes = keySet(mediaTypes_),
+ fontProperties = keySet(fontProperties_),
+ operatorsRegexp = /^\s*([.]{2,3}|&&|\|\||\*\*|[?!=:]?=|[-+*\/%<>]=?|\?:|\~)/,
+ wordOperatorKeywordsRegexp = wordRegexp(wordOperatorKeywords_),
+ blockKeywords = keySet(blockKeywords_),
+ vendorPrefixesRegexp = new RegExp(/^\-(moz|ms|o|webkit)-/i),
+ commonAtoms = keySet(commonAtoms_),
+ firstWordMatch = "",
+ states = {},
+ ch,
+ style,
+ type,
+ override;
+
+ while (indentUnitString.length < indentUnit) indentUnitString += ' ';
+
+ /**
+ * Tokenizers
+ */
+ function tokenBase(stream, state) {
+ firstWordMatch = stream.string.match(/(^[\w-]+\s*=\s*$)|(^\s*[\w-]+\s*=\s*[\w-])|(^\s*(\.|#|@|\$|\&|\[|\d|\+|::?|\{|\>|~|\/)?\s*[\w-]*([a-z0-9-]|\*|\/\*)(\(|,)?)/);
+ state.context.line.firstWord = firstWordMatch ? firstWordMatch[0].replace(/^\s*/, "") : "";
+ state.context.line.indent = stream.indentation();
+ ch = stream.peek();
+
+ // Line comment
+ if (stream.match("//")) {
+ stream.skipToEnd();
+ return ["comment", "comment"];
+ }
+ // Block comment
+ if (stream.match("/*")) {
+ state.tokenize = tokenCComment;
+ return tokenCComment(stream, state);
+ }
+ // String
+ if (ch == "\"" || ch == "'") {
+ stream.next();
+ state.tokenize = tokenString(ch);
+ return state.tokenize(stream, state);
+ }
+ // Def
+ if (ch == "@") {
+ stream.next();
+ stream.eatWhile(/[\w\\-]/);
+ return ["def", stream.current()];
+ }
+ // ID selector or Hex color
+ if (ch == "#") {
+ stream.next();
+ // Hex color
+ if (stream.match(/^[0-9a-f]{3}([0-9a-f]([0-9a-f]{2}){0,2})?\b(?!-)/i)) {
+ return ["atom", "atom"];
+ }
+ // ID selector
+ if (stream.match(/^[a-z][\w-]*/i)) {
+ return ["builtin", "hash"];
+ }
+ }
+ // Vendor prefixes
+ if (stream.match(vendorPrefixesRegexp)) {
+ return ["meta", "vendor-prefixes"];
+ }
+ // Numbers
+ if (stream.match(/^-?[0-9]?\.?[0-9]/)) {
+ stream.eatWhile(/[a-z%]/i);
+ return ["number", "unit"];
+ }
+ // !important|optional
+ if (ch == "!") {
+ stream.next();
+ return [stream.match(/^(important|optional)/i) ? "keyword": "operator", "important"];
+ }
+ // Class
+ if (ch == "." && stream.match(/^\.[a-z][\w-]*/i)) {
+ return ["qualifier", "qualifier"];
+ }
+ // url url-prefix domain regexp
+ if (stream.match(documentTypesRegexp)) {
+ if (stream.peek() == "(") state.tokenize = tokenParenthesized;
+ return ["property", "word"];
+ }
+ // Mixins / Functions
+ if (stream.match(/^[a-z][\w-]*\(/i)) {
+ stream.backUp(1);
+ return ["keyword", "mixin"];
+ }
+ // Block mixins
+ if (stream.match(/^(\+|-)[a-z][\w-]*\(/i)) {
+ stream.backUp(1);
+ return ["keyword", "block-mixin"];
+ }
+ // Parent Reference BEM naming
+ if (stream.string.match(/^\s*&/) && stream.match(/^[-_]+[a-z][\w-]*/)) {
+ return ["qualifier", "qualifier"];
+ }
+ // / Root Reference & Parent Reference
+ if (stream.match(/^(\/|&)(-|_|:|\.|#|[a-z])/)) {
+ stream.backUp(1);
+ return ["variable-3", "reference"];
+ }
+ if (stream.match(/^&{1}\s*$/)) {
+ return ["variable-3", "reference"];
+ }
+ // Word operator
+ if (stream.match(wordOperatorKeywordsRegexp)) {
+ return ["operator", "operator"];
+ }
+ // Word
+ if (stream.match(/^\$?[-_]*[a-z0-9]+[\w-]*/i)) {
+ // Variable
+ if (stream.match(/^(\.|\[)[\w-\'\"\]]+/i, false)) {
+ if (!wordIsTag(stream.current())) {
+ stream.match('.');
+ return ["variable-2", "variable-name"];
+ }
+ }
+ return ["variable-2", "word"];
+ }
+ // Operators
+ if (stream.match(operatorsRegexp)) {
+ return ["operator", stream.current()];
+ }
+ // Delimiters
+ if (/[:;,{}\[\]\(\)]/.test(ch)) {
+ stream.next();
+ return [null, ch];
+ }
+ // Non-detected items
+ stream.next();
+ return [null, null];
+ }
+
+ /**
+ * Token comment
+ */
+ function tokenCComment(stream, state) {
+ var maybeEnd = false, ch;
+ while ((ch = stream.next()) != null) {
+ if (maybeEnd && ch == "/") {
+ state.tokenize = null;
+ break;
+ }
+ maybeEnd = (ch == "*");
+ }
+ return ["comment", "comment"];
+ }
+
+ /**
+ * Token string
+ */
+ function tokenString(quote) {
+ return function(stream, state) {
+ var escaped = false, ch;
+ while ((ch = stream.next()) != null) {
+ if (ch == quote && !escaped) {
+ if (quote == ")") stream.backUp(1);
+ break;
+ }
+ escaped = !escaped && ch == "\\";
+ }
+ if (ch == quote || !escaped && quote != ")") state.tokenize = null;
+ return ["string", "string"];
+ };
+ }
+
+ /**
+ * Token parenthesized
+ */
+ function tokenParenthesized(stream, state) {
+ stream.next(); // Must be "("
+ if (!stream.match(/\s*[\"\')]/, false))
+ state.tokenize = tokenString(")");
+ else
+ state.tokenize = null;
+ return [null, "("];
+ }
+
+ /**
+ * Context management
+ */
+ function Context(type, indent, prev, line) {
+ this.type = type;
+ this.indent = indent;
+ this.prev = prev;
+ this.line = line || {firstWord: "", indent: 0};
+ }
+
+ function pushContext(state, stream, type, indent) {
+ indent = indent >= 0 ? indent : indentUnit;
+ state.context = new Context(type, stream.indentation() + indent, state.context);
+ return type;
+ }
+
+ function popContext(state, currentIndent) {
+ var contextIndent = state.context.indent - indentUnit;
+ currentIndent = currentIndent || false;
+ state.context = state.context.prev;
+ if (currentIndent) state.context.indent = contextIndent;
+ return state.context.type;
+ }
+
+ function pass(type, stream, state) {
+ return states[state.context.type](type, stream, state);
+ }
+
+ function popAndPass(type, stream, state, n) {
+ for (var i = n || 1; i > 0; i--)
+ state.context = state.context.prev;
+ return pass(type, stream, state);
+ }
+
+
+ /**
+ * Parser
+ */
+ function wordIsTag(word) {
+ return word.toLowerCase() in tagKeywords;
+ }
+
+ function wordIsProperty(word) {
+ word = word.toLowerCase();
+ return word in propertyKeywords || word in fontProperties;
+ }
+
+ function wordIsBlock(word) {
+ return word.toLowerCase() in blockKeywords;
+ }
+
+ function wordIsVendorPrefix(word) {
+ return word.toLowerCase().match(vendorPrefixesRegexp);
+ }
+
+ function wordAsValue(word) {
+ var wordLC = word.toLowerCase();
+ var override = "variable-2";
+ if (wordIsTag(word)) override = "tag";
+ else if (wordIsBlock(word)) override = "block-keyword";
+ else if (wordIsProperty(word)) override = "property";
+ else if (wordLC in valueKeywords || wordLC in commonAtoms) override = "atom";
+ else if (wordLC == "return" || wordLC in colorKeywords) override = "keyword";
+
+ // Font family
+ else if (word.match(/^[A-Z]/)) override = "string";
+ return override;
+ }
+
+ function typeIsBlock(type, stream) {
+ return ((endOfLine(stream) && (type == "{" || type == "]" || type == "hash" || type == "qualifier")) || type == "block-mixin");
+ }
+
+ function typeIsInterpolation(type, stream) {
+ return type == "{" && stream.match(/^\s*\$?[\w-]+/i, false);
+ }
+
+ function typeIsPseudo(type, stream) {
+ return type == ":" && stream.match(/^[a-z-]+/, false);
+ }
+
+ function startOfLine(stream) {
+ return stream.sol() || stream.string.match(new RegExp("^\\s*" + escapeRegExp(stream.current())));
+ }
+
+ function endOfLine(stream) {
+ return stream.eol() || stream.match(/^\s*$/, false);
+ }
+
+ function firstWordOfLine(line) {
+ var re = /^\s*[-_]*[a-z0-9]+[\w-]*/i;
+ var result = typeof line == "string" ? line.match(re) : line.string.match(re);
+ return result ? result[0].replace(/^\s*/, "") : "";
+ }
+
+
+ /**
+ * Block
+ */
+ states.block = function(type, stream, state) {
+ if ((type == "comment" && startOfLine(stream)) ||
+ (type == "," && endOfLine(stream)) ||
+ type == "mixin") {
+ return pushContext(state, stream, "block", 0);
+ }
+ if (typeIsInterpolation(type, stream)) {
+ return pushContext(state, stream, "interpolation");
+ }
+ if (endOfLine(stream) && type == "]") {
+ if (!/^\s*(\.|#|:|\[|\*|&)/.test(stream.string) && !wordIsTag(firstWordOfLine(stream))) {
+ return pushContext(state, stream, "block", 0);
+ }
+ }
+ if (typeIsBlock(type, stream)) {
+ return pushContext(state, stream, "block");
+ }
+ if (type == "}" && endOfLine(stream)) {
+ return pushContext(state, stream, "block", 0);
+ }
+ if (type == "variable-name") {
+ if (stream.string.match(/^\s?\$[\w-\.\[\]\'\"]+$/) || wordIsBlock(firstWordOfLine(stream))) {
+ return pushContext(state, stream, "variableName");
+ }
+ else {
+ return pushContext(state, stream, "variableName", 0);
+ }
+ }
+ if (type == "=") {
+ if (!endOfLine(stream) && !wordIsBlock(firstWordOfLine(stream))) {
+ return pushContext(state, stream, "block", 0);
+ }
+ return pushContext(state, stream, "block");
+ }
+ if (type == "*") {
+ if (endOfLine(stream) || stream.match(/\s*(,|\.|#|\[|:|{)/,false)) {
+ override = "tag";
+ return pushContext(state, stream, "block");
+ }
+ }
+ if (typeIsPseudo(type, stream)) {
+ return pushContext(state, stream, "pseudo");
+ }
+ if (/@(font-face|media|supports|(-moz-)?document)/.test(type)) {
+ return pushContext(state, stream, endOfLine(stream) ? "block" : "atBlock");
+ }
+ if (/@(-(moz|ms|o|webkit)-)?keyframes$/.test(type)) {
+ return pushContext(state, stream, "keyframes");
+ }
+ if (/@extends?/.test(type)) {
+ return pushContext(state, stream, "extend", 0);
+ }
+ if (type && type.charAt(0) == "@") {
+
+ // Property Lookup
+ if (stream.indentation() > 0 && wordIsProperty(stream.current().slice(1))) {
+ override = "variable-2";
+ return "block";
+ }
+ if (/(@import|@require|@charset)/.test(type)) {
+ return pushContext(state, stream, "block", 0);
+ }
+ return pushContext(state, stream, "block");
+ }
+ if (type == "reference" && endOfLine(stream)) {
+ return pushContext(state, stream, "block");
+ }
+ if (type == "(") {
+ return pushContext(state, stream, "parens");
+ }
+
+ if (type == "vendor-prefixes") {
+ return pushContext(state, stream, "vendorPrefixes");
+ }
+ if (type == "word") {
+ var word = stream.current();
+ override = wordAsValue(word);
+
+ if (override == "property") {
+ if (startOfLine(stream)) {
+ return pushContext(state, stream, "block", 0);
+ } else {
+ override = "atom";
+ return "block";
+ }
+ }
+
+ if (override == "tag") {
+
+ // tag is a css value
+ if (/embed|menu|pre|progress|sub|table/.test(word)) {
+ if (wordIsProperty(firstWordOfLine(stream))) {
+ override = "atom";
+ return "block";
+ }
+ }
+
+ // tag is an attribute
+ if (stream.string.match(new RegExp("\\[\\s*" + word + "|" + word +"\\s*\\]"))) {
+ override = "atom";
+ return "block";
+ }
+
+ // tag is a variable
+ if (tagVariablesRegexp.test(word)) {
+ if ((startOfLine(stream) && stream.string.match(/=/)) ||
+ (!startOfLine(stream) &&
+ !stream.string.match(/^(\s*\.|#|\&|\[|\/|>|\*)/) &&
+ !wordIsTag(firstWordOfLine(stream)))) {
+ override = "variable-2";
+ if (wordIsBlock(firstWordOfLine(stream))) return "block";
+ return pushContext(state, stream, "block", 0);
+ }
+ }
+
+ if (endOfLine(stream)) return pushContext(state, stream, "block");
+ }
+ if (override == "block-keyword") {
+ override = "keyword";
+
+ // Postfix conditionals
+ if (stream.current(/(if|unless)/) && !startOfLine(stream)) {
+ return "block";
+ }
+ return pushContext(state, stream, "block");
+ }
+ if (word == "return") return pushContext(state, stream, "block", 0);
+
+ // Placeholder selector
+ if (override == "variable-2" && stream.string.match(/^\s?\$[\w-\.\[\]\'\"]+$/)) {
+ return pushContext(state, stream, "block");
+ }
+ }
+ return state.context.type;
+ };
+
+
+ /**
+ * Parens
+ */
+ states.parens = function(type, stream, state) {
+ if (type == "(") return pushContext(state, stream, "parens");
+ if (type == ")") {
+ if (state.context.prev.type == "parens") {
+ return popContext(state);
+ }
+ if ((stream.string.match(/^[a-z][\w-]*\(/i) && endOfLine(stream)) ||
+ wordIsBlock(firstWordOfLine(stream)) ||
+ /(\.|#|:|\[|\*|&|>|~|\+|\/)/.test(firstWordOfLine(stream)) ||
+ (!stream.string.match(/^-?[a-z][\w-\.\[\]\'\"]*\s*=/) &&
+ wordIsTag(firstWordOfLine(stream)))) {
+ return pushContext(state, stream, "block");
+ }
+ if (stream.string.match(/^[\$-]?[a-z][\w-\.\[\]\'\"]*\s*=/) ||
+ stream.string.match(/^\s*(\(|\)|[0-9])/) ||
+ stream.string.match(/^\s+[a-z][\w-]*\(/i) ||
+ stream.string.match(/^\s+[\$-]?[a-z]/i)) {
+ return pushContext(state, stream, "block", 0);
+ }
+ if (endOfLine(stream)) return pushContext(state, stream, "block");
+ else return pushContext(state, stream, "block", 0);
+ }
+ if (type && type.charAt(0) == "@" && wordIsProperty(stream.current().slice(1))) {
+ override = "variable-2";
+ }
+ if (type == "word") {
+ var word = stream.current();
+ override = wordAsValue(word);
+ if (override == "tag" && tagVariablesRegexp.test(word)) {
+ override = "variable-2";
+ }
+ if (override == "property" || word == "to") override = "atom";
+ }
+ if (type == "variable-name") {
+ return pushContext(state, stream, "variableName");
+ }
+ if (typeIsPseudo(type, stream)) {
+ return pushContext(state, stream, "pseudo");
+ }
+ return state.context.type;
+ };
+
+
+ /**
+ * Vendor prefixes
+ */
+ states.vendorPrefixes = function(type, stream, state) {
+ if (type == "word") {
+ override = "property";
+ return pushContext(state, stream, "block", 0);
+ }
+ return popContext(state);
+ };
+
+
+ /**
+ * Pseudo
+ */
+ states.pseudo = function(type, stream, state) {
+ if (!wordIsProperty(firstWordOfLine(stream.string))) {
+ stream.match(/^[a-z-]+/);
+ override = "variable-3";
+ if (endOfLine(stream)) return pushContext(state, stream, "block");
+ return popContext(state);
+ }
+ return popAndPass(type, stream, state);
+ };
+
+
+ /**
+ * atBlock
+ */
+ states.atBlock = function(type, stream, state) {
+ if (type == "(") return pushContext(state, stream, "atBlock_parens");
+ if (typeIsBlock(type, stream)) {
+ return pushContext(state, stream, "block");
+ }
+ if (typeIsInterpolation(type, stream)) {
+ return pushContext(state, stream, "interpolation");
+ }
+ if (type == "word") {
+ var word = stream.current().toLowerCase();
+ if (/^(only|not|and|or)$/.test(word))
+ override = "keyword";
+ else if (documentTypes.hasOwnProperty(word))
+ override = "tag";
+ else if (mediaTypes.hasOwnProperty(word))
+ override = "attribute";
+ else if (mediaFeatures.hasOwnProperty(word))
+ override = "property";
+ else if (nonStandardPropertyKeywords.hasOwnProperty(word))
+ override = "string-2";
+ else override = wordAsValue(stream.current());
+ if (override == "tag" && endOfLine(stream)) {
+ return pushContext(state, stream, "block");
+ }
+ }
+ if (type == "operator" && /^(not|and|or)$/.test(stream.current())) {
+ override = "keyword";
+ }
+ return state.context.type;
+ };
+
+ states.atBlock_parens = function(type, stream, state) {
+ if (type == "{" || type == "}") return state.context.type;
+ if (type == ")") {
+ if (endOfLine(stream)) return pushContext(state, stream, "block");
+ else return pushContext(state, stream, "atBlock");
+ }
+ if (type == "word") {
+ var word = stream.current().toLowerCase();
+ override = wordAsValue(word);
+ if (/^(max|min)/.test(word)) override = "property";
+ if (override == "tag") {
+ tagVariablesRegexp.test(word) ? override = "variable-2" : override = "atom";
+ }
+ return state.context.type;
+ }
+ return states.atBlock(type, stream, state);
+ };
+
+
+ /**
+ * Keyframes
+ */
+ states.keyframes = function(type, stream, state) {
+ if (stream.indentation() == "0" && ((type == "}" && startOfLine(stream)) || type == "]" || type == "hash"
+ || type == "qualifier" || wordIsTag(stream.current()))) {
+ return popAndPass(type, stream, state);
+ }
+ if (type == "{") return pushContext(state, stream, "keyframes");
+ if (type == "}") {
+ if (startOfLine(stream)) return popContext(state, true);
+ else return pushContext(state, stream, "keyframes");
+ }
+ if (type == "unit" && /^[0-9]+\%$/.test(stream.current())) {
+ return pushContext(state, stream, "keyframes");
+ }
+ if (type == "word") {
+ override = wordAsValue(stream.current());
+ if (override == "block-keyword") {
+ override = "keyword";
+ return pushContext(state, stream, "keyframes");
+ }
+ }
+ if (/@(font-face|media|supports|(-moz-)?document)/.test(type)) {
+ return pushContext(state, stream, endOfLine(stream) ? "block" : "atBlock");
+ }
+ if (type == "mixin") {
+ return pushContext(state, stream, "block", 0);
+ }
+ return state.context.type;
+ };
+
+
+ /**
+ * Interpolation
+ */
+ states.interpolation = function(type, stream, state) {
+ if (type == "{") popContext(state) && pushContext(state, stream, "block");
+ if (type == "}") {
+ if (stream.string.match(/^\s*(\.|#|:|\[|\*|&|>|~|\+|\/)/i) ||
+ (stream.string.match(/^\s*[a-z]/i) && wordIsTag(firstWordOfLine(stream)))) {
+ return pushContext(state, stream, "block");
+ }
+ if (!stream.string.match(/^(\{|\s*\&)/) ||
+ stream.match(/\s*[\w-]/,false)) {
+ return pushContext(state, stream, "block", 0);
+ }
+ return pushContext(state, stream, "block");
+ }
+ if (type == "variable-name") {
+ return pushContext(state, stream, "variableName", 0);
+ }
+ if (type == "word") {
+ override = wordAsValue(stream.current());
+ if (override == "tag") override = "atom";
+ }
+ return state.context.type;
+ };
+
+
+ /**
+ * Extend/s
+ */
+ states.extend = function(type, stream, state) {
+ if (type == "[" || type == "=") return "extend";
+ if (type == "]") return popContext(state);
+ if (type == "word") {
+ override = wordAsValue(stream.current());
+ return "extend";
+ }
+ return popContext(state);
+ };
+
+
+ /**
+ * Variable name
+ */
+ states.variableName = function(type, stream, state) {
+ if (type == "string" || type == "[" || type == "]" || stream.current().match(/^(\.|\$)/)) {
+ if (stream.current().match(/^\.[\w-]+/i)) override = "variable-2";
+ return "variableName";
+ }
+ return popAndPass(type, stream, state);
+ };
+
+
+ return {
+ startState: function(base) {
+ return {
+ tokenize: null,
+ state: "block",
+ context: new Context("block", base || 0, null)
+ };
+ },
+ token: function(stream, state) {
+ if (!state.tokenize && stream.eatSpace()) return null;
+ style = (state.tokenize || tokenBase)(stream, state);
+ if (style && typeof style == "object") {
+ type = style[1];
+ style = style[0];
+ }
+ override = style;
+ state.state = states[state.state](type, stream, state);
+ return override;
+ },
+ indent: function(state, textAfter, line) {
+
+ var cx = state.context,
+ ch = textAfter && textAfter.charAt(0),
+ indent = cx.indent,
+ lineFirstWord = firstWordOfLine(textAfter),
+ lineIndent = line.match(/^\s*/)[0].replace(/\t/g, indentUnitString).length,
+ prevLineFirstWord = state.context.prev ? state.context.prev.line.firstWord : "",
+ prevLineIndent = state.context.prev ? state.context.prev.line.indent : lineIndent;
+
+ if (cx.prev &&
+ (ch == "}" && (cx.type == "block" || cx.type == "atBlock" || cx.type == "keyframes") ||
+ ch == ")" && (cx.type == "parens" || cx.type == "atBlock_parens") ||
+ ch == "{" && (cx.type == "at"))) {
+ indent = cx.indent - indentUnit;
+ } else if (!(/(\})/.test(ch))) {
+ if (/@|\$|\d/.test(ch) ||
+ /^\{/.test(textAfter) ||
+/^\s*\/(\/|\*)/.test(textAfter) ||
+ /^\s*\/\*/.test(prevLineFirstWord) ||
+ /^\s*[\w-\.\[\]\'\"]+\s*(\?|:|\+)?=/i.test(textAfter) ||
+/^(\+|-)?[a-z][\w-]*\(/i.test(textAfter) ||
+/^return/.test(textAfter) ||
+ wordIsBlock(lineFirstWord)) {
+ indent = lineIndent;
+ } else if (/(\.|#|:|\[|\*|&|>|~|\+|\/)/.test(ch) || wordIsTag(lineFirstWord)) {
+ if (/\,\s*$/.test(prevLineFirstWord)) {
+ indent = prevLineIndent;
+ } else if (/^\s+/.test(line) && (/(\.|#|:|\[|\*|&|>|~|\+|\/)/.test(prevLineFirstWord) || wordIsTag(prevLineFirstWord))) {
+ indent = lineIndent <= prevLineIndent ? prevLineIndent : prevLineIndent + indentUnit;
+ } else {
+ indent = lineIndent;
+ }
+ } else if (!/,\s*$/.test(line) && (wordIsVendorPrefix(lineFirstWord) || wordIsProperty(lineFirstWord))) {
+ if (wordIsBlock(prevLineFirstWord)) {
+ indent = lineIndent <= prevLineIndent ? prevLineIndent : prevLineIndent + indentUnit;
+ } else if (/^\{/.test(prevLineFirstWord)) {
+ indent = lineIndent <= prevLineIndent ? lineIndent : prevLineIndent + indentUnit;
+ } else if (wordIsVendorPrefix(prevLineFirstWord) || wordIsProperty(prevLineFirstWord)) {
+ indent = lineIndent >= prevLineIndent ? prevLineIndent : lineIndent;
+ } else if (/^(\.|#|:|\[|\*|&|@|\+|\-|>|~|\/)/.test(prevLineFirstWord) ||
+ /=\s*$/.test(prevLineFirstWord) ||
+ wordIsTag(prevLineFirstWord) ||
+ /^\$[\w-\.\[\]\'\"]/.test(prevLineFirstWord)) {
+ indent = prevLineIndent + indentUnit;
+ } else {
+ indent = lineIndent;
+ }
+ }
+ }
+ return indent;
+ },
+ electricChars: "}",
+ blockCommentStart: "/*",
+ blockCommentEnd: "*/",
+ blockCommentContinue: " * ",
+ lineComment: "//",
+ fold: "indent"
+ };
+ });
+
+ // developer.mozilla.org/en-US/docs/Web/HTML/Element
+ var tagKeywords_ = ["a","abbr","address","area","article","aside","audio", "b", "base","bdi", "bdo","bgsound","blockquote","body","br","button","canvas","caption","cite", "code","col","colgroup","data","datalist","dd","del","details","dfn","div", "dl","dt","em","embed","fieldset","figcaption","figure","footer","form","h1", "h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","iframe", "img","input","ins","kbd","keygen","label","legend","li","link","main","map", "mark","marquee","menu","menuitem","meta","meter","nav","nobr","noframes", "noscript","object","ol","optgroup","option","output","p","param","pre", "progress","q","rp","rt","ruby","s","samp","script","section","select", "small","source","span","strong","style","sub","summary","sup","table","tbody","td","textarea","tfoot","th","thead","time","tr","track", "u","ul","var","video"];
+
+ // github.com/codemirror/CodeMirror/blob/master/mode/css/css.js
+ // Note, "url-prefix" should precede "url" in order to match correctly in documentTypesRegexp
+ var documentTypes_ = ["domain", "regexp", "url-prefix", "url"];
+ var mediaTypes_ = ["all","aural","braille","handheld","print","projection","screen","tty","tv","embossed"];
+ var mediaFeatures_ = ["width","min-width","max-width","height","min-height","max-height","device-width","min-device-width","max-device-width","device-height","min-device-height","max-device-height","aspect-ratio","min-aspect-ratio","max-aspect-ratio","device-aspect-ratio","min-device-aspect-ratio","max-device-aspect-ratio","color","min-color","max-color","color-index","min-color-index","max-color-index","monochrome","min-monochrome","max-monochrome","resolution","min-resolution","max-resolution","scan","grid","dynamic-range","video-dynamic-range"];
+ var propertyKeywords_ = ["align-content","align-items","align-self","alignment-adjust","alignment-baseline","anchor-point","animation","animation-delay","animation-direction","animation-duration","animation-fill-mode","animation-iteration-count","animation-name","animation-play-state","animation-timing-function","appearance","azimuth","backface-visibility","background","background-attachment","background-clip","background-color","background-image","background-origin","background-position","background-repeat","background-size","baseline-shift","binding","bleed","bookmark-label","bookmark-level","bookmark-state","bookmark-target","border","border-bottom","border-bottom-color","border-bottom-left-radius","border-bottom-right-radius","border-bottom-style","border-bottom-width","border-collapse","border-color","border-image","border-image-outset","border-image-repeat","border-image-slice","border-image-source","border-image-width","border-left","border-left-color","border-left-style","border-left-width","border-radius","border-right","border-right-color","border-right-style","border-right-width","border-spacing","border-style","border-top","border-top-color","border-top-left-radius","border-top-right-radius","border-top-style","border-top-width","border-width","bottom","box-decoration-break","box-shadow","box-sizing","break-after","break-before","break-inside","caption-side","clear","clip","color","color-profile","column-count","column-fill","column-gap","column-rule","column-rule-color","column-rule-style","column-rule-width","column-span","column-width","columns","content","counter-increment","counter-reset","crop","cue","cue-after","cue-before","cursor","direction","display","dominant-baseline","drop-initial-after-adjust","drop-initial-after-align","drop-initial-before-adjust","drop-initial-before-align","drop-initial-size","drop-initial-value","elevation","empty-cells","fit","fit-position","flex","flex-basis","flex-direction","flex-flow","flex-grow","flex-shrink","flex-wrap","float","float-offset","flow-from","flow-into","font","font-feature-settings","font-family","font-kerning","font-language-override","font-size","font-size-adjust","font-stretch","font-style","font-synthesis","font-variant","font-variant-alternates","font-variant-caps","font-variant-east-asian","font-variant-ligatures","font-variant-numeric","font-variant-position","font-weight","grid","grid-area","grid-auto-columns","grid-auto-flow","grid-auto-position","grid-auto-rows","grid-column","grid-column-end","grid-column-start","grid-row","grid-row-end","grid-row-start","grid-template","grid-template-areas","grid-template-columns","grid-template-rows","hanging-punctuation","height","hyphens","icon","image-orientation","image-rendering","image-resolution","inline-box-align","justify-content","left","letter-spacing","line-break","line-height","line-stacking","line-stacking-ruby","line-stacking-shift","line-stacking-strategy","list-style","list-style-image","list-style-position","list-style-type","margin","margin-bottom","margin-left","margin-right","margin-top","marker-offset","marks","marquee-direction","marquee-loop","marquee-play-count","marquee-speed","marquee-style","max-height","max-width","min-height","min-width","move-to","nav-down","nav-index","nav-left","nav-right","nav-up","object-fit","object-position","opacity","order","orphans","outline","outline-color","outline-offset","outline-style","outline-width","overflow","overflow-style","overflow-wrap","overflow-x","overflow-y","padding","padding-bottom","padding-left","padding-right","padding-top","page","page-break-after","page-break-before","page-break-inside","page-policy","pause","pause-after","pause-before","perspective","perspective-origin","pitch","pitch-range","play-during","position","presentation-level","punctuation-trim","quotes","region-break-after","region-break-before","region-break-inside","region-fragment","rendering-intent","resize","rest","rest-after","rest-before","richness","right","rotation","rotation-point","ruby-align","ruby-overhang","ruby-position","ruby-span","shape-image-threshold","shape-inside","shape-margin","shape-outside","size","speak","speak-as","speak-header","speak-numeral","speak-punctuation","speech-rate","stress","string-set","tab-size","table-layout","target","target-name","target-new","target-position","text-align","text-align-last","text-decoration","text-decoration-color","text-decoration-line","text-decoration-skip","text-decoration-style","text-emphasis","text-emphasis-color","text-emphasis-position","text-emphasis-style","text-height","text-indent","text-justify","text-outline","text-overflow","text-shadow","text-size-adjust","text-space-collapse","text-transform","text-underline-position","text-wrap","top","transform","transform-origin","transform-style","transition","transition-delay","transition-duration","transition-property","transition-timing-function","unicode-bidi","vertical-align","visibility","voice-balance","voice-duration","voice-family","voice-pitch","voice-range","voice-rate","voice-stress","voice-volume","volume","white-space","widows","width","will-change","word-break","word-spacing","word-wrap","z-index","clip-path","clip-rule","mask","enable-background","filter","flood-color","flood-opacity","lighting-color","stop-color","stop-opacity","pointer-events","color-interpolation","color-interpolation-filters","color-rendering","fill","fill-opacity","fill-rule","image-rendering","marker","marker-end","marker-mid","marker-start","shape-rendering","stroke","stroke-dasharray","stroke-dashoffset","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke-width","text-rendering","baseline-shift","dominant-baseline","glyph-orientation-horizontal","glyph-orientation-vertical","text-anchor","writing-mode","font-smoothing","osx-font-smoothing"];
+ var nonStandardPropertyKeywords_ = ["scrollbar-arrow-color","scrollbar-base-color","scrollbar-dark-shadow-color","scrollbar-face-color","scrollbar-highlight-color","scrollbar-shadow-color","scrollbar-3d-light-color","scrollbar-track-color","shape-inside","searchfield-cancel-button","searchfield-decoration","searchfield-results-button","searchfield-results-decoration","zoom"];
+ var fontProperties_ = ["font-family","src","unicode-range","font-variant","font-feature-settings","font-stretch","font-weight","font-style"];
+ var colorKeywords_ = ["aliceblue","antiquewhite","aqua","aquamarine","azure","beige","bisque","black","blanchedalmond","blue","blueviolet","brown","burlywood","cadetblue","chartreuse","chocolate","coral","cornflowerblue","cornsilk","crimson","cyan","darkblue","darkcyan","darkgoldenrod","darkgray","darkgreen","darkkhaki","darkmagenta","darkolivegreen","darkorange","darkorchid","darkred","darksalmon","darkseagreen","darkslateblue","darkslategray","darkturquoise","darkviolet","deeppink","deepskyblue","dimgray","dodgerblue","firebrick","floralwhite","forestgreen","fuchsia","gainsboro","ghostwhite","gold","goldenrod","gray","grey","green","greenyellow","honeydew","hotpink","indianred","indigo","ivory","khaki","lavender","lavenderblush","lawngreen","lemonchiffon","lightblue","lightcoral","lightcyan","lightgoldenrodyellow","lightgray","lightgreen","lightpink","lightsalmon","lightseagreen","lightskyblue","lightslategray","lightsteelblue","lightyellow","lime","limegreen","linen","magenta","maroon","mediumaquamarine","mediumblue","mediumorchid","mediumpurple","mediumseagreen","mediumslateblue","mediumspringgreen","mediumturquoise","mediumvioletred","midnightblue","mintcream","mistyrose","moccasin","navajowhite","navy","oldlace","olive","olivedrab","orange","orangered","orchid","palegoldenrod","palegreen","paleturquoise","palevioletred","papayawhip","peachpuff","peru","pink","plum","powderblue","purple","rebeccapurple","red","rosybrown","royalblue","saddlebrown","salmon","sandybrown","seagreen","seashell","sienna","silver","skyblue","slateblue","slategray","snow","springgreen","steelblue","tan","teal","thistle","tomato","turquoise","violet","wheat","white","whitesmoke","yellow","yellowgreen"];
+ var valueKeywords_ = ["above","absolute","activeborder","additive","activecaption","afar","after-white-space","ahead","alias","all","all-scroll","alphabetic","alternate","always","amharic","amharic-abegede","antialiased","appworkspace","arabic-indic","armenian","asterisks","attr","auto","avoid","avoid-column","avoid-page","avoid-region","background","backwards","baseline","below","bidi-override","binary","bengali","blink","block","block-axis","bold","bolder","border","border-box","both","bottom","break","break-all","break-word","bullets","button","button-bevel","buttonface","buttonhighlight","buttonshadow","buttontext","calc","cambodian","capitalize","caps-lock-indicator","caption","captiontext","caret","cell","center","checkbox","circle","cjk-decimal","cjk-earthly-branch","cjk-heavenly-stem","cjk-ideographic","clear","clip","close-quote","col-resize","collapse","column","compact","condensed","conic-gradient","contain","content","contents","content-box","context-menu","continuous","copy","counter","counters","cover","crop","cross","crosshair","currentcolor","cursive","cyclic","dashed","decimal","decimal-leading-zero","default","default-button","destination-atop","destination-in","destination-out","destination-over","devanagari","disc","discard","disclosure-closed","disclosure-open","document","dot-dash","dot-dot-dash","dotted","double","down","e-resize","ease","ease-in","ease-in-out","ease-out","element","ellipse","ellipsis","embed","end","ethiopic","ethiopic-abegede","ethiopic-abegede-am-et","ethiopic-abegede-gez","ethiopic-abegede-ti-er","ethiopic-abegede-ti-et","ethiopic-halehame-aa-er","ethiopic-halehame-aa-et","ethiopic-halehame-am-et","ethiopic-halehame-gez","ethiopic-halehame-om-et","ethiopic-halehame-sid-et","ethiopic-halehame-so-et","ethiopic-halehame-ti-er","ethiopic-halehame-ti-et","ethiopic-halehame-tig","ethiopic-numeric","ew-resize","expanded","extends","extra-condensed","extra-expanded","fantasy","fast","fill","fixed","flat","flex","footnotes","forwards","from","geometricPrecision","georgian","graytext","groove","gujarati","gurmukhi","hand","hangul","hangul-consonant","hebrew","help","hidden","hide","high","higher","highlight","highlighttext","hiragana","hiragana-iroha","horizontal","hsl","hsla","icon","ignore","inactiveborder","inactivecaption","inactivecaptiontext","infinite","infobackground","infotext","inherit","initial","inline","inline-axis","inline-block","inline-flex","inline-table","inset","inside","intrinsic","invert","italic","japanese-formal","japanese-informal","justify","kannada","katakana","katakana-iroha","keep-all","khmer","korean-hangul-formal","korean-hanja-formal","korean-hanja-informal","landscape","lao","large","larger","left","level","lighter","line-through","linear","linear-gradient","lines","list-item","listbox","listitem","local","logical","loud","lower","lower-alpha","lower-armenian","lower-greek","lower-hexadecimal","lower-latin","lower-norwegian","lower-roman","lowercase","ltr","malayalam","match","matrix","matrix3d","media-controls-background","media-current-time-display","media-fullscreen-button","media-mute-button","media-play-button","media-return-to-realtime-button","media-rewind-button","media-seek-back-button","media-seek-forward-button","media-slider","media-sliderthumb","media-time-remaining-display","media-volume-slider","media-volume-slider-container","media-volume-sliderthumb","medium","menu","menulist","menulist-button","menulist-text","menulist-textfield","menutext","message-box","middle","min-intrinsic","mix","mongolian","monospace","move","multiple","myanmar","n-resize","narrower","ne-resize","nesw-resize","no-close-quote","no-drop","no-open-quote","no-repeat","none","normal","not-allowed","nowrap","ns-resize","numbers","numeric","nw-resize","nwse-resize","oblique","octal","open-quote","optimizeLegibility","optimizeSpeed","oriya","oromo","outset","outside","outside-shape","overlay","overline","padding","padding-box","painted","page","paused","persian","perspective","plus-darker","plus-lighter","pointer","polygon","portrait","pre","pre-line","pre-wrap","preserve-3d","progress","push-button","radial-gradient","radio","read-only","read-write","read-write-plaintext-only","rectangle","region","relative","repeat","repeating-linear-gradient","repeating-radial-gradient","repeating-conic-gradient","repeat-x","repeat-y","reset","reverse","rgb","rgba","ridge","right","rotate","rotate3d","rotateX","rotateY","rotateZ","round","row-resize","rtl","run-in","running","s-resize","sans-serif","scale","scale3d","scaleX","scaleY","scaleZ","scroll","scrollbar","scroll-position","se-resize","searchfield","searchfield-cancel-button","searchfield-decoration","searchfield-results-button","searchfield-results-decoration","semi-condensed","semi-expanded","separate","serif","show","sidama","simp-chinese-formal","simp-chinese-informal","single","skew","skewX","skewY","skip-white-space","slide","slider-horizontal","slider-vertical","sliderthumb-horizontal","sliderthumb-vertical","slow","small","small-caps","small-caption","smaller","solid","somali","source-atop","source-in","source-out","source-over","space","spell-out","square","square-button","standard","start","static","status-bar","stretch","stroke","sub","subpixel-antialiased","super","sw-resize","symbolic","symbols","table","table-caption","table-cell","table-column","table-column-group","table-footer-group","table-header-group","table-row","table-row-group","tamil","telugu","text","text-bottom","text-top","textarea","textfield","thai","thick","thin","threeddarkshadow","threedface","threedhighlight","threedlightshadow","threedshadow","tibetan","tigre","tigrinya-er","tigrinya-er-abegede","tigrinya-et","tigrinya-et-abegede","to","top","trad-chinese-formal","trad-chinese-informal","translate","translate3d","translateX","translateY","translateZ","transparent","ultra-condensed","ultra-expanded","underline","up","upper-alpha","upper-armenian","upper-greek","upper-hexadecimal","upper-latin","upper-norwegian","upper-roman","uppercase","urdu","url","var","vertical","vertical-text","visible","visibleFill","visiblePainted","visibleStroke","visual","w-resize","wait","wave","wider","window","windowframe","windowtext","words","x-large","x-small","xor","xx-large","xx-small","bicubic","optimizespeed","grayscale","row","row-reverse","wrap","wrap-reverse","column-reverse","flex-start","flex-end","space-between","space-around", "unset"];
+
+ var wordOperatorKeywords_ = ["in","and","or","not","is not","is a","is","isnt","defined","if unless"],
+ blockKeywords_ = ["for","if","else","unless", "from", "to"],
+ commonAtoms_ = ["null","true","false","href","title","type","not-allowed","readonly","disabled"],
+ commonDef_ = ["@font-face", "@keyframes", "@media", "@viewport", "@page", "@host", "@supports", "@block", "@css"];
+
+ var hintWords = tagKeywords_.concat(documentTypes_,mediaTypes_,mediaFeatures_,
+ propertyKeywords_,nonStandardPropertyKeywords_,
+ colorKeywords_,valueKeywords_,fontProperties_,
+ wordOperatorKeywords_,blockKeywords_,
+ commonAtoms_,commonDef_);
+
+ function wordRegexp(words) {
+ words = words.sort(function(a,b){return b > a;});
+ return new RegExp("^((" + words.join(")|(") + "))\\b");
+ }
+
+ function keySet(array) {
+ var keys = {};
+ for (var i = 0; i < array.length; ++i) keys[array[i]] = true;
+ return keys;
+ }
+
+ function escapeRegExp(text) {
+ return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
+ }
+
+ CodeMirror.registerHelper("hintWords", "stylus", hintWords);
+ CodeMirror.defineMIME("text/x-styl", "stylus");
+});
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/swift/swift.js b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/swift/swift.js
new file mode 100644
index 0000000000..55e31e2708
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/swift/swift.js
@@ -0,0 +1,223 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: https://codemirror.net/LICENSE
+
+// Swift mode created by Michael Kaminsky https://github.com/mkaminsky11
+
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object")
+ mod(require("../../lib/codemirror"))
+ else if (typeof define == "function" && define.amd)
+ define(["../../lib/codemirror"], mod)
+ else
+ mod(CodeMirror)
+})(function(CodeMirror) {
+ "use strict"
+
+ function wordSet(words) {
+ var set = {}
+ for (var i = 0; i < words.length; i++) set[words[i]] = true
+ return set
+ }
+
+ var keywords = wordSet(["_","var","let","class","enum","extension","import","protocol","struct","func","typealias","associatedtype",
+ "open","public","internal","fileprivate","private","deinit","init","new","override","self","subscript","super",
+ "convenience","dynamic","final","indirect","lazy","required","static","unowned","unowned(safe)","unowned(unsafe)","weak","as","is",
+ "break","case","continue","default","else","fallthrough","for","guard","if","in","repeat","switch","where","while",
+ "defer","return","inout","mutating","nonmutating","catch","do","rethrows","throw","throws","try","didSet","get","set","willSet",
+ "assignment","associativity","infix","left","none","operator","postfix","precedence","precedencegroup","prefix","right",
+ "Any","AnyObject","Type","dynamicType","Self","Protocol","__COLUMN__","__FILE__","__FUNCTION__","__LINE__"])
+ var definingKeywords = wordSet(["var","let","class","enum","extension","import","protocol","struct","func","typealias","associatedtype","for"])
+ var atoms = wordSet(["true","false","nil","self","super","_"])
+ var types = wordSet(["Array","Bool","Character","Dictionary","Double","Float","Int","Int8","Int16","Int32","Int64","Never","Optional","Set","String",
+ "UInt8","UInt16","UInt32","UInt64","Void"])
+ var operators = "+-/*%=|&<>~^?!"
+ var punc = ":;,.(){}[]"
+ var binary = /^\-?0b[01][01_]*/
+ var octal = /^\-?0o[0-7][0-7_]*/
+ var hexadecimal = /^\-?0x[\dA-Fa-f][\dA-Fa-f_]*(?:(?:\.[\dA-Fa-f][\dA-Fa-f_]*)?[Pp]\-?\d[\d_]*)?/
+ var decimal = /^\-?\d[\d_]*(?:\.\d[\d_]*)?(?:[Ee]\-?\d[\d_]*)?/
+ var identifier = /^\$\d+|(`?)[_A-Za-z][_A-Za-z$0-9]*\1/
+ var property = /^\.(?:\$\d+|(`?)[_A-Za-z][_A-Za-z$0-9]*\1)/
+ var instruction = /^\#[A-Za-z]+/
+ var attribute = /^@(?:\$\d+|(`?)[_A-Za-z][_A-Za-z$0-9]*\1)/
+ //var regexp = /^\/(?!\s)(?:\/\/)?(?:\\.|[^\/])+\//
+
+ function tokenBase(stream, state, prev) {
+ if (stream.sol()) state.indented = stream.indentation()
+ if (stream.eatSpace()) return null
+
+ var ch = stream.peek()
+ if (ch == "/") {
+ if (stream.match("//")) {
+ stream.skipToEnd()
+ return "comment"
+ }
+ if (stream.match("/*")) {
+ state.tokenize.push(tokenComment)
+ return tokenComment(stream, state)
+ }
+ }
+ if (stream.match(instruction)) return "builtin"
+ if (stream.match(attribute)) return "attribute"
+ if (stream.match(binary)) return "number"
+ if (stream.match(octal)) return "number"
+ if (stream.match(hexadecimal)) return "number"
+ if (stream.match(decimal)) return "number"
+ if (stream.match(property)) return "property"
+ if (operators.indexOf(ch) > -1) {
+ stream.next()
+ return "operator"
+ }
+ if (punc.indexOf(ch) > -1) {
+ stream.next()
+ stream.match("..")
+ return "punctuation"
+ }
+ var stringMatch
+ if (stringMatch = stream.match(/("""|"|')/)) {
+ var tokenize = tokenString.bind(null, stringMatch[0])
+ state.tokenize.push(tokenize)
+ return tokenize(stream, state)
+ }
+
+ if (stream.match(identifier)) {
+ var ident = stream.current()
+ if (types.hasOwnProperty(ident)) return "variable-2"
+ if (atoms.hasOwnProperty(ident)) return "atom"
+ if (keywords.hasOwnProperty(ident)) {
+ if (definingKeywords.hasOwnProperty(ident))
+ state.prev = "define"
+ return "keyword"
+ }
+ if (prev == "define") return "def"
+ return "variable"
+ }
+
+ stream.next()
+ return null
+ }
+
+ function tokenUntilClosingParen() {
+ var depth = 0
+ return function(stream, state, prev) {
+ var inner = tokenBase(stream, state, prev)
+ if (inner == "punctuation") {
+ if (stream.current() == "(") ++depth
+ else if (stream.current() == ")") {
+ if (depth == 0) {
+ stream.backUp(1)
+ state.tokenize.pop()
+ return state.tokenize[state.tokenize.length - 1](stream, state)
+ }
+ else --depth
+ }
+ }
+ return inner
+ }
+ }
+
+ function tokenString(openQuote, stream, state) {
+ var singleLine = openQuote.length == 1
+ var ch, escaped = false
+ while (ch = stream.peek()) {
+ if (escaped) {
+ stream.next()
+ if (ch == "(") {
+ state.tokenize.push(tokenUntilClosingParen())
+ return "string"
+ }
+ escaped = false
+ } else if (stream.match(openQuote)) {
+ state.tokenize.pop()
+ return "string"
+ } else {
+ stream.next()
+ escaped = ch == "\\"
+ }
+ }
+ if (singleLine) {
+ state.tokenize.pop()
+ }
+ return "string"
+ }
+
+ function tokenComment(stream, state) {
+ var ch
+ while (true) {
+ stream.match(/^[^/*]+/, true)
+ ch = stream.next()
+ if (!ch) break
+ if (ch === "/" && stream.eat("*")) {
+ state.tokenize.push(tokenComment)
+ } else if (ch === "*" && stream.eat("/")) {
+ state.tokenize.pop()
+ }
+ }
+ return "comment"
+ }
+
+ function Context(prev, align, indented) {
+ this.prev = prev
+ this.align = align
+ this.indented = indented
+ }
+
+ function pushContext(state, stream) {
+ var align = stream.match(/^\s*($|\/[\/\*])/, false) ? null : stream.column() + 1
+ state.context = new Context(state.context, align, state.indented)
+ }
+
+ function popContext(state) {
+ if (state.context) {
+ state.indented = state.context.indented
+ state.context = state.context.prev
+ }
+ }
+
+ CodeMirror.defineMode("swift", function(config) {
+ return {
+ startState: function() {
+ return {
+ prev: null,
+ context: null,
+ indented: 0,
+ tokenize: []
+ }
+ },
+
+ token: function(stream, state) {
+ var prev = state.prev
+ state.prev = null
+ var tokenize = state.tokenize[state.tokenize.length - 1] || tokenBase
+ var style = tokenize(stream, state, prev)
+ if (!style || style == "comment") state.prev = prev
+ else if (!state.prev) state.prev = style
+
+ if (style == "punctuation") {
+ var bracket = /[\(\[\{]|([\]\)\}])/.exec(stream.current())
+ if (bracket) (bracket[1] ? popContext : pushContext)(state, stream)
+ }
+
+ return style
+ },
+
+ indent: function(state, textAfter) {
+ var cx = state.context
+ if (!cx) return 0
+ var closing = /^[\]\}\)]/.test(textAfter)
+ if (cx.align != null) return cx.align - (closing ? 1 : 0)
+ return cx.indented + (closing ? 0 : config.indentUnit)
+ },
+
+ electricInput: /^\s*[\)\}\]]$/,
+
+ lineComment: "//",
+ blockCommentStart: "/*",
+ blockCommentEnd: "*/",
+ fold: "brace",
+ closeBrackets: "()[]{}''\"\"``"
+ }
+ })
+
+ CodeMirror.defineMIME("text/x-swift","swift")
+});
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/tcl/tcl.js b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/tcl/tcl.js
new file mode 100644
index 0000000000..dec0662a60
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/tcl/tcl.js
@@ -0,0 +1,140 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: https://codemirror.net/LICENSE
+
+//tcl mode by Ford_Lawnmower :: Based on Velocity mode by Steve O'Hara
+
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
+ mod(require("../../lib/codemirror"));
+ else if (typeof define == "function" && define.amd) // AMD
+ define(["../../lib/codemirror"], mod);
+ else // Plain browser env
+ mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("tcl", function() {
+ function parseWords(str) {
+ var obj = {}, words = str.split(" ");
+ for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
+ return obj;
+ }
+ var keywords = parseWords("Tcl safe after append array auto_execok auto_import auto_load " +
+ "auto_mkindex auto_mkindex_old auto_qualify auto_reset bgerror " +
+ "binary break catch cd close concat continue dde eof encoding error " +
+ "eval exec exit expr fblocked fconfigure fcopy file fileevent filename " +
+ "filename flush for foreach format gets glob global history http if " +
+ "incr info interp join lappend lindex linsert list llength load lrange " +
+ "lreplace lsearch lset lsort memory msgcat namespace open package parray " +
+ "pid pkg::create pkg_mkIndex proc puts pwd re_syntax read regex regexp " +
+ "registry regsub rename resource return scan seek set socket source split " +
+ "string subst switch tcl_endOfWord tcl_findLibrary tcl_startOfNextWord " +
+ "tcl_wordBreakAfter tcl_startOfPreviousWord tcl_wordBreakBefore tcltest " +
+ "tclvars tell time trace unknown unset update uplevel upvar variable " +
+ "vwait");
+ var functions = parseWords("if elseif else and not or eq ne in ni for foreach while switch");
+ var isOperatorChar = /[+\-*&%=<>!?^\/\|]/;
+ function chain(stream, state, f) {
+ state.tokenize = f;
+ return f(stream, state);
+ }
+ function tokenBase(stream, state) {
+ var beforeParams = state.beforeParams;
+ state.beforeParams = false;
+ var ch = stream.next();
+ if ((ch == '"' || ch == "'") && state.inParams) {
+ return chain(stream, state, tokenString(ch));
+ } else if (/[\[\]{}\(\),;\.]/.test(ch)) {
+ if (ch == "(" && beforeParams) state.inParams = true;
+ else if (ch == ")") state.inParams = false;
+ return null;
+ } else if (/\d/.test(ch)) {
+ stream.eatWhile(/[\w\.]/);
+ return "number";
+ } else if (ch == "#") {
+ if (stream.eat("*"))
+ return chain(stream, state, tokenComment);
+ if (ch == "#" && stream.match(/ *\[ *\[/))
+ return chain(stream, state, tokenUnparsed);
+ stream.skipToEnd();
+ return "comment";
+ } else if (ch == '"') {
+ stream.skipTo(/"/);
+ return "comment";
+ } else if (ch == "$") {
+ stream.eatWhile(/[$_a-z0-9A-Z\.{:]/);
+ stream.eatWhile(/}/);
+ state.beforeParams = true;
+ return "builtin";
+ } else if (isOperatorChar.test(ch)) {
+ stream.eatWhile(isOperatorChar);
+ return "comment";
+ } else {
+ stream.eatWhile(/[\w\$_{}\xa1-\uffff]/);
+ var word = stream.current().toLowerCase();
+ if (keywords && keywords.propertyIsEnumerable(word))
+ return "keyword";
+ if (functions && functions.propertyIsEnumerable(word)) {
+ state.beforeParams = true;
+ return "keyword";
+ }
+ return null;
+ }
+ }
+ function tokenString(quote) {
+ return function(stream, state) {
+ var escaped = false, next, end = false;
+ while ((next = stream.next()) != null) {
+ if (next == quote && !escaped) {
+ end = true;
+ break;
+ }
+ escaped = !escaped && next == "\\";
+ }
+ if (end) state.tokenize = tokenBase;
+ return "string";
+ };
+ }
+ function tokenComment(stream, state) {
+ var maybeEnd = false, ch;
+ while (ch = stream.next()) {
+ if (ch == "#" && maybeEnd) {
+ state.tokenize = tokenBase;
+ break;
+ }
+ maybeEnd = (ch == "*");
+ }
+ return "comment";
+ }
+ function tokenUnparsed(stream, state) {
+ var maybeEnd = 0, ch;
+ while (ch = stream.next()) {
+ if (ch == "#" && maybeEnd == 2) {
+ state.tokenize = tokenBase;
+ break;
+ }
+ if (ch == "]")
+ maybeEnd++;
+ else if (ch != " ")
+ maybeEnd = 0;
+ }
+ return "meta";
+ }
+ return {
+ startState: function() {
+ return {
+ tokenize: tokenBase,
+ beforeParams: false,
+ inParams: false
+ };
+ },
+ token: function(stream, state) {
+ if (stream.eatSpace()) return null;
+ return state.tokenize(stream, state);
+ },
+ lineComment: "#"
+ };
+});
+CodeMirror.defineMIME("text/x-tcl", "tcl");
+
+});
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/textile/textile.js b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/textile/textile.js
new file mode 100644
index 0000000000..b378fb61f5
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/textile/textile.js
@@ -0,0 +1,469 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: https://codemirror.net/LICENSE
+
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object") { // CommonJS
+ mod(require("../../lib/codemirror"));
+ } else if (typeof define == "function" && define.amd) { // AMD
+ define(["../../lib/codemirror"], mod);
+ } else { // Plain browser env
+ mod(CodeMirror);
+ }
+})(function(CodeMirror) {
+ "use strict";
+
+ var TOKEN_STYLES = {
+ addition: "positive",
+ attributes: "attribute",
+ bold: "strong",
+ cite: "keyword",
+ code: "atom",
+ definitionList: "number",
+ deletion: "negative",
+ div: "punctuation",
+ em: "em",
+ footnote: "variable",
+ footCite: "qualifier",
+ header: "header",
+ html: "comment",
+ image: "string",
+ italic: "em",
+ link: "link",
+ linkDefinition: "link",
+ list1: "variable-2",
+ list2: "variable-3",
+ list3: "keyword",
+ notextile: "string-2",
+ pre: "operator",
+ p: "property",
+ quote: "bracket",
+ span: "quote",
+ specialChar: "tag",
+ strong: "strong",
+ sub: "builtin",
+ sup: "builtin",
+ table: "variable-3",
+ tableHeading: "operator"
+ };
+
+ function startNewLine(stream, state) {
+ state.mode = Modes.newLayout;
+ state.tableHeading = false;
+
+ if (state.layoutType === "definitionList" && state.spanningLayout &&
+ stream.match(RE("definitionListEnd"), false))
+ state.spanningLayout = false;
+ }
+
+ function handlePhraseModifier(stream, state, ch) {
+ if (ch === "_") {
+ if (stream.eat("_"))
+ return togglePhraseModifier(stream, state, "italic", /__/, 2);
+ else
+ return togglePhraseModifier(stream, state, "em", /_/, 1);
+ }
+
+ if (ch === "*") {
+ if (stream.eat("*")) {
+ return togglePhraseModifier(stream, state, "bold", /\*\*/, 2);
+ }
+ return togglePhraseModifier(stream, state, "strong", /\*/, 1);
+ }
+
+ if (ch === "[") {
+ if (stream.match(/\d+\]/)) state.footCite = true;
+ return tokenStyles(state);
+ }
+
+ if (ch === "(") {
+ var spec = stream.match(/^(r|tm|c)\)/);
+ if (spec)
+ return tokenStylesWith(state, TOKEN_STYLES.specialChar);
+ }
+
+ if (ch === "<" && stream.match(/(\w+)[^>]+>[^<]+<\/\1>/))
+ return tokenStylesWith(state, TOKEN_STYLES.html);
+
+ if (ch === "?" && stream.eat("?"))
+ return togglePhraseModifier(stream, state, "cite", /\?\?/, 2);
+
+ if (ch === "=" && stream.eat("="))
+ return togglePhraseModifier(stream, state, "notextile", /==/, 2);
+
+ if (ch === "-" && !stream.eat("-"))
+ return togglePhraseModifier(stream, state, "deletion", /-/, 1);
+
+ if (ch === "+")
+ return togglePhraseModifier(stream, state, "addition", /\+/, 1);
+
+ if (ch === "~")
+ return togglePhraseModifier(stream, state, "sub", /~/, 1);
+
+ if (ch === "^")
+ return togglePhraseModifier(stream, state, "sup", /\^/, 1);
+
+ if (ch === "%")
+ return togglePhraseModifier(stream, state, "span", /%/, 1);
+
+ if (ch === "@")
+ return togglePhraseModifier(stream, state, "code", /@/, 1);
+
+ if (ch === "!") {
+ var type = togglePhraseModifier(stream, state, "image", /(?:\([^\)]+\))?!/, 1);
+ stream.match(/^:\S+/); // optional Url portion
+ return type;
+ }
+ return tokenStyles(state);
+ }
+
+ function togglePhraseModifier(stream, state, phraseModifier, closeRE, openSize) {
+ var charBefore = stream.pos > openSize ? stream.string.charAt(stream.pos - openSize - 1) : null;
+ var charAfter = stream.peek();
+ if (state[phraseModifier]) {
+ if ((!charAfter || /\W/.test(charAfter)) && charBefore && /\S/.test(charBefore)) {
+ var type = tokenStyles(state);
+ state[phraseModifier] = false;
+ return type;
+ }
+ } else if ((!charBefore || /\W/.test(charBefore)) && charAfter && /\S/.test(charAfter) &&
+ stream.match(new RegExp("^.*\\S" + closeRE.source + "(?:\\W|$)"), false)) {
+ state[phraseModifier] = true;
+ state.mode = Modes.attributes;
+ }
+ return tokenStyles(state);
+ };
+
+ function tokenStyles(state) {
+ var disabled = textileDisabled(state);
+ if (disabled) return disabled;
+
+ var styles = [];
+ if (state.layoutType) styles.push(TOKEN_STYLES[state.layoutType]);
+
+ styles = styles.concat(activeStyles(
+ state, "addition", "bold", "cite", "code", "deletion", "em", "footCite",
+ "image", "italic", "link", "span", "strong", "sub", "sup", "table", "tableHeading"));
+
+ if (state.layoutType === "header")
+ styles.push(TOKEN_STYLES.header + "-" + state.header);
+
+ return styles.length ? styles.join(" ") : null;
+ }
+
+ function textileDisabled(state) {
+ var type = state.layoutType;
+
+ switch(type) {
+ case "notextile":
+ case "code":
+ case "pre":
+ return TOKEN_STYLES[type];
+ default:
+ if (state.notextile)
+ return TOKEN_STYLES.notextile + (type ? (" " + TOKEN_STYLES[type]) : "");
+ return null;
+ }
+ }
+
+ function tokenStylesWith(state, extraStyles) {
+ var disabled = textileDisabled(state);
+ if (disabled) return disabled;
+
+ var type = tokenStyles(state);
+ if (extraStyles)
+ return type ? (type + " " + extraStyles) : extraStyles;
+ else
+ return type;
+ }
+
+ function activeStyles(state) {
+ var styles = [];
+ for (var i = 1; i < arguments.length; ++i) {
+ if (state[arguments[i]])
+ styles.push(TOKEN_STYLES[arguments[i]]);
+ }
+ return styles;
+ }
+
+ function blankLine(state) {
+ var spanningLayout = state.spanningLayout, type = state.layoutType;
+
+ for (var key in state) if (state.hasOwnProperty(key))
+ delete state[key];
+
+ state.mode = Modes.newLayout;
+ if (spanningLayout) {
+ state.layoutType = type;
+ state.spanningLayout = true;
+ }
+ }
+
+ var REs = {
+ cache: {},
+ single: {
+ bc: "bc",
+ bq: "bq",
+ definitionList: /- .*?:=+/,
+ definitionListEnd: /.*=:\s*$/,
+ div: "div",
+ drawTable: /\|.*\|/,
+ foot: /fn\d+/,
+ header: /h[1-6]/,
+ html: /\s*<(?:\/)?(\w+)(?:[^>]+)?>(?:[^<]+<\/\1>)?/,
+ link: /[^"]+":\S/,
+ linkDefinition: /\[[^\s\]]+\]\S+/,
+ list: /(?:#+|\*+)/,
+ notextile: "notextile",
+ para: "p",
+ pre: "pre",
+ table: "table",
+ tableCellAttributes: /[\/\\]\d+/,
+ tableHeading: /\|_\./,
+ tableText: /[^"_\*\[\(\?\+~\^%@|-]+/,
+ text: /[^!"_=\*\[\(<\?\+~\^%@-]+/
+ },
+ attributes: {
+ align: /(?:<>|<|>|=)/,
+ selector: /\([^\(][^\)]+\)/,
+ lang: /\[[^\[\]]+\]/,
+ pad: /(?:\(+|\)+){1,2}/,
+ css: /\{[^\}]+\}/
+ },
+ createRe: function(name) {
+ switch (name) {
+ case "drawTable":
+ return REs.makeRe("^", REs.single.drawTable, "$");
+ case "html":
+ return REs.makeRe("^", REs.single.html, "(?:", REs.single.html, ")*", "$");
+ case "linkDefinition":
+ return REs.makeRe("^", REs.single.linkDefinition, "$");
+ case "listLayout":
+ return REs.makeRe("^", REs.single.list, RE("allAttributes"), "*\\s+");
+ case "tableCellAttributes":
+ return REs.makeRe("^", REs.choiceRe(REs.single.tableCellAttributes,
+ RE("allAttributes")), "+\\.");
+ case "type":
+ return REs.makeRe("^", RE("allTypes"));
+ case "typeLayout":
+ return REs.makeRe("^", RE("allTypes"), RE("allAttributes"),
+ "*\\.\\.?", "(\\s+|$)");
+ case "attributes":
+ return REs.makeRe("^", RE("allAttributes"), "+");
+
+ case "allTypes":
+ return REs.choiceRe(REs.single.div, REs.single.foot,
+ REs.single.header, REs.single.bc, REs.single.bq,
+ REs.single.notextile, REs.single.pre, REs.single.table,
+ REs.single.para);
+
+ case "allAttributes":
+ return REs.choiceRe(REs.attributes.selector, REs.attributes.css,
+ REs.attributes.lang, REs.attributes.align, REs.attributes.pad);
+
+ default:
+ return REs.makeRe("^", REs.single[name]);
+ }
+ },
+ makeRe: function() {
+ var pattern = "";
+ for (var i = 0; i < arguments.length; ++i) {
+ var arg = arguments[i];
+ pattern += (typeof arg === "string") ? arg : arg.source;
+ }
+ return new RegExp(pattern);
+ },
+ choiceRe: function() {
+ var parts = [arguments[0]];
+ for (var i = 1; i < arguments.length; ++i) {
+ parts[i * 2 - 1] = "|";
+ parts[i * 2] = arguments[i];
+ }
+
+ parts.unshift("(?:");
+ parts.push(")");
+ return REs.makeRe.apply(null, parts);
+ }
+ };
+
+ function RE(name) {
+ return (REs.cache[name] || (REs.cache[name] = REs.createRe(name)));
+ }
+
+ var Modes = {
+ newLayout: function(stream, state) {
+ if (stream.match(RE("typeLayout"), false)) {
+ state.spanningLayout = false;
+ return (state.mode = Modes.blockType)(stream, state);
+ }
+ var newMode;
+ if (!textileDisabled(state)) {
+ if (stream.match(RE("listLayout"), false))
+ newMode = Modes.list;
+ else if (stream.match(RE("drawTable"), false))
+ newMode = Modes.table;
+ else if (stream.match(RE("linkDefinition"), false))
+ newMode = Modes.linkDefinition;
+ else if (stream.match(RE("definitionList")))
+ newMode = Modes.definitionList;
+ else if (stream.match(RE("html"), false))
+ newMode = Modes.html;
+ }
+ return (state.mode = (newMode || Modes.text))(stream, state);
+ },
+
+ blockType: function(stream, state) {
+ var match, type;
+ state.layoutType = null;
+
+ if (match = stream.match(RE("type")))
+ type = match[0];
+ else
+ return (state.mode = Modes.text)(stream, state);
+
+ if (match = type.match(RE("header"))) {
+ state.layoutType = "header";
+ state.header = parseInt(match[0][1]);
+ } else if (type.match(RE("bq"))) {
+ state.layoutType = "quote";
+ } else if (type.match(RE("bc"))) {
+ state.layoutType = "code";
+ } else if (type.match(RE("foot"))) {
+ state.layoutType = "footnote";
+ } else if (type.match(RE("notextile"))) {
+ state.layoutType = "notextile";
+ } else if (type.match(RE("pre"))) {
+ state.layoutType = "pre";
+ } else if (type.match(RE("div"))) {
+ state.layoutType = "div";
+ } else if (type.match(RE("table"))) {
+ state.layoutType = "table";
+ }
+
+ state.mode = Modes.attributes;
+ return tokenStyles(state);
+ },
+
+ text: function(stream, state) {
+ if (stream.match(RE("text"))) return tokenStyles(state);
+
+ var ch = stream.next();
+ if (ch === '"')
+ return (state.mode = Modes.link)(stream, state);
+ return handlePhraseModifier(stream, state, ch);
+ },
+
+ attributes: function(stream, state) {
+ state.mode = Modes.layoutLength;
+
+ if (stream.match(RE("attributes")))
+ return tokenStylesWith(state, TOKEN_STYLES.attributes);
+ else
+ return tokenStyles(state);
+ },
+
+ layoutLength: function(stream, state) {
+ if (stream.eat(".") && stream.eat("."))
+ state.spanningLayout = true;
+
+ state.mode = Modes.text;
+ return tokenStyles(state);
+ },
+
+ list: function(stream, state) {
+ var match = stream.match(RE("list"));
+ state.listDepth = match[0].length;
+ var listMod = (state.listDepth - 1) % 3;
+ if (!listMod)
+ state.layoutType = "list1";
+ else if (listMod === 1)
+ state.layoutType = "list2";
+ else
+ state.layoutType = "list3";
+
+ state.mode = Modes.attributes;
+ return tokenStyles(state);
+ },
+
+ link: function(stream, state) {
+ state.mode = Modes.text;
+ if (stream.match(RE("link"))) {
+ stream.match(/\S+/);
+ return tokenStylesWith(state, TOKEN_STYLES.link);
+ }
+ return tokenStyles(state);
+ },
+
+ linkDefinition: function(stream, state) {
+ stream.skipToEnd();
+ return tokenStylesWith(state, TOKEN_STYLES.linkDefinition);
+ },
+
+ definitionList: function(stream, state) {
+ stream.match(RE("definitionList"));
+
+ state.layoutType = "definitionList";
+
+ if (stream.match(/\s*$/))
+ state.spanningLayout = true;
+ else
+ state.mode = Modes.attributes;
+
+ return tokenStyles(state);
+ },
+
+ html: function(stream, state) {
+ stream.skipToEnd();
+ return tokenStylesWith(state, TOKEN_STYLES.html);
+ },
+
+ table: function(stream, state) {
+ state.layoutType = "table";
+ return (state.mode = Modes.tableCell)(stream, state);
+ },
+
+ tableCell: function(stream, state) {
+ if (stream.match(RE("tableHeading")))
+ state.tableHeading = true;
+ else
+ stream.eat("|");
+
+ state.mode = Modes.tableCellAttributes;
+ return tokenStyles(state);
+ },
+
+ tableCellAttributes: function(stream, state) {
+ state.mode = Modes.tableText;
+
+ if (stream.match(RE("tableCellAttributes")))
+ return tokenStylesWith(state, TOKEN_STYLES.attributes);
+ else
+ return tokenStyles(state);
+ },
+
+ tableText: function(stream, state) {
+ if (stream.match(RE("tableText")))
+ return tokenStyles(state);
+
+ if (stream.peek() === "|") { // end of cell
+ state.mode = Modes.tableCell;
+ return tokenStyles(state);
+ }
+ return handlePhraseModifier(stream, state, stream.next());
+ }
+ };
+
+ CodeMirror.defineMode("textile", function() {
+ return {
+ startState: function() {
+ return { mode: Modes.newLayout };
+ },
+ token: function(stream, state) {
+ if (stream.sol()) startNewLine(stream, state);
+ return state.mode(stream, state);
+ },
+ blankLine: blankLine
+ };
+ });
+
+ CodeMirror.defineMIME("text/x-textile", "textile");
+});
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/tiddlywiki/tiddlywiki.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/tiddlywiki/tiddlywiki.css
new file mode 100644
index 0000000000..9a69b639f8
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/tiddlywiki/tiddlywiki.css
@@ -0,0 +1,14 @@
+span.cm-underlined {
+ text-decoration: underline;
+}
+span.cm-strikethrough {
+ text-decoration: line-through;
+}
+span.cm-brace {
+ color: #170;
+ font-weight: bold;
+}
+span.cm-table {
+ color: blue;
+ font-weight: bold;
+}
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/tiddlywiki/tiddlywiki.js b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/tiddlywiki/tiddlywiki.js
new file mode 100644
index 0000000000..6a9ce447ba
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/tiddlywiki/tiddlywiki.js
@@ -0,0 +1,308 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: https://codemirror.net/LICENSE
+
+/***
+ |''Name''|tiddlywiki.js|
+ |''Description''|Enables TiddlyWikiy syntax highlighting using CodeMirror|
+ |''Author''|PMario|
+ |''Version''|0.1.7|
+ |''Status''|''stable''|
+ |''Source''|[[GitHub|https://github.com/pmario/CodeMirror2/blob/tw-syntax/mode/tiddlywiki]]|
+ |''Documentation''|https://codemirror.tiddlyspace.com/|
+ |''License''|[[MIT License|http://www.opensource.org/licenses/mit-license.php]]|
+ |''CoreVersion''|2.5.0|
+ |''Requires''|codemirror.js|
+ |''Keywords''|syntax highlighting color code mirror codemirror|
+ ! Info
+ CoreVersion parameter is needed for TiddlyWiki only!
+***/
+
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
+ mod(require("../../lib/codemirror"));
+ else if (typeof define == "function" && define.amd) // AMD
+ define(["../../lib/codemirror"], mod);
+ else // Plain browser env
+ mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("tiddlywiki", function () {
+ // Tokenizer
+ var textwords = {};
+
+ var keywords = {
+ "allTags": true, "closeAll": true, "list": true,
+ "newJournal": true, "newTiddler": true,
+ "permaview": true, "saveChanges": true,
+ "search": true, "slider": true, "tabs": true,
+ "tag": true, "tagging": true, "tags": true,
+ "tiddler": true, "timeline": true,
+ "today": true, "version": true, "option": true,
+ "with": true, "filter": true
+ };
+
+ var isSpaceName = /[\w_\-]/i,
+ reHR = /^\-\-\-\-+$/, //
+ reWikiCommentStart = /^\/\*\*\*$/, // /***
+ reWikiCommentStop = /^\*\*\*\/$/, // ***/
+ reBlockQuote = /^<<<$/,
+
+ reJsCodeStart = /^\/\/\{\{\{$/, // //{{{ js block start
+ reJsCodeStop = /^\/\/\}\}\}$/, // //}}} js stop
+ reXmlCodeStart = /^$/, // xml block start
+ reXmlCodeStop = /^$/, // xml stop
+
+ reCodeBlockStart = /^\{\{\{$/, // {{{ TW text div block start
+ reCodeBlockStop = /^\}\}\}$/, // }}} TW text stop
+
+ reUntilCodeStop = /.*?\}\}\}/;
+
+ function chain(stream, state, f) {
+ state.tokenize = f;
+ return f(stream, state);
+ }
+
+ function tokenBase(stream, state) {
+ var sol = stream.sol(), ch = stream.peek();
+
+ state.block = false; // indicates the start of a code block.
+
+ // check start of blocks
+ if (sol && /[<\/\*{}\-]/.test(ch)) {
+ if (stream.match(reCodeBlockStart)) {
+ state.block = true;
+ return chain(stream, state, twTokenCode);
+ }
+ if (stream.match(reBlockQuote))
+ return 'quote';
+ if (stream.match(reWikiCommentStart) || stream.match(reWikiCommentStop))
+ return 'comment';
+ if (stream.match(reJsCodeStart) || stream.match(reJsCodeStop) || stream.match(reXmlCodeStart) || stream.match(reXmlCodeStop))
+ return 'comment';
+ if (stream.match(reHR))
+ return 'hr';
+ }
+
+ stream.next();
+ if (sol && /[\/\*!#;:>|]/.test(ch)) {
+ if (ch == "!") { // tw header
+ stream.skipToEnd();
+ return "header";
+ }
+ if (ch == "*") { // tw list
+ stream.eatWhile('*');
+ return "comment";
+ }
+ if (ch == "#") { // tw numbered list
+ stream.eatWhile('#');
+ return "comment";
+ }
+ if (ch == ";") { // definition list, term
+ stream.eatWhile(';');
+ return "comment";
+ }
+ if (ch == ":") { // definition list, description
+ stream.eatWhile(':');
+ return "comment";
+ }
+ if (ch == ">") { // single line quote
+ stream.eatWhile(">");
+ return "quote";
+ }
+ if (ch == '|')
+ return 'header';
+ }
+
+ if (ch == '{' && stream.match('{{'))
+ return chain(stream, state, twTokenCode);
+
+ // rudimentary html:// file:// link matching. TW knows much more ...
+ if (/[hf]/i.test(ch) &&
+ /[ti]/i.test(stream.peek()) &&
+ stream.match(/\b(ttps?|tp|ile):\/\/[\-A-Z0-9+&@#\/%?=~_|$!:,.;]*[A-Z0-9+&@#\/%=~_|$]/i))
+ return "link";
+
+ // just a little string indicator, don't want to have the whole string covered
+ if (ch == '"')
+ return 'string';
+
+ if (ch == '~') // _no_ CamelCase indicator should be bold
+ return 'brace';
+
+ if (/[\[\]]/.test(ch) && stream.match(ch)) // check for [[..]]
+ return 'brace';
+
+ if (ch == "@") { // check for space link. TODO fix @@...@@ highlighting
+ stream.eatWhile(isSpaceName);
+ return "link";
+ }
+
+ if (/\d/.test(ch)) { // numbers
+ stream.eatWhile(/\d/);
+ return "number";
+ }
+
+ if (ch == "/") { // tw invisible comment
+ if (stream.eat("%")) {
+ return chain(stream, state, twTokenComment);
+ } else if (stream.eat("/")) { //
+ return chain(stream, state, twTokenEm);
+ }
+ }
+
+ if (ch == "_" && stream.eat("_")) // tw underline
+ return chain(stream, state, twTokenUnderline);
+
+ // strikethrough and mdash handling
+ if (ch == "-" && stream.eat("-")) {
+ // if strikethrough looks ugly, change CSS.
+ if (stream.peek() != ' ')
+ return chain(stream, state, twTokenStrike);
+ // mdash
+ if (stream.peek() == ' ')
+ return 'brace';
+ }
+
+ if (ch == "'" && stream.eat("'")) // tw bold
+ return chain(stream, state, twTokenStrong);
+
+ if (ch == "<" && stream.eat("<")) // tw macro
+ return chain(stream, state, twTokenMacro);
+
+ // core macro handling
+ stream.eatWhile(/[\w\$_]/);
+ return textwords.propertyIsEnumerable(stream.current()) ? "keyword" : null
+ }
+
+ // tw invisible comment
+ function twTokenComment(stream, state) {
+ var maybeEnd = false, ch;
+ while (ch = stream.next()) {
+ if (ch == "/" && maybeEnd) {
+ state.tokenize = tokenBase;
+ break;
+ }
+ maybeEnd = (ch == "%");
+ }
+ return "comment";
+ }
+
+ // tw strong / bold
+ function twTokenStrong(stream, state) {
+ var maybeEnd = false,
+ ch;
+ while (ch = stream.next()) {
+ if (ch == "'" && maybeEnd) {
+ state.tokenize = tokenBase;
+ break;
+ }
+ maybeEnd = (ch == "'");
+ }
+ return "strong";
+ }
+
+ // tw code
+ function twTokenCode(stream, state) {
+ var sb = state.block;
+
+ if (sb && stream.current()) {
+ return "comment";
+ }
+
+ if (!sb && stream.match(reUntilCodeStop)) {
+ state.tokenize = tokenBase;
+ return "comment";
+ }
+
+ if (sb && stream.sol() && stream.match(reCodeBlockStop)) {
+ state.tokenize = tokenBase;
+ return "comment";
+ }
+
+ stream.next();
+ return "comment";
+ }
+
+ // tw em / italic
+ function twTokenEm(stream, state) {
+ var maybeEnd = false,
+ ch;
+ while (ch = stream.next()) {
+ if (ch == "/" && maybeEnd) {
+ state.tokenize = tokenBase;
+ break;
+ }
+ maybeEnd = (ch == "/");
+ }
+ return "em";
+ }
+
+ // tw underlined text
+ function twTokenUnderline(stream, state) {
+ var maybeEnd = false,
+ ch;
+ while (ch = stream.next()) {
+ if (ch == "_" && maybeEnd) {
+ state.tokenize = tokenBase;
+ break;
+ }
+ maybeEnd = (ch == "_");
+ }
+ return "underlined";
+ }
+
+ // tw strike through text looks ugly
+ // change CSS if needed
+ function twTokenStrike(stream, state) {
+ var maybeEnd = false, ch;
+
+ while (ch = stream.next()) {
+ if (ch == "-" && maybeEnd) {
+ state.tokenize = tokenBase;
+ break;
+ }
+ maybeEnd = (ch == "-");
+ }
+ return "strikethrough";
+ }
+
+ // macro
+ function twTokenMacro(stream, state) {
+ if (stream.current() == '<<') {
+ return 'macro';
+ }
+
+ var ch = stream.next();
+ if (!ch) {
+ state.tokenize = tokenBase;
+ return null;
+ }
+ if (ch == ">") {
+ if (stream.peek() == '>') {
+ stream.next();
+ state.tokenize = tokenBase;
+ return "macro";
+ }
+ }
+
+ stream.eatWhile(/[\w\$_]/);
+ return keywords.propertyIsEnumerable(stream.current()) ? "keyword" : null
+ }
+
+ // Interface
+ return {
+ startState: function () {
+ return {tokenize: tokenBase};
+ },
+
+ token: function (stream, state) {
+ if (stream.eatSpace()) return null;
+ var style = state.tokenize(stream, state);
+ return style;
+ }
+ };
+});
+
+CodeMirror.defineMIME("text/x-tiddlywiki", "tiddlywiki");
+});
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/tiki/tiki.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/tiki/tiki.css
new file mode 100644
index 0000000000..1d8704c780
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/tiki/tiki.css
@@ -0,0 +1,26 @@
+.cm-tw-syntaxerror {
+ color: #FFF;
+ background-color: #900;
+}
+
+.cm-tw-deleted {
+ text-decoration: line-through;
+}
+
+.cm-tw-header5 {
+ font-weight: bold;
+}
+.cm-tw-listitem:first-child { /*Added first child to fix duplicate padding when highlighting*/
+ padding-left: 10px;
+}
+
+.cm-tw-box {
+ border-top-width: 0px !important;
+ border-style: solid;
+ border-width: 1px;
+ border-color: inherit;
+}
+
+.cm-tw-underline {
+ text-decoration: underline;
+}
\ No newline at end of file
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/tiki/tiki.js b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/tiki/tiki.js
new file mode 100644
index 0000000000..092b859532
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/tiki/tiki.js
@@ -0,0 +1,312 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: https://codemirror.net/LICENSE
+
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
+ mod(require("../../lib/codemirror"));
+ else if (typeof define == "function" && define.amd) // AMD
+ define(["../../lib/codemirror"], mod);
+ else // Plain browser env
+ mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode('tiki', function(config) {
+ function inBlock(style, terminator, returnTokenizer) {
+ return function(stream, state) {
+ while (!stream.eol()) {
+ if (stream.match(terminator)) {
+ state.tokenize = inText;
+ break;
+ }
+ stream.next();
+ }
+
+ if (returnTokenizer) state.tokenize = returnTokenizer;
+
+ return style;
+ };
+ }
+
+ function inLine(style) {
+ return function(stream, state) {
+ while(!stream.eol()) {
+ stream.next();
+ }
+ state.tokenize = inText;
+ return style;
+ };
+ }
+
+ function inText(stream, state) {
+ function chain(parser) {
+ state.tokenize = parser;
+ return parser(stream, state);
+ }
+
+ var sol = stream.sol();
+ var ch = stream.next();
+
+ //non start of line
+ switch (ch) { //switch is generally much faster than if, so it is used here
+ case "{": //plugin
+ stream.eat("/");
+ stream.eatSpace();
+ stream.eatWhile(/[^\s\u00a0=\"\'\/?(}]/);
+ state.tokenize = inPlugin;
+ return "tag";
+ case "_": //bold
+ if (stream.eat("_"))
+ return chain(inBlock("strong", "__", inText));
+ break;
+ case "'": //italics
+ if (stream.eat("'"))
+ return chain(inBlock("em", "''", inText));
+ break;
+ case "(":// Wiki Link
+ if (stream.eat("("))
+ return chain(inBlock("variable-2", "))", inText));
+ break;
+ case "[":// Weblink
+ return chain(inBlock("variable-3", "]", inText));
+ break;
+ case "|": //table
+ if (stream.eat("|"))
+ return chain(inBlock("comment", "||"));
+ break;
+ case "-":
+ if (stream.eat("=")) {//titleBar
+ return chain(inBlock("header string", "=-", inText));
+ } else if (stream.eat("-")) {//deleted
+ return chain(inBlock("error tw-deleted", "--", inText));
+ }
+ break;
+ case "=": //underline
+ if (stream.match("=="))
+ return chain(inBlock("tw-underline", "===", inText));
+ break;
+ case ":":
+ if (stream.eat(":"))
+ return chain(inBlock("comment", "::"));
+ break;
+ case "^": //box
+ return chain(inBlock("tw-box", "^"));
+ break;
+ case "~": //np
+ if (stream.match("np~"))
+ return chain(inBlock("meta", "~/np~"));
+ break;
+ }
+
+ //start of line types
+ if (sol) {
+ switch (ch) {
+ case "!": //header at start of line
+ if (stream.match('!!!!!')) {
+ return chain(inLine("header string"));
+ } else if (stream.match('!!!!')) {
+ return chain(inLine("header string"));
+ } else if (stream.match('!!!')) {
+ return chain(inLine("header string"));
+ } else if (stream.match('!!')) {
+ return chain(inLine("header string"));
+ } else {
+ return chain(inLine("header string"));
+ }
+ break;
+ case "*": //unordered list line item, or at start of line
+ case "#": //ordered list line item, or at start of line
+ case "+": //ordered list line item, or at start of line
+ return chain(inLine("tw-listitem bracket"));
+ break;
+ }
+ }
+
+ //stream.eatWhile(/[&{]/); was eating up plugins, turned off to act less like html and more like tiki
+ return null;
+ }
+
+ var indentUnit = config.indentUnit;
+
+ // Return variables for tokenizers
+ var pluginName, type;
+ function inPlugin(stream, state) {
+ var ch = stream.next();
+ var peek = stream.peek();
+
+ if (ch == "}") {
+ state.tokenize = inText;
+ //type = ch == ")" ? "endPlugin" : "selfclosePlugin"; inPlugin
+ return "tag";
+ } else if (ch == "(" || ch == ")") {
+ return "bracket";
+ } else if (ch == "=") {
+ type = "equals";
+
+ if (peek == ">") {
+ stream.next();
+ peek = stream.peek();
+ }
+
+ //here we detect values directly after equal character with no quotes
+ if (!/[\'\"]/.test(peek)) {
+ state.tokenize = inAttributeNoQuote();
+ }
+ //end detect values
+
+ return "operator";
+ } else if (/[\'\"]/.test(ch)) {
+ state.tokenize = inAttribute(ch);
+ return state.tokenize(stream, state);
+ } else {
+ stream.eatWhile(/[^\s\u00a0=\"\'\/?]/);
+ return "keyword";
+ }
+ }
+
+ function inAttribute(quote) {
+ return function(stream, state) {
+ while (!stream.eol()) {
+ if (stream.next() == quote) {
+ state.tokenize = inPlugin;
+ break;
+ }
+ }
+ return "string";
+ };
+ }
+
+ function inAttributeNoQuote() {
+ return function(stream, state) {
+ while (!stream.eol()) {
+ var ch = stream.next();
+ var peek = stream.peek();
+ if (ch == " " || ch == "," || /[ )}]/.test(peek)) {
+ state.tokenize = inPlugin;
+ break;
+ }
+ }
+ return "string";
+};
+ }
+
+var curState, setStyle;
+function pass() {
+ for (var i = arguments.length - 1; i >= 0; i--) curState.cc.push(arguments[i]);
+}
+
+function cont() {
+ pass.apply(null, arguments);
+ return true;
+}
+
+function pushContext(pluginName, startOfLine) {
+ var noIndent = curState.context && curState.context.noIndent;
+ curState.context = {
+ prev: curState.context,
+ pluginName: pluginName,
+ indent: curState.indented,
+ startOfLine: startOfLine,
+ noIndent: noIndent
+ };
+}
+
+function popContext() {
+ if (curState.context) curState.context = curState.context.prev;
+}
+
+function element(type) {
+ if (type == "openPlugin") {curState.pluginName = pluginName; return cont(attributes, endplugin(curState.startOfLine));}
+ else if (type == "closePlugin") {
+ var err = false;
+ if (curState.context) {
+ err = curState.context.pluginName != pluginName;
+ popContext();
+ } else {
+ err = true;
+ }
+ if (err) setStyle = "error";
+ return cont(endcloseplugin(err));
+ }
+ else if (type == "string") {
+ if (!curState.context || curState.context.name != "!cdata") pushContext("!cdata");
+ if (curState.tokenize == inText) popContext();
+ return cont();
+ }
+ else return cont();
+}
+
+function endplugin(startOfLine) {
+ return function(type) {
+ if (
+ type == "selfclosePlugin" ||
+ type == "endPlugin"
+ )
+ return cont();
+ if (type == "endPlugin") {pushContext(curState.pluginName, startOfLine); return cont();}
+ return cont();
+ };
+}
+
+function endcloseplugin(err) {
+ return function(type) {
+ if (err) setStyle = "error";
+ if (type == "endPlugin") return cont();
+ return pass();
+ };
+}
+
+function attributes(type) {
+ if (type == "keyword") {setStyle = "attribute"; return cont(attributes);}
+ if (type == "equals") return cont(attvalue, attributes);
+ return pass();
+}
+function attvalue(type) {
+ if (type == "keyword") {setStyle = "string"; return cont();}
+ if (type == "string") return cont(attvaluemaybe);
+ return pass();
+}
+function attvaluemaybe(type) {
+ if (type == "string") return cont(attvaluemaybe);
+ else return pass();
+}
+return {
+ startState: function() {
+ return {tokenize: inText, cc: [], indented: 0, startOfLine: true, pluginName: null, context: null};
+ },
+ token: function(stream, state) {
+ if (stream.sol()) {
+ state.startOfLine = true;
+ state.indented = stream.indentation();
+ }
+ if (stream.eatSpace()) return null;
+
+ setStyle = type = pluginName = null;
+ var style = state.tokenize(stream, state);
+ if ((style || type) && style != "comment") {
+ curState = state;
+ while (true) {
+ var comb = state.cc.pop() || element;
+ if (comb(type || style)) break;
+ }
+ }
+ state.startOfLine = false;
+ return setStyle || style;
+ },
+ indent: function(state, textAfter) {
+ var context = state.context;
+ if (context && context.noIndent) return 0;
+ if (context && /^{\//.test(textAfter))
+ context = context.prev;
+ while (context && !context.startOfLine)
+ context = context.prev;
+ if (context) return context.indent + indentUnit;
+ else return 0;
+ },
+ electricChars: "/"
+};
+});
+
+CodeMirror.defineMIME("text/tiki", "tiki");
+
+});
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/toml/toml.js b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/toml/toml.js
new file mode 100644
index 0000000000..891f384b5b
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/toml/toml.js
@@ -0,0 +1,88 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: https://codemirror.net/LICENSE
+
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
+ mod(require("../../lib/codemirror"));
+ else if (typeof define == "function" && define.amd) // AMD
+ define(["../../lib/codemirror"], mod);
+ else // Plain browser env
+ mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("toml", function () {
+ return {
+ startState: function () {
+ return {
+ inString: false,
+ stringType: "",
+ lhs: true,
+ inArray: 0
+ };
+ },
+ token: function (stream, state) {
+ //check for state changes
+ if (!state.inString && ((stream.peek() == '"') || (stream.peek() == "'"))) {
+ state.stringType = stream.peek();
+ stream.next(); // Skip quote
+ state.inString = true; // Update state
+ }
+ if (stream.sol() && state.inArray === 0) {
+ state.lhs = true;
+ }
+ //return state
+ if (state.inString) {
+ while (state.inString && !stream.eol()) {
+ if (stream.peek() === state.stringType) {
+ stream.next(); // Skip quote
+ state.inString = false; // Clear flag
+ } else if (stream.peek() === '\\') {
+ stream.next();
+ stream.next();
+ } else {
+ stream.match(/^.[^\\\"\']*/);
+ }
+ }
+ return state.lhs ? "property string" : "string"; // Token style
+ } else if (state.inArray && stream.peek() === ']') {
+ stream.next();
+ state.inArray--;
+ return 'bracket';
+ } else if (state.lhs && stream.peek() === '[' && stream.skipTo(']')) {
+ stream.next();//skip closing ]
+ // array of objects has an extra open & close []
+ if (stream.peek() === ']') stream.next();
+ return "atom";
+ } else if (stream.peek() === "#") {
+ stream.skipToEnd();
+ return "comment";
+ } else if (stream.eatSpace()) {
+ return null;
+ } else if (state.lhs && stream.eatWhile(function (c) { return c != '=' && c != ' '; })) {
+ return "property";
+ } else if (state.lhs && stream.peek() === "=") {
+ stream.next();
+ state.lhs = false;
+ return null;
+ } else if (!state.lhs && stream.match(/^\d\d\d\d[\d\-\:\.T]*Z/)) {
+ return 'atom'; //date
+ } else if (!state.lhs && (stream.match('true') || stream.match('false'))) {
+ return 'atom';
+ } else if (!state.lhs && stream.peek() === '[') {
+ state.inArray++;
+ stream.next();
+ return 'bracket';
+ } else if (!state.lhs && stream.match(/^\-?\d+(?:\.\d+)?/)) {
+ return 'number';
+ } else if (!stream.eatSpace()) {
+ stream.next();
+ }
+ return null;
+ }
+ };
+});
+
+CodeMirror.defineMIME('text/x-toml', 'toml');
+
+});
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/tornado/tornado.js b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/tornado/tornado.js
new file mode 100644
index 0000000000..aa589a08c3
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/tornado/tornado.js
@@ -0,0 +1,68 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: https://codemirror.net/LICENSE
+
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
+ mod(require("../../lib/codemirror"), require("../htmlmixed/htmlmixed"),
+ require("../../addon/mode/overlay"));
+ else if (typeof define == "function" && define.amd) // AMD
+ define(["../../lib/codemirror", "../htmlmixed/htmlmixed",
+ "../../addon/mode/overlay"], mod);
+ else // Plain browser env
+ mod(CodeMirror);
+})(function(CodeMirror) {
+ "use strict";
+
+ CodeMirror.defineMode("tornado:inner", function() {
+ var keywords = ["and","as","assert","autoescape","block","break","class","comment","context",
+ "continue","datetime","def","del","elif","else","end","escape","except",
+ "exec","extends","false","finally","for","from","global","if","import","in",
+ "include","is","json_encode","lambda","length","linkify","load","module",
+ "none","not","or","pass","print","put","raise","raw","return","self","set",
+ "squeeze","super","true","try","url_escape","while","with","without","xhtml_escape","yield"];
+ keywords = new RegExp("^((" + keywords.join(")|(") + "))\\b");
+
+ function tokenBase (stream, state) {
+ stream.eatWhile(/[^\{]/);
+ var ch = stream.next();
+ if (ch == "{") {
+ if (ch = stream.eat(/\{|%|#/)) {
+ state.tokenize = inTag(ch);
+ return "tag";
+ }
+ }
+ }
+ function inTag (close) {
+ if (close == "{") {
+ close = "}";
+ }
+ return function (stream, state) {
+ var ch = stream.next();
+ if ((ch == close) && stream.eat("}")) {
+ state.tokenize = tokenBase;
+ return "tag";
+ }
+ if (stream.match(keywords)) {
+ return "keyword";
+ }
+ return close == "#" ? "comment" : "string";
+ };
+ }
+ return {
+ startState: function () {
+ return {tokenize: tokenBase};
+ },
+ token: function (stream, state) {
+ return state.tokenize(stream, state);
+ }
+ };
+ });
+
+ CodeMirror.defineMode("tornado", function(config) {
+ var htmlBase = CodeMirror.getMode(config, "text/html");
+ var tornadoInner = CodeMirror.getMode(config, "tornado:inner");
+ return CodeMirror.overlayMode(htmlBase, tornadoInner);
+ });
+
+ CodeMirror.defineMIME("text/x-tornado", "tornado");
+});
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/troff/troff.js b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/troff/troff.js
new file mode 100644
index 0000000000..0c2220d2cc
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/troff/troff.js
@@ -0,0 +1,84 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: https://codemirror.net/LICENSE
+
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object")
+ mod(require("../../lib/codemirror"));
+ else if (typeof define == "function" && define.amd)
+ define(["../../lib/codemirror"], mod);
+ else
+ mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode('troff', function() {
+
+ var words = {};
+
+ function tokenBase(stream) {
+ if (stream.eatSpace()) return null;
+
+ var sol = stream.sol();
+ var ch = stream.next();
+
+ if (ch === '\\') {
+ if (stream.match('fB') || stream.match('fR') || stream.match('fI') ||
+ stream.match('u') || stream.match('d') ||
+ stream.match('%') || stream.match('&')) {
+ return 'string';
+ }
+ if (stream.match('m[')) {
+ stream.skipTo(']');
+ stream.next();
+ return 'string';
+ }
+ if (stream.match('s+') || stream.match('s-')) {
+ stream.eatWhile(/[\d-]/);
+ return 'string';
+ }
+ if (stream.match('\(') || stream.match('*\(')) {
+ stream.eatWhile(/[\w-]/);
+ return 'string';
+ }
+ return 'string';
+ }
+ if (sol && (ch === '.' || ch === '\'')) {
+ if (stream.eat('\\') && stream.eat('\"')) {
+ stream.skipToEnd();
+ return 'comment';
+ }
+ }
+ if (sol && ch === '.') {
+ if (stream.match('B ') || stream.match('I ') || stream.match('R ')) {
+ return 'attribute';
+ }
+ if (stream.match('TH ') || stream.match('SH ') || stream.match('SS ') || stream.match('HP ')) {
+ stream.skipToEnd();
+ return 'quote';
+ }
+ if ((stream.match(/[A-Z]/) && stream.match(/[A-Z]/)) || (stream.match(/[a-z]/) && stream.match(/[a-z]/))) {
+ return 'attribute';
+ }
+ }
+ stream.eatWhile(/[\w-]/);
+ var cur = stream.current();
+ return words.hasOwnProperty(cur) ? words[cur] : null;
+ }
+
+ function tokenize(stream, state) {
+ return (state.tokens[0] || tokenBase) (stream, state);
+ };
+
+ return {
+ startState: function() {return {tokens:[]};},
+ token: function(stream, state) {
+ return tokenize(stream, state);
+ }
+ };
+});
+
+CodeMirror.defineMIME('text/troff', 'troff');
+CodeMirror.defineMIME('text/x-troff', 'troff');
+CodeMirror.defineMIME('application/x-troff', 'troff');
+
+});
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/ttcn-cfg/ttcn-cfg.js b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/ttcn-cfg/ttcn-cfg.js
new file mode 100644
index 0000000000..9d4b8405af
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/ttcn-cfg/ttcn-cfg.js
@@ -0,0 +1,214 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: https://codemirror.net/LICENSE
+
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
+ mod(require("../../lib/codemirror"));
+ else if (typeof define == "function" && define.amd) // AMD
+ define(["../../lib/codemirror"], mod);
+ else // Plain browser env
+ mod(CodeMirror);
+})(function(CodeMirror) {
+ "use strict";
+
+ CodeMirror.defineMode("ttcn-cfg", function(config, parserConfig) {
+ var indentUnit = config.indentUnit,
+ keywords = parserConfig.keywords || {},
+ fileNCtrlMaskOptions = parserConfig.fileNCtrlMaskOptions || {},
+ externalCommands = parserConfig.externalCommands || {},
+ multiLineStrings = parserConfig.multiLineStrings,
+ indentStatements = parserConfig.indentStatements !== false;
+ var isOperatorChar = /[\|]/;
+ var curPunc;
+
+ function tokenBase(stream, state) {
+ var ch = stream.next();
+ if (ch == '"' || ch == "'") {
+ state.tokenize = tokenString(ch);
+ return state.tokenize(stream, state);
+ }
+ if (/[:=]/.test(ch)) {
+ curPunc = ch;
+ return "punctuation";
+ }
+ if (ch == "#"){
+ stream.skipToEnd();
+ return "comment";
+ }
+ if (/\d/.test(ch)) {
+ stream.eatWhile(/[\w\.]/);
+ return "number";
+ }
+ if (isOperatorChar.test(ch)) {
+ stream.eatWhile(isOperatorChar);
+ return "operator";
+ }
+ if (ch == "["){
+ stream.eatWhile(/[\w_\]]/);
+ return "number sectionTitle";
+ }
+
+ stream.eatWhile(/[\w\$_]/);
+ var cur = stream.current();
+ if (keywords.propertyIsEnumerable(cur)) return "keyword";
+ if (fileNCtrlMaskOptions.propertyIsEnumerable(cur))
+ return "negative fileNCtrlMaskOptions";
+ if (externalCommands.propertyIsEnumerable(cur)) return "negative externalCommands";
+
+ return "variable";
+ }
+
+ function tokenString(quote) {
+ return function(stream, state) {
+ var escaped = false, next, end = false;
+ while ((next = stream.next()) != null) {
+ if (next == quote && !escaped){
+ var afterNext = stream.peek();
+ //look if the character if the quote is like the B in '10100010'B
+ if (afterNext){
+ afterNext = afterNext.toLowerCase();
+ if(afterNext == "b" || afterNext == "h" || afterNext == "o")
+ stream.next();
+ }
+ end = true; break;
+ }
+ escaped = !escaped && next == "\\";
+ }
+ if (end || !(escaped || multiLineStrings))
+ state.tokenize = null;
+ return "string";
+ };
+ }
+
+ function Context(indented, column, type, align, prev) {
+ this.indented = indented;
+ this.column = column;
+ this.type = type;
+ this.align = align;
+ this.prev = prev;
+ }
+ function pushContext(state, col, type) {
+ var indent = state.indented;
+ if (state.context && state.context.type == "statement")
+ indent = state.context.indented;
+ return state.context = new Context(indent, col, type, null, state.context);
+ }
+ function popContext(state) {
+ var t = state.context.type;
+ if (t == ")" || t == "]" || t == "}")
+ state.indented = state.context.indented;
+ return state.context = state.context.prev;
+ }
+
+ //Interface
+ return {
+ startState: function(basecolumn) {
+ return {
+ tokenize: null,
+ context: new Context((basecolumn || 0) - indentUnit, 0, "top", false),
+ indented: 0,
+ startOfLine: true
+ };
+ },
+
+ token: function(stream, state) {
+ var ctx = state.context;
+ if (stream.sol()) {
+ if (ctx.align == null) ctx.align = false;
+ state.indented = stream.indentation();
+ state.startOfLine = true;
+ }
+ if (stream.eatSpace()) return null;
+ curPunc = null;
+ var style = (state.tokenize || tokenBase)(stream, state);
+ if (style == "comment") return style;
+ if (ctx.align == null) ctx.align = true;
+
+ if ((curPunc == ";" || curPunc == ":" || curPunc == ",")
+ && ctx.type == "statement"){
+ popContext(state);
+ }
+ else if (curPunc == "{") pushContext(state, stream.column(), "}");
+ else if (curPunc == "[") pushContext(state, stream.column(), "]");
+ else if (curPunc == "(") pushContext(state, stream.column(), ")");
+ else if (curPunc == "}") {
+ while (ctx.type == "statement") ctx = popContext(state);
+ if (ctx.type == "}") ctx = popContext(state);
+ while (ctx.type == "statement") ctx = popContext(state);
+ }
+ else if (curPunc == ctx.type) popContext(state);
+ else if (indentStatements && (((ctx.type == "}" || ctx.type == "top")
+ && curPunc != ';') || (ctx.type == "statement"
+ && curPunc == "newstatement")))
+ pushContext(state, stream.column(), "statement");
+ state.startOfLine = false;
+ return style;
+ },
+
+ electricChars: "{}",
+ lineComment: "#",
+ fold: "brace"
+ };
+ });
+
+ function words(str) {
+ var obj = {}, words = str.split(" ");
+ for (var i = 0; i < words.length; ++i)
+ obj[words[i]] = true;
+ return obj;
+ }
+
+ CodeMirror.defineMIME("text/x-ttcn-cfg", {
+ name: "ttcn-cfg",
+ keywords: words("Yes No LogFile FileMask ConsoleMask AppendFile" +
+ " TimeStampFormat LogEventTypes SourceInfoFormat" +
+ " LogEntityName LogSourceInfo DiskFullAction" +
+ " LogFileNumber LogFileSize MatchingHints Detailed" +
+ " Compact SubCategories Stack Single None Seconds" +
+ " DateTime Time Stop Error Retry Delete TCPPort KillTimer" +
+ " NumHCs UnixSocketsEnabled LocalAddress"),
+ fileNCtrlMaskOptions: words("TTCN_EXECUTOR TTCN_ERROR TTCN_WARNING" +
+ " TTCN_PORTEVENT TTCN_TIMEROP TTCN_VERDICTOP" +
+ " TTCN_DEFAULTOP TTCN_TESTCASE TTCN_ACTION" +
+ " TTCN_USER TTCN_FUNCTION TTCN_STATISTICS" +
+ " TTCN_PARALLEL TTCN_MATCHING TTCN_DEBUG" +
+ " EXECUTOR ERROR WARNING PORTEVENT TIMEROP" +
+ " VERDICTOP DEFAULTOP TESTCASE ACTION USER" +
+ " FUNCTION STATISTICS PARALLEL MATCHING DEBUG" +
+ " LOG_ALL LOG_NOTHING ACTION_UNQUALIFIED" +
+ " DEBUG_ENCDEC DEBUG_TESTPORT" +
+ " DEBUG_UNQUALIFIED DEFAULTOP_ACTIVATE" +
+ " DEFAULTOP_DEACTIVATE DEFAULTOP_EXIT" +
+ " DEFAULTOP_UNQUALIFIED ERROR_UNQUALIFIED" +
+ " EXECUTOR_COMPONENT EXECUTOR_CONFIGDATA" +
+ " EXECUTOR_EXTCOMMAND EXECUTOR_LOGOPTIONS" +
+ " EXECUTOR_RUNTIME EXECUTOR_UNQUALIFIED" +
+ " FUNCTION_RND FUNCTION_UNQUALIFIED" +
+ " MATCHING_DONE MATCHING_MCSUCCESS" +
+ " MATCHING_MCUNSUCC MATCHING_MMSUCCESS" +
+ " MATCHING_MMUNSUCC MATCHING_PCSUCCESS" +
+ " MATCHING_PCUNSUCC MATCHING_PMSUCCESS" +
+ " MATCHING_PMUNSUCC MATCHING_PROBLEM" +
+ " MATCHING_TIMEOUT MATCHING_UNQUALIFIED" +
+ " PARALLEL_PORTCONN PARALLEL_PORTMAP" +
+ " PARALLEL_PTC PARALLEL_UNQUALIFIED" +
+ " PORTEVENT_DUALRECV PORTEVENT_DUALSEND" +
+ " PORTEVENT_MCRECV PORTEVENT_MCSEND" +
+ " PORTEVENT_MMRECV PORTEVENT_MMSEND" +
+ " PORTEVENT_MQUEUE PORTEVENT_PCIN" +
+ " PORTEVENT_PCOUT PORTEVENT_PMIN" +
+ " PORTEVENT_PMOUT PORTEVENT_PQUEUE" +
+ " PORTEVENT_STATE PORTEVENT_UNQUALIFIED" +
+ " STATISTICS_UNQUALIFIED STATISTICS_VERDICT" +
+ " TESTCASE_FINISH TESTCASE_START" +
+ " TESTCASE_UNQUALIFIED TIMEROP_GUARD" +
+ " TIMEROP_READ TIMEROP_START TIMEROP_STOP" +
+ " TIMEROP_TIMEOUT TIMEROP_UNQUALIFIED" +
+ " USER_UNQUALIFIED VERDICTOP_FINAL" +
+ " VERDICTOP_GETVERDICT VERDICTOP_SETVERDICT" +
+ " VERDICTOP_UNQUALIFIED WARNING_UNQUALIFIED"),
+ externalCommands: words("BeginControlPart EndControlPart BeginTestCase" +
+ " EndTestCase"),
+ multiLineStrings: true
+ });
+});
\ No newline at end of file
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/ttcn/ttcn.js b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/ttcn/ttcn.js
new file mode 100644
index 0000000000..0304e7c53d
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/ttcn/ttcn.js
@@ -0,0 +1,283 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: https://codemirror.net/LICENSE
+
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
+ mod(require("../../lib/codemirror"));
+ else if (typeof define == "function" && define.amd) // AMD
+ define(["../../lib/codemirror"], mod);
+ else // Plain browser env
+ mod(CodeMirror);
+})(function(CodeMirror) {
+ "use strict";
+
+ CodeMirror.defineMode("ttcn", function(config, parserConfig) {
+ var indentUnit = config.indentUnit,
+ keywords = parserConfig.keywords || {},
+ builtin = parserConfig.builtin || {},
+ timerOps = parserConfig.timerOps || {},
+ portOps = parserConfig.portOps || {},
+ configOps = parserConfig.configOps || {},
+ verdictOps = parserConfig.verdictOps || {},
+ sutOps = parserConfig.sutOps || {},
+ functionOps = parserConfig.functionOps || {},
+
+ verdictConsts = parserConfig.verdictConsts || {},
+ booleanConsts = parserConfig.booleanConsts || {},
+ otherConsts = parserConfig.otherConsts || {},
+
+ types = parserConfig.types || {},
+ visibilityModifiers = parserConfig.visibilityModifiers || {},
+ templateMatch = parserConfig.templateMatch || {},
+ multiLineStrings = parserConfig.multiLineStrings,
+ indentStatements = parserConfig.indentStatements !== false;
+ var isOperatorChar = /[+\-*&@=<>!\/]/;
+ var curPunc;
+
+ function tokenBase(stream, state) {
+ var ch = stream.next();
+
+ if (ch == '"' || ch == "'") {
+ state.tokenize = tokenString(ch);
+ return state.tokenize(stream, state);
+ }
+ if (/[\[\]{}\(\),;\\:\?\.]/.test(ch)) {
+ curPunc = ch;
+ return "punctuation";
+ }
+ if (ch == "#"){
+ stream.skipToEnd();
+ return "atom preprocessor";
+ }
+ if (ch == "%"){
+ stream.eatWhile(/\b/);
+ return "atom ttcn3Macros";
+ }
+ if (/\d/.test(ch)) {
+ stream.eatWhile(/[\w\.]/);
+ return "number";
+ }
+ if (ch == "/") {
+ if (stream.eat("*")) {
+ state.tokenize = tokenComment;
+ return tokenComment(stream, state);
+ }
+ if (stream.eat("/")) {
+ stream.skipToEnd();
+ return "comment";
+ }
+ }
+ if (isOperatorChar.test(ch)) {
+ if(ch == "@"){
+ if(stream.match("try") || stream.match("catch")
+ || stream.match("lazy")){
+ return "keyword";
+ }
+ }
+ stream.eatWhile(isOperatorChar);
+ return "operator";
+ }
+ stream.eatWhile(/[\w\$_\xa1-\uffff]/);
+ var cur = stream.current();
+
+ if (keywords.propertyIsEnumerable(cur)) return "keyword";
+ if (builtin.propertyIsEnumerable(cur)) return "builtin";
+
+ if (timerOps.propertyIsEnumerable(cur)) return "def timerOps";
+ if (configOps.propertyIsEnumerable(cur)) return "def configOps";
+ if (verdictOps.propertyIsEnumerable(cur)) return "def verdictOps";
+ if (portOps.propertyIsEnumerable(cur)) return "def portOps";
+ if (sutOps.propertyIsEnumerable(cur)) return "def sutOps";
+ if (functionOps.propertyIsEnumerable(cur)) return "def functionOps";
+
+ if (verdictConsts.propertyIsEnumerable(cur)) return "string verdictConsts";
+ if (booleanConsts.propertyIsEnumerable(cur)) return "string booleanConsts";
+ if (otherConsts.propertyIsEnumerable(cur)) return "string otherConsts";
+
+ if (types.propertyIsEnumerable(cur)) return "builtin types";
+ if (visibilityModifiers.propertyIsEnumerable(cur))
+ return "builtin visibilityModifiers";
+ if (templateMatch.propertyIsEnumerable(cur)) return "atom templateMatch";
+
+ return "variable";
+ }
+
+ function tokenString(quote) {
+ return function(stream, state) {
+ var escaped = false, next, end = false;
+ while ((next = stream.next()) != null) {
+ if (next == quote && !escaped){
+ var afterQuote = stream.peek();
+ //look if the character after the quote is like the B in '10100010'B
+ if (afterQuote){
+ afterQuote = afterQuote.toLowerCase();
+ if(afterQuote == "b" || afterQuote == "h" || afterQuote == "o")
+ stream.next();
+ }
+ end = true; break;
+ }
+ escaped = !escaped && next == "\\";
+ }
+ if (end || !(escaped || multiLineStrings))
+ state.tokenize = null;
+ return "string";
+ };
+ }
+
+ function tokenComment(stream, state) {
+ var maybeEnd = false, ch;
+ while (ch = stream.next()) {
+ if (ch == "/" && maybeEnd) {
+ state.tokenize = null;
+ break;
+ }
+ maybeEnd = (ch == "*");
+ }
+ return "comment";
+ }
+
+ function Context(indented, column, type, align, prev) {
+ this.indented = indented;
+ this.column = column;
+ this.type = type;
+ this.align = align;
+ this.prev = prev;
+ }
+
+ function pushContext(state, col, type) {
+ var indent = state.indented;
+ if (state.context && state.context.type == "statement")
+ indent = state.context.indented;
+ return state.context = new Context(indent, col, type, null, state.context);
+ }
+
+ function popContext(state) {
+ var t = state.context.type;
+ if (t == ")" || t == "]" || t == "}")
+ state.indented = state.context.indented;
+ return state.context = state.context.prev;
+ }
+
+ //Interface
+ return {
+ startState: function(basecolumn) {
+ return {
+ tokenize: null,
+ context: new Context((basecolumn || 0) - indentUnit, 0, "top", false),
+ indented: 0,
+ startOfLine: true
+ };
+ },
+
+ token: function(stream, state) {
+ var ctx = state.context;
+ if (stream.sol()) {
+ if (ctx.align == null) ctx.align = false;
+ state.indented = stream.indentation();
+ state.startOfLine = true;
+ }
+ if (stream.eatSpace()) return null;
+ curPunc = null;
+ var style = (state.tokenize || tokenBase)(stream, state);
+ if (style == "comment") return style;
+ if (ctx.align == null) ctx.align = true;
+
+ if ((curPunc == ";" || curPunc == ":" || curPunc == ",")
+ && ctx.type == "statement"){
+ popContext(state);
+ }
+ else if (curPunc == "{") pushContext(state, stream.column(), "}");
+ else if (curPunc == "[") pushContext(state, stream.column(), "]");
+ else if (curPunc == "(") pushContext(state, stream.column(), ")");
+ else if (curPunc == "}") {
+ while (ctx.type == "statement") ctx = popContext(state);
+ if (ctx.type == "}") ctx = popContext(state);
+ while (ctx.type == "statement") ctx = popContext(state);
+ }
+ else if (curPunc == ctx.type) popContext(state);
+ else if (indentStatements &&
+ (((ctx.type == "}" || ctx.type == "top") && curPunc != ';') ||
+ (ctx.type == "statement" && curPunc == "newstatement")))
+ pushContext(state, stream.column(), "statement");
+
+ state.startOfLine = false;
+
+ return style;
+ },
+
+ electricChars: "{}",
+ blockCommentStart: "/*",
+ blockCommentEnd: "*/",
+ lineComment: "//",
+ fold: "brace"
+ };
+ });
+
+ function words(str) {
+ var obj = {}, words = str.split(" ");
+ for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
+ return obj;
+ }
+
+ function def(mimes, mode) {
+ if (typeof mimes == "string") mimes = [mimes];
+ var words = [];
+ function add(obj) {
+ if (obj) for (var prop in obj) if (obj.hasOwnProperty(prop))
+ words.push(prop);
+ }
+
+ add(mode.keywords);
+ add(mode.builtin);
+ add(mode.timerOps);
+ add(mode.portOps);
+
+ if (words.length) {
+ mode.helperType = mimes[0];
+ CodeMirror.registerHelper("hintWords", mimes[0], words);
+ }
+
+ for (var i = 0; i < mimes.length; ++i)
+ CodeMirror.defineMIME(mimes[i], mode);
+ }
+
+ def(["text/x-ttcn", "text/x-ttcn3", "text/x-ttcnpp"], {
+ name: "ttcn",
+ keywords: words("activate address alive all alt altstep and and4b any" +
+ " break case component const continue control deactivate" +
+ " display do else encode enumerated except exception" +
+ " execute extends extension external for from function" +
+ " goto group if import in infinity inout interleave" +
+ " label language length log match message mixed mod" +
+ " modifies module modulepar mtc noblock not not4b nowait" +
+ " of on optional or or4b out override param pattern port" +
+ " procedure record recursive rem repeat return runs select" +
+ " self sender set signature system template testcase to" +
+ " type union value valueof var variant while with xor xor4b"),
+ builtin: words("bit2hex bit2int bit2oct bit2str char2int char2oct encvalue" +
+ " decomp decvalue float2int float2str hex2bit hex2int" +
+ " hex2oct hex2str int2bit int2char int2float int2hex" +
+ " int2oct int2str int2unichar isbound ischosen ispresent" +
+ " isvalue lengthof log2str oct2bit oct2char oct2hex oct2int" +
+ " oct2str regexp replace rnd sizeof str2bit str2float" +
+ " str2hex str2int str2oct substr unichar2int unichar2char" +
+ " enum2int"),
+ types: words("anytype bitstring boolean char charstring default float" +
+ " hexstring integer objid octetstring universal verdicttype timer"),
+ timerOps: words("read running start stop timeout"),
+ portOps: words("call catch check clear getcall getreply halt raise receive" +
+ " reply send trigger"),
+ configOps: words("create connect disconnect done kill killed map unmap"),
+ verdictOps: words("getverdict setverdict"),
+ sutOps: words("action"),
+ functionOps: words("apply derefers refers"),
+
+ verdictConsts: words("error fail inconc none pass"),
+ booleanConsts: words("true false"),
+ otherConsts: words("null NULL omit"),
+
+ visibilityModifiers: words("private public friend"),
+ templateMatch: words("complement ifpresent subset superset permutation"),
+ multiLineStrings: true
+ });
+});
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/turtle/turtle.js b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/turtle/turtle.js
new file mode 100644
index 0000000000..695239661f
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/turtle/turtle.js
@@ -0,0 +1,162 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: https://codemirror.net/LICENSE
+
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
+ mod(require("../../lib/codemirror"));
+ else if (typeof define == "function" && define.amd) // AMD
+ define(["../../lib/codemirror"], mod);
+ else // Plain browser env
+ mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("turtle", function(config) {
+ var indentUnit = config.indentUnit;
+ var curPunc;
+
+ function wordRegexp(words) {
+ return new RegExp("^(?:" + words.join("|") + ")$", "i");
+ }
+ var ops = wordRegexp([]);
+ var keywords = wordRegexp(["@prefix", "@base", "a"]);
+ var operatorChars = /[*+\-<>=&|]/;
+
+ function tokenBase(stream, state) {
+ var ch = stream.next();
+ curPunc = null;
+ if (ch == "<" && !stream.match(/^[\s\u00a0=]/, false)) {
+ stream.match(/^[^\s\u00a0>]*>?/);
+ return "atom";
+ }
+ else if (ch == "\"" || ch == "'") {
+ state.tokenize = tokenLiteral(ch);
+ return state.tokenize(stream, state);
+ }
+ else if (/[{}\(\),\.;\[\]]/.test(ch)) {
+ curPunc = ch;
+ return null;
+ }
+ else if (ch == "#") {
+ stream.skipToEnd();
+ return "comment";
+ }
+ else if (operatorChars.test(ch)) {
+ stream.eatWhile(operatorChars);
+ return null;
+ }
+ else if (ch == ":") {
+ return "operator";
+ } else {
+ stream.eatWhile(/[_\w\d]/);
+ if(stream.peek() == ":") {
+ return "variable-3";
+ } else {
+ var word = stream.current();
+
+ if(keywords.test(word)) {
+ return "meta";
+ }
+
+ if(ch >= "A" && ch <= "Z") {
+ return "comment";
+ } else {
+ return "keyword";
+ }
+ }
+ var word = stream.current();
+ if (ops.test(word))
+ return null;
+ else if (keywords.test(word))
+ return "meta";
+ else
+ return "variable";
+ }
+ }
+
+ function tokenLiteral(quote) {
+ return function(stream, state) {
+ var escaped = false, ch;
+ while ((ch = stream.next()) != null) {
+ if (ch == quote && !escaped) {
+ state.tokenize = tokenBase;
+ break;
+ }
+ escaped = !escaped && ch == "\\";
+ }
+ return "string";
+ };
+ }
+
+ function pushContext(state, type, col) {
+ state.context = {prev: state.context, indent: state.indent, col: col, type: type};
+ }
+ function popContext(state) {
+ state.indent = state.context.indent;
+ state.context = state.context.prev;
+ }
+
+ return {
+ startState: function() {
+ return {tokenize: tokenBase,
+ context: null,
+ indent: 0,
+ col: 0};
+ },
+
+ token: function(stream, state) {
+ if (stream.sol()) {
+ if (state.context && state.context.align == null) state.context.align = false;
+ state.indent = stream.indentation();
+ }
+ if (stream.eatSpace()) return null;
+ var style = state.tokenize(stream, state);
+
+ if (style != "comment" && state.context && state.context.align == null && state.context.type != "pattern") {
+ state.context.align = true;
+ }
+
+ if (curPunc == "(") pushContext(state, ")", stream.column());
+ else if (curPunc == "[") pushContext(state, "]", stream.column());
+ else if (curPunc == "{") pushContext(state, "}", stream.column());
+ else if (/[\]\}\)]/.test(curPunc)) {
+ while (state.context && state.context.type == "pattern") popContext(state);
+ if (state.context && curPunc == state.context.type) popContext(state);
+ }
+ else if (curPunc == "." && state.context && state.context.type == "pattern") popContext(state);
+ else if (/atom|string|variable/.test(style) && state.context) {
+ if (/[\}\]]/.test(state.context.type))
+ pushContext(state, "pattern", stream.column());
+ else if (state.context.type == "pattern" && !state.context.align) {
+ state.context.align = true;
+ state.context.col = stream.column();
+ }
+ }
+
+ return style;
+ },
+
+ indent: function(state, textAfter) {
+ var firstChar = textAfter && textAfter.charAt(0);
+ var context = state.context;
+ if (/[\]\}]/.test(firstChar))
+ while (context && context.type == "pattern") context = context.prev;
+
+ var closing = context && firstChar == context.type;
+ if (!context)
+ return 0;
+ else if (context.type == "pattern")
+ return context.col;
+ else if (context.align)
+ return context.col + (closing ? 0 : 1);
+ else
+ return context.indent + (closing ? 0 : indentUnit);
+ },
+
+ lineComment: "#"
+ };
+});
+
+CodeMirror.defineMIME("text/turtle", "turtle");
+
+});
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/twig/twig.js b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/twig/twig.js
new file mode 100644
index 0000000000..a6dd3f1a68
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/twig/twig.js
@@ -0,0 +1,141 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: https://codemirror.net/LICENSE
+
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
+ mod(require("../../lib/codemirror"), require("../../addon/mode/multiplex"));
+ else if (typeof define == "function" && define.amd) // AMD
+ define(["../../lib/codemirror", "../../addon/mode/multiplex"], mod);
+ else // Plain browser env
+ mod(CodeMirror);
+})(function(CodeMirror) {
+ "use strict";
+
+ CodeMirror.defineMode("twig:inner", function() {
+ var keywords = ["and", "as", "autoescape", "endautoescape", "block", "do", "endblock", "else", "elseif", "extends", "for", "endfor", "embed", "endembed", "filter", "endfilter", "flush", "from", "if", "endif", "in", "is", "include", "import", "not", "or", "set", "spaceless", "endspaceless", "with", "endwith", "trans", "endtrans", "blocktrans", "endblocktrans", "macro", "endmacro", "use", "verbatim", "endverbatim"],
+ operator = /^[+\-*&%=<>!?|~^]/,
+ sign = /^[:\[\(\{]/,
+ atom = ["true", "false", "null", "empty", "defined", "divisibleby", "divisible by", "even", "odd", "iterable", "sameas", "same as"],
+ number = /^(\d[+\-\*\/])?\d+(\.\d+)?/;
+
+ keywords = new RegExp("((" + keywords.join(")|(") + "))\\b");
+ atom = new RegExp("((" + atom.join(")|(") + "))\\b");
+
+ function tokenBase (stream, state) {
+ var ch = stream.peek();
+
+ //Comment
+ if (state.incomment) {
+ if (!stream.skipTo("#}")) {
+ stream.skipToEnd();
+ } else {
+ stream.eatWhile(/\#|}/);
+ state.incomment = false;
+ }
+ return "comment";
+ //Tag
+ } else if (state.intag) {
+ //After operator
+ if (state.operator) {
+ state.operator = false;
+ if (stream.match(atom)) {
+ return "atom";
+ }
+ if (stream.match(number)) {
+ return "number";
+ }
+ }
+ //After sign
+ if (state.sign) {
+ state.sign = false;
+ if (stream.match(atom)) {
+ return "atom";
+ }
+ if (stream.match(number)) {
+ return "number";
+ }
+ }
+
+ if (state.instring) {
+ if (ch == state.instring) {
+ state.instring = false;
+ }
+ stream.next();
+ return "string";
+ } else if (ch == "'" || ch == '"') {
+ state.instring = ch;
+ stream.next();
+ return "string";
+ } else if (stream.match(state.intag + "}") || stream.eat("-") && stream.match(state.intag + "}")) {
+ state.intag = false;
+ return "tag";
+ } else if (stream.match(operator)) {
+ state.operator = true;
+ return "operator";
+ } else if (stream.match(sign)) {
+ state.sign = true;
+ } else {
+ if (stream.eat(" ") || stream.sol()) {
+ if (stream.match(keywords)) {
+ return "keyword";
+ }
+ if (stream.match(atom)) {
+ return "atom";
+ }
+ if (stream.match(number)) {
+ return "number";
+ }
+ if (stream.sol()) {
+ stream.next();
+ }
+ } else {
+ stream.next();
+ }
+
+ }
+ return "variable";
+ } else if (stream.eat("{")) {
+ if (stream.eat("#")) {
+ state.incomment = true;
+ if (!stream.skipTo("#}")) {
+ stream.skipToEnd();
+ } else {
+ stream.eatWhile(/\#|}/);
+ state.incomment = false;
+ }
+ return "comment";
+ //Open tag
+ } else if (ch = stream.eat(/\{|%/)) {
+ //Cache close tag
+ state.intag = ch;
+ if (ch == "{") {
+ state.intag = "}";
+ }
+ stream.eat("-");
+ return "tag";
+ }
+ }
+ stream.next();
+ };
+
+ return {
+ startState: function () {
+ return {};
+ },
+ token: function (stream, state) {
+ return tokenBase(stream, state);
+ }
+ };
+ });
+
+ CodeMirror.defineMode("twig", function(config, parserConfig) {
+ var twigInner = CodeMirror.getMode(config, "twig:inner");
+ if (!parserConfig || !parserConfig.base) return twigInner;
+ return CodeMirror.multiplexingMode(
+ CodeMirror.getMode(config, parserConfig.base), {
+ open: /\{[{#%]/, close: /[}#%]\}/, mode: twigInner, parseDelimiters: true
+ }
+ );
+ });
+ CodeMirror.defineMIME("text/x-twig", "twig");
+});
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/vb/vb.js b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/vb/vb.js
new file mode 100644
index 0000000000..6e4b476309
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/vb/vb.js
@@ -0,0 +1,275 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: https://codemirror.net/LICENSE
+
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
+ mod(require("../../lib/codemirror"));
+ else if (typeof define == "function" && define.amd) // AMD
+ define(["../../lib/codemirror"], mod);
+ else // Plain browser env
+ mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("vb", function(conf, parserConf) {
+ var ERRORCLASS = 'error';
+
+ function wordRegexp(words) {
+ return new RegExp("^((" + words.join(")|(") + "))\\b", "i");
+ }
+
+ var singleOperators = new RegExp("^[\\+\\-\\*/%&\\\\|\\^~<>!]");
+ var singleDelimiters = new RegExp('^[\\(\\)\\[\\]\\{\\}@,:`=;\\.]');
+ var doubleOperators = new RegExp("^((==)|(<>)|(<=)|(>=)|(<>)|(<<)|(>>)|(//)|(\\*\\*))");
+ var doubleDelimiters = new RegExp("^((\\+=)|(\\-=)|(\\*=)|(%=)|(/=)|(&=)|(\\|=)|(\\^=))");
+ var tripleDelimiters = new RegExp("^((//=)|(>>=)|(<<=)|(\\*\\*=))");
+ var identifiers = new RegExp("^[_A-Za-z][_A-Za-z0-9]*");
+
+ var openingKeywords = ['class','module', 'sub','enum','select','while','if','function', 'get','set','property', 'try', 'structure', 'synclock', 'using', 'with'];
+ var middleKeywords = ['else','elseif','case', 'catch', 'finally'];
+ var endKeywords = ['next','loop'];
+
+ var operatorKeywords = ['and', "andalso", 'or', 'orelse', 'xor', 'in', 'not', 'is', 'isnot', 'like'];
+ var wordOperators = wordRegexp(operatorKeywords);
+
+ var commonKeywords = ["#const", "#else", "#elseif", "#end", "#if", "#region", "addhandler", "addressof", "alias", "as", "byref", "byval", "cbool", "cbyte", "cchar", "cdate", "cdbl", "cdec", "cint", "clng", "cobj", "compare", "const", "continue", "csbyte", "cshort", "csng", "cstr", "cuint", "culng", "cushort", "declare", "default", "delegate", "dim", "directcast", "each", "erase", "error", "event", "exit", "explicit", "false", "for", "friend", "gettype", "goto", "handles", "implements", "imports", "infer", "inherits", "interface", "isfalse", "istrue", "lib", "me", "mod", "mustinherit", "mustoverride", "my", "mybase", "myclass", "namespace", "narrowing", "new", "nothing", "notinheritable", "notoverridable", "of", "off", "on", "operator", "option", "optional", "out", "overloads", "overridable", "overrides", "paramarray", "partial", "private", "protected", "public", "raiseevent", "readonly", "redim", "removehandler", "resume", "return", "shadows", "shared", "static", "step", "stop", "strict", "then", "throw", "to", "true", "trycast", "typeof", "until", "until", "when", "widening", "withevents", "writeonly"];
+
+ var commontypes = ['object', 'boolean', 'char', 'string', 'byte', 'sbyte', 'short', 'ushort', 'int16', 'uint16', 'integer', 'uinteger', 'int32', 'uint32', 'long', 'ulong', 'int64', 'uint64', 'decimal', 'single', 'double', 'float', 'date', 'datetime', 'intptr', 'uintptr'];
+
+ var keywords = wordRegexp(commonKeywords);
+ var types = wordRegexp(commontypes);
+ var stringPrefixes = '"';
+
+ var opening = wordRegexp(openingKeywords);
+ var middle = wordRegexp(middleKeywords);
+ var closing = wordRegexp(endKeywords);
+ var doubleClosing = wordRegexp(['end']);
+ var doOpening = wordRegexp(['do']);
+
+ var indentInfo = null;
+
+ CodeMirror.registerHelper("hintWords", "vb", openingKeywords.concat(middleKeywords).concat(endKeywords)
+ .concat(operatorKeywords).concat(commonKeywords).concat(commontypes));
+
+ function indent(_stream, state) {
+ state.currentIndent++;
+ }
+
+ function dedent(_stream, state) {
+ state.currentIndent--;
+ }
+ // tokenizers
+ function tokenBase(stream, state) {
+ if (stream.eatSpace()) {
+ return null;
+ }
+
+ var ch = stream.peek();
+
+ // Handle Comments
+ if (ch === "'") {
+ stream.skipToEnd();
+ return 'comment';
+ }
+
+
+ // Handle Number Literals
+ if (stream.match(/^((&H)|(&O))?[0-9\.a-f]/i, false)) {
+ var floatLiteral = false;
+ // Floats
+ if (stream.match(/^\d*\.\d+F?/i)) { floatLiteral = true; }
+ else if (stream.match(/^\d+\.\d*F?/)) { floatLiteral = true; }
+ else if (stream.match(/^\.\d+F?/)) { floatLiteral = true; }
+
+ if (floatLiteral) {
+ // Float literals may be "imaginary"
+ stream.eat(/J/i);
+ return 'number';
+ }
+ // Integers
+ var intLiteral = false;
+ // Hex
+ if (stream.match(/^&H[0-9a-f]+/i)) { intLiteral = true; }
+ // Octal
+ else if (stream.match(/^&O[0-7]+/i)) { intLiteral = true; }
+ // Decimal
+ else if (stream.match(/^[1-9]\d*F?/)) {
+ // Decimal literals may be "imaginary"
+ stream.eat(/J/i);
+ // TODO - Can you have imaginary longs?
+ intLiteral = true;
+ }
+ // Zero by itself with no other piece of number.
+ else if (stream.match(/^0(?![\dx])/i)) { intLiteral = true; }
+ if (intLiteral) {
+ // Integer literals may be "long"
+ stream.eat(/L/i);
+ return 'number';
+ }
+ }
+
+ // Handle Strings
+ if (stream.match(stringPrefixes)) {
+ state.tokenize = tokenStringFactory(stream.current());
+ return state.tokenize(stream, state);
+ }
+
+ // Handle operators and Delimiters
+ if (stream.match(tripleDelimiters) || stream.match(doubleDelimiters)) {
+ return null;
+ }
+ if (stream.match(doubleOperators)
+ || stream.match(singleOperators)
+ || stream.match(wordOperators)) {
+ return 'operator';
+ }
+ if (stream.match(singleDelimiters)) {
+ return null;
+ }
+ if (stream.match(doOpening)) {
+ indent(stream,state);
+ state.doInCurrentLine = true;
+ return 'keyword';
+ }
+ if (stream.match(opening)) {
+ if (! state.doInCurrentLine)
+ indent(stream,state);
+ else
+ state.doInCurrentLine = false;
+ return 'keyword';
+ }
+ if (stream.match(middle)) {
+ return 'keyword';
+ }
+
+ if (stream.match(doubleClosing)) {
+ dedent(stream,state);
+ dedent(stream,state);
+ return 'keyword';
+ }
+ if (stream.match(closing)) {
+ dedent(stream,state);
+ return 'keyword';
+ }
+
+ if (stream.match(types)) {
+ return 'keyword';
+ }
+
+ if (stream.match(keywords)) {
+ return 'keyword';
+ }
+
+ if (stream.match(identifiers)) {
+ return 'variable';
+ }
+
+ // Handle non-detected items
+ stream.next();
+ return ERRORCLASS;
+ }
+
+ function tokenStringFactory(delimiter) {
+ var singleline = delimiter.length == 1;
+ var OUTCLASS = 'string';
+
+ return function(stream, state) {
+ while (!stream.eol()) {
+ stream.eatWhile(/[^'"]/);
+ if (stream.match(delimiter)) {
+ state.tokenize = tokenBase;
+ return OUTCLASS;
+ } else {
+ stream.eat(/['"]/);
+ }
+ }
+ if (singleline) {
+ if (parserConf.singleLineStringErrors) {
+ return ERRORCLASS;
+ } else {
+ state.tokenize = tokenBase;
+ }
+ }
+ return OUTCLASS;
+ };
+ }
+
+
+ function tokenLexer(stream, state) {
+ var style = state.tokenize(stream, state);
+ var current = stream.current();
+
+ // Handle '.' connected identifiers
+ if (current === '.') {
+ style = state.tokenize(stream, state);
+ if (style === 'variable') {
+ return 'variable';
+ } else {
+ return ERRORCLASS;
+ }
+ }
+
+
+ var delimiter_index = '[({'.indexOf(current);
+ if (delimiter_index !== -1) {
+ indent(stream, state );
+ }
+ if (indentInfo === 'dedent') {
+ if (dedent(stream, state)) {
+ return ERRORCLASS;
+ }
+ }
+ delimiter_index = '])}'.indexOf(current);
+ if (delimiter_index !== -1) {
+ if (dedent(stream, state)) {
+ return ERRORCLASS;
+ }
+ }
+
+ return style;
+ }
+
+ var external = {
+ electricChars:"dDpPtTfFeE ",
+ startState: function() {
+ return {
+ tokenize: tokenBase,
+ lastToken: null,
+ currentIndent: 0,
+ nextLineIndent: 0,
+ doInCurrentLine: false
+
+
+ };
+ },
+
+ token: function(stream, state) {
+ if (stream.sol()) {
+ state.currentIndent += state.nextLineIndent;
+ state.nextLineIndent = 0;
+ state.doInCurrentLine = 0;
+ }
+ var style = tokenLexer(stream, state);
+
+ state.lastToken = {style:style, content: stream.current()};
+
+
+
+ return style;
+ },
+
+ indent: function(state, textAfter) {
+ var trueText = textAfter.replace(/^\s+|\s+$/g, '') ;
+ if (trueText.match(closing) || trueText.match(doubleClosing) || trueText.match(middle)) return conf.indentUnit*(state.currentIndent-1);
+ if(state.currentIndent < 0) return 0;
+ return state.currentIndent * conf.indentUnit;
+ },
+
+ lineComment: "'"
+ };
+ return external;
+});
+
+CodeMirror.defineMIME("text/x-vb", "vb");
+
+});
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/vbscript/vbscript.js b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/vbscript/vbscript.js
new file mode 100644
index 0000000000..4033948133
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/vbscript/vbscript.js
@@ -0,0 +1,350 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: https://codemirror.net/LICENSE
+
+/*
+For extra ASP classic objects, initialize CodeMirror instance with this option:
+ isASP: true
+
+E.G.:
+ var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+ lineNumbers: true,
+ isASP: true
+ });
+*/
+
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
+ mod(require("../../lib/codemirror"));
+ else if (typeof define == "function" && define.amd) // AMD
+ define(["../../lib/codemirror"], mod);
+ else // Plain browser env
+ mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("vbscript", function(conf, parserConf) {
+ var ERRORCLASS = 'error';
+
+ function wordRegexp(words) {
+ return new RegExp("^((" + words.join(")|(") + "))\\b", "i");
+ }
+
+ var singleOperators = new RegExp("^[\\+\\-\\*/&\\\\\\^<>=]");
+ var doubleOperators = new RegExp("^((<>)|(<=)|(>=))");
+ var singleDelimiters = new RegExp('^[\\.,]');
+ var brackets = new RegExp('^[\\(\\)]');
+ var identifiers = new RegExp("^[A-Za-z][_A-Za-z0-9]*");
+
+ var openingKeywords = ['class','sub','select','while','if','function', 'property', 'with', 'for'];
+ var middleKeywords = ['else','elseif','case'];
+ var endKeywords = ['next','loop','wend'];
+
+ var wordOperators = wordRegexp(['and', 'or', 'not', 'xor', 'is', 'mod', 'eqv', 'imp']);
+ var commonkeywords = ['dim', 'redim', 'then', 'until', 'randomize',
+ 'byval','byref','new','property', 'exit', 'in',
+ 'const','private', 'public',
+ 'get','set','let', 'stop', 'on error resume next', 'on error goto 0', 'option explicit', 'call', 'me'];
+
+ //This list was from: http://msdn.microsoft.com/en-us/library/f8tbc79x(v=vs.84).aspx
+ var atomWords = ['true', 'false', 'nothing', 'empty', 'null'];
+ //This list was from: http://msdn.microsoft.com/en-us/library/3ca8tfek(v=vs.84).aspx
+ var builtinFuncsWords = ['abs', 'array', 'asc', 'atn', 'cbool', 'cbyte', 'ccur', 'cdate', 'cdbl', 'chr', 'cint', 'clng', 'cos', 'csng', 'cstr', 'date', 'dateadd', 'datediff', 'datepart',
+ 'dateserial', 'datevalue', 'day', 'escape', 'eval', 'execute', 'exp', 'filter', 'formatcurrency', 'formatdatetime', 'formatnumber', 'formatpercent', 'getlocale', 'getobject',
+ 'getref', 'hex', 'hour', 'inputbox', 'instr', 'instrrev', 'int', 'fix', 'isarray', 'isdate', 'isempty', 'isnull', 'isnumeric', 'isobject', 'join', 'lbound', 'lcase', 'left',
+ 'len', 'loadpicture', 'log', 'ltrim', 'rtrim', 'trim', 'maths', 'mid', 'minute', 'month', 'monthname', 'msgbox', 'now', 'oct', 'replace', 'rgb', 'right', 'rnd', 'round',
+ 'scriptengine', 'scriptenginebuildversion', 'scriptenginemajorversion', 'scriptengineminorversion', 'second', 'setlocale', 'sgn', 'sin', 'space', 'split', 'sqr', 'strcomp',
+ 'string', 'strreverse', 'tan', 'time', 'timer', 'timeserial', 'timevalue', 'typename', 'ubound', 'ucase', 'unescape', 'vartype', 'weekday', 'weekdayname', 'year'];
+
+ //This list was from: http://msdn.microsoft.com/en-us/library/ydz4cfk3(v=vs.84).aspx
+ var builtinConsts = ['vbBlack', 'vbRed', 'vbGreen', 'vbYellow', 'vbBlue', 'vbMagenta', 'vbCyan', 'vbWhite', 'vbBinaryCompare', 'vbTextCompare',
+ 'vbSunday', 'vbMonday', 'vbTuesday', 'vbWednesday', 'vbThursday', 'vbFriday', 'vbSaturday', 'vbUseSystemDayOfWeek', 'vbFirstJan1', 'vbFirstFourDays', 'vbFirstFullWeek',
+ 'vbGeneralDate', 'vbLongDate', 'vbShortDate', 'vbLongTime', 'vbShortTime', 'vbObjectError',
+ 'vbOKOnly', 'vbOKCancel', 'vbAbortRetryIgnore', 'vbYesNoCancel', 'vbYesNo', 'vbRetryCancel', 'vbCritical', 'vbQuestion', 'vbExclamation', 'vbInformation', 'vbDefaultButton1', 'vbDefaultButton2',
+ 'vbDefaultButton3', 'vbDefaultButton4', 'vbApplicationModal', 'vbSystemModal', 'vbOK', 'vbCancel', 'vbAbort', 'vbRetry', 'vbIgnore', 'vbYes', 'vbNo',
+ 'vbCr', 'VbCrLf', 'vbFormFeed', 'vbLf', 'vbNewLine', 'vbNullChar', 'vbNullString', 'vbTab', 'vbVerticalTab', 'vbUseDefault', 'vbTrue', 'vbFalse',
+ 'vbEmpty', 'vbNull', 'vbInteger', 'vbLong', 'vbSingle', 'vbDouble', 'vbCurrency', 'vbDate', 'vbString', 'vbObject', 'vbError', 'vbBoolean', 'vbVariant', 'vbDataObject', 'vbDecimal', 'vbByte', 'vbArray'];
+ //This list was from: http://msdn.microsoft.com/en-us/library/hkc375ea(v=vs.84).aspx
+ var builtinObjsWords = ['WScript', 'err', 'debug', 'RegExp'];
+ var knownProperties = ['description', 'firstindex', 'global', 'helpcontext', 'helpfile', 'ignorecase', 'length', 'number', 'pattern', 'source', 'value', 'count'];
+ var knownMethods = ['clear', 'execute', 'raise', 'replace', 'test', 'write', 'writeline', 'close', 'open', 'state', 'eof', 'update', 'addnew', 'end', 'createobject', 'quit'];
+
+ var aspBuiltinObjsWords = ['server', 'response', 'request', 'session', 'application'];
+ var aspKnownProperties = ['buffer', 'cachecontrol', 'charset', 'contenttype', 'expires', 'expiresabsolute', 'isclientconnected', 'pics', 'status', //response
+ 'clientcertificate', 'cookies', 'form', 'querystring', 'servervariables', 'totalbytes', //request
+ 'contents', 'staticobjects', //application
+ 'codepage', 'lcid', 'sessionid', 'timeout', //session
+ 'scripttimeout']; //server
+ var aspKnownMethods = ['addheader', 'appendtolog', 'binarywrite', 'end', 'flush', 'redirect', //response
+ 'binaryread', //request
+ 'remove', 'removeall', 'lock', 'unlock', //application
+ 'abandon', //session
+ 'getlasterror', 'htmlencode', 'mappath', 'transfer', 'urlencode']; //server
+
+ var knownWords = knownMethods.concat(knownProperties);
+
+ builtinObjsWords = builtinObjsWords.concat(builtinConsts);
+
+ if (conf.isASP){
+ builtinObjsWords = builtinObjsWords.concat(aspBuiltinObjsWords);
+ knownWords = knownWords.concat(aspKnownMethods, aspKnownProperties);
+ };
+
+ var keywords = wordRegexp(commonkeywords);
+ var atoms = wordRegexp(atomWords);
+ var builtinFuncs = wordRegexp(builtinFuncsWords);
+ var builtinObjs = wordRegexp(builtinObjsWords);
+ var known = wordRegexp(knownWords);
+ var stringPrefixes = '"';
+
+ var opening = wordRegexp(openingKeywords);
+ var middle = wordRegexp(middleKeywords);
+ var closing = wordRegexp(endKeywords);
+ var doubleClosing = wordRegexp(['end']);
+ var doOpening = wordRegexp(['do']);
+ var noIndentWords = wordRegexp(['on error resume next', 'exit']);
+ var comment = wordRegexp(['rem']);
+
+
+ function indent(_stream, state) {
+ state.currentIndent++;
+ }
+
+ function dedent(_stream, state) {
+ state.currentIndent--;
+ }
+ // tokenizers
+ function tokenBase(stream, state) {
+ if (stream.eatSpace()) {
+ return 'space';
+ //return null;
+ }
+
+ var ch = stream.peek();
+
+ // Handle Comments
+ if (ch === "'") {
+ stream.skipToEnd();
+ return 'comment';
+ }
+ if (stream.match(comment)){
+ stream.skipToEnd();
+ return 'comment';
+ }
+
+
+ // Handle Number Literals
+ if (stream.match(/^((&H)|(&O))?[0-9\.]/i, false) && !stream.match(/^((&H)|(&O))?[0-9\.]+[a-z_]/i, false)) {
+ var floatLiteral = false;
+ // Floats
+ if (stream.match(/^\d*\.\d+/i)) { floatLiteral = true; }
+ else if (stream.match(/^\d+\.\d*/)) { floatLiteral = true; }
+ else if (stream.match(/^\.\d+/)) { floatLiteral = true; }
+
+ if (floatLiteral) {
+ // Float literals may be "imaginary"
+ stream.eat(/J/i);
+ return 'number';
+ }
+ // Integers
+ var intLiteral = false;
+ // Hex
+ if (stream.match(/^&H[0-9a-f]+/i)) { intLiteral = true; }
+ // Octal
+ else if (stream.match(/^&O[0-7]+/i)) { intLiteral = true; }
+ // Decimal
+ else if (stream.match(/^[1-9]\d*F?/)) {
+ // Decimal literals may be "imaginary"
+ stream.eat(/J/i);
+ // TODO - Can you have imaginary longs?
+ intLiteral = true;
+ }
+ // Zero by itself with no other piece of number.
+ else if (stream.match(/^0(?![\dx])/i)) { intLiteral = true; }
+ if (intLiteral) {
+ // Integer literals may be "long"
+ stream.eat(/L/i);
+ return 'number';
+ }
+ }
+
+ // Handle Strings
+ if (stream.match(stringPrefixes)) {
+ state.tokenize = tokenStringFactory(stream.current());
+ return state.tokenize(stream, state);
+ }
+
+ // Handle operators and Delimiters
+ if (stream.match(doubleOperators)
+ || stream.match(singleOperators)
+ || stream.match(wordOperators)) {
+ return 'operator';
+ }
+ if (stream.match(singleDelimiters)) {
+ return null;
+ }
+
+ if (stream.match(brackets)) {
+ return "bracket";
+ }
+
+ if (stream.match(noIndentWords)) {
+ state.doInCurrentLine = true;
+
+ return 'keyword';
+ }
+
+ if (stream.match(doOpening)) {
+ indent(stream,state);
+ state.doInCurrentLine = true;
+
+ return 'keyword';
+ }
+ if (stream.match(opening)) {
+ if (! state.doInCurrentLine)
+ indent(stream,state);
+ else
+ state.doInCurrentLine = false;
+
+ return 'keyword';
+ }
+ if (stream.match(middle)) {
+ return 'keyword';
+ }
+
+
+ if (stream.match(doubleClosing)) {
+ dedent(stream,state);
+ dedent(stream,state);
+
+ return 'keyword';
+ }
+ if (stream.match(closing)) {
+ if (! state.doInCurrentLine)
+ dedent(stream,state);
+ else
+ state.doInCurrentLine = false;
+
+ return 'keyword';
+ }
+
+ if (stream.match(keywords)) {
+ return 'keyword';
+ }
+
+ if (stream.match(atoms)) {
+ return 'atom';
+ }
+
+ if (stream.match(known)) {
+ return 'variable-2';
+ }
+
+ if (stream.match(builtinFuncs)) {
+ return 'builtin';
+ }
+
+ if (stream.match(builtinObjs)){
+ return 'variable-2';
+ }
+
+ if (stream.match(identifiers)) {
+ return 'variable';
+ }
+
+ // Handle non-detected items
+ stream.next();
+ return ERRORCLASS;
+ }
+
+ function tokenStringFactory(delimiter) {
+ var singleline = delimiter.length == 1;
+ var OUTCLASS = 'string';
+
+ return function(stream, state) {
+ while (!stream.eol()) {
+ stream.eatWhile(/[^'"]/);
+ if (stream.match(delimiter)) {
+ state.tokenize = tokenBase;
+ return OUTCLASS;
+ } else {
+ stream.eat(/['"]/);
+ }
+ }
+ if (singleline) {
+ if (parserConf.singleLineStringErrors) {
+ return ERRORCLASS;
+ } else {
+ state.tokenize = tokenBase;
+ }
+ }
+ return OUTCLASS;
+ };
+ }
+
+
+ function tokenLexer(stream, state) {
+ var style = state.tokenize(stream, state);
+ var current = stream.current();
+
+ // Handle '.' connected identifiers
+ if (current === '.') {
+ style = state.tokenize(stream, state);
+
+ current = stream.current();
+ if (style && (style.substr(0, 8) === 'variable' || style==='builtin' || style==='keyword')){//|| knownWords.indexOf(current.substring(1)) > -1) {
+ if (style === 'builtin' || style === 'keyword') style='variable';
+ if (knownWords.indexOf(current.substr(1)) > -1) style='variable-2';
+
+ return style;
+ } else {
+ return ERRORCLASS;
+ }
+ }
+
+ return style;
+ }
+
+ var external = {
+ electricChars:"dDpPtTfFeE ",
+ startState: function() {
+ return {
+ tokenize: tokenBase,
+ lastToken: null,
+ currentIndent: 0,
+ nextLineIndent: 0,
+ doInCurrentLine: false,
+ ignoreKeyword: false
+
+
+ };
+ },
+
+ token: function(stream, state) {
+ if (stream.sol()) {
+ state.currentIndent += state.nextLineIndent;
+ state.nextLineIndent = 0;
+ state.doInCurrentLine = 0;
+ }
+ var style = tokenLexer(stream, state);
+
+ state.lastToken = {style:style, content: stream.current()};
+
+ if (style==='space') style=null;
+
+ return style;
+ },
+
+ indent: function(state, textAfter) {
+ var trueText = textAfter.replace(/^\s+|\s+$/g, '') ;
+ if (trueText.match(closing) || trueText.match(doubleClosing) || trueText.match(middle)) return conf.indentUnit*(state.currentIndent-1);
+ if(state.currentIndent < 0) return 0;
+ return state.currentIndent * conf.indentUnit;
+ }
+
+ };
+ return external;
+});
+
+CodeMirror.defineMIME("text/vbscript", "vbscript");
+
+});
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/velocity/velocity.js b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/velocity/velocity.js
new file mode 100644
index 0000000000..79a621a5b0
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/velocity/velocity.js
@@ -0,0 +1,202 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: https://codemirror.net/LICENSE
+
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
+ mod(require("../../lib/codemirror"));
+ else if (typeof define == "function" && define.amd) // AMD
+ define(["../../lib/codemirror"], mod);
+ else // Plain browser env
+ mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("velocity", function() {
+ function parseWords(str) {
+ var obj = {}, words = str.split(" ");
+ for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
+ return obj;
+ }
+
+ var keywords = parseWords("#end #else #break #stop #[[ #]] " +
+ "#{end} #{else} #{break} #{stop}");
+ var functions = parseWords("#if #elseif #foreach #set #include #parse #macro #define #evaluate " +
+ "#{if} #{elseif} #{foreach} #{set} #{include} #{parse} #{macro} #{define} #{evaluate}");
+ var specials = parseWords("$foreach.count $foreach.hasNext $foreach.first $foreach.last $foreach.topmost $foreach.parent.count $foreach.parent.hasNext $foreach.parent.first $foreach.parent.last $foreach.parent $velocityCount $!bodyContent $bodyContent");
+ var isOperatorChar = /[+\-*&%=<>!?:\/|]/;
+
+ function chain(stream, state, f) {
+ state.tokenize = f;
+ return f(stream, state);
+ }
+ function tokenBase(stream, state) {
+ var beforeParams = state.beforeParams;
+ state.beforeParams = false;
+ var ch = stream.next();
+ // start of unparsed string?
+ if ((ch == "'") && !state.inString && state.inParams) {
+ state.lastTokenWasBuiltin = false;
+ return chain(stream, state, tokenString(ch));
+ }
+ // start of parsed string?
+ else if ((ch == '"')) {
+ state.lastTokenWasBuiltin = false;
+ if (state.inString) {
+ state.inString = false;
+ return "string";
+ }
+ else if (state.inParams)
+ return chain(stream, state, tokenString(ch));
+ }
+ // is it one of the special signs []{}().,;? Separator?
+ else if (/[\[\]{}\(\),;\.]/.test(ch)) {
+ if (ch == "(" && beforeParams)
+ state.inParams = true;
+ else if (ch == ")") {
+ state.inParams = false;
+ state.lastTokenWasBuiltin = true;
+ }
+ return null;
+ }
+ // start of a number value?
+ else if (/\d/.test(ch)) {
+ state.lastTokenWasBuiltin = false;
+ stream.eatWhile(/[\w\.]/);
+ return "number";
+ }
+ // multi line comment?
+ else if (ch == "#" && stream.eat("*")) {
+ state.lastTokenWasBuiltin = false;
+ return chain(stream, state, tokenComment);
+ }
+ // unparsed content?
+ else if (ch == "#" && stream.match(/ *\[ *\[/)) {
+ state.lastTokenWasBuiltin = false;
+ return chain(stream, state, tokenUnparsed);
+ }
+ // single line comment?
+ else if (ch == "#" && stream.eat("#")) {
+ state.lastTokenWasBuiltin = false;
+ stream.skipToEnd();
+ return "comment";
+ }
+ // variable?
+ else if (ch == "$") {
+ stream.eat("!");
+ stream.eatWhile(/[\w\d\$_\.{}-]/);
+ // is it one of the specials?
+ if (specials && specials.propertyIsEnumerable(stream.current())) {
+ return "keyword";
+ }
+ else {
+ state.lastTokenWasBuiltin = true;
+ state.beforeParams = true;
+ return "builtin";
+ }
+ }
+ // is it a operator?
+ else if (isOperatorChar.test(ch)) {
+ state.lastTokenWasBuiltin = false;
+ stream.eatWhile(isOperatorChar);
+ return "operator";
+ }
+ else {
+ // get the whole word
+ stream.eatWhile(/[\w\$_{}@]/);
+ var word = stream.current();
+ // is it one of the listed keywords?
+ if (keywords && keywords.propertyIsEnumerable(word))
+ return "keyword";
+ // is it one of the listed functions?
+ if (functions && functions.propertyIsEnumerable(word) ||
+ (stream.current().match(/^#@?[a-z0-9_]+ *$/i) && stream.peek()=="(") &&
+ !(functions && functions.propertyIsEnumerable(word.toLowerCase()))) {
+ state.beforeParams = true;
+ state.lastTokenWasBuiltin = false;
+ return "keyword";
+ }
+ if (state.inString) {
+ state.lastTokenWasBuiltin = false;
+ return "string";
+ }
+ if (stream.pos > word.length && stream.string.charAt(stream.pos-word.length-1)=="." && state.lastTokenWasBuiltin)
+ return "builtin";
+ // default: just a "word"
+ state.lastTokenWasBuiltin = false;
+ return null;
+ }
+ }
+
+ function tokenString(quote) {
+ return function(stream, state) {
+ var escaped = false, next, end = false;
+ while ((next = stream.next()) != null) {
+ if ((next == quote) && !escaped) {
+ end = true;
+ break;
+ }
+ if (quote=='"' && stream.peek() == '$' && !escaped) {
+ state.inString = true;
+ end = true;
+ break;
+ }
+ escaped = !escaped && next == "\\";
+ }
+ if (end) state.tokenize = tokenBase;
+ return "string";
+ };
+ }
+
+ function tokenComment(stream, state) {
+ var maybeEnd = false, ch;
+ while (ch = stream.next()) {
+ if (ch == "#" && maybeEnd) {
+ state.tokenize = tokenBase;
+ break;
+ }
+ maybeEnd = (ch == "*");
+ }
+ return "comment";
+ }
+
+ function tokenUnparsed(stream, state) {
+ var maybeEnd = 0, ch;
+ while (ch = stream.next()) {
+ if (ch == "#" && maybeEnd == 2) {
+ state.tokenize = tokenBase;
+ break;
+ }
+ if (ch == "]")
+ maybeEnd++;
+ else if (ch != " ")
+ maybeEnd = 0;
+ }
+ return "meta";
+ }
+ // Interface
+
+ return {
+ startState: function() {
+ return {
+ tokenize: tokenBase,
+ beforeParams: false,
+ inParams: false,
+ inString: false,
+ lastTokenWasBuiltin: false
+ };
+ },
+
+ token: function(stream, state) {
+ if (stream.eatSpace()) return null;
+ return state.tokenize(stream, state);
+ },
+ blockCommentStart: "#*",
+ blockCommentEnd: "*#",
+ lineComment: "##",
+ fold: "velocity"
+ };
+});
+
+CodeMirror.defineMIME("text/velocity", "velocity");
+
+});
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/verilog/verilog.js b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/verilog/verilog.js
new file mode 100644
index 0000000000..6c799f298b
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/verilog/verilog.js
@@ -0,0 +1,781 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: https://codemirror.net/LICENSE
+
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
+ mod(require("../../lib/codemirror"));
+ else if (typeof define == "function" && define.amd) // AMD
+ define(["../../lib/codemirror"], mod);
+ else // Plain browser env
+ mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("verilog", function(config, parserConfig) {
+
+ var indentUnit = config.indentUnit,
+ statementIndentUnit = parserConfig.statementIndentUnit || indentUnit,
+ dontAlignCalls = parserConfig.dontAlignCalls,
+ // compilerDirectivesUseRegularIndentation - If set, Compiler directive
+ // indentation follows the same rules as everything else. Otherwise if
+ // false, compiler directives will track their own indentation.
+ // For example, `ifdef nested inside another `ifndef will be indented,
+ // but a `ifdef inside a function block may not be indented.
+ compilerDirectivesUseRegularIndentation = parserConfig.compilerDirectivesUseRegularIndentation,
+ noIndentKeywords = parserConfig.noIndentKeywords || [],
+ multiLineStrings = parserConfig.multiLineStrings,
+ hooks = parserConfig.hooks || {};
+
+ function words(str) {
+ var obj = {}, words = str.split(" ");
+ for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
+ return obj;
+ }
+
+ /**
+ * Keywords from IEEE 1800-2012
+ */
+ var keywords = words(
+ "accept_on alias always always_comb always_ff always_latch and assert assign assume automatic before begin bind " +
+ "bins binsof bit break buf bufif0 bufif1 byte case casex casez cell chandle checker class clocking cmos config " +
+ "const constraint context continue cover covergroup coverpoint cross deassign default defparam design disable " +
+ "dist do edge else end endcase endchecker endclass endclocking endconfig endfunction endgenerate endgroup " +
+ "endinterface endmodule endpackage endprimitive endprogram endproperty endspecify endsequence endtable endtask " +
+ "enum event eventually expect export extends extern final first_match for force foreach forever fork forkjoin " +
+ "function generate genvar global highz0 highz1 if iff ifnone ignore_bins illegal_bins implements implies import " +
+ "incdir include initial inout input inside instance int integer interconnect interface intersect join join_any " +
+ "join_none large let liblist library local localparam logic longint macromodule matches medium modport module " +
+ "nand negedge nettype new nexttime nmos nor noshowcancelled not notif0 notif1 null or output package packed " +
+ "parameter pmos posedge primitive priority program property protected pull0 pull1 pulldown pullup " +
+ "pulsestyle_ondetect pulsestyle_onevent pure rand randc randcase randsequence rcmos real realtime ref reg " +
+ "reject_on release repeat restrict return rnmos rpmos rtran rtranif0 rtranif1 s_always s_eventually s_nexttime " +
+ "s_until s_until_with scalared sequence shortint shortreal showcancelled signed small soft solve specify " +
+ "specparam static string strong strong0 strong1 struct super supply0 supply1 sync_accept_on sync_reject_on " +
+ "table tagged task this throughout time timeprecision timeunit tran tranif0 tranif1 tri tri0 tri1 triand trior " +
+ "trireg type typedef union unique unique0 unsigned until until_with untyped use uwire var vectored virtual void " +
+ "wait wait_order wand weak weak0 weak1 while wildcard wire with within wor xnor xor");
+
+ /** Operators from IEEE 1800-2012
+ unary_operator ::=
+ + | - | ! | ~ | & | ~& | | | ~| | ^ | ~^ | ^~
+ binary_operator ::=
+ + | - | * | / | % | == | != | === | !== | ==? | !=? | && | || | **
+ | < | <= | > | >= | & | | | ^ | ^~ | ~^ | >> | << | >>> | <<<
+ | -> | <->
+ inc_or_dec_operator ::= ++ | --
+ unary_module_path_operator ::=
+ ! | ~ | & | ~& | | | ~| | ^ | ~^ | ^~
+ binary_module_path_operator ::=
+ == | != | && | || | & | | | ^ | ^~ | ~^
+ */
+ var isOperatorChar = /[\+\-\*\/!~&|^%=?:<>]/;
+ var isBracketChar = /[\[\]{}()]/;
+
+ var unsignedNumber = /\d[0-9_]*/;
+ var decimalLiteral = /\d*\s*'s?d\s*\d[0-9_]*/i;
+ var binaryLiteral = /\d*\s*'s?b\s*[xz01][xz01_]*/i;
+ var octLiteral = /\d*\s*'s?o\s*[xz0-7][xz0-7_]*/i;
+ var hexLiteral = /\d*\s*'s?h\s*[0-9a-fxz?][0-9a-fxz?_]*/i;
+ var realLiteral = /(\d[\d_]*(\.\d[\d_]*)?E-?[\d_]+)|(\d[\d_]*\.\d[\d_]*)/i;
+
+ var closingBracketOrWord = /^((`?\w+)|[)}\]])/;
+ var closingBracket = /[)}\]]/;
+ var compilerDirectiveRegex = new RegExp(
+ "^(`(?:ifdef|ifndef|elsif|else|endif|undef|undefineall|define|include|begin_keywords|celldefine|default|" +
+ "nettype|end_keywords|endcelldefine|line|nounconnected_drive|pragma|resetall|timescale|unconnected_drive))\\b");
+ var compilerDirectiveBeginRegex = /^(`(?:ifdef|ifndef|elsif|else))\b/;
+ var compilerDirectiveEndRegex = /^(`(?:elsif|else|endif))\b/;
+
+ var curPunc;
+ var curKeyword;
+
+ // Block openings which are closed by a matching keyword in the form of ("end" + keyword)
+ // E.g. "task" => "endtask"
+ var blockKeywords = words(
+ "case checker class clocking config function generate interface module package " +
+ "primitive program property specify sequence table task"
+ );
+
+ // Opening/closing pairs
+ var openClose = {};
+ for (var keyword in blockKeywords) {
+ openClose[keyword] = "end" + keyword;
+ }
+ openClose["begin"] = "end";
+ openClose["casex"] = "endcase";
+ openClose["casez"] = "endcase";
+ openClose["do" ] = "while";
+ openClose["fork" ] = "join;join_any;join_none";
+ openClose["covergroup"] = "endgroup";
+ openClose["macro_begin"] = "macro_end";
+
+ for (var i in noIndentKeywords) {
+ var keyword = noIndentKeywords[i];
+ if (openClose[keyword]) {
+ openClose[keyword] = undefined;
+ }
+ }
+
+ // Keywords which open statements that are ended with a semi-colon
+ var statementKeywords = words("always always_comb always_ff always_latch assert assign assume else export for foreach forever if import initial repeat while extern typedef");
+
+ function tokenBase(stream, state) {
+ var ch = stream.peek(), style;
+ if (hooks[ch] && (style = hooks[ch](stream, state)) != false) return style;
+ if (hooks.tokenBase && (style = hooks.tokenBase(stream, state)) != false)
+ return style;
+
+ if (/[,;:\.]/.test(ch)) {
+ curPunc = stream.next();
+ return null;
+ }
+ if (isBracketChar.test(ch)) {
+ curPunc = stream.next();
+ return "bracket";
+ }
+ // Macros (tick-defines)
+ if (ch == '`') {
+ stream.next();
+ if (stream.eatWhile(/[\w\$_]/)) {
+ var cur = stream.current();
+ curKeyword = cur;
+ // Macros that end in _begin, are start of block and end with _end
+ if (cur.startsWith("`uvm_") && cur.endsWith("_begin")) {
+ var keywordClose = curKeyword.substr(0,curKeyword.length - 5) + "end";
+ openClose[cur] = keywordClose;
+ curPunc = "newblock";
+ } else {
+ stream.eatSpace();
+ if (stream.peek() == '(') {
+ // Check if this is a block
+ curPunc = "newmacro";
+ }
+ var withSpace = stream.current();
+ // Move the stream back before the spaces
+ stream.backUp(withSpace.length - cur.length);
+ }
+ return "def";
+ } else {
+ return null;
+ }
+ }
+ // System calls
+ if (ch == '$') {
+ stream.next();
+ if (stream.eatWhile(/[\w\$_]/)) {
+ return "meta";
+ } else {
+ return null;
+ }
+ }
+ // Time literals
+ if (ch == '#') {
+ stream.next();
+ stream.eatWhile(/[\d_.]/);
+ return "def";
+ }
+ // Event
+ if (ch == '@') {
+ stream.next();
+ stream.eatWhile(/[@]/);
+ return "def";
+ }
+ // Strings
+ if (ch == '"') {
+ stream.next();
+ state.tokenize = tokenString(ch);
+ return state.tokenize(stream, state);
+ }
+ // Comments
+ if (ch == "/") {
+ stream.next();
+ if (stream.eat("*")) {
+ state.tokenize = tokenComment;
+ return tokenComment(stream, state);
+ }
+ if (stream.eat("/")) {
+ stream.skipToEnd();
+ return "comment";
+ }
+ stream.backUp(1);
+ }
+
+ // Numeric literals
+ if (stream.match(realLiteral) ||
+ stream.match(decimalLiteral) ||
+ stream.match(binaryLiteral) ||
+ stream.match(octLiteral) ||
+ stream.match(hexLiteral) ||
+ stream.match(unsignedNumber) ||
+ stream.match(realLiteral)) {
+ return "number";
+ }
+
+ // Operators
+ if (stream.eatWhile(isOperatorChar)) {
+ curPunc = stream.current();
+ return "meta";
+ }
+
+ // Keywords / plain variables
+ if (stream.eatWhile(/[\w\$_]/)) {
+ var cur = stream.current();
+ if (keywords[cur]) {
+ if (openClose[cur]) {
+ curPunc = "newblock";
+ if (cur === "fork") {
+ // Fork can be a statement instead of block in cases of:
+ // "disable fork;" and "wait fork;" (trailing semicolon)
+ stream.eatSpace()
+ if (stream.peek() == ';') {
+ curPunc = "newstatement";
+ }
+ stream.backUp(stream.current().length - cur.length);
+ }
+ }
+ if (statementKeywords[cur]) {
+ curPunc = "newstatement";
+ }
+ curKeyword = cur;
+ return "keyword";
+ }
+ return "variable";
+ }
+
+ stream.next();
+ return null;
+ }
+
+ function tokenString(quote) {
+ return function(stream, state) {
+ var escaped = false, next, end = false;
+ while ((next = stream.next()) != null) {
+ if (next == quote && !escaped) {end = true; break;}
+ escaped = !escaped && next == "\\";
+ }
+ if (end || !(escaped || multiLineStrings))
+ state.tokenize = tokenBase;
+ return "string";
+ };
+ }
+
+ function tokenComment(stream, state) {
+ var maybeEnd = false, ch;
+ while (ch = stream.next()) {
+ if (ch == "/" && maybeEnd) {
+ state.tokenize = tokenBase;
+ break;
+ }
+ maybeEnd = (ch == "*");
+ }
+ return "comment";
+ }
+
+ function Context(indented, column, type, scopekind, align, prev) {
+ this.indented = indented;
+ this.column = column;
+ this.type = type;
+ this.scopekind = scopekind;
+ this.align = align;
+ this.prev = prev;
+ }
+ function pushContext(state, col, type, scopekind) {
+ var indent = state.indented;
+ var c = new Context(indent, col, type, scopekind ? scopekind : "", null, state.context);
+ return state.context = c;
+ }
+ function popContext(state) {
+ var t = state.context.type;
+ if (t == ")" || t == "]" || t == "}") {
+ state.indented = state.context.indented;
+ }
+ return state.context = state.context.prev;
+ }
+
+ function isClosing(text, contextClosing) {
+ if (text == contextClosing) {
+ return true;
+ } else {
+ // contextClosing may be multiple keywords separated by ;
+ var closingKeywords = contextClosing.split(";");
+ for (var i in closingKeywords) {
+ if (text == closingKeywords[i]) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
+ function isInsideScopeKind(ctx, scopekind) {
+ if (ctx == null) {
+ return false;
+ }
+ if (ctx.scopekind === scopekind) {
+ return true;
+ }
+ return isInsideScopeKind(ctx.prev, scopekind);
+ }
+
+ function buildElectricInputRegEx() {
+ // Reindentation should occur on any bracket char: {}()[]
+ // or on a match of any of the block closing keywords, at
+ // the end of a line
+ var allClosings = [];
+ for (var i in openClose) {
+ if (openClose[i]) {
+ var closings = openClose[i].split(";");
+ for (var j in closings) {
+ allClosings.push(closings[j]);
+ }
+ }
+ }
+ var re = new RegExp("[{}()\\[\\]]|(" + allClosings.join("|") + ")$");
+ return re;
+ }
+
+ // Interface
+ return {
+
+ // Regex to force current line to reindent
+ electricInput: buildElectricInputRegEx(),
+
+ startState: function(basecolumn) {
+ var state = {
+ tokenize: null,
+ context: new Context((basecolumn || 0) - indentUnit, 0, "top", "top", false),
+ indented: 0,
+ compilerDirectiveIndented: 0,
+ startOfLine: true
+ };
+ if (hooks.startState) hooks.startState(state);
+ return state;
+ },
+
+ token: function(stream, state) {
+ var ctx = state.context;
+ if (stream.sol()) {
+ if (ctx.align == null) ctx.align = false;
+ state.indented = stream.indentation();
+ state.startOfLine = true;
+ }
+ if (hooks.token) {
+ // Call hook, with an optional return value of a style to override verilog styling.
+ var style = hooks.token(stream, state);
+ if (style !== undefined) {
+ return style;
+ }
+ }
+ if (stream.eatSpace()) return null;
+ curPunc = null;
+ curKeyword = null;
+ var style = (state.tokenize || tokenBase)(stream, state);
+ if (style == "comment" || style == "meta" || style == "variable") {
+ if (((curPunc === "=") || (curPunc === "<=")) && !isInsideScopeKind(ctx, "assignment")) {
+ // '<=' could be nonblocking assignment or lessthan-equals (which shouldn't cause indent)
+ // Search through the context to see if we are already in an assignment.
+ // '=' could be inside port declaration with comma or ')' afterward, or inside for(;;) block.
+ pushContext(state, stream.column() + curPunc.length, "assignment", "assignment");
+ if (ctx.align == null) ctx.align = true;
+ }
+ return style;
+ }
+ if (ctx.align == null) ctx.align = true;
+
+ var isClosingAssignment = ctx.type == "assignment" &&
+ closingBracket.test(curPunc) && ctx.prev && ctx.prev.type === curPunc;
+ if (curPunc == ctx.type || isClosingAssignment) {
+ if (isClosingAssignment) {
+ ctx = popContext(state);
+ }
+ ctx = popContext(state);
+ if (curPunc == ")") {
+ // Handle closing macros, assuming they could have a semicolon or begin/end block inside.
+ if (ctx && (ctx.type === "macro")) {
+ ctx = popContext(state);
+ while (ctx && (ctx.type == "statement" || ctx.type == "assignment")) ctx = popContext(state);
+ }
+ } else if (curPunc == "}") {
+ // Handle closing statements like constraint block: "foreach () {}" which
+ // do not have semicolon at end.
+ if (ctx && (ctx.type === "statement")) {
+ while (ctx && (ctx.type == "statement")) ctx = popContext(state);
+ }
+ }
+ } else if (((curPunc == ";" || curPunc == ",") && (ctx.type == "statement" || ctx.type == "assignment")) ||
+ (ctx.type && isClosing(curKeyword, ctx.type))) {
+ ctx = popContext(state);
+ while (ctx && (ctx.type == "statement" || ctx.type == "assignment")) ctx = popContext(state);
+ } else if (curPunc == "{") {
+ pushContext(state, stream.column(), "}");
+ } else if (curPunc == "[") {
+ pushContext(state, stream.column(), "]");
+ } else if (curPunc == "(") {
+ pushContext(state, stream.column(), ")");
+ } else if (ctx && ctx.type == "endcase" && curPunc == ":") {
+ pushContext(state, stream.column(), "statement", "case");
+ } else if (curPunc == "newstatement") {
+ pushContext(state, stream.column(), "statement", curKeyword);
+ } else if (curPunc == "newblock") {
+ if (curKeyword == "function" && ctx && (ctx.type == "statement" || ctx.type == "endgroup")) {
+ // The 'function' keyword can appear in some other contexts where it actually does not
+ // indicate a function (import/export DPI and covergroup definitions).
+ // Do nothing in this case
+ } else if (curKeyword == "task" && ctx && ctx.type == "statement") {
+ // Same thing for task
+ } else if (curKeyword == "class" && ctx && ctx.type == "statement") {
+ // Same thing for class (e.g. typedef)
+ } else {
+ var close = openClose[curKeyword];
+ pushContext(state, stream.column(), close, curKeyword);
+ }
+ } else if (curPunc == "newmacro" || (curKeyword && curKeyword.match(compilerDirectiveRegex))) {
+ if (curPunc == "newmacro") {
+ // Macros (especially if they have parenthesis) potentially have a semicolon
+ // or complete statement/block inside, and should be treated as such.
+ pushContext(state, stream.column(), "macro", "macro");
+ }
+ if (curKeyword.match(compilerDirectiveEndRegex)) {
+ state.compilerDirectiveIndented -= statementIndentUnit;
+ }
+ if (curKeyword.match(compilerDirectiveBeginRegex)) {
+ state.compilerDirectiveIndented += statementIndentUnit;
+ }
+ }
+
+ state.startOfLine = false;
+ return style;
+ },
+
+ indent: function(state, textAfter) {
+ if (state.tokenize != tokenBase && state.tokenize != null) return CodeMirror.Pass;
+ if (hooks.indent) {
+ var fromHook = hooks.indent(state);
+ if (fromHook >= 0) return fromHook;
+ }
+ var ctx = state.context, firstChar = textAfter && textAfter.charAt(0);
+ if (ctx.type == "statement" && firstChar == "}") ctx = ctx.prev;
+ var closing = false;
+ var possibleClosing = textAfter.match(closingBracketOrWord);
+ if (possibleClosing)
+ closing = isClosing(possibleClosing[0], ctx.type);
+ if (!compilerDirectivesUseRegularIndentation && textAfter.match(compilerDirectiveRegex)) {
+ if (textAfter.match(compilerDirectiveEndRegex)) {
+ return state.compilerDirectiveIndented - statementIndentUnit;
+ }
+ return state.compilerDirectiveIndented;
+ }
+ if (ctx.type == "statement") return ctx.indented + (firstChar == "{" ? 0 : statementIndentUnit);
+ else if ((closingBracket.test(ctx.type) || ctx.type == "assignment")
+ && ctx.align && !dontAlignCalls) return ctx.column + (closing ? 0 : 1);
+ else if (ctx.type == ")" && !closing) return ctx.indented + statementIndentUnit;
+ else return ctx.indented + (closing ? 0 : indentUnit);
+ },
+
+ blockCommentStart: "/*",
+ blockCommentEnd: "*/",
+ lineComment: "//",
+ fold: "indent"
+ };
+});
+
+ CodeMirror.defineMIME("text/x-verilog", {
+ name: "verilog"
+ });
+
+ CodeMirror.defineMIME("text/x-systemverilog", {
+ name: "verilog"
+ });
+
+
+
+ // TL-Verilog mode.
+ // See tl-x.org for language spec.
+ // See the mode in action at makerchip.com.
+ // Contact: steve.hoover@redwoodeda.com
+
+ // TLV Identifier prefixes.
+ // Note that sign is not treated separately, so "+/-" versions of numeric identifiers
+ // are included.
+ var tlvIdentifierStyle = {
+ "|": "link",
+ ">": "property", // Should condition this off for > TLV 1c.
+ "$": "variable",
+ "$$": "variable",
+ "?$": "qualifier",
+ "?*": "qualifier",
+ "-": "hr",
+ "/": "property",
+ "/-": "property",
+ "@": "variable-3",
+ "@-": "variable-3",
+ "@++": "variable-3",
+ "@+=": "variable-3",
+ "@+=-": "variable-3",
+ "@--": "variable-3",
+ "@-=": "variable-3",
+ "%+": "tag",
+ "%-": "tag",
+ "%": "tag",
+ ">>": "tag",
+ "<<": "tag",
+ "<>": "tag",
+ "#": "tag", // Need to choose a style for this.
+ "^": "attribute",
+ "^^": "attribute",
+ "^!": "attribute",
+ "*": "variable-2",
+ "**": "variable-2",
+ "\\": "keyword",
+ "\"": "comment"
+ };
+
+ // Lines starting with these characters define scope (result in indentation).
+ var tlvScopePrefixChars = {
+ "/": "beh-hier",
+ ">": "beh-hier",
+ "-": "phys-hier",
+ "|": "pipe",
+ "?": "when",
+ "@": "stage",
+ "\\": "keyword"
+ };
+ var tlvIndentUnit = 3;
+ var tlvTrackStatements = false;
+ var tlvIdentMatch = /^([~!@#\$%\^&\*-\+=\?\/\\\|'"<>]+)([\d\w_]*)/; // Matches an identifier.
+ // Note that ':' is excluded, because of it's use in [:].
+ var tlvFirstLevelIndentMatch = /^[! ] /;
+ var tlvLineIndentationMatch = /^[! ] */;
+ var tlvCommentMatch = /^\/[\/\*]/;
+
+
+ // Returns a style specific to the scope at the given indentation column.
+ // Type is one of: "indent", "scope-ident", "before-scope-ident".
+ function tlvScopeStyle(state, indentation, type) {
+ // Begin scope.
+ var depth = indentation / tlvIndentUnit; // TODO: Pass this in instead.
+ return "tlv-" + state.tlvIndentationStyle[depth] + "-" + type;
+ }
+
+ // Return true if the next thing in the stream is an identifier with a mnemonic.
+ function tlvIdentNext(stream) {
+ var match;
+ return (match = stream.match(tlvIdentMatch, false)) && match[2].length > 0;
+ }
+
+ CodeMirror.defineMIME("text/x-tlv", {
+ name: "verilog",
+
+ hooks: {
+
+ electricInput: false,
+
+
+ // Return undefined for verilog tokenizing, or style for TLV token (null not used).
+ // Standard CM styles are used for most formatting, but some TL-Verilog-specific highlighting
+ // can be enabled with the definition of cm-tlv-* styles, including highlighting for:
+ // - M4 tokens
+ // - TLV scope indentation
+ // - Statement delimitation (enabled by tlvTrackStatements)
+ token: function(stream, state) {
+ var style = undefined;
+ var match; // Return value of pattern matches.
+
+ // Set highlighting mode based on code region (TLV or SV).
+ if (stream.sol() && ! state.tlvInBlockComment) {
+ // Process region.
+ if (stream.peek() == '\\') {
+ style = "def";
+ stream.skipToEnd();
+ if (stream.string.match(/\\SV/)) {
+ state.tlvCodeActive = false;
+ } else if (stream.string.match(/\\TLV/)){
+ state.tlvCodeActive = true;
+ }
+ }
+ // Correct indentation in the face of a line prefix char.
+ if (state.tlvCodeActive && stream.pos == 0 &&
+ (state.indented == 0) && (match = stream.match(tlvLineIndentationMatch, false))) {
+ state.indented = match[0].length;
+ }
+
+ // Compute indentation state:
+ // o Auto indentation on next line
+ // o Indentation scope styles
+ var indented = state.indented;
+ var depth = indented / tlvIndentUnit;
+ if (depth <= state.tlvIndentationStyle.length) {
+ // not deeper than current scope
+
+ var blankline = stream.string.length == indented;
+ var chPos = depth * tlvIndentUnit;
+ if (chPos < stream.string.length) {
+ var bodyString = stream.string.slice(chPos);
+ var ch = bodyString[0];
+ if (tlvScopePrefixChars[ch] && ((match = bodyString.match(tlvIdentMatch)) &&
+ tlvIdentifierStyle[match[1]])) {
+ // This line begins scope.
+ // Next line gets indented one level.
+ indented += tlvIndentUnit;
+ // Style the next level of indentation (except non-region keyword identifiers,
+ // which are statements themselves)
+ if (!(ch == "\\" && chPos > 0)) {
+ state.tlvIndentationStyle[depth] = tlvScopePrefixChars[ch];
+ if (tlvTrackStatements) {state.statementComment = false;}
+ depth++;
+ }
+ }
+ }
+ // Clear out deeper indentation levels unless line is blank.
+ if (!blankline) {
+ while (state.tlvIndentationStyle.length > depth) {
+ state.tlvIndentationStyle.pop();
+ }
+ }
+ }
+ // Set next level of indentation.
+ state.tlvNextIndent = indented;
+ }
+
+ if (state.tlvCodeActive) {
+ // Highlight as TLV.
+
+ var beginStatement = false;
+ if (tlvTrackStatements) {
+ // This starts a statement if the position is at the scope level
+ // and we're not within a statement leading comment.
+ beginStatement =
+ (stream.peek() != " ") && // not a space
+ (style === undefined) && // not a region identifier
+ !state.tlvInBlockComment && // not in block comment
+ //!stream.match(tlvCommentMatch, false) && // not comment start
+ (stream.column() == state.tlvIndentationStyle.length * tlvIndentUnit); // at scope level
+ if (beginStatement) {
+ if (state.statementComment) {
+ // statement already started by comment
+ beginStatement = false;
+ }
+ state.statementComment =
+ stream.match(tlvCommentMatch, false); // comment start
+ }
+ }
+
+ var match;
+ if (style !== undefined) {
+ // Region line.
+ style += " " + tlvScopeStyle(state, 0, "scope-ident")
+ } else if (((stream.pos / tlvIndentUnit) < state.tlvIndentationStyle.length) &&
+ (match = stream.match(stream.sol() ? tlvFirstLevelIndentMatch : /^ /))) {
+ // Indentation
+ style = // make this style distinct from the previous one to prevent
+ // codemirror from combining spans
+ "tlv-indent-" + (((stream.pos % 2) == 0) ? "even" : "odd") +
+ // and style it
+ " " + tlvScopeStyle(state, stream.pos - tlvIndentUnit, "indent");
+ // Style the line prefix character.
+ if (match[0].charAt(0) == "!") {
+ style += " tlv-alert-line-prefix";
+ }
+ // Place a class before a scope identifier.
+ if (tlvIdentNext(stream)) {
+ style += " " + tlvScopeStyle(state, stream.pos, "before-scope-ident");
+ }
+ } else if (state.tlvInBlockComment) {
+ // In a block comment.
+ if (stream.match(/^.*?\*\//)) {
+ // Exit block comment.
+ state.tlvInBlockComment = false;
+ if (tlvTrackStatements && !stream.eol()) {
+ // Anything after comment is assumed to be real statement content.
+ state.statementComment = false;
+ }
+ } else {
+ stream.skipToEnd();
+ }
+ style = "comment";
+ } else if ((match = stream.match(tlvCommentMatch)) && !state.tlvInBlockComment) {
+ // Start comment.
+ if (match[0] == "//") {
+ // Line comment.
+ stream.skipToEnd();
+ } else {
+ // Block comment.
+ state.tlvInBlockComment = true;
+ }
+ style = "comment";
+ } else if (match = stream.match(tlvIdentMatch)) {
+ // looks like an identifier (or identifier prefix)
+ var prefix = match[1];
+ var mnemonic = match[2];
+ if (// is identifier prefix
+ tlvIdentifierStyle.hasOwnProperty(prefix) &&
+ // has mnemonic or we're at the end of the line (maybe it hasn't been typed yet)
+ (mnemonic.length > 0 || stream.eol())) {
+ style = tlvIdentifierStyle[prefix];
+ if (stream.column() == state.indented) {
+ // Begin scope.
+ style += " " + tlvScopeStyle(state, stream.column(), "scope-ident")
+ }
+ } else {
+ // Just swallow one character and try again.
+ // This enables subsequent identifier match with preceding symbol character, which
+ // is legal within a statement. (E.g., !$reset). It also enables detection of
+ // comment start with preceding symbols.
+ stream.backUp(stream.current().length - 1);
+ style = "tlv-default";
+ }
+ } else if (stream.match(/^\t+/)) {
+ // Highlight tabs, which are illegal.
+ style = "tlv-tab";
+ } else if (stream.match(/^[\[\]{}\(\);\:]+/)) {
+ // [:], (), {}, ;.
+ style = "meta";
+ } else if (match = stream.match(/^[mM]4([\+_])?[\w\d_]*/)) {
+ // m4 pre proc
+ style = (match[1] == "+") ? "tlv-m4-plus" : "tlv-m4";
+ } else if (stream.match(/^ +/)){
+ // Skip over spaces.
+ if (stream.eol()) {
+ // Trailing spaces.
+ style = "error";
+ } else {
+ // Non-trailing spaces.
+ style = "tlv-default";
+ }
+ } else if (stream.match(/^[\w\d_]+/)) {
+ // alpha-numeric token.
+ style = "number";
+ } else {
+ // Eat the next char w/ no formatting.
+ stream.next();
+ style = "tlv-default";
+ }
+ if (beginStatement) {
+ style += " tlv-statement";
+ }
+ } else {
+ if (stream.match(/^[mM]4([\w\d_]*)/)) {
+ // m4 pre proc
+ style = "tlv-m4";
+ }
+ }
+ return style;
+ },
+
+ indent: function(state) {
+ return (state.tlvCodeActive == true) ? state.tlvNextIndent : -1;
+ },
+
+ startState: function(state) {
+ state.tlvIndentationStyle = []; // Styles to use for each level of indentation.
+ state.tlvCodeActive = true; // True when we're in a TLV region (and at beginning of file).
+ state.tlvNextIndent = -1; // The number of spaces to autoindent the next line if tlvCodeActive.
+ state.tlvInBlockComment = false; // True inside /**/ comment.
+ if (tlvTrackStatements) {
+ state.statementComment = false; // True inside a statement's header comment.
+ }
+ }
+
+ }
+ });
+});
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/vhdl/vhdl.js b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/vhdl/vhdl.js
new file mode 100644
index 0000000000..133e67a268
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/vhdl/vhdl.js
@@ -0,0 +1,189 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: https://codemirror.net/LICENSE
+
+// Originally written by Alf Nielsen, re-written by Michael Zhou
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
+ mod(require("../../lib/codemirror"));
+ else if (typeof define == "function" && define.amd) // AMD
+ define(["../../lib/codemirror"], mod);
+ else // Plain browser env
+ mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+function words(str) {
+ var obj = {}, words = str.split(",");
+ for (var i = 0; i < words.length; ++i) {
+ var allCaps = words[i].toUpperCase();
+ var firstCap = words[i].charAt(0).toUpperCase() + words[i].slice(1);
+ obj[words[i]] = true;
+ obj[allCaps] = true;
+ obj[firstCap] = true;
+ }
+ return obj;
+}
+
+function metaHook(stream) {
+ stream.eatWhile(/[\w\$_]/);
+ return "meta";
+}
+
+CodeMirror.defineMode("vhdl", function(config, parserConfig) {
+ var indentUnit = config.indentUnit,
+ atoms = parserConfig.atoms || words("null"),
+ hooks = parserConfig.hooks || {"`": metaHook, "$": metaHook},
+ multiLineStrings = parserConfig.multiLineStrings;
+
+ var keywords = words("abs,access,after,alias,all,and,architecture,array,assert,attribute,begin,block," +
+ "body,buffer,bus,case,component,configuration,constant,disconnect,downto,else,elsif,end,end block,end case," +
+ "end component,end for,end generate,end if,end loop,end process,end record,end units,entity,exit,file,for," +
+ "function,generate,generic,generic map,group,guarded,if,impure,in,inertial,inout,is,label,library,linkage," +
+ "literal,loop,map,mod,nand,new,next,nor,null,of,on,open,or,others,out,package,package body,port,port map," +
+ "postponed,procedure,process,pure,range,record,register,reject,rem,report,return,rol,ror,select,severity,signal," +
+ "sla,sll,sra,srl,subtype,then,to,transport,type,unaffected,units,until,use,variable,wait,when,while,with,xnor,xor");
+
+ var blockKeywords = words("architecture,entity,begin,case,port,else,elsif,end,for,function,if");
+
+ var isOperatorChar = /[&|~>!\?@#$%&|:\.]+)/, token: "variable-2"},
+ {regex: /"(?:[^"\\\x00-\x1f\x7f]|\\[nt\\'"]|\\[0-9a-fA-F][0-9a-fA-F])*"/, token: "string"},
+ {regex: /\(;.*?/, token: "comment", next: "comment"},
+ {regex: /;;.*$/, token: "comment"},
+ {regex: /\(/, indent: true},
+ {regex: /\)/, dedent: true},
+ ],
+
+ comment: [
+ {regex: /.*?;\)/, token: "comment", next: "start"},
+ {regex: /.*/, token: "comment"},
+ ],
+
+ meta: {
+ dontIndentStates: ['comment'],
+ },
+});
+
+// https://github.com/WebAssembly/design/issues/981 mentions text/webassembly,
+// which seems like a reasonable choice, although it's not standard right now.
+CodeMirror.defineMIME("text/webassembly", "wast");
+
+});
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/webidl/webidl.js b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/webidl/webidl.js
new file mode 100644
index 0000000000..120de6bea7
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/webidl/webidl.js
@@ -0,0 +1,195 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: https://codemirror.net/LICENSE
+
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
+ mod(require("../../lib/codemirror"));
+ else if (typeof define == "function" && define.amd) // AMD
+ define(["../../lib/codemirror"], mod);
+ else // Plain browser env
+ mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+function wordRegexp(words) {
+ return new RegExp("^((" + words.join(")|(") + "))\\b");
+};
+
+var builtinArray = [
+ "Clamp",
+ "Constructor",
+ "EnforceRange",
+ "Exposed",
+ "ImplicitThis",
+ "Global", "PrimaryGlobal",
+ "LegacyArrayClass",
+ "LegacyUnenumerableNamedProperties",
+ "LenientThis",
+ "NamedConstructor",
+ "NewObject",
+ "NoInterfaceObject",
+ "OverrideBuiltins",
+ "PutForwards",
+ "Replaceable",
+ "SameObject",
+ "TreatNonObjectAsNull",
+ "TreatNullAs",
+ "EmptyString",
+ "Unforgeable",
+ "Unscopeable"
+];
+var builtins = wordRegexp(builtinArray);
+
+var typeArray = [
+ "unsigned", "short", "long", // UnsignedIntegerType
+ "unrestricted", "float", "double", // UnrestrictedFloatType
+ "boolean", "byte", "octet", // Rest of PrimitiveType
+ "Promise", // PromiseType
+ "ArrayBuffer", "DataView", "Int8Array", "Int16Array", "Int32Array",
+ "Uint8Array", "Uint16Array", "Uint32Array", "Uint8ClampedArray",
+ "Float32Array", "Float64Array", // BufferRelatedType
+ "ByteString", "DOMString", "USVString", "sequence", "object", "RegExp",
+ "Error", "DOMException", "FrozenArray", // Rest of NonAnyType
+ "any", // Rest of SingleType
+ "void" // Rest of ReturnType
+];
+var types = wordRegexp(typeArray);
+
+var keywordArray = [
+ "attribute", "callback", "const", "deleter", "dictionary", "enum", "getter",
+ "implements", "inherit", "interface", "iterable", "legacycaller", "maplike",
+ "partial", "required", "serializer", "setlike", "setter", "static",
+ "stringifier", "typedef", // ArgumentNameKeyword except
+ // "unrestricted"
+ "optional", "readonly", "or"
+];
+var keywords = wordRegexp(keywordArray);
+
+var atomArray = [
+ "true", "false", // BooleanLiteral
+ "Infinity", "NaN", // FloatLiteral
+ "null" // Rest of ConstValue
+];
+var atoms = wordRegexp(atomArray);
+
+CodeMirror.registerHelper("hintWords", "webidl",
+ builtinArray.concat(typeArray).concat(keywordArray).concat(atomArray));
+
+var startDefArray = ["callback", "dictionary", "enum", "interface"];
+var startDefs = wordRegexp(startDefArray);
+
+var endDefArray = ["typedef"];
+var endDefs = wordRegexp(endDefArray);
+
+var singleOperators = /^[:<=>?]/;
+var integers = /^-?([1-9][0-9]*|0[Xx][0-9A-Fa-f]+|0[0-7]*)/;
+var floats = /^-?(([0-9]+\.[0-9]*|[0-9]*\.[0-9]+)([Ee][+-]?[0-9]+)?|[0-9]+[Ee][+-]?[0-9]+)/;
+var identifiers = /^_?[A-Za-z][0-9A-Z_a-z-]*/;
+var identifiersEnd = /^_?[A-Za-z][0-9A-Z_a-z-]*(?=\s*;)/;
+var strings = /^"[^"]*"/;
+var multilineComments = /^\/\*.*?\*\//;
+var multilineCommentsStart = /^\/\*.*/;
+var multilineCommentsEnd = /^.*?\*\//;
+
+function readToken(stream, state) {
+ // whitespace
+ if (stream.eatSpace()) return null;
+
+ // comment
+ if (state.inComment) {
+ if (stream.match(multilineCommentsEnd)) {
+ state.inComment = false;
+ return "comment";
+ }
+ stream.skipToEnd();
+ return "comment";
+ }
+ if (stream.match("//")) {
+ stream.skipToEnd();
+ return "comment";
+ }
+ if (stream.match(multilineComments)) return "comment";
+ if (stream.match(multilineCommentsStart)) {
+ state.inComment = true;
+ return "comment";
+ }
+
+ // integer and float
+ if (stream.match(/^-?[0-9\.]/, false)) {
+ if (stream.match(integers) || stream.match(floats)) return "number";
+ }
+
+ // string
+ if (stream.match(strings)) return "string";
+
+ // identifier
+ if (state.startDef && stream.match(identifiers)) return "def";
+
+ if (state.endDef && stream.match(identifiersEnd)) {
+ state.endDef = false;
+ return "def";
+ }
+
+ if (stream.match(keywords)) return "keyword";
+
+ if (stream.match(types)) {
+ var lastToken = state.lastToken;
+ var nextToken = (stream.match(/^\s*(.+?)\b/, false) || [])[1];
+
+ if (lastToken === ":" || lastToken === "implements" ||
+ nextToken === "implements" || nextToken === "=") {
+ // Used as identifier
+ return "builtin";
+ } else {
+ // Used as type
+ return "variable-3";
+ }
+ }
+
+ if (stream.match(builtins)) return "builtin";
+ if (stream.match(atoms)) return "atom";
+ if (stream.match(identifiers)) return "variable";
+
+ // other
+ if (stream.match(singleOperators)) return "operator";
+
+ // unrecognized
+ stream.next();
+ return null;
+};
+
+CodeMirror.defineMode("webidl", function() {
+ return {
+ startState: function() {
+ return {
+ // Is in multiline comment
+ inComment: false,
+ // Last non-whitespace, matched token
+ lastToken: "",
+ // Next token is a definition
+ startDef: false,
+ // Last token of the statement is a definition
+ endDef: false
+ };
+ },
+ token: function(stream, state) {
+ var style = readToken(stream, state);
+
+ if (style) {
+ var cur = stream.current();
+ state.lastToken = cur;
+ if (style === "keyword") {
+ state.startDef = startDefs.test(cur);
+ state.endDef = state.endDef || endDefs.test(cur);
+ } else {
+ state.startDef = false;
+ }
+ }
+
+ return style;
+ }
+ };
+});
+
+CodeMirror.defineMIME("text/x-webidl", "webidl");
+});
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/xml/xml.js b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/xml/xml.js
new file mode 100644
index 0000000000..4e36106b49
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/xml/xml.js
@@ -0,0 +1,417 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: https://codemirror.net/LICENSE
+
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
+ mod(require("../../lib/codemirror"));
+ else if (typeof define == "function" && define.amd) // AMD
+ define(["../../lib/codemirror"], mod);
+ else // Plain browser env
+ mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+var htmlConfig = {
+ autoSelfClosers: {'area': true, 'base': true, 'br': true, 'col': true, 'command': true,
+ 'embed': true, 'frame': true, 'hr': true, 'img': true, 'input': true,
+ 'keygen': true, 'link': true, 'meta': true, 'param': true, 'source': true,
+ 'track': true, 'wbr': true, 'menuitem': true},
+ implicitlyClosed: {'dd': true, 'li': true, 'optgroup': true, 'option': true, 'p': true,
+ 'rp': true, 'rt': true, 'tbody': true, 'td': true, 'tfoot': true,
+ 'th': true, 'tr': true},
+ contextGrabbers: {
+ 'dd': {'dd': true, 'dt': true},
+ 'dt': {'dd': true, 'dt': true},
+ 'li': {'li': true},
+ 'option': {'option': true, 'optgroup': true},
+ 'optgroup': {'optgroup': true},
+ 'p': {'address': true, 'article': true, 'aside': true, 'blockquote': true, 'dir': true,
+ 'div': true, 'dl': true, 'fieldset': true, 'footer': true, 'form': true,
+ 'h1': true, 'h2': true, 'h3': true, 'h4': true, 'h5': true, 'h6': true,
+ 'header': true, 'hgroup': true, 'hr': true, 'menu': true, 'nav': true, 'ol': true,
+ 'p': true, 'pre': true, 'section': true, 'table': true, 'ul': true},
+ 'rp': {'rp': true, 'rt': true},
+ 'rt': {'rp': true, 'rt': true},
+ 'tbody': {'tbody': true, 'tfoot': true},
+ 'td': {'td': true, 'th': true},
+ 'tfoot': {'tbody': true},
+ 'th': {'td': true, 'th': true},
+ 'thead': {'tbody': true, 'tfoot': true},
+ 'tr': {'tr': true}
+ },
+ doNotIndent: {"pre": true},
+ allowUnquoted: true,
+ allowMissing: true,
+ caseFold: true
+}
+
+var xmlConfig = {
+ autoSelfClosers: {},
+ implicitlyClosed: {},
+ contextGrabbers: {},
+ doNotIndent: {},
+ allowUnquoted: false,
+ allowMissing: false,
+ allowMissingTagName: false,
+ caseFold: false
+}
+
+CodeMirror.defineMode("xml", function(editorConf, config_) {
+ var indentUnit = editorConf.indentUnit
+ var config = {}
+ var defaults = config_.htmlMode ? htmlConfig : xmlConfig
+ for (var prop in defaults) config[prop] = defaults[prop]
+ for (var prop in config_) config[prop] = config_[prop]
+
+ // Return variables for tokenizers
+ var type, setStyle;
+
+ function inText(stream, state) {
+ function chain(parser) {
+ state.tokenize = parser;
+ return parser(stream, state);
+ }
+
+ var ch = stream.next();
+ if (ch == "<") {
+ if (stream.eat("!")) {
+ if (stream.eat("[")) {
+ if (stream.match("CDATA[")) return chain(inBlock("atom", "]]>"));
+ else return null;
+ } else if (stream.match("--")) {
+ return chain(inBlock("comment", "-->"));
+ } else if (stream.match("DOCTYPE", true, true)) {
+ stream.eatWhile(/[\w\._\-]/);
+ return chain(doctype(1));
+ } else {
+ return null;
+ }
+ } else if (stream.eat("?")) {
+ stream.eatWhile(/[\w\._\-]/);
+ state.tokenize = inBlock("meta", "?>");
+ return "meta";
+ } else {
+ type = stream.eat("/") ? "closeTag" : "openTag";
+ state.tokenize = inTag;
+ return "tag bracket";
+ }
+ } else if (ch == "&") {
+ var ok;
+ if (stream.eat("#")) {
+ if (stream.eat("x")) {
+ ok = stream.eatWhile(/[a-fA-F\d]/) && stream.eat(";");
+ } else {
+ ok = stream.eatWhile(/[\d]/) && stream.eat(";");
+ }
+ } else {
+ ok = stream.eatWhile(/[\w\.\-:]/) && stream.eat(";");
+ }
+ return ok ? "atom" : "error";
+ } else {
+ stream.eatWhile(/[^&<]/);
+ return null;
+ }
+ }
+ inText.isInText = true;
+
+ function inTag(stream, state) {
+ var ch = stream.next();
+ if (ch == ">" || (ch == "/" && stream.eat(">"))) {
+ state.tokenize = inText;
+ type = ch == ">" ? "endTag" : "selfcloseTag";
+ return "tag bracket";
+ } else if (ch == "=") {
+ type = "equals";
+ return null;
+ } else if (ch == "<") {
+ state.tokenize = inText;
+ state.state = baseState;
+ state.tagName = state.tagStart = null;
+ var next = state.tokenize(stream, state);
+ return next ? next + " tag error" : "tag error";
+ } else if (/[\'\"]/.test(ch)) {
+ state.tokenize = inAttribute(ch);
+ state.stringStartCol = stream.column();
+ return state.tokenize(stream, state);
+ } else {
+ stream.match(/^[^\s\u00a0=<>\"\']*[^\s\u00a0=<>\"\'\/]/);
+ return "word";
+ }
+ }
+
+ function inAttribute(quote) {
+ var closure = function(stream, state) {
+ while (!stream.eol()) {
+ if (stream.next() == quote) {
+ state.tokenize = inTag;
+ break;
+ }
+ }
+ return "string";
+ };
+ closure.isInAttribute = true;
+ return closure;
+ }
+
+ function inBlock(style, terminator) {
+ return function(stream, state) {
+ while (!stream.eol()) {
+ if (stream.match(terminator)) {
+ state.tokenize = inText;
+ break;
+ }
+ stream.next();
+ }
+ return style;
+ }
+ }
+
+ function doctype(depth) {
+ return function(stream, state) {
+ var ch;
+ while ((ch = stream.next()) != null) {
+ if (ch == "<") {
+ state.tokenize = doctype(depth + 1);
+ return state.tokenize(stream, state);
+ } else if (ch == ">") {
+ if (depth == 1) {
+ state.tokenize = inText;
+ break;
+ } else {
+ state.tokenize = doctype(depth - 1);
+ return state.tokenize(stream, state);
+ }
+ }
+ }
+ return "meta";
+ };
+ }
+
+ function lower(tagName) {
+ return tagName && tagName.toLowerCase();
+ }
+
+ function Context(state, tagName, startOfLine) {
+ this.prev = state.context;
+ this.tagName = tagName || "";
+ this.indent = state.indented;
+ this.startOfLine = startOfLine;
+ if (config.doNotIndent.hasOwnProperty(tagName) || (state.context && state.context.noIndent))
+ this.noIndent = true;
+ }
+ function popContext(state) {
+ if (state.context) state.context = state.context.prev;
+ }
+ function maybePopContext(state, nextTagName) {
+ var parentTagName;
+ while (true) {
+ if (!state.context) {
+ return;
+ }
+ parentTagName = state.context.tagName;
+ if (!config.contextGrabbers.hasOwnProperty(lower(parentTagName)) ||
+ !config.contextGrabbers[lower(parentTagName)].hasOwnProperty(lower(nextTagName))) {
+ return;
+ }
+ popContext(state);
+ }
+ }
+
+ function baseState(type, stream, state) {
+ if (type == "openTag") {
+ state.tagStart = stream.column();
+ return tagNameState;
+ } else if (type == "closeTag") {
+ return closeTagNameState;
+ } else {
+ return baseState;
+ }
+ }
+ function tagNameState(type, stream, state) {
+ if (type == "word") {
+ state.tagName = stream.current();
+ setStyle = "tag";
+ return attrState;
+ } else if (config.allowMissingTagName && type == "endTag") {
+ setStyle = "tag bracket";
+ return attrState(type, stream, state);
+ } else {
+ setStyle = "error";
+ return tagNameState;
+ }
+ }
+ function closeTagNameState(type, stream, state) {
+ if (type == "word") {
+ var tagName = stream.current();
+ if (state.context && state.context.tagName != tagName &&
+ config.implicitlyClosed.hasOwnProperty(lower(state.context.tagName)))
+ popContext(state);
+ if ((state.context && state.context.tagName == tagName) || config.matchClosing === false) {
+ setStyle = "tag";
+ return closeState;
+ } else {
+ setStyle = "tag error";
+ return closeStateErr;
+ }
+ } else if (config.allowMissingTagName && type == "endTag") {
+ setStyle = "tag bracket";
+ return closeState(type, stream, state);
+ } else {
+ setStyle = "error";
+ return closeStateErr;
+ }
+ }
+
+ function closeState(type, _stream, state) {
+ if (type != "endTag") {
+ setStyle = "error";
+ return closeState;
+ }
+ popContext(state);
+ return baseState;
+ }
+ function closeStateErr(type, stream, state) {
+ setStyle = "error";
+ return closeState(type, stream, state);
+ }
+
+ function attrState(type, _stream, state) {
+ if (type == "word") {
+ setStyle = "attribute";
+ return attrEqState;
+ } else if (type == "endTag" || type == "selfcloseTag") {
+ var tagName = state.tagName, tagStart = state.tagStart;
+ state.tagName = state.tagStart = null;
+ if (type == "selfcloseTag" ||
+ config.autoSelfClosers.hasOwnProperty(lower(tagName))) {
+ maybePopContext(state, tagName);
+ } else {
+ maybePopContext(state, tagName);
+ state.context = new Context(state, tagName, tagStart == state.indented);
+ }
+ return baseState;
+ }
+ setStyle = "error";
+ return attrState;
+ }
+ function attrEqState(type, stream, state) {
+ if (type == "equals") return attrValueState;
+ if (!config.allowMissing) setStyle = "error";
+ return attrState(type, stream, state);
+ }
+ function attrValueState(type, stream, state) {
+ if (type == "string") return attrContinuedState;
+ if (type == "word" && config.allowUnquoted) {setStyle = "string"; return attrState;}
+ setStyle = "error";
+ return attrState(type, stream, state);
+ }
+ function attrContinuedState(type, stream, state) {
+ if (type == "string") return attrContinuedState;
+ return attrState(type, stream, state);
+ }
+
+ return {
+ startState: function(baseIndent) {
+ var state = {tokenize: inText,
+ state: baseState,
+ indented: baseIndent || 0,
+ tagName: null, tagStart: null,
+ context: null}
+ if (baseIndent != null) state.baseIndent = baseIndent
+ return state
+ },
+
+ token: function(stream, state) {
+ if (!state.tagName && stream.sol())
+ state.indented = stream.indentation();
+
+ if (stream.eatSpace()) return null;
+ type = null;
+ var style = state.tokenize(stream, state);
+ if ((style || type) && style != "comment") {
+ setStyle = null;
+ state.state = state.state(type || style, stream, state);
+ if (setStyle)
+ style = setStyle == "error" ? style + " error" : setStyle;
+ }
+ return style;
+ },
+
+ indent: function(state, textAfter, fullLine) {
+ var context = state.context;
+ // Indent multi-line strings (e.g. css).
+ if (state.tokenize.isInAttribute) {
+ if (state.tagStart == state.indented)
+ return state.stringStartCol + 1;
+ else
+ return state.indented + indentUnit;
+ }
+ if (context && context.noIndent) return CodeMirror.Pass;
+ if (state.tokenize != inTag && state.tokenize != inText)
+ return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0;
+ // Indent the starts of attribute names.
+ if (state.tagName) {
+ if (config.multilineTagIndentPastTag !== false)
+ return state.tagStart + state.tagName.length + 2;
+ else
+ return state.tagStart + indentUnit * (config.multilineTagIndentFactor || 1);
+ }
+ if (config.alignCDATA && /$/,
+ blockCommentStart: "",
+
+ configuration: config.htmlMode ? "html" : "xml",
+ helperType: config.htmlMode ? "html" : "xml",
+
+ skipAttribute: function(state) {
+ if (state.state == attrValueState)
+ state.state = attrState
+ },
+
+ xmlCurrentTag: function(state) {
+ return state.tagName ? {name: state.tagName, close: state.type == "closeTag"} : null
+ },
+
+ xmlCurrentContext: function(state) {
+ var context = []
+ for (var cx = state.context; cx; cx = cx.prev)
+ context.push(cx.tagName)
+ return context.reverse()
+ }
+ };
+});
+
+CodeMirror.defineMIME("text/xml", "xml");
+CodeMirror.defineMIME("application/xml", "xml");
+if (!CodeMirror.mimeModes.hasOwnProperty("text/html"))
+ CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: true});
+
+});
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/xquery/xquery.js b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/xquery/xquery.js
new file mode 100644
index 0000000000..395b6a7014
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/xquery/xquery.js
@@ -0,0 +1,448 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: https://codemirror.net/LICENSE
+
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
+ mod(require("../../lib/codemirror"));
+ else if (typeof define == "function" && define.amd) // AMD
+ define(["../../lib/codemirror"], mod);
+ else // Plain browser env
+ mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("xquery", function() {
+
+ // The keywords object is set to the result of this self executing
+ // function. Each keyword is a property of the keywords object whose
+ // value is {type: atype, style: astyle}
+ var keywords = function(){
+ // convenience functions used to build keywords object
+ function kw(type) {return {type: type, style: "keyword"};}
+ var operator = kw("operator")
+ , atom = {type: "atom", style: "atom"}
+ , punctuation = {type: "punctuation", style: null}
+ , qualifier = {type: "axis_specifier", style: "qualifier"};
+
+ // kwObj is what is return from this function at the end
+ var kwObj = {
+ ',': punctuation
+ };
+
+ // a list of 'basic' keywords. For each add a property to kwObj with the value of
+ // {type: basic[i], style: "keyword"} e.g. 'after' --> {type: "after", style: "keyword"}
+ var basic = ['after', 'all', 'allowing', 'ancestor', 'ancestor-or-self', 'any', 'array', 'as',
+ 'ascending', 'at', 'attribute', 'base-uri', 'before', 'boundary-space', 'by', 'case', 'cast',
+ 'castable', 'catch', 'child', 'collation', 'comment', 'construction', 'contains', 'content',
+ 'context', 'copy', 'copy-namespaces', 'count', 'decimal-format', 'declare', 'default', 'delete',
+ 'descendant', 'descendant-or-self', 'descending', 'diacritics', 'different', 'distance',
+ 'document', 'document-node', 'element', 'else', 'empty', 'empty-sequence', 'encoding', 'end',
+ 'entire', 'every', 'exactly', 'except', 'external', 'first', 'following', 'following-sibling',
+ 'for', 'from', 'ftand', 'ftnot', 'ft-option', 'ftor', 'function', 'fuzzy', 'greatest', 'group',
+ 'if', 'import', 'in', 'inherit', 'insensitive', 'insert', 'instance', 'intersect', 'into',
+ 'invoke', 'is', 'item', 'language', 'last', 'lax', 'least', 'let', 'levels', 'lowercase', 'map',
+ 'modify', 'module', 'most', 'namespace', 'next', 'no', 'node', 'nodes', 'no-inherit',
+ 'no-preserve', 'not', 'occurs', 'of', 'only', 'option', 'order', 'ordered', 'ordering',
+ 'paragraph', 'paragraphs', 'parent', 'phrase', 'preceding', 'preceding-sibling', 'preserve',
+ 'previous', 'processing-instruction', 'relationship', 'rename', 'replace', 'return',
+ 'revalidation', 'same', 'satisfies', 'schema', 'schema-attribute', 'schema-element', 'score',
+ 'self', 'sensitive', 'sentence', 'sentences', 'sequence', 'skip', 'sliding', 'some', 'stable',
+ 'start', 'stemming', 'stop', 'strict', 'strip', 'switch', 'text', 'then', 'thesaurus', 'times',
+ 'to', 'transform', 'treat', 'try', 'tumbling', 'type', 'typeswitch', 'union', 'unordered',
+ 'update', 'updating', 'uppercase', 'using', 'validate', 'value', 'variable', 'version',
+ 'weight', 'when', 'where', 'wildcards', 'window', 'with', 'without', 'word', 'words', 'xquery'];
+ for(var i=0, l=basic.length; i < l; i++) { kwObj[basic[i]] = kw(basic[i]);};
+
+ // a list of types. For each add a property to kwObj with the value of
+ // {type: "atom", style: "atom"}
+ var types = ['xs:anyAtomicType', 'xs:anySimpleType', 'xs:anyType', 'xs:anyURI',
+ 'xs:base64Binary', 'xs:boolean', 'xs:byte', 'xs:date', 'xs:dateTime', 'xs:dateTimeStamp',
+ 'xs:dayTimeDuration', 'xs:decimal', 'xs:double', 'xs:duration', 'xs:ENTITIES', 'xs:ENTITY',
+ 'xs:float', 'xs:gDay', 'xs:gMonth', 'xs:gMonthDay', 'xs:gYear', 'xs:gYearMonth', 'xs:hexBinary',
+ 'xs:ID', 'xs:IDREF', 'xs:IDREFS', 'xs:int', 'xs:integer', 'xs:item', 'xs:java', 'xs:language',
+ 'xs:long', 'xs:Name', 'xs:NCName', 'xs:negativeInteger', 'xs:NMTOKEN', 'xs:NMTOKENS',
+ 'xs:nonNegativeInteger', 'xs:nonPositiveInteger', 'xs:normalizedString', 'xs:NOTATION',
+ 'xs:numeric', 'xs:positiveInteger', 'xs:precisionDecimal', 'xs:QName', 'xs:short', 'xs:string',
+ 'xs:time', 'xs:token', 'xs:unsignedByte', 'xs:unsignedInt', 'xs:unsignedLong',
+ 'xs:unsignedShort', 'xs:untyped', 'xs:untypedAtomic', 'xs:yearMonthDuration'];
+ for(var i=0, l=types.length; i < l; i++) { kwObj[types[i]] = atom;};
+
+ // each operator will add a property to kwObj with value of {type: "operator", style: "keyword"}
+ var operators = ['eq', 'ne', 'lt', 'le', 'gt', 'ge', ':=', '=', '>', '>=', '<', '<=', '.', '|', '?', 'and', 'or', 'div', 'idiv', 'mod', '*', '/', '+', '-'];
+ for(var i=0, l=operators.length; i < l; i++) { kwObj[operators[i]] = operator;};
+
+ // each axis_specifiers will add a property to kwObj with value of {type: "axis_specifier", style: "qualifier"}
+ var axis_specifiers = ["self::", "attribute::", "child::", "descendant::", "descendant-or-self::", "parent::",
+ "ancestor::", "ancestor-or-self::", "following::", "preceding::", "following-sibling::", "preceding-sibling::"];
+ for(var i=0, l=axis_specifiers.length; i < l; i++) { kwObj[axis_specifiers[i]] = qualifier; };
+
+ return kwObj;
+ }();
+
+ function chain(stream, state, f) {
+ state.tokenize = f;
+ return f(stream, state);
+ }
+
+ // the primary mode tokenizer
+ function tokenBase(stream, state) {
+ var ch = stream.next(),
+ mightBeFunction = false,
+ isEQName = isEQNameAhead(stream);
+
+ // an XML tag (if not in some sub, chained tokenizer)
+ if (ch == "<") {
+ if(stream.match("!--", true))
+ return chain(stream, state, tokenXMLComment);
+
+ if(stream.match("![CDATA", false)) {
+ state.tokenize = tokenCDATA;
+ return "tag";
+ }
+
+ if(stream.match("?", false)) {
+ return chain(stream, state, tokenPreProcessing);
+ }
+
+ var isclose = stream.eat("/");
+ stream.eatSpace();
+ var tagName = "", c;
+ while ((c = stream.eat(/[^\s\u00a0=<>\"\'\/?]/))) tagName += c;
+
+ return chain(stream, state, tokenTag(tagName, isclose));
+ }
+ // start code block
+ else if(ch == "{") {
+ pushStateStack(state, { type: "codeblock"});
+ return null;
+ }
+ // end code block
+ else if(ch == "}") {
+ popStateStack(state);
+ return null;
+ }
+ // if we're in an XML block
+ else if(isInXmlBlock(state)) {
+ if(ch == ">")
+ return "tag";
+ else if(ch == "/" && stream.eat(">")) {
+ popStateStack(state);
+ return "tag";
+ }
+ else
+ return "variable";
+ }
+ // if a number
+ else if (/\d/.test(ch)) {
+ stream.match(/^\d*(?:\.\d*)?(?:E[+\-]?\d+)?/);
+ return "atom";
+ }
+ // comment start
+ else if (ch === "(" && stream.eat(":")) {
+ pushStateStack(state, { type: "comment"});
+ return chain(stream, state, tokenComment);
+ }
+ // quoted string
+ else if (!isEQName && (ch === '"' || ch === "'"))
+ return chain(stream, state, tokenString(ch));
+ // variable
+ else if(ch === "$") {
+ return chain(stream, state, tokenVariable);
+ }
+ // assignment
+ else if(ch ===":" && stream.eat("=")) {
+ return "keyword";
+ }
+ // open paren
+ else if(ch === "(") {
+ pushStateStack(state, { type: "paren"});
+ return null;
+ }
+ // close paren
+ else if(ch === ")") {
+ popStateStack(state);
+ return null;
+ }
+ // open paren
+ else if(ch === "[") {
+ pushStateStack(state, { type: "bracket"});
+ return null;
+ }
+ // close paren
+ else if(ch === "]") {
+ popStateStack(state);
+ return null;
+ }
+ else {
+ var known = keywords.propertyIsEnumerable(ch) && keywords[ch];
+
+ // if there's a EQName ahead, consume the rest of the string portion, it's likely a function
+ if(isEQName && ch === '\"') while(stream.next() !== '"'){}
+ if(isEQName && ch === '\'') while(stream.next() !== '\''){}
+
+ // gobble up a word if the character is not known
+ if(!known) stream.eatWhile(/[\w\$_-]/);
+
+ // gobble a colon in the case that is a lib func type call fn:doc
+ var foundColon = stream.eat(":");
+
+ // if there's not a second colon, gobble another word. Otherwise, it's probably an axis specifier
+ // which should get matched as a keyword
+ if(!stream.eat(":") && foundColon) {
+ stream.eatWhile(/[\w\$_-]/);
+ }
+ // if the next non whitespace character is an open paren, this is probably a function (if not a keyword of other sort)
+ if(stream.match(/^[ \t]*\(/, false)) {
+ mightBeFunction = true;
+ }
+ // is the word a keyword?
+ var word = stream.current();
+ known = keywords.propertyIsEnumerable(word) && keywords[word];
+
+ // if we think it's a function call but not yet known,
+ // set style to variable for now for lack of something better
+ if(mightBeFunction && !known) known = {type: "function_call", style: "variable def"};
+
+ // if the previous word was element, attribute, axis specifier, this word should be the name of that
+ if(isInXmlConstructor(state)) {
+ popStateStack(state);
+ return "variable";
+ }
+ // as previously checked, if the word is element,attribute, axis specifier, call it an "xmlconstructor" and
+ // push the stack so we know to look for it on the next word
+ if(word == "element" || word == "attribute" || known.type == "axis_specifier") pushStateStack(state, {type: "xmlconstructor"});
+
+ // if the word is known, return the details of that else just call this a generic 'word'
+ return known ? known.style : "variable";
+ }
+ }
+
+ // handle comments, including nested
+ function tokenComment(stream, state) {
+ var maybeEnd = false, maybeNested = false, nestedCount = 0, ch;
+ while (ch = stream.next()) {
+ if (ch == ")" && maybeEnd) {
+ if(nestedCount > 0)
+ nestedCount--;
+ else {
+ popStateStack(state);
+ break;
+ }
+ }
+ else if(ch == ":" && maybeNested) {
+ nestedCount++;
+ }
+ maybeEnd = (ch == ":");
+ maybeNested = (ch == "(");
+ }
+
+ return "comment";
+ }
+
+ // tokenizer for string literals
+ // optionally pass a tokenizer function to set state.tokenize back to when finished
+ function tokenString(quote, f) {
+ return function(stream, state) {
+ var ch;
+
+ if(isInString(state) && stream.current() == quote) {
+ popStateStack(state);
+ if(f) state.tokenize = f;
+ return "string";
+ }
+
+ pushStateStack(state, { type: "string", name: quote, tokenize: tokenString(quote, f) });
+
+ // if we're in a string and in an XML block, allow an embedded code block
+ if(stream.match("{", false) && isInXmlAttributeBlock(state)) {
+ state.tokenize = tokenBase;
+ return "string";
+ }
+
+
+ while (ch = stream.next()) {
+ if (ch == quote) {
+ popStateStack(state);
+ if(f) state.tokenize = f;
+ break;
+ }
+ else {
+ // if we're in a string and in an XML block, allow an embedded code block in an attribute
+ if(stream.match("{", false) && isInXmlAttributeBlock(state)) {
+ state.tokenize = tokenBase;
+ return "string";
+ }
+
+ }
+ }
+
+ return "string";
+ };
+ }
+
+ // tokenizer for variables
+ function tokenVariable(stream, state) {
+ var isVariableChar = /[\w\$_-]/;
+
+ // a variable may start with a quoted EQName so if the next character is quote, consume to the next quote
+ if(stream.eat("\"")) {
+ while(stream.next() !== '\"'){};
+ stream.eat(":");
+ } else {
+ stream.eatWhile(isVariableChar);
+ if(!stream.match(":=", false)) stream.eat(":");
+ }
+ stream.eatWhile(isVariableChar);
+ state.tokenize = tokenBase;
+ return "variable";
+ }
+
+ // tokenizer for XML tags
+ function tokenTag(name, isclose) {
+ return function(stream, state) {
+ stream.eatSpace();
+ if(isclose && stream.eat(">")) {
+ popStateStack(state);
+ state.tokenize = tokenBase;
+ return "tag";
+ }
+ // self closing tag without attributes?
+ if(!stream.eat("/"))
+ pushStateStack(state, { type: "tag", name: name, tokenize: tokenBase});
+ if(!stream.eat(">")) {
+ state.tokenize = tokenAttribute;
+ return "tag";
+ }
+ else {
+ state.tokenize = tokenBase;
+ }
+ return "tag";
+ };
+ }
+
+ // tokenizer for XML attributes
+ function tokenAttribute(stream, state) {
+ var ch = stream.next();
+
+ if(ch == "/" && stream.eat(">")) {
+ if(isInXmlAttributeBlock(state)) popStateStack(state);
+ if(isInXmlBlock(state)) popStateStack(state);
+ return "tag";
+ }
+ if(ch == ">") {
+ if(isInXmlAttributeBlock(state)) popStateStack(state);
+ return "tag";
+ }
+ if(ch == "=")
+ return null;
+ // quoted string
+ if (ch == '"' || ch == "'")
+ return chain(stream, state, tokenString(ch, tokenAttribute));
+
+ if(!isInXmlAttributeBlock(state))
+ pushStateStack(state, { type: "attribute", tokenize: tokenAttribute});
+
+ stream.eat(/[a-zA-Z_:]/);
+ stream.eatWhile(/[-a-zA-Z0-9_:.]/);
+ stream.eatSpace();
+
+ // the case where the attribute has not value and the tag was closed
+ if(stream.match(">", false) || stream.match("/", false)) {
+ popStateStack(state);
+ state.tokenize = tokenBase;
+ }
+
+ return "attribute";
+ }
+
+ // handle comments, including nested
+ function tokenXMLComment(stream, state) {
+ var ch;
+ while (ch = stream.next()) {
+ if (ch == "-" && stream.match("->", true)) {
+ state.tokenize = tokenBase;
+ return "comment";
+ }
+ }
+ }
+
+
+ // handle CDATA
+ function tokenCDATA(stream, state) {
+ var ch;
+ while (ch = stream.next()) {
+ if (ch == "]" && stream.match("]", true)) {
+ state.tokenize = tokenBase;
+ return "comment";
+ }
+ }
+ }
+
+ // handle preprocessing instructions
+ function tokenPreProcessing(stream, state) {
+ var ch;
+ while (ch = stream.next()) {
+ if (ch == "?" && stream.match(">", true)) {
+ state.tokenize = tokenBase;
+ return "comment meta";
+ }
+ }
+ }
+
+
+ // functions to test the current context of the state
+ function isInXmlBlock(state) { return isIn(state, "tag"); }
+ function isInXmlAttributeBlock(state) { return isIn(state, "attribute"); }
+ function isInXmlConstructor(state) { return isIn(state, "xmlconstructor"); }
+ function isInString(state) { return isIn(state, "string"); }
+
+ function isEQNameAhead(stream) {
+ // assume we've already eaten a quote (")
+ if(stream.current() === '"')
+ return stream.match(/^[^\"]+\"\:/, false);
+ else if(stream.current() === '\'')
+ return stream.match(/^[^\"]+\'\:/, false);
+ else
+ return false;
+ }
+
+ function isIn(state, type) {
+ return (state.stack.length && state.stack[state.stack.length - 1].type == type);
+ }
+
+ function pushStateStack(state, newState) {
+ state.stack.push(newState);
+ }
+
+ function popStateStack(state) {
+ state.stack.pop();
+ var reinstateTokenize = state.stack.length && state.stack[state.stack.length-1].tokenize;
+ state.tokenize = reinstateTokenize || tokenBase;
+ }
+
+ // the interface for the mode API
+ return {
+ startState: function() {
+ return {
+ tokenize: tokenBase,
+ cc: [],
+ stack: []
+ };
+ },
+
+ token: function(stream, state) {
+ if (stream.eatSpace()) return null;
+ var style = state.tokenize(stream, state);
+ return style;
+ },
+
+ blockCommentStart: "(:",
+ blockCommentEnd: ":)"
+
+ };
+
+});
+
+CodeMirror.defineMIME("application/xquery", "xquery");
+
+});
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/yacas/yacas.js b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/yacas/yacas.js
new file mode 100644
index 0000000000..b7ac96b71d
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/yacas/yacas.js
@@ -0,0 +1,204 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: https://codemirror.net/LICENSE
+
+// Yacas mode copyright (c) 2015 by Grzegorz Mazur
+// Loosely based on mathematica mode by Calin Barbat
+
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
+ mod(require("../../lib/codemirror"));
+ else if (typeof define == "function" && define.amd) // AMD
+ define(["../../lib/codemirror"], mod);
+ else // Plain browser env
+ mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode('yacas', function(_config, _parserConfig) {
+
+ function words(str) {
+ var obj = {}, words = str.split(" ");
+ for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
+ return obj;
+ }
+
+ var bodiedOps = words("Assert BackQuote D Defun Deriv For ForEach FromFile " +
+ "FromString Function Integrate InverseTaylor Limit " +
+ "LocalSymbols Macro MacroRule MacroRulePattern " +
+ "NIntegrate Rule RulePattern Subst TD TExplicitSum " +
+ "TSum Taylor Taylor1 Taylor2 Taylor3 ToFile " +
+ "ToStdout ToString TraceRule Until While");
+
+ // patterns
+ var pFloatForm = "(?:(?:\\.\\d+|\\d+\\.\\d*|\\d+)(?:[eE][+-]?\\d+)?)";
+ var pIdentifier = "(?:[a-zA-Z\\$'][a-zA-Z0-9\\$']*)";
+
+ // regular expressions
+ var reFloatForm = new RegExp(pFloatForm);
+ var reIdentifier = new RegExp(pIdentifier);
+ var rePattern = new RegExp(pIdentifier + "?_" + pIdentifier);
+ var reFunctionLike = new RegExp(pIdentifier + "\\s*\\(");
+
+ function tokenBase(stream, state) {
+ var ch;
+
+ // get next character
+ ch = stream.next();
+
+ // string
+ if (ch === '"') {
+ state.tokenize = tokenString;
+ return state.tokenize(stream, state);
+ }
+
+ // comment
+ if (ch === '/') {
+ if (stream.eat('*')) {
+ state.tokenize = tokenComment;
+ return state.tokenize(stream, state);
+ }
+ if (stream.eat("/")) {
+ stream.skipToEnd();
+ return "comment";
+ }
+ }
+
+ // go back one character
+ stream.backUp(1);
+
+ // update scope info
+ var m = stream.match(/^(\w+)\s*\(/, false);
+ if (m !== null && bodiedOps.hasOwnProperty(m[1]))
+ state.scopes.push('bodied');
+
+ var scope = currentScope(state);
+
+ if (scope === 'bodied' && ch === '[')
+ state.scopes.pop();
+
+ if (ch === '[' || ch === '{' || ch === '(')
+ state.scopes.push(ch);
+
+ scope = currentScope(state);
+
+ if (scope === '[' && ch === ']' ||
+ scope === '{' && ch === '}' ||
+ scope === '(' && ch === ')')
+ state.scopes.pop();
+
+ if (ch === ';') {
+ while (scope === 'bodied') {
+ state.scopes.pop();
+ scope = currentScope(state);
+ }
+ }
+
+ // look for ordered rules
+ if (stream.match(/\d+ *#/, true, false)) {
+ return 'qualifier';
+ }
+
+ // look for numbers
+ if (stream.match(reFloatForm, true, false)) {
+ return 'number';
+ }
+
+ // look for placeholders
+ if (stream.match(rePattern, true, false)) {
+ return 'variable-3';
+ }
+
+ // match all braces separately
+ if (stream.match(/(?:\[|\]|{|}|\(|\))/, true, false)) {
+ return 'bracket';
+ }
+
+ // literals looking like function calls
+ if (stream.match(reFunctionLike, true, false)) {
+ stream.backUp(1);
+ return 'variable';
+ }
+
+ // all other identifiers
+ if (stream.match(reIdentifier, true, false)) {
+ return 'variable-2';
+ }
+
+ // operators; note that operators like @@ or /; are matched separately for each symbol.
+ if (stream.match(/(?:\\|\+|\-|\*|\/|,|;|\.|:|@|~|=|>|<|&|\||_|`|'|\^|\?|!|%|#)/, true, false)) {
+ return 'operator';
+ }
+
+ // everything else is an error
+ return 'error';
+ }
+
+ function tokenString(stream, state) {
+ var next, end = false, escaped = false;
+ while ((next = stream.next()) != null) {
+ if (next === '"' && !escaped) {
+ end = true;
+ break;
+ }
+ escaped = !escaped && next === '\\';
+ }
+ if (end && !escaped) {
+ state.tokenize = tokenBase;
+ }
+ return 'string';
+ };
+
+ function tokenComment(stream, state) {
+ var prev, next;
+ while((next = stream.next()) != null) {
+ if (prev === '*' && next === '/') {
+ state.tokenize = tokenBase;
+ break;
+ }
+ prev = next;
+ }
+ return 'comment';
+ }
+
+ function currentScope(state) {
+ var scope = null;
+ if (state.scopes.length > 0)
+ scope = state.scopes[state.scopes.length - 1];
+ return scope;
+ }
+
+ return {
+ startState: function() {
+ return {
+ tokenize: tokenBase,
+ scopes: []
+ };
+ },
+ token: function(stream, state) {
+ if (stream.eatSpace()) return null;
+ return state.tokenize(stream, state);
+ },
+ indent: function(state, textAfter) {
+ if (state.tokenize !== tokenBase && state.tokenize !== null)
+ return CodeMirror.Pass;
+
+ var delta = 0;
+ if (textAfter === ']' || textAfter === '];' ||
+ textAfter === '}' || textAfter === '};' ||
+ textAfter === ');')
+ delta = -1;
+
+ return (state.scopes.length + delta) * _config.indentUnit;
+ },
+ electricChars: "{}[]();",
+ blockCommentStart: "/*",
+ blockCommentEnd: "*/",
+ lineComment: "//"
+ };
+});
+
+CodeMirror.defineMIME('text/x-yacas', {
+ name: 'yacas'
+});
+
+});
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/yaml-frontmatter/yaml-frontmatter.js b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/yaml-frontmatter/yaml-frontmatter.js
new file mode 100644
index 0000000000..5c6175e4ec
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/yaml-frontmatter/yaml-frontmatter.js
@@ -0,0 +1,72 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: https://codemirror.net/LICENSE
+
+(function (mod) {
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
+ mod(require("../../lib/codemirror"), require("../yaml/yaml"))
+ else if (typeof define == "function" && define.amd) // AMD
+ define(["../../lib/codemirror", "../yaml/yaml"], mod)
+ else // Plain browser env
+ mod(CodeMirror)
+})(function (CodeMirror) {
+
+ var START = 0, FRONTMATTER = 1, BODY = 2
+
+ // a mixed mode for Markdown text with an optional YAML front matter
+ CodeMirror.defineMode("yaml-frontmatter", function (config, parserConfig) {
+ var yamlMode = CodeMirror.getMode(config, "yaml")
+ var innerMode = CodeMirror.getMode(config, parserConfig && parserConfig.base || "gfm")
+
+ function localMode(state) {
+ return state.state == FRONTMATTER ? {mode: yamlMode, state: state.yaml} : {mode: innerMode, state: state.inner}
+ }
+
+ return {
+ startState: function () {
+ return {
+ state: START,
+ yaml: null,
+ inner: CodeMirror.startState(innerMode)
+ }
+ },
+ copyState: function (state) {
+ return {
+ state: state.state,
+ yaml: state.yaml && CodeMirror.copyState(yamlMode, state.yaml),
+ inner: CodeMirror.copyState(innerMode, state.inner)
+ }
+ },
+ token: function (stream, state) {
+ if (state.state == START) {
+ if (stream.match('---', false)) {
+ state.state = FRONTMATTER
+ state.yaml = CodeMirror.startState(yamlMode)
+ return yamlMode.token(stream, state.yaml)
+ } else {
+ state.state = BODY
+ return innerMode.token(stream, state.inner)
+ }
+ } else if (state.state == FRONTMATTER) {
+ var end = stream.sol() && stream.match(/(---|\.\.\.)/, false)
+ var style = yamlMode.token(stream, state.yaml)
+ if (end) {
+ state.state = BODY
+ state.yaml = null
+ }
+ return style
+ } else {
+ return innerMode.token(stream, state.inner)
+ }
+ },
+ innerMode: localMode,
+ indent: function(state, a, b) {
+ var m = localMode(state)
+ return m.mode.indent ? m.mode.indent(m.state, a, b) : CodeMirror.Pass
+ },
+ blankLine: function (state) {
+ var m = localMode(state)
+ if (m.mode.blankLine) return m.mode.blankLine(m.state)
+ }
+ }
+ })
+});
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/yaml/yaml.js b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/yaml/yaml.js
new file mode 100644
index 0000000000..d464941026
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/yaml/yaml.js
@@ -0,0 +1,120 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: https://codemirror.net/LICENSE
+
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
+ mod(require("../../lib/codemirror"));
+ else if (typeof define == "function" && define.amd) // AMD
+ define(["../../lib/codemirror"], mod);
+ else // Plain browser env
+ mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("yaml", function() {
+
+ var cons = ['true', 'false', 'on', 'off', 'yes', 'no'];
+ var keywordRegex = new RegExp("\\b(("+cons.join(")|(")+"))$", 'i');
+
+ return {
+ token: function(stream, state) {
+ var ch = stream.peek();
+ var esc = state.escaped;
+ state.escaped = false;
+ /* comments */
+ if (ch == "#" && (stream.pos == 0 || /\s/.test(stream.string.charAt(stream.pos - 1)))) {
+ stream.skipToEnd();
+ return "comment";
+ }
+
+ if (stream.match(/^('([^']|\\.)*'?|"([^"]|\\.)*"?)/))
+ return "string";
+
+ if (state.literal && stream.indentation() > state.keyCol) {
+ stream.skipToEnd(); return "string";
+ } else if (state.literal) { state.literal = false; }
+ if (stream.sol()) {
+ state.keyCol = 0;
+ state.pair = false;
+ state.pairStart = false;
+ /* document start */
+ if(stream.match('---')) { return "def"; }
+ /* document end */
+ if (stream.match('...')) { return "def"; }
+ /* array list item */
+ if (stream.match(/\s*-\s+/)) { return 'meta'; }
+ }
+ /* inline pairs/lists */
+ if (stream.match(/^(\{|\}|\[|\])/)) {
+ if (ch == '{')
+ state.inlinePairs++;
+ else if (ch == '}')
+ state.inlinePairs--;
+ else if (ch == '[')
+ state.inlineList++;
+ else
+ state.inlineList--;
+ return 'meta';
+ }
+
+ /* list separator */
+ if (state.inlineList > 0 && !esc && ch == ',') {
+ stream.next();
+ return 'meta';
+ }
+ /* pairs separator */
+ if (state.inlinePairs > 0 && !esc && ch == ',') {
+ state.keyCol = 0;
+ state.pair = false;
+ state.pairStart = false;
+ stream.next();
+ return 'meta';
+ }
+
+ /* start of value of a pair */
+ if (state.pairStart) {
+ /* block literals */
+ if (stream.match(/^\s*(\||\>)\s*/)) { state.literal = true; return 'meta'; };
+ /* references */
+ if (stream.match(/^\s*(\&|\*)[a-z0-9\._-]+\b/i)) { return 'variable-2'; }
+ /* numbers */
+ if (state.inlinePairs == 0 && stream.match(/^\s*-?[0-9\.\,]+\s?$/)) { return 'number'; }
+ if (state.inlinePairs > 0 && stream.match(/^\s*-?[0-9\.\,]+\s?(?=(,|}))/)) { return 'number'; }
+ /* keywords */
+ if (stream.match(keywordRegex)) { return 'keyword'; }
+ }
+
+ /* pairs (associative arrays) -> key */
+ if (!state.pair && stream.match(/^\s*(?:[,\[\]{}&*!|>'"%@`][^\s'":]|[^,\[\]{}#&*!|>'"%@`])[^#]*?(?=\s*:($|\s))/)) {
+ state.pair = true;
+ state.keyCol = stream.indentation();
+ return "atom";
+ }
+ if (state.pair && stream.match(/^:\s*/)) { state.pairStart = true; return 'meta'; }
+
+ /* nothing found, continue */
+ state.pairStart = false;
+ state.escaped = (ch == '\\');
+ stream.next();
+ return null;
+ },
+ startState: function() {
+ return {
+ pair: false,
+ pairStart: false,
+ keyCol: 0,
+ inlinePairs: 0,
+ inlineList: 0,
+ literal: false,
+ escaped: false
+ };
+ },
+ lineComment: "#",
+ fold: "indent"
+ };
+});
+
+CodeMirror.defineMIME("text/x-yaml", "yaml");
+CodeMirror.defineMIME("text/yaml", "yaml");
+
+});
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/z80/z80.js b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/z80/z80.js
new file mode 100644
index 0000000000..8cea4ff90c
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/mode/z80/z80.js
@@ -0,0 +1,116 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: https://codemirror.net/LICENSE
+
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
+ mod(require("../../lib/codemirror"));
+ else if (typeof define == "function" && define.amd) // AMD
+ define(["../../lib/codemirror"], mod);
+ else // Plain browser env
+ mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode('z80', function(_config, parserConfig) {
+ var ez80 = parserConfig.ez80;
+ var keywords1, keywords2;
+ if (ez80) {
+ keywords1 = /^(exx?|(ld|cp)([di]r?)?|[lp]ea|pop|push|ad[cd]|cpl|daa|dec|inc|neg|sbc|sub|and|bit|[cs]cf|x?or|res|set|r[lr]c?a?|r[lr]d|s[lr]a|srl|djnz|nop|[de]i|halt|im|in([di]mr?|ir?|irx|2r?)|ot(dmr?|[id]rx|imr?)|out(0?|[di]r?|[di]2r?)|tst(io)?|slp)(\.([sl]?i)?[sl])?\b/i;
+ keywords2 = /^(((call|j[pr]|rst|ret[in]?)(\.([sl]?i)?[sl])?)|(rs|st)mix)\b/i;
+ } else {
+ keywords1 = /^(exx?|(ld|cp|in)([di]r?)?|pop|push|ad[cd]|cpl|daa|dec|inc|neg|sbc|sub|and|bit|[cs]cf|x?or|res|set|r[lr]c?a?|r[lr]d|s[lr]a|srl|djnz|nop|rst|[de]i|halt|im|ot[di]r|out[di]?)\b/i;
+ keywords2 = /^(call|j[pr]|ret[in]?|b_?(call|jump))\b/i;
+ }
+
+ var variables1 = /^(af?|bc?|c|de?|e|hl?|l|i[xy]?|r|sp)\b/i;
+ var variables2 = /^(n?[zc]|p[oe]?|m)\b/i;
+ var errors = /^([hl][xy]|i[xy][hl]|slia|sll)\b/i;
+ var numbers = /^([\da-f]+h|[0-7]+o|[01]+b|\d+d?)\b/i;
+
+ return {
+ startState: function() {
+ return {
+ context: 0
+ };
+ },
+ token: function(stream, state) {
+ if (!stream.column())
+ state.context = 0;
+
+ if (stream.eatSpace())
+ return null;
+
+ var w;
+
+ if (stream.eatWhile(/\w/)) {
+ if (ez80 && stream.eat('.')) {
+ stream.eatWhile(/\w/);
+ }
+ w = stream.current();
+
+ if (stream.indentation()) {
+ if ((state.context == 1 || state.context == 4) && variables1.test(w)) {
+ state.context = 4;
+ return 'var2';
+ }
+
+ if (state.context == 2 && variables2.test(w)) {
+ state.context = 4;
+ return 'var3';
+ }
+
+ if (keywords1.test(w)) {
+ state.context = 1;
+ return 'keyword';
+ } else if (keywords2.test(w)) {
+ state.context = 2;
+ return 'keyword';
+ } else if (state.context == 4 && numbers.test(w)) {
+ return 'number';
+ }
+
+ if (errors.test(w))
+ return 'error';
+ } else if (stream.match(numbers)) {
+ return 'number';
+ } else {
+ return null;
+ }
+ } else if (stream.eat(';')) {
+ stream.skipToEnd();
+ return 'comment';
+ } else if (stream.eat('"')) {
+ while (w = stream.next()) {
+ if (w == '"')
+ break;
+
+ if (w == '\\')
+ stream.next();
+ }
+ return 'string';
+ } else if (stream.eat('\'')) {
+ if (stream.match(/\\?.'/))
+ return 'number';
+ } else if (stream.eat('.') || stream.sol() && stream.eat('#')) {
+ state.context = 5;
+
+ if (stream.eatWhile(/\w/))
+ return 'def';
+ } else if (stream.eat('$')) {
+ if (stream.eatWhile(/[\da-f]/i))
+ return 'number';
+ } else if (stream.eat('%')) {
+ if (stream.eatWhile(/[01]/))
+ return 'number';
+ } else {
+ stream.next();
+ }
+ return null;
+ }
+ };
+});
+
+CodeMirror.defineMIME("text/x-z80", "z80");
+CodeMirror.defineMIME("text/x-ez80", { name: "z80", ez80: true });
+
+});
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/3024-day.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/3024-day.css
new file mode 100644
index 0000000000..7132655306
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/3024-day.css
@@ -0,0 +1,41 @@
+/*
+
+ Name: 3024 day
+ Author: Jan T. Sott (http://github.com/idleberg)
+
+ CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror)
+ Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16)
+
+*/
+
+.cm-s-3024-day.CodeMirror { background: #f7f7f7; color: #3a3432; }
+.cm-s-3024-day div.CodeMirror-selected { background: #d6d5d4; }
+
+.cm-s-3024-day .CodeMirror-line::selection, .cm-s-3024-day .CodeMirror-line > span::selection, .cm-s-3024-day .CodeMirror-line > span > span::selection { background: #d6d5d4; }
+.cm-s-3024-day .CodeMirror-line::-moz-selection, .cm-s-3024-day .CodeMirror-line > span::-moz-selection, .cm-s-3024-day .CodeMirror-line > span > span::selection { background: #d9d9d9; }
+
+.cm-s-3024-day .CodeMirror-gutters { background: #f7f7f7; border-right: 0px; }
+.cm-s-3024-day .CodeMirror-guttermarker { color: #db2d20; }
+.cm-s-3024-day .CodeMirror-guttermarker-subtle { color: #807d7c; }
+.cm-s-3024-day .CodeMirror-linenumber { color: #807d7c; }
+
+.cm-s-3024-day .CodeMirror-cursor { border-left: 1px solid #5c5855; }
+
+.cm-s-3024-day span.cm-comment { color: #cdab53; }
+.cm-s-3024-day span.cm-atom { color: #a16a94; }
+.cm-s-3024-day span.cm-number { color: #a16a94; }
+
+.cm-s-3024-day span.cm-property, .cm-s-3024-day span.cm-attribute { color: #01a252; }
+.cm-s-3024-day span.cm-keyword { color: #db2d20; }
+.cm-s-3024-day span.cm-string { color: #fded02; }
+
+.cm-s-3024-day span.cm-variable { color: #01a252; }
+.cm-s-3024-day span.cm-variable-2 { color: #01a0e4; }
+.cm-s-3024-day span.cm-def { color: #e8bbd0; }
+.cm-s-3024-day span.cm-bracket { color: #3a3432; }
+.cm-s-3024-day span.cm-tag { color: #db2d20; }
+.cm-s-3024-day span.cm-link { color: #a16a94; }
+.cm-s-3024-day span.cm-error { background: #db2d20; color: #5c5855; }
+
+.cm-s-3024-day .CodeMirror-activeline-background { background: #e8f2ff; }
+.cm-s-3024-day .CodeMirror-matchingbracket { text-decoration: underline; color: #a16a94 !important; }
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/3024-night.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/3024-night.css
new file mode 100644
index 0000000000..adc5900ad1
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/3024-night.css
@@ -0,0 +1,39 @@
+/*
+
+ Name: 3024 night
+ Author: Jan T. Sott (http://github.com/idleberg)
+
+ CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror)
+ Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16)
+
+*/
+
+.cm-s-3024-night.CodeMirror { background: #090300; color: #d6d5d4; }
+.cm-s-3024-night div.CodeMirror-selected { background: #3a3432; }
+.cm-s-3024-night .CodeMirror-line::selection, .cm-s-3024-night .CodeMirror-line > span::selection, .cm-s-3024-night .CodeMirror-line > span > span::selection { background: rgba(58, 52, 50, .99); }
+.cm-s-3024-night .CodeMirror-line::-moz-selection, .cm-s-3024-night .CodeMirror-line > span::-moz-selection, .cm-s-3024-night .CodeMirror-line > span > span::-moz-selection { background: rgba(58, 52, 50, .99); }
+.cm-s-3024-night .CodeMirror-gutters { background: #090300; border-right: 0px; }
+.cm-s-3024-night .CodeMirror-guttermarker { color: #db2d20; }
+.cm-s-3024-night .CodeMirror-guttermarker-subtle { color: #5c5855; }
+.cm-s-3024-night .CodeMirror-linenumber { color: #5c5855; }
+
+.cm-s-3024-night .CodeMirror-cursor { border-left: 1px solid #807d7c; }
+
+.cm-s-3024-night span.cm-comment { color: #cdab53; }
+.cm-s-3024-night span.cm-atom { color: #a16a94; }
+.cm-s-3024-night span.cm-number { color: #a16a94; }
+
+.cm-s-3024-night span.cm-property, .cm-s-3024-night span.cm-attribute { color: #01a252; }
+.cm-s-3024-night span.cm-keyword { color: #db2d20; }
+.cm-s-3024-night span.cm-string { color: #fded02; }
+
+.cm-s-3024-night span.cm-variable { color: #01a252; }
+.cm-s-3024-night span.cm-variable-2 { color: #01a0e4; }
+.cm-s-3024-night span.cm-def { color: #e8bbd0; }
+.cm-s-3024-night span.cm-bracket { color: #d6d5d4; }
+.cm-s-3024-night span.cm-tag { color: #db2d20; }
+.cm-s-3024-night span.cm-link { color: #a16a94; }
+.cm-s-3024-night span.cm-error { background: #db2d20; color: #807d7c; }
+
+.cm-s-3024-night .CodeMirror-activeline-background { background: #2F2F2F; }
+.cm-s-3024-night .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; }
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/abbott.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/abbott.css
new file mode 100644
index 0000000000..3e516a67f9
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/abbott.css
@@ -0,0 +1,268 @@
+/*
+ * abbott.css
+ * A warm, dark theme for prose and code, with pastels and pretty greens.
+ *
+ * Ported from abbott.vim (https://github.com/bcat/abbott.vim) version 2.1.
+ * Original design and CodeMirror port by Jonathan Rascher.
+ *
+ * This theme shares the following color palette with the Vim color scheme.
+ *
+ * Brown shades:
+ * bistre: #231c14
+ * chocolate: #3c3022
+ * cocoa: #745d42
+ * vanilla_cream: #fef3b4
+ *
+ * Red shades:
+ * crimson: #d80450
+ * cinnabar: #f63f05
+ *
+ * Green shades:
+ * dark_olive: #273900
+ * forest_green: #24a507
+ * chartreuse: #a0ea00
+ * pastel_chartreuse: #d8ff84
+ *
+ * Yellow shades:
+ * marigold: #fbb32f
+ * lemon_meringue: #fbec5d
+ *
+ * Blue shades:
+ * cornflower_blue: #3f91f1
+ * periwinkle_blue: #8ccdf0
+ *
+ * Magenta shades:
+ * french_pink: #ec6c99
+ * lavender: #e6a2f3
+ *
+ * Cyan shades:
+ * zomp: #39a78d
+ * seafoam_green: #00ff7f
+ */
+
+/* Style the UI: */
+
+/* Equivalent to Vim's Normal group. */
+.cm-s-abbott.CodeMirror {
+ background: #231c14 /* bistre */;
+ color: #d8ff84 /* pastel_chartreuse */;
+}
+
+/* Roughly equivalent to Vim's LineNr group. */
+.cm-s-abbott .CodeMirror-gutters {
+ background: #231c14 /* bistre */;
+ border: none;
+}
+.cm-s-abbott .CodeMirror-linenumber { color: #fbec5d /* lemon_meringue */; }
+
+.cm-s-abbott .CodeMirror-guttermarker { color: #f63f05 /* cinnabar */; }
+
+/* Roughly equivalent to Vim's FoldColumn group. */
+.cm-s-abbott .CodeMirror-guttermarker-subtle { color: #fbb32f /* marigold */; }
+
+/*
+ * Roughly equivalent to Vim's CursorColumn group. (We use a brighter color
+ * since Vim's cursorcolumn option highlights a whole column, whereas
+ * CodeMirror's rule just highlights a thin line.)
+ */
+.cm-s-abbott .CodeMirror-ruler { border-color: #745d42 /* cocoa */; }
+
+/* Equivalent to Vim's Cursor group in insert mode. */
+.cm-s-abbott .CodeMirror-cursor { border-color: #a0ea00 /* chartreuse */; }
+
+/* Equivalent to Vim's Cursor group in normal mode. */
+.cm-s-abbott.cm-fat-cursor .CodeMirror-cursor,
+.cm-s-abbott .cm-animate-fat-cursor {
+ /*
+ * CodeMirror doesn't allow changing the foreground color of the character
+ * under the cursor, so we can't use a reverse video effect for the cursor.
+ * Instead, make it semitransparent.
+ */
+ background: rgba(160, 234, 0, 0.5) /* chartreuse */;
+}
+.cm-s-abbott.cm-fat-cursor .CodeMirror-cursors {
+ /*
+ * Boost the z-index so the fat cursor shows up on top of text and
+ * matchingbracket/matchingtag highlights.
+ */
+ z-index: 3;
+}
+
+/* Equivalent to Vim's Cursor group in replace mode. */
+.cm-s-abbott .CodeMirror-overwrite .CodeMirror-cursor {
+ border-bottom: 1px solid #a0ea00 /* chartreuse */;
+ border-left: none;
+ width: auto;
+}
+
+/* Roughly equivalent to Vim's CursorIM group. */
+.cm-s-abbott .CodeMirror-secondarycursor {
+ border-color: #00ff7f /* seafoam_green */;
+}
+
+/* Roughly equivalent to Vim's Visual group. */
+.cm-s-abbott .CodeMirror-selected,
+.cm-s-abbott.CodeMirror-focused .CodeMirror-selected {
+ background: #273900 /* dark_olive */;
+}
+.cm-s-abbott .CodeMirror-line::selection,
+.cm-s-abbott .CodeMirror-line > span::selection,
+.cm-s-abbott .CodeMirror-line > span > span::selection {
+ background: #273900 /* dark_olive */;
+}
+.cm-s-abbott .CodeMirror-line::-moz-selection,
+.cm-s-abbott .CodeMirror-line > span::-moz-selection,
+.cm-s-abbott .CodeMirror-line > span > span::-moz-selection {
+ background: #273900 /* dark_olive */;
+}
+
+/* Roughly equivalent to Vim's SpecialKey group. */
+.cm-s-abbott .cm-tab { color: #00ff7f /* seafoam_green */; }
+
+/* Equivalent to Vim's Search group. */
+.cm-s-abbott .cm-searching {
+ background: #fef3b4 /* vanilla_cream */ !important;
+ color: #231c14 /* bistre */ !important;
+}
+
+/* Style syntax highlighting modes: */
+
+/* Equivalent to Vim's Comment group. */
+.cm-s-abbott span.cm-comment {
+ color: #fbb32f /* marigold */;
+ font-style: italic;
+}
+
+/* Equivalent to Vim's String group. */
+.cm-s-abbott span.cm-string,
+.cm-s-abbott span.cm-string-2 {
+ color: #e6a2f3 /* lavender */;
+}
+
+/* Equivalent to Vim's Constant group. */
+.cm-s-abbott span.cm-number,
+.cm-s-abbott span.cm-string.cm-url { color: #f63f05 /* cinnabar */; }
+
+/* Roughly equivalent to Vim's SpecialKey group. */
+.cm-s-abbott span.cm-invalidchar { color: #00ff7f /* seafoam_green */; }
+
+/* Equivalent to Vim's Special group. */
+.cm-s-abbott span.cm-atom { color: #fef3b4 /* vanilla_cream */; }
+
+/* Equivalent to Vim's Delimiter group. */
+.cm-s-abbott span.cm-bracket,
+.cm-s-abbott span.cm-punctuation {
+ color: #fef3b4 /* vanilla_cream */;
+}
+
+/* Equivalent Vim's Operator group. */
+.cm-s-abbott span.cm-operator { font-weight: bold; }
+
+/* Roughly equivalent to Vim's Identifier group. */
+.cm-s-abbott span.cm-def,
+.cm-s-abbott span.cm-variable,
+.cm-s-abbott span.cm-variable-2,
+.cm-s-abbott span.cm-variable-3 {
+ color: #8ccdf0 /* periwinkle_blue */;
+}
+
+/* Roughly equivalent to Vim's Function group. */
+.cm-s-abbott span.cm-builtin,
+.cm-s-abbott span.cm-property,
+.cm-s-abbott span.cm-qualifier {
+ color: #3f91f1 /* cornflower_blue */;
+}
+
+/* Equivalent to Vim's Type group. */
+.cm-s-abbott span.cm-type { color: #24a507 /* forest_green */; }
+
+/* Equivalent to Vim's Keyword group. */
+.cm-s-abbott span.cm-keyword {
+ color: #d80450 /* crimson */;
+ font-weight: bold;
+}
+
+/* Equivalent to Vim's PreProc group. */
+.cm-s-abbott span.cm-meta { color: #ec6c99 /* french_pink */; }
+
+/* Equivalent to Vim's htmlTagName group (linked to Statement). */
+.cm-s-abbott span.cm-tag {
+ color: #d80450 /* crimson */;
+ font-weight: bold;
+}
+
+/* Equivalent to Vim's htmlArg group (linked to Type). */
+.cm-s-abbott span.cm-attribute { color: #24a507 /* forest_green */; }
+
+/* Equivalent to Vim's htmlH1, markdownH1, etc. groups (linked to Title). */
+.cm-s-abbott span.cm-header {
+ color: #d80450 /* crimson */;
+ font-weight: bold;
+}
+
+/* Equivalent to Vim's markdownRule group (linked to PreProc). */
+.cm-s-abbott span.cm-hr { color: #ec6c99 /* french_pink */; }
+
+/* Roughly equivalent to Vim's Underlined group. */
+.cm-s-abbott span.cm-link { color: #e6a2f3 /* lavender */; }
+
+/* Equivalent to Vim's diffRemoved group. */
+.cm-s-abbott span.cm-negative {
+ background: #d80450 /* crimson */;
+ color: #231c14 /* bistre */;
+}
+
+/* Equivalent to Vim's diffAdded group. */
+.cm-s-abbott span.cm-positive {
+ background: #a0ea00 /* chartreuse */;
+ color: #231c14 /* bistre */;
+ font-weight: bold;
+}
+
+/* Equivalent to Vim's Error group. */
+.cm-s-abbott span.cm-error {
+ background: #d80450 /* crimson */;
+ color: #231c14 /* bistre */;
+}
+
+/* Style addons: */
+
+/* Equivalent to Vim's MatchParen group. */
+.cm-s-abbott span.CodeMirror-matchingbracket {
+ background: #745d42 /* cocoa */ !important;
+ color: #231c14 /* bistre */ !important;
+ font-weight: bold;
+}
+
+/*
+ * Roughly equivalent to Vim's Error group. (Vim doesn't seem to have a direct
+ * equivalent in its own matchparen plugin, but many syntax highlighting plugins
+ * mark mismatched brackets as Error.)
+ */
+.cm-s-abbott span.CodeMirror-nonmatchingbracket {
+ background: #d80450 /* crimson */ !important;
+ color: #231c14 /* bistre */ !important;
+}
+
+.cm-s-abbott .CodeMirror-matchingtag,
+.cm-s-abbott .cm-matchhighlight {
+ outline: 1px solid #39a78d /* zomp */;
+}
+
+/* Equivalent to Vim's CursorLine group. */
+.cm-s-abbott .CodeMirror-activeline-background,
+.cm-s-abbott .CodeMirror-activeline-gutter {
+ background: #3c3022 /* chocolate */;
+}
+
+/* Equivalent to Vim's CursorLineNr group. */
+.cm-s-abbott .CodeMirror-activeline-gutter .CodeMirror-linenumber {
+ color: #d8ff84 /* pastel_chartreuse */;
+ font-weight: bold;
+}
+
+/* Roughly equivalent to Vim's Folded group. */
+.cm-s-abbott .CodeMirror-foldmarker {
+ color: #f63f05 /* cinnabar */;
+ text-shadow: none;
+}
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/abcdef.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/abcdef.css
new file mode 100644
index 0000000000..cf93530946
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/abcdef.css
@@ -0,0 +1,32 @@
+.cm-s-abcdef.CodeMirror { background: #0f0f0f; color: #defdef; }
+.cm-s-abcdef div.CodeMirror-selected { background: #515151; }
+.cm-s-abcdef .CodeMirror-line::selection, .cm-s-abcdef .CodeMirror-line > span::selection, .cm-s-abcdef .CodeMirror-line > span > span::selection { background: rgba(56, 56, 56, 0.99); }
+.cm-s-abcdef .CodeMirror-line::-moz-selection, .cm-s-abcdef .CodeMirror-line > span::-moz-selection, .cm-s-abcdef .CodeMirror-line > span > span::-moz-selection { background: rgba(56, 56, 56, 0.99); }
+.cm-s-abcdef .CodeMirror-gutters { background: #555; border-right: 2px solid #314151; }
+.cm-s-abcdef .CodeMirror-guttermarker { color: #222; }
+.cm-s-abcdef .CodeMirror-guttermarker-subtle { color: azure; }
+.cm-s-abcdef .CodeMirror-linenumber { color: #FFFFFF; }
+.cm-s-abcdef .CodeMirror-cursor { border-left: 1px solid #00FF00; }
+
+.cm-s-abcdef span.cm-keyword { color: darkgoldenrod; font-weight: bold; }
+.cm-s-abcdef span.cm-atom { color: #77F; }
+.cm-s-abcdef span.cm-number { color: violet; }
+.cm-s-abcdef span.cm-def { color: #fffabc; }
+.cm-s-abcdef span.cm-variable { color: #abcdef; }
+.cm-s-abcdef span.cm-variable-2 { color: #cacbcc; }
+.cm-s-abcdef span.cm-variable-3, .cm-s-abcdef span.cm-type { color: #def; }
+.cm-s-abcdef span.cm-property { color: #fedcba; }
+.cm-s-abcdef span.cm-operator { color: #ff0; }
+.cm-s-abcdef span.cm-comment { color: #7a7b7c; font-style: italic;}
+.cm-s-abcdef span.cm-string { color: #2b4; }
+.cm-s-abcdef span.cm-meta { color: #C9F; }
+.cm-s-abcdef span.cm-qualifier { color: #FFF700; }
+.cm-s-abcdef span.cm-builtin { color: #30aabc; }
+.cm-s-abcdef span.cm-bracket { color: #8a8a8a; }
+.cm-s-abcdef span.cm-tag { color: #FFDD44; }
+.cm-s-abcdef span.cm-attribute { color: #DDFF00; }
+.cm-s-abcdef span.cm-error { color: #FF0000; }
+.cm-s-abcdef span.cm-header { color: aquamarine; font-weight: bold; }
+.cm-s-abcdef span.cm-link { color: blueviolet; }
+
+.cm-s-abcdef .CodeMirror-activeline-background { background: #314151; }
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/ambiance-mobile.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/ambiance-mobile.css
new file mode 100644
index 0000000000..88d332e1a7
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/ambiance-mobile.css
@@ -0,0 +1,5 @@
+.cm-s-ambiance.CodeMirror {
+ -webkit-box-shadow: none;
+ -moz-box-shadow: none;
+ box-shadow: none;
+}
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/ambiance.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/ambiance.css
new file mode 100644
index 0000000000..782fca43f5
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/ambiance.css
@@ -0,0 +1,74 @@
+/* ambiance theme for codemirror */
+
+/* Color scheme */
+
+.cm-s-ambiance .cm-header { color: blue; }
+.cm-s-ambiance .cm-quote { color: #24C2C7; }
+
+.cm-s-ambiance .cm-keyword { color: #cda869; }
+.cm-s-ambiance .cm-atom { color: #CF7EA9; }
+.cm-s-ambiance .cm-number { color: #78CF8A; }
+.cm-s-ambiance .cm-def { color: #aac6e3; }
+.cm-s-ambiance .cm-variable { color: #ffb795; }
+.cm-s-ambiance .cm-variable-2 { color: #eed1b3; }
+.cm-s-ambiance .cm-variable-3, .cm-s-ambiance .cm-type { color: #faded3; }
+.cm-s-ambiance .cm-property { color: #eed1b3; }
+.cm-s-ambiance .cm-operator { color: #fa8d6a; }
+.cm-s-ambiance .cm-comment { color: #555; font-style:italic; }
+.cm-s-ambiance .cm-string { color: #8f9d6a; }
+.cm-s-ambiance .cm-string-2 { color: #9d937c; }
+.cm-s-ambiance .cm-meta { color: #D2A8A1; }
+.cm-s-ambiance .cm-qualifier { color: yellow; }
+.cm-s-ambiance .cm-builtin { color: #9999cc; }
+.cm-s-ambiance .cm-bracket { color: #24C2C7; }
+.cm-s-ambiance .cm-tag { color: #fee4ff; }
+.cm-s-ambiance .cm-attribute { color: #9B859D; }
+.cm-s-ambiance .cm-hr { color: pink; }
+.cm-s-ambiance .cm-link { color: #F4C20B; }
+.cm-s-ambiance .cm-special { color: #FF9D00; }
+.cm-s-ambiance .cm-error { color: #AF2018; }
+
+.cm-s-ambiance .CodeMirror-matchingbracket { color: #0f0; }
+.cm-s-ambiance .CodeMirror-nonmatchingbracket { color: #f22; }
+
+.cm-s-ambiance div.CodeMirror-selected { background: rgba(255, 255, 255, 0.15); }
+.cm-s-ambiance.CodeMirror-focused div.CodeMirror-selected { background: rgba(255, 255, 255, 0.10); }
+.cm-s-ambiance .CodeMirror-line::selection, .cm-s-ambiance .CodeMirror-line > span::selection, .cm-s-ambiance .CodeMirror-line > span > span::selection { background: rgba(255, 255, 255, 0.10); }
+.cm-s-ambiance .CodeMirror-line::-moz-selection, .cm-s-ambiance .CodeMirror-line > span::-moz-selection, .cm-s-ambiance .CodeMirror-line > span > span::-moz-selection { background: rgba(255, 255, 255, 0.10); }
+
+/* Editor styling */
+
+.cm-s-ambiance.CodeMirror {
+ line-height: 1.40em;
+ color: #E6E1DC;
+ background-color: #202020;
+ -webkit-box-shadow: inset 0 0 10px black;
+ -moz-box-shadow: inset 0 0 10px black;
+ box-shadow: inset 0 0 10px black;
+}
+
+.cm-s-ambiance .CodeMirror-gutters {
+ background: #3D3D3D;
+ border-right: 1px solid #4D4D4D;
+ box-shadow: 0 10px 20px black;
+}
+
+.cm-s-ambiance .CodeMirror-linenumber {
+ text-shadow: 0px 1px 1px #4d4d4d;
+ color: #111;
+ padding: 0 5px;
+}
+
+.cm-s-ambiance .CodeMirror-guttermarker { color: #aaa; }
+.cm-s-ambiance .CodeMirror-guttermarker-subtle { color: #111; }
+
+.cm-s-ambiance .CodeMirror-cursor { border-left: 1px solid #7991E8; }
+
+.cm-s-ambiance .CodeMirror-activeline-background {
+ background: none repeat scroll 0% 0% rgba(255, 255, 255, 0.031);
+}
+
+.cm-s-ambiance.CodeMirror,
+.cm-s-ambiance .CodeMirror-gutters {
+ background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAQAAAAHUWYVAABFFUlEQVQYGbzBCeDVU/74/6fj9HIcx/FRHx9JCFmzMyGRURhLZIkUsoeRfUjS2FNDtr6WkMhO9sm+S8maJfu+Jcsg+/o/c+Z4z/t97/vezy3z+z8ekGlnYICG/o7gdk+wmSHZ1z4pJItqapjoKXWahm8NmV6eOTbWUOp6/6a/XIg6GQqmenJ2lDHyvCFZ2cBDbmtHA043VFhHwXxClWmeYAdLhV00Bd85go8VmaFCkbVkzlQENzfBDZ5gtN7HwF0KDrTwJ0dypSOzpaKCMwQHKTIreYIxlmhXTzTWkVm+LTynZhiSBT3RZQ7aGfjGEd3qyXQ1FDymqbKxpspERQN2MiRjNZlFFQXfCNFm9nM1zpAsoYjmtRTc5ajwuaXc5xrWskT97RaKzAGe5ARHhVUsDbjKklziiX5WROcJwSNCNI+9w1Jwv4Zb2r7lCMZ4oq5C0EdTx+2GzNuKpJ+iFf38JEWkHJn9DNF7mmBDITrWEg0VWL3pHU20tSZnuqWu+R3BtYa8XxV1HO7GyD32UkOpL/yDloINFTmvtId+nmAjxRw40VMwVKiwrKLE4bK5UOVntYwhOcSSXKrJHKPJedocpGjVz/ZMIbnYUPB10/eKCrs5apqpgVmWzBYWpmtKHecJPjaUuEgRDDaU0oZghCJ6zNMQ5ZhDYx05r5v2muQdM0EILtXUsaKiQX9WMEUotagQzFbUNN6NUPC2nm5pxEWGCjMc3GdJHjSU2kORLK/JGSrkfGEIjncU/CYUnOipoYemwj8tST9NsJmB7TUVXtbUtXATJVZXBMvYeTXJfobgJUPmGMP/yFaWonaa6BcFO3nqcIqCozSZoZoSr1g4zJOzuyGnxTEX3lUEJ7WcZgme8ddaWvWJo2AJR9DZU3CUIbhCSG6ybSwN6qtJVnCU2svDTP2ZInOw2cBTrqtQahtNZn9NcJ4l2NaSmSkkP1noZWnVwkLmdUPOwLZEwy2Z3S3R+4rIG9hcbpPXHFVWcQdZkn2FOta3cKWQnNRC5g1LsJah4GCzSVsKnCOY5OAFRTBekyyryeyilhFKva75r4Mc0aWanGEaThcy31s439KKxTzJYY5WTHPU1FtIHjQU3Oip4xlNzj/lBw23dYZVliQa7WAXf4shetcQfatI+jWRDBPmyNeW6A1P5kdDgyYJlba0BIM8BZu1JfrFwItyjcAMR3K0BWOIrtMEXyhyrlVEx3ui5dUBjmB/Q3CXW85R4mBD0s7B+4q5tKUjOlb9qqmhi5AZ6GFIC5HXtOobdYGlVdMVbNJ8toNTFcHxnoL+muBagcctjWnbNMuR00uI7nQESwg5q2qqrKWIfrNUmeQocY6HuyxJV02wj36w00yhpmUFenv4p6fUkZYqLyuinx2RGOjhCXYyJF84oiU00YMOOhhquNdfbOB7gU88pY4xJO8LVdp6/q2voeB4R04vIdhSE40xZObx1HGGJ/ja0LBthFInKaLPPFzuCaYaoj8JjPME8yoyxo6zlBqkiUZYgq00OYMswbWO5NGmq+xhipxHLRW29ARjNKXO0wRnear8XSg4XFPLKEPUS1GqvyLwiuBUoa7zpZ0l5xxFwWmWZC1H5h5FwU8eQ7K+g8UcVY6TMQreVQT/8uQ8Z+ALIXnSEa2pYZQneE9RZbSBNYXfWYJzW/h/4j4Dp1tYVcFIC5019Vyi4ThPqSFCzjGWaHQTBU8q6vrVwgxP9Lkm840imWKpcLCjYTtrKuwvsKSnrvHCXGkSMk9p6lhckfRpIeis+N2PiszT+mFLspyGleUhDwcLrZqmyeylxwjBcKHEapqkmyangyLZRVOijwOtCY5SsG5zL0OwlCJ4y5KznF3EUNDDrinwiyLZRzOXtlBbK5ITHFGLp8Q0R6ab6mS7enI2cFrxOyHvOCFaT1HThS1krjCwqWeurCkk+willhCC+RSZnRXBiZaC5RXRIZYKp2lyfrHwiKPKR0JDzrdU2EFgpidawlFDR6FgXUMNa+g1FY3bUQh2cLCwosRdnuQTS/S+JVrGLeWIvtQUvONJxlqSQYYKpwoN2kaocLjdVsis4Mk80ESF2YpSkzwldjHkjFCUutI/r+EHDU8oCs6yzL3PhWiEooZdFMkymlas4AcI3KmoMMNSQ3tHzjGWCrcJJdYyZC7QFGwjRL9p+MrRkAGWzIaWCn9W0F3TsK01c2ZvQw0byvxuQU0r1lM0qJO7wW0kRIMdDTtXEdzi4VIh+EoIHm0mWtAtpCixlabgn83fKTI7anJe9ST7WIK1DMGpQmYeA58ImV6ezOGOzK2Kgq01pd60cKWiUi9Lievb/0vIDPHQ05Kzt4ddPckQBQtoaurjyHnek/nKzpQLrVgKPjIkh2v4uyezpv+Xoo7fPFXaGFp1vaLKxQ4uUpQQS5VuQs7BCq4xRJv7fwpVvvFEB3j+620haOuocqMhWd6TTPAEx+mdFNGHdranFe95WrWmIvlY4F1Dle2ECgc6cto7SryuqGGGha0tFQ5V53migUKmg6XKAo4qS3mik+0OZpAhOLeZKicacgaYcyx5hypYQE02ZA4xi/pNhOQxR4klNKyqacj+mpxnLTnnGSo85++3ZCZq6lrZkXlGEX3o+C9FieccJbZWVFjC0Yo1FZnJhoYMFoI1hEZ9r6hwg75HwzBNhbZCdJEfJwTPGzJvaKImw1yYX1HDAmpXR+ZJQ/SmgqMNVQb5vgamGwLtt7VwvP7Qk1xpiM5x5Cyv93E06MZmgs0Nya2azIKOYKCGBQQW97RmhKNKF02JZqHEJ4o58qp7X5EcZmc56trXEqzjCBZ1MFGR87Ql2tSTs6CGxS05PTzRQorkbw7aKoKXFDXsYW42VJih/q+FP2BdTzDTwVqOYB13liM50vG7wy28qagyuIXMeQI/Oqq8bcn5wJI50xH00CRntyfpL1T4hydYpoXgNiFzoIUTDZnLNRzh4TBHwbYGDvZkxmlyJloyr6tRihpeUG94GnKtIznREF0tzJG/OOr73JBcrSh1k6WuTprgLU+mnSGnv6Zge0NNz+kTDdH8nuAuTdJDCNb21LCiIuqlYbqGzT3RAoZofQfjFazkqeNWdYaGvYTM001EW2oKPvVk1ldUGSgUtHFwjKM1h9jnFcmy5lChoLNaQMGGDsYbKixlaMBmmsx1QjCfflwTfO/gckW0ruZ3jugKR3R5W9hGUWqCgxuFgsuaCHorotGKzGaeZB9DMsaTnKCpMtwTvOzhYk0rdrArKCqcaWmVk1+F372ur1YkKxgatI8Qfe1gIX9wE9FgS8ESmuABIXnRUbCapcKe+nO7slClSZFzpV/LkLncEb1qiO42fS3R855Su2mCLh62t1SYZZYVmKwIHjREF2uihTzB20JOkz7dkxzYQnK0UOU494wh+VWRc6Un2kpTaVgLDFEkJ/uhzRcI0YKGgpGWOlocBU/a4fKoJ/pEaNV6jip3+Es9VXY078rGnmAdf7t9ylPXS34RBSuYPs1UecZTU78WanhBCHpZ5sAoTz0LGZKjPf9TRypqWEiTvOFglL1fCEY3wY/++rbk7C8bWebA6p6om6PgOL2kp44TFJlVNBXae2rqqdZztOJpT87GQsE9jqCPIe9VReZuQ/CIgacsyZdCpIScSYqcZk8r+nsyCzhyfhOqHGOIvrLknC8wTpFcaYiGC/RU1NRbUeUpocQOnkRpGOrIOcNRx+1uA0UrzhSSt+VyS3SJpnFWkzNDqOFGIWcfR86DnmARTQ1HKIL33ExPiemeOhYSSjzlSUZZuE4TveoJLnBUOFof6KiysCbnAEcZgcUNTDOwkqWu3RWtmGpZwlHhJENdZ3miGz0lJlsKnjbwqSHQjpxnFDlTLLwqJPMZMjd7KrzkSG7VsxXBZE+F8YZkb01Oe00yyRK9psh5SYh29ySPKBo2ylNht7ZkZnsKenjKNJu9PNEyZpaCHv4Kt6RQsLvAVp7M9kIimmCUwGeWqLMmGuIotYMmWNpSahkhZw9FqZsVnKJhsjAHvtHMsTM9fCI06Dx/u3vfUXCqfsKRc4oFY2jMsoo/7DJDwZ1CsIKnJu+J9ldkpmiCxQx1rWjI+T9FwcWWzOuaYH0Hj7klNRVWEQpmaqosakiGNTFHdjS/qnUdmf0NJW5xsL0HhimCCZZSRzmSPTXJQ4aaztAwtZnoabebJ+htCaZ7Cm535ByoqXKbX1WRc4Eh2MkRXWzImVc96Cj4VdOKVxR84VdQsIUM8Psoou2byVHyZFuq7O8otbSQ2UAoeEWTudATLGSpZzVLlXVkPU2Jc+27lsw2jmg5T5VhbeE3BT083K9WsTTkFU/Osi0rC5lRlpwRHUiesNS0sOvmqGML1aRbPAxTJD9ZKtxuob+hhl8cwYGWpJ8nub7t5p6coYbMovZ1BTdaKn1jYD6h4GFDNFyT/Kqe1XCXphXHOKLZmuRSRdBPEfVUXQzJm5YGPGGJdvAEr7hHNdGZnuBvrpciGmopOLf5N0uVMy0FfYToJk90uUCbJupaVpO53UJXR2bVpoU00V2KOo4zMFrBd0Jtz2pa0clT5Q5L8IpQ177mWQejPMEJhuQjS10ref6HHjdEhy1P1EYR7GtO0uSsKJQYLiTnG1rVScj5lyazpqWGl5uBbRWl7m6ixGOOnEsMJR7z8J0n6KMnCdxhiNYQCoZ6CmYLnO8omC3MkW3bktlPmEt/VQQHejL3+dOE5FlPdK/Mq8hZxxJtLyRrepLThYKbLZxkSb5W52vYxNOaOxUF0yxMUPwBTYqCzy01XayYK0sJyWBLqX0MwU5CzoymRzV0EjjeUeLgDpTo6ij42ZAzvD01dHUUTPLU96MdLbBME8nFBn7zJCMtJcZokn8YoqU0FS5WFKyniHobguMcmW8N0XkWZjkyN3hqOMtS08r+/xTBwpZSZ3qiVRX8SzMHHjfUNFjgHEPmY9PL3ykEzxkSre/1ZD6z/NuznuB0RcE1TWTm9zRgfUWVJiG6yrzgmWPXC8EAR4Wxhlad0ZbgQyEz3pG5RVEwwDJH2mgKpjcTiCOzn1lfUWANFbZ2BA8balnEweJC9J0iuaeZoI+ippFCztEKVvckR2iice1JvhVytrQwUAZpgsubCPaU7xUe9vWnaOpaSBEspalykhC9bUlOMpT42ZHca6hyrqKmw/wMR8H5ZmdFoBVJb03O4UL0tSNnvIeRmkrLWqrs78gcrEn2tpcboh0UPOW3UUR9PMk4T4nnNKWmCjlrefhCwxRNztfmIQVdDElvS4m1/WuOujoZCs5XVOjtKPGokJzsYCtFYoWonSPT21DheU/wWhM19FcElwqNGOsp9Q8N/cwXaiND1MmeL1Q5XROtYYgGeFq1aTMsoMmcrKjQrOFQTQ1fmBYhmW6o8Jkjc7iDJRTBIo5kgJD5yMEYA3srCg7VFKwiVJkmRCc5ohGOKhsYMn/XBLdo5taZjlb9YAlGWRimqbCsoY7HFAXLa5I1HPRxMMsQDHFkWtRNniqT9UEeNjcE7RUlrCJ4R2CSJuqlKHWvJXjAUNcITYkenuBRB84TbeepcqTj3zZyFJzgYQdHnqfgI0ddUwS6GqWpsKWhjq9cV0vBAEMN2znq+EBfIWT+pClYw5xsTlJU6GeIBsjGmmANTzJZiIYpgrM0Oa8ZMjd7NP87jxhqGOhJlnQtjuQpB+8aEE00wZFznSJPyHxgH3HkPOsJFvYk8zqCHzTs1BYOa4J3PFU+UVRZxlHDM4YavlNUuMoRveiZA2d7grMNc2g+RbSCEKzmgYsUmWmazFJyoiOZ4KnyhKOGRzWJa0+moyV4TVHDzn51Awtqaphfk/lRQ08FX1iiqxTB/kLwd0VynKfEvI6cd4XMV5bMhZ7gZUWVzYQ6Nm2BYzxJbw3bGthEUUMfgbGeorae6DxHtJoZ6alhZ0+ytiVoK1R4z5PTrOECT/SugseEOlb1MMNR4VRNcJy+V1Hg9ONClSZFZjdHlc6W6FBLdJja2MC5hhpu0DBYEY1TFGwiFAxRRCsYkiM9JRb0JNMVkW6CZYT/2EiTGWmo8k+h4FhDNE7BvppoTSFnmCV5xZKzvcCdDo7VVPnIU+I+Rc68juApC90MwcFCsJ5hDqxgScYKreruyQwTqrzoqDCmhWi4IbhB0Yrt3RGa6GfDv52rKXWhh28dyZaWUvcZeMTBaZoSGyiCtRU5J8iviioHaErs7Jkj61syVzTTgOcUOQ8buFBTYWdL5g3T4qlpe0+wvD63heAXRfCCIed9RbCsp2CiI7raUOYOTU13N8PNHvpaGvayo4a3LLT1lDrVEPT2zLUlheB1R+ZTRfKWJ+dcocLJfi11vyJ51lLqJ0WD7tRwryezjiV5W28uJO9qykzX8JDe2lHl/9oyBwa2UMfOngpXCixvKdXTk3wrsKmiVYdZIqsoWEERjbcUNDuiaQomGoIbFdEHmsyWnuR+IeriKDVLnlawlyNHKwKlSU631PKep8J4Q+ayjkSLKYLhalNHlYvttb6fHm0p6OApsZ4l2VfdqZkjuysy6ysKLlckf1KUutCTs39bmCgEyyoasIWlVaMF7mgmWtBT8Kol5xpH9IGllo8cJdopcvZ2sImlDmMIbtDk3KIpeNiS08lQw11NFPTwVFlPP6pJ2gvRfI7gQUfmNAtf6Gs0wQxDsKGlVBdF8rCa3jzdwMaGHOsItrZk7hAyOzpK9VS06j5F49b0VNGOOfKs3lDToMsMBe9ZWtHFEgxTJLs7qrygKZjUnmCYoeAqeU6jqWuLJup4WghOdvCYJnrSkSzoyRkm5M2StQwVltPkfCAk58tET/CSg+8MUecmotMEnhBKfWBIZsg2ihruMJQaoIm+tkTLKEqspMh00w95gvFCQRtDwTT1gVDDSEVdlwqZfxoQRbK0g+tbiBZxzKlpnpypejdDwTaeOvorMk/IJE10h9CqRe28hhLbe0pMsdSwv4ZbhKivo2BjDWfL8UKJgeavwlwb5KlwhyE4u4XkGE2ytZCznKLCDZZq42VzT8HLCrpruFbIfOIINmh/qCdZ1ZBc65kLHR1Bkyf5zn6pN3SvGKIlFNGplhrO9QSXanLOMQTLCa0YJCRrCZm/CZmrLTm7WzCK4GJDiWUdFeYx1LCFg3NMd0XmCuF3Y5rITLDUsYS9zoHVzwnJoYpSTQoObyEzr4cFBNqYTopoaU/wkyLZ2lPhX/5Y95ulxGTV7KjhWrOZgl8MyUUafjYraNjNU1N3IWcjT5WzWqjwtoarHSUObGYO3GCJZpsBlnJGPd6ZYLyl1GdCA2625IwwJDP8GUKymbzuyPlZlvTUsaUh5zFDhRWFzPKKZLAlWdcQbObgF9tOqOsmB1dqcqYJmWstFbZRRI9poolmqiLnU0POvxScpah2iSL5UJNzgScY5+AuIbpO0YD3NCW+dLMszFSdFCWGqG6eVq2uYVNDdICGD6W7EPRWZEY5gpsE9rUkS3mijzzJnm6UpUFXG1hCUeVoS5WfNcFpblELL2qqrCvMvRfd45oalvKU2tiQ6ePJOVMRXase9iTtLJztPxJKLWpo2CRDcJwn2sWSLKIO1WQWNTCvpVUvOZhgSC40JD0dOctaSqzkCRbXsKlb11Oip6PCJ0IwSJM31j3akRxlP7Rwn6aGaUL0qiLnJkvB3xWZ2+Q1TfCwpQH3G0o92UzmX4o/oJNQMMSQc547wVHhdk+VCw01DFYEnTxzZKAm74QmeNNR1w6WzEhNK15VJzuCdxQ53dRUDws5KvwgBMOEgpcVNe0hZI6RXT1Jd0cyj5nsaEAHgVmGaJIlWdsc5Ui2ElrRR6jrRAttNMEAIWrTDFubkZaok7/AkzfIwfuWVq0jHzuCK4QabtLUMVPB3kJ0oyHTSVFlqMALilJf2Rf8k5aaHtMfayocLBS8L89oKoxpJvnAkDPa0qp5DAUTHKWmCcnthlou8iCKaFFLHWcINd1nyIwXqrSxMNmSs6KmoL2QrKuWtlQ5V0120xQ5vRyZS1rgFkWwhiOwiuQbR0OOVhQM9iS3tiXp4RawRPMp5tDletOOBL95MpM01dZTBM9pkn5qF010rIeHFcFZhmSGpYpTsI6nwhqe5C9ynhlpp5ophuRb6WcJFldkVnVEwwxVfrVkvnWUuNLCg5bgboFHPDlDPDmnK7hUrWiIbjadDclujlZcaokOFup4Ri1kacV6jmrrK1hN9bGwpKEBQ4Q6DvIUXOmo6U5LqQM6EPyiKNjVkPnJkDPNEaxhiFay5ExW1NXVUGqcpYYdPcGiCq7z/TSlbhL4pplWXKd7NZO5QQFrefhRQW/NHOsqcIglc4UhWklR8K0QzbAw08CBDnpbgqXdeD/QUsM4RZXDFBW6WJKe/mFPdH0LtBgiq57wFLzlyQzz82qYx5D5WJP5yVJDW01BfyHnS6HKO/reZqId1WGa4Hkh2kWodJ8i6KoIPlAj2hPt76CzXsVR6koPRzWTfKqIentatYpQw2me4AA3y1Kind3SwoOKZDcFXTwl9tWU6mfgRk9d71sKtlNwrjnYw5tC5n5LdKiGry3JKNlHEd3oaMCFHrazBPMp/uNJ+V7IudcSbeOIdjUEdwl0VHCOZo5t6YluEuaC9mQeMgSfOyKnYGFHcIeQ84yQWbuJYJpZw5CzglDH7gKnWqqM9ZTaXcN0TeYhR84eQtJT76JJ1lREe7WnnvsMmRc9FQ7SBBM9mV3lCUdmHk/S2RAMt0QjFNFqQpWjDPQ01DXWUdDBkXziKPjGEP3VP+zIWU2t7im41FOloyWzn/L6dkUy3VLDaZ6appgDLHPjJEsyvJngWEPUyVBiAaHCTEXwrLvSEbV1e1gKJniicWorC1MUrVjB3uDhJE/wgSOzk1DXpk0k73qCM8xw2UvD5kJmDUfOomqMpWCkJRlvKXGmoeBm18USjVIk04SClxTB6YrgLAPLWYK9HLUt5cmc0vYES8GnTeRc6skZbQkWdxRsIcyBRzx1DbTk9FbU0caTPOgJHhJKnOGIVhQqvKmo0llRw9sabrZkDtdg3PqaKi9oatjY8B+G371paMg6+mZFNNtQ04mWBq3rYLOmtWWQp8KJnpy9DdFensyjdqZ+yY40VJlH8wcdLzC8PZnvHMFUTZUrDTkLyQaGus5X5LzpYAf3i+e/ZlhqGqWhh6Ou6xTR9Z6oi5AZZtp7Mj2EEm8oSpxiYZCHU/1fbGdNNNRRoZMhmilEb2gqHOEJDtXkHK/JnG6IrvbPCwV3NhONVdS1thBMs1T4QOBcTWa2IzhMk2nW5Kyn9tXUtpv9RsG2msxk+ZsQzRQacJncpgke0+T8y5Fzj8BiGo7XlJjaTIlpQs7KFjpqGnKuoyEPeIKnFMkZHvopgh81ySxNFWvJWcKRs70j2FOT012IllEEO1n4pD1513Yg2ssQPOThOkvyrqHUdEXOSEsihmBbTbKX1kLBPWqWkLOqJbjB3GBIZmoa8qWl4CG/iZ7oiA72ZL7TJNeZUY7kFQftDcHHluBzRbCegzMtrRjVQpX2lgoPKKLJAkcbMl01XK2p7yhL8pCBbQ3BN2avJgKvttcrWDK3CiUOVxQ8ZP+pqXKyIxnmBymCg5vJjNfkPK4+c8cIfK8ocVt7kmfd/I5SR1hKvCzUtb+lhgc00ZaO6CyhIQP1Uv4yIZjload72PXX0OIJvnFU+0Zf6MhsJwTfW0r0UwQfW4LNLZl5HK261JCZ4qnBaAreVAS3WrjV0LBnNDUNNDToCEeFfwgcb4gOEqLRhirWkexrCEYKVV711DLYEE1XBEsp5tpTGjorkomKYF9FDXv7fR3BGwbettSxnyL53MBPjsxDZjMh+VUW9NRxq1DhVk+FSxQcaGjV9Pawv6eGByw5qzoy7xk4RsOShqjJwWKe/1pEEfzkobeD/dQJmpqedcyBTy2sr4nGNRH0c0SPWTLrqAc0OQcb/gemKgqucQT7ySWKCn2EUotoCvpZct7RO2sy/QW0IWcXd7pQRQyZVwT2USRO87uhjioTLKV2brpMUcMQRbKH/N2T+UlTpaMls6cmc6CCNy3JdYYSUzzJQ4oSD3oKLncULOiJvjBEC2oqnCJkJluCYy2ZQ5so9YYlZ1VLlQU1mXEW1jZERwj/MUSRc24TdexlqLKfQBtDTScJUV8FszXBEY5ktpD5Ur9hYB4Nb1iikw3JoYpkKX+RodRKFt53MMuRnKSpY31PwYaGaILh3wxJGz9TkTPEETxoCWZrgvOlmyMzxFEwVJE5xZKzvyJ4WxEc16Gd4Xe3Weq4XH2jKRikqOkGQ87hQnC7wBmGYLAnesX3M+S87eFATauuN+Qcrh7xIxXJbUIdMw3JGE3ylCWzrieaqCn4zhGM19TQ3z1oH1AX+pWEqIc7wNGAkULBo/ZxRaV9NNyh4Br3rCHZzbzmSfawBL0dNRwpW1kK9mxPXR9povcdrGSZK9c2k0xwFGzjuniCtRSZCZ6ccZ7gaktmgAOtKbG/JnOkJrjcQTdFMsxRQ2cLY3WTIrlCw1eWKn8R6pvt4GFDso3QoL4a3nLk3G6JrtME3dSenpx7PNFTmga0EaJTLQ061sEeQoWXhSo9LTXsaSjoJQRXeZLtDclbCrYzfzHHeaKjHCVOUkQHO3JeEepr56mhiyaYYKjjNU+Fed1wS5VlhWSqI/hYUdDOkaxiKehoyOnrCV5yBHtbWFqTHCCwtpDcYolesVR5yUzTZBb3RNMd0d6WP+SvhuBmRcGxnuQzT95IC285cr41cLGQ6aJJhmi4TMGempxeimBRQw1tFKV+8jd6KuzoSTqqDxzRtpZkurvKEHxlqXKRIjjfUNNXQsNOsRScoWFLT+YeRZVD3GRN0MdQcKqQjHDMrdGGVu3iYJpQx3WGUvfbmxwFfR20WBq0oYY7LMFhhgYtr8jpaEnaOzjawWWaTP8mMr0t/EPDPoqcnxTBI5o58L7uoWnMrpoqPwgVrlAUWE+V+TQl9rawoyP6QGAlQw2TPRX+YSkxyBC8Z6jhHkXBgQL7WII3DVFnRfCrBfxewv9D6xsyjys4VkhWb9pUU627JllV0YDNHMku/ldNMMXDEo4aFnAkk4U6frNEU4XgZUPmEKHUl44KrzmYamjAbh0JFvGnaTLPu1s9jPCwjFpYiN7z1DTOk/nc07CfDFzmCf7i+bfNHXhDtLeBXzTBT5rkMvWOIxpl4EMh2LGJBu2syDnAEx2naEhHDWMMzPZEhygyS1mS5RTJr5ZkoKbEUoYqr2kqdDUE8ztK7OaIntJkFrIECwv8LJTaVx5XJE86go8dFeZ3FN3rjabCAYpoYEeC9zzJVULBbmZhDyd7ko09ydpNZ3nm2Kee4FPPXHnYEF1nqOFEC08LUVcDvYXkJHW8gTaKCk9YGOeIJhqiE4ToPEepdp7IWFjdwnWaufGMwJJCMtUTTBBK9BGCOy2tGGrJTHIwyEOzp6aPzNMOtlZkDvcEWpP5SVNhfkvDxhmSazTJXYrM9U1E0xwFVwqZQwzJxw6+kGGGUj2FglGGmnb1/G51udRSMNlTw6GGnCcUwVcOpmsqTHa06o72sw1RL02p9z0VbnMLOaIX3QKaYKSCFQzBKEUNHTSc48k53RH9wxGMtpQa5KjjW0W0n6XCCCG4yxNNdhQ4R4l1Ff+2sSd6UFHiIEOyqqFgT01mEUMD+joy75jPhOA+oVVLm309FR4yVOlp4RhLiScNmSmaYF5Pw0STrOIoWMSR2UkRXOMp+M4SHW8o8Zoi6OZgjKOaFar8zZDzkWzvKOjkKBjmCXby8JahhjXULY4KlzgKLvAwxVGhvyd4zxB1d9T0piazmKLCVZY5sKiD0y2ZSYrkUEPUbIk+dlQ4SJHTR50k1DPaUWIdTZW9NJwnJMOECgd7ou/MnppMJ02O1VT4Wsh85MnZzcFTngpXGKo84qmwgKbCL/orR/SzJ2crA+t6Mp94KvxJUeIbT3CQu1uIdlQEOzlKfS3UMcrTiFmOuroocrZrT2AcmamOKg8YomeEKm/rlT2sociMaybaUlFhuqHCM2qIJ+rg4EcDFymiDSxzaHdPcpE62pD5kyM5SBMoA1PaUtfIthS85ig1VPiPPYXgYEMNk4Qq7TXBgo7oT57gPUdwgCHzhIVFPFU6OYJzHAX9m5oNrVjeE61miDrqQ4VSa1oiURTsKHC0IfjNwU2WzK6eqK8jWln4g15TVBnqmDteCJ501PGAocJhhqjZdtBEB6lnhLreFJKxmlKbeGrqLiSThVIbCdGzloasa6lpMQXHCME2boLpJgT7yWaemu6wBONbqGNVRS0PKIL7LckbjmQtR7K8I5qtqel+T/ChJTNIKLjdUMNIRyvOEko9YYl2cwQveBikCNawJKcLBbc7+JM92mysNvd/Fqp8a0k6CNEe7cnZrxlW0wQXaXjaktnRwNOGZKYiONwS7a1JVheq3WgJHlQUGKHKmp4KAxXR/ULURcNgoa4zhKSLpZR3kxRRb0NmD0OFn+UCS7CzI1nbP6+o4x47QZE5xRCt3ZagnYcvmpYQktXdk5YKXTzBC57kKEe0VVuiSYqapssMS3C9p2CKkHOg8B8Pa8p5atrIw3qezIWanMGa5HRDNF6RM9wcacl0N+Q8Z8hsIkSnaIIdHRUOEebAPy1zbCkhM062FCJtif7PU+UtoVXzWKqM1PxXO8cfdruhFQ/a6x3JKYagvVDhQEtNiyiiSQ7OsuRsZUku0CRNDs4Sog6KKjsZgk2bYJqijgsEenoKeniinRXBn/U3lgpPdyDZynQx8IiioMnCep5Ky8mjGs6Wty0l1hUQTcNWswS3WRp2kCNZwJG8omG8JphPUaFbC8lEfabwP7VtM9yoaNCAjpR41VNhrD9LkbN722v0CoZMByFzhaW+MyzRYEWFDQwN2M4/JiT76PuljT3VU/A36eaIThb+R9oZGOAJ9tewkgGvqOMNRWYjT/Cwu99Q8LqDE4TgbLWxJ1jaDDAERsFOFrobgjUsBScaguXU8kKm2RL19tRypSHnHNlHiIZqgufs4opgQdVdwxBNNFBR6kVFqb8ogimOzB6a6HTzrlDHEpYaxjiiA4TMQobkDg2vejjfwJGWmnbVFAw3H3hq2NyQfG7hz4aC+w3BbwbesG0swYayvpAs6++Ri1Vfzx93mFChvyN5xVHTS+0p9aqCAxyZ6ZacZyw5+7uuQkFPR9DDk9NOiE7X1PCYJVjVUqq7JlrHwWALF5nfHNGjApdpqgzx5OwilDhCiDYTgnc9waGW4BdLNNUQvOtpzDOWHDH8D7TR/A/85KljEQu3NREc4Pl/6B1Hhc8Umb5CsKMmGC9EPcxoT2amwHNCmeOEnOPbklnMkbOgIvO5UMOpQrS9UGVdt6iH/fURjhI/WOpaW9OKLYRod6HCUEdOX000wpDZQ6hwg6LgZfOqo1RfT/CrJzjekXOGhpc1VW71ZLbXyyp+93ILbC1kPtIEYx0FIx1VDrLoVzXRKRYWk809yYlC9ImcrinxtabKnzRJk3lAU1OLEN1j2zrYzr2myHRXJFf4h4QKT1qSTzTB5+ZNTzTRkAxX8FcLV2uS8eoQQ2aAkFzvCM72sJIcJET3WPjRk5wi32uSS9rfZajpWEvj9hW42F4o5NytSXYy8IKHay10VYdrcl4SkqscrXpMwyGOgtkajheSxdQqmpxP1L3t4R5PqasFnrQEjytq6qgp9Y09Qx9o4S1FzhUCn1kyHSzBWLemoSGvOqLNhZyBjmCaAUYpMgt4Ck7wBBMMwWKWgjsUwTaGVsxWC1mYoKiyqqeGKYqonSIRQ3KIkHO0pmAxTdBHkbOvfllfr+AA+7gnc50huVKYK393FOyg7rbPO/izI7hE4CnHHHnJ0ogNPRUGeUpsrZZTBJcrovUcJe51BPsr6GkJdhCCsZ6aTtMEb2pqWkqeVtDXE/QVggsU/Nl86d9RMF3DxvZTA58agu810RWawCiSzzXBeU3MMW9oyJUedvNEvQyNu1f10BSMddR1vaLCYpYa/mGocLSiYDcLbQz8aMn5iyF4xBNMs1P0QEOV7o5gaWGuzSeLue4tt3ro7y4Tgm4G/mopdZgl6q0o6KzJWE3mMksNr3r+a6CbT8g5wZNzT9O7fi/zpaOmnz3BRoqos+tv9zMbdpxsqDBOEewtJLt7cg5wtKKbvldpSzRRCD43VFheCI7yZLppggMVBS/KMAdHODJvOwq2NQSbKKKPLdFWQs7Fqo+mpl01JXYRgq8dnGLhTiFzqmWsUMdpllZdbKlyvSdYxhI9YghOtxR8LgSLWHK62mGGVoxzBE8LNWzqH9CUesQzFy5RQzTc56mhi6fgXEWwpKfE5Z7M05ZgZUPmo6auiv8YKzDYwWBLMErIbKHJvOwIrvEdhOBcQ9JdU1NHQ7CXn2XIDFBKU2WAgcX9UAUzDXWd5alwuyJ41Z9rjKLCL4aCp4WarhPm2rH+SaHUYE001JDZ2ZAzXPjdMpZWvC9wmqIB2lLhQ01D5jO06hghWMndbM7yRJMsoCj1vYbnFQVrW9jak3OlEJ3s/96+p33dEPRV5GxiqaGjIthUU6FFEZyqCa5qJrpBdzSw95IUnOPIrCUUjRZQFrbw5PR0R1qiYx3cb6nrWUMrBmmiBQxVHtTew5ICP/ip6g4hed/Akob/32wvBHsIOX83cI8hGeNeNPCIkPmXe8fPKx84OMSRM1MTdXSwjCZ4S30jVGhvqTRak/OVhgGazHuOCud5onEO1lJr6ecVyaOK6H7zqlBlIaHE0oroCgfvGJIdPcmfLNGLjpz7hZwZQpUbFME0A1cIJa7VNORkgfsMBatbKgwwJM9bSvQXeNOvbIjelg6WWvo5kvbKaJJNHexkKNHL9xRyFlH8Ti2riB5wVPhUk7nGkJnoCe428LR/wRGdYIlmWebCyxou1rCk4g/ShugBDX0V0ZQWkh0dOVsagkM0yV6OoLd5ye+pRlsCr0n+KiQrGuq5yJDzrTAXHtLUMduTDBVKrSm3eHL+6ijxhFDX9Z5gVU/wliHYTMiMFpKLNMEywu80wd3meoFmt6VbRMPenhrOc6DVe4pgXU8DnnHakLOIIrlF4FZPIw6R+zxBP0dyq6OOZ4Q5sLKCcz084ok+VsMMyQhNZmmBgX5xIXOEJTmi7VsGTvMTNdHHhpzdbE8Du2oKxgvBqQKdDDnTFOylCFaxR1syz2iqrOI/FEpNc3C6f11/7+ASS6l2inq2ciTrCCzgyemrCL5SVPjQkdPZUmGy2c9Sw9FtR1sS30RmsKPCS4rkIC/2U0MduwucYolGaPjKEyhzmiPYXagyWbYz8LWBDdzRimAXzxx4z8K9hpzlhLq+NiQ97HuKorMUfK/OVvC2JfiHUPCQI/q7J2gjK+tTDNxkCc4TMssqCs4TGtLVwQihyoAWgj9bosU80XGW6Ac9TJGziaUh5+hnFcHOnlaM1iRn29NaqGENTTTSUHCH2tWTeV0osUhH6psuVLjRUmGWhm6OZEshGeNowABHcJ2Bpy2ZszRcKkRXd2QuKVEeXnbfaEq825FguqfgfE2whlChSRMdron+LATTPQ2Z369t4B9C5gs/ylzv+CMmepIDPclFQl13W0rspPd1JOcbghGOEutqCv5qacURQl3dDKyvyJlqKXGPgcM9FfawJAMVmdcspcYKOZc4GjDYkFlK05olNMHyHn4zFNykyOxt99RkHlfwmiHo60l2EKI+mhreEKp080Tbug08BVPcgoqC5zWt+NLDTZ7oNSF51N1qie7Va3uCCwyZbkINf/NED6jzOsBdZjFN8oqG3wxVunqCSYYKf3EdhJyf9YWGf7tRU2oH3VHgPr1fe5J9hOgHd7xQ0y7qBwXr23aGErP0cm64JVjZwsOGqL+mhNgZmhJLW2oY4UhedsyBgzrCKrq7BmcpNVhR6jBPq64Vgi+kn6XE68pp8J5/+0wRHGOpsKenQn9DZntPzjRLZpDAdD2fnSgkG9tmIXnUwQ6WVighs7Yi2MxQ0N3CqYaCXkJ0oyOztMDJjmSSpcpvlrk0RMMOjmArQ04PRV1DO1FwhCVaUVPpKUM03JK5SxPsIWRu8/CGHi8UHChiqGFDTbSRJWeYUDDcH6vJWUxR4k1FXbMUwV6e4AJFXS8oMqsZKqzvYQ9DDQdZckY4aGsIhtlubbd2r3j4QBMoTamdPZk7O/Bf62lacZwneNjQoGcdVU7zJOd7ghsUHOkosagic6cnWc8+4gg285R6zZP5s1/LUbCKIznTwK36PkdwlOrl4U1LwfdCCa+IrvFkmgw1PCAUXKWo0sURXWcI2muKJlgyFzhynCY4RBOsqCjoI1R5zREco0n2Vt09BQtYSizgKNHfUmUrQ5UOCh51BFcLmY7umhYqXKQomOop8bUnWNNQcIiBcYaC6xzMNOS8JQQfeqKBmmglB+97ok/lfk3ygaHSyZaCRTzRxQo6GzLfa2jWBPepw+UmT7SQEJyiyRkhBLMVOfcoMjcK0eZChfUNzFAUzCsEN5vP/X1uP/n/aoMX+K+nw/Hjr/9xOo7j7Pju61tLcgvJpTWXNbfN5jLpi6VfCOviTktKlFusQixdEKWmEBUKNaIpjZRSSOXSgzaaKLdabrm1/9nZ+/f+vd/vz/v9+Xy+zZ7PRorYoZqyLrCwQdEAixxVOEXNNnjX2nUSRlkqGmWowk8lxR50JPy9Bo6qJXaXwNvREBvnThPEPrewryLhcAnj5WE15Fqi8W7R1sAuEu86S4ENikItFN4xkv9Af4nXSnUVcLiA9xzesFpivRRVeFKtsMRaKBhuSbjOELnAUtlSQUpXgdfB4Z1oSbnFEetbQ0IrAe+Y+pqnDcEJFj6S8LDZzZHwY4e3XONNlARraomNEt2bkvGsosA3ioyHm+6jCMbI59wqt4eeara28IzEmyPgoRaUOEDhTVdEJhmCoTWfC0p8aNkCp0oYqih2iqGi4yXeMkOsn4LdLLnmKfh/YogjNsPebeFGR4m9BJHLzB61XQ3BtpISfS2FugsK9FAtLWX1dCRcrCnUp44CNzuCowUZmxSRgYaE6Za0W2u/E7CVXCiI/UOR8aAm1+OSyE3mOUcwyc1zBBeoX1kiKy0Zfxck1Gsyulti11i83QTBF5Kg3pDQThFMVHiPSlK+0cSedng/VaS8bOZbtsBcTcZAR8JP5KeqQ1OYKAi20njdNNRpgnsU//K+JnaXJaGTomr7aYIphoRn9aeShJWKEq9LcozSF7QleEfDI5LYm5bgVkFkRwVDBCVu0DDIkGupo8TZBq+/pMQURYErJQmPKGKjNDkWOLx7Jd5QizdUweIaKrlP7SwJDhZvONjLkOsBBX9UpGxnydhXkfBLQ8IxgojQbLFnJf81JytSljclYYyEFyx0kVBvKWOFJmONpshGAcsduQY5giVNCV51eOdJYo/pLhbvM0uDHSevNKRcrKZIqnCtJeEsO95RoqcgGK4ocZcho1tTYtcZvH41pNQ7vA0WrhIfOSraIIntIAi+NXWCErdbkvrWwjRLrt0NKUdL6KSOscTOdMSOUtBHwL6OLA0vNSdynaWQEnCpIvKaIrJJEbvHkmuNhn6OjM8VkSGSqn1uYJCGHnq9I3aLhNME3t6GjIkO7xrNFumpyTNX/NrwX7CrIRiqqWijI9JO4d1iieykyfiposQIQ8YjjsjlBh6oHWbwRjgYJQn2NgSnNycmJAk3NiXhx44Sxykihxm8ybUwT1OVKySc7vi3OXVkdBJ4AyXBeksDXG0IhgtYY0lY5ahCD0ehborIk5aUWRJviMA7Xt5kyRjonrXENkm8yYqgs8VzgrJmClK20uMM3jRJ0FiQICQF9hdETlLQWRIb5ki6WDfWRPobvO6a4GP5mcOrNzDFELtTkONLh9dXE8xypEg7z8A9jkhrQ6Fhjlg/QVktJXxt4WXzT/03Q8IaQWSqIuEvloQ2mqC9Jfi7wRul4RX3pSPlzpoVlmCtI2jvKHCFhjcM3sN6lqF6HxnKelLjXWbwrpR4xzuCrTUZx2qq9oAh8p6ixCUGr78g8oyjRAtB5CZFwi80VerVpI0h+IeBxa6Zg6kWvpDHaioYYuEsRbDC3eOmC2JvGYLeioxGknL2UATNJN6hmtj1DlpLvDVmocYbrGCVJKOrg4X6DgddLA203BKMFngdJJFtFd7vJLm6KEpc5yjQrkk7M80SGe34X24nSex1Ra5Omgb71JKyg8SrU3i/kARKwWpH0kOGhKkObyfd0ZGjvyXlAkVZ4xRbYJ2irFMkFY1SwyWxr2oo4zlNiV+7zmaweFpT4kR3kaDAFW6xpSqzJay05FtYR4HmZhc9UxKbbfF2V8RG1MBmSaE+kmC6JnaRXK9gsiXhJHl/U0qM0WTcbyhwkYIvFGwjSbjfwhiJt8ZSQU+Bd5+marPMOkVkD0muxYLIfEuhh60x/J92itguihJSEMySVPQnTewnEm+620rTQEMsOfo4/kP/0ARvWjitlpSX7GxBgcMEsd3EEeYWvdytd+Saawi6aCIj1CkGb6Aj9rwhx16Cf3vAwFy5pyLhVonXzy51FDpdEblbkdJbUcEPDEFzQ8qNmhzzLTmmKWKbFCXeEuRabp6rxbvAtLF442QjQ+wEA9eL1xSR7Q0JXzlSHjJ4exq89yR0laScJ/FW6z4a73pFMEfDiRZvuvijIt86RaSFOl01riV2mD1UEvxGk/Geg5aWwGki1zgKPG9J2U8PEg8qYvMsZeytiTRXBMslCU8JSlxi8EabjwUldlDNLfzTUmCgxWsjqWCOHavYAqsknKFIO0yQ61VL5AVFxk6WhEaCAkdJgt9aSkzXlKNX2jEa79waYuc7gq0N3GDJGCBhoiTXUEPsdknCUE1CK0fwsiaylSF2uiDyO4XX3pFhNd7R4itFGc0k/ElBZwWvq+GC6szVeEoS/MZ+qylwpKNKv9Z469UOjqCjwlusicyTxG6VpNxcQ8IncoR4RhLbR+NdpGGmJWOcIzJGUuKPGpQg8rrG21dOMqQssJQ4RxH5jaUqnZuQ0F4Q+cjxLwPtpZbIAk3QTJHQWBE5S1BokoVtDd6lhqr9UpHSUxMcIYl9pojsb8h4SBOsMQcqvOWC2E8EVehqiJ1hrrAEbQxeK0NGZ0Gkq+guSRgniM23bIHVkqwx4hiHd7smaOyglyIyQuM978j4VS08J/A2G1KeMBRo4fBaSNhKUEZfQewVQ/C1I+MgfbEleEzCUw7mKXI0M3hd1EESVji8x5uQ41nxs1q4RMJCCXs7Iq9acpxn22oSDnQ/sJTxsCbHIYZiLyhY05TY0ZLIOQrGaSJDDN4t8pVaIrsqqFdEegtizc1iTew5Q4ayBDMUsQMkXocaYkc0hZua412siZ1rSXlR460zRJ5SlHGe5j801RLMlJTxtaOM3Q1pvxJ45zUlWFD7rsAbpfEm1JHxG0eh8w2R7QQVzBUw28FhFp5QZzq8t2rx2joqulYTWSuJdTYfWwqMFMcovFmSyJPNyLhE4E10pHzYjOC3huArRa571ZsGajQpQx38SBP5pyZB6lMU3khDnp0MBV51BE9o2E+TY5Ml2E8S7C0o6w1xvCZjf0HkVEHCzFoyNmqC+9wdcqN+Tp7jSDheE9ws8Y5V0NJCn2bk2tqSY4okdrEhx1iDN8cSudwepWmAGXKcJXK65H9to8jYQRH7SBF01ESUJdd0TayVInaWhLkOjlXE5irKGOnI6GSWGCJa482zBI9rCr0jyTVcEuzriC1vcr6mwFGSiqy5zMwxBH/TJHwjSPhL8+01kaaSUuMFKTcLEvaUePcrSmwn8DZrgikWb7CGPxkSjhQwrRk57tctmxLsb9sZvL9LSlyuSLlWkqOjwduo8b6Uv1DkmudIeFF2dHCgxVtk8dpIvHpBxhEOdhKk7OLIUSdJ+cSRY57B+0DgGUUlNfpthTfGkauzxrvTsUUaCVhlKeteTXCoJDCa2NOKhOmC4G1H8JBd4OBZReSRGkqcb/CO1PyLJTLB4j1q8JYaIutEjSLX8YKM+a6phdMsdLFUoV5RTm9JSkuDN8WcIon0NZMNZWh1q8C7SJEwV5HxrmnnTrf3KoJBlmCYI2ilSLlfEvlE4011NNgjgthzEua0oKK7JLE7HZHlEl60BLMVFewg4EWNt0ThrVNEVkkiTwpKXSWJzdRENgvKGq4IhjsiezgSFtsfCUq8qki5S1LRQeYQQ4nemmCkImWMw3tFUoUBZk4NOeZYEp4XRKTGa6wJjrWNHBVJR4m3FCnbuD6aak2WsMTh3SZImGCIPKNgsDpVwnsa70K31lCFJZYcwwSMFcQulGTsZuEaSdBXkPGZhu0FsdUO73RHjq8MPGGIfaGIbVTk6iuI3GFgucHrIQkmWSJdBd7BBu+uOryWAhY7+Lki9rK5wtEQzWwvtbqGhIMFwWRJsElsY4m9IIg9L6lCX0VklaPAYkfkZEGDnOWowlBJjtMUkcGK4Lg6EtoZInMUBVYLgn0UsdmCyCz7gIGHFfk+k1QwTh5We7A9x+IdJ6CvIkEagms0hR50eH9UnTQJ+2oiKyVlLFUE+8gBGu8MQ3CppUHesnjTHN4QB/UGPhCTHLFPHMFrCqa73gqObUJGa03wgbhHkrCfpEpzNLE7JDS25FMKhlhKKWKfCgqstLCPu1zBXy0J2ztwjtixBu8UTRn9LVtkmCN2iyFhtME70JHRQ1KVZXqKI/KNIKYMCYs1GUMEKbM1bKOI9LDXC7zbHS+bt+1MTWS9odA9DtrYtpbImQJ2VHh/lisEwaHqUk1kjKTAKknkBEXkbkdMGwq0dnhzLJF3NJH3JVwrqOB4Sca2hti75nmJN0WzxS6UxDYoEpxpa4htVlRjkYE7DZGzJVU72uC9IyhQL4i8YfGWSYLLNcHXloyz7QhNifmKSE9JgfGmuyLhc403Xm9vqcp6gXe3xuuv8F6VJNxkyTHEkHG2g0aKXL0MsXc1bGfgas2//dCONXiNLCX+5mB7eZIl1kHh7ajwpikyzlUUWOVOsjSQlsS+M0R+pPje/dzBXRZGO0rMtgQrLLG9VSu9n6CMXS3BhwYmSoIBhsjNBmZbgusE9BCPCP5triU4VhNbJfE+swSP27aayE8tuTpYYjtrYjMVGZdp2NpS1s6aBnKSHDsbKuplKbHM4a0wMFd/5/DmGyKrJSUaW4IBrqUhx0vyfzTBBLPIUcnZdrAkNsKR0sWRspumSns6Ch0v/qqIbBYUWKvPU/CFoyrDJGwSNFhbA/MlzKqjrO80hRbpKx0Jewsi/STftwGSlKc1JZyAzx05dhLEdnfQvhZOqiHWWEAHC7+30FuRcZUgaO5gpaIK+xsiHRUsqaPElTV40xQZQ107Q9BZE1nryDVGU9ZSQ47bmhBpLcYpUt7S+xuK/FiT8qKjwXYw5ypS2iuCv7q1gtgjhuBuB8LCFY5cUuCNtsQOFcT+4Ih9JX+k8Ea6v0iCIRZOtCT0Et00JW5UeC85Cg0ScK0k411HcG1zKtre3SeITBRk7WfwDhEvaYLTHP9le0m8By0JDwn4TlLW/aJOvGHxdjYUes+ScZigCkYQdNdEOhkiezgShqkx8ueKjI8lDfK2oNiOFvrZH1hS+tk7NV7nOmLHicGWEgubkXKdwdtZknCLJXaCpkrjZBtLZFsDP9CdxWsSr05Sxl6CMmoFbCOgryX40uDtamB7SVmXW4Ihlgpmq+00tBKUUa83WbjLUNkzDmY7cow1JDygyPGlhgGKYKz4vcV7QBNbJIgM11TUqZaMdwTeSguH6rOaw1JRKzaaGyxVm2EJ/uCIrVWUcZUkcp2grMsEjK+DMwS59jQk3Kd6SEq1d0S6uVmO4Bc1lDXTUcHjluCXEq+1OlBDj1pi9zgiXxnKuE0SqTXwhqbETW6RggMEnGl/q49UT2iCzgJvRwVXS2K/d6+ZkyUl7jawSVLit46EwxVljDZwoSQ20sDBihztHfk2yA8NVZghiXwrYHQdfKAOtzsayjhY9bY0yE2CWEeJ9xfzO423xhL5syS2TFJofO2pboHob0nY4GiAgRrvGQEDa/FWSsoaaYl0syRsEt3kWoH3B01shCXhTUWe9w3Bt44SC9QCh3eShQctwbaK2ApLroGCMlZrYqvlY3qYhM0aXpFkPOuoqJ3Dm6fxXrGwVF9gCWZagjPqznfkuMKQ8DPTQRO8ZqG1hPGKEm9IgpGW4DZDgTNriTxvFiq+Lz+0cKfp4wj6OCK9JSnzNSn9LFU7UhKZZMnYwcJ8s8yRsECScK4j5UOB95HFO0CzhY4xJxuCix0lDlEUeMdS6EZBkTsUkZ4K74dugyTXS7aNgL8aqjDfkCE0ZbwkCXpaWCKhl8P7VD5jxykivSyxyZrYERbe168LYu9ZYh86IkscgVLE7tWPKmJv11CgoyJltMEbrohtVAQfO4ImltiHEroYEs7RxAarVpY8AwXMcMReFOTYWe5iiLRQxJ5Q8DtJ8LQhWOhIeFESPGsILhbNDRljNbHzNRlTFbk2S3L0NOS6V1KFJYKUbSTcIIhM0wQ/s2TM0SRMNcQmSap3jCH4yhJZKSkwyRHpYYgsFeQ4U7xoCB7VVOExhXepo9ABBsYbvGWKXPME3lyH95YioZ0gssQRWWbI+FaSMkXijZXwgiTlYdPdkNLaETxlyDVIwqeaEus0aTcYcg0RVOkpR3CSJqIddK+90JCxzsDVloyrFd5ZAr4TBKfaWa6boEA7C7s6EpYaeFPjveooY72mjIccLHJ9HUwVlDhKkmutJDJBwnp1rvulJZggKDRfbXAkvC/4l3ozQOG9a8lxjx0i7nV4jSXc7vhe3OwIxjgSHjdEhhsif9YkPGlus3iLFDnWOFhtCZbJg0UbQcIaR67JjthoCyMEZRwhiXWyxO5QxI6w5NhT4U1WsJvDO60J34fW9hwzwlKij6ZAW9ne4L0s8C6XeBMEkd/LQy1VucBRot6QMlbivaBhoBgjqGiCJNhsqVp/S2SsG6DIONCR0dXhvWbJ+MRRZJkkuEjgDXJjFQW6SSL7GXK8Z2CZg7cVsbWGoKmEpzQ5elpiy8Ryg7dMkLLUEauzeO86CuwlSOlgYLojZWeJ9xM3S1PWfEfKl5ISLQ0MEKR8YOB2QfCxJBjrKPCN4f9MkaSsqoVXJBmP7EpFZ9UQfOoOFwSzBN4MQ8LsGrymlipcJQhmy0GaQjPqCHaXRwuCZwRbqK2Fg9wlClZqYicrIgMdZfxTQ0c7TBIbrChxmuzoKG8XRaSrIhhiyNFJkrC7oIAWMEOQa5aBekPCRknCo4IKPrYkvCDI8aYmY7WFtprgekcJZ3oLIqssCSMtFbQTJKwXYy3BY5oCh2iKPCpJOE+zRdpYgi6O2KmOAgvVCYaU4ySRek1sgyFhJ403QFHiVEmJHwtybO1gs8Hr5+BETQX3War0qZngYGgtVZtoqd6vFSk/UwdZElYqyjrF4HXUeFspIi9IGKf4j92pKGAdCYMVsbcV3kRF0N+R8LUd5PCsIGWoxDtBkCI0nKofdJQxT+LtZflvuc8Q3CjwWkq8KwUpHzkK/NmSsclCL0nseQdj5FRH5CNHSgtLiW80Of5HU9Hhlsga9bnBq3fEVltKfO5IaSTmGjjc4J0otcP7QsJUSQM8pEj5/wCuUuC2DWz8AAAAAElFTkSuQmCC");
+}
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/ayu-dark.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/ayu-dark.css
new file mode 100644
index 0000000000..13656b94bb
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/ayu-dark.css
@@ -0,0 +1,44 @@
+/* Based on https://github.com/dempfi/ayu */
+
+.cm-s-ayu-dark.CodeMirror { background: #0a0e14; color: #b3b1ad; }
+.cm-s-ayu-dark div.CodeMirror-selected { background: #273747; }
+.cm-s-ayu-dark .CodeMirror-line::selection, .cm-s-ayu-dark .CodeMirror-line > span::selection, .cm-s-ayu-dark .CodeMirror-line > span > span::selection { background: rgba(39, 55, 71, 99); }
+.cm-s-ayu-dark .CodeMirror-line::-moz-selection, .cm-s-ayu-dark .CodeMirror-line > span::-moz-selection, .cm-s-ayu-dark .CodeMirror-line > span > span::-moz-selection { background: rgba(39, 55, 71, 99); }
+.cm-s-ayu-dark .CodeMirror-gutters { background: #0a0e14; border-right: 0px; }
+.cm-s-ayu-dark .CodeMirror-guttermarker { color: white; }
+.cm-s-ayu-dark .CodeMirror-guttermarker-subtle { color: #3d424d; }
+.cm-s-ayu-dark .CodeMirror-linenumber { color: #3d424d; }
+.cm-s-ayu-dark .CodeMirror-cursor { border-left: 1px solid #e6b450; }
+.cm-s-ayu-dark.cm-fat-cursor .CodeMirror-cursor { background-color: #a2a8a175 !important; }
+.cm-s-ayu-dark .cm-animate-fat-cursor { background-color: #a2a8a175 !important; }
+
+.cm-s-ayu-dark span.cm-comment { color: #626a73; }
+.cm-s-ayu-dark span.cm-atom { color: #ae81ff; }
+.cm-s-ayu-dark span.cm-number { color: #e6b450; }
+
+.cm-s-ayu-dark span.cm-comment.cm-attribute { color: #ffb454; }
+.cm-s-ayu-dark span.cm-comment.cm-def { color: rgba(57, 186, 230, 80); }
+.cm-s-ayu-dark span.cm-comment.cm-tag { color: #39bae6; }
+.cm-s-ayu-dark span.cm-comment.cm-type { color: #5998a6; }
+
+.cm-s-ayu-dark span.cm-property, .cm-s-ayu-dark span.cm-attribute { color: #ffb454; }
+.cm-s-ayu-dark span.cm-keyword { color: #ff8f40; }
+.cm-s-ayu-dark span.cm-builtin { color: #e6b450; }
+.cm-s-ayu-dark span.cm-string { color: #c2d94c; }
+
+.cm-s-ayu-dark span.cm-variable { color: #b3b1ad; }
+.cm-s-ayu-dark span.cm-variable-2 { color: #f07178; }
+.cm-s-ayu-dark span.cm-variable-3 { color: #39bae6; }
+.cm-s-ayu-dark span.cm-type { color: #ff8f40; }
+.cm-s-ayu-dark span.cm-def { color: #ffee99; }
+.cm-s-ayu-dark span.cm-bracket { color: #f8f8f2; }
+.cm-s-ayu-dark span.cm-tag { color: rgba(57, 186, 230, 80); }
+.cm-s-ayu-dark span.cm-header { color: #c2d94c; }
+.cm-s-ayu-dark span.cm-link { color: #39bae6; }
+.cm-s-ayu-dark span.cm-error { color: #ff3333; }
+
+.cm-s-ayu-dark .CodeMirror-activeline-background { background: #01060e; }
+.cm-s-ayu-dark .CodeMirror-matchingbracket {
+ text-decoration: underline;
+ color: white !important;
+}
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/ayu-mirage.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/ayu-mirage.css
new file mode 100644
index 0000000000..19403cefb5
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/ayu-mirage.css
@@ -0,0 +1,45 @@
+/* Based on https://github.com/dempfi/ayu */
+
+.cm-s-ayu-mirage.CodeMirror { background: #1f2430; color: #cbccc6; }
+.cm-s-ayu-mirage div.CodeMirror-selected { background: #34455a; }
+.cm-s-ayu-mirage .CodeMirror-line::selection, .cm-s-ayu-mirage .CodeMirror-line > span::selection, .cm-s-ayu-mirage .CodeMirror-line > span > span::selection { background: #34455a; }
+.cm-s-ayu-mirage .CodeMirror-line::-moz-selection, .cm-s-ayu-mirage .CodeMirror-line > span::-moz-selection, .cm-s-ayu-mirage .CodeMirror-line > span > span::-moz-selection { background: rgba(25, 30, 42, 99); }
+.cm-s-ayu-mirage .CodeMirror-gutters { background: #1f2430; border-right: 0px; }
+.cm-s-ayu-mirage .CodeMirror-guttermarker { color: white; }
+.cm-s-ayu-mirage .CodeMirror-guttermarker-subtle { color: rgba(112, 122, 140, 66); }
+.cm-s-ayu-mirage .CodeMirror-linenumber { color: rgba(61, 66, 77, 99); }
+.cm-s-ayu-mirage .CodeMirror-cursor { border-left: 1px solid #ffcc66; }
+.cm-s-ayu-mirage.cm-fat-cursor .CodeMirror-cursor {background-color: #a2a8a175 !important;}
+.cm-s-ayu-mirage .cm-animate-fat-cursor { background-color: #a2a8a175 !important; }
+
+.cm-s-ayu-mirage span.cm-comment { color: #5c6773; font-style:italic; }
+.cm-s-ayu-mirage span.cm-atom { color: #ae81ff; }
+.cm-s-ayu-mirage span.cm-number { color: #ffcc66; }
+
+.cm-s-ayu-mirage span.cm-comment.cm-attribute { color: #ffd580; }
+.cm-s-ayu-mirage span.cm-comment.cm-def { color: #d4bfff; }
+.cm-s-ayu-mirage span.cm-comment.cm-tag { color: #5ccfe6; }
+.cm-s-ayu-mirage span.cm-comment.cm-type { color: #5998a6; }
+
+.cm-s-ayu-mirage span.cm-property { color: #f29e74; }
+.cm-s-ayu-mirage span.cm-attribute { color: #ffd580; }
+.cm-s-ayu-mirage span.cm-keyword { color: #ffa759; }
+.cm-s-ayu-mirage span.cm-builtin { color: #ffcc66; }
+.cm-s-ayu-mirage span.cm-string { color: #bae67e; }
+
+.cm-s-ayu-mirage span.cm-variable { color: #cbccc6; }
+.cm-s-ayu-mirage span.cm-variable-2 { color: #f28779; }
+.cm-s-ayu-mirage span.cm-variable-3 { color: #5ccfe6; }
+.cm-s-ayu-mirage span.cm-type { color: #ffa759; }
+.cm-s-ayu-mirage span.cm-def { color: #ffd580; }
+.cm-s-ayu-mirage span.cm-bracket { color: rgba(92, 207, 230, 80); }
+.cm-s-ayu-mirage span.cm-tag { color: #5ccfe6; }
+.cm-s-ayu-mirage span.cm-header { color: #bae67e; }
+.cm-s-ayu-mirage span.cm-link { color: #5ccfe6; }
+.cm-s-ayu-mirage span.cm-error { color: #ff3333; }
+
+.cm-s-ayu-mirage .CodeMirror-activeline-background { background: #191e2a; }
+.cm-s-ayu-mirage .CodeMirror-matchingbracket {
+ text-decoration: underline;
+ color: white !important;
+}
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/base16-dark.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/base16-dark.css
new file mode 100644
index 0000000000..b3c31aba20
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/base16-dark.css
@@ -0,0 +1,40 @@
+/*
+
+ Name: Base16 Default Dark
+ Author: Chris Kempson (http://chriskempson.com)
+
+ CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror)
+ Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16)
+
+*/
+
+.cm-s-base16-dark.CodeMirror { background: #151515; color: #e0e0e0; }
+.cm-s-base16-dark div.CodeMirror-selected { background: #303030; }
+.cm-s-base16-dark .CodeMirror-line::selection, .cm-s-base16-dark .CodeMirror-line > span::selection, .cm-s-base16-dark .CodeMirror-line > span > span::selection { background: rgba(48, 48, 48, .99); }
+.cm-s-base16-dark .CodeMirror-line::-moz-selection, .cm-s-base16-dark .CodeMirror-line > span::-moz-selection, .cm-s-base16-dark .CodeMirror-line > span > span::-moz-selection { background: rgba(48, 48, 48, .99); }
+.cm-s-base16-dark .CodeMirror-gutters { background: #151515; border-right: 0px; }
+.cm-s-base16-dark .CodeMirror-guttermarker { color: #ac4142; }
+.cm-s-base16-dark .CodeMirror-guttermarker-subtle { color: #505050; }
+.cm-s-base16-dark .CodeMirror-linenumber { color: #505050; }
+.cm-s-base16-dark .CodeMirror-cursor { border-left: 1px solid #b0b0b0; }
+.cm-s-base16-dark.cm-fat-cursor .CodeMirror-cursor { background-color: #8e8d8875 !important; }
+.cm-s-base16-dark .cm-animate-fat-cursor { background-color: #8e8d8875 !important; }
+
+.cm-s-base16-dark span.cm-comment { color: #8f5536; }
+.cm-s-base16-dark span.cm-atom { color: #aa759f; }
+.cm-s-base16-dark span.cm-number { color: #aa759f; }
+
+.cm-s-base16-dark span.cm-property, .cm-s-base16-dark span.cm-attribute { color: #90a959; }
+.cm-s-base16-dark span.cm-keyword { color: #ac4142; }
+.cm-s-base16-dark span.cm-string { color: #f4bf75; }
+
+.cm-s-base16-dark span.cm-variable { color: #90a959; }
+.cm-s-base16-dark span.cm-variable-2 { color: #6a9fb5; }
+.cm-s-base16-dark span.cm-def { color: #d28445; }
+.cm-s-base16-dark span.cm-bracket { color: #e0e0e0; }
+.cm-s-base16-dark span.cm-tag { color: #ac4142; }
+.cm-s-base16-dark span.cm-link { color: #aa759f; }
+.cm-s-base16-dark span.cm-error { background: #ac4142; color: #b0b0b0; }
+
+.cm-s-base16-dark .CodeMirror-activeline-background { background: #202020; }
+.cm-s-base16-dark .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; }
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/base16-light.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/base16-light.css
new file mode 100644
index 0000000000..1d5f582f6a
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/base16-light.css
@@ -0,0 +1,38 @@
+/*
+
+ Name: Base16 Default Light
+ Author: Chris Kempson (http://chriskempson.com)
+
+ CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror)
+ Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16)
+
+*/
+
+.cm-s-base16-light.CodeMirror { background: #f5f5f5; color: #202020; }
+.cm-s-base16-light div.CodeMirror-selected { background: #e0e0e0; }
+.cm-s-base16-light .CodeMirror-line::selection, .cm-s-base16-light .CodeMirror-line > span::selection, .cm-s-base16-light .CodeMirror-line > span > span::selection { background: #e0e0e0; }
+.cm-s-base16-light .CodeMirror-line::-moz-selection, .cm-s-base16-light .CodeMirror-line > span::-moz-selection, .cm-s-base16-light .CodeMirror-line > span > span::-moz-selection { background: #e0e0e0; }
+.cm-s-base16-light .CodeMirror-gutters { background: #f5f5f5; border-right: 0px; }
+.cm-s-base16-light .CodeMirror-guttermarker { color: #ac4142; }
+.cm-s-base16-light .CodeMirror-guttermarker-subtle { color: #b0b0b0; }
+.cm-s-base16-light .CodeMirror-linenumber { color: #b0b0b0; }
+.cm-s-base16-light .CodeMirror-cursor { border-left: 1px solid #505050; }
+
+.cm-s-base16-light span.cm-comment { color: #8f5536; }
+.cm-s-base16-light span.cm-atom { color: #aa759f; }
+.cm-s-base16-light span.cm-number { color: #aa759f; }
+
+.cm-s-base16-light span.cm-property, .cm-s-base16-light span.cm-attribute { color: #90a959; }
+.cm-s-base16-light span.cm-keyword { color: #ac4142; }
+.cm-s-base16-light span.cm-string { color: #f4bf75; }
+
+.cm-s-base16-light span.cm-variable { color: #90a959; }
+.cm-s-base16-light span.cm-variable-2 { color: #6a9fb5; }
+.cm-s-base16-light span.cm-def { color: #d28445; }
+.cm-s-base16-light span.cm-bracket { color: #202020; }
+.cm-s-base16-light span.cm-tag { color: #ac4142; }
+.cm-s-base16-light span.cm-link { color: #aa759f; }
+.cm-s-base16-light span.cm-error { background: #ac4142; color: #505050; }
+
+.cm-s-base16-light .CodeMirror-activeline-background { background: #DDDCDC; }
+.cm-s-base16-light .CodeMirror-matchingbracket { color: #f5f5f5 !important; background-color: #6A9FB5 !important}
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/bespin.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/bespin.css
new file mode 100644
index 0000000000..60913ba938
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/bespin.css
@@ -0,0 +1,34 @@
+/*
+
+ Name: Bespin
+ Author: Mozilla / Jan T. Sott
+
+ CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror)
+ Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16)
+
+*/
+
+.cm-s-bespin.CodeMirror {background: #28211c; color: #9d9b97;}
+.cm-s-bespin div.CodeMirror-selected {background: #36312e !important;}
+.cm-s-bespin .CodeMirror-gutters {background: #28211c; border-right: 0px;}
+.cm-s-bespin .CodeMirror-linenumber {color: #666666;}
+.cm-s-bespin .CodeMirror-cursor {border-left: 1px solid #797977 !important;}
+
+.cm-s-bespin span.cm-comment {color: #937121;}
+.cm-s-bespin span.cm-atom {color: #9b859d;}
+.cm-s-bespin span.cm-number {color: #9b859d;}
+
+.cm-s-bespin span.cm-property, .cm-s-bespin span.cm-attribute {color: #54be0d;}
+.cm-s-bespin span.cm-keyword {color: #cf6a4c;}
+.cm-s-bespin span.cm-string {color: #f9ee98;}
+
+.cm-s-bespin span.cm-variable {color: #54be0d;}
+.cm-s-bespin span.cm-variable-2 {color: #5ea6ea;}
+.cm-s-bespin span.cm-def {color: #cf7d34;}
+.cm-s-bespin span.cm-error {background: #cf6a4c; color: #797977;}
+.cm-s-bespin span.cm-bracket {color: #9d9b97;}
+.cm-s-bespin span.cm-tag {color: #cf6a4c;}
+.cm-s-bespin span.cm-link {color: #9b859d;}
+
+.cm-s-bespin .CodeMirror-matchingbracket { text-decoration: underline; color: white !important;}
+.cm-s-bespin .CodeMirror-activeline-background { background: #404040; }
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/blackboard.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/blackboard.css
new file mode 100644
index 0000000000..b6eaedb180
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/blackboard.css
@@ -0,0 +1,32 @@
+/* Port of TextMate's Blackboard theme */
+
+.cm-s-blackboard.CodeMirror { background: #0C1021; color: #F8F8F8; }
+.cm-s-blackboard div.CodeMirror-selected { background: #253B76; }
+.cm-s-blackboard .CodeMirror-line::selection, .cm-s-blackboard .CodeMirror-line > span::selection, .cm-s-blackboard .CodeMirror-line > span > span::selection { background: rgba(37, 59, 118, .99); }
+.cm-s-blackboard .CodeMirror-line::-moz-selection, .cm-s-blackboard .CodeMirror-line > span::-moz-selection, .cm-s-blackboard .CodeMirror-line > span > span::-moz-selection { background: rgba(37, 59, 118, .99); }
+.cm-s-blackboard .CodeMirror-gutters { background: #0C1021; border-right: 0; }
+.cm-s-blackboard .CodeMirror-guttermarker { color: #FBDE2D; }
+.cm-s-blackboard .CodeMirror-guttermarker-subtle { color: #888; }
+.cm-s-blackboard .CodeMirror-linenumber { color: #888; }
+.cm-s-blackboard .CodeMirror-cursor { border-left: 1px solid #A7A7A7; }
+
+.cm-s-blackboard .cm-keyword { color: #FBDE2D; }
+.cm-s-blackboard .cm-atom { color: #D8FA3C; }
+.cm-s-blackboard .cm-number { color: #D8FA3C; }
+.cm-s-blackboard .cm-def { color: #8DA6CE; }
+.cm-s-blackboard .cm-variable { color: #FF6400; }
+.cm-s-blackboard .cm-operator { color: #FBDE2D; }
+.cm-s-blackboard .cm-comment { color: #AEAEAE; }
+.cm-s-blackboard .cm-string { color: #61CE3C; }
+.cm-s-blackboard .cm-string-2 { color: #61CE3C; }
+.cm-s-blackboard .cm-meta { color: #D8FA3C; }
+.cm-s-blackboard .cm-builtin { color: #8DA6CE; }
+.cm-s-blackboard .cm-tag { color: #8DA6CE; }
+.cm-s-blackboard .cm-attribute { color: #8DA6CE; }
+.cm-s-blackboard .cm-header { color: #FF6400; }
+.cm-s-blackboard .cm-hr { color: #AEAEAE; }
+.cm-s-blackboard .cm-link { color: #8DA6CE; }
+.cm-s-blackboard .cm-error { background: #9D1E15; color: #F8F8F8; }
+
+.cm-s-blackboard .CodeMirror-activeline-background { background: #3C3636; }
+.cm-s-blackboard .CodeMirror-matchingbracket { outline:1px solid grey;color:white !important; }
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/cobalt.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/cobalt.css
new file mode 100644
index 0000000000..bbbda3b543
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/cobalt.css
@@ -0,0 +1,25 @@
+.cm-s-cobalt.CodeMirror { background: #002240; color: white; }
+.cm-s-cobalt div.CodeMirror-selected { background: #b36539; }
+.cm-s-cobalt .CodeMirror-line::selection, .cm-s-cobalt .CodeMirror-line > span::selection, .cm-s-cobalt .CodeMirror-line > span > span::selection { background: rgba(179, 101, 57, .99); }
+.cm-s-cobalt .CodeMirror-line::-moz-selection, .cm-s-cobalt .CodeMirror-line > span::-moz-selection, .cm-s-cobalt .CodeMirror-line > span > span::-moz-selection { background: rgba(179, 101, 57, .99); }
+.cm-s-cobalt .CodeMirror-gutters { background: #002240; border-right: 1px solid #aaa; }
+.cm-s-cobalt .CodeMirror-guttermarker { color: #ffee80; }
+.cm-s-cobalt .CodeMirror-guttermarker-subtle { color: #d0d0d0; }
+.cm-s-cobalt .CodeMirror-linenumber { color: #d0d0d0; }
+.cm-s-cobalt .CodeMirror-cursor { border-left: 1px solid white; }
+
+.cm-s-cobalt span.cm-comment { color: #08f; }
+.cm-s-cobalt span.cm-atom { color: #845dc4; }
+.cm-s-cobalt span.cm-number, .cm-s-cobalt span.cm-attribute { color: #ff80e1; }
+.cm-s-cobalt span.cm-keyword { color: #ffee80; }
+.cm-s-cobalt span.cm-string { color: #3ad900; }
+.cm-s-cobalt span.cm-meta { color: #ff9d00; }
+.cm-s-cobalt span.cm-variable-2, .cm-s-cobalt span.cm-tag { color: #9effff; }
+.cm-s-cobalt span.cm-variable-3, .cm-s-cobalt span.cm-def, .cm-s-cobalt .cm-type { color: white; }
+.cm-s-cobalt span.cm-bracket { color: #d8d8d8; }
+.cm-s-cobalt span.cm-builtin, .cm-s-cobalt span.cm-special { color: #ff9e59; }
+.cm-s-cobalt span.cm-link { color: #845dc4; }
+.cm-s-cobalt span.cm-error { color: #9d1e15; }
+
+.cm-s-cobalt .CodeMirror-activeline-background { background: #002D57; }
+.cm-s-cobalt .CodeMirror-matchingbracket { outline:1px solid grey;color:white !important; }
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/colorforth.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/colorforth.css
new file mode 100644
index 0000000000..19095e41d9
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/colorforth.css
@@ -0,0 +1,33 @@
+.cm-s-colorforth.CodeMirror { background: #000000; color: #f8f8f8; }
+.cm-s-colorforth .CodeMirror-gutters { background: #0a001f; border-right: 1px solid #aaa; }
+.cm-s-colorforth .CodeMirror-guttermarker { color: #FFBD40; }
+.cm-s-colorforth .CodeMirror-guttermarker-subtle { color: #78846f; }
+.cm-s-colorforth .CodeMirror-linenumber { color: #bababa; }
+.cm-s-colorforth .CodeMirror-cursor { border-left: 1px solid white; }
+
+.cm-s-colorforth span.cm-comment { color: #ededed; }
+.cm-s-colorforth span.cm-def { color: #ff1c1c; font-weight:bold; }
+.cm-s-colorforth span.cm-keyword { color: #ffd900; }
+.cm-s-colorforth span.cm-builtin { color: #00d95a; }
+.cm-s-colorforth span.cm-variable { color: #73ff00; }
+.cm-s-colorforth span.cm-string { color: #007bff; }
+.cm-s-colorforth span.cm-number { color: #00c4ff; }
+.cm-s-colorforth span.cm-atom { color: #606060; }
+
+.cm-s-colorforth span.cm-variable-2 { color: #EEE; }
+.cm-s-colorforth span.cm-variable-3, .cm-s-colorforth span.cm-type { color: #DDD; }
+.cm-s-colorforth span.cm-property {}
+.cm-s-colorforth span.cm-operator {}
+
+.cm-s-colorforth span.cm-meta { color: yellow; }
+.cm-s-colorforth span.cm-qualifier { color: #FFF700; }
+.cm-s-colorforth span.cm-bracket { color: #cc7; }
+.cm-s-colorforth span.cm-tag { color: #FFBD40; }
+.cm-s-colorforth span.cm-attribute { color: #FFF700; }
+.cm-s-colorforth span.cm-error { color: #f00; }
+
+.cm-s-colorforth div.CodeMirror-selected { background: #333d53; }
+
+.cm-s-colorforth span.cm-compilation { background: rgba(255, 255, 255, 0.12); }
+
+.cm-s-colorforth .CodeMirror-activeline-background { background: #253540; }
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/darcula.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/darcula.css
new file mode 100644
index 0000000000..2ec81a3557
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/darcula.css
@@ -0,0 +1,53 @@
+/**
+ Name: IntelliJ IDEA darcula theme
+ From IntelliJ IDEA by JetBrains
+ */
+
+.cm-s-darcula { font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, serif;}
+.cm-s-darcula.CodeMirror { background: #2B2B2B; color: #A9B7C6; }
+
+.cm-s-darcula span.cm-meta { color: #BBB529; }
+.cm-s-darcula span.cm-number { color: #6897BB; }
+.cm-s-darcula span.cm-keyword { color: #CC7832; line-height: 1em; font-weight: bold; }
+.cm-s-darcula span.cm-def { color: #A9B7C6; font-style: italic; }
+.cm-s-darcula span.cm-variable { color: #A9B7C6; }
+.cm-s-darcula span.cm-variable-2 { color: #A9B7C6; }
+.cm-s-darcula span.cm-variable-3 { color: #9876AA; }
+.cm-s-darcula span.cm-type { color: #AABBCC; font-weight: bold; }
+.cm-s-darcula span.cm-property { color: #FFC66D; }
+.cm-s-darcula span.cm-operator { color: #A9B7C6; }
+.cm-s-darcula span.cm-string { color: #6A8759; }
+.cm-s-darcula span.cm-string-2 { color: #6A8759; }
+.cm-s-darcula span.cm-comment { color: #61A151; font-style: italic; }
+.cm-s-darcula span.cm-link { color: #CC7832; }
+.cm-s-darcula span.cm-atom { color: #CC7832; }
+.cm-s-darcula span.cm-error { color: #BC3F3C; }
+.cm-s-darcula span.cm-tag { color: #629755; font-weight: bold; font-style: italic; text-decoration: underline; }
+.cm-s-darcula span.cm-attribute { color: #6897bb; }
+.cm-s-darcula span.cm-qualifier { color: #6A8759; }
+.cm-s-darcula span.cm-bracket { color: #A9B7C6; }
+.cm-s-darcula span.cm-builtin { color: #FF9E59; }
+.cm-s-darcula span.cm-special { color: #FF9E59; }
+.cm-s-darcula span.cm-matchhighlight { color: #FFFFFF; background-color: rgba(50, 89, 48, .7); font-weight: normal;}
+.cm-s-darcula span.cm-searching { color: #FFFFFF; background-color: rgba(61, 115, 59, .7); font-weight: normal;}
+
+.cm-s-darcula .CodeMirror-cursor { border-left: 1px solid #A9B7C6; }
+.cm-s-darcula .CodeMirror-activeline-background { background: #323232; }
+.cm-s-darcula .CodeMirror-gutters { background: #313335; border-right: 1px solid #313335; }
+.cm-s-darcula .CodeMirror-guttermarker { color: #FFEE80; }
+.cm-s-darcula .CodeMirror-guttermarker-subtle { color: #D0D0D0; }
+.cm-s-darcula .CodeMirrir-linenumber { color: #606366; }
+.cm-s-darcula .CodeMirror-matchingbracket { background-color: #3B514D; color: #FFEF28 !important; font-weight: bold; }
+
+.cm-s-darcula div.CodeMirror-selected { background: #214283; }
+
+.CodeMirror-hints.darcula {
+ font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;
+ color: #9C9E9E;
+ background-color: #3B3E3F !important;
+}
+
+.CodeMirror-hints.darcula .CodeMirror-hint-active {
+ background-color: #494D4E !important;
+ color: #9C9E9E !important;
+}
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/dracula.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/dracula.css
new file mode 100644
index 0000000000..253133efe7
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/dracula.css
@@ -0,0 +1,40 @@
+/*
+
+ Name: dracula
+ Author: Michael Kaminsky (http://github.com/mkaminsky11)
+
+ Original dracula color scheme by Zeno Rocha (https://github.com/zenorocha/dracula-theme)
+
+*/
+
+
+.cm-s-dracula.CodeMirror, .cm-s-dracula .CodeMirror-gutters {
+ background-color: #282a36 !important;
+ color: #f8f8f2 !important;
+ border: none;
+}
+.cm-s-dracula .CodeMirror-gutters { color: #282a36; }
+.cm-s-dracula .CodeMirror-cursor { border-left: solid thin #f8f8f0; }
+.cm-s-dracula .CodeMirror-linenumber { color: #6D8A88; }
+.cm-s-dracula .CodeMirror-selected { background: rgba(255, 255, 255, 0.10); }
+.cm-s-dracula .CodeMirror-line::selection, .cm-s-dracula .CodeMirror-line > span::selection, .cm-s-dracula .CodeMirror-line > span > span::selection { background: rgba(255, 255, 255, 0.10); }
+.cm-s-dracula .CodeMirror-line::-moz-selection, .cm-s-dracula .CodeMirror-line > span::-moz-selection, .cm-s-dracula .CodeMirror-line > span > span::-moz-selection { background: rgba(255, 255, 255, 0.10); }
+.cm-s-dracula span.cm-comment { color: #6272a4; }
+.cm-s-dracula span.cm-string, .cm-s-dracula span.cm-string-2 { color: #f1fa8c; }
+.cm-s-dracula span.cm-number { color: #bd93f9; }
+.cm-s-dracula span.cm-variable { color: #50fa7b; }
+.cm-s-dracula span.cm-variable-2 { color: white; }
+.cm-s-dracula span.cm-def { color: #50fa7b; }
+.cm-s-dracula span.cm-operator { color: #ff79c6; }
+.cm-s-dracula span.cm-keyword { color: #ff79c6; }
+.cm-s-dracula span.cm-atom { color: #bd93f9; }
+.cm-s-dracula span.cm-meta { color: #f8f8f2; }
+.cm-s-dracula span.cm-tag { color: #ff79c6; }
+.cm-s-dracula span.cm-attribute { color: #50fa7b; }
+.cm-s-dracula span.cm-qualifier { color: #50fa7b; }
+.cm-s-dracula span.cm-property { color: #66d9ef; }
+.cm-s-dracula span.cm-builtin { color: #50fa7b; }
+.cm-s-dracula span.cm-variable-3, .cm-s-dracula span.cm-type { color: #ffb86c; }
+
+.cm-s-dracula .CodeMirror-activeline-background { background: rgba(255,255,255,0.1); }
+.cm-s-dracula .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; }
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/duotone-dark.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/duotone-dark.css
new file mode 100644
index 0000000000..88fdc76c8e
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/duotone-dark.css
@@ -0,0 +1,35 @@
+/*
+Name: DuoTone-Dark
+Author: by Bram de Haan, adapted from DuoTone themes by Simurai (http://simurai.com/projects/2016/01/01/duotone-themes)
+
+CodeMirror template by Jan T. Sott (https://github.com/idleberg), adapted by Bram de Haan (https://github.com/atelierbram/)
+*/
+
+.cm-s-duotone-dark.CodeMirror { background: #2a2734; color: #6c6783; }
+.cm-s-duotone-dark div.CodeMirror-selected { background: #545167!important; }
+.cm-s-duotone-dark .CodeMirror-gutters { background: #2a2734; border-right: 0px; }
+.cm-s-duotone-dark .CodeMirror-linenumber { color: #545167; }
+
+/* begin cursor */
+.cm-s-duotone-dark .CodeMirror-cursor { border-left: 1px solid #ffad5c; /* border-left: 1px solid #ffad5c80; */ border-right: .5em solid #ffad5c; /* border-right: .5em solid #ffad5c80; */ opacity: .5; }
+.cm-s-duotone-dark .CodeMirror-activeline-background { background: #363342; /* background: #36334280; */ opacity: .5;}
+.cm-s-duotone-dark .cm-fat-cursor .CodeMirror-cursor { background: #ffad5c; /* background: #ffad5c80; */ opacity: .5;}
+/* end cursor */
+
+.cm-s-duotone-dark span.cm-atom, .cm-s-duotone-dark span.cm-number, .cm-s-duotone-dark span.cm-keyword, .cm-s-duotone-dark span.cm-variable, .cm-s-duotone-dark span.cm-attribute, .cm-s-duotone-dark span.cm-quote, .cm-s-duotone-dark span.cm-hr, .cm-s-duotone-dark span.cm-link { color: #ffcc99; }
+
+.cm-s-duotone-dark span.cm-property { color: #9a86fd; }
+.cm-s-duotone-dark span.cm-punctuation, .cm-s-duotone-dark span.cm-unit, .cm-s-duotone-dark span.cm-negative { color: #e09142; }
+.cm-s-duotone-dark span.cm-string { color: #ffb870; }
+.cm-s-duotone-dark span.cm-operator { color: #ffad5c; }
+.cm-s-duotone-dark span.cm-positive { color: #6a51e6; }
+
+.cm-s-duotone-dark span.cm-variable-2, .cm-s-duotone-dark span.cm-variable-3, .cm-s-duotone-dark span.cm-type, .cm-s-duotone-dark span.cm-string-2, .cm-s-duotone-dark span.cm-url { color: #7a63ee; }
+.cm-s-duotone-dark span.cm-def, .cm-s-duotone-dark span.cm-tag, .cm-s-duotone-dark span.cm-builtin, .cm-s-duotone-dark span.cm-qualifier, .cm-s-duotone-dark span.cm-header, .cm-s-duotone-dark span.cm-em { color: #eeebff; }
+.cm-s-duotone-dark span.cm-bracket, .cm-s-duotone-dark span.cm-comment { color: #6c6783; }
+
+/* using #f00 red for errors, don't think any of the colorscheme variables will stand out enough, ... maybe by giving it a background-color ... */
+.cm-s-duotone-dark span.cm-error, .cm-s-duotone-dark span.cm-invalidchar { color: #f00; }
+
+.cm-s-duotone-dark span.cm-header { font-weight: normal; }
+.cm-s-duotone-dark .CodeMirror-matchingbracket { text-decoration: underline; color: #eeebff !important; }
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/duotone-light.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/duotone-light.css
new file mode 100644
index 0000000000..d99480f7c4
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/duotone-light.css
@@ -0,0 +1,36 @@
+/*
+Name: DuoTone-Light
+Author: by Bram de Haan, adapted from DuoTone themes by Simurai (http://simurai.com/projects/2016/01/01/duotone-themes)
+
+CodeMirror template by Jan T. Sott (https://github.com/idleberg), adapted by Bram de Haan (https://github.com/atelierbram/)
+*/
+
+.cm-s-duotone-light.CodeMirror { background: #faf8f5; color: #b29762; }
+.cm-s-duotone-light div.CodeMirror-selected { background: #e3dcce !important; }
+.cm-s-duotone-light .CodeMirror-gutters { background: #faf8f5; border-right: 0px; }
+.cm-s-duotone-light .CodeMirror-linenumber { color: #cdc4b1; }
+
+/* begin cursor */
+.cm-s-duotone-light .CodeMirror-cursor { border-left: 1px solid #93abdc; /* border-left: 1px solid #93abdc80; */ border-right: .5em solid #93abdc; /* border-right: .5em solid #93abdc80; */ opacity: .5; }
+.cm-s-duotone-light .CodeMirror-activeline-background { background: #e3dcce; /* background: #e3dcce80; */ opacity: .5; }
+.cm-s-duotone-light .cm-fat-cursor .CodeMirror-cursor { background: #93abdc; /* #93abdc80; */ opacity: .5; }
+/* end cursor */
+
+.cm-s-duotone-light span.cm-atom, .cm-s-duotone-light span.cm-number, .cm-s-duotone-light span.cm-keyword, .cm-s-duotone-light span.cm-variable, .cm-s-duotone-light span.cm-attribute, .cm-s-duotone-light span.cm-quote, .cm-s-duotone-light-light span.cm-hr, .cm-s-duotone-light-light span.cm-link { color: #063289; }
+
+.cm-s-duotone-light span.cm-property { color: #b29762; }
+.cm-s-duotone-light span.cm-punctuation, .cm-s-duotone-light span.cm-unit, .cm-s-duotone-light span.cm-negative { color: #063289; }
+.cm-s-duotone-light span.cm-string, .cm-s-duotone-light span.cm-operator { color: #1659df; }
+.cm-s-duotone-light span.cm-positive { color: #896724; }
+
+.cm-s-duotone-light span.cm-variable-2, .cm-s-duotone-light span.cm-variable-3, .cm-s-duotone-light span.cm-type, .cm-s-duotone-light span.cm-string-2, .cm-s-duotone-light span.cm-url { color: #896724; }
+.cm-s-duotone-light span.cm-def, .cm-s-duotone-light span.cm-tag, .cm-s-duotone-light span.cm-builtin, .cm-s-duotone-light span.cm-qualifier, .cm-s-duotone-light span.cm-header, .cm-s-duotone-light span.cm-em { color: #2d2006; }
+.cm-s-duotone-light span.cm-bracket, .cm-s-duotone-light span.cm-comment { color: #b6ad9a; }
+
+/* using #f00 red for errors, don't think any of the colorscheme variables will stand out enough, ... maybe by giving it a background-color ... */
+/* .cm-s-duotone-light span.cm-error { background: #896724; color: #728fcb; } */
+.cm-s-duotone-light span.cm-error, .cm-s-duotone-light span.cm-invalidchar { color: #f00; }
+
+.cm-s-duotone-light span.cm-header { font-weight: normal; }
+.cm-s-duotone-light .CodeMirror-matchingbracket { text-decoration: underline; color: #faf8f5 !important; }
+
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/eclipse.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/eclipse.css
new file mode 100644
index 0000000000..800d603f6d
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/eclipse.css
@@ -0,0 +1,23 @@
+.cm-s-eclipse span.cm-meta { color: #FF1717; }
+.cm-s-eclipse span.cm-keyword { line-height: 1em; font-weight: bold; color: #7F0055; }
+.cm-s-eclipse span.cm-atom { color: #219; }
+.cm-s-eclipse span.cm-number { color: #164; }
+.cm-s-eclipse span.cm-def { color: #00f; }
+.cm-s-eclipse span.cm-variable { color: black; }
+.cm-s-eclipse span.cm-variable-2 { color: #0000C0; }
+.cm-s-eclipse span.cm-variable-3, .cm-s-eclipse span.cm-type { color: #0000C0; }
+.cm-s-eclipse span.cm-property { color: black; }
+.cm-s-eclipse span.cm-operator { color: black; }
+.cm-s-eclipse span.cm-comment { color: #3F7F5F; }
+.cm-s-eclipse span.cm-string { color: #2A00FF; }
+.cm-s-eclipse span.cm-string-2 { color: #f50; }
+.cm-s-eclipse span.cm-qualifier { color: #555; }
+.cm-s-eclipse span.cm-builtin { color: #30a; }
+.cm-s-eclipse span.cm-bracket { color: #cc7; }
+.cm-s-eclipse span.cm-tag { color: #170; }
+.cm-s-eclipse span.cm-attribute { color: #00c; }
+.cm-s-eclipse span.cm-link { color: #219; }
+.cm-s-eclipse span.cm-error { color: #f00; }
+
+.cm-s-eclipse .CodeMirror-activeline-background { background: #e8f2ff; }
+.cm-s-eclipse .CodeMirror-matchingbracket { outline:1px solid grey; color:black !important; }
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/elegant.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/elegant.css
new file mode 100644
index 0000000000..45b3ea655e
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/elegant.css
@@ -0,0 +1,13 @@
+.cm-s-elegant span.cm-number, .cm-s-elegant span.cm-string, .cm-s-elegant span.cm-atom { color: #762; }
+.cm-s-elegant span.cm-comment { color: #262; font-style: italic; line-height: 1em; }
+.cm-s-elegant span.cm-meta { color: #555; font-style: italic; line-height: 1em; }
+.cm-s-elegant span.cm-variable { color: black; }
+.cm-s-elegant span.cm-variable-2 { color: #b11; }
+.cm-s-elegant span.cm-qualifier { color: #555; }
+.cm-s-elegant span.cm-keyword { color: #730; }
+.cm-s-elegant span.cm-builtin { color: #30a; }
+.cm-s-elegant span.cm-link { color: #762; }
+.cm-s-elegant span.cm-error { background-color: #fdd; }
+
+.cm-s-elegant .CodeMirror-activeline-background { background: #e8f2ff; }
+.cm-s-elegant .CodeMirror-matchingbracket { outline:1px solid grey; color:black !important; }
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/erlang-dark.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/erlang-dark.css
new file mode 100644
index 0000000000..8c8a4171a6
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/erlang-dark.css
@@ -0,0 +1,34 @@
+.cm-s-erlang-dark.CodeMirror { background: #002240; color: white; }
+.cm-s-erlang-dark div.CodeMirror-selected { background: #b36539; }
+.cm-s-erlang-dark .CodeMirror-line::selection, .cm-s-erlang-dark .CodeMirror-line > span::selection, .cm-s-erlang-dark .CodeMirror-line > span > span::selection { background: rgba(179, 101, 57, .99); }
+.cm-s-erlang-dark .CodeMirror-line::-moz-selection, .cm-s-erlang-dark .CodeMirror-line > span::-moz-selection, .cm-s-erlang-dark .CodeMirror-line > span > span::-moz-selection { background: rgba(179, 101, 57, .99); }
+.cm-s-erlang-dark .CodeMirror-gutters { background: #002240; border-right: 1px solid #aaa; }
+.cm-s-erlang-dark .CodeMirror-guttermarker { color: white; }
+.cm-s-erlang-dark .CodeMirror-guttermarker-subtle { color: #d0d0d0; }
+.cm-s-erlang-dark .CodeMirror-linenumber { color: #d0d0d0; }
+.cm-s-erlang-dark .CodeMirror-cursor { border-left: 1px solid white; }
+
+.cm-s-erlang-dark span.cm-quote { color: #ccc; }
+.cm-s-erlang-dark span.cm-atom { color: #f133f1; }
+.cm-s-erlang-dark span.cm-attribute { color: #ff80e1; }
+.cm-s-erlang-dark span.cm-bracket { color: #ff9d00; }
+.cm-s-erlang-dark span.cm-builtin { color: #eaa; }
+.cm-s-erlang-dark span.cm-comment { color: #77f; }
+.cm-s-erlang-dark span.cm-def { color: #e7a; }
+.cm-s-erlang-dark span.cm-keyword { color: #ffee80; }
+.cm-s-erlang-dark span.cm-meta { color: #50fefe; }
+.cm-s-erlang-dark span.cm-number { color: #ffd0d0; }
+.cm-s-erlang-dark span.cm-operator { color: #d55; }
+.cm-s-erlang-dark span.cm-property { color: #ccc; }
+.cm-s-erlang-dark span.cm-qualifier { color: #ccc; }
+.cm-s-erlang-dark span.cm-special { color: #ffbbbb; }
+.cm-s-erlang-dark span.cm-string { color: #3ad900; }
+.cm-s-erlang-dark span.cm-string-2 { color: #ccc; }
+.cm-s-erlang-dark span.cm-tag { color: #9effff; }
+.cm-s-erlang-dark span.cm-variable { color: #50fe50; }
+.cm-s-erlang-dark span.cm-variable-2 { color: #e0e; }
+.cm-s-erlang-dark span.cm-variable-3, .cm-s-erlang-dark span.cm-type { color: #ccc; }
+.cm-s-erlang-dark span.cm-error { color: #9d1e15; }
+
+.cm-s-erlang-dark .CodeMirror-activeline-background { background: #013461; }
+.cm-s-erlang-dark .CodeMirror-matchingbracket { outline:1px solid grey; color:white !important; }
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/gruvbox-dark.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/gruvbox-dark.css
new file mode 100644
index 0000000000..d712dda08d
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/gruvbox-dark.css
@@ -0,0 +1,39 @@
+/*
+
+ Name: gruvbox-dark
+ Author: kRkk (https://github.com/krkk)
+
+ Original gruvbox color scheme by Pavel Pertsev (https://github.com/morhetz/gruvbox)
+
+*/
+
+.cm-s-gruvbox-dark.CodeMirror, .cm-s-gruvbox-dark .CodeMirror-gutters { background-color: #282828; color: #bdae93; }
+.cm-s-gruvbox-dark .CodeMirror-gutters {background: #282828; border-right: 0px;}
+.cm-s-gruvbox-dark .CodeMirror-linenumber {color: #7c6f64;}
+.cm-s-gruvbox-dark .CodeMirror-cursor { border-left: 1px solid #ebdbb2; }
+.cm-s-gruvbox-dark.cm-fat-cursor .CodeMirror-cursor { background-color: #8e8d8875 !important; }
+.cm-s-gruvbox-dark .cm-animate-fat-cursor { background-color: #8e8d8875 !important; }
+.cm-s-gruvbox-dark div.CodeMirror-selected { background: #928374; }
+.cm-s-gruvbox-dark span.cm-meta { color: #83a598; }
+
+.cm-s-gruvbox-dark span.cm-comment { color: #928374; }
+.cm-s-gruvbox-dark span.cm-number, span.cm-atom { color: #d3869b; }
+.cm-s-gruvbox-dark span.cm-keyword { color: #f84934; }
+
+.cm-s-gruvbox-dark span.cm-variable { color: #ebdbb2; }
+.cm-s-gruvbox-dark span.cm-variable-2 { color: #ebdbb2; }
+.cm-s-gruvbox-dark span.cm-variable-3, .cm-s-gruvbox-dark span.cm-type { color: #fabd2f; }
+.cm-s-gruvbox-dark span.cm-operator { color: #ebdbb2; }
+.cm-s-gruvbox-dark span.cm-callee { color: #ebdbb2; }
+.cm-s-gruvbox-dark span.cm-def { color: #ebdbb2; }
+.cm-s-gruvbox-dark span.cm-property { color: #ebdbb2; }
+.cm-s-gruvbox-dark span.cm-string { color: #b8bb26; }
+.cm-s-gruvbox-dark span.cm-string-2 { color: #8ec07c; }
+.cm-s-gruvbox-dark span.cm-qualifier { color: #8ec07c; }
+.cm-s-gruvbox-dark span.cm-attribute { color: #8ec07c; }
+
+.cm-s-gruvbox-dark .CodeMirror-activeline-background { background: #3c3836; }
+.cm-s-gruvbox-dark .CodeMirror-matchingbracket { background: #928374; color:#282828 !important; }
+
+.cm-s-gruvbox-dark span.cm-builtin { color: #fe8019; }
+.cm-s-gruvbox-dark span.cm-tag { color: #fe8019; }
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/hopscotch.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/hopscotch.css
new file mode 100644
index 0000000000..7d05431bdc
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/hopscotch.css
@@ -0,0 +1,34 @@
+/*
+
+ Name: Hopscotch
+ Author: Jan T. Sott
+
+ CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror)
+ Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16)
+
+*/
+
+.cm-s-hopscotch.CodeMirror {background: #322931; color: #d5d3d5;}
+.cm-s-hopscotch div.CodeMirror-selected {background: #433b42 !important;}
+.cm-s-hopscotch .CodeMirror-gutters {background: #322931; border-right: 0px;}
+.cm-s-hopscotch .CodeMirror-linenumber {color: #797379;}
+.cm-s-hopscotch .CodeMirror-cursor {border-left: 1px solid #989498 !important;}
+
+.cm-s-hopscotch span.cm-comment {color: #b33508;}
+.cm-s-hopscotch span.cm-atom {color: #c85e7c;}
+.cm-s-hopscotch span.cm-number {color: #c85e7c;}
+
+.cm-s-hopscotch span.cm-property, .cm-s-hopscotch span.cm-attribute {color: #8fc13e;}
+.cm-s-hopscotch span.cm-keyword {color: #dd464c;}
+.cm-s-hopscotch span.cm-string {color: #fdcc59;}
+
+.cm-s-hopscotch span.cm-variable {color: #8fc13e;}
+.cm-s-hopscotch span.cm-variable-2 {color: #1290bf;}
+.cm-s-hopscotch span.cm-def {color: #fd8b19;}
+.cm-s-hopscotch span.cm-error {background: #dd464c; color: #989498;}
+.cm-s-hopscotch span.cm-bracket {color: #d5d3d5;}
+.cm-s-hopscotch span.cm-tag {color: #dd464c;}
+.cm-s-hopscotch span.cm-link {color: #c85e7c;}
+
+.cm-s-hopscotch .CodeMirror-matchingbracket { text-decoration: underline; color: white !important;}
+.cm-s-hopscotch .CodeMirror-activeline-background { background: #302020; }
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/icecoder.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/icecoder.css
new file mode 100644
index 0000000000..5440fbe27c
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/icecoder.css
@@ -0,0 +1,43 @@
+/*
+ICEcoder default theme by Matt Pass, used in code editor available at https://icecoder.net
+*/
+
+.cm-s-icecoder { color: #666; background: #1d1d1b; }
+
+.cm-s-icecoder span.cm-keyword { color: #eee; font-weight:bold; } /* off-white 1 */
+.cm-s-icecoder span.cm-atom { color: #e1c76e; } /* yellow */
+.cm-s-icecoder span.cm-number { color: #6cb5d9; } /* blue */
+.cm-s-icecoder span.cm-def { color: #b9ca4a; } /* green */
+
+.cm-s-icecoder span.cm-variable { color: #6cb5d9; } /* blue */
+.cm-s-icecoder span.cm-variable-2 { color: #cc1e5c; } /* pink */
+.cm-s-icecoder span.cm-variable-3, .cm-s-icecoder span.cm-type { color: #f9602c; } /* orange */
+
+.cm-s-icecoder span.cm-property { color: #eee; } /* off-white 1 */
+.cm-s-icecoder span.cm-operator { color: #9179bb; } /* purple */
+.cm-s-icecoder span.cm-comment { color: #97a3aa; } /* grey-blue */
+
+.cm-s-icecoder span.cm-string { color: #b9ca4a; } /* green */
+.cm-s-icecoder span.cm-string-2 { color: #6cb5d9; } /* blue */
+
+.cm-s-icecoder span.cm-meta { color: #555; } /* grey */
+
+.cm-s-icecoder span.cm-qualifier { color: #555; } /* grey */
+.cm-s-icecoder span.cm-builtin { color: #214e7b; } /* bright blue */
+.cm-s-icecoder span.cm-bracket { color: #cc7; } /* grey-yellow */
+
+.cm-s-icecoder span.cm-tag { color: #e8e8e8; } /* off-white 2 */
+.cm-s-icecoder span.cm-attribute { color: #099; } /* teal */
+
+.cm-s-icecoder span.cm-header { color: #6a0d6a; } /* purple-pink */
+.cm-s-icecoder span.cm-quote { color: #186718; } /* dark green */
+.cm-s-icecoder span.cm-hr { color: #888; } /* mid-grey */
+.cm-s-icecoder span.cm-link { color: #e1c76e; } /* yellow */
+.cm-s-icecoder span.cm-error { color: #d00; } /* red */
+
+.cm-s-icecoder .CodeMirror-cursor { border-left: 1px solid white; }
+.cm-s-icecoder div.CodeMirror-selected { color: #fff; background: #037; }
+.cm-s-icecoder .CodeMirror-gutters { background: #1d1d1b; min-width: 41px; border-right: 0; }
+.cm-s-icecoder .CodeMirror-linenumber { color: #555; cursor: default; }
+.cm-s-icecoder .CodeMirror-matchingbracket { color: #fff !important; background: #555 !important; }
+.cm-s-icecoder .CodeMirror-activeline-background { background: #000; }
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/idea.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/idea.css
new file mode 100644
index 0000000000..eab36717ad
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/idea.css
@@ -0,0 +1,42 @@
+/**
+ Name: IDEA default theme
+ From IntelliJ IDEA by JetBrains
+ */
+
+.cm-s-idea span.cm-meta { color: #808000; }
+.cm-s-idea span.cm-number { color: #0000FF; }
+.cm-s-idea span.cm-keyword { line-height: 1em; font-weight: bold; color: #000080; }
+.cm-s-idea span.cm-atom { font-weight: bold; color: #000080; }
+.cm-s-idea span.cm-def { color: #000000; }
+.cm-s-idea span.cm-variable { color: black; }
+.cm-s-idea span.cm-variable-2 { color: black; }
+.cm-s-idea span.cm-variable-3, .cm-s-idea span.cm-type { color: black; }
+.cm-s-idea span.cm-property { color: black; }
+.cm-s-idea span.cm-operator { color: black; }
+.cm-s-idea span.cm-comment { color: #808080; }
+.cm-s-idea span.cm-string { color: #008000; }
+.cm-s-idea span.cm-string-2 { color: #008000; }
+.cm-s-idea span.cm-qualifier { color: #555; }
+.cm-s-idea span.cm-error { color: #FF0000; }
+.cm-s-idea span.cm-attribute { color: #0000FF; }
+.cm-s-idea span.cm-tag { color: #000080; }
+.cm-s-idea span.cm-link { color: #0000FF; }
+.cm-s-idea .CodeMirror-activeline-background { background: #FFFAE3; }
+
+.cm-s-idea span.cm-builtin { color: #30a; }
+.cm-s-idea span.cm-bracket { color: #cc7; }
+.cm-s-idea { font-family: Consolas, Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace, serif;}
+
+
+.cm-s-idea .CodeMirror-matchingbracket { outline:1px solid grey; color:black !important; }
+
+.CodeMirror-hints.idea {
+ font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;
+ color: #616569;
+ background-color: #ebf3fd !important;
+}
+
+.CodeMirror-hints.idea .CodeMirror-hint-active {
+ background-color: #a2b8c9 !important;
+ color: #5c6065 !important;
+}
\ No newline at end of file
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/isotope.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/isotope.css
new file mode 100644
index 0000000000..d0d6263cf4
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/isotope.css
@@ -0,0 +1,34 @@
+/*
+
+ Name: Isotope
+ Author: David Desandro / Jan T. Sott
+
+ CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror)
+ Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16)
+
+*/
+
+.cm-s-isotope.CodeMirror {background: #000000; color: #e0e0e0;}
+.cm-s-isotope div.CodeMirror-selected {background: #404040 !important;}
+.cm-s-isotope .CodeMirror-gutters {background: #000000; border-right: 0px;}
+.cm-s-isotope .CodeMirror-linenumber {color: #808080;}
+.cm-s-isotope .CodeMirror-cursor {border-left: 1px solid #c0c0c0 !important;}
+
+.cm-s-isotope span.cm-comment {color: #3300ff;}
+.cm-s-isotope span.cm-atom {color: #cc00ff;}
+.cm-s-isotope span.cm-number {color: #cc00ff;}
+
+.cm-s-isotope span.cm-property, .cm-s-isotope span.cm-attribute {color: #33ff00;}
+.cm-s-isotope span.cm-keyword {color: #ff0000;}
+.cm-s-isotope span.cm-string {color: #ff0099;}
+
+.cm-s-isotope span.cm-variable {color: #33ff00;}
+.cm-s-isotope span.cm-variable-2 {color: #0066ff;}
+.cm-s-isotope span.cm-def {color: #ff9900;}
+.cm-s-isotope span.cm-error {background: #ff0000; color: #c0c0c0;}
+.cm-s-isotope span.cm-bracket {color: #e0e0e0;}
+.cm-s-isotope span.cm-tag {color: #ff0000;}
+.cm-s-isotope span.cm-link {color: #cc00ff;}
+
+.cm-s-isotope .CodeMirror-matchingbracket { text-decoration: underline; color: white !important;}
+.cm-s-isotope .CodeMirror-activeline-background { background: #202020; }
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/juejin.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/juejin.css
new file mode 100644
index 0000000000..38cf7fe373
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/juejin.css
@@ -0,0 +1,30 @@
+.cm-s-juejin.CodeMirror {
+ background: #f8f9fa;
+}
+.cm-s-juejin .cm-header,
+.cm-s-juejin .cm-def {
+ color: #1ba2f0;
+}
+.cm-s-juejin .cm-comment {
+ color: #009e9d;
+}
+.cm-s-juejin .cm-quote,
+.cm-s-juejin .cm-link,
+.cm-s-juejin .cm-strong,
+.cm-s-juejin .cm-attribute {
+ color: #fd7741;
+}
+.cm-s-juejin .cm-url,
+.cm-s-juejin .cm-keyword,
+.cm-s-juejin .cm-builtin {
+ color: #bb51b8;
+}
+.cm-s-juejin .cm-hr {
+ color: #909090;
+}
+.cm-s-juejin .cm-tag {
+ color: #107000;
+}
+.cm-s-juejin .cm-variable-2 {
+ color: #0050a0;
+}
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/lesser-dark.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/lesser-dark.css
new file mode 100644
index 0000000000..f96bf430c2
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/lesser-dark.css
@@ -0,0 +1,47 @@
+/*
+http://lesscss.org/ dark theme
+Ported to CodeMirror by Peter Kroon
+*/
+.cm-s-lesser-dark {
+ line-height: 1.3em;
+}
+.cm-s-lesser-dark.CodeMirror { background: #262626; color: #EBEFE7; text-shadow: 0 -1px 1px #262626; }
+.cm-s-lesser-dark div.CodeMirror-selected { background: #45443B; } /* 33322B*/
+.cm-s-lesser-dark .CodeMirror-line::selection, .cm-s-lesser-dark .CodeMirror-line > span::selection, .cm-s-lesser-dark .CodeMirror-line > span > span::selection { background: rgba(69, 68, 59, .99); }
+.cm-s-lesser-dark .CodeMirror-line::-moz-selection, .cm-s-lesser-dark .CodeMirror-line > span::-moz-selection, .cm-s-lesser-dark .CodeMirror-line > span > span::-moz-selection { background: rgba(69, 68, 59, .99); }
+.cm-s-lesser-dark .CodeMirror-cursor { border-left: 1px solid white; }
+.cm-s-lesser-dark pre { padding: 0 8px; }/*editable code holder*/
+
+.cm-s-lesser-dark.CodeMirror span.CodeMirror-matchingbracket { color: #7EFC7E; }/*65FC65*/
+
+.cm-s-lesser-dark .CodeMirror-gutters { background: #262626; border-right:1px solid #aaa; }
+.cm-s-lesser-dark .CodeMirror-guttermarker { color: #599eff; }
+.cm-s-lesser-dark .CodeMirror-guttermarker-subtle { color: #777; }
+.cm-s-lesser-dark .CodeMirror-linenumber { color: #777; }
+
+.cm-s-lesser-dark span.cm-header { color: #a0a; }
+.cm-s-lesser-dark span.cm-quote { color: #090; }
+.cm-s-lesser-dark span.cm-keyword { color: #599eff; }
+.cm-s-lesser-dark span.cm-atom { color: #C2B470; }
+.cm-s-lesser-dark span.cm-number { color: #B35E4D; }
+.cm-s-lesser-dark span.cm-def { color: white; }
+.cm-s-lesser-dark span.cm-variable { color:#D9BF8C; }
+.cm-s-lesser-dark span.cm-variable-2 { color: #669199; }
+.cm-s-lesser-dark span.cm-variable-3, .cm-s-lesser-dark span.cm-type { color: white; }
+.cm-s-lesser-dark span.cm-property { color: #92A75C; }
+.cm-s-lesser-dark span.cm-operator { color: #92A75C; }
+.cm-s-lesser-dark span.cm-comment { color: #666; }
+.cm-s-lesser-dark span.cm-string { color: #BCD279; }
+.cm-s-lesser-dark span.cm-string-2 { color: #f50; }
+.cm-s-lesser-dark span.cm-meta { color: #738C73; }
+.cm-s-lesser-dark span.cm-qualifier { color: #555; }
+.cm-s-lesser-dark span.cm-builtin { color: #ff9e59; }
+.cm-s-lesser-dark span.cm-bracket { color: #EBEFE7; }
+.cm-s-lesser-dark span.cm-tag { color: #669199; }
+.cm-s-lesser-dark span.cm-attribute { color: #81a4d5; }
+.cm-s-lesser-dark span.cm-hr { color: #999; }
+.cm-s-lesser-dark span.cm-link { color: #7070E6; }
+.cm-s-lesser-dark span.cm-error { color: #9d1e15; }
+
+.cm-s-lesser-dark .CodeMirror-activeline-background { background: #3C3A3A; }
+.cm-s-lesser-dark .CodeMirror-matchingbracket { outline:1px solid grey; color:white !important; }
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/liquibyte.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/liquibyte.css
new file mode 100644
index 0000000000..393825e029
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/liquibyte.css
@@ -0,0 +1,95 @@
+.cm-s-liquibyte.CodeMirror {
+ background-color: #000;
+ color: #fff;
+ line-height: 1.2em;
+ font-size: 1em;
+}
+.cm-s-liquibyte .CodeMirror-focused .cm-matchhighlight {
+ text-decoration: underline;
+ text-decoration-color: #0f0;
+ text-decoration-style: wavy;
+}
+.cm-s-liquibyte .cm-trailingspace {
+ text-decoration: line-through;
+ text-decoration-color: #f00;
+ text-decoration-style: dotted;
+}
+.cm-s-liquibyte .cm-tab {
+ text-decoration: line-through;
+ text-decoration-color: #404040;
+ text-decoration-style: dotted;
+}
+.cm-s-liquibyte .CodeMirror-gutters { background-color: #262626; border-right: 1px solid #505050; padding-right: 0.8em; }
+.cm-s-liquibyte .CodeMirror-gutter-elt div { font-size: 1.2em; }
+.cm-s-liquibyte .CodeMirror-guttermarker { }
+.cm-s-liquibyte .CodeMirror-guttermarker-subtle { }
+.cm-s-liquibyte .CodeMirror-linenumber { color: #606060; padding-left: 0; }
+.cm-s-liquibyte .CodeMirror-cursor { border-left: 1px solid #eee; }
+
+.cm-s-liquibyte span.cm-comment { color: #008000; }
+.cm-s-liquibyte span.cm-def { color: #ffaf40; font-weight: bold; }
+.cm-s-liquibyte span.cm-keyword { color: #c080ff; font-weight: bold; }
+.cm-s-liquibyte span.cm-builtin { color: #ffaf40; font-weight: bold; }
+.cm-s-liquibyte span.cm-variable { color: #5967ff; font-weight: bold; }
+.cm-s-liquibyte span.cm-string { color: #ff8000; }
+.cm-s-liquibyte span.cm-number { color: #0f0; font-weight: bold; }
+.cm-s-liquibyte span.cm-atom { color: #bf3030; font-weight: bold; }
+
+.cm-s-liquibyte span.cm-variable-2 { color: #007f7f; font-weight: bold; }
+.cm-s-liquibyte span.cm-variable-3, .cm-s-liquibyte span.cm-type { color: #c080ff; font-weight: bold; }
+.cm-s-liquibyte span.cm-property { color: #999; font-weight: bold; }
+.cm-s-liquibyte span.cm-operator { color: #fff; }
+
+.cm-s-liquibyte span.cm-meta { color: #0f0; }
+.cm-s-liquibyte span.cm-qualifier { color: #fff700; font-weight: bold; }
+.cm-s-liquibyte span.cm-bracket { color: #cc7; }
+.cm-s-liquibyte span.cm-tag { color: #ff0; font-weight: bold; }
+.cm-s-liquibyte span.cm-attribute { color: #c080ff; font-weight: bold; }
+.cm-s-liquibyte span.cm-error { color: #f00; }
+
+.cm-s-liquibyte div.CodeMirror-selected { background-color: rgba(255, 0, 0, 0.25); }
+
+.cm-s-liquibyte span.cm-compilation { background-color: rgba(255, 255, 255, 0.12); }
+
+.cm-s-liquibyte .CodeMirror-activeline-background { background-color: rgba(0, 255, 0, 0.15); }
+
+/* Default styles for common addons */
+.cm-s-liquibyte .CodeMirror span.CodeMirror-matchingbracket { color: #0f0; font-weight: bold; }
+.cm-s-liquibyte .CodeMirror span.CodeMirror-nonmatchingbracket { color: #f00; font-weight: bold; }
+.CodeMirror-matchingtag { background-color: rgba(150, 255, 0, .3); }
+/* Scrollbars */
+/* Simple */
+.cm-s-liquibyte div.CodeMirror-simplescroll-horizontal div:hover, .cm-s-liquibyte div.CodeMirror-simplescroll-vertical div:hover {
+ background-color: rgba(80, 80, 80, .7);
+}
+.cm-s-liquibyte div.CodeMirror-simplescroll-horizontal div, .cm-s-liquibyte div.CodeMirror-simplescroll-vertical div {
+ background-color: rgba(80, 80, 80, .3);
+ border: 1px solid #404040;
+ border-radius: 5px;
+}
+.cm-s-liquibyte div.CodeMirror-simplescroll-vertical div {
+ border-top: 1px solid #404040;
+ border-bottom: 1px solid #404040;
+}
+.cm-s-liquibyte div.CodeMirror-simplescroll-horizontal div {
+ border-left: 1px solid #404040;
+ border-right: 1px solid #404040;
+}
+.cm-s-liquibyte div.CodeMirror-simplescroll-vertical {
+ background-color: #262626;
+}
+.cm-s-liquibyte div.CodeMirror-simplescroll-horizontal {
+ background-color: #262626;
+ border-top: 1px solid #404040;
+}
+/* Overlay */
+.cm-s-liquibyte div.CodeMirror-overlayscroll-horizontal div, div.CodeMirror-overlayscroll-vertical div {
+ background-color: #404040;
+ border-radius: 5px;
+}
+.cm-s-liquibyte div.CodeMirror-overlayscroll-vertical div {
+ border: 1px solid #404040;
+}
+.cm-s-liquibyte div.CodeMirror-overlayscroll-horizontal div {
+ border: 1px solid #404040;
+}
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/lucario.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/lucario.css
new file mode 100644
index 0000000000..17a1551032
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/lucario.css
@@ -0,0 +1,37 @@
+/*
+ Name: lucario
+ Author: Raphael Amorim
+
+ Original Lucario color scheme (https://github.com/raphamorim/lucario)
+*/
+
+.cm-s-lucario.CodeMirror, .cm-s-lucario .CodeMirror-gutters {
+ background-color: #2b3e50 !important;
+ color: #f8f8f2 !important;
+ border: none;
+}
+.cm-s-lucario .CodeMirror-gutters { color: #2b3e50; }
+.cm-s-lucario .CodeMirror-cursor { border-left: solid thin #E6C845; }
+.cm-s-lucario .CodeMirror-linenumber { color: #f8f8f2; }
+.cm-s-lucario .CodeMirror-selected { background: #243443; }
+.cm-s-lucario .CodeMirror-line::selection, .cm-s-lucario .CodeMirror-line > span::selection, .cm-s-lucario .CodeMirror-line > span > span::selection { background: #243443; }
+.cm-s-lucario .CodeMirror-line::-moz-selection, .cm-s-lucario .CodeMirror-line > span::-moz-selection, .cm-s-lucario .CodeMirror-line > span > span::-moz-selection { background: #243443; }
+.cm-s-lucario span.cm-comment { color: #5c98cd; }
+.cm-s-lucario span.cm-string, .cm-s-lucario span.cm-string-2 { color: #E6DB74; }
+.cm-s-lucario span.cm-number { color: #ca94ff; }
+.cm-s-lucario span.cm-variable { color: #f8f8f2; }
+.cm-s-lucario span.cm-variable-2 { color: #f8f8f2; }
+.cm-s-lucario span.cm-def { color: #72C05D; }
+.cm-s-lucario span.cm-operator { color: #66D9EF; }
+.cm-s-lucario span.cm-keyword { color: #ff6541; }
+.cm-s-lucario span.cm-atom { color: #bd93f9; }
+.cm-s-lucario span.cm-meta { color: #f8f8f2; }
+.cm-s-lucario span.cm-tag { color: #ff6541; }
+.cm-s-lucario span.cm-attribute { color: #66D9EF; }
+.cm-s-lucario span.cm-qualifier { color: #72C05D; }
+.cm-s-lucario span.cm-property { color: #f8f8f2; }
+.cm-s-lucario span.cm-builtin { color: #72C05D; }
+.cm-s-lucario span.cm-variable-3, .cm-s-lucario span.cm-type { color: #ffb86c; }
+
+.cm-s-lucario .CodeMirror-activeline-background { background: #243443; }
+.cm-s-lucario .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; }
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/material-darker.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/material-darker.css
new file mode 100644
index 0000000000..45b64efb25
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/material-darker.css
@@ -0,0 +1,135 @@
+/*
+ Name: material
+ Author: Mattia Astorino (http://github.com/equinusocio)
+ Website: https://material-theme.site/
+*/
+
+.cm-s-material-darker.CodeMirror {
+ background-color: #212121;
+ color: #EEFFFF;
+}
+
+.cm-s-material-darker .CodeMirror-gutters {
+ background: #212121;
+ color: #545454;
+ border: none;
+}
+
+.cm-s-material-darker .CodeMirror-guttermarker,
+.cm-s-material-darker .CodeMirror-guttermarker-subtle,
+.cm-s-material-darker .CodeMirror-linenumber {
+ color: #545454;
+}
+
+.cm-s-material-darker .CodeMirror-cursor {
+ border-left: 1px solid #FFCC00;
+}
+
+.cm-s-material-darker div.CodeMirror-selected {
+ background: rgba(97, 97, 97, 0.2);
+}
+
+.cm-s-material-darker.CodeMirror-focused div.CodeMirror-selected {
+ background: rgba(97, 97, 97, 0.2);
+}
+
+.cm-s-material-darker .CodeMirror-line::selection,
+.cm-s-material-darker .CodeMirror-line>span::selection,
+.cm-s-material-darker .CodeMirror-line>span>span::selection {
+ background: rgba(128, 203, 196, 0.2);
+}
+
+.cm-s-material-darker .CodeMirror-line::-moz-selection,
+.cm-s-material-darker .CodeMirror-line>span::-moz-selection,
+.cm-s-material-darker .CodeMirror-line>span>span::-moz-selection {
+ background: rgba(128, 203, 196, 0.2);
+}
+
+.cm-s-material-darker .CodeMirror-activeline-background {
+ background: rgba(0, 0, 0, 0.5);
+}
+
+.cm-s-material-darker .cm-keyword {
+ color: #C792EA;
+}
+
+.cm-s-material-darker .cm-operator {
+ color: #89DDFF;
+}
+
+.cm-s-material-darker .cm-variable-2 {
+ color: #EEFFFF;
+}
+
+.cm-s-material-darker .cm-variable-3,
+.cm-s-material-darker .cm-type {
+ color: #f07178;
+}
+
+.cm-s-material-darker .cm-builtin {
+ color: #FFCB6B;
+}
+
+.cm-s-material-darker .cm-atom {
+ color: #F78C6C;
+}
+
+.cm-s-material-darker .cm-number {
+ color: #FF5370;
+}
+
+.cm-s-material-darker .cm-def {
+ color: #82AAFF;
+}
+
+.cm-s-material-darker .cm-string {
+ color: #C3E88D;
+}
+
+.cm-s-material-darker .cm-string-2 {
+ color: #f07178;
+}
+
+.cm-s-material-darker .cm-comment {
+ color: #545454;
+}
+
+.cm-s-material-darker .cm-variable {
+ color: #f07178;
+}
+
+.cm-s-material-darker .cm-tag {
+ color: #FF5370;
+}
+
+.cm-s-material-darker .cm-meta {
+ color: #FFCB6B;
+}
+
+.cm-s-material-darker .cm-attribute {
+ color: #C792EA;
+}
+
+.cm-s-material-darker .cm-property {
+ color: #C792EA;
+}
+
+.cm-s-material-darker .cm-qualifier {
+ color: #DECB6B;
+}
+
+.cm-s-material-darker .cm-variable-3,
+.cm-s-material-darker .cm-type {
+ color: #DECB6B;
+}
+
+
+.cm-s-material-darker .cm-error {
+ color: rgba(255, 255, 255, 1.0);
+ background-color: #FF5370;
+}
+
+.cm-s-material-darker .CodeMirror-matchingbracket {
+ text-decoration: underline;
+ color: white !important;
+}
\ No newline at end of file
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/material-ocean.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/material-ocean.css
new file mode 100644
index 0000000000..404178de22
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/material-ocean.css
@@ -0,0 +1,141 @@
+/*
+ Name: material
+ Author: Mattia Astorino (http://github.com/equinusocio)
+ Website: https://material-theme.site/
+*/
+
+.cm-s-material-ocean.CodeMirror {
+ background-color: #0F111A;
+ color: #8F93A2;
+}
+
+.cm-s-material-ocean .CodeMirror-gutters {
+ background: #0F111A;
+ color: #464B5D;
+ border: none;
+}
+
+.cm-s-material-ocean .CodeMirror-guttermarker,
+.cm-s-material-ocean .CodeMirror-guttermarker-subtle,
+.cm-s-material-ocean .CodeMirror-linenumber {
+ color: #464B5D;
+}
+
+.cm-s-material-ocean .CodeMirror-cursor {
+ border-left: 1px solid #FFCC00;
+}
+.cm-s-material-ocean.cm-fat-cursor .CodeMirror-cursor {
+ background-color: #a2a8a175 !important;
+}
+.cm-s-material-ocean .cm-animate-fat-cursor {
+ background-color: #a2a8a175 !important;
+}
+
+.cm-s-material-ocean div.CodeMirror-selected {
+ background: rgba(113, 124, 180, 0.2);
+}
+
+.cm-s-material-ocean.CodeMirror-focused div.CodeMirror-selected {
+ background: rgba(113, 124, 180, 0.2);
+}
+
+.cm-s-material-ocean .CodeMirror-line::selection,
+.cm-s-material-ocean .CodeMirror-line>span::selection,
+.cm-s-material-ocean .CodeMirror-line>span>span::selection {
+ background: rgba(128, 203, 196, 0.2);
+}
+
+.cm-s-material-ocean .CodeMirror-line::-moz-selection,
+.cm-s-material-ocean .CodeMirror-line>span::-moz-selection,
+.cm-s-material-ocean .CodeMirror-line>span>span::-moz-selection {
+ background: rgba(128, 203, 196, 0.2);
+}
+
+.cm-s-material-ocean .CodeMirror-activeline-background {
+ background: rgba(0, 0, 0, 0.5);
+}
+
+.cm-s-material-ocean .cm-keyword {
+ color: #C792EA;
+}
+
+.cm-s-material-ocean .cm-operator {
+ color: #89DDFF;
+}
+
+.cm-s-material-ocean .cm-variable-2 {
+ color: #EEFFFF;
+}
+
+.cm-s-material-ocean .cm-variable-3,
+.cm-s-material-ocean .cm-type {
+ color: #f07178;
+}
+
+.cm-s-material-ocean .cm-builtin {
+ color: #FFCB6B;
+}
+
+.cm-s-material-ocean .cm-atom {
+ color: #F78C6C;
+}
+
+.cm-s-material-ocean .cm-number {
+ color: #FF5370;
+}
+
+.cm-s-material-ocean .cm-def {
+ color: #82AAFF;
+}
+
+.cm-s-material-ocean .cm-string {
+ color: #C3E88D;
+}
+
+.cm-s-material-ocean .cm-string-2 {
+ color: #f07178;
+}
+
+.cm-s-material-ocean .cm-comment {
+ color: #464B5D;
+}
+
+.cm-s-material-ocean .cm-variable {
+ color: #f07178;
+}
+
+.cm-s-material-ocean .cm-tag {
+ color: #FF5370;
+}
+
+.cm-s-material-ocean .cm-meta {
+ color: #FFCB6B;
+}
+
+.cm-s-material-ocean .cm-attribute {
+ color: #C792EA;
+}
+
+.cm-s-material-ocean .cm-property {
+ color: #C792EA;
+}
+
+.cm-s-material-ocean .cm-qualifier {
+ color: #DECB6B;
+}
+
+.cm-s-material-ocean .cm-variable-3,
+.cm-s-material-ocean .cm-type {
+ color: #DECB6B;
+}
+
+
+.cm-s-material-ocean .cm-error {
+ color: rgba(255, 255, 255, 1.0);
+ background-color: #FF5370;
+}
+
+.cm-s-material-ocean .CodeMirror-matchingbracket {
+ text-decoration: underline;
+ color: white !important;
+}
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/material-palenight.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/material-palenight.css
new file mode 100644
index 0000000000..6712c43a0e
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/material-palenight.css
@@ -0,0 +1,141 @@
+/*
+ Name: material
+ Author: Mattia Astorino (http://github.com/equinusocio)
+ Website: https://material-theme.site/
+*/
+
+.cm-s-material-palenight.CodeMirror {
+ background-color: #292D3E;
+ color: #A6ACCD;
+}
+
+.cm-s-material-palenight .CodeMirror-gutters {
+ background: #292D3E;
+ color: #676E95;
+ border: none;
+}
+
+.cm-s-material-palenight .CodeMirror-guttermarker,
+.cm-s-material-palenight .CodeMirror-guttermarker-subtle,
+.cm-s-material-palenight .CodeMirror-linenumber {
+ color: #676E95;
+}
+
+.cm-s-material-palenight .CodeMirror-cursor {
+ border-left: 1px solid #FFCC00;
+}
+.cm-s-material-palenight.cm-fat-cursor .CodeMirror-cursor {
+ background-color: #607c8b80 !important;
+}
+.cm-s-material-palenight .cm-animate-fat-cursor {
+ background-color: #607c8b80 !important;
+}
+
+.cm-s-material-palenight div.CodeMirror-selected {
+ background: rgba(113, 124, 180, 0.2);
+}
+
+.cm-s-material-palenight.CodeMirror-focused div.CodeMirror-selected {
+ background: rgba(113, 124, 180, 0.2);
+}
+
+.cm-s-material-palenight .CodeMirror-line::selection,
+.cm-s-material-palenight .CodeMirror-line>span::selection,
+.cm-s-material-palenight .CodeMirror-line>span>span::selection {
+ background: rgba(128, 203, 196, 0.2);
+}
+
+.cm-s-material-palenight .CodeMirror-line::-moz-selection,
+.cm-s-material-palenight .CodeMirror-line>span::-moz-selection,
+.cm-s-material-palenight .CodeMirror-line>span>span::-moz-selection {
+ background: rgba(128, 203, 196, 0.2);
+}
+
+.cm-s-material-palenight .CodeMirror-activeline-background {
+ background: rgba(0, 0, 0, 0.5);
+}
+
+.cm-s-material-palenight .cm-keyword {
+ color: #C792EA;
+}
+
+.cm-s-material-palenight .cm-operator {
+ color: #89DDFF;
+}
+
+.cm-s-material-palenight .cm-variable-2 {
+ color: #EEFFFF;
+}
+
+.cm-s-material-palenight .cm-variable-3,
+.cm-s-material-palenight .cm-type {
+ color: #f07178;
+}
+
+.cm-s-material-palenight .cm-builtin {
+ color: #FFCB6B;
+}
+
+.cm-s-material-palenight .cm-atom {
+ color: #F78C6C;
+}
+
+.cm-s-material-palenight .cm-number {
+ color: #FF5370;
+}
+
+.cm-s-material-palenight .cm-def {
+ color: #82AAFF;
+}
+
+.cm-s-material-palenight .cm-string {
+ color: #C3E88D;
+}
+
+.cm-s-material-palenight .cm-string-2 {
+ color: #f07178;
+}
+
+.cm-s-material-palenight .cm-comment {
+ color: #676E95;
+}
+
+.cm-s-material-palenight .cm-variable {
+ color: #f07178;
+}
+
+.cm-s-material-palenight .cm-tag {
+ color: #FF5370;
+}
+
+.cm-s-material-palenight .cm-meta {
+ color: #FFCB6B;
+}
+
+.cm-s-material-palenight .cm-attribute {
+ color: #C792EA;
+}
+
+.cm-s-material-palenight .cm-property {
+ color: #C792EA;
+}
+
+.cm-s-material-palenight .cm-qualifier {
+ color: #DECB6B;
+}
+
+.cm-s-material-palenight .cm-variable-3,
+.cm-s-material-palenight .cm-type {
+ color: #DECB6B;
+}
+
+
+.cm-s-material-palenight .cm-error {
+ color: rgba(255, 255, 255, 1.0);
+ background-color: #FF5370;
+}
+
+.cm-s-material-palenight .CodeMirror-matchingbracket {
+ text-decoration: underline;
+ color: white !important;
+}
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/material.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/material.css
new file mode 100644
index 0000000000..a7848499a7
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/material.css
@@ -0,0 +1,141 @@
+/*
+ Name: material
+ Author: Mattia Astorino (http://github.com/equinusocio)
+ Website: https://material-theme.site/
+*/
+
+.cm-s-material.CodeMirror {
+ background-color: #263238;
+ color: #EEFFFF;
+}
+
+.cm-s-material .CodeMirror-gutters {
+ background: #263238;
+ color: #546E7A;
+ border: none;
+}
+
+.cm-s-material .CodeMirror-guttermarker,
+.cm-s-material .CodeMirror-guttermarker-subtle,
+.cm-s-material .CodeMirror-linenumber {
+ color: #546E7A;
+}
+
+.cm-s-material .CodeMirror-cursor {
+ border-left: 1px solid #FFCC00;
+}
+.cm-s-material.cm-fat-cursor .CodeMirror-cursor {
+ background-color: #5d6d5c80 !important;
+}
+.cm-s-material .cm-animate-fat-cursor {
+ background-color: #5d6d5c80 !important;
+}
+
+.cm-s-material div.CodeMirror-selected {
+ background: rgba(128, 203, 196, 0.2);
+}
+
+.cm-s-material.CodeMirror-focused div.CodeMirror-selected {
+ background: rgba(128, 203, 196, 0.2);
+}
+
+.cm-s-material .CodeMirror-line::selection,
+.cm-s-material .CodeMirror-line>span::selection,
+.cm-s-material .CodeMirror-line>span>span::selection {
+ background: rgba(128, 203, 196, 0.2);
+}
+
+.cm-s-material .CodeMirror-line::-moz-selection,
+.cm-s-material .CodeMirror-line>span::-moz-selection,
+.cm-s-material .CodeMirror-line>span>span::-moz-selection {
+ background: rgba(128, 203, 196, 0.2);
+}
+
+.cm-s-material .CodeMirror-activeline-background {
+ background: rgba(0, 0, 0, 0.5);
+}
+
+.cm-s-material .cm-keyword {
+ color: #C792EA;
+}
+
+.cm-s-material .cm-operator {
+ color: #89DDFF;
+}
+
+.cm-s-material .cm-variable-2 {
+ color: #EEFFFF;
+}
+
+.cm-s-material .cm-variable-3,
+.cm-s-material .cm-type {
+ color: #f07178;
+}
+
+.cm-s-material .cm-builtin {
+ color: #FFCB6B;
+}
+
+.cm-s-material .cm-atom {
+ color: #F78C6C;
+}
+
+.cm-s-material .cm-number {
+ color: #FF5370;
+}
+
+.cm-s-material .cm-def {
+ color: #82AAFF;
+}
+
+.cm-s-material .cm-string {
+ color: #C3E88D;
+}
+
+.cm-s-material .cm-string-2 {
+ color: #f07178;
+}
+
+.cm-s-material .cm-comment {
+ color: #546E7A;
+}
+
+.cm-s-material .cm-variable {
+ color: #f07178;
+}
+
+.cm-s-material .cm-tag {
+ color: #FF5370;
+}
+
+.cm-s-material .cm-meta {
+ color: #FFCB6B;
+}
+
+.cm-s-material .cm-attribute {
+ color: #C792EA;
+}
+
+.cm-s-material .cm-property {
+ color: #C792EA;
+}
+
+.cm-s-material .cm-qualifier {
+ color: #DECB6B;
+}
+
+.cm-s-material .cm-variable-3,
+.cm-s-material .cm-type {
+ color: #DECB6B;
+}
+
+
+.cm-s-material .cm-error {
+ color: rgba(255, 255, 255, 1.0);
+ background-color: #FF5370;
+}
+
+.cm-s-material .CodeMirror-matchingbracket {
+ text-decoration: underline;
+ color: white !important;
+}
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/mbo.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/mbo.css
new file mode 100644
index 0000000000..e164fcf42a
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/mbo.css
@@ -0,0 +1,37 @@
+/****************************************************************/
+/* Based on mbonaci's Brackets mbo theme */
+/* https://github.com/mbonaci/global/blob/master/Mbo.tmTheme */
+/* Create your own: http://tmtheme-editor.herokuapp.com */
+/****************************************************************/
+
+.cm-s-mbo.CodeMirror { background: #2c2c2c; color: #ffffec; }
+.cm-s-mbo div.CodeMirror-selected { background: #716C62; }
+.cm-s-mbo .CodeMirror-line::selection, .cm-s-mbo .CodeMirror-line > span::selection, .cm-s-mbo .CodeMirror-line > span > span::selection { background: rgba(113, 108, 98, .99); }
+.cm-s-mbo .CodeMirror-line::-moz-selection, .cm-s-mbo .CodeMirror-line > span::-moz-selection, .cm-s-mbo .CodeMirror-line > span > span::-moz-selection { background: rgba(113, 108, 98, .99); }
+.cm-s-mbo .CodeMirror-gutters { background: #4e4e4e; border-right: 0px; }
+.cm-s-mbo .CodeMirror-guttermarker { color: white; }
+.cm-s-mbo .CodeMirror-guttermarker-subtle { color: grey; }
+.cm-s-mbo .CodeMirror-linenumber { color: #dadada; }
+.cm-s-mbo .CodeMirror-cursor { border-left: 1px solid #ffffec; }
+
+.cm-s-mbo span.cm-comment { color: #95958a; }
+.cm-s-mbo span.cm-atom { color: #00a8c6; }
+.cm-s-mbo span.cm-number { color: #00a8c6; }
+
+.cm-s-mbo span.cm-property, .cm-s-mbo span.cm-attribute { color: #9ddfe9; }
+.cm-s-mbo span.cm-keyword { color: #ffb928; }
+.cm-s-mbo span.cm-string { color: #ffcf6c; }
+.cm-s-mbo span.cm-string.cm-property { color: #ffffec; }
+
+.cm-s-mbo span.cm-variable { color: #ffffec; }
+.cm-s-mbo span.cm-variable-2 { color: #00a8c6; }
+.cm-s-mbo span.cm-def { color: #ffffec; }
+.cm-s-mbo span.cm-bracket { color: #fffffc; font-weight: bold; }
+.cm-s-mbo span.cm-tag { color: #9ddfe9; }
+.cm-s-mbo span.cm-link { color: #f54b07; }
+.cm-s-mbo span.cm-error { border-bottom: #636363; color: #ffffec; }
+.cm-s-mbo span.cm-qualifier { color: #ffffec; }
+
+.cm-s-mbo .CodeMirror-activeline-background { background: #494b41; }
+.cm-s-mbo .CodeMirror-matchingbracket { color: #ffb928 !important; }
+.cm-s-mbo .CodeMirror-matchingtag { background: rgba(255, 255, 255, .37); }
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/mdn-like.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/mdn-like.css
new file mode 100644
index 0000000000..622ed3efb7
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/mdn-like.css
@@ -0,0 +1,46 @@
+/*
+ MDN-LIKE Theme - Mozilla
+ Ported to CodeMirror by Peter Kroon
+ Report bugs/issues here: https://github.com/codemirror/CodeMirror/issues
+ GitHub: @peterkroon
+
+ The mdn-like theme is inspired on the displayed code examples at: https://developer.mozilla.org/en-US/docs/Web/CSS/animation
+
+*/
+.cm-s-mdn-like.CodeMirror { color: #999; background-color: #fff; }
+.cm-s-mdn-like div.CodeMirror-selected { background: #cfc; }
+.cm-s-mdn-like .CodeMirror-line::selection, .cm-s-mdn-like .CodeMirror-line > span::selection, .cm-s-mdn-like .CodeMirror-line > span > span::selection { background: #cfc; }
+.cm-s-mdn-like .CodeMirror-line::-moz-selection, .cm-s-mdn-like .CodeMirror-line > span::-moz-selection, .cm-s-mdn-like .CodeMirror-line > span > span::-moz-selection { background: #cfc; }
+
+.cm-s-mdn-like .CodeMirror-gutters { background: #f8f8f8; border-left: 6px solid rgba(0,83,159,0.65); color: #333; }
+.cm-s-mdn-like .CodeMirror-linenumber { color: #aaa; padding-left: 8px; }
+.cm-s-mdn-like .CodeMirror-cursor { border-left: 2px solid #222; }
+
+.cm-s-mdn-like .cm-keyword { color: #6262FF; }
+.cm-s-mdn-like .cm-atom { color: #F90; }
+.cm-s-mdn-like .cm-number { color: #ca7841; }
+.cm-s-mdn-like .cm-def { color: #8DA6CE; }
+.cm-s-mdn-like span.cm-variable-2, .cm-s-mdn-like span.cm-tag { color: #690; }
+.cm-s-mdn-like span.cm-variable-3, .cm-s-mdn-like span.cm-def, .cm-s-mdn-like span.cm-type { color: #07a; }
+
+.cm-s-mdn-like .cm-variable { color: #07a; }
+.cm-s-mdn-like .cm-property { color: #905; }
+.cm-s-mdn-like .cm-qualifier { color: #690; }
+
+.cm-s-mdn-like .cm-operator { color: #cda869; }
+.cm-s-mdn-like .cm-comment { color:#777; font-weight:normal; }
+.cm-s-mdn-like .cm-string { color:#07a; font-style:italic; }
+.cm-s-mdn-like .cm-string-2 { color:#bd6b18; } /*?*/
+.cm-s-mdn-like .cm-meta { color: #000; } /*?*/
+.cm-s-mdn-like .cm-builtin { color: #9B7536; } /*?*/
+.cm-s-mdn-like .cm-tag { color: #997643; }
+.cm-s-mdn-like .cm-attribute { color: #d6bb6d; } /*?*/
+.cm-s-mdn-like .cm-header { color: #FF6400; }
+.cm-s-mdn-like .cm-hr { color: #AEAEAE; }
+.cm-s-mdn-like .cm-link { color:#ad9361; font-style:italic; text-decoration:none; }
+.cm-s-mdn-like .cm-error { border-bottom: 1px solid red; }
+
+div.cm-s-mdn-like .CodeMirror-activeline-background { background: #efefff; }
+div.cm-s-mdn-like span.CodeMirror-matchingbracket { outline:1px solid grey; color: inherit; }
+
+.cm-s-mdn-like.CodeMirror { background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFcAAAAyCAYAAAAp8UeFAAAHvklEQVR42s2b63bcNgyEQZCSHCdt2vd/0tWF7I+Q6XgMXiTtuvU5Pl57ZQKkKHzEAOtF5KeIJBGJ8uvL599FRFREZhFx8DeXv8trn68RuGaC8TRfo3SNp9dlDDHedyLyTUTeRWStXKPZrjtpZxaRw5hPqozRs1N8/enzIiQRWcCgy4MUA0f+XWliDhyL8Lfyvx7ei/Ae3iQFHyw7U/59pQVIMEEPEz0G7XiwdRjzSfC3UTtz9vchIntxvry5iMgfIhJoEflOz2CQr3F5h/HfeFe+GTdLaKcu9L8LTeQb/R/7GgbsfKedyNdoHsN31uRPWrfZ5wsj/NzzRQHuToIdU3ahwnsKPxXCjJITuOsi7XLc7SG/v5GdALs7wf8JjTFiB5+QvTEfRyGOfX3Lrx8wxyQi3sNq46O7QahQiCsRFgqddjBouVEHOKDgXAQHD9gJCr5sMKkEdjwsarG/ww3BMHBU7OBjXnzdyY7SfCxf5/z6ATccrwlKuwC/jhznnPF4CgVzhhVf4xp2EixcBActO75iZ8/fM9zAs2OMzKdslgXWJ9XG8PQoOAMA5fGcsvORgv0doBXyHrCwfLJAOwo71QLNkb8n2Pl6EWiR7OCibtkPaz4Kc/0NNAze2gju3zOwekALDaCFPI5vjPFmgGY5AZqyGEvH1x7QfIb8YtxMnA/b+QQ0aQDAwc6JMFg8CbQZ4qoYEEHbRwNojuK3EHwd7VALSgq+MNDKzfT58T8qdpADrgW0GmgcAS1lhzztJmkAzcPNOQbsWEALBDSlMKUG0Eq4CLAQWvEVQ9WU57gZJwZtgPO3r9oBTQ9WO8TjqXINx8R0EYpiZEUWOF3FxkbJkgU9B2f41YBrIj5ZfsQa0M5kTgiAAqM3ShXLgu8XMqcrQBvJ0CL5pnTsfMB13oB8athpAq2XOQmcGmoACCLydx7nToa23ATaSIY2ichfOdPTGxlasXMLaL0MLZAOwAKIM+y8CmicobGdCcbbK9DzN+yYGVoNNI5iUKTMyYOjPse4A8SM1MmcXgU0toOq1yO/v8FOxlASyc7TgeYaAMBJHcY1CcCwGI/TK4AmDbDyKYBBtFUkRwto8gygiQEaByFgJ00BH2M8JWwQS1nafDXQCidWyOI8AcjDCSjCLk8ngObuAm3JAHAdubAmOaK06V8MNEsKPJOhobSprwQa6gD7DclRQdqcwL4zxqgBrQcabUiBLclRDKAlWp+etPkBaNMA0AKlrHwTdEByZAA4GM+SNluSY6wAzcMNewxmgig5Ks0nkrSpBvSaQHMdKTBAnLojOdYyGpQ254602ZILPdTD1hdlggdIm74jbTp8vDwF5ZYUeLWGJpWsh6XNyXgcYwVoJQTEhhTYkxzZjiU5npU2TaB979TQehlaAVq4kaGpiPwwwLkYUuBbQwocyQTv1tA0+1UFWoJF3iv1oq+qoSk8EQdJmwHkziIF7oOZk14EGitibAdjLYYK78H5vZOhtWpoI0ATGHs0Q8OMb4Ey+2bU2UYztCtA0wFAs7TplGLRVQCcqaFdGSPCeTI1QNIC52iWNzof6Uib7xjEp07mNNoUYmVosVItHrHzRlLgBn9LFyRHaQCtVUMbtTNhoXWiTOO9k/V8BdAc1Oq0ArSQs6/5SU0hckNy9NnXqQY0PGYo5dWJ7nINaN6o958FWin27aBaWRka1r5myvLOAm0j30eBJqCxHLReVclxhxOEN2JfDWjxBtAC7MIH1fVaGdoOp4qJYDgKtKPSFNID2gSnGldrCqkFZ+5UeQXQBIRrSwocbdZYQT/2LwRahBPBXoHrB8nxaGROST62DKUbQOMMzZIC9abkuELfQzQALWTnDNAm8KHWFOJgJ5+SHIvTPcmx1xQyZRhNL5Qci689aXMEaN/uNIWkEwDAvFpOZmgsBaaGnbs1NPa1Jm32gBZAIh1pCtG7TSH4aE0y1uVY4uqoFPisGlpP2rSA5qTecWn5agK6BzSpgAyD+wFaqhnYoSZ1Vwr8CmlTQbrcO3ZaX0NAEyMbYaAlyquFoLKK3SPby9CeVUPThrSJmkCAE0CrKUQadi4DrdSlWhmah0YL9z9vClH59YGbHx1J8VZTyAjQepJjmXwAKTDQI3omc3p1U4gDUf6RfcdYfrUp5ClAi2J3Ba6UOXGo+K+bQrjjssitG2SJzshaLwMtXgRagUNpYYoVkMSBLM+9GGiJZMvduG6DRZ4qc04DMPtQQxOjEtACmhO7K1AbNbQDEggZyJwscFpAGwENhoBeUwh3bWolhe8BTYVKxQEWrSUn/uhcM5KhvUu/+eQu0Lzhi+VrK0PrZZNDQKs9cpYUuFYgMVpD4/NxenJTiMCNqdUEUf1qZWjppLT5qSkkUZbCwkbZMSuVnu80hfSkzRbQeqCZSAh6huR4VtoM2gHAlLf72smuWgE+VV7XpE25Ab2WFDgyhnSuKbs4GuGzCjR+tIoUuMFg3kgcWKLTwRqanJQ2W00hAsenfaApRC42hbCvK1SlE0HtE9BGgneJO+ELamitD1YjjOYnNYVcraGhtKkW0EqVVeDx733I2NH581k1NNxNLG0i0IJ8/NjVaOZ0tYZ2Vtr0Xv7tPV3hkWp9EFkgS/J0vosngTaSoaG06WHi+xObQkaAdlbanP8B2+2l0f90LmUAAAAASUVORK5CYII=); }
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/midnight.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/midnight.css
new file mode 100644
index 0000000000..fc26474a4a
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/midnight.css
@@ -0,0 +1,39 @@
+/* Based on the theme at http://bonsaiden.github.com/JavaScript-Garden */
+
+/**/
+.cm-s-midnight .CodeMirror-activeline-background { background: #253540; }
+
+.cm-s-midnight.CodeMirror {
+ background: #0F192A;
+ color: #D1EDFF;
+}
+
+.cm-s-midnight div.CodeMirror-selected { background: #314D67; }
+.cm-s-midnight .CodeMirror-line::selection, .cm-s-midnight .CodeMirror-line > span::selection, .cm-s-midnight .CodeMirror-line > span > span::selection { background: rgba(49, 77, 103, .99); }
+.cm-s-midnight .CodeMirror-line::-moz-selection, .cm-s-midnight .CodeMirror-line > span::-moz-selection, .cm-s-midnight .CodeMirror-line > span > span::-moz-selection { background: rgba(49, 77, 103, .99); }
+.cm-s-midnight .CodeMirror-gutters { background: #0F192A; border-right: 1px solid; }
+.cm-s-midnight .CodeMirror-guttermarker { color: white; }
+.cm-s-midnight .CodeMirror-guttermarker-subtle { color: #d0d0d0; }
+.cm-s-midnight .CodeMirror-linenumber { color: #D0D0D0; }
+.cm-s-midnight .CodeMirror-cursor { border-left: 1px solid #F8F8F0; }
+
+.cm-s-midnight span.cm-comment { color: #428BDD; }
+.cm-s-midnight span.cm-atom { color: #AE81FF; }
+.cm-s-midnight span.cm-number { color: #D1EDFF; }
+
+.cm-s-midnight span.cm-property, .cm-s-midnight span.cm-attribute { color: #A6E22E; }
+.cm-s-midnight span.cm-keyword { color: #E83737; }
+.cm-s-midnight span.cm-string { color: #1DC116; }
+
+.cm-s-midnight span.cm-variable { color: #FFAA3E; }
+.cm-s-midnight span.cm-variable-2 { color: #FFAA3E; }
+.cm-s-midnight span.cm-def { color: #4DD; }
+.cm-s-midnight span.cm-bracket { color: #D1EDFF; }
+.cm-s-midnight span.cm-tag { color: #449; }
+.cm-s-midnight span.cm-link { color: #AE81FF; }
+.cm-s-midnight span.cm-error { background: #F92672; color: #F8F8F0; }
+
+.cm-s-midnight .CodeMirror-matchingbracket {
+ text-decoration: underline;
+ color: white !important;
+}
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/monokai.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/monokai.css
new file mode 100644
index 0000000000..cd4cd55720
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/monokai.css
@@ -0,0 +1,41 @@
+/* Based on Sublime Text's Monokai theme */
+
+.cm-s-monokai.CodeMirror { background: #272822; color: #f8f8f2; }
+.cm-s-monokai div.CodeMirror-selected { background: #49483E; }
+.cm-s-monokai .CodeMirror-line::selection, .cm-s-monokai .CodeMirror-line > span::selection, .cm-s-monokai .CodeMirror-line > span > span::selection { background: rgba(73, 72, 62, .99); }
+.cm-s-monokai .CodeMirror-line::-moz-selection, .cm-s-monokai .CodeMirror-line > span::-moz-selection, .cm-s-monokai .CodeMirror-line > span > span::-moz-selection { background: rgba(73, 72, 62, .99); }
+.cm-s-monokai .CodeMirror-gutters { background: #272822; border-right: 0px; }
+.cm-s-monokai .CodeMirror-guttermarker { color: white; }
+.cm-s-monokai .CodeMirror-guttermarker-subtle { color: #d0d0d0; }
+.cm-s-monokai .CodeMirror-linenumber { color: #d0d0d0; }
+.cm-s-monokai .CodeMirror-cursor { border-left: 1px solid #f8f8f0; }
+
+.cm-s-monokai span.cm-comment { color: #75715e; }
+.cm-s-monokai span.cm-atom { color: #ae81ff; }
+.cm-s-monokai span.cm-number { color: #ae81ff; }
+
+.cm-s-monokai span.cm-comment.cm-attribute { color: #97b757; }
+.cm-s-monokai span.cm-comment.cm-def { color: #bc9262; }
+.cm-s-monokai span.cm-comment.cm-tag { color: #bc6283; }
+.cm-s-monokai span.cm-comment.cm-type { color: #5998a6; }
+
+.cm-s-monokai span.cm-property, .cm-s-monokai span.cm-attribute { color: #a6e22e; }
+.cm-s-monokai span.cm-keyword { color: #f92672; }
+.cm-s-monokai span.cm-builtin { color: #66d9ef; }
+.cm-s-monokai span.cm-string { color: #e6db74; }
+
+.cm-s-monokai span.cm-variable { color: #f8f8f2; }
+.cm-s-monokai span.cm-variable-2 { color: #9effff; }
+.cm-s-monokai span.cm-variable-3, .cm-s-monokai span.cm-type { color: #66d9ef; }
+.cm-s-monokai span.cm-def { color: #fd971f; }
+.cm-s-monokai span.cm-bracket { color: #f8f8f2; }
+.cm-s-monokai span.cm-tag { color: #f92672; }
+.cm-s-monokai span.cm-header { color: #ae81ff; }
+.cm-s-monokai span.cm-link { color: #ae81ff; }
+.cm-s-monokai span.cm-error { background: #f92672; color: #f8f8f0; }
+
+.cm-s-monokai .CodeMirror-activeline-background { background: #373831; }
+.cm-s-monokai .CodeMirror-matchingbracket {
+ text-decoration: underline;
+ color: white !important;
+}
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/moxer.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/moxer.css
new file mode 100644
index 0000000000..b3ca35e385
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/moxer.css
@@ -0,0 +1,143 @@
+/*
+ Name: Moxer Theme
+ Author: Mattia Astorino (http://github.com/equinusocio)
+ Website: https://github.com/moxer-theme/moxer-code
+*/
+
+.cm-s-moxer.CodeMirror {
+ background-color: #090A0F;
+ color: #8E95B4;
+ line-height: 1.8;
+}
+
+.cm-s-moxer .CodeMirror-gutters {
+ background: #090A0F;
+ color: #35394B;
+ border: none;
+}
+
+.cm-s-moxer .CodeMirror-guttermarker,
+.cm-s-moxer .CodeMirror-guttermarker-subtle,
+.cm-s-moxer .CodeMirror-linenumber {
+ color: #35394B;
+}
+
+
+.cm-s-moxer .CodeMirror-cursor {
+ border-left: 1px solid #FFCC00;
+}
+
+.cm-s-moxer div.CodeMirror-selected {
+ background: rgba(128, 203, 196, 0.2);
+}
+
+.cm-s-moxer.CodeMirror-focused div.CodeMirror-selected {
+ background: #212431;
+}
+
+.cm-s-moxer .CodeMirror-line::selection,
+.cm-s-moxer .CodeMirror-line>span::selection,
+.cm-s-moxer .CodeMirror-line>span>span::selection {
+ background: #212431;
+}
+
+.cm-s-moxer .CodeMirror-line::-moz-selection,
+.cm-s-moxer .CodeMirror-line>span::-moz-selection,
+.cm-s-moxer .CodeMirror-line>span>span::-moz-selection {
+ background: #212431;
+}
+
+.cm-s-moxer .CodeMirror-activeline-background,
+.cm-s-moxer .CodeMirror-activeline-gutter .CodeMirror-linenumber {
+ background: rgba(33, 36, 49, 0.5);
+}
+
+.cm-s-moxer .cm-keyword {
+ color: #D46C6C;
+}
+
+.cm-s-moxer .cm-operator {
+ color: #D46C6C;
+}
+
+.cm-s-moxer .cm-variable-2 {
+ color: #81C5DA;
+}
+
+
+.cm-s-moxer .cm-variable-3,
+.cm-s-moxer .cm-type {
+ color: #f07178;
+}
+
+.cm-s-moxer .cm-builtin {
+ color: #FFCB6B;
+}
+
+.cm-s-moxer .cm-atom {
+ color: #A99BE2;
+}
+
+.cm-s-moxer .cm-number {
+ color: #7CA4C0;
+}
+
+.cm-s-moxer .cm-def {
+ color: #F5DFA5;
+}
+
+.cm-s-moxer .CodeMirror-line .cm-def ~ .cm-def {
+ color: #81C5DA;
+}
+
+.cm-s-moxer .cm-string {
+ color: #B2E4AE;
+}
+
+.cm-s-moxer .cm-string-2 {
+ color: #f07178;
+}
+
+.cm-s-moxer .cm-comment {
+ color: #3F445A;
+}
+
+.cm-s-moxer .cm-variable {
+ color: #8E95B4;
+}
+
+.cm-s-moxer .cm-tag {
+ color: #FF5370;
+}
+
+.cm-s-moxer .cm-meta {
+ color: #FFCB6B;
+}
+
+.cm-s-moxer .cm-attribute {
+ color: #C792EA;
+}
+
+.cm-s-moxer .cm-property {
+ color: #81C5DA;
+}
+
+.cm-s-moxer .cm-qualifier {
+ color: #DECB6B;
+}
+
+.cm-s-moxer .cm-variable-3,
+.cm-s-moxer .cm-type {
+ color: #DECB6B;
+}
+
+
+.cm-s-moxer .cm-error {
+ color: rgba(255, 255, 255, 1.0);
+ background-color: #FF5370;
+}
+
+.cm-s-moxer .CodeMirror-matchingbracket {
+ text-decoration: underline;
+ color: white !important;
+}
\ No newline at end of file
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/neat.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/neat.css
new file mode 100644
index 0000000000..4267b1a37d
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/neat.css
@@ -0,0 +1,12 @@
+.cm-s-neat span.cm-comment { color: #a86; }
+.cm-s-neat span.cm-keyword { line-height: 1em; font-weight: bold; color: blue; }
+.cm-s-neat span.cm-string { color: #a22; }
+.cm-s-neat span.cm-builtin { line-height: 1em; font-weight: bold; color: #077; }
+.cm-s-neat span.cm-special { line-height: 1em; font-weight: bold; color: #0aa; }
+.cm-s-neat span.cm-variable { color: black; }
+.cm-s-neat span.cm-number, .cm-s-neat span.cm-atom { color: #3a3; }
+.cm-s-neat span.cm-meta { color: #555; }
+.cm-s-neat span.cm-link { color: #3a3; }
+
+.cm-s-neat .CodeMirror-activeline-background { background: #e8f2ff; }
+.cm-s-neat .CodeMirror-matchingbracket { outline:1px solid grey; color:black !important; }
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/neo.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/neo.css
new file mode 100644
index 0000000000..b28d5c65fa
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/neo.css
@@ -0,0 +1,43 @@
+/* neo theme for codemirror */
+
+/* Color scheme */
+
+.cm-s-neo.CodeMirror {
+ background-color:#ffffff;
+ color:#2e383c;
+ line-height:1.4375;
+}
+.cm-s-neo .cm-comment { color:#75787b; }
+.cm-s-neo .cm-keyword, .cm-s-neo .cm-property { color:#1d75b3; }
+.cm-s-neo .cm-atom,.cm-s-neo .cm-number { color:#75438a; }
+.cm-s-neo .cm-node,.cm-s-neo .cm-tag { color:#9c3328; }
+.cm-s-neo .cm-string { color:#b35e14; }
+.cm-s-neo .cm-variable,.cm-s-neo .cm-qualifier { color:#047d65; }
+
+
+/* Editor styling */
+
+.cm-s-neo pre {
+ padding:0;
+}
+
+.cm-s-neo .CodeMirror-gutters {
+ border:none;
+ border-right:10px solid transparent;
+ background-color:transparent;
+}
+
+.cm-s-neo .CodeMirror-linenumber {
+ padding:0;
+ color:#e0e2e5;
+}
+
+.cm-s-neo .CodeMirror-guttermarker { color: #1d75b3; }
+.cm-s-neo .CodeMirror-guttermarker-subtle { color: #e0e2e5; }
+
+.cm-s-neo .CodeMirror-cursor {
+ width: auto;
+ border: 0;
+ background: rgba(155,157,162,0.37);
+ z-index: 1;
+}
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/night.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/night.css
new file mode 100644
index 0000000000..f631bf42c7
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/night.css
@@ -0,0 +1,27 @@
+/* Loosely based on the Midnight Textmate theme */
+
+.cm-s-night.CodeMirror { background: #0a001f; color: #f8f8f8; }
+.cm-s-night div.CodeMirror-selected { background: #447; }
+.cm-s-night .CodeMirror-line::selection, .cm-s-night .CodeMirror-line > span::selection, .cm-s-night .CodeMirror-line > span > span::selection { background: rgba(68, 68, 119, .99); }
+.cm-s-night .CodeMirror-line::-moz-selection, .cm-s-night .CodeMirror-line > span::-moz-selection, .cm-s-night .CodeMirror-line > span > span::-moz-selection { background: rgba(68, 68, 119, .99); }
+.cm-s-night .CodeMirror-gutters { background: #0a001f; border-right: 1px solid #aaa; }
+.cm-s-night .CodeMirror-guttermarker { color: white; }
+.cm-s-night .CodeMirror-guttermarker-subtle { color: #bbb; }
+.cm-s-night .CodeMirror-linenumber { color: #f8f8f8; }
+.cm-s-night .CodeMirror-cursor { border-left: 1px solid white; }
+
+.cm-s-night span.cm-comment { color: #8900d1; }
+.cm-s-night span.cm-atom { color: #845dc4; }
+.cm-s-night span.cm-number, .cm-s-night span.cm-attribute { color: #ffd500; }
+.cm-s-night span.cm-keyword { color: #599eff; }
+.cm-s-night span.cm-string { color: #37f14a; }
+.cm-s-night span.cm-meta { color: #7678e2; }
+.cm-s-night span.cm-variable-2, .cm-s-night span.cm-tag { color: #99b2ff; }
+.cm-s-night span.cm-variable-3, .cm-s-night span.cm-def, .cm-s-night span.cm-type { color: white; }
+.cm-s-night span.cm-bracket { color: #8da6ce; }
+.cm-s-night span.cm-builtin, .cm-s-night span.cm-special { color: #ff9e59; }
+.cm-s-night span.cm-link { color: #845dc4; }
+.cm-s-night span.cm-error { color: #9d1e15; }
+
+.cm-s-night .CodeMirror-activeline-background { background: #1C005A; }
+.cm-s-night .CodeMirror-matchingbracket { outline:1px solid grey; color:white !important; }
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/nord.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/nord.css
new file mode 100644
index 0000000000..41a8ad7782
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/nord.css
@@ -0,0 +1,42 @@
+/* Based on arcticicestudio's Nord theme */
+/* https://github.com/arcticicestudio/nord */
+
+.cm-s-nord.CodeMirror { background: #2e3440; color: #d8dee9; }
+.cm-s-nord div.CodeMirror-selected { background: #434c5e; }
+.cm-s-nord .CodeMirror-line::selection, .cm-s-nord .CodeMirror-line > span::selection, .cm-s-nord .CodeMirror-line > span > span::selection { background: #3b4252; }
+.cm-s-nord .CodeMirror-line::-moz-selection, .cm-s-nord .CodeMirror-line > span::-moz-selection, .cm-s-nord .CodeMirror-line > span > span::-moz-selection { background: #3b4252; }
+.cm-s-nord .CodeMirror-gutters { background: #2e3440; border-right: 0px; }
+.cm-s-nord .CodeMirror-guttermarker { color: #4c566a; }
+.cm-s-nord .CodeMirror-guttermarker-subtle { color: #4c566a; }
+.cm-s-nord .CodeMirror-linenumber { color: #4c566a; }
+.cm-s-nord .CodeMirror-cursor { border-left: 1px solid #f8f8f0; }
+
+.cm-s-nord span.cm-comment { color: #4c566a; }
+.cm-s-nord span.cm-atom { color: #b48ead; }
+.cm-s-nord span.cm-number { color: #b48ead; }
+
+.cm-s-nord span.cm-comment.cm-attribute { color: #97b757; }
+.cm-s-nord span.cm-comment.cm-def { color: #bc9262; }
+.cm-s-nord span.cm-comment.cm-tag { color: #bc6283; }
+.cm-s-nord span.cm-comment.cm-type { color: #5998a6; }
+
+.cm-s-nord span.cm-property, .cm-s-nord span.cm-attribute { color: #8FBCBB; }
+.cm-s-nord span.cm-keyword { color: #81A1C1; }
+.cm-s-nord span.cm-builtin { color: #81A1C1; }
+.cm-s-nord span.cm-string { color: #A3BE8C; }
+
+.cm-s-nord span.cm-variable { color: #d8dee9; }
+.cm-s-nord span.cm-variable-2 { color: #d8dee9; }
+.cm-s-nord span.cm-variable-3, .cm-s-nord span.cm-type { color: #d8dee9; }
+.cm-s-nord span.cm-def { color: #8FBCBB; }
+.cm-s-nord span.cm-bracket { color: #81A1C1; }
+.cm-s-nord span.cm-tag { color: #bf616a; }
+.cm-s-nord span.cm-header { color: #b48ead; }
+.cm-s-nord span.cm-link { color: #b48ead; }
+.cm-s-nord span.cm-error { background: #bf616a; color: #f8f8f0; }
+
+.cm-s-nord .CodeMirror-activeline-background { background: #3b4252; }
+.cm-s-nord .CodeMirror-matchingbracket {
+ text-decoration: underline;
+ color: white !important;
+}
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/oceanic-next.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/oceanic-next.css
new file mode 100644
index 0000000000..f3d0d08acb
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/oceanic-next.css
@@ -0,0 +1,46 @@
+/*
+
+ Name: oceanic-next
+ Author: Filype Pereira (https://github.com/fpereira1)
+
+ Original oceanic-next color scheme by Dmitri Voronianski (https://github.com/voronianski/oceanic-next-color-scheme)
+
+*/
+
+.cm-s-oceanic-next.CodeMirror { background: #304148; color: #f8f8f2; }
+.cm-s-oceanic-next div.CodeMirror-selected { background: rgba(101, 115, 126, 0.33); }
+.cm-s-oceanic-next .CodeMirror-line::selection, .cm-s-oceanic-next .CodeMirror-line > span::selection, .cm-s-oceanic-next .CodeMirror-line > span > span::selection { background: rgba(101, 115, 126, 0.33); }
+.cm-s-oceanic-next .CodeMirror-line::-moz-selection, .cm-s-oceanic-next .CodeMirror-line > span::-moz-selection, .cm-s-oceanic-next .CodeMirror-line > span > span::-moz-selection { background: rgba(101, 115, 126, 0.33); }
+.cm-s-oceanic-next .CodeMirror-gutters { background: #304148; border-right: 10px; }
+.cm-s-oceanic-next .CodeMirror-guttermarker { color: white; }
+.cm-s-oceanic-next .CodeMirror-guttermarker-subtle { color: #d0d0d0; }
+.cm-s-oceanic-next .CodeMirror-linenumber { color: #d0d0d0; }
+.cm-s-oceanic-next .CodeMirror-cursor { border-left: 1px solid #f8f8f0; }
+.cm-s-oceanic-next.cm-fat-cursor .CodeMirror-cursor { background-color: #a2a8a175 !important; }
+.cm-s-oceanic-next .cm-animate-fat-cursor { background-color: #a2a8a175 !important; }
+
+.cm-s-oceanic-next span.cm-comment { color: #65737E; }
+.cm-s-oceanic-next span.cm-atom { color: #C594C5; }
+.cm-s-oceanic-next span.cm-number { color: #F99157; }
+
+.cm-s-oceanic-next span.cm-property { color: #99C794; }
+.cm-s-oceanic-next span.cm-attribute,
+.cm-s-oceanic-next span.cm-keyword { color: #C594C5; }
+.cm-s-oceanic-next span.cm-builtin { color: #66d9ef; }
+.cm-s-oceanic-next span.cm-string { color: #99C794; }
+
+.cm-s-oceanic-next span.cm-variable,
+.cm-s-oceanic-next span.cm-variable-2,
+.cm-s-oceanic-next span.cm-variable-3 { color: #f8f8f2; }
+.cm-s-oceanic-next span.cm-def { color: #6699CC; }
+.cm-s-oceanic-next span.cm-bracket { color: #5FB3B3; }
+.cm-s-oceanic-next span.cm-tag { color: #C594C5; }
+.cm-s-oceanic-next span.cm-header { color: #C594C5; }
+.cm-s-oceanic-next span.cm-link { color: #C594C5; }
+.cm-s-oceanic-next span.cm-error { background: #C594C5; color: #f8f8f0; }
+
+.cm-s-oceanic-next .CodeMirror-activeline-background { background: rgba(101, 115, 126, 0.33); }
+.cm-s-oceanic-next .CodeMirror-matchingbracket {
+ text-decoration: underline;
+ color: white !important;
+}
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/panda-syntax.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/panda-syntax.css
new file mode 100644
index 0000000000..de14e91124
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/panda-syntax.css
@@ -0,0 +1,85 @@
+/*
+ Name: Panda Syntax
+ Author: Siamak Mokhtari (http://github.com/siamak/)
+ CodeMirror template by Siamak Mokhtari (https://github.com/siamak/atom-panda-syntax)
+*/
+.cm-s-panda-syntax {
+ background: #292A2B;
+ color: #E6E6E6;
+ line-height: 1.5;
+ font-family: 'Operator Mono', 'Source Code Pro', Menlo, Monaco, Consolas, Courier New, monospace;
+}
+.cm-s-panda-syntax .CodeMirror-cursor { border-color: #ff2c6d; }
+.cm-s-panda-syntax .CodeMirror-activeline-background {
+ background: rgba(99, 123, 156, 0.1);
+}
+.cm-s-panda-syntax .CodeMirror-selected {
+ background: #FFF;
+}
+.cm-s-panda-syntax .cm-comment {
+ font-style: italic;
+ color: #676B79;
+}
+.cm-s-panda-syntax .cm-operator {
+ color: #f3f3f3;
+}
+.cm-s-panda-syntax .cm-string {
+ color: #19F9D8;
+}
+.cm-s-panda-syntax .cm-string-2 {
+ color: #FFB86C;
+}
+
+.cm-s-panda-syntax .cm-tag {
+ color: #ff2c6d;
+}
+.cm-s-panda-syntax .cm-meta {
+ color: #b084eb;
+}
+
+.cm-s-panda-syntax .cm-number {
+ color: #FFB86C;
+}
+.cm-s-panda-syntax .cm-atom {
+ color: #ff2c6d;
+}
+.cm-s-panda-syntax .cm-keyword {
+ color: #FF75B5;
+}
+.cm-s-panda-syntax .cm-variable {
+ color: #ffb86c;
+}
+.cm-s-panda-syntax .cm-variable-2 {
+ color: #ff9ac1;
+}
+.cm-s-panda-syntax .cm-variable-3, .cm-s-panda-syntax .cm-type {
+ color: #ff9ac1;
+}
+
+.cm-s-panda-syntax .cm-def {
+ color: #e6e6e6;
+}
+.cm-s-panda-syntax .cm-property {
+ color: #f3f3f3;
+}
+.cm-s-panda-syntax .cm-unit {
+ color: #ffb86c;
+}
+
+.cm-s-panda-syntax .cm-attribute {
+ color: #ffb86c;
+}
+
+.cm-s-panda-syntax .CodeMirror-matchingbracket {
+ border-bottom: 1px dotted #19F9D8;
+ padding-bottom: 2px;
+ color: #e6e6e6;
+}
+.cm-s-panda-syntax .CodeMirror-gutters {
+ background: #292a2b;
+ border-right-color: rgba(255, 255, 255, 0.1);
+}
+.cm-s-panda-syntax .CodeMirror-linenumber {
+ color: #e6e6e6;
+ opacity: 0.6;
+}
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/paraiso-dark.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/paraiso-dark.css
new file mode 100644
index 0000000000..aa9d207e6d
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/paraiso-dark.css
@@ -0,0 +1,38 @@
+/*
+
+ Name: Paraíso (Dark)
+ Author: Jan T. Sott
+
+ Color scheme by Jan T. Sott (https://github.com/idleberg/Paraiso-CodeMirror)
+ Inspired by the art of Rubens LP (http://www.rubenslp.com.br)
+
+*/
+
+.cm-s-paraiso-dark.CodeMirror { background: #2f1e2e; color: #b9b6b0; }
+.cm-s-paraiso-dark div.CodeMirror-selected { background: #41323f; }
+.cm-s-paraiso-dark .CodeMirror-line::selection, .cm-s-paraiso-dark .CodeMirror-line > span::selection, .cm-s-paraiso-dark .CodeMirror-line > span > span::selection { background: rgba(65, 50, 63, .99); }
+.cm-s-paraiso-dark .CodeMirror-line::-moz-selection, .cm-s-paraiso-dark .CodeMirror-line > span::-moz-selection, .cm-s-paraiso-dark .CodeMirror-line > span > span::-moz-selection { background: rgba(65, 50, 63, .99); }
+.cm-s-paraiso-dark .CodeMirror-gutters { background: #2f1e2e; border-right: 0px; }
+.cm-s-paraiso-dark .CodeMirror-guttermarker { color: #ef6155; }
+.cm-s-paraiso-dark .CodeMirror-guttermarker-subtle { color: #776e71; }
+.cm-s-paraiso-dark .CodeMirror-linenumber { color: #776e71; }
+.cm-s-paraiso-dark .CodeMirror-cursor { border-left: 1px solid #8d8687; }
+
+.cm-s-paraiso-dark span.cm-comment { color: #e96ba8; }
+.cm-s-paraiso-dark span.cm-atom { color: #815ba4; }
+.cm-s-paraiso-dark span.cm-number { color: #815ba4; }
+
+.cm-s-paraiso-dark span.cm-property, .cm-s-paraiso-dark span.cm-attribute { color: #48b685; }
+.cm-s-paraiso-dark span.cm-keyword { color: #ef6155; }
+.cm-s-paraiso-dark span.cm-string { color: #fec418; }
+
+.cm-s-paraiso-dark span.cm-variable { color: #48b685; }
+.cm-s-paraiso-dark span.cm-variable-2 { color: #06b6ef; }
+.cm-s-paraiso-dark span.cm-def { color: #f99b15; }
+.cm-s-paraiso-dark span.cm-bracket { color: #b9b6b0; }
+.cm-s-paraiso-dark span.cm-tag { color: #ef6155; }
+.cm-s-paraiso-dark span.cm-link { color: #815ba4; }
+.cm-s-paraiso-dark span.cm-error { background: #ef6155; color: #8d8687; }
+
+.cm-s-paraiso-dark .CodeMirror-activeline-background { background: #4D344A; }
+.cm-s-paraiso-dark .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; }
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/paraiso-light.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/paraiso-light.css
new file mode 100644
index 0000000000..ae0c755f89
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/paraiso-light.css
@@ -0,0 +1,38 @@
+/*
+
+ Name: Paraíso (Light)
+ Author: Jan T. Sott
+
+ Color scheme by Jan T. Sott (https://github.com/idleberg/Paraiso-CodeMirror)
+ Inspired by the art of Rubens LP (http://www.rubenslp.com.br)
+
+*/
+
+.cm-s-paraiso-light.CodeMirror { background: #e7e9db; color: #41323f; }
+.cm-s-paraiso-light div.CodeMirror-selected { background: #b9b6b0; }
+.cm-s-paraiso-light .CodeMirror-line::selection, .cm-s-paraiso-light .CodeMirror-line > span::selection, .cm-s-paraiso-light .CodeMirror-line > span > span::selection { background: #b9b6b0; }
+.cm-s-paraiso-light .CodeMirror-line::-moz-selection, .cm-s-paraiso-light .CodeMirror-line > span::-moz-selection, .cm-s-paraiso-light .CodeMirror-line > span > span::-moz-selection { background: #b9b6b0; }
+.cm-s-paraiso-light .CodeMirror-gutters { background: #e7e9db; border-right: 0px; }
+.cm-s-paraiso-light .CodeMirror-guttermarker { color: black; }
+.cm-s-paraiso-light .CodeMirror-guttermarker-subtle { color: #8d8687; }
+.cm-s-paraiso-light .CodeMirror-linenumber { color: #8d8687; }
+.cm-s-paraiso-light .CodeMirror-cursor { border-left: 1px solid #776e71; }
+
+.cm-s-paraiso-light span.cm-comment { color: #e96ba8; }
+.cm-s-paraiso-light span.cm-atom { color: #815ba4; }
+.cm-s-paraiso-light span.cm-number { color: #815ba4; }
+
+.cm-s-paraiso-light span.cm-property, .cm-s-paraiso-light span.cm-attribute { color: #48b685; }
+.cm-s-paraiso-light span.cm-keyword { color: #ef6155; }
+.cm-s-paraiso-light span.cm-string { color: #fec418; }
+
+.cm-s-paraiso-light span.cm-variable { color: #48b685; }
+.cm-s-paraiso-light span.cm-variable-2 { color: #06b6ef; }
+.cm-s-paraiso-light span.cm-def { color: #f99b15; }
+.cm-s-paraiso-light span.cm-bracket { color: #41323f; }
+.cm-s-paraiso-light span.cm-tag { color: #ef6155; }
+.cm-s-paraiso-light span.cm-link { color: #815ba4; }
+.cm-s-paraiso-light span.cm-error { background: #ef6155; color: #776e71; }
+
+.cm-s-paraiso-light .CodeMirror-activeline-background { background: #CFD1C4; }
+.cm-s-paraiso-light .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; }
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/pastel-on-dark.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/pastel-on-dark.css
new file mode 100644
index 0000000000..60435dd15e
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/pastel-on-dark.css
@@ -0,0 +1,52 @@
+/**
+ * Pastel On Dark theme ported from ACE editor
+ * @license MIT
+ * @copyright AtomicPages LLC 2014
+ * @author Dennis Thompson, AtomicPages LLC
+ * @version 1.1
+ * @source https://github.com/atomicpages/codemirror-pastel-on-dark-theme
+ */
+
+.cm-s-pastel-on-dark.CodeMirror {
+ background: #2c2827;
+ color: #8F938F;
+ line-height: 1.5;
+}
+.cm-s-pastel-on-dark div.CodeMirror-selected { background: rgba(221,240,255,0.2); }
+.cm-s-pastel-on-dark .CodeMirror-line::selection, .cm-s-pastel-on-dark .CodeMirror-line > span::selection, .cm-s-pastel-on-dark .CodeMirror-line > span > span::selection { background: rgba(221,240,255,0.2); }
+.cm-s-pastel-on-dark .CodeMirror-line::-moz-selection, .cm-s-pastel-on-dark .CodeMirror-line > span::-moz-selection, .cm-s-pastel-on-dark .CodeMirror-line > span > span::-moz-selection { background: rgba(221,240,255,0.2); }
+
+.cm-s-pastel-on-dark .CodeMirror-gutters {
+ background: #34302f;
+ border-right: 0px;
+ padding: 0 3px;
+}
+.cm-s-pastel-on-dark .CodeMirror-guttermarker { color: white; }
+.cm-s-pastel-on-dark .CodeMirror-guttermarker-subtle { color: #8F938F; }
+.cm-s-pastel-on-dark .CodeMirror-linenumber { color: #8F938F; }
+.cm-s-pastel-on-dark .CodeMirror-cursor { border-left: 1px solid #A7A7A7; }
+.cm-s-pastel-on-dark span.cm-comment { color: #A6C6FF; }
+.cm-s-pastel-on-dark span.cm-atom { color: #DE8E30; }
+.cm-s-pastel-on-dark span.cm-number { color: #CCCCCC; }
+.cm-s-pastel-on-dark span.cm-property { color: #8F938F; }
+.cm-s-pastel-on-dark span.cm-attribute { color: #a6e22e; }
+.cm-s-pastel-on-dark span.cm-keyword { color: #AEB2F8; }
+.cm-s-pastel-on-dark span.cm-string { color: #66A968; }
+.cm-s-pastel-on-dark span.cm-variable { color: #AEB2F8; }
+.cm-s-pastel-on-dark span.cm-variable-2 { color: #BEBF55; }
+.cm-s-pastel-on-dark span.cm-variable-3, .cm-s-pastel-on-dark span.cm-type { color: #DE8E30; }
+.cm-s-pastel-on-dark span.cm-def { color: #757aD8; }
+.cm-s-pastel-on-dark span.cm-bracket { color: #f8f8f2; }
+.cm-s-pastel-on-dark span.cm-tag { color: #C1C144; }
+.cm-s-pastel-on-dark span.cm-link { color: #ae81ff; }
+.cm-s-pastel-on-dark span.cm-qualifier,.cm-s-pastel-on-dark span.cm-builtin { color: #C1C144; }
+.cm-s-pastel-on-dark span.cm-error {
+ background: #757aD8;
+ color: #f8f8f0;
+}
+.cm-s-pastel-on-dark .CodeMirror-activeline-background { background: rgba(255, 255, 255, 0.031); }
+.cm-s-pastel-on-dark .CodeMirror-matchingbracket {
+ border: 1px solid rgba(255,255,255,0.25);
+ color: #8F938F !important;
+ margin: -1px -1px 0 -1px;
+}
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/railscasts.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/railscasts.css
new file mode 100644
index 0000000000..aeff0449d5
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/railscasts.css
@@ -0,0 +1,34 @@
+/*
+
+ Name: Railscasts
+ Author: Ryan Bates (http://railscasts.com)
+
+ CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror)
+ Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16)
+
+*/
+
+.cm-s-railscasts.CodeMirror {background: #2b2b2b; color: #f4f1ed;}
+.cm-s-railscasts div.CodeMirror-selected {background: #272935 !important;}
+.cm-s-railscasts .CodeMirror-gutters {background: #2b2b2b; border-right: 0px;}
+.cm-s-railscasts .CodeMirror-linenumber {color: #5a647e;}
+.cm-s-railscasts .CodeMirror-cursor {border-left: 1px solid #d4cfc9 !important;}
+
+.cm-s-railscasts span.cm-comment {color: #bc9458;}
+.cm-s-railscasts span.cm-atom {color: #b6b3eb;}
+.cm-s-railscasts span.cm-number {color: #b6b3eb;}
+
+.cm-s-railscasts span.cm-property, .cm-s-railscasts span.cm-attribute {color: #a5c261;}
+.cm-s-railscasts span.cm-keyword {color: #da4939;}
+.cm-s-railscasts span.cm-string {color: #ffc66d;}
+
+.cm-s-railscasts span.cm-variable {color: #a5c261;}
+.cm-s-railscasts span.cm-variable-2 {color: #6d9cbe;}
+.cm-s-railscasts span.cm-def {color: #cc7833;}
+.cm-s-railscasts span.cm-error {background: #da4939; color: #d4cfc9;}
+.cm-s-railscasts span.cm-bracket {color: #f4f1ed;}
+.cm-s-railscasts span.cm-tag {color: #da4939;}
+.cm-s-railscasts span.cm-link {color: #b6b3eb;}
+
+.cm-s-railscasts .CodeMirror-matchingbracket { text-decoration: underline; color: white !important;}
+.cm-s-railscasts .CodeMirror-activeline-background { background: #303040; }
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/rubyblue.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/rubyblue.css
new file mode 100644
index 0000000000..1f181b06ec
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/rubyblue.css
@@ -0,0 +1,25 @@
+.cm-s-rubyblue.CodeMirror { background: #112435; color: white; }
+.cm-s-rubyblue div.CodeMirror-selected { background: #38566F; }
+.cm-s-rubyblue .CodeMirror-line::selection, .cm-s-rubyblue .CodeMirror-line > span::selection, .cm-s-rubyblue .CodeMirror-line > span > span::selection { background: rgba(56, 86, 111, 0.99); }
+.cm-s-rubyblue .CodeMirror-line::-moz-selection, .cm-s-rubyblue .CodeMirror-line > span::-moz-selection, .cm-s-rubyblue .CodeMirror-line > span > span::-moz-selection { background: rgba(56, 86, 111, 0.99); }
+.cm-s-rubyblue .CodeMirror-gutters { background: #1F4661; border-right: 7px solid #3E7087; }
+.cm-s-rubyblue .CodeMirror-guttermarker { color: white; }
+.cm-s-rubyblue .CodeMirror-guttermarker-subtle { color: #3E7087; }
+.cm-s-rubyblue .CodeMirror-linenumber { color: white; }
+.cm-s-rubyblue .CodeMirror-cursor { border-left: 1px solid white; }
+
+.cm-s-rubyblue span.cm-comment { color: #999; font-style:italic; line-height: 1em; }
+.cm-s-rubyblue span.cm-atom { color: #F4C20B; }
+.cm-s-rubyblue span.cm-number, .cm-s-rubyblue span.cm-attribute { color: #82C6E0; }
+.cm-s-rubyblue span.cm-keyword { color: #F0F; }
+.cm-s-rubyblue span.cm-string { color: #F08047; }
+.cm-s-rubyblue span.cm-meta { color: #F0F; }
+.cm-s-rubyblue span.cm-variable-2, .cm-s-rubyblue span.cm-tag { color: #7BD827; }
+.cm-s-rubyblue span.cm-variable-3, .cm-s-rubyblue span.cm-def, .cm-s-rubyblue span.cm-type { color: white; }
+.cm-s-rubyblue span.cm-bracket { color: #F0F; }
+.cm-s-rubyblue span.cm-link { color: #F4C20B; }
+.cm-s-rubyblue span.CodeMirror-matchingbracket { color:#F0F !important; }
+.cm-s-rubyblue span.cm-builtin, .cm-s-rubyblue span.cm-special { color: #FF9D00; }
+.cm-s-rubyblue span.cm-error { color: #AF2018; }
+
+.cm-s-rubyblue .CodeMirror-activeline-background { background: #173047; }
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/seti.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/seti.css
new file mode 100644
index 0000000000..814f76f7de
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/seti.css
@@ -0,0 +1,44 @@
+/*
+
+ Name: seti
+ Author: Michael Kaminsky (http://github.com/mkaminsky11)
+
+ Original seti color scheme by Jesse Weed (https://github.com/jesseweed/seti-syntax)
+
+*/
+
+
+.cm-s-seti.CodeMirror {
+ background-color: #151718 !important;
+ color: #CFD2D1 !important;
+ border: none;
+}
+.cm-s-seti .CodeMirror-gutters {
+ color: #404b53;
+ background-color: #0E1112;
+ border: none;
+}
+.cm-s-seti .CodeMirror-cursor { border-left: solid thin #f8f8f0; }
+.cm-s-seti .CodeMirror-linenumber { color: #6D8A88; }
+.cm-s-seti.CodeMirror-focused div.CodeMirror-selected { background: rgba(255, 255, 255, 0.10); }
+.cm-s-seti .CodeMirror-line::selection, .cm-s-seti .CodeMirror-line > span::selection, .cm-s-seti .CodeMirror-line > span > span::selection { background: rgba(255, 255, 255, 0.10); }
+.cm-s-seti .CodeMirror-line::-moz-selection, .cm-s-seti .CodeMirror-line > span::-moz-selection, .cm-s-seti .CodeMirror-line > span > span::-moz-selection { background: rgba(255, 255, 255, 0.10); }
+.cm-s-seti span.cm-comment { color: #41535b; }
+.cm-s-seti span.cm-string, .cm-s-seti span.cm-string-2 { color: #55b5db; }
+.cm-s-seti span.cm-number { color: #cd3f45; }
+.cm-s-seti span.cm-variable { color: #55b5db; }
+.cm-s-seti span.cm-variable-2 { color: #a074c4; }
+.cm-s-seti span.cm-def { color: #55b5db; }
+.cm-s-seti span.cm-keyword { color: #ff79c6; }
+.cm-s-seti span.cm-operator { color: #9fca56; }
+.cm-s-seti span.cm-keyword { color: #e6cd69; }
+.cm-s-seti span.cm-atom { color: #cd3f45; }
+.cm-s-seti span.cm-meta { color: #55b5db; }
+.cm-s-seti span.cm-tag { color: #55b5db; }
+.cm-s-seti span.cm-attribute { color: #9fca56; }
+.cm-s-seti span.cm-qualifier { color: #9fca56; }
+.cm-s-seti span.cm-property { color: #a074c4; }
+.cm-s-seti span.cm-variable-3, .cm-s-seti span.cm-type { color: #9fca56; }
+.cm-s-seti span.cm-builtin { color: #9fca56; }
+.cm-s-seti .CodeMirror-activeline-background { background: #101213; }
+.cm-s-seti .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; }
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/shadowfox.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/shadowfox.css
new file mode 100644
index 0000000000..32d59b139a
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/shadowfox.css
@@ -0,0 +1,52 @@
+/*
+
+ Name: shadowfox
+ Author: overdodactyl (http://github.com/overdodactyl)
+
+ Original shadowfox color scheme by Firefox
+
+*/
+
+.cm-s-shadowfox.CodeMirror { background: #2a2a2e; color: #b1b1b3; }
+.cm-s-shadowfox div.CodeMirror-selected { background: #353B48; }
+.cm-s-shadowfox .CodeMirror-line::selection, .cm-s-shadowfox .CodeMirror-line > span::selection, .cm-s-shadowfox .CodeMirror-line > span > span::selection { background: #353B48; }
+.cm-s-shadowfox .CodeMirror-line::-moz-selection, .cm-s-shadowfox .CodeMirror-line > span::-moz-selection, .cm-s-shadowfox .CodeMirror-line > span > span::-moz-selection { background: #353B48; }
+.cm-s-shadowfox .CodeMirror-gutters { background: #0c0c0d ; border-right: 1px solid #0c0c0d; }
+.cm-s-shadowfox .CodeMirror-guttermarker { color: #555; }
+.cm-s-shadowfox .CodeMirror-linenumber { color: #939393; }
+.cm-s-shadowfox .CodeMirror-cursor { border-left: 1px solid #fff; }
+
+.cm-s-shadowfox span.cm-comment { color: #939393; }
+.cm-s-shadowfox span.cm-atom { color: #FF7DE9; }
+.cm-s-shadowfox span.cm-quote { color: #FF7DE9; }
+.cm-s-shadowfox span.cm-builtin { color: #FF7DE9; }
+.cm-s-shadowfox span.cm-attribute { color: #FF7DE9; }
+.cm-s-shadowfox span.cm-keyword { color: #FF7DE9; }
+.cm-s-shadowfox span.cm-error { color: #FF7DE9; }
+
+.cm-s-shadowfox span.cm-number { color: #6B89FF; }
+.cm-s-shadowfox span.cm-string { color: #6B89FF; }
+.cm-s-shadowfox span.cm-string-2 { color: #6B89FF; }
+
+.cm-s-shadowfox span.cm-meta { color: #939393; }
+.cm-s-shadowfox span.cm-hr { color: #939393; }
+
+.cm-s-shadowfox span.cm-header { color: #75BFFF; }
+.cm-s-shadowfox span.cm-qualifier { color: #75BFFF; }
+.cm-s-shadowfox span.cm-variable-2 { color: #75BFFF; }
+
+.cm-s-shadowfox span.cm-property { color: #86DE74; }
+
+.cm-s-shadowfox span.cm-def { color: #75BFFF; }
+.cm-s-shadowfox span.cm-bracket { color: #75BFFF; }
+.cm-s-shadowfox span.cm-tag { color: #75BFFF; }
+.cm-s-shadowfox span.cm-link:visited { color: #75BFFF; }
+
+.cm-s-shadowfox span.cm-variable { color: #B98EFF; }
+.cm-s-shadowfox span.cm-variable-3 { color: #d7d7db; }
+.cm-s-shadowfox span.cm-link { color: #737373; }
+.cm-s-shadowfox span.cm-operator { color: #b1b1b3; }
+.cm-s-shadowfox span.cm-special { color: #d7d7db; }
+
+.cm-s-shadowfox .CodeMirror-activeline-background { background: rgba(185, 215, 253, .15) }
+.cm-s-shadowfox .CodeMirror-matchingbracket { outline: solid 1px rgba(255, 255, 255, .25); color: white !important; }
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/solarized.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/solarized.css
new file mode 100644
index 0000000000..e978fec9b0
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/solarized.css
@@ -0,0 +1,165 @@
+/*
+Solarized theme for code-mirror
+http://ethanschoonover.com/solarized
+*/
+
+/*
+Solarized color palette
+http://ethanschoonover.com/solarized/img/solarized-palette.png
+*/
+
+.solarized.base03 { color: #002b36; }
+.solarized.base02 { color: #073642; }
+.solarized.base01 { color: #586e75; }
+.solarized.base00 { color: #657b83; }
+.solarized.base0 { color: #839496; }
+.solarized.base1 { color: #93a1a1; }
+.solarized.base2 { color: #eee8d5; }
+.solarized.base3 { color: #fdf6e3; }
+.solarized.solar-yellow { color: #b58900; }
+.solarized.solar-orange { color: #cb4b16; }
+.solarized.solar-red { color: #dc322f; }
+.solarized.solar-magenta { color: #d33682; }
+.solarized.solar-violet { color: #6c71c4; }
+.solarized.solar-blue { color: #268bd2; }
+.solarized.solar-cyan { color: #2aa198; }
+.solarized.solar-green { color: #859900; }
+
+/* Color scheme for code-mirror */
+
+.cm-s-solarized {
+ line-height: 1.45em;
+ color-profile: sRGB;
+ rendering-intent: auto;
+}
+.cm-s-solarized.cm-s-dark {
+ color: #839496;
+ background-color: #002b36;
+}
+.cm-s-solarized.cm-s-light {
+ background-color: #fdf6e3;
+ color: #657b83;
+}
+
+.cm-s-solarized .CodeMirror-widget {
+ text-shadow: none;
+}
+
+.cm-s-solarized .cm-header { color: #586e75; }
+.cm-s-solarized .cm-quote { color: #93a1a1; }
+
+.cm-s-solarized .cm-keyword { color: #cb4b16; }
+.cm-s-solarized .cm-atom { color: #d33682; }
+.cm-s-solarized .cm-number { color: #d33682; }
+.cm-s-solarized .cm-def { color: #2aa198; }
+
+.cm-s-solarized .cm-variable { color: #839496; }
+.cm-s-solarized .cm-variable-2 { color: #b58900; }
+.cm-s-solarized .cm-variable-3, .cm-s-solarized .cm-type { color: #6c71c4; }
+
+.cm-s-solarized .cm-property { color: #2aa198; }
+.cm-s-solarized .cm-operator { color: #6c71c4; }
+
+.cm-s-solarized .cm-comment { color: #586e75; font-style:italic; }
+
+.cm-s-solarized .cm-string { color: #859900; }
+.cm-s-solarized .cm-string-2 { color: #b58900; }
+
+.cm-s-solarized .cm-meta { color: #859900; }
+.cm-s-solarized .cm-qualifier { color: #b58900; }
+.cm-s-solarized .cm-builtin { color: #d33682; }
+.cm-s-solarized .cm-bracket { color: #cb4b16; }
+.cm-s-solarized .CodeMirror-matchingbracket { color: #859900; }
+.cm-s-solarized .CodeMirror-nonmatchingbracket { color: #dc322f; }
+.cm-s-solarized .cm-tag { color: #93a1a1; }
+.cm-s-solarized .cm-attribute { color: #2aa198; }
+.cm-s-solarized .cm-hr {
+ color: transparent;
+ border-top: 1px solid #586e75;
+ display: block;
+}
+.cm-s-solarized .cm-link { color: #93a1a1; cursor: pointer; }
+.cm-s-solarized .cm-special { color: #6c71c4; }
+.cm-s-solarized .cm-em {
+ color: #999;
+ text-decoration: underline;
+ text-decoration-style: dotted;
+}
+.cm-s-solarized .cm-error,
+.cm-s-solarized .cm-invalidchar {
+ color: #586e75;
+ border-bottom: 1px dotted #dc322f;
+}
+
+.cm-s-solarized.cm-s-dark div.CodeMirror-selected { background: #073642; }
+.cm-s-solarized.cm-s-dark.CodeMirror ::selection { background: rgba(7, 54, 66, 0.99); }
+.cm-s-solarized.cm-s-dark .CodeMirror-line::-moz-selection, .cm-s-dark .CodeMirror-line > span::-moz-selection, .cm-s-dark .CodeMirror-line > span > span::-moz-selection { background: rgba(7, 54, 66, 0.99); }
+
+.cm-s-solarized.cm-s-light div.CodeMirror-selected { background: #eee8d5; }
+.cm-s-solarized.cm-s-light .CodeMirror-line::selection, .cm-s-light .CodeMirror-line > span::selection, .cm-s-light .CodeMirror-line > span > span::selection { background: #eee8d5; }
+.cm-s-solarized.cm-s-light .CodeMirror-line::-moz-selection, .cm-s-light .CodeMirror-line > span::-moz-selection, .cm-s-light .CodeMirror-line > span > span::-moz-selection { background: #eee8d5; }
+
+/* Editor styling */
+
+
+
+/* Little shadow on the view-port of the buffer view */
+.cm-s-solarized.CodeMirror {
+ -moz-box-shadow: inset 7px 0 12px -6px #000;
+ -webkit-box-shadow: inset 7px 0 12px -6px #000;
+ box-shadow: inset 7px 0 12px -6px #000;
+}
+
+/* Remove gutter border */
+.cm-s-solarized .CodeMirror-gutters {
+ border-right: 0;
+}
+
+/* Gutter colors and line number styling based of color scheme (dark / light) */
+
+/* Dark */
+.cm-s-solarized.cm-s-dark .CodeMirror-gutters {
+ background-color: #073642;
+}
+
+.cm-s-solarized.cm-s-dark .CodeMirror-linenumber {
+ color: #586e75;
+}
+
+/* Light */
+.cm-s-solarized.cm-s-light .CodeMirror-gutters {
+ background-color: #eee8d5;
+}
+
+.cm-s-solarized.cm-s-light .CodeMirror-linenumber {
+ color: #839496;
+}
+
+/* Common */
+.cm-s-solarized .CodeMirror-linenumber {
+ padding: 0 5px;
+}
+.cm-s-solarized .CodeMirror-guttermarker-subtle { color: #586e75; }
+.cm-s-solarized.cm-s-dark .CodeMirror-guttermarker { color: #ddd; }
+.cm-s-solarized.cm-s-light .CodeMirror-guttermarker { color: #cb4b16; }
+
+.cm-s-solarized .CodeMirror-gutter .CodeMirror-gutter-text {
+ color: #586e75;
+}
+
+/* Cursor */
+.cm-s-solarized .CodeMirror-cursor { border-left: 1px solid #819090; }
+
+/* Fat cursor */
+.cm-s-solarized.cm-s-light.cm-fat-cursor .CodeMirror-cursor { background: #77ee77; }
+.cm-s-solarized.cm-s-light .cm-animate-fat-cursor { background-color: #77ee77; }
+.cm-s-solarized.cm-s-dark.cm-fat-cursor .CodeMirror-cursor { background: #586e75; }
+.cm-s-solarized.cm-s-dark .cm-animate-fat-cursor { background-color: #586e75; }
+
+/* Active line */
+.cm-s-solarized.cm-s-dark .CodeMirror-activeline-background {
+ background: rgba(255, 255, 255, 0.06);
+}
+.cm-s-solarized.cm-s-light .CodeMirror-activeline-background {
+ background: rgba(0, 0, 0, 0.06);
+}
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/ssms.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/ssms.css
new file mode 100644
index 0000000000..9494c14c20
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/ssms.css
@@ -0,0 +1,16 @@
+.cm-s-ssms span.cm-keyword { color: blue; }
+.cm-s-ssms span.cm-comment { color: darkgreen; }
+.cm-s-ssms span.cm-string { color: red; }
+.cm-s-ssms span.cm-def { color: black; }
+.cm-s-ssms span.cm-variable { color: black; }
+.cm-s-ssms span.cm-variable-2 { color: black; }
+.cm-s-ssms span.cm-atom { color: darkgray; }
+.cm-s-ssms .CodeMirror-linenumber { color: teal; }
+.cm-s-ssms .CodeMirror-activeline-background { background: #ffffff; }
+.cm-s-ssms span.cm-string-2 { color: #FF00FF; }
+.cm-s-ssms span.cm-operator,
+.cm-s-ssms span.cm-bracket,
+.cm-s-ssms span.cm-punctuation { color: darkgray; }
+.cm-s-ssms .CodeMirror-gutters { border-right: 3px solid #ffee62; background-color: #ffffff; }
+.cm-s-ssms div.CodeMirror-selected { background: #ADD6FF; }
+
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/the-matrix.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/the-matrix.css
new file mode 100644
index 0000000000..c4c93c11ea
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/the-matrix.css
@@ -0,0 +1,30 @@
+.cm-s-the-matrix.CodeMirror { background: #000000; color: #00FF00; }
+.cm-s-the-matrix div.CodeMirror-selected { background: #2D2D2D; }
+.cm-s-the-matrix .CodeMirror-line::selection, .cm-s-the-matrix .CodeMirror-line > span::selection, .cm-s-the-matrix .CodeMirror-line > span > span::selection { background: rgba(45, 45, 45, 0.99); }
+.cm-s-the-matrix .CodeMirror-line::-moz-selection, .cm-s-the-matrix .CodeMirror-line > span::-moz-selection, .cm-s-the-matrix .CodeMirror-line > span > span::-moz-selection { background: rgba(45, 45, 45, 0.99); }
+.cm-s-the-matrix .CodeMirror-gutters { background: #060; border-right: 2px solid #00FF00; }
+.cm-s-the-matrix .CodeMirror-guttermarker { color: #0f0; }
+.cm-s-the-matrix .CodeMirror-guttermarker-subtle { color: white; }
+.cm-s-the-matrix .CodeMirror-linenumber { color: #FFFFFF; }
+.cm-s-the-matrix .CodeMirror-cursor { border-left: 1px solid #00FF00; }
+
+.cm-s-the-matrix span.cm-keyword { color: #008803; font-weight: bold; }
+.cm-s-the-matrix span.cm-atom { color: #3FF; }
+.cm-s-the-matrix span.cm-number { color: #FFB94F; }
+.cm-s-the-matrix span.cm-def { color: #99C; }
+.cm-s-the-matrix span.cm-variable { color: #F6C; }
+.cm-s-the-matrix span.cm-variable-2 { color: #C6F; }
+.cm-s-the-matrix span.cm-variable-3, .cm-s-the-matrix span.cm-type { color: #96F; }
+.cm-s-the-matrix span.cm-property { color: #62FFA0; }
+.cm-s-the-matrix span.cm-operator { color: #999; }
+.cm-s-the-matrix span.cm-comment { color: #CCCCCC; }
+.cm-s-the-matrix span.cm-string { color: #39C; }
+.cm-s-the-matrix span.cm-meta { color: #C9F; }
+.cm-s-the-matrix span.cm-qualifier { color: #FFF700; }
+.cm-s-the-matrix span.cm-builtin { color: #30a; }
+.cm-s-the-matrix span.cm-bracket { color: #cc7; }
+.cm-s-the-matrix span.cm-tag { color: #FFBD40; }
+.cm-s-the-matrix span.cm-attribute { color: #FFF700; }
+.cm-s-the-matrix span.cm-error { color: #FF0000; }
+
+.cm-s-the-matrix .CodeMirror-activeline-background { background: #040; }
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/tomorrow-night-bright.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/tomorrow-night-bright.css
new file mode 100644
index 0000000000..b6dd4a9278
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/tomorrow-night-bright.css
@@ -0,0 +1,35 @@
+/*
+
+ Name: Tomorrow Night - Bright
+ Author: Chris Kempson
+
+ Port done by Gerard Braad
+
+*/
+
+.cm-s-tomorrow-night-bright.CodeMirror { background: #000000; color: #eaeaea; }
+.cm-s-tomorrow-night-bright div.CodeMirror-selected { background: #424242; }
+.cm-s-tomorrow-night-bright .CodeMirror-gutters { background: #000000; border-right: 0px; }
+.cm-s-tomorrow-night-bright .CodeMirror-guttermarker { color: #e78c45; }
+.cm-s-tomorrow-night-bright .CodeMirror-guttermarker-subtle { color: #777; }
+.cm-s-tomorrow-night-bright .CodeMirror-linenumber { color: #424242; }
+.cm-s-tomorrow-night-bright .CodeMirror-cursor { border-left: 1px solid #6A6A6A; }
+
+.cm-s-tomorrow-night-bright span.cm-comment { color: #d27b53; }
+.cm-s-tomorrow-night-bright span.cm-atom { color: #a16a94; }
+.cm-s-tomorrow-night-bright span.cm-number { color: #a16a94; }
+
+.cm-s-tomorrow-night-bright span.cm-property, .cm-s-tomorrow-night-bright span.cm-attribute { color: #99cc99; }
+.cm-s-tomorrow-night-bright span.cm-keyword { color: #d54e53; }
+.cm-s-tomorrow-night-bright span.cm-string { color: #e7c547; }
+
+.cm-s-tomorrow-night-bright span.cm-variable { color: #b9ca4a; }
+.cm-s-tomorrow-night-bright span.cm-variable-2 { color: #7aa6da; }
+.cm-s-tomorrow-night-bright span.cm-def { color: #e78c45; }
+.cm-s-tomorrow-night-bright span.cm-bracket { color: #eaeaea; }
+.cm-s-tomorrow-night-bright span.cm-tag { color: #d54e53; }
+.cm-s-tomorrow-night-bright span.cm-link { color: #a16a94; }
+.cm-s-tomorrow-night-bright span.cm-error { background: #d54e53; color: #6A6A6A; }
+
+.cm-s-tomorrow-night-bright .CodeMirror-activeline-background { background: #2a2a2a; }
+.cm-s-tomorrow-night-bright .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; }
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/tomorrow-night-eighties.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/tomorrow-night-eighties.css
new file mode 100644
index 0000000000..2a9debc327
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/tomorrow-night-eighties.css
@@ -0,0 +1,38 @@
+/*
+
+ Name: Tomorrow Night - Eighties
+ Author: Chris Kempson
+
+ CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror)
+ Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16)
+
+*/
+
+.cm-s-tomorrow-night-eighties.CodeMirror { background: #000000; color: #CCCCCC; }
+.cm-s-tomorrow-night-eighties div.CodeMirror-selected { background: #2D2D2D; }
+.cm-s-tomorrow-night-eighties .CodeMirror-line::selection, .cm-s-tomorrow-night-eighties .CodeMirror-line > span::selection, .cm-s-tomorrow-night-eighties .CodeMirror-line > span > span::selection { background: rgba(45, 45, 45, 0.99); }
+.cm-s-tomorrow-night-eighties .CodeMirror-line::-moz-selection, .cm-s-tomorrow-night-eighties .CodeMirror-line > span::-moz-selection, .cm-s-tomorrow-night-eighties .CodeMirror-line > span > span::-moz-selection { background: rgba(45, 45, 45, 0.99); }
+.cm-s-tomorrow-night-eighties .CodeMirror-gutters { background: #000000; border-right: 0px; }
+.cm-s-tomorrow-night-eighties .CodeMirror-guttermarker { color: #f2777a; }
+.cm-s-tomorrow-night-eighties .CodeMirror-guttermarker-subtle { color: #777; }
+.cm-s-tomorrow-night-eighties .CodeMirror-linenumber { color: #515151; }
+.cm-s-tomorrow-night-eighties .CodeMirror-cursor { border-left: 1px solid #6A6A6A; }
+
+.cm-s-tomorrow-night-eighties span.cm-comment { color: #d27b53; }
+.cm-s-tomorrow-night-eighties span.cm-atom { color: #a16a94; }
+.cm-s-tomorrow-night-eighties span.cm-number { color: #a16a94; }
+
+.cm-s-tomorrow-night-eighties span.cm-property, .cm-s-tomorrow-night-eighties span.cm-attribute { color: #99cc99; }
+.cm-s-tomorrow-night-eighties span.cm-keyword { color: #f2777a; }
+.cm-s-tomorrow-night-eighties span.cm-string { color: #ffcc66; }
+
+.cm-s-tomorrow-night-eighties span.cm-variable { color: #99cc99; }
+.cm-s-tomorrow-night-eighties span.cm-variable-2 { color: #6699cc; }
+.cm-s-tomorrow-night-eighties span.cm-def { color: #f99157; }
+.cm-s-tomorrow-night-eighties span.cm-bracket { color: #CCCCCC; }
+.cm-s-tomorrow-night-eighties span.cm-tag { color: #f2777a; }
+.cm-s-tomorrow-night-eighties span.cm-link { color: #a16a94; }
+.cm-s-tomorrow-night-eighties span.cm-error { background: #f2777a; color: #6A6A6A; }
+
+.cm-s-tomorrow-night-eighties .CodeMirror-activeline-background { background: #343600; }
+.cm-s-tomorrow-night-eighties .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; }
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/ttcn.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/ttcn.css
new file mode 100644
index 0000000000..0b14ac35d6
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/ttcn.css
@@ -0,0 +1,64 @@
+.cm-s-ttcn .cm-quote { color: #090; }
+.cm-s-ttcn .cm-negative { color: #d44; }
+.cm-s-ttcn .cm-positive { color: #292; }
+.cm-s-ttcn .cm-header, .cm-strong { font-weight: bold; }
+.cm-s-ttcn .cm-em { font-style: italic; }
+.cm-s-ttcn .cm-link { text-decoration: underline; }
+.cm-s-ttcn .cm-strikethrough { text-decoration: line-through; }
+.cm-s-ttcn .cm-header { color: #00f; font-weight: bold; }
+
+.cm-s-ttcn .cm-atom { color: #219; }
+.cm-s-ttcn .cm-attribute { color: #00c; }
+.cm-s-ttcn .cm-bracket { color: #997; }
+.cm-s-ttcn .cm-comment { color: #333333; }
+.cm-s-ttcn .cm-def { color: #00f; }
+.cm-s-ttcn .cm-em { font-style: italic; }
+.cm-s-ttcn .cm-error { color: #f00; }
+.cm-s-ttcn .cm-hr { color: #999; }
+.cm-s-ttcn .cm-invalidchar { color: #f00; }
+.cm-s-ttcn .cm-keyword { font-weight:bold; }
+.cm-s-ttcn .cm-link { color: #00c; text-decoration: underline; }
+.cm-s-ttcn .cm-meta { color: #555; }
+.cm-s-ttcn .cm-negative { color: #d44; }
+.cm-s-ttcn .cm-positive { color: #292; }
+.cm-s-ttcn .cm-qualifier { color: #555; }
+.cm-s-ttcn .cm-strikethrough { text-decoration: line-through; }
+.cm-s-ttcn .cm-string { color: #006400; }
+.cm-s-ttcn .cm-string-2 { color: #f50; }
+.cm-s-ttcn .cm-strong { font-weight: bold; }
+.cm-s-ttcn .cm-tag { color: #170; }
+.cm-s-ttcn .cm-variable { color: #8B2252; }
+.cm-s-ttcn .cm-variable-2 { color: #05a; }
+.cm-s-ttcn .cm-variable-3, .cm-s-ttcn .cm-type { color: #085; }
+
+.cm-s-ttcn .cm-invalidchar { color: #f00; }
+
+/* ASN */
+.cm-s-ttcn .cm-accessTypes,
+.cm-s-ttcn .cm-compareTypes { color: #27408B; }
+.cm-s-ttcn .cm-cmipVerbs { color: #8B2252; }
+.cm-s-ttcn .cm-modifier { color:#D2691E; }
+.cm-s-ttcn .cm-status { color:#8B4545; }
+.cm-s-ttcn .cm-storage { color:#A020F0; }
+.cm-s-ttcn .cm-tags { color:#006400; }
+
+/* CFG */
+.cm-s-ttcn .cm-externalCommands { color: #8B4545; font-weight:bold; }
+.cm-s-ttcn .cm-fileNCtrlMaskOptions,
+.cm-s-ttcn .cm-sectionTitle { color: #2E8B57; font-weight:bold; }
+
+/* TTCN */
+.cm-s-ttcn .cm-booleanConsts,
+.cm-s-ttcn .cm-otherConsts,
+.cm-s-ttcn .cm-verdictConsts { color: #006400; }
+.cm-s-ttcn .cm-configOps,
+.cm-s-ttcn .cm-functionOps,
+.cm-s-ttcn .cm-portOps,
+.cm-s-ttcn .cm-sutOps,
+.cm-s-ttcn .cm-timerOps,
+.cm-s-ttcn .cm-verdictOps { color: #0000FF; }
+.cm-s-ttcn .cm-preprocessor,
+.cm-s-ttcn .cm-templateMatch,
+.cm-s-ttcn .cm-ttcn3Macros { color: #27408B; }
+.cm-s-ttcn .cm-types { color: #A52A2A; font-weight:bold; }
+.cm-s-ttcn .cm-visibilityModifiers { font-weight:bold; }
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/twilight.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/twilight.css
new file mode 100644
index 0000000000..b2b1b2aa93
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/twilight.css
@@ -0,0 +1,32 @@
+.cm-s-twilight.CodeMirror { background: #141414; color: #f7f7f7; } /**/
+.cm-s-twilight div.CodeMirror-selected { background: #323232; } /**/
+.cm-s-twilight .CodeMirror-line::selection, .cm-s-twilight .CodeMirror-line > span::selection, .cm-s-twilight .CodeMirror-line > span > span::selection { background: rgba(50, 50, 50, 0.99); }
+.cm-s-twilight .CodeMirror-line::-moz-selection, .cm-s-twilight .CodeMirror-line > span::-moz-selection, .cm-s-twilight .CodeMirror-line > span > span::-moz-selection { background: rgba(50, 50, 50, 0.99); }
+
+.cm-s-twilight .CodeMirror-gutters { background: #222; border-right: 1px solid #aaa; }
+.cm-s-twilight .CodeMirror-guttermarker { color: white; }
+.cm-s-twilight .CodeMirror-guttermarker-subtle { color: #aaa; }
+.cm-s-twilight .CodeMirror-linenumber { color: #aaa; }
+.cm-s-twilight .CodeMirror-cursor { border-left: 1px solid white; }
+
+.cm-s-twilight .cm-keyword { color: #f9ee98; } /**/
+.cm-s-twilight .cm-atom { color: #FC0; }
+.cm-s-twilight .cm-number { color: #ca7841; } /**/
+.cm-s-twilight .cm-def { color: #8DA6CE; }
+.cm-s-twilight span.cm-variable-2, .cm-s-twilight span.cm-tag { color: #607392; } /**/
+.cm-s-twilight span.cm-variable-3, .cm-s-twilight span.cm-def, .cm-s-twilight span.cm-type { color: #607392; } /**/
+.cm-s-twilight .cm-operator { color: #cda869; } /**/
+.cm-s-twilight .cm-comment { color:#777; font-style:italic; font-weight:normal; } /**/
+.cm-s-twilight .cm-string { color:#8f9d6a; font-style:italic; } /**/
+.cm-s-twilight .cm-string-2 { color:#bd6b18; } /*?*/
+.cm-s-twilight .cm-meta { background-color:#141414; color:#f7f7f7; } /*?*/
+.cm-s-twilight .cm-builtin { color: #cda869; } /*?*/
+.cm-s-twilight .cm-tag { color: #997643; } /**/
+.cm-s-twilight .cm-attribute { color: #d6bb6d; } /*?*/
+.cm-s-twilight .cm-header { color: #FF6400; }
+.cm-s-twilight .cm-hr { color: #AEAEAE; }
+.cm-s-twilight .cm-link { color:#ad9361; font-style:italic; text-decoration:none; } /**/
+.cm-s-twilight .cm-error { border-bottom: 1px solid red; }
+
+.cm-s-twilight .CodeMirror-activeline-background { background: #27282E; }
+.cm-s-twilight .CodeMirror-matchingbracket { outline:1px solid grey; color:white !important; }
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/vibrant-ink.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/vibrant-ink.css
new file mode 100644
index 0000000000..6358ad3655
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/vibrant-ink.css
@@ -0,0 +1,34 @@
+/* Taken from the popular Visual Studio Vibrant Ink Schema */
+
+.cm-s-vibrant-ink.CodeMirror { background: black; color: white; }
+.cm-s-vibrant-ink div.CodeMirror-selected { background: #35493c; }
+.cm-s-vibrant-ink .CodeMirror-line::selection, .cm-s-vibrant-ink .CodeMirror-line > span::selection, .cm-s-vibrant-ink .CodeMirror-line > span > span::selection { background: rgba(53, 73, 60, 0.99); }
+.cm-s-vibrant-ink .CodeMirror-line::-moz-selection, .cm-s-vibrant-ink .CodeMirror-line > span::-moz-selection, .cm-s-vibrant-ink .CodeMirror-line > span > span::-moz-selection { background: rgba(53, 73, 60, 0.99); }
+
+.cm-s-vibrant-ink .CodeMirror-gutters { background: #002240; border-right: 1px solid #aaa; }
+.cm-s-vibrant-ink .CodeMirror-guttermarker { color: white; }
+.cm-s-vibrant-ink .CodeMirror-guttermarker-subtle { color: #d0d0d0; }
+.cm-s-vibrant-ink .CodeMirror-linenumber { color: #d0d0d0; }
+.cm-s-vibrant-ink .CodeMirror-cursor { border-left: 1px solid white; }
+
+.cm-s-vibrant-ink .cm-keyword { color: #CC7832; }
+.cm-s-vibrant-ink .cm-atom { color: #FC0; }
+.cm-s-vibrant-ink .cm-number { color: #FFEE98; }
+.cm-s-vibrant-ink .cm-def { color: #8DA6CE; }
+.cm-s-vibrant-ink span.cm-variable-2, .cm-s-vibrant span.cm-tag { color: #FFC66D; }
+.cm-s-vibrant-ink span.cm-variable-3, .cm-s-vibrant span.cm-def, .cm-s-vibrant span.cm-type { color: #FFC66D; }
+.cm-s-vibrant-ink .cm-operator { color: #888; }
+.cm-s-vibrant-ink .cm-comment { color: gray; font-weight: bold; }
+.cm-s-vibrant-ink .cm-string { color: #A5C25C; }
+.cm-s-vibrant-ink .cm-string-2 { color: red; }
+.cm-s-vibrant-ink .cm-meta { color: #D8FA3C; }
+.cm-s-vibrant-ink .cm-builtin { color: #8DA6CE; }
+.cm-s-vibrant-ink .cm-tag { color: #8DA6CE; }
+.cm-s-vibrant-ink .cm-attribute { color: #8DA6CE; }
+.cm-s-vibrant-ink .cm-header { color: #FF6400; }
+.cm-s-vibrant-ink .cm-hr { color: #AEAEAE; }
+.cm-s-vibrant-ink .cm-link { color: #5656F3; }
+.cm-s-vibrant-ink .cm-error { border-bottom: 1px solid red; }
+
+.cm-s-vibrant-ink .CodeMirror-activeline-background { background: #27282E; }
+.cm-s-vibrant-ink .CodeMirror-matchingbracket { outline:1px solid grey; color:white !important; }
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/xq-dark.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/xq-dark.css
new file mode 100644
index 0000000000..7da1a0f705
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/xq-dark.css
@@ -0,0 +1,53 @@
+/*
+Copyright (C) 2011 by MarkLogic Corporation
+Author: Mike Brevoort
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+.cm-s-xq-dark.CodeMirror { background: #0a001f; color: #f8f8f8; }
+.cm-s-xq-dark div.CodeMirror-selected { background: #27007A; }
+.cm-s-xq-dark .CodeMirror-line::selection, .cm-s-xq-dark .CodeMirror-line > span::selection, .cm-s-xq-dark .CodeMirror-line > span > span::selection { background: rgba(39, 0, 122, 0.99); }
+.cm-s-xq-dark .CodeMirror-line::-moz-selection, .cm-s-xq-dark .CodeMirror-line > span::-moz-selection, .cm-s-xq-dark .CodeMirror-line > span > span::-moz-selection { background: rgba(39, 0, 122, 0.99); }
+.cm-s-xq-dark .CodeMirror-gutters { background: #0a001f; border-right: 1px solid #aaa; }
+.cm-s-xq-dark .CodeMirror-guttermarker { color: #FFBD40; }
+.cm-s-xq-dark .CodeMirror-guttermarker-subtle { color: #f8f8f8; }
+.cm-s-xq-dark .CodeMirror-linenumber { color: #f8f8f8; }
+.cm-s-xq-dark .CodeMirror-cursor { border-left: 1px solid white; }
+
+.cm-s-xq-dark span.cm-keyword { color: #FFBD40; }
+.cm-s-xq-dark span.cm-atom { color: #6C8CD5; }
+.cm-s-xq-dark span.cm-number { color: #164; }
+.cm-s-xq-dark span.cm-def { color: #FFF; text-decoration:underline; }
+.cm-s-xq-dark span.cm-variable { color: #FFF; }
+.cm-s-xq-dark span.cm-variable-2 { color: #EEE; }
+.cm-s-xq-dark span.cm-variable-3, .cm-s-xq-dark span.cm-type { color: #DDD; }
+.cm-s-xq-dark span.cm-property {}
+.cm-s-xq-dark span.cm-operator {}
+.cm-s-xq-dark span.cm-comment { color: gray; }
+.cm-s-xq-dark span.cm-string { color: #9FEE00; }
+.cm-s-xq-dark span.cm-meta { color: yellow; }
+.cm-s-xq-dark span.cm-qualifier { color: #FFF700; }
+.cm-s-xq-dark span.cm-builtin { color: #30a; }
+.cm-s-xq-dark span.cm-bracket { color: #cc7; }
+.cm-s-xq-dark span.cm-tag { color: #FFBD40; }
+.cm-s-xq-dark span.cm-attribute { color: #FFF700; }
+.cm-s-xq-dark span.cm-error { color: #f00; }
+
+.cm-s-xq-dark .CodeMirror-activeline-background { background: #27282E; }
+.cm-s-xq-dark .CodeMirror-matchingbracket { outline:1px solid grey; color:white !important; }
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/xq-light.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/xq-light.css
new file mode 100644
index 0000000000..7b182ea997
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/xq-light.css
@@ -0,0 +1,43 @@
+/*
+Copyright (C) 2011 by MarkLogic Corporation
+Author: Mike Brevoort
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+.cm-s-xq-light span.cm-keyword { line-height: 1em; font-weight: bold; color: #5A5CAD; }
+.cm-s-xq-light span.cm-atom { color: #6C8CD5; }
+.cm-s-xq-light span.cm-number { color: #164; }
+.cm-s-xq-light span.cm-def { text-decoration:underline; }
+.cm-s-xq-light span.cm-variable { color: black; }
+.cm-s-xq-light span.cm-variable-2 { color:black; }
+.cm-s-xq-light span.cm-variable-3, .cm-s-xq-light span.cm-type { color: black; }
+.cm-s-xq-light span.cm-property {}
+.cm-s-xq-light span.cm-operator {}
+.cm-s-xq-light span.cm-comment { color: #0080FF; font-style: italic; }
+.cm-s-xq-light span.cm-string { color: red; }
+.cm-s-xq-light span.cm-meta { color: yellow; }
+.cm-s-xq-light span.cm-qualifier { color: grey; }
+.cm-s-xq-light span.cm-builtin { color: #7EA656; }
+.cm-s-xq-light span.cm-bracket { color: #cc7; }
+.cm-s-xq-light span.cm-tag { color: #3F7F7F; }
+.cm-s-xq-light span.cm-attribute { color: #7F007F; }
+.cm-s-xq-light span.cm-error { color: #f00; }
+
+.cm-s-xq-light .CodeMirror-activeline-background { background: #e8f2ff; }
+.cm-s-xq-light .CodeMirror-matchingbracket { outline:1px solid grey;color:black !important;background:yellow; }
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/yeti.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/yeti.css
new file mode 100644
index 0000000000..d085f72497
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/yeti.css
@@ -0,0 +1,44 @@
+/*
+
+ Name: yeti
+ Author: Michael Kaminsky (http://github.com/mkaminsky11)
+
+ Original yeti color scheme by Jesse Weed (https://github.com/jesseweed/yeti-syntax)
+
+*/
+
+
+.cm-s-yeti.CodeMirror {
+ background-color: #ECEAE8 !important;
+ color: #d1c9c0 !important;
+ border: none;
+}
+
+.cm-s-yeti .CodeMirror-gutters {
+ color: #adaba6;
+ background-color: #E5E1DB;
+ border: none;
+}
+.cm-s-yeti .CodeMirror-cursor { border-left: solid thin #d1c9c0; }
+.cm-s-yeti .CodeMirror-linenumber { color: #adaba6; }
+.cm-s-yeti.CodeMirror-focused div.CodeMirror-selected { background: #DCD8D2; }
+.cm-s-yeti .CodeMirror-line::selection, .cm-s-yeti .CodeMirror-line > span::selection, .cm-s-yeti .CodeMirror-line > span > span::selection { background: #DCD8D2; }
+.cm-s-yeti .CodeMirror-line::-moz-selection, .cm-s-yeti .CodeMirror-line > span::-moz-selection, .cm-s-yeti .CodeMirror-line > span > span::-moz-selection { background: #DCD8D2; }
+.cm-s-yeti span.cm-comment { color: #d4c8be; }
+.cm-s-yeti span.cm-string, .cm-s-yeti span.cm-string-2 { color: #96c0d8; }
+.cm-s-yeti span.cm-number { color: #a074c4; }
+.cm-s-yeti span.cm-variable { color: #55b5db; }
+.cm-s-yeti span.cm-variable-2 { color: #a074c4; }
+.cm-s-yeti span.cm-def { color: #55b5db; }
+.cm-s-yeti span.cm-operator { color: #9fb96e; }
+.cm-s-yeti span.cm-keyword { color: #9fb96e; }
+.cm-s-yeti span.cm-atom { color: #a074c4; }
+.cm-s-yeti span.cm-meta { color: #96c0d8; }
+.cm-s-yeti span.cm-tag { color: #96c0d8; }
+.cm-s-yeti span.cm-attribute { color: #9fb96e; }
+.cm-s-yeti span.cm-qualifier { color: #96c0d8; }
+.cm-s-yeti span.cm-property { color: #a074c4; }
+.cm-s-yeti span.cm-builtin { color: #a074c4; }
+.cm-s-yeti span.cm-variable-3, .cm-s-yeti span.cm-type { color: #96c0d8; }
+.cm-s-yeti .CodeMirror-activeline-background { background: #E7E4E0; }
+.cm-s-yeti .CodeMirror-matchingbracket { text-decoration: underline; }
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/yonce.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/yonce.css
new file mode 100644
index 0000000000..975f0788a2
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/yonce.css
@@ -0,0 +1,59 @@
+/*
+
+ Name: yoncé
+ Author: Thomas MacLean (http://github.com/thomasmaclean)
+
+ Original yoncé color scheme by Mina Markham (https://github.com/minamarkham)
+
+*/
+
+.cm-s-yonce.CodeMirror { background: #1C1C1C; color: #d4d4d4; } /**/
+.cm-s-yonce div.CodeMirror-selected { background: rgba(252, 69, 133, 0.478); } /**/
+.cm-s-yonce .CodeMirror-selectedtext,
+.cm-s-yonce .CodeMirror-selected,
+.cm-s-yonce .CodeMirror-line::selection,
+.cm-s-yonce .CodeMirror-line > span::selection,
+.cm-s-yonce .CodeMirror-line > span > span::selection,
+.cm-s-yonce .CodeMirror-line::-moz-selection,
+.cm-s-yonce .CodeMirror-line > span::-moz-selection,
+.cm-s-yonce .CodeMirror-line > span > span::-moz-selection { background: rgba(252, 67, 132, 0.47); }
+
+.cm-s-yonce.CodeMirror pre { padding-left: 0px; }
+.cm-s-yonce .CodeMirror-gutters {background: #1C1C1C; border-right: 0px;}
+.cm-s-yonce .CodeMirror-linenumber {color: #777777; padding-right: 10px; }
+.cm-s-yonce .CodeMirror-activeline .CodeMirror-linenumber.CodeMirror-gutter-elt { background: #1C1C1C; color: #fc4384; }
+.cm-s-yonce .CodeMirror-linenumber { color: #777; }
+.cm-s-yonce .CodeMirror-cursor { border-left: 2px solid #FC4384; }
+.cm-s-yonce .cm-searching { background: rgba(243, 155, 53, .3) !important; outline: 1px solid #F39B35; }
+.cm-s-yonce .cm-searching.CodeMirror-selectedtext { background: rgba(243, 155, 53, .7) !important; color: white; }
+
+.cm-s-yonce .cm-keyword { color: #00A7AA; } /**/
+.cm-s-yonce .cm-atom { color: #F39B35; }
+.cm-s-yonce .cm-number, .cm-s-yonce span.cm-type { color: #A06FCA; } /**/
+.cm-s-yonce .cm-def { color: #98E342; }
+.cm-s-yonce .cm-property,
+.cm-s-yonce span.cm-variable { color: #D4D4D4; font-style: italic; }
+.cm-s-yonce span.cm-variable-2 { color: #da7dae; font-style: italic; }
+.cm-s-yonce span.cm-variable-3 { color: #A06FCA; }
+.cm-s-yonce .cm-type.cm-def { color: #FC4384; font-style: normal; text-decoration: underline; }
+.cm-s-yonce .cm-property.cm-def { color: #FC4384; font-style: normal; }
+.cm-s-yonce .cm-callee { color: #FC4384; font-style: normal; }
+.cm-s-yonce .cm-operator { color: #FC4384; } /**/
+.cm-s-yonce .cm-qualifier,
+.cm-s-yonce .cm-tag { color: #FC4384; }
+.cm-s-yonce .cm-tag.cm-bracket { color: #D4D4D4; }
+.cm-s-yonce .cm-attribute { color: #A06FCA; }
+.cm-s-yonce .cm-comment { color:#696d70; font-style:italic; font-weight:normal; } /**/
+.cm-s-yonce .cm-comment.cm-tag { color: #FC4384 }
+.cm-s-yonce .cm-comment.cm-attribute { color: #D4D4D4; }
+.cm-s-yonce .cm-string { color:#E6DB74; } /**/
+.cm-s-yonce .cm-string-2 { color:#F39B35; } /*?*/
+.cm-s-yonce .cm-meta { color: #D4D4D4; background: inherit; }
+.cm-s-yonce .cm-builtin { color: #FC4384; } /*?*/
+.cm-s-yonce .cm-header { color: #da7dae; }
+.cm-s-yonce .cm-hr { color: #98E342; }
+.cm-s-yonce .cm-link { color:#696d70; font-style:italic; text-decoration:none; } /**/
+.cm-s-yonce .cm-error { border-bottom: 1px solid #C42412; }
+
+.cm-s-yonce .CodeMirror-activeline-background { background: #272727; }
+.cm-s-yonce .CodeMirror-matchingbracket { outline:1px solid grey; color:#D4D4D4 !important; }
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/zenburn.css b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/zenburn.css
new file mode 100644
index 0000000000..4eb4247c92
--- /dev/null
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/wwwroot/libs/codemirror/theme/zenburn.css
@@ -0,0 +1,37 @@
+/**
+ * "
+ * Using Zenburn color palette from the Emacs Zenburn Theme
+ * https://github.com/bbatsov/zenburn-emacs/blob/master/zenburn-theme.el
+ *
+ * Also using parts of https://github.com/xavi/coderay-lighttable-theme
+ * "
+ * From: https://github.com/wisenomad/zenburn-lighttable-theme/blob/master/zenburn.css
+ */
+
+.cm-s-zenburn .CodeMirror-gutters { background: #3f3f3f !important; }
+.cm-s-zenburn .CodeMirror-foldgutter-open, .CodeMirror-foldgutter-folded { color: #999; }
+.cm-s-zenburn .CodeMirror-cursor { border-left: 1px solid white; }
+.cm-s-zenburn.CodeMirror { background-color: #3f3f3f; color: #dcdccc; }
+.cm-s-zenburn span.cm-builtin { color: #dcdccc; font-weight: bold; }
+.cm-s-zenburn span.cm-comment { color: #7f9f7f; }
+.cm-s-zenburn span.cm-keyword { color: #f0dfaf; font-weight: bold; }
+.cm-s-zenburn span.cm-atom { color: #bfebbf; }
+.cm-s-zenburn span.cm-def { color: #dcdccc; }
+.cm-s-zenburn span.cm-variable { color: #dfaf8f; }
+.cm-s-zenburn span.cm-variable-2 { color: #dcdccc; }
+.cm-s-zenburn span.cm-string { color: #cc9393; }
+.cm-s-zenburn span.cm-string-2 { color: #cc9393; }
+.cm-s-zenburn span.cm-number { color: #dcdccc; }
+.cm-s-zenburn span.cm-tag { color: #93e0e3; }
+.cm-s-zenburn span.cm-property { color: #dfaf8f; }
+.cm-s-zenburn span.cm-attribute { color: #dfaf8f; }
+.cm-s-zenburn span.cm-qualifier { color: #7cb8bb; }
+.cm-s-zenburn span.cm-meta { color: #f0dfaf; }
+.cm-s-zenburn span.cm-header { color: #f0efd0; }
+.cm-s-zenburn span.cm-operator { color: #f0efd0; }
+.cm-s-zenburn span.CodeMirror-matchingbracket { box-sizing: border-box; background: transparent; border-bottom: 1px solid; }
+.cm-s-zenburn span.CodeMirror-nonmatchingbracket { border-bottom: 1px solid; background: none; }
+.cm-s-zenburn .CodeMirror-activeline { background: #000000; }
+.cm-s-zenburn .CodeMirror-activeline-background { background: #000000; }
+.cm-s-zenburn div.CodeMirror-selected { background: #545454; }
+.cm-s-zenburn .CodeMirror-focused div.CodeMirror-selected { background: #4f4f4f; }
diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/yarn.lock b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/yarn.lock
index cedf508cc2..92b8cbcfbd 100644
--- a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/yarn.lock
+++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/yarn.lock
@@ -2,37 +2,37 @@
# yarn lockfile v1
-"@abp/aspnetcore.mvc.ui.theme.basic@^5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-5.2.1.tgz#25bd7116b9b0e72ba45f0f5246343343de8561b2"
- integrity sha512-DYr9ROcTPfCRHxD1QSWqLZ9+ARbO5p9I6SRo893NtJ39aHacAa9RIAwZmP0JLG0C4hLXfJLKXJ2DpNcwY+ubXA==
- dependencies:
- "@abp/aspnetcore.mvc.ui.theme.shared" "~5.2.1"
-
-"@abp/aspnetcore.mvc.ui.theme.shared@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-5.2.1.tgz#dc291fe9c7100cc796068e19abf7579bd5e54b44"
- integrity sha512-/1C5RyPIRPZT5ir8Len2EnSt1KfWcRdPyn/avAG+9JKBZ8FoUL8mO2/ffESOvikh/wItZZgxJ5VEJVGwHNjgdQ==
- dependencies:
- "@abp/aspnetcore.mvc.ui" "~5.2.1"
- "@abp/bootstrap" "~5.2.1"
- "@abp/bootstrap-datepicker" "~5.2.1"
- "@abp/datatables.net-bs5" "~5.2.1"
- "@abp/font-awesome" "~5.2.1"
- "@abp/jquery-form" "~5.2.1"
- "@abp/jquery-validation-unobtrusive" "~5.2.1"
- "@abp/lodash" "~5.2.1"
- "@abp/luxon" "~5.2.1"
- "@abp/malihu-custom-scrollbar-plugin" "~5.2.1"
- "@abp/select2" "~5.2.1"
- "@abp/sweetalert2" "~5.2.1"
- "@abp/timeago" "~5.2.1"
- "@abp/toastr" "~5.2.1"
-
-"@abp/aspnetcore.mvc.ui@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-5.2.1.tgz#239ceeec332cebe2fedec0bb0cdec09089b499d3"
- integrity sha512-VUSPOKjBSF+NxfwdsEVQte8u7mGP1t7jd1+ej2ND8JEKYJ1Vh7z2mfsT+lQaEJg0JWggU1AxkIMOOfHDNTU3Kg==
+"@abp/aspnetcore.mvc.ui.theme.basic@^5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.basic/-/aspnetcore.mvc.ui.theme.basic-5.3.0-rc.1.tgz#dc27eb79ba7353eb6b16e4a2f50d17c3cfc9157d"
+ integrity sha512-TEbz/ISsGhfTec66XSeivQjCOCpTidufdpZmj8JRyrbQvhXOYohJs3ImrGJOIxUwo6nuzagGpotqXryjIF+jrg==
+ dependencies:
+ "@abp/aspnetcore.mvc.ui.theme.shared" "~5.3.0-rc.1"
+
+"@abp/aspnetcore.mvc.ui.theme.shared@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui.theme.shared/-/aspnetcore.mvc.ui.theme.shared-5.3.0-rc.1.tgz#ed993befe99682baee55ea8771f983980ba8f93f"
+ integrity sha512-kL4CXe0YoZ4wJ4XvutqLPkv4fMuFeRJFzdix6lx4dPAArnPu69n3P4qFhokPkcoGpB2KTRqyn9fHQs8g2FCGQw==
+ dependencies:
+ "@abp/aspnetcore.mvc.ui" "~5.3.0-rc.1"
+ "@abp/bootstrap" "~5.3.0-rc.1"
+ "@abp/bootstrap-datepicker" "~5.3.0-rc.1"
+ "@abp/datatables.net-bs5" "~5.3.0-rc.1"
+ "@abp/font-awesome" "~5.3.0-rc.1"
+ "@abp/jquery-form" "~5.3.0-rc.1"
+ "@abp/jquery-validation-unobtrusive" "~5.3.0-rc.1"
+ "@abp/lodash" "~5.3.0-rc.1"
+ "@abp/luxon" "~5.3.0-rc.1"
+ "@abp/malihu-custom-scrollbar-plugin" "~5.3.0-rc.1"
+ "@abp/select2" "~5.3.0-rc.1"
+ "@abp/sweetalert2" "~5.3.0-rc.1"
+ "@abp/timeago" "~5.3.0-rc.1"
+ "@abp/toastr" "~5.3.0-rc.1"
+
+"@abp/aspnetcore.mvc.ui@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/aspnetcore.mvc.ui/-/aspnetcore.mvc.ui-5.3.0-rc.1.tgz#5205d3a5ea500ff3b8d525dcc11a2ce4cfccdfd3"
+ integrity sha512-mIefq3QSVtP7heNl0ocHiSKLU+DwN5/TDvvPj2L3IZkCzuOrDxoBUIBIciea4k10HIQzqo6gmm1YOw0CEfzNHg==
dependencies:
ansi-colors "^4.1.1"
extend-object "^1.0.0"
@@ -41,234 +41,243 @@
merge-stream "^2.0.0"
micromatch "^4.0.2"
-"@abp/bootstrap-datepicker@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-5.2.1.tgz#20d565211d05ca184f8e3ef4db840dbd98a58fbd"
- integrity sha512-UPdVu9t7XybINSfonQN0DB9Lpz1r5vCz7F8CMpbjQprvPmsFmkAZyY0p6MS3kGO5eu5rlpGAGPBGOTeSfEp9ww==
+"@abp/bootstrap-datepicker@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/bootstrap-datepicker/-/bootstrap-datepicker-5.3.0-rc.1.tgz#1a5a29d7f9904e8d99c7085bc4545ad2665195cb"
+ integrity sha512-Y5QLLNd2UpbzbWSh+5nKdpAdz2i3V8+feTHTpAxnPgYRabPGqAFiOrty8KZ1MJEgjQFWC1ypGHYII7GWVyIS6Q==
dependencies:
bootstrap-datepicker "^1.9.0"
-"@abp/bootstrap@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-5.2.1.tgz#fe15144d7136a26be44be23fd2470cdef0bd28b9"
- integrity sha512-vFW8OxfRhiDkIrDVIn3TyGkGyiCLLFmPMjSOmMg3o2XPdRk5uhwSBzWYpk/m+kmPpP6cEsJMxaHpCsirSlPE+A==
+"@abp/bootstrap@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/bootstrap/-/bootstrap-5.3.0-rc.1.tgz#977d579f59e18b1eb2c9b43612d525a859a575a4"
+ integrity sha512-dpY0bPHdhUI5yL23+EsR6w/KjoPyehaEgHLLKQDERdubX1Zk/SDWrhrYXnXxtJ0fvxG2aRVOEBMULmHD3m/PoA==
dependencies:
- "@abp/core" "~5.2.1"
+ "@abp/core" "~5.3.0-rc.1"
bootstrap "^5.1.3"
-"@abp/clipboard@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/clipboard/-/clipboard-5.2.1.tgz#c6bddd279b37e9b2bd27b027d5686411c9ae942b"
- integrity sha512-aouNTDz8t+8M4O2a+UsEdtABRsyhvzGpXqCG2+LYE1vA3I+CKhglkvEFp+GyIgWsipEHY1U1w6V3qZtcRINn+A==
+"@abp/clipboard@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/clipboard/-/clipboard-5.3.0-rc.1.tgz#da893847d2d86f53f99dfefc8898d14410d45600"
+ integrity sha512-Eqkgd3ZJXHE5xovfb+2SzGxzISCjzLsGYSV/uZs2BYVfyIZ0+D2Jx0jOT8j8oVPAlRTCCMAbvoxMKZJZr/WC0Q==
dependencies:
- "@abp/core" "~5.2.1"
+ "@abp/core" "~5.3.0-rc.1"
clipboard "^2.0.8"
-"@abp/cms-kit.admin@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/cms-kit.admin/-/cms-kit.admin-5.2.1.tgz#f685e8533366fa7a7db9641a61681f664af6d979"
- integrity sha512-KkT3eJMR0XCzlIY3KXNId3KfN8rQmGuThTZIPo5cifGg0mpW/HdkCfI4Dmv6v2xkUnZ/o5dOf+cXkvFrt6zzfg==
+"@abp/cms-kit.admin@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/cms-kit.admin/-/cms-kit.admin-5.3.0-rc.1.tgz#741350a9669532d3bd8e703c2a8cde5e693b1b9d"
+ integrity sha512-xmdfrlAOBDB1Fi/aBjpkNEG5m4OBiSOo1xt88fG1KJiKxfDYsH84XB+V7rJ/3IWtlaQJDzdnYFrqoex/5h0S/A==
dependencies:
- "@abp/jstree" "~5.2.1"
- "@abp/slugify" "~5.2.1"
- "@abp/tui-editor" "~5.2.1"
- "@abp/uppy" "~5.2.1"
+ "@abp/codemirror" "~5.3.0-rc.1"
+ "@abp/jstree" "~5.3.0-rc.1"
+ "@abp/slugify" "~5.3.0-rc.1"
+ "@abp/tui-editor" "~5.3.0-rc.1"
+ "@abp/uppy" "~5.3.0-rc.1"
-"@abp/cms-kit.public@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/cms-kit.public/-/cms-kit.public-5.2.1.tgz#8f4860b17470f57fce3bbd732a7954031a244d14"
- integrity sha512-dOhzJjWuXO74GFUg78JRhLOJCaUXjwOHuQMbzpWHnMyrj88nEJkEtHwYs1vxf9GWvyhhES6h7ZyusxJhy+Ybww==
+"@abp/cms-kit.public@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/cms-kit.public/-/cms-kit.public-5.3.0-rc.1.tgz#4f0fe30a5c6f5450dfde265162d68239e00e2f9b"
+ integrity sha512-B9FX1bq9Ki9bouatcY9MJRbOo8/QLFmq24Ua3ASgmMhMwwSpUUu+GBUtxpUkRepWcpPze4m3rWIn5Ff8ZVnOEw==
dependencies:
- "@abp/highlight.js" "~5.2.1"
- "@abp/star-rating-svg" "~5.2.1"
+ "@abp/highlight.js" "~5.3.0-rc.1"
+ "@abp/star-rating-svg" "~5.3.0-rc.1"
-"@abp/cms-kit@5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/cms-kit/-/cms-kit-5.2.1.tgz#2cab9de4bb4e14ec39f8a2086b16fc38556af6bb"
- integrity sha512-SuIJYj8LAdYeATYrpLxRGg7gMQ52Wq2gApriv7c7pC45mPQosi57wjEMvsI2MKAurEwQqTf7J38R3UJNRgmQbQ==
+"@abp/cms-kit@5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/cms-kit/-/cms-kit-5.3.0-rc.1.tgz#da749badac6681d8049a4d6c522c172fdb72f02b"
+ integrity sha512-ACKZf69dGti9W8M0ZZWn0UiZA+LlGqQtEx9rkTnzrzma4uePsDvIFvbMGyK8UZLSVGHOVVhE2kN1OGTioeqgGw==
dependencies:
- "@abp/cms-kit.admin" "~5.2.1"
- "@abp/cms-kit.public" "~5.2.1"
+ "@abp/cms-kit.admin" "~5.3.0-rc.1"
+ "@abp/cms-kit.public" "~5.3.0-rc.1"
-"@abp/core@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/core/-/core-5.2.1.tgz#9cd7f25dec0b4e654f7998f89c19f3d73169c74a"
- integrity sha512-FDOhIPjig3oGxkbadJZzFSC1ZHzgQV4R75fsDNH56lQ9mTyRUPQdg0Y54eCtY7yOSjiJOctOUUWHaxoFG7frGQ==
+"@abp/codemirror@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/codemirror/-/codemirror-5.3.0-rc.1.tgz#20386caeffa7f0a65030a635532935d669fc5295"
+ integrity sha512-46AeZEeHEvOKjA6KS/SkhiizoLqQUB9cRJfOgT7NKP18OKx5ra4+Cj2CGtoq2N+FjuA7hgdnbbjX8E1GkfHAPg==
dependencies:
- "@abp/utils" "~5.2.1"
+ "@abp/core" "~5.3.0-rc.1"
+ codemirror "^5.65.1"
-"@abp/datatables.net-bs5@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs5/-/datatables.net-bs5-5.2.1.tgz#fafc65295d00d5b351404740702f7e56ff1341fe"
- integrity sha512-B8lSAeMM9qOwYbDK/Dhp7BX5lFaCpao4RCPcSqgFrye8vlH8bcobmp4tMD23r24y/gRIEuQBcKzp0Lf0OUpLhA==
+"@abp/core@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/core/-/core-5.3.0-rc.1.tgz#4ede309ccfab440deb66fecb091273027483676a"
+ integrity sha512-cTw9xaWMkRDQjXRtkB5zx4Za0CPx7yvCRnTngIJs7xO86lRMVnuiwVGjP66vYTmiiu2ulGFgCeuw1AaK5t+g4Q==
dependencies:
- "@abp/datatables.net" "~5.2.1"
+ "@abp/utils" "~5.3.0-rc.1"
+
+"@abp/datatables.net-bs5@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/datatables.net-bs5/-/datatables.net-bs5-5.3.0-rc.1.tgz#ca624d788acdcc547d0bdf1f76ba3ffc105dfd52"
+ integrity sha512-uyFBkD9rM3wGve0ZKrr7bEbC0Z/ywi8S/EYL6GwLzGNtogSsVj5HGtSvifKjCBn7KmAvo54skKoVgVEn77dlWQ==
+ dependencies:
+ "@abp/datatables.net" "~5.3.0-rc.1"
datatables.net-bs5 "^1.11.4"
-"@abp/datatables.net@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-5.2.1.tgz#397a3e7db2017c20c082598214478c277b2abec6"
- integrity sha512-6Q3+W+d8e4TMAkZr/IdPDQuL1v+tjbS50ChLvrJX/BLb4fBhu1LGJWWKzKJFj721DwIsuQQiM4uq9xX/TjiS0w==
+"@abp/datatables.net@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/datatables.net/-/datatables.net-5.3.0-rc.1.tgz#38c0f6323f7e6305a50f7de9885b8a3f440cdf15"
+ integrity sha512-lecJ9Yelgey/nfSscsUHET0gyB6pZgkhnJXu3u8d9XhV2M5sc/WSnnCO3bgVBqMDImprR4GFPFw2cUlWkb8QBg==
dependencies:
- "@abp/jquery" "~5.2.1"
+ "@abp/jquery" "~5.3.0-rc.1"
datatables.net "^1.11.4"
-"@abp/font-awesome@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-5.2.1.tgz#357785a0366f555b72f76e2b8ee8a2d607aed6fb"
- integrity sha512-9fAUdA9QeNRMjp6v8i6EOR480bjB4OzqzriFCKUu4k6VwbA6PxUsJIRFyKIt5UpC12Zqdhpkyj0iG6tE0nRekQ==
+"@abp/font-awesome@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/font-awesome/-/font-awesome-5.3.0-rc.1.tgz#de14dca2b33fdc098d2325c5047e030a3927bfa9"
+ integrity sha512-tIuDwo+L5CuLpQ+ARsaTYmxuqpSJLqcaXuoFfk6JAC20bw881t7y8w4xWy1PUs0+SEQwTT7diZjQrcA/xxlMUQ==
dependencies:
- "@abp/core" "~5.2.1"
+ "@abp/core" "~5.3.0-rc.1"
"@fortawesome/fontawesome-free" "^5.15.4"
-"@abp/highlight.js@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/highlight.js/-/highlight.js-5.2.1.tgz#345e826047b2e87861d08b5ca2a9e5a313c22bda"
- integrity sha512-Pi/pMWqdvdBr0E63UrhapuUtNNoY9Jt3R1Py52JQ0r90r53k5fmYOIaSwmaFlVZ8T/JApJt2D9i0Z4k8Tcn7Vg==
+"@abp/highlight.js@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/highlight.js/-/highlight.js-5.3.0-rc.1.tgz#a6dad18c759ff4c1488b6aef4898d88d55e0ce1a"
+ integrity sha512-z4vvoETKcciumaED4hnpgrUnjWhtRejG+nW/er+X1dxrUJk58oh6ReFs0/xb+xlrKc/ALOYTh0VY5LBU2KU5Qw==
dependencies:
- "@abp/core" "~5.2.1"
+ "@abp/core" "~5.3.0-rc.1"
"@highlightjs/cdn-assets" "~11.4.0"
-"@abp/jquery-form@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-5.2.1.tgz#c9cc6ad3997f7fa036d5cd8e0d15923ad7fff790"
- integrity sha512-L7uKs7vReOQEETG9xIDq5aXjshbaPa+ZZQcCbn2uwY813e0ErS7Rb1mnowEt/LNEB02AtLet1B4TDVwZUl1uXQ==
+"@abp/jquery-form@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/jquery-form/-/jquery-form-5.3.0-rc.1.tgz#0a363d8e4814651e0c46e2109d19dcc84fc884b0"
+ integrity sha512-IWazO6BW5rHJ+ODk4haEqWzfzHvbxtW2+T1o534Lr7d+LI9yabNiQmRZ24yzNDb6SmRvDUVsumZ+lxPn2WBhIw==
dependencies:
- "@abp/jquery" "~5.2.1"
+ "@abp/jquery" "~5.3.0-rc.1"
jquery-form "^4.3.0"
-"@abp/jquery-validation-unobtrusive@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-5.2.1.tgz#7fdfa3867f61f862ee575114560f79b505649093"
- integrity sha512-uZ36D1FfoLdBb6h44fQ3kZuTk4gJ5yzhyOprkgMsGAJDVakX7w/W4V3ThpiEO+iUpNKTboVIhW2QQ0AXK9rrsg==
+"@abp/jquery-validation-unobtrusive@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-5.3.0-rc.1.tgz#0aa2a5535acd79b5288ef04a0dc1b83a7a57b4b9"
+ integrity sha512-Qv/+nrd+ZeUs/2mCMahpQFqEguMOcmHrLg7hcw0LgcHr+MmEcG4WDcijTY6suFyekaf0DZD6vsFZjdvZmhsVYQ==
dependencies:
- "@abp/jquery-validation" "~5.2.1"
+ "@abp/jquery-validation" "~5.3.0-rc.1"
jquery-validation-unobtrusive "^3.2.12"
-"@abp/jquery-validation@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-5.2.1.tgz#e7fbaa1715af5667559e3b6f0fcb916766b28244"
- integrity sha512-Rr/+SWGlXJ53jfysMB/HVNZqsJKCF3rg23ip2Kg6Q+kQTvWVRE3tpkpoBJczOii5tPUk/A/lsJKgRlcsnP0ASw==
+"@abp/jquery-validation@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/jquery-validation/-/jquery-validation-5.3.0-rc.1.tgz#d05afbe0209c0815afe3a7cb0cf811256e9905fc"
+ integrity sha512-3DoRX6c8duRx1/g7MFuPAO/qesJCFqbVbw+x0+QnKmCkVZmz5VFAqdO9yFMxDFRbBAtyp7faaarc0lOtAcBsoA==
dependencies:
- "@abp/jquery" "~5.2.1"
+ "@abp/jquery" "~5.3.0-rc.1"
jquery-validation "^1.19.3"
-"@abp/jquery@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-5.2.1.tgz#6b88af5c22fb25d953d38847bcddcf591aeb3228"
- integrity sha512-FiIRnDx/gm6JR8QljiulwCc5d8+YC123X0qxMIBI8IY9vznEX+Jk48jYG8fLABnRqKEIYfV8UsYSK8IJx3mcSg==
+"@abp/jquery@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/jquery/-/jquery-5.3.0-rc.1.tgz#26e5d5761f2629d02b2534ad964080221d536308"
+ integrity sha512-//bqInarV6XOs8+I5GW1q/c05sjnCq/Z0vuzFW1i1NDrQ2Q5kqF5leMV9hhGEZmfR+yG1T0MsbVvueieRkV/cA==
dependencies:
- "@abp/core" "~5.2.1"
+ "@abp/core" "~5.3.0-rc.1"
jquery "~3.6.0"
-"@abp/jstree@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/jstree/-/jstree-5.2.1.tgz#27f8c80053fbd7f5b242cc144b3ebdc33a668b9d"
- integrity sha512-KYcdkjm33OEOBH/HHgOvIoVX8Bg/KlTJ4muyWYzPK0JK8T61rjrAw8cnlvMl5fqnuzdUUWFgfpuZq7HhgU30NQ==
+"@abp/jstree@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/jstree/-/jstree-5.3.0-rc.1.tgz#e6c4a3ed1afe23ba3029674833c3135ac37dceda"
+ integrity sha512-MKJX2IXtTijjNfGNoy486/XdQ7nncIaoUSAZUcah0NXP1cyBC+PMl+zI9y1G/nJsAjX7zSpmWh8TXkbP20HZBQ==
dependencies:
- "@abp/jquery" "~5.2.1"
+ "@abp/jquery" "~5.3.0-rc.1"
jstree "^3.3.12"
-"@abp/lodash@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-5.2.1.tgz#87601162025a4a376e3c335d418636ef2079ad2d"
- integrity sha512-ILg3X5tTH2HhJMRmg7BP/r+Kstm/nf+0aNQ2exsJoMMnKE7CC0eYQjpSgrze6GwG3a13eamyTlrz+RrlIm5IBA==
+"@abp/lodash@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/lodash/-/lodash-5.3.0-rc.1.tgz#c53304fbd9b1c885a9a812c681c3698dd8ecea47"
+ integrity sha512-yBvUB05z/SSEEbZ79nFfb0cKwWVFbrt9OtUkQHy9ER7ip0R9escG2n1djFtAA33yZr/NLzSUh+vVBYsEhk8MOA==
dependencies:
- "@abp/core" "~5.2.1"
+ "@abp/core" "~5.3.0-rc.1"
lodash "^4.17.21"
-"@abp/luxon@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-5.2.1.tgz#72a9e9bb0e7f3a688662c8e9ad52016b9cfa3a17"
- integrity sha512-D3KVsba969UBYktdbCxq1JQp4kYZ1S7rIMymDJMBoHByXxwwdeXMkvuphAifBmSYTt3K6bNoZdR0VxtnNlPn2A==
+"@abp/luxon@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/luxon/-/luxon-5.3.0-rc.1.tgz#bcb4de01b20a8e4da8db186e88fdebfcde47fb8f"
+ integrity sha512-SLozcDvCL/2jyvG2ZU+DHjzbfHYdmwiRjWu7gWyNjaY2e6D3NraHHjpMQ7ubObXZRlhhvfcp0i6eeKKoZNJtEQ==
dependencies:
- "@abp/core" "~5.2.1"
+ "@abp/core" "~5.3.0-rc.1"
luxon "^2.3.0"
-"@abp/malihu-custom-scrollbar-plugin@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-5.2.1.tgz#8d1b600552607e28a274775ad3bb68ac7cfbba09"
- integrity sha512-5mvABMCT7tiwPl1vUK8kriN/SRi2gC4VqkEuxghT7uBQG9Cqh5jhJrl80M9ZK/oQFind3r6+SF8OlfwF8yvxHQ==
+"@abp/malihu-custom-scrollbar-plugin@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-5.3.0-rc.1.tgz#398181c7c6cc1805544e7a1ccd0423ed96005e0b"
+ integrity sha512-KZar881wtotKc+1bqDlBWo2vLUEeeqEpMBg8+BiXsGofp5ovudifVPM6mHZ9Gi29U9LAMyI0VEGwLJctgB/UoA==
dependencies:
- "@abp/core" "~5.2.1"
+ "@abp/core" "~5.3.0-rc.1"
malihu-custom-scrollbar-plugin "^3.1.5"
-"@abp/prismjs@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/prismjs/-/prismjs-5.2.1.tgz#86aae6ee4529401da75744f1e43c7cd3c0b494a0"
- integrity sha512-YNgcM7Kvmu3hGXJh4B8gl7rLzC28VuZYYP7AVptVSbTz/n6usCo21evG/st8L3vXixuQkvnNpBFgacJnHdSJZQ==
+"@abp/prismjs@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/prismjs/-/prismjs-5.3.0-rc.1.tgz#ee1a49b8bd0af2a29aa7bfb93d22ce07a4edbe70"
+ integrity sha512-oOnzwUtI6q2u7iE/YWQEULm1I+f7Bo+0tQ9rYlzIoalBRnqN57Zw0VMf5AHq8qjn6GiInehPtU9wsaVTPqXmtw==
dependencies:
- "@abp/clipboard" "~5.2.1"
- "@abp/core" "~5.2.1"
+ "@abp/clipboard" "~5.3.0-rc.1"
+ "@abp/core" "~5.3.0-rc.1"
prismjs "^1.26.0"
-"@abp/select2@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-5.2.1.tgz#f52a3c88da52bbfc4b135671064326aebb98b332"
- integrity sha512-JH/PqOxhTY05sUyN7of6TNai0W4M3N3OF3Hlwmr8i7hNdYfFwJvQnQzKeKrk/vt8Hv44/JTQDlNKU02BmSBfOQ==
+"@abp/select2@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/select2/-/select2-5.3.0-rc.1.tgz#b2ce00b6545674d6bccc10fdfe4626a4598a0cdc"
+ integrity sha512-frE5jia7bBdZinW4LqD5JR+wknWu2ARX3L3pPiQ080ulB+P58gRj07ZPd1BWgRcvutnuANYyP9rZtDA18Ls+9Q==
dependencies:
- "@abp/core" "~5.2.1"
+ "@abp/core" "~5.3.0-rc.1"
select2 "^4.0.13"
-"@abp/slugify@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/slugify/-/slugify-5.2.1.tgz#97c8b54fcfc271e7fb2f1697fafa3dff30ba6891"
- integrity sha512-e/QxzbeOJYgKdYJQSCeP7QnnraLEafxB/AAzQDDJH2hKid9lNDeUxjggw/xCSiiRCG9Qz8OYuei6bNaYDHcxbQ==
+"@abp/slugify@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/slugify/-/slugify-5.3.0-rc.1.tgz#dfebf924365d8627a6dae770394396ffa383a960"
+ integrity sha512-gPHLGVfrXSiuUMxEdPpZm6ie+ZkOVk2SXb9B2/+ndL+Wy8FYJiP6v2xn0SJ3ENqGL4nvuZdDOfAGKbrICpb/Pg==
dependencies:
slugify "^1.6.5"
-"@abp/star-rating-svg@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/star-rating-svg/-/star-rating-svg-5.2.1.tgz#f8cd6a965079acfa3633731eacf653e142886c1e"
- integrity sha512-QofOzA0kjpXEm80tkxBptKYTUZa4uolHRy4KNTzDFdcf8TyC6hT8I6kmUS9ym7F3HKLjLhDWfRsd1kKaDwxzQw==
+"@abp/star-rating-svg@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/star-rating-svg/-/star-rating-svg-5.3.0-rc.1.tgz#1589d7407932c6113312a6dbc43be32363363314"
+ integrity sha512-o7fP05qMm7OP9A1TPf5ysSqnujC6WWMQEUceIqRdp2UWiLKd8c/3GrtLbA+NDDN7ddES8JPrU98ENdfRxqb6CA==
dependencies:
- "@abp/jquery" "~5.2.1"
+ "@abp/jquery" "~5.3.0-rc.1"
star-rating-svg "^3.5.0"
-"@abp/sweetalert2@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/sweetalert2/-/sweetalert2-5.2.1.tgz#f5ff712b4f7a4cb5a75a754aa4642f099f382e51"
- integrity sha512-laaF/5WhYw+hNJRTfMzO93fVhaYqnnOcQTUlkGgsZMe2gwebyX73VI8O8Xw7zXmN1Tu/JwqRI46qiafDrPFTLg==
+"@abp/sweetalert2@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/sweetalert2/-/sweetalert2-5.3.0-rc.1.tgz#6eb10b257e7f256da64ff6fe248a370671a26920"
+ integrity sha512-g9nddGcDGaG6EmjX7qpRcLzy3F38BTtFc0RBWApH7Da1o/LMYFYa6xGfS7ouIynZBM9j/BRP12CVTR+Y9qqbGg==
dependencies:
- "@abp/core" "~5.2.1"
+ "@abp/core" "~5.3.0-rc.1"
sweetalert2 "^11.3.6"
-"@abp/timeago@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-5.2.1.tgz#a410dbf652c0f78f86384e116111aa613458b6de"
- integrity sha512-xmgqKEKusB6pcqFhMaz8RTi886ad8RrRMYgMWSw4Zjk1Lr9EqQwKtcE43Ve5XWJamh2Wpk8H7IKLQKHfrV12oA==
+"@abp/timeago@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/timeago/-/timeago-5.3.0-rc.1.tgz#2702a0f22db52dbf4c0717e4abcd317c56d10563"
+ integrity sha512-XRc4D98FIZR0YTXIoV0+OxVJTdixtNDiwatZRffopHT4Kpptmpj6O9KMcB4SngCH99/TrUFdEUnA2CgszxiEOA==
dependencies:
- "@abp/jquery" "~5.2.1"
+ "@abp/jquery" "~5.3.0-rc.1"
timeago "^1.6.7"
-"@abp/toastr@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/toastr/-/toastr-5.2.1.tgz#4ed96a7967d028b8e849ff79b8a0a8a041bb20e4"
- integrity sha512-HrnIzvM9LgQdzlmLmvHUVSG4PmWfx9YuozxkFTv+AGa2FAPby5W9hbQ025ry3bPkU9lGWSu/w7JSDqoiL16bPA==
+"@abp/toastr@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/toastr/-/toastr-5.3.0-rc.1.tgz#ec3a3d302ac91d5393c3caeb8b4884ad811b6edb"
+ integrity sha512-InZweYuBkrNZNBQKp6A+6gxGdO/lB0XsrXaa+CIVe55p8aNJPzE0mnvSfKWhN5G273wR08AD9RjR22kYS+bgFA==
dependencies:
- "@abp/jquery" "~5.2.1"
+ "@abp/jquery" "~5.3.0-rc.1"
toastr "^2.1.4"
-"@abp/tui-editor@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/tui-editor/-/tui-editor-5.2.1.tgz#06be1a029de754868fa11ce3479be3fbc90ba103"
- integrity sha512-Mi3preBkGEU1hrtSNCkOjeXPc9c74DFt8BL82sPIVDglYcVrVLXbnNTWE/CHP0spmKWh33ek4FoH1Pt0TePMuw==
+"@abp/tui-editor@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/tui-editor/-/tui-editor-5.3.0-rc.1.tgz#d5b6e46c922e9743216395bc055ed8208c2ead0b"
+ integrity sha512-wMEph23kwGJyAGweivKn2EDTRQQD0UG0X23qMd4Cv285qdu4AoYL2/shBDFKiXfhN0Q7EZ06mhOyTuhJmTnNUg==
dependencies:
- "@abp/jquery" "~5.2.1"
- "@abp/prismjs" "~5.2.1"
+ "@abp/jquery" "~5.3.0-rc.1"
+ "@abp/prismjs" "~5.3.0-rc.1"
-"@abp/uppy@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/uppy/-/uppy-5.2.1.tgz#560bbb363a0b0b493cc2f1c20f4f7b51e95cb331"
- integrity sha512-cLqeGHrfwuOgPKjIBTq7H/l3P494sEgmrdH3UW9wVIjD5OAIbK/2AeZ2xTIIg0Mn+ALm+rqfsw0+qBoBug1WHQ==
+"@abp/uppy@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/uppy/-/uppy-5.3.0-rc.1.tgz#19f2e09eb6a34e70e08f7d79189624012ab265dd"
+ integrity sha512-a4V1MzvLdCfI4va8U7nxvUfsh/+h4UG+Utu/HFJ2iHPpH/cj/xIBbCWljDt4uToHUIiZ2kXVCE+0TfWiYV+JJQ==
dependencies:
- "@abp/core" "~5.2.1"
+ "@abp/core" "~5.3.0-rc.1"
uppy "^1.16.1"
-"@abp/utils@~5.2.1":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-5.2.1.tgz#7c2d20f1bcc8cf9f90c060ed31ed3a114a463064"
- integrity sha512-9hxI24aRZCnxCP+WsOoCltSg4YqG9WtW06t9/f6hFO9B0udXIKyV+95Ndipca/R1G94Snx81ifSwAa+DHbFfvQ==
+"@abp/utils@~5.3.0-rc.1":
+ version "5.3.0-rc.1"
+ resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-5.3.0-rc.1.tgz#3fa758944e7325e7b3f528141e03bb71f8e04d24"
+ integrity sha512-/8BTYZomNMdy+RpYXWLp5dg0lRhmfiguciZEVWo4qRw1lCXm/JR+0842XT1XYE1dQ4orNNJ3/H86eRX8Ab6Yfg==
dependencies:
just-compare "^1.3.0"
@@ -999,6 +1008,11 @@ code-point-at@^1.0.0:
resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=
+codemirror@^5.65.1:
+ version "5.65.3"
+ resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.65.3.tgz#2d029930d5a293bc5fb96ceea64654803c0d4ac7"
+ integrity sha512-kCC0iwGZOVZXHEKW3NDTObvM7pTIyowjty4BUqeREROc/3I6bWbgZDA3fGDwlA+rbgRjvnRnfqs9SfXynel1AQ==
+
collection-map@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/collection-map/-/collection-map-1.0.0.tgz#aea0f06f8d26c780c2b75494385544b2255af18c"
diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/BlogPostAdminClientProxy.Generated.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/BlogPostAdminClientProxy.Generated.cs
index 974d0a279b..ba54e8e334 100644
--- a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/BlogPostAdminClientProxy.Generated.cs
+++ b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/BlogPostAdminClientProxy.Generated.cs
@@ -55,20 +55,20 @@ public partial class BlogPostAdminClientProxy : ClientProxyBase CreateAndSendToReviewAsync(CreateBlogPostDto input)
{
return await RequestAsync(nameof(CreateAndSendToReviewAsync), new ClientProxyRequestTypeValue
@@ -95,7 +95,7 @@ public partial class BlogPostAdminClientProxy : ClientProxyBase HasBlogPostWaitingForReviewAsync()
{
return await RequestAsync(nameof(HasBlogPostWaitingForReviewAsync));
diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/cms-kit-admin-generate-proxy.json b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/cms-kit-admin-generate-proxy.json
index 1a2814324d..0e93081b39 100644
--- a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/cms-kit-admin-generate-proxy.json
+++ b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi.Client/ClientProxies/cms-kit-admin-generate-proxy.json
@@ -1941,6 +1941,30 @@
"bindingSourceId": "ModelBinding",
"descriptorName": "input"
},
+ {
+ "nameOnMethod": "input",
+ "name": "AuthorId",
+ "jsonName": null,
+ "type": "System.Guid?",
+ "typeSimple": "string?",
+ "isOptional": false,
+ "defaultValue": null,
+ "constraintTypes": null,
+ "bindingSourceId": "ModelBinding",
+ "descriptorName": "input"
+ },
+ {
+ "nameOnMethod": "input",
+ "name": "Status",
+ "jsonName": null,
+ "type": "Volo.CmsKit.Blogs.BlogPostStatus?",
+ "typeSimple": "Volo.CmsKit.Blogs.BlogPostStatus?",
+ "isOptional": false,
+ "defaultValue": null,
+ "constraintTypes": null,
+ "bindingSourceId": "ModelBinding",
+ "descriptorName": "input"
+ },
{
"nameOnMethod": "input",
"name": "Sorting",
@@ -2041,6 +2065,206 @@
},
"allowAnonymous": false,
"implementFrom": "Volo.Abp.Application.Services.IUpdateAppService"
+ },
+ "PublishAsyncById": {
+ "uniqueName": "PublishAsyncById",
+ "name": "PublishAsync",
+ "httpMethod": "POST",
+ "url": "api/cms-kit-admin/blogs/blog-posts/{id}/publish",
+ "supportedVersions": [],
+ "parametersOnMethod": [
+ {
+ "name": "id",
+ "typeAsString": "System.Guid, System.Private.CoreLib",
+ "type": "System.Guid",
+ "typeSimple": "string",
+ "isOptional": false,
+ "defaultValue": null
+ }
+ ],
+ "parameters": [
+ {
+ "nameOnMethod": "id",
+ "name": "id",
+ "jsonName": null,
+ "type": "System.Guid",
+ "typeSimple": "string",
+ "isOptional": false,
+ "defaultValue": null,
+ "constraintTypes": [],
+ "bindingSourceId": "Path",
+ "descriptorName": ""
+ }
+ ],
+ "returnValue": {
+ "type": "System.Void",
+ "typeSimple": "System.Void"
+ },
+ "allowAnonymous": false,
+ "implementFrom": "Volo.CmsKit.Admin.Blogs.IBlogPostAdminAppService"
+ },
+ "DraftAsyncById": {
+ "uniqueName": "DraftAsyncById",
+ "name": "DraftAsync",
+ "httpMethod": "POST",
+ "url": "api/cms-kit-admin/blogs/blog-posts/{id}/draft",
+ "supportedVersions": [],
+ "parametersOnMethod": [
+ {
+ "name": "id",
+ "typeAsString": "System.Guid, System.Private.CoreLib",
+ "type": "System.Guid",
+ "typeSimple": "string",
+ "isOptional": false,
+ "defaultValue": null
+ }
+ ],
+ "parameters": [
+ {
+ "nameOnMethod": "id",
+ "name": "id",
+ "jsonName": null,
+ "type": "System.Guid",
+ "typeSimple": "string",
+ "isOptional": false,
+ "defaultValue": null,
+ "constraintTypes": [],
+ "bindingSourceId": "Path",
+ "descriptorName": ""
+ }
+ ],
+ "returnValue": {
+ "type": "System.Void",
+ "typeSimple": "System.Void"
+ },
+ "allowAnonymous": false,
+ "implementFrom": "Volo.CmsKit.Admin.Blogs.IBlogPostAdminAppService"
+ },
+ "CreateAndPublishAsyncByInput": {
+ "uniqueName": "CreateAndPublishAsyncByInput",
+ "name": "CreateAndPublishAsync",
+ "httpMethod": "POST",
+ "url": "api/cms-kit-admin/blogs/blog-posts/create-and-publish",
+ "supportedVersions": [],
+ "parametersOnMethod": [
+ {
+ "name": "input",
+ "typeAsString": "Volo.CmsKit.Admin.Blogs.CreateBlogPostDto, Volo.CmsKit.Admin.Application.Contracts",
+ "type": "Volo.CmsKit.Admin.Blogs.CreateBlogPostDto",
+ "typeSimple": "Volo.CmsKit.Admin.Blogs.CreateBlogPostDto",
+ "isOptional": false,
+ "defaultValue": null
+ }
+ ],
+ "parameters": [
+ {
+ "nameOnMethod": "input",
+ "name": "input",
+ "jsonName": null,
+ "type": "Volo.CmsKit.Admin.Blogs.CreateBlogPostDto",
+ "typeSimple": "Volo.CmsKit.Admin.Blogs.CreateBlogPostDto",
+ "isOptional": false,
+ "defaultValue": null,
+ "constraintTypes": null,
+ "bindingSourceId": "Body",
+ "descriptorName": ""
+ }
+ ],
+ "returnValue": {
+ "type": "Volo.CmsKit.Admin.Blogs.BlogPostDto",
+ "typeSimple": "Volo.CmsKit.Admin.Blogs.BlogPostDto"
+ },
+ "allowAnonymous": false,
+ "implementFrom": "Volo.CmsKit.Admin.Blogs.IBlogPostAdminAppService"
+ },
+ "SendToReviewAsyncById": {
+ "uniqueName": "SendToReviewAsyncById",
+ "name": "SendToReviewAsync",
+ "httpMethod": "POST",
+ "url": "api/cms-kit-admin/blogs/blog-posts/{id}/send-to-review",
+ "supportedVersions": [],
+ "parametersOnMethod": [
+ {
+ "name": "id",
+ "typeAsString": "System.Guid, System.Private.CoreLib",
+ "type": "System.Guid",
+ "typeSimple": "string",
+ "isOptional": false,
+ "defaultValue": null
+ }
+ ],
+ "parameters": [
+ {
+ "nameOnMethod": "id",
+ "name": "id",
+ "jsonName": null,
+ "type": "System.Guid",
+ "typeSimple": "string",
+ "isOptional": false,
+ "defaultValue": null,
+ "constraintTypes": [],
+ "bindingSourceId": "Path",
+ "descriptorName": ""
+ }
+ ],
+ "returnValue": {
+ "type": "System.Void",
+ "typeSimple": "System.Void"
+ },
+ "allowAnonymous": false,
+ "implementFrom": "Volo.CmsKit.Admin.Blogs.IBlogPostAdminAppService"
+ },
+ "CreateAndSendToReviewAsyncByInput": {
+ "uniqueName": "CreateAndSendToReviewAsyncByInput",
+ "name": "CreateAndSendToReviewAsync",
+ "httpMethod": "POST",
+ "url": "api/cms-kit-admin/blogs/blog-posts/create-and-send-to-review",
+ "supportedVersions": [],
+ "parametersOnMethod": [
+ {
+ "name": "input",
+ "typeAsString": "Volo.CmsKit.Admin.Blogs.CreateBlogPostDto, Volo.CmsKit.Admin.Application.Contracts",
+ "type": "Volo.CmsKit.Admin.Blogs.CreateBlogPostDto",
+ "typeSimple": "Volo.CmsKit.Admin.Blogs.CreateBlogPostDto",
+ "isOptional": false,
+ "defaultValue": null
+ }
+ ],
+ "parameters": [
+ {
+ "nameOnMethod": "input",
+ "name": "input",
+ "jsonName": null,
+ "type": "Volo.CmsKit.Admin.Blogs.CreateBlogPostDto",
+ "typeSimple": "Volo.CmsKit.Admin.Blogs.CreateBlogPostDto",
+ "isOptional": false,
+ "defaultValue": null,
+ "constraintTypes": null,
+ "bindingSourceId": "Body",
+ "descriptorName": ""
+ }
+ ],
+ "returnValue": {
+ "type": "Volo.CmsKit.Admin.Blogs.BlogPostDto",
+ "typeSimple": "Volo.CmsKit.Admin.Blogs.BlogPostDto"
+ },
+ "allowAnonymous": false,
+ "implementFrom": "Volo.CmsKit.Admin.Blogs.IBlogPostAdminAppService"
+ },
+ "HasBlogPostWaitingForReviewAsync": {
+ "uniqueName": "HasBlogPostWaitingForReviewAsync",
+ "name": "HasBlogPostWaitingForReviewAsync",
+ "httpMethod": "GET",
+ "url": "api/cms-kit-admin/blogs/blog-posts/has-blogpost-waiting-for-review",
+ "supportedVersions": [],
+ "parametersOnMethod": [],
+ "parameters": [],
+ "returnValue": {
+ "type": "System.Boolean",
+ "typeSimple": "boolean"
+ },
+ "allowAnonymous": false,
+ "implementFrom": "Volo.CmsKit.Admin.Blogs.IBlogPostAdminAppService"
}
}
}
diff --git a/modules/cms-kit/src/Volo.CmsKit.Common.HttpApi.Client/ClientProxies/cms-kit-common-generate-proxy.json b/modules/cms-kit/src/Volo.CmsKit.Common.HttpApi.Client/ClientProxies/cms-kit-common-generate-proxy.json
index ba052dc973..6b7b45220a 100644
--- a/modules/cms-kit/src/Volo.CmsKit.Common.HttpApi.Client/ClientProxies/cms-kit-common-generate-proxy.json
+++ b/modules/cms-kit/src/Volo.CmsKit.Common.HttpApi.Client/ClientProxies/cms-kit-common-generate-proxy.json
@@ -7,6 +7,8 @@
"Volo.CmsKit.MediaDescriptors.MediaDescriptorController": {
"controllerName": "MediaDescriptor",
"controllerGroupName": "MediaDescriptor",
+ "isRemoteService": true,
+ "apiVersion": null,
"type": "Volo.CmsKit.MediaDescriptors.MediaDescriptorController",
"interfaces": [
{
@@ -56,6 +58,8 @@
"Volo.CmsKit.Blogs.BlogFeatureController": {
"controllerName": "BlogFeature",
"controllerGroupName": "BlogFeature",
+ "isRemoteService": true,
+ "apiVersion": null,
"type": "Volo.CmsKit.Blogs.BlogFeatureController",
"interfaces": [
{
diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/wwwroot/client-proxies/cms-kit-proxy.js b/modules/cms-kit/src/Volo.CmsKit.Public.Web/wwwroot/client-proxies/cms-kit-proxy.js
index 6b2e3f1b04..e1cdae5ec3 100644
--- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/wwwroot/client-proxies/cms-kit-proxy.js
+++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/wwwroot/client-proxies/cms-kit-proxy.js
@@ -188,7 +188,21 @@
volo.cmsKit.public.blogs.blogPostPublic.getList = function(blogSlug, input, ajaxParams) {
return abp.ajax($.extend(true, {
- url: abp.appPath + 'api/cms-kit-public/blog-posts/' + blogSlug + '' + abp.utils.buildQueryString([{ name: 'skipCount', value: input.skipCount }, { name: 'maxResultCount', value: input.maxResultCount }, { name: 'sorting', value: input.sorting }]) + '',
+ url: abp.appPath + 'api/cms-kit-public/blog-posts/' + blogSlug + '' + abp.utils.buildQueryString([{ name: 'authorId', value: input.authorId }, { name: 'sorting', value: input.sorting }, { name: 'skipCount', value: input.skipCount }, { name: 'maxResultCount', value: input.maxResultCount }]) + '',
+ type: 'GET'
+ }, ajaxParams));
+ };
+
+ volo.cmsKit.public.blogs.blogPostPublic.getAuthorsHasBlogPosts = function(input, ajaxParams) {
+ return abp.ajax($.extend(true, {
+ url: abp.appPath + 'api/cms-kit-public/blog-posts/authors' + abp.utils.buildQueryString([{ name: 'filter', value: input.filter }, { name: 'sorting', value: input.sorting }, { name: 'skipCount', value: input.skipCount }, { name: 'maxResultCount', value: input.maxResultCount }]) + '',
+ type: 'GET'
+ }, ajaxParams));
+ };
+
+ volo.cmsKit.public.blogs.blogPostPublic.getAuthorHasBlogPost = function(id, ajaxParams) {
+ return abp.ajax($.extend(true, {
+ url: abp.appPath + 'api/cms-kit-public/blog-posts/authors/' + id + '',
type: 'GET'
}, ajaxParams));
};
diff --git a/modules/docs/app/VoloDocs.Web/package.json b/modules/docs/app/VoloDocs.Web/package.json
index 2ec4d524e2..bfd84f86a8 100644
--- a/modules/docs/app/VoloDocs.Web/package.json
+++ b/modules/docs/app/VoloDocs.Web/package.json
@@ -3,7 +3,7 @@
"name": "volo.docstestapp",
"private": true,
"dependencies": {
- "@abp/aspnetcore.mvc.ui.theme.basic": "^5.2.1",
- "@abp/docs": "^5.2.1"
+ "@abp/aspnetcore.mvc.ui.theme.basic": "^5.3.0-rc.1",
+ "@abp/docs": "^5.3.0-rc.1"
}
}
diff --git a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/CHANGELOG.md b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/CHANGELOG.md
index 6329ab4686..2d792fe64d 100644
--- a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/CHANGELOG.md
+++ b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/CHANGELOG.md
@@ -1,40 +1,129 @@
# Prism Changelog
+## 1.28.0 (2022-04-17)
+
+### New components
+
+* __Ado__ & __Mata__ (Stata) ([#3383](https://github.com/PrismJS/prism/issues/3383)) [`63806d57`](https://github.com/PrismJS/prism/commit/63806d57)
+* __ARM Assembly__ ([#3376](https://github.com/PrismJS/prism/issues/3376)) [`554ff324`](https://github.com/PrismJS/prism/commit/554ff324)
+* __Arturo__ ([#3403](https://github.com/PrismJS/prism/issues/3403)) [`e2fe1f79`](https://github.com/PrismJS/prism/commit/e2fe1f79)
+* __AWK__ & __GAWK__ ([#3374](https://github.com/PrismJS/prism/issues/3374)) [`ea8a0f40`](https://github.com/PrismJS/prism/commit/ea8a0f40)
+* __Cooklang__ ([#3337](https://github.com/PrismJS/prism/issues/3337)) [`4eb928c3`](https://github.com/PrismJS/prism/commit/4eb928c3)
+* __CUE__ ([#3375](https://github.com/PrismJS/prism/issues/3375)) [`a1340666`](https://github.com/PrismJS/prism/commit/a1340666)
+* __gettext__ ([#3369](https://github.com/PrismJS/prism/issues/3369)) [`dfef9b61`](https://github.com/PrismJS/prism/commit/dfef9b61)
+* __GNU Linker Script__ ([#3373](https://github.com/PrismJS/prism/issues/3373)) [`33f2cf95`](https://github.com/PrismJS/prism/commit/33f2cf95)
+* __Odin__ ([#3424](https://github.com/PrismJS/prism/issues/3424)) [`8a3fef6d`](https://github.com/PrismJS/prism/commit/8a3fef6d)
+* __PlantUML__ ([#3372](https://github.com/PrismJS/prism/issues/3372)) [`0d49553c`](https://github.com/PrismJS/prism/commit/0d49553c)
+* __ReScript__ ([#3435](https://github.com/PrismJS/prism/issues/3435)) [`cbef9af7`](https://github.com/PrismJS/prism/commit/cbef9af7)
+* __SuperCollider__ ([#3371](https://github.com/PrismJS/prism/issues/3371)) [`1b1d6731`](https://github.com/PrismJS/prism/commit/1b1d6731)
+
+### Updated components
+
+* __.properties__
+ * Use `key`, `value` for token names; `attr-name`, `attr-value` as aliases ([#3377](https://github.com/PrismJS/prism/issues/3377)) [`b94a664d`](https://github.com/PrismJS/prism/commit/b94a664d)
+* __ABAP__
+ * Sorted keyword list ([#3368](https://github.com/PrismJS/prism/issues/3368)) [`7bda2bf1`](https://github.com/PrismJS/prism/commit/7bda2bf1)
+* __Ada__
+ * Changed `attr-name` to `attribute`; Use `attr-name` as alias ([#3381](https://github.com/PrismJS/prism/issues/3381)) [`cde0b5b2`](https://github.com/PrismJS/prism/commit/cde0b5b2)
+ * Added `or` keyword ([#3380](https://github.com/PrismJS/prism/issues/3380)) [`c30b736f`](https://github.com/PrismJS/prism/commit/c30b736f)
+* __Atmel AVR Assembly__
+ * Fixed `&=` and `|=` operators ([#3395](https://github.com/PrismJS/prism/issues/3395)) [`8c4ae5a5`](https://github.com/PrismJS/prism/commit/8c4ae5a5)
+* __AutoHotkey__
+ * Use standard tokens ([#3385](https://github.com/PrismJS/prism/issues/3385)) [`61c460e8`](https://github.com/PrismJS/prism/commit/61c460e8)
+ * Use general pattern instead of name list for directives ([#3384](https://github.com/PrismJS/prism/issues/3384)) [`7ac84dda`](https://github.com/PrismJS/prism/commit/7ac84dda)
+* __CFScript__
+ * Simplified operator regex ([#3396](https://github.com/PrismJS/prism/issues/3396)) [`6a215fe0`](https://github.com/PrismJS/prism/commit/6a215fe0)
+* __CMake__
+ * Simplified `variable` and `operator` regexes ([#3398](https://github.com/PrismJS/prism/issues/3398)) [`8e59744b`](https://github.com/PrismJS/prism/commit/8e59744b)
+* __Erlang__
+ * Added `begin` keyword ([#3387](https://github.com/PrismJS/prism/issues/3387)) [`cf38d059`](https://github.com/PrismJS/prism/commit/cf38d059)
+* __Excel Formula__
+ * Use more fitting aliases for `function-name`, `range`, and `cell` ([#3391](https://github.com/PrismJS/prism/issues/3391)) [`ef0ec02a`](https://github.com/PrismJS/prism/commit/ef0ec02a)
+* __Flow__
+ * Changed alias of `type` to `class-name` ([#3390](https://github.com/PrismJS/prism/issues/3390)) [`ce41434d`](https://github.com/PrismJS/prism/commit/ce41434d)
+ * Recognise `[Ss]ymbol` as a type ([#3388](https://github.com/PrismJS/prism/issues/3388)) [`3916883a`](https://github.com/PrismJS/prism/commit/3916883a)
+* __GEDCOM__
+ * Update `tag` to `record` ([#3386](https://github.com/PrismJS/prism/issues/3386)) [`f8f95340`](https://github.com/PrismJS/prism/commit/f8f95340)
+* __Groovy__
+ * Added string interpolation without hook ([#3366](https://github.com/PrismJS/prism/issues/3366)) [`5617765f`](https://github.com/PrismJS/prism/commit/5617765f)
+* __Handlebars__
+ * Added Mustache alias ([#3422](https://github.com/PrismJS/prism/issues/3422)) [`cb5229af`](https://github.com/PrismJS/prism/commit/cb5229af)
+* __Java__
+ * Improved class name detection ([#3351](https://github.com/PrismJS/prism/issues/3351)) [`4cb3d038`](https://github.com/PrismJS/prism/commit/4cb3d038)
+ * Fixed `record` false positives ([#3348](https://github.com/PrismJS/prism/issues/3348)) [`3bd8fdb1`](https://github.com/PrismJS/prism/commit/3bd8fdb1)
+* __JavaScript__
+ * Added support for new regex syntax ([#3399](https://github.com/PrismJS/prism/issues/3399)) [`ca78cde6`](https://github.com/PrismJS/prism/commit/ca78cde6)
+* __Keyman__
+ * Added new keywords ([#3401](https://github.com/PrismJS/prism/issues/3401)) [`bac36827`](https://github.com/PrismJS/prism/commit/bac36827)
+* __MEL__
+ * Improved functions, code, and comments ([#3393](https://github.com/PrismJS/prism/issues/3393)) [`8e648dab`](https://github.com/PrismJS/prism/commit/8e648dab)
+* __NEON__
+ * Change alias of `key` to `property` ([#3394](https://github.com/PrismJS/prism/issues/3394)) [`1c533f4a`](https://github.com/PrismJS/prism/commit/1c533f4a)
+* __PHP__
+ * Added `never` return type + minor fix of named arguments ([#3421](https://github.com/PrismJS/prism/issues/3421)) [`4ffab525`](https://github.com/PrismJS/prism/commit/4ffab525)
+ * Added `readonly` keyword ([#3349](https://github.com/PrismJS/prism/issues/3349)) [`4c3f1969`](https://github.com/PrismJS/prism/commit/4c3f1969)
+* __PureBasic__
+ * Added support for pointer to string operator ([#3362](https://github.com/PrismJS/prism/issues/3362)) [`499b1fa0`](https://github.com/PrismJS/prism/commit/499b1fa0)
+* __Razor C#__
+ * Added support for `@helper` and inline C# inside attribute values ([#3355](https://github.com/PrismJS/prism/issues/3355)) [`31a38d0c`](https://github.com/PrismJS/prism/commit/31a38d0c)
+* __VHDL__
+ * Add `private`, `view` keywords; Distinguish `attribute` from `keyword` ([#3389](https://github.com/PrismJS/prism/issues/3389)) [`d1a5ce30`](https://github.com/PrismJS/prism/commit/d1a5ce30)
+* __Wolfram language__
+ * Simplified `operator` regex ([#3397](https://github.com/PrismJS/prism/issues/3397)) [`10ae6da3`](https://github.com/PrismJS/prism/commit/10ae6da3)
+
+### Updated plugins
+
+* __Autolinker__
+ * Fixed URL regex to match more valid URLs ([#3358](https://github.com/PrismJS/prism/issues/3358)) [`17ed9160`](https://github.com/PrismJS/prism/commit/17ed9160)
+* __Command Line__
+ * Add support for command continuation prefix ([#3344](https://github.com/PrismJS/prism/issues/3344)) [`b53832cd`](https://github.com/PrismJS/prism/commit/b53832cd)
+ * Increased prompt opacity ([#3352](https://github.com/PrismJS/prism/issues/3352)) [`f95dd190`](https://github.com/PrismJS/prism/commit/f95dd190)
+* __Keep Markup__
+ * Use original nodes instead of clones ([#3365](https://github.com/PrismJS/prism/issues/3365)) [`8a843a17`](https://github.com/PrismJS/prism/commit/8a843a17)
+
+### Other
+
+* __Infrastructure__
+ * Use terser ([#3407](https://github.com/PrismJS/prism/issues/3407)) [`11c54624`](https://github.com/PrismJS/prism/commit/11c54624)
+ * Tests: Cache results for exp backtracking check ([#3356](https://github.com/PrismJS/prism/issues/3356)) [`ead22e1e`](https://github.com/PrismJS/prism/commit/ead22e1e)
+* __Website__
+ * More documentation for language definitons ([#3427](https://github.com/PrismJS/prism/issues/3427)) [`333bd590`](https://github.com/PrismJS/prism/commit/333bd590)
+
## 1.27.0 (2022-02-17)
### New components
-* __UO Razor Script__ (#3309) [`3f8cc5a0`](https://github.com/PrismJS/prism/commit/3f8cc5a0)
+* __UO Razor Script__ ([#3309](https://github.com/PrismJS/prism/issues/3309)) [`3f8cc5a0`](https://github.com/PrismJS/prism/commit/3f8cc5a0)
### Updated components
* __AutoIt__
- * Allow hyphen in directive (#3308) [`bcb2e2c8`](https://github.com/PrismJS/prism/commit/bcb2e2c8)
+ * Allow hyphen in directive ([#3308](https://github.com/PrismJS/prism/issues/3308)) [`bcb2e2c8`](https://github.com/PrismJS/prism/commit/bcb2e2c8)
* __EditorConfig__
- * Change alias of `section` from `keyword` to `selector` (#3305) [`e46501b9`](https://github.com/PrismJS/prism/commit/e46501b9)
+ * Change alias of `section` from `keyword` to `selector` ([#3305](https://github.com/PrismJS/prism/issues/3305)) [`e46501b9`](https://github.com/PrismJS/prism/commit/e46501b9)
* __Ini__
- * Swap out `header` for `section` (#3304) [`deb3a97f`](https://github.com/PrismJS/prism/commit/deb3a97f)
+ * Swap out `header` for `section` ([#3304](https://github.com/PrismJS/prism/issues/3304)) [`deb3a97f`](https://github.com/PrismJS/prism/commit/deb3a97f)
* __MongoDB__
- * Added v5 support (#3297) [`8458c41f`](https://github.com/PrismJS/prism/commit/8458c41f)
+ * Added v5 support ([#3297](https://github.com/PrismJS/prism/issues/3297)) [`8458c41f`](https://github.com/PrismJS/prism/commit/8458c41f)
* __PureBasic__
- * Added missing keyword and fixed constants ending with `$` (#3320) [`d6c53726`](https://github.com/PrismJS/prism/commit/d6c53726)
+ * Added missing keyword and fixed constants ending with `$` ([#3320](https://github.com/PrismJS/prism/issues/3320)) [`d6c53726`](https://github.com/PrismJS/prism/commit/d6c53726)
* __Scala__
- * Added support for interpolated strings (#3293) [`441a1422`](https://github.com/PrismJS/prism/commit/441a1422)
+ * Added support for interpolated strings ([#3293](https://github.com/PrismJS/prism/issues/3293)) [`441a1422`](https://github.com/PrismJS/prism/commit/441a1422)
* __Systemd configuration file__
- * Swap out `operator` for `punctuation` (#3306) [`2eb89e15`](https://github.com/PrismJS/prism/commit/2eb89e15)
+ * Swap out `operator` for `punctuation` ([#3306](https://github.com/PrismJS/prism/issues/3306)) [`2eb89e15`](https://github.com/PrismJS/prism/commit/2eb89e15)
### Updated plugins
* __Command Line__
- * Escape markup in command line output (#3341) [`e002e78c`](https://github.com/PrismJS/prism/commit/e002e78c)
- * Add support for line continuation and improved colors (#3326) [`1784b175`](https://github.com/PrismJS/prism/commit/1784b175)
- * Added span around command and output (#3312) [`82d0ca15`](https://github.com/PrismJS/prism/commit/82d0ca15)
+ * Escape markup in command line output ([#3341](https://github.com/PrismJS/prism/issues/3341)) [`e002e78c`](https://github.com/PrismJS/prism/commit/e002e78c)
+ * Add support for line continuation and improved colors ([#3326](https://github.com/PrismJS/prism/issues/3326)) [`1784b175`](https://github.com/PrismJS/prism/commit/1784b175)
+ * Added span around command and output ([#3312](https://github.com/PrismJS/prism/issues/3312)) [`82d0ca15`](https://github.com/PrismJS/prism/commit/82d0ca15)
### Other
* __Core__
- * Added better error message for missing grammars (#3311) [`2cc4660b`](https://github.com/PrismJS/prism/commit/2cc4660b)
+ * Added better error message for missing grammars ([#3311](https://github.com/PrismJS/prism/issues/3311)) [`2cc4660b`](https://github.com/PrismJS/prism/commit/2cc4660b)
## 1.26.0 (2022-01-06)
diff --git a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components.js b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components.js
index 6d3c1562e0..d58ff9037b 100644
--- a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components.js
+++ b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components.js
@@ -1,2 +1,2 @@
-var components = {"core":{"meta":{"path":"components/prism-core.js","option":"mandatory"},"core":"Core"},"themes":{"meta":{"path":"themes/{id}.css","link":"index.html?theme={id}","exclusive":true},"prism":{"title":"Default","option":"default"},"prism-dark":"Dark","prism-funky":"Funky","prism-okaidia":{"title":"Okaidia","owner":"ocodia"},"prism-twilight":{"title":"Twilight","owner":"remybach"},"prism-coy":{"title":"Coy","owner":"tshedor"},"prism-solarizedlight":{"title":"Solarized Light","owner":"hectormatos2011 "},"prism-tomorrow":{"title":"Tomorrow Night","owner":"Rosey"}},"languages":{"meta":{"path":"components/prism-{id}","noCSS":true,"examplesPath":"examples/prism-{id}","addCheckAll":true},"markup":{"title":"Markup","alias":["html","xml","svg","mathml","ssml","atom","rss"],"aliasTitles":{"html":"HTML","xml":"XML","svg":"SVG","mathml":"MathML","ssml":"SSML","atom":"Atom","rss":"RSS"},"option":"default"},"css":{"title":"CSS","option":"default","modify":"markup"},"clike":{"title":"C-like","option":"default"},"javascript":{"title":"JavaScript","require":"clike","modify":"markup","optional":"regex","alias":"js","option":"default"},"abap":{"title":"ABAP","owner":"dellagustin"},"abnf":{"title":"ABNF","owner":"RunDevelopment"},"actionscript":{"title":"ActionScript","require":"javascript","modify":"markup","owner":"Golmote"},"ada":{"title":"Ada","owner":"Lucretia"},"agda":{"title":"Agda","owner":"xy-ren"},"al":{"title":"AL","owner":"RunDevelopment"},"antlr4":{"title":"ANTLR4","alias":"g4","owner":"RunDevelopment"},"apacheconf":{"title":"Apache Configuration","owner":"GuiTeK"},"apex":{"title":"Apex","require":["clike","sql"],"owner":"RunDevelopment"},"apl":{"title":"APL","owner":"ngn"},"applescript":{"title":"AppleScript","owner":"Golmote"},"aql":{"title":"AQL","owner":"RunDevelopment"},"arduino":{"title":"Arduino","require":"cpp","alias":"ino","owner":"dkern"},"arff":{"title":"ARFF","owner":"Golmote"},"asciidoc":{"alias":"adoc","title":"AsciiDoc","owner":"Golmote"},"aspnet":{"title":"ASP.NET (C#)","require":["markup","csharp"],"owner":"nauzilus"},"asm6502":{"title":"6502 Assembly","owner":"kzurawel"},"asmatmel":{"title":"Atmel AVR Assembly","owner":"cerkit"},"autohotkey":{"title":"AutoHotkey","owner":"aviaryan"},"autoit":{"title":"AutoIt","owner":"Golmote"},"avisynth":{"title":"AviSynth","alias":"avs","owner":"Zinfidel"},"avro-idl":{"title":"Avro IDL","alias":"avdl","owner":"RunDevelopment"},"bash":{"title":"Bash","alias":"shell","aliasTitles":{"shell":"Shell"},"owner":"zeitgeist87"},"basic":{"title":"BASIC","owner":"Golmote"},"batch":{"title":"Batch","owner":"Golmote"},"bbcode":{"title":"BBcode","alias":"shortcode","aliasTitles":{"shortcode":"Shortcode"},"owner":"RunDevelopment"},"bicep":{"title":"Bicep","owner":"johnnyreilly"},"birb":{"title":"Birb","require":"clike","owner":"Calamity210"},"bison":{"title":"Bison","require":"c","owner":"Golmote"},"bnf":{"title":"BNF","alias":"rbnf","aliasTitles":{"rbnf":"RBNF"},"owner":"RunDevelopment"},"brainfuck":{"title":"Brainfuck","owner":"Golmote"},"brightscript":{"title":"BrightScript","owner":"RunDevelopment"},"bro":{"title":"Bro","owner":"wayward710"},"bsl":{"title":"BSL (1C:Enterprise)","alias":"oscript","aliasTitles":{"oscript":"OneScript"},"owner":"Diversus23"},"c":{"title":"C","require":"clike","owner":"zeitgeist87"},"csharp":{"title":"C#","require":"clike","alias":["cs","dotnet"],"owner":"mvalipour"},"cpp":{"title":"C++","require":"c","owner":"zeitgeist87"},"cfscript":{"title":"CFScript","require":"clike","alias":"cfc","owner":"mjclemente"},"chaiscript":{"title":"ChaiScript","require":["clike","cpp"],"owner":"RunDevelopment"},"cil":{"title":"CIL","owner":"sbrl"},"clojure":{"title":"Clojure","owner":"troglotit"},"cmake":{"title":"CMake","owner":"mjrogozinski"},"cobol":{"title":"COBOL","owner":"RunDevelopment"},"coffeescript":{"title":"CoffeeScript","require":"javascript","alias":"coffee","owner":"R-osey"},"concurnas":{"title":"Concurnas","alias":"conc","owner":"jasontatton"},"csp":{"title":"Content-Security-Policy","owner":"ScottHelme"},"coq":{"title":"Coq","owner":"RunDevelopment"},"crystal":{"title":"Crystal","require":"ruby","owner":"MakeNowJust"},"css-extras":{"title":"CSS Extras","require":"css","modify":"css","owner":"milesj"},"csv":{"title":"CSV","owner":"RunDevelopment"},"cypher":{"title":"Cypher","owner":"RunDevelopment"},"d":{"title":"D","require":"clike","owner":"Golmote"},"dart":{"title":"Dart","require":"clike","owner":"Golmote"},"dataweave":{"title":"DataWeave","owner":"machaval"},"dax":{"title":"DAX","owner":"peterbud"},"dhall":{"title":"Dhall","owner":"RunDevelopment"},"diff":{"title":"Diff","owner":"uranusjr"},"django":{"title":"Django/Jinja2","require":"markup-templating","alias":"jinja2","owner":"romanvm"},"dns-zone-file":{"title":"DNS zone file","owner":"RunDevelopment","alias":"dns-zone"},"docker":{"title":"Docker","alias":"dockerfile","owner":"JustinBeckwith"},"dot":{"title":"DOT (Graphviz)","alias":"gv","optional":"markup","owner":"RunDevelopment"},"ebnf":{"title":"EBNF","owner":"RunDevelopment"},"editorconfig":{"title":"EditorConfig","owner":"osipxd"},"eiffel":{"title":"Eiffel","owner":"Conaclos"},"ejs":{"title":"EJS","require":["javascript","markup-templating"],"owner":"RunDevelopment","alias":"eta","aliasTitles":{"eta":"Eta"}},"elixir":{"title":"Elixir","owner":"Golmote"},"elm":{"title":"Elm","owner":"zwilias"},"etlua":{"title":"Embedded Lua templating","require":["lua","markup-templating"],"owner":"RunDevelopment"},"erb":{"title":"ERB","require":["ruby","markup-templating"],"owner":"Golmote"},"erlang":{"title":"Erlang","owner":"Golmote"},"excel-formula":{"title":"Excel Formula","alias":["xlsx","xls"],"owner":"RunDevelopment"},"fsharp":{"title":"F#","require":"clike","owner":"simonreynolds7"},"factor":{"title":"Factor","owner":"catb0t"},"false":{"title":"False","owner":"edukisto"},"firestore-security-rules":{"title":"Firestore security rules","require":"clike","owner":"RunDevelopment"},"flow":{"title":"Flow","require":"javascript","owner":"Golmote"},"fortran":{"title":"Fortran","owner":"Golmote"},"ftl":{"title":"FreeMarker Template Language","require":"markup-templating","owner":"RunDevelopment"},"gml":{"title":"GameMaker Language","alias":"gamemakerlanguage","require":"clike","owner":"LiarOnce"},"gap":{"title":"GAP (CAS)","owner":"RunDevelopment"},"gcode":{"title":"G-code","owner":"RunDevelopment"},"gdscript":{"title":"GDScript","owner":"RunDevelopment"},"gedcom":{"title":"GEDCOM","owner":"Golmote"},"gherkin":{"title":"Gherkin","owner":"hason"},"git":{"title":"Git","owner":"lgiraudel"},"glsl":{"title":"GLSL","require":"c","owner":"Golmote"},"gn":{"title":"GN","alias":"gni","owner":"RunDevelopment"},"go":{"title":"Go","require":"clike","owner":"arnehormann"},"go-module":{"title":"Go module","alias":"go-mod","owner":"RunDevelopment"},"graphql":{"title":"GraphQL","optional":"markdown","owner":"Golmote"},"groovy":{"title":"Groovy","require":"clike","owner":"robfletcher"},"haml":{"title":"Haml","require":"ruby","optional":["css","css-extras","coffeescript","erb","javascript","less","markdown","scss","textile"],"owner":"Golmote"},"handlebars":{"title":"Handlebars","require":"markup-templating","alias":"hbs","owner":"Golmote"},"haskell":{"title":"Haskell","alias":"hs","owner":"bholst"},"haxe":{"title":"Haxe","require":"clike","optional":"regex","owner":"Golmote"},"hcl":{"title":"HCL","owner":"outsideris"},"hlsl":{"title":"HLSL","require":"c","owner":"RunDevelopment"},"hoon":{"title":"Hoon","owner":"matildepark"},"http":{"title":"HTTP","optional":["csp","css","hpkp","hsts","javascript","json","markup","uri"],"owner":"danielgtaylor"},"hpkp":{"title":"HTTP Public-Key-Pins","owner":"ScottHelme"},"hsts":{"title":"HTTP Strict-Transport-Security","owner":"ScottHelme"},"ichigojam":{"title":"IchigoJam","owner":"BlueCocoa"},"icon":{"title":"Icon","owner":"Golmote"},"icu-message-format":{"title":"ICU Message Format","owner":"RunDevelopment"},"idris":{"title":"Idris","alias":"idr","owner":"KeenS","require":"haskell"},"ignore":{"title":".ignore","owner":"osipxd","alias":["gitignore","hgignore","npmignore"],"aliasTitles":{"gitignore":".gitignore","hgignore":".hgignore","npmignore":".npmignore"}},"inform7":{"title":"Inform 7","owner":"Golmote"},"ini":{"title":"Ini","owner":"aviaryan"},"io":{"title":"Io","owner":"AlesTsurko"},"j":{"title":"J","owner":"Golmote"},"java":{"title":"Java","require":"clike","owner":"sherblot"},"javadoc":{"title":"JavaDoc","require":["markup","java","javadoclike"],"modify":"java","optional":"scala","owner":"RunDevelopment"},"javadoclike":{"title":"JavaDoc-like","modify":["java","javascript","php"],"owner":"RunDevelopment"},"javastacktrace":{"title":"Java stack trace","owner":"RunDevelopment"},"jexl":{"title":"Jexl","owner":"czosel"},"jolie":{"title":"Jolie","require":"clike","owner":"thesave"},"jq":{"title":"JQ","owner":"RunDevelopment"},"jsdoc":{"title":"JSDoc","require":["javascript","javadoclike","typescript"],"modify":"javascript","optional":["actionscript","coffeescript"],"owner":"RunDevelopment"},"js-extras":{"title":"JS Extras","require":"javascript","modify":"javascript","optional":["actionscript","coffeescript","flow","n4js","typescript"],"owner":"RunDevelopment"},"json":{"title":"JSON","alias":"webmanifest","aliasTitles":{"webmanifest":"Web App Manifest"},"owner":"CupOfTea696"},"json5":{"title":"JSON5","require":"json","owner":"RunDevelopment"},"jsonp":{"title":"JSONP","require":"json","owner":"RunDevelopment"},"jsstacktrace":{"title":"JS stack trace","owner":"sbrl"},"js-templates":{"title":"JS Templates","require":"javascript","modify":"javascript","optional":["css","css-extras","graphql","markdown","markup","sql"],"owner":"RunDevelopment"},"julia":{"title":"Julia","owner":"cdagnino"},"keepalived":{"title":"Keepalived Configure","owner":"dev-itsheng"},"keyman":{"title":"Keyman","owner":"mcdurdin"},"kotlin":{"title":"Kotlin","alias":["kt","kts"],"aliasTitles":{"kts":"Kotlin Script"},"require":"clike","owner":"Golmote"},"kumir":{"title":"KuMir (КуМир)","alias":"kum","owner":"edukisto"},"kusto":{"title":"Kusto","owner":"RunDevelopment"},"latex":{"title":"LaTeX","alias":["tex","context"],"aliasTitles":{"tex":"TeX","context":"ConTeXt"},"owner":"japborst"},"latte":{"title":"Latte","require":["clike","markup-templating","php"],"owner":"nette"},"less":{"title":"Less","require":"css","optional":"css-extras","owner":"Golmote"},"lilypond":{"title":"LilyPond","require":"scheme","alias":"ly","owner":"RunDevelopment"},"liquid":{"title":"Liquid","require":"markup-templating","owner":"cinhtau"},"lisp":{"title":"Lisp","alias":["emacs","elisp","emacs-lisp"],"owner":"JuanCaicedo"},"livescript":{"title":"LiveScript","owner":"Golmote"},"llvm":{"title":"LLVM IR","owner":"porglezomp"},"log":{"title":"Log file","optional":"javastacktrace","owner":"RunDevelopment"},"lolcode":{"title":"LOLCODE","owner":"Golmote"},"lua":{"title":"Lua","owner":"Golmote"},"magma":{"title":"Magma (CAS)","owner":"RunDevelopment"},"makefile":{"title":"Makefile","owner":"Golmote"},"markdown":{"title":"Markdown","require":"markup","optional":"yaml","alias":"md","owner":"Golmote"},"markup-templating":{"title":"Markup templating","require":"markup","owner":"Golmote"},"matlab":{"title":"MATLAB","owner":"Golmote"},"maxscript":{"title":"MAXScript","owner":"RunDevelopment"},"mel":{"title":"MEL","owner":"Golmote"},"mermaid":{"title":"Mermaid","owner":"RunDevelopment"},"mizar":{"title":"Mizar","owner":"Golmote"},"mongodb":{"title":"MongoDB","owner":"airs0urce","require":"javascript"},"monkey":{"title":"Monkey","owner":"Golmote"},"moonscript":{"title":"MoonScript","alias":"moon","owner":"RunDevelopment"},"n1ql":{"title":"N1QL","owner":"TMWilds"},"n4js":{"title":"N4JS","require":"javascript","optional":"jsdoc","alias":"n4jsd","owner":"bsmith-n4"},"nand2tetris-hdl":{"title":"Nand To Tetris HDL","owner":"stephanmax"},"naniscript":{"title":"Naninovel Script","owner":"Elringus","alias":"nani"},"nasm":{"title":"NASM","owner":"rbmj"},"neon":{"title":"NEON","owner":"nette"},"nevod":{"title":"Nevod","owner":"nezaboodka"},"nginx":{"title":"nginx","owner":"volado"},"nim":{"title":"Nim","owner":"Golmote"},"nix":{"title":"Nix","owner":"Golmote"},"nsis":{"title":"NSIS","owner":"idleberg"},"objectivec":{"title":"Objective-C","require":"c","alias":"objc","owner":"uranusjr"},"ocaml":{"title":"OCaml","owner":"Golmote"},"opencl":{"title":"OpenCL","require":"c","modify":["c","cpp"],"owner":"Milania1"},"openqasm":{"title":"OpenQasm","alias":"qasm","owner":"RunDevelopment"},"oz":{"title":"Oz","owner":"Golmote"},"parigp":{"title":"PARI/GP","owner":"Golmote"},"parser":{"title":"Parser","require":"markup","owner":"Golmote"},"pascal":{"title":"Pascal","alias":"objectpascal","aliasTitles":{"objectpascal":"Object Pascal"},"owner":"Golmote"},"pascaligo":{"title":"Pascaligo","owner":"DefinitelyNotAGoat"},"psl":{"title":"PATROL Scripting Language","owner":"bertysentry"},"pcaxis":{"title":"PC-Axis","alias":"px","owner":"RunDevelopment"},"peoplecode":{"title":"PeopleCode","alias":"pcode","owner":"RunDevelopment"},"perl":{"title":"Perl","owner":"Golmote"},"php":{"title":"PHP","require":"markup-templating","owner":"milesj"},"phpdoc":{"title":"PHPDoc","require":["php","javadoclike"],"modify":"php","owner":"RunDevelopment"},"php-extras":{"title":"PHP Extras","require":"php","modify":"php","owner":"milesj"},"plsql":{"title":"PL/SQL","require":"sql","owner":"Golmote"},"powerquery":{"title":"PowerQuery","alias":["pq","mscript"],"owner":"peterbud"},"powershell":{"title":"PowerShell","owner":"nauzilus"},"processing":{"title":"Processing","require":"clike","owner":"Golmote"},"prolog":{"title":"Prolog","owner":"Golmote"},"promql":{"title":"PromQL","owner":"arendjr"},"properties":{"title":".properties","owner":"Golmote"},"protobuf":{"title":"Protocol Buffers","require":"clike","owner":"just-boris"},"pug":{"title":"Pug","require":["markup","javascript"],"optional":["coffeescript","ejs","handlebars","less","livescript","markdown","scss","stylus","twig"],"owner":"Golmote"},"puppet":{"title":"Puppet","owner":"Golmote"},"pure":{"title":"Pure","optional":["c","cpp","fortran"],"owner":"Golmote"},"purebasic":{"title":"PureBasic","require":"clike","alias":"pbfasm","owner":"HeX0R101"},"purescript":{"title":"PureScript","require":"haskell","alias":"purs","owner":"sriharshachilakapati"},"python":{"title":"Python","alias":"py","owner":"multipetros"},"qsharp":{"title":"Q#","require":"clike","alias":"qs","owner":"fedonman"},"q":{"title":"Q (kdb+ database)","owner":"Golmote"},"qml":{"title":"QML","require":"javascript","owner":"RunDevelopment"},"qore":{"title":"Qore","require":"clike","owner":"temnroegg"},"r":{"title":"R","owner":"Golmote"},"racket":{"title":"Racket","require":"scheme","alias":"rkt","owner":"RunDevelopment"},"cshtml":{"title":"Razor C#","alias":"razor","require":["markup","csharp"],"optional":["css","css-extras","javascript","js-extras"],"owner":"RunDevelopment"},"jsx":{"title":"React JSX","require":["markup","javascript"],"optional":["jsdoc","js-extras","js-templates"],"owner":"vkbansal"},"tsx":{"title":"React TSX","require":["jsx","typescript"]},"reason":{"title":"Reason","require":"clike","owner":"Golmote"},"regex":{"title":"Regex","owner":"RunDevelopment"},"rego":{"title":"Rego","owner":"JordanSh"},"renpy":{"title":"Ren'py","alias":"rpy","owner":"HyuchiaDiego"},"rest":{"title":"reST (reStructuredText)","owner":"Golmote"},"rip":{"title":"Rip","owner":"ravinggenius"},"roboconf":{"title":"Roboconf","owner":"Golmote"},"robotframework":{"title":"Robot Framework","alias":"robot","owner":"RunDevelopment"},"ruby":{"title":"Ruby","require":"clike","alias":"rb","owner":"samflores"},"rust":{"title":"Rust","owner":"Golmote"},"sas":{"title":"SAS","optional":["groovy","lua","sql"],"owner":"Golmote"},"sass":{"title":"Sass (Sass)","require":"css","optional":"css-extras","owner":"Golmote"},"scss":{"title":"Sass (Scss)","require":"css","optional":"css-extras","owner":"MoOx"},"scala":{"title":"Scala","require":"java","owner":"jozic"},"scheme":{"title":"Scheme","owner":"bacchus123"},"shell-session":{"title":"Shell session","require":"bash","alias":["sh-session","shellsession"],"owner":"RunDevelopment"},"smali":{"title":"Smali","owner":"RunDevelopment"},"smalltalk":{"title":"Smalltalk","owner":"Golmote"},"smarty":{"title":"Smarty","require":"markup-templating","optional":"php","owner":"Golmote"},"sml":{"title":"SML","alias":"smlnj","aliasTitles":{"smlnj":"SML/NJ"},"owner":"RunDevelopment"},"solidity":{"title":"Solidity (Ethereum)","alias":"sol","require":"clike","owner":"glachaud"},"solution-file":{"title":"Solution file","alias":"sln","owner":"RunDevelopment"},"soy":{"title":"Soy (Closure Template)","require":"markup-templating","owner":"Golmote"},"sparql":{"title":"SPARQL","require":"turtle","owner":"Triply-Dev","alias":"rq"},"splunk-spl":{"title":"Splunk SPL","owner":"RunDevelopment"},"sqf":{"title":"SQF: Status Quo Function (Arma 3)","require":"clike","owner":"RunDevelopment"},"sql":{"title":"SQL","owner":"multipetros"},"squirrel":{"title":"Squirrel","require":"clike","owner":"RunDevelopment"},"stan":{"title":"Stan","owner":"RunDevelopment"},"iecst":{"title":"Structured Text (IEC 61131-3)","owner":"serhioromano"},"stylus":{"title":"Stylus","owner":"vkbansal"},"swift":{"title":"Swift","owner":"chrischares"},"systemd":{"title":"Systemd configuration file","owner":"RunDevelopment"},"t4-templating":{"title":"T4 templating","owner":"RunDevelopment"},"t4-cs":{"title":"T4 Text Templates (C#)","require":["t4-templating","csharp"],"alias":"t4","owner":"RunDevelopment"},"t4-vb":{"title":"T4 Text Templates (VB)","require":["t4-templating","vbnet"],"owner":"RunDevelopment"},"tap":{"title":"TAP","owner":"isaacs","require":"yaml"},"tcl":{"title":"Tcl","owner":"PeterChaplin"},"tt2":{"title":"Template Toolkit 2","require":["clike","markup-templating"],"owner":"gflohr"},"textile":{"title":"Textile","require":"markup","optional":"css","owner":"Golmote"},"toml":{"title":"TOML","owner":"RunDevelopment"},"tremor":{"title":"Tremor","alias":["trickle","troy"],"owner":"darach","aliasTitles":{"trickle":"trickle","troy":"troy"}},"turtle":{"title":"Turtle","alias":"trig","aliasTitles":{"trig":"TriG"},"owner":"jakubklimek"},"twig":{"title":"Twig","require":"markup-templating","owner":"brandonkelly"},"typescript":{"title":"TypeScript","require":"javascript","optional":"js-templates","alias":"ts","owner":"vkbansal"},"typoscript":{"title":"TypoScript","alias":"tsconfig","aliasTitles":{"tsconfig":"TSConfig"},"owner":"dkern"},"unrealscript":{"title":"UnrealScript","alias":["uscript","uc"],"owner":"RunDevelopment"},"uorazor":{"title":"UO Razor Script","owner":"jaseowns"},"uri":{"title":"URI","alias":"url","aliasTitles":{"url":"URL"},"owner":"RunDevelopment"},"v":{"title":"V","require":"clike","owner":"taggon"},"vala":{"title":"Vala","require":"clike","optional":"regex","owner":"TemplarVolk"},"vbnet":{"title":"VB.Net","require":"basic","owner":"Bigsby"},"velocity":{"title":"Velocity","require":"markup","owner":"Golmote"},"verilog":{"title":"Verilog","owner":"a-rey"},"vhdl":{"title":"VHDL","owner":"a-rey"},"vim":{"title":"vim","owner":"westonganger"},"visual-basic":{"title":"Visual Basic","alias":["vb","vba"],"aliasTitles":{"vba":"VBA"},"owner":"Golmote"},"warpscript":{"title":"WarpScript","owner":"RunDevelopment"},"wasm":{"title":"WebAssembly","owner":"Golmote"},"web-idl":{"title":"Web IDL","alias":"webidl","owner":"RunDevelopment"},"wiki":{"title":"Wiki markup","require":"markup","owner":"Golmote"},"wolfram":{"title":"Wolfram language","alias":["mathematica","nb","wl"],"aliasTitles":{"mathematica":"Mathematica","nb":"Mathematica Notebook"},"owner":"msollami"},"wren":{"title":"Wren","owner":"clsource"},"xeora":{"title":"Xeora","require":"markup","alias":"xeoracube","aliasTitles":{"xeoracube":"XeoraCube"},"owner":"freakmaxi"},"xml-doc":{"title":"XML doc (.net)","require":"markup","modify":["csharp","fsharp","vbnet"],"owner":"RunDevelopment"},"xojo":{"title":"Xojo (REALbasic)","owner":"Golmote"},"xquery":{"title":"XQuery","require":"markup","owner":"Golmote"},"yaml":{"title":"YAML","alias":"yml","owner":"hason"},"yang":{"title":"YANG","owner":"RunDevelopment"},"zig":{"title":"Zig","owner":"RunDevelopment"}},"plugins":{"meta":{"path":"plugins/{id}/prism-{id}","link":"plugins/{id}/"},"line-highlight":{"title":"Line Highlight","description":"Highlights specific lines and/or line ranges."},"line-numbers":{"title":"Line Numbers","description":"Line number at the beginning of code lines.","owner":"kuba-kubula"},"show-invisibles":{"title":"Show Invisibles","description":"Show hidden characters such as tabs and line breaks.","optional":["autolinker","data-uri-highlight"]},"autolinker":{"title":"Autolinker","description":"Converts URLs and emails in code to clickable links. Parses Markdown links in comments."},"wpd":{"title":"WebPlatform Docs","description":"Makes tokens link to WebPlatform.org documentation. The links open in a new tab."},"custom-class":{"title":"Custom Class","description":"This plugin allows you to prefix Prism's default classes (.comment can become .namespace--comment) or replace them with your defined ones (like .editor__comment). You can even add new classes.","owner":"dvkndn","noCSS":true},"file-highlight":{"title":"File Highlight","description":"Fetch external files and highlight them with Prism. Used on the Prism website itself.","noCSS":true},"show-language":{"title":"Show Language","description":"Display the highlighted language in code blocks (inline code does not show the label).","owner":"nauzilus","noCSS":true,"require":"toolbar"},"jsonp-highlight":{"title":"JSONP Highlight","description":"Fetch content with JSONP and highlight some interesting content (e.g. GitHub/Gists or Bitbucket API).","noCSS":true,"owner":"nauzilus"},"highlight-keywords":{"title":"Highlight Keywords","description":"Adds special CSS classes for each keyword for fine-grained highlighting.","owner":"vkbansal","noCSS":true},"remove-initial-line-feed":{"title":"Remove initial line feed","description":"Removes the initial line feed in code blocks.","owner":"Golmote","noCSS":true},"inline-color":{"title":"Inline color","description":"Adds a small inline preview for colors in style sheets.","require":"css-extras","owner":"RunDevelopment"},"previewers":{"title":"Previewers","description":"Previewers for angles, colors, gradients, easing and time.","require":"css-extras","owner":"Golmote"},"autoloader":{"title":"Autoloader","description":"Automatically loads the needed languages to highlight the code blocks.","owner":"Golmote","noCSS":true},"keep-markup":{"title":"Keep Markup","description":"Prevents custom markup from being dropped out during highlighting.","owner":"Golmote","optional":"normalize-whitespace","noCSS":true},"command-line":{"title":"Command Line","description":"Display a command line with a prompt and, optionally, the output/response from the commands.","owner":"chriswells0"},"unescaped-markup":{"title":"Unescaped Markup","description":"Write markup without having to escape anything."},"normalize-whitespace":{"title":"Normalize Whitespace","description":"Supports multiple operations to normalize whitespace in code blocks.","owner":"zeitgeist87","optional":"unescaped-markup","noCSS":true},"data-uri-highlight":{"title":"Data-URI Highlight","description":"Highlights data-URI contents.","owner":"Golmote","noCSS":true},"toolbar":{"title":"Toolbar","description":"Attach a toolbar for plugins to easily register buttons on the top of a code block.","owner":"mAAdhaTTah"},"copy-to-clipboard":{"title":"Copy to Clipboard Button","description":"Add a button that copies the code block to the clipboard when clicked.","owner":"mAAdhaTTah","require":"toolbar","noCSS":true},"download-button":{"title":"Download Button","description":"A button in the toolbar of a code block adding a convenient way to download a code file.","owner":"Golmote","require":"toolbar","noCSS":true},"match-braces":{"title":"Match braces","description":"Highlights matching braces.","owner":"RunDevelopment"},"diff-highlight":{"title":"Diff Highlight","description":"Highlights the code inside diff blocks.","owner":"RunDevelopment","require":"diff"},"filter-highlight-all":{"title":"Filter highlightAll","description":"Filters the elements the highlightAll and highlightAllUnder methods actually highlight.","owner":"RunDevelopment","noCSS":true},"treeview":{"title":"Treeview","description":"A language with special styles to highlight file system tree structures.","owner":"Golmote"}}};
+var components = {"core":{"meta":{"path":"components/prism-core.js","option":"mandatory"},"core":"Core"},"themes":{"meta":{"path":"themes/{id}.css","link":"index.html?theme={id}","exclusive":true},"prism":{"title":"Default","option":"default"},"prism-dark":"Dark","prism-funky":"Funky","prism-okaidia":{"title":"Okaidia","owner":"ocodia"},"prism-twilight":{"title":"Twilight","owner":"remybach"},"prism-coy":{"title":"Coy","owner":"tshedor"},"prism-solarizedlight":{"title":"Solarized Light","owner":"hectormatos2011 "},"prism-tomorrow":{"title":"Tomorrow Night","owner":"Rosey"}},"languages":{"meta":{"path":"components/prism-{id}","noCSS":true,"examplesPath":"examples/prism-{id}","addCheckAll":true},"markup":{"title":"Markup","alias":["html","xml","svg","mathml","ssml","atom","rss"],"aliasTitles":{"html":"HTML","xml":"XML","svg":"SVG","mathml":"MathML","ssml":"SSML","atom":"Atom","rss":"RSS"},"option":"default"},"css":{"title":"CSS","option":"default","modify":"markup"},"clike":{"title":"C-like","option":"default"},"javascript":{"title":"JavaScript","require":"clike","modify":"markup","optional":"regex","alias":"js","option":"default"},"abap":{"title":"ABAP","owner":"dellagustin"},"abnf":{"title":"ABNF","owner":"RunDevelopment"},"actionscript":{"title":"ActionScript","require":"javascript","modify":"markup","owner":"Golmote"},"ada":{"title":"Ada","owner":"Lucretia"},"agda":{"title":"Agda","owner":"xy-ren"},"al":{"title":"AL","owner":"RunDevelopment"},"antlr4":{"title":"ANTLR4","alias":"g4","owner":"RunDevelopment"},"apacheconf":{"title":"Apache Configuration","owner":"GuiTeK"},"apex":{"title":"Apex","require":["clike","sql"],"owner":"RunDevelopment"},"apl":{"title":"APL","owner":"ngn"},"applescript":{"title":"AppleScript","owner":"Golmote"},"aql":{"title":"AQL","owner":"RunDevelopment"},"arduino":{"title":"Arduino","require":"cpp","alias":"ino","owner":"dkern"},"arff":{"title":"ARFF","owner":"Golmote"},"armasm":{"title":"ARM Assembly","alias":"arm-asm","owner":"RunDevelopment"},"arturo":{"title":"Arturo","alias":"art","optional":["bash","css","javascript","markup","markdown","sql"],"owner":"drkameleon"},"asciidoc":{"alias":"adoc","title":"AsciiDoc","owner":"Golmote"},"aspnet":{"title":"ASP.NET (C#)","require":["markup","csharp"],"owner":"nauzilus"},"asm6502":{"title":"6502 Assembly","owner":"kzurawel"},"asmatmel":{"title":"Atmel AVR Assembly","owner":"cerkit"},"autohotkey":{"title":"AutoHotkey","owner":"aviaryan"},"autoit":{"title":"AutoIt","owner":"Golmote"},"avisynth":{"title":"AviSynth","alias":"avs","owner":"Zinfidel"},"avro-idl":{"title":"Avro IDL","alias":"avdl","owner":"RunDevelopment"},"awk":{"title":"AWK","alias":"gawk","aliasTitles":{"gawk":"GAWK"},"owner":"RunDevelopment"},"bash":{"title":"Bash","alias":"shell","aliasTitles":{"shell":"Shell"},"owner":"zeitgeist87"},"basic":{"title":"BASIC","owner":"Golmote"},"batch":{"title":"Batch","owner":"Golmote"},"bbcode":{"title":"BBcode","alias":"shortcode","aliasTitles":{"shortcode":"Shortcode"},"owner":"RunDevelopment"},"bicep":{"title":"Bicep","owner":"johnnyreilly"},"birb":{"title":"Birb","require":"clike","owner":"Calamity210"},"bison":{"title":"Bison","require":"c","owner":"Golmote"},"bnf":{"title":"BNF","alias":"rbnf","aliasTitles":{"rbnf":"RBNF"},"owner":"RunDevelopment"},"brainfuck":{"title":"Brainfuck","owner":"Golmote"},"brightscript":{"title":"BrightScript","owner":"RunDevelopment"},"bro":{"title":"Bro","owner":"wayward710"},"bsl":{"title":"BSL (1C:Enterprise)","alias":"oscript","aliasTitles":{"oscript":"OneScript"},"owner":"Diversus23"},"c":{"title":"C","require":"clike","owner":"zeitgeist87"},"csharp":{"title":"C#","require":"clike","alias":["cs","dotnet"],"owner":"mvalipour"},"cpp":{"title":"C++","require":"c","owner":"zeitgeist87"},"cfscript":{"title":"CFScript","require":"clike","alias":"cfc","owner":"mjclemente"},"chaiscript":{"title":"ChaiScript","require":["clike","cpp"],"owner":"RunDevelopment"},"cil":{"title":"CIL","owner":"sbrl"},"clojure":{"title":"Clojure","owner":"troglotit"},"cmake":{"title":"CMake","owner":"mjrogozinski"},"cobol":{"title":"COBOL","owner":"RunDevelopment"},"coffeescript":{"title":"CoffeeScript","require":"javascript","alias":"coffee","owner":"R-osey"},"concurnas":{"title":"Concurnas","alias":"conc","owner":"jasontatton"},"csp":{"title":"Content-Security-Policy","owner":"ScottHelme"},"cooklang":{"title":"Cooklang","owner":"ahue"},"coq":{"title":"Coq","owner":"RunDevelopment"},"crystal":{"title":"Crystal","require":"ruby","owner":"MakeNowJust"},"css-extras":{"title":"CSS Extras","require":"css","modify":"css","owner":"milesj"},"csv":{"title":"CSV","owner":"RunDevelopment"},"cue":{"title":"CUE","owner":"RunDevelopment"},"cypher":{"title":"Cypher","owner":"RunDevelopment"},"d":{"title":"D","require":"clike","owner":"Golmote"},"dart":{"title":"Dart","require":"clike","owner":"Golmote"},"dataweave":{"title":"DataWeave","owner":"machaval"},"dax":{"title":"DAX","owner":"peterbud"},"dhall":{"title":"Dhall","owner":"RunDevelopment"},"diff":{"title":"Diff","owner":"uranusjr"},"django":{"title":"Django/Jinja2","require":"markup-templating","alias":"jinja2","owner":"romanvm"},"dns-zone-file":{"title":"DNS zone file","owner":"RunDevelopment","alias":"dns-zone"},"docker":{"title":"Docker","alias":"dockerfile","owner":"JustinBeckwith"},"dot":{"title":"DOT (Graphviz)","alias":"gv","optional":"markup","owner":"RunDevelopment"},"ebnf":{"title":"EBNF","owner":"RunDevelopment"},"editorconfig":{"title":"EditorConfig","owner":"osipxd"},"eiffel":{"title":"Eiffel","owner":"Conaclos"},"ejs":{"title":"EJS","require":["javascript","markup-templating"],"owner":"RunDevelopment","alias":"eta","aliasTitles":{"eta":"Eta"}},"elixir":{"title":"Elixir","owner":"Golmote"},"elm":{"title":"Elm","owner":"zwilias"},"etlua":{"title":"Embedded Lua templating","require":["lua","markup-templating"],"owner":"RunDevelopment"},"erb":{"title":"ERB","require":["ruby","markup-templating"],"owner":"Golmote"},"erlang":{"title":"Erlang","owner":"Golmote"},"excel-formula":{"title":"Excel Formula","alias":["xlsx","xls"],"owner":"RunDevelopment"},"fsharp":{"title":"F#","require":"clike","owner":"simonreynolds7"},"factor":{"title":"Factor","owner":"catb0t"},"false":{"title":"False","owner":"edukisto"},"firestore-security-rules":{"title":"Firestore security rules","require":"clike","owner":"RunDevelopment"},"flow":{"title":"Flow","require":"javascript","owner":"Golmote"},"fortran":{"title":"Fortran","owner":"Golmote"},"ftl":{"title":"FreeMarker Template Language","require":"markup-templating","owner":"RunDevelopment"},"gml":{"title":"GameMaker Language","alias":"gamemakerlanguage","require":"clike","owner":"LiarOnce"},"gap":{"title":"GAP (CAS)","owner":"RunDevelopment"},"gcode":{"title":"G-code","owner":"RunDevelopment"},"gdscript":{"title":"GDScript","owner":"RunDevelopment"},"gedcom":{"title":"GEDCOM","owner":"Golmote"},"gettext":{"title":"gettext","alias":"po","owner":"RunDevelopment"},"gherkin":{"title":"Gherkin","owner":"hason"},"git":{"title":"Git","owner":"lgiraudel"},"glsl":{"title":"GLSL","require":"c","owner":"Golmote"},"gn":{"title":"GN","alias":"gni","owner":"RunDevelopment"},"linker-script":{"title":"GNU Linker Script","alias":"ld","owner":"RunDevelopment"},"go":{"title":"Go","require":"clike","owner":"arnehormann"},"go-module":{"title":"Go module","alias":"go-mod","owner":"RunDevelopment"},"graphql":{"title":"GraphQL","optional":"markdown","owner":"Golmote"},"groovy":{"title":"Groovy","require":"clike","owner":"robfletcher"},"haml":{"title":"Haml","require":"ruby","optional":["css","css-extras","coffeescript","erb","javascript","less","markdown","scss","textile"],"owner":"Golmote"},"handlebars":{"title":"Handlebars","require":"markup-templating","alias":["hbs","mustache"],"aliasTitles":{"mustache":"Mustache"},"owner":"Golmote"},"haskell":{"title":"Haskell","alias":"hs","owner":"bholst"},"haxe":{"title":"Haxe","require":"clike","optional":"regex","owner":"Golmote"},"hcl":{"title":"HCL","owner":"outsideris"},"hlsl":{"title":"HLSL","require":"c","owner":"RunDevelopment"},"hoon":{"title":"Hoon","owner":"matildepark"},"http":{"title":"HTTP","optional":["csp","css","hpkp","hsts","javascript","json","markup","uri"],"owner":"danielgtaylor"},"hpkp":{"title":"HTTP Public-Key-Pins","owner":"ScottHelme"},"hsts":{"title":"HTTP Strict-Transport-Security","owner":"ScottHelme"},"ichigojam":{"title":"IchigoJam","owner":"BlueCocoa"},"icon":{"title":"Icon","owner":"Golmote"},"icu-message-format":{"title":"ICU Message Format","owner":"RunDevelopment"},"idris":{"title":"Idris","alias":"idr","owner":"KeenS","require":"haskell"},"ignore":{"title":".ignore","owner":"osipxd","alias":["gitignore","hgignore","npmignore"],"aliasTitles":{"gitignore":".gitignore","hgignore":".hgignore","npmignore":".npmignore"}},"inform7":{"title":"Inform 7","owner":"Golmote"},"ini":{"title":"Ini","owner":"aviaryan"},"io":{"title":"Io","owner":"AlesTsurko"},"j":{"title":"J","owner":"Golmote"},"java":{"title":"Java","require":"clike","owner":"sherblot"},"javadoc":{"title":"JavaDoc","require":["markup","java","javadoclike"],"modify":"java","optional":"scala","owner":"RunDevelopment"},"javadoclike":{"title":"JavaDoc-like","modify":["java","javascript","php"],"owner":"RunDevelopment"},"javastacktrace":{"title":"Java stack trace","owner":"RunDevelopment"},"jexl":{"title":"Jexl","owner":"czosel"},"jolie":{"title":"Jolie","require":"clike","owner":"thesave"},"jq":{"title":"JQ","owner":"RunDevelopment"},"jsdoc":{"title":"JSDoc","require":["javascript","javadoclike","typescript"],"modify":"javascript","optional":["actionscript","coffeescript"],"owner":"RunDevelopment"},"js-extras":{"title":"JS Extras","require":"javascript","modify":"javascript","optional":["actionscript","coffeescript","flow","n4js","typescript"],"owner":"RunDevelopment"},"json":{"title":"JSON","alias":"webmanifest","aliasTitles":{"webmanifest":"Web App Manifest"},"owner":"CupOfTea696"},"json5":{"title":"JSON5","require":"json","owner":"RunDevelopment"},"jsonp":{"title":"JSONP","require":"json","owner":"RunDevelopment"},"jsstacktrace":{"title":"JS stack trace","owner":"sbrl"},"js-templates":{"title":"JS Templates","require":"javascript","modify":"javascript","optional":["css","css-extras","graphql","markdown","markup","sql"],"owner":"RunDevelopment"},"julia":{"title":"Julia","owner":"cdagnino"},"keepalived":{"title":"Keepalived Configure","owner":"dev-itsheng"},"keyman":{"title":"Keyman","owner":"mcdurdin"},"kotlin":{"title":"Kotlin","alias":["kt","kts"],"aliasTitles":{"kts":"Kotlin Script"},"require":"clike","owner":"Golmote"},"kumir":{"title":"KuMir (КуМир)","alias":"kum","owner":"edukisto"},"kusto":{"title":"Kusto","owner":"RunDevelopment"},"latex":{"title":"LaTeX","alias":["tex","context"],"aliasTitles":{"tex":"TeX","context":"ConTeXt"},"owner":"japborst"},"latte":{"title":"Latte","require":["clike","markup-templating","php"],"owner":"nette"},"less":{"title":"Less","require":"css","optional":"css-extras","owner":"Golmote"},"lilypond":{"title":"LilyPond","require":"scheme","alias":"ly","owner":"RunDevelopment"},"liquid":{"title":"Liquid","require":"markup-templating","owner":"cinhtau"},"lisp":{"title":"Lisp","alias":["emacs","elisp","emacs-lisp"],"owner":"JuanCaicedo"},"livescript":{"title":"LiveScript","owner":"Golmote"},"llvm":{"title":"LLVM IR","owner":"porglezomp"},"log":{"title":"Log file","optional":"javastacktrace","owner":"RunDevelopment"},"lolcode":{"title":"LOLCODE","owner":"Golmote"},"lua":{"title":"Lua","owner":"Golmote"},"magma":{"title":"Magma (CAS)","owner":"RunDevelopment"},"makefile":{"title":"Makefile","owner":"Golmote"},"markdown":{"title":"Markdown","require":"markup","optional":"yaml","alias":"md","owner":"Golmote"},"markup-templating":{"title":"Markup templating","require":"markup","owner":"Golmote"},"mata":{"title":"Mata","owner":"RunDevelopment"},"matlab":{"title":"MATLAB","owner":"Golmote"},"maxscript":{"title":"MAXScript","owner":"RunDevelopment"},"mel":{"title":"MEL","owner":"Golmote"},"mermaid":{"title":"Mermaid","owner":"RunDevelopment"},"mizar":{"title":"Mizar","owner":"Golmote"},"mongodb":{"title":"MongoDB","owner":"airs0urce","require":"javascript"},"monkey":{"title":"Monkey","owner":"Golmote"},"moonscript":{"title":"MoonScript","alias":"moon","owner":"RunDevelopment"},"n1ql":{"title":"N1QL","owner":"TMWilds"},"n4js":{"title":"N4JS","require":"javascript","optional":"jsdoc","alias":"n4jsd","owner":"bsmith-n4"},"nand2tetris-hdl":{"title":"Nand To Tetris HDL","owner":"stephanmax"},"naniscript":{"title":"Naninovel Script","owner":"Elringus","alias":"nani"},"nasm":{"title":"NASM","owner":"rbmj"},"neon":{"title":"NEON","owner":"nette"},"nevod":{"title":"Nevod","owner":"nezaboodka"},"nginx":{"title":"nginx","owner":"volado"},"nim":{"title":"Nim","owner":"Golmote"},"nix":{"title":"Nix","owner":"Golmote"},"nsis":{"title":"NSIS","owner":"idleberg"},"objectivec":{"title":"Objective-C","require":"c","alias":"objc","owner":"uranusjr"},"ocaml":{"title":"OCaml","owner":"Golmote"},"odin":{"title":"Odin","owner":"edukisto"},"opencl":{"title":"OpenCL","require":"c","modify":["c","cpp"],"owner":"Milania1"},"openqasm":{"title":"OpenQasm","alias":"qasm","owner":"RunDevelopment"},"oz":{"title":"Oz","owner":"Golmote"},"parigp":{"title":"PARI/GP","owner":"Golmote"},"parser":{"title":"Parser","require":"markup","owner":"Golmote"},"pascal":{"title":"Pascal","alias":"objectpascal","aliasTitles":{"objectpascal":"Object Pascal"},"owner":"Golmote"},"pascaligo":{"title":"Pascaligo","owner":"DefinitelyNotAGoat"},"psl":{"title":"PATROL Scripting Language","owner":"bertysentry"},"pcaxis":{"title":"PC-Axis","alias":"px","owner":"RunDevelopment"},"peoplecode":{"title":"PeopleCode","alias":"pcode","owner":"RunDevelopment"},"perl":{"title":"Perl","owner":"Golmote"},"php":{"title":"PHP","require":"markup-templating","owner":"milesj"},"phpdoc":{"title":"PHPDoc","require":["php","javadoclike"],"modify":"php","owner":"RunDevelopment"},"php-extras":{"title":"PHP Extras","require":"php","modify":"php","owner":"milesj"},"plant-uml":{"title":"PlantUML","alias":"plantuml","owner":"RunDevelopment"},"plsql":{"title":"PL/SQL","require":"sql","owner":"Golmote"},"powerquery":{"title":"PowerQuery","alias":["pq","mscript"],"owner":"peterbud"},"powershell":{"title":"PowerShell","owner":"nauzilus"},"processing":{"title":"Processing","require":"clike","owner":"Golmote"},"prolog":{"title":"Prolog","owner":"Golmote"},"promql":{"title":"PromQL","owner":"arendjr"},"properties":{"title":".properties","owner":"Golmote"},"protobuf":{"title":"Protocol Buffers","require":"clike","owner":"just-boris"},"pug":{"title":"Pug","require":["markup","javascript"],"optional":["coffeescript","ejs","handlebars","less","livescript","markdown","scss","stylus","twig"],"owner":"Golmote"},"puppet":{"title":"Puppet","owner":"Golmote"},"pure":{"title":"Pure","optional":["c","cpp","fortran"],"owner":"Golmote"},"purebasic":{"title":"PureBasic","require":"clike","alias":"pbfasm","owner":"HeX0R101"},"purescript":{"title":"PureScript","require":"haskell","alias":"purs","owner":"sriharshachilakapati"},"python":{"title":"Python","alias":"py","owner":"multipetros"},"qsharp":{"title":"Q#","require":"clike","alias":"qs","owner":"fedonman"},"q":{"title":"Q (kdb+ database)","owner":"Golmote"},"qml":{"title":"QML","require":"javascript","owner":"RunDevelopment"},"qore":{"title":"Qore","require":"clike","owner":"temnroegg"},"r":{"title":"R","owner":"Golmote"},"racket":{"title":"Racket","require":"scheme","alias":"rkt","owner":"RunDevelopment"},"cshtml":{"title":"Razor C#","alias":"razor","require":["markup","csharp"],"optional":["css","css-extras","javascript","js-extras"],"owner":"RunDevelopment"},"jsx":{"title":"React JSX","require":["markup","javascript"],"optional":["jsdoc","js-extras","js-templates"],"owner":"vkbansal"},"tsx":{"title":"React TSX","require":["jsx","typescript"]},"reason":{"title":"Reason","require":"clike","owner":"Golmote"},"regex":{"title":"Regex","owner":"RunDevelopment"},"rego":{"title":"Rego","owner":"JordanSh"},"renpy":{"title":"Ren'py","alias":"rpy","owner":"HyuchiaDiego"},"rescript":{"title":"ReScript","alias":"res","owner":"vmarcosp"},"rest":{"title":"reST (reStructuredText)","owner":"Golmote"},"rip":{"title":"Rip","owner":"ravinggenius"},"roboconf":{"title":"Roboconf","owner":"Golmote"},"robotframework":{"title":"Robot Framework","alias":"robot","owner":"RunDevelopment"},"ruby":{"title":"Ruby","require":"clike","alias":"rb","owner":"samflores"},"rust":{"title":"Rust","owner":"Golmote"},"sas":{"title":"SAS","optional":["groovy","lua","sql"],"owner":"Golmote"},"sass":{"title":"Sass (Sass)","require":"css","optional":"css-extras","owner":"Golmote"},"scss":{"title":"Sass (Scss)","require":"css","optional":"css-extras","owner":"MoOx"},"scala":{"title":"Scala","require":"java","owner":"jozic"},"scheme":{"title":"Scheme","owner":"bacchus123"},"shell-session":{"title":"Shell session","require":"bash","alias":["sh-session","shellsession"],"owner":"RunDevelopment"},"smali":{"title":"Smali","owner":"RunDevelopment"},"smalltalk":{"title":"Smalltalk","owner":"Golmote"},"smarty":{"title":"Smarty","require":"markup-templating","optional":"php","owner":"Golmote"},"sml":{"title":"SML","alias":"smlnj","aliasTitles":{"smlnj":"SML/NJ"},"owner":"RunDevelopment"},"solidity":{"title":"Solidity (Ethereum)","alias":"sol","require":"clike","owner":"glachaud"},"solution-file":{"title":"Solution file","alias":"sln","owner":"RunDevelopment"},"soy":{"title":"Soy (Closure Template)","require":"markup-templating","owner":"Golmote"},"sparql":{"title":"SPARQL","require":"turtle","owner":"Triply-Dev","alias":"rq"},"splunk-spl":{"title":"Splunk SPL","owner":"RunDevelopment"},"sqf":{"title":"SQF: Status Quo Function (Arma 3)","require":"clike","owner":"RunDevelopment"},"sql":{"title":"SQL","owner":"multipetros"},"squirrel":{"title":"Squirrel","require":"clike","owner":"RunDevelopment"},"stan":{"title":"Stan","owner":"RunDevelopment"},"stata":{"title":"Stata Ado","require":["mata","java","python"],"owner":"RunDevelopment"},"iecst":{"title":"Structured Text (IEC 61131-3)","owner":"serhioromano"},"stylus":{"title":"Stylus","owner":"vkbansal"},"supercollider":{"title":"SuperCollider","alias":"sclang","owner":"RunDevelopment"},"swift":{"title":"Swift","owner":"chrischares"},"systemd":{"title":"Systemd configuration file","owner":"RunDevelopment"},"t4-templating":{"title":"T4 templating","owner":"RunDevelopment"},"t4-cs":{"title":"T4 Text Templates (C#)","require":["t4-templating","csharp"],"alias":"t4","owner":"RunDevelopment"},"t4-vb":{"title":"T4 Text Templates (VB)","require":["t4-templating","vbnet"],"owner":"RunDevelopment"},"tap":{"title":"TAP","owner":"isaacs","require":"yaml"},"tcl":{"title":"Tcl","owner":"PeterChaplin"},"tt2":{"title":"Template Toolkit 2","require":["clike","markup-templating"],"owner":"gflohr"},"textile":{"title":"Textile","require":"markup","optional":"css","owner":"Golmote"},"toml":{"title":"TOML","owner":"RunDevelopment"},"tremor":{"title":"Tremor","alias":["trickle","troy"],"owner":"darach","aliasTitles":{"trickle":"trickle","troy":"troy"}},"turtle":{"title":"Turtle","alias":"trig","aliasTitles":{"trig":"TriG"},"owner":"jakubklimek"},"twig":{"title":"Twig","require":"markup-templating","owner":"brandonkelly"},"typescript":{"title":"TypeScript","require":"javascript","optional":"js-templates","alias":"ts","owner":"vkbansal"},"typoscript":{"title":"TypoScript","alias":"tsconfig","aliasTitles":{"tsconfig":"TSConfig"},"owner":"dkern"},"unrealscript":{"title":"UnrealScript","alias":["uscript","uc"],"owner":"RunDevelopment"},"uorazor":{"title":"UO Razor Script","owner":"jaseowns"},"uri":{"title":"URI","alias":"url","aliasTitles":{"url":"URL"},"owner":"RunDevelopment"},"v":{"title":"V","require":"clike","owner":"taggon"},"vala":{"title":"Vala","require":"clike","optional":"regex","owner":"TemplarVolk"},"vbnet":{"title":"VB.Net","require":"basic","owner":"Bigsby"},"velocity":{"title":"Velocity","require":"markup","owner":"Golmote"},"verilog":{"title":"Verilog","owner":"a-rey"},"vhdl":{"title":"VHDL","owner":"a-rey"},"vim":{"title":"vim","owner":"westonganger"},"visual-basic":{"title":"Visual Basic","alias":["vb","vba"],"aliasTitles":{"vba":"VBA"},"owner":"Golmote"},"warpscript":{"title":"WarpScript","owner":"RunDevelopment"},"wasm":{"title":"WebAssembly","owner":"Golmote"},"web-idl":{"title":"Web IDL","alias":"webidl","owner":"RunDevelopment"},"wiki":{"title":"Wiki markup","require":"markup","owner":"Golmote"},"wolfram":{"title":"Wolfram language","alias":["mathematica","nb","wl"],"aliasTitles":{"mathematica":"Mathematica","nb":"Mathematica Notebook"},"owner":"msollami"},"wren":{"title":"Wren","owner":"clsource"},"xeora":{"title":"Xeora","require":"markup","alias":"xeoracube","aliasTitles":{"xeoracube":"XeoraCube"},"owner":"freakmaxi"},"xml-doc":{"title":"XML doc (.net)","require":"markup","modify":["csharp","fsharp","vbnet"],"owner":"RunDevelopment"},"xojo":{"title":"Xojo (REALbasic)","owner":"Golmote"},"xquery":{"title":"XQuery","require":"markup","owner":"Golmote"},"yaml":{"title":"YAML","alias":"yml","owner":"hason"},"yang":{"title":"YANG","owner":"RunDevelopment"},"zig":{"title":"Zig","owner":"RunDevelopment"}},"plugins":{"meta":{"path":"plugins/{id}/prism-{id}","link":"plugins/{id}/"},"line-highlight":{"title":"Line Highlight","description":"Highlights specific lines and/or line ranges."},"line-numbers":{"title":"Line Numbers","description":"Line number at the beginning of code lines.","owner":"kuba-kubula"},"show-invisibles":{"title":"Show Invisibles","description":"Show hidden characters such as tabs and line breaks.","optional":["autolinker","data-uri-highlight"]},"autolinker":{"title":"Autolinker","description":"Converts URLs and emails in code to clickable links. Parses Markdown links in comments."},"wpd":{"title":"WebPlatform Docs","description":"Makes tokens link to WebPlatform.org documentation. The links open in a new tab."},"custom-class":{"title":"Custom Class","description":"This plugin allows you to prefix Prism's default classes (.comment can become .namespace--comment) or replace them with your defined ones (like .editor__comment). You can even add new classes.","owner":"dvkndn","noCSS":true},"file-highlight":{"title":"File Highlight","description":"Fetch external files and highlight them with Prism. Used on the Prism website itself.","noCSS":true},"show-language":{"title":"Show Language","description":"Display the highlighted language in code blocks (inline code does not show the label).","owner":"nauzilus","noCSS":true,"require":"toolbar"},"jsonp-highlight":{"title":"JSONP Highlight","description":"Fetch content with JSONP and highlight some interesting content (e.g. GitHub/Gists or Bitbucket API).","noCSS":true,"owner":"nauzilus"},"highlight-keywords":{"title":"Highlight Keywords","description":"Adds special CSS classes for each keyword for fine-grained highlighting.","owner":"vkbansal","noCSS":true},"remove-initial-line-feed":{"title":"Remove initial line feed","description":"Removes the initial line feed in code blocks.","owner":"Golmote","noCSS":true},"inline-color":{"title":"Inline color","description":"Adds a small inline preview for colors in style sheets.","require":"css-extras","owner":"RunDevelopment"},"previewers":{"title":"Previewers","description":"Previewers for angles, colors, gradients, easing and time.","require":"css-extras","owner":"Golmote"},"autoloader":{"title":"Autoloader","description":"Automatically loads the needed languages to highlight the code blocks.","owner":"Golmote","noCSS":true},"keep-markup":{"title":"Keep Markup","description":"Prevents custom markup from being dropped out during highlighting.","owner":"Golmote","optional":"normalize-whitespace","noCSS":true},"command-line":{"title":"Command Line","description":"Display a command line with a prompt and, optionally, the output/response from the commands.","owner":"chriswells0"},"unescaped-markup":{"title":"Unescaped Markup","description":"Write markup without having to escape anything."},"normalize-whitespace":{"title":"Normalize Whitespace","description":"Supports multiple operations to normalize whitespace in code blocks.","owner":"zeitgeist87","optional":"unescaped-markup","noCSS":true},"data-uri-highlight":{"title":"Data-URI Highlight","description":"Highlights data-URI contents.","owner":"Golmote","noCSS":true},"toolbar":{"title":"Toolbar","description":"Attach a toolbar for plugins to easily register buttons on the top of a code block.","owner":"mAAdhaTTah"},"copy-to-clipboard":{"title":"Copy to Clipboard Button","description":"Add a button that copies the code block to the clipboard when clicked.","owner":"mAAdhaTTah","require":"toolbar","noCSS":true},"download-button":{"title":"Download Button","description":"A button in the toolbar of a code block adding a convenient way to download a code file.","owner":"Golmote","require":"toolbar","noCSS":true},"match-braces":{"title":"Match braces","description":"Highlights matching braces.","owner":"RunDevelopment"},"diff-highlight":{"title":"Diff Highlight","description":"Highlights the code inside diff blocks.","owner":"RunDevelopment","require":"diff"},"filter-highlight-all":{"title":"Filter highlightAll","description":"Filters the elements the highlightAll and highlightAllUnder methods actually highlight.","owner":"RunDevelopment","noCSS":true},"treeview":{"title":"Treeview","description":"A language with special styles to highlight file system tree structures.","owner":"Golmote"}}};
if (typeof module !== 'undefined' && module.exports) { module.exports = components; }
\ No newline at end of file
diff --git a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components.json b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components.json
index 903e4cfbc1..9c58e568ba 100644
--- a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components.json
+++ b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components.json
@@ -139,6 +139,24 @@
"title": "ARFF",
"owner": "Golmote"
},
+ "armasm": {
+ "title": "ARM Assembly",
+ "alias": "arm-asm",
+ "owner": "RunDevelopment"
+ },
+ "arturo": {
+ "title": "Arturo",
+ "alias": "art",
+ "optional": [
+ "bash",
+ "css",
+ "javascript",
+ "markup",
+ "markdown",
+ "sql"
+ ],
+ "owner": "drkameleon"
+ },
"asciidoc": {
"alias": "adoc",
"title": "AsciiDoc",
@@ -175,6 +193,14 @@
"alias": "avdl",
"owner": "RunDevelopment"
},
+ "awk": {
+ "title": "AWK",
+ "alias": "gawk",
+ "aliasTitles": {
+ "gawk": "GAWK"
+ },
+ "owner": "RunDevelopment"
+ },
"bash": {
"title": "Bash",
"alias": "shell",
@@ -299,6 +325,10 @@
"title": "Content-Security-Policy",
"owner": "ScottHelme"
},
+ "cooklang": {
+ "title": "Cooklang",
+ "owner": "ahue"
+ },
"coq": {
"title": "Coq",
"owner": "RunDevelopment"
@@ -318,6 +348,10 @@
"title": "CSV",
"owner": "RunDevelopment"
},
+ "cue": {
+ "title": "CUE",
+ "owner": "RunDevelopment"
+ },
"cypher": {
"title": "Cypher",
"owner": "RunDevelopment"
@@ -472,6 +506,11 @@
"title": "GEDCOM",
"owner": "Golmote"
},
+ "gettext": {
+ "title": "gettext",
+ "alias": "po",
+ "owner": "RunDevelopment"
+ },
"gherkin": {
"title": "Gherkin",
"owner": "hason"
@@ -490,6 +529,11 @@
"alias": "gni",
"owner": "RunDevelopment"
},
+ "linker-script": {
+ "title": "GNU Linker Script",
+ "alias": "ld",
+ "owner": "RunDevelopment"
+ },
"go": {
"title": "Go",
"require": "clike",
@@ -529,7 +573,10 @@
"handlebars": {
"title": "Handlebars",
"require": "markup-templating",
- "alias": "hbs",
+ "alias": ["hbs", "mustache"],
+ "aliasTitles": {
+ "mustache": "Mustache"
+ },
"owner": "Golmote"
},
"haskell": {
@@ -830,6 +877,10 @@
"require": "markup",
"owner": "Golmote"
},
+ "mata": {
+ "title": "Mata",
+ "owner": "RunDevelopment"
+ },
"matlab": {
"title": "MATLAB",
"owner": "Golmote"
@@ -922,6 +973,10 @@
"title": "OCaml",
"owner": "Golmote"
},
+ "odin": {
+ "title": "Odin",
+ "owner": "edukisto"
+ },
"opencl": {
"title": "OpenCL",
"require": "c",
@@ -996,6 +1051,11 @@
"modify": "php",
"owner": "milesj"
},
+ "plant-uml": {
+ "title": "PlantUML",
+ "alias": "plantuml",
+ "owner": "RunDevelopment"
+ },
"plsql": {
"title": "PL/SQL",
"require": "sql",
@@ -1152,6 +1212,11 @@
"alias": "rpy",
"owner": "HyuchiaDiego"
},
+ "rescript": {
+ "title": "ReScript",
+ "alias": "res",
+ "owner": "vmarcosp"
+ },
"rest": {
"title": "reST (reStructuredText)",
"owner": "Golmote"
@@ -1277,6 +1342,11 @@
"title": "Stan",
"owner": "RunDevelopment"
},
+ "stata": {
+ "title": "Stata Ado",
+ "require": ["mata", "java", "python"],
+ "owner": "RunDevelopment"
+ },
"iecst": {
"title": "Structured Text (IEC 61131-3)",
"owner": "serhioromano"
@@ -1285,6 +1355,11 @@
"title": "Stylus",
"owner": "vkbansal"
},
+ "supercollider": {
+ "title": "SuperCollider",
+ "alias": "sclang",
+ "owner": "RunDevelopment"
+ },
"swift": {
"title": "Swift",
"owner": "chrischares"
diff --git a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-abap.js b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-abap.js
index ba7c4acbbe..f086acd788 100644
--- a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-abap.js
+++ b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-abap.js
@@ -16,7 +16,7 @@ Prism.languages.abap = {
alias: 'comment'
},
'keyword': {
- pattern: /(\s|\.|^)(?:SCIENTIFIC_WITH_LEADING_ZERO|SCALE_PRESERVING_SCIENTIFIC|RMC_COMMUNICATION_FAILURE|END-ENHANCEMENT-SECTION|MULTIPLY-CORRESPONDING|SUBTRACT-CORRESPONDING|VERIFICATION-MESSAGE|DIVIDE-CORRESPONDING|ENHANCEMENT-SECTION|CURRENCY_CONVERSION|RMC_SYSTEM_FAILURE|START-OF-SELECTION|MOVE-CORRESPONDING|RMC_INVALID_STATUS|CUSTOMER-FUNCTION|END-OF-DEFINITION|ENHANCEMENT-POINT|SYSTEM-EXCEPTIONS|ADD-CORRESPONDING|SCALE_PRESERVING|SELECTION-SCREEN|CURSOR-SELECTION|END-OF-SELECTION|LOAD-OF-PROGRAM|SCROLL-BOUNDARY|SELECTION-TABLE|EXCEPTION-TABLE|IMPLEMENTATIONS|PARAMETER-TABLE|RIGHT-JUSTIFIED|UNIT_CONVERSION|AUTHORITY-CHECK|LIST-PROCESSING|SIGN_AS_POSTFIX|COL_BACKGROUND|IMPLEMENTATION|INTERFACE-POOL|TRANSFORMATION|IDENTIFICATION|ENDENHANCEMENT|LINE-SELECTION|INITIALIZATION|LEFT-JUSTIFIED|SELECT-OPTIONS|SELECTION-SETS|COMMUNICATION|CORRESPONDING|DECIMAL_SHIFT|PRINT-CONTROL|VALUE-REQUEST|CHAIN-REQUEST|FUNCTION-POOL|FIELD-SYMBOLS|FUNCTIONALITY|INVERTED-DATE|SELECTION-SET|CLASS-METHODS|OUTPUT-LENGTH|CLASS-CODING|COL_NEGATIVE|ERRORMESSAGE|FIELD-GROUPS|HELP-REQUEST|NO-EXTENSION|NO-TOPOFPAGE|REDEFINITION|DISPLAY-MODE|ENDINTERFACE|EXIT-COMMAND|FIELD-SYMBOL|NO-SCROLLING|SHORTDUMP-ID|ACCESSPOLICY|CLASS-EVENTS|COL_POSITIVE|DECLARATIONS|ENHANCEMENTS|FILTER-TABLE|SWITCHSTATES|SYNTAX-CHECK|TRANSPORTING|ASYNCHRONOUS|SYNTAX-TRACE|TOKENIZATION|USER-COMMAND|WITH-HEADING|ABAP-SOURCE|BREAK-POINT|CHAIN-INPUT|COMPRESSION|FIXED-POINT|NEW-SECTION|NON-UNICODE|OCCURRENCES|RESPONSIBLE|SYSTEM-CALL|TRACE-TABLE|ABBREVIATED|CHAR-TO-HEX|END-OF-FILE|ENDFUNCTION|ENVIRONMENT|ASSOCIATION|COL_HEADING|EDITOR-CALL|END-OF-PAGE|ENGINEERING|IMPLEMENTED|INTENSIFIED|RADIOBUTTON|SYSTEM-EXIT|TOP-OF-PAGE|TRANSACTION|APPLICATION|CONCATENATE|DESTINATION|ENHANCEMENT|IMMEDIATELY|NO-GROUPING|PRECOMPILED|REPLACEMENT|TITLE-LINES|ACTIVATION|BYTE-ORDER|CLASS-POOL|CONNECTION|CONVERSION|DEFINITION|DEPARTMENT|EXPIRATION|INHERITING|MESSAGE-ID|NO-HEADING|PERFORMING|QUEUE-ONLY|RIGHTSPACE|SCIENTIFIC|STATUSINFO|STRUCTURES|SYNCPOINTS|WITH-TITLE|ATTRIBUTES|BOUNDARIES|CLASS-DATA|COL_NORMAL|DD\/MM\/YYYY|DESCENDING|INTERFACES|LINE-COUNT|MM\/DD\/YYYY|NON-UNIQUE|PRESERVING|SELECTIONS|STATEMENTS|SUBROUTINE|TRUNCATION|TYPE-POOLS|ARITHMETIC|BACKGROUND|ENDPROVIDE|EXCEPTIONS|IDENTIFIER|INDEX-LINE|OBLIGATORY|PARAMETERS|PERCENTAGE|PUSHBUTTON|RESOLUTION|COMPONENTS|DEALLOCATE|DISCONNECT|DUPLICATES|FIRST-LINE|HEAD-LINES|NO-DISPLAY|OCCURRENCE|RESPECTING|RETURNCODE|SUBMATCHES|TRACE-FILE|ASCENDING|BYPASSING|ENDMODULE|EXCEPTION|EXCLUDING|EXPORTING|INCREMENT|MATCHCODE|PARAMETER|PARTIALLY|PREFERRED|REFERENCE|REPLACING|RETURNING|SELECTION|SEPARATED|SPECIFIED|STATEMENT|TIMESTAMP|TYPE-POOL|ACCEPTING|APPENDAGE|ASSIGNING|COL_GROUP|COMPARING|CONSTANTS|DANGEROUS|IMPORTING|INSTANCES|LEFTSPACE|LOG-POINT|QUICKINFO|READ-ONLY|SCROLLING|SQLSCRIPT|STEP-LOOP|TOP-LINES|TRANSLATE|APPENDING|AUTHORITY|CHARACTER|COMPONENT|CONDITION|DIRECTORY|DUPLICATE|MESSAGING|RECEIVING|SUBSCREEN|ACCORDING|COL_TOTAL|END-LINES|ENDMETHOD|ENDSELECT|EXPANDING|EXTENSION|INCLUDING|INFOTYPES|INTERFACE|INTERVALS|LINE-SIZE|PF-STATUS|PROCEDURE|PROTECTED|REQUESTED|RESUMABLE|RIGHTPLUS|SAP-SPOOL|SECONDARY|STRUCTURE|SUBSTRING|TABLEVIEW|NUMOFCHAR|ADJACENT|ANALYSIS|ASSIGNED|BACKWARD|CHANNELS|CHECKBOX|CONTINUE|CRITICAL|DATAINFO|DD\/MM\/YY|DURATION|ENCODING|ENDCLASS|FUNCTION|LEFTPLUS|LINEFEED|MM\/DD\/YY|OVERFLOW|RECEIVED|SKIPPING|SORTABLE|STANDARD|SUBTRACT|SUPPRESS|TABSTRIP|TITLEBAR|TRUNCATE|UNASSIGN|WHENEVER|ANALYZER|COALESCE|COMMENTS|CONDENSE|DECIMALS|DEFERRED|ENDWHILE|EXPLICIT|KEYWORDS|MESSAGES|POSITION|PRIORITY|RECEIVER|RENAMING|TIMEZONE|TRAILING|ALLOCATE|CENTERED|CIRCULAR|CONTROLS|CURRENCY|DELETING|DESCRIBE|DISTANCE|ENDCATCH|EXPONENT|EXTENDED|GENERATE|IGNORING|INCLUDES|INTERNAL|MAJOR-ID|MODIFIER|NEW-LINE|OPTIONAL|PROPERTY|ROLLBACK|STARTING|SUPPLIED|ABSTRACT|CHANGING|CONTEXTS|CREATING|CUSTOMER|DATABASE|DAYLIGHT|DEFINING|DISTINCT|DIVISION|ENABLING|ENDCHAIN|ESCAPING|HARMLESS|IMPLICIT|INACTIVE|LANGUAGE|MINOR-ID|MULTIPLY|NEW-PAGE|NO-TITLE|POS_HIGH|SEPARATE|TEXTPOOL|TRANSFER|SELECTOR|DBMAXLEN|ITERATOR|ARCHIVE|BIT-XOR|BYTE-CO|COLLECT|COMMENT|CURRENT|DEFAULT|DISPLAY|ENDFORM|EXTRACT|LEADING|LISTBOX|LOCATOR|MEMBERS|METHODS|NESTING|POS_LOW|PROCESS|PROVIDE|RAISING|RESERVE|SECONDS|SUMMARY|VISIBLE|BETWEEN|BIT-AND|BYTE-CS|CLEANUP|COMPUTE|CONTROL|CONVERT|DATASET|ENDCASE|FORWARD|HEADERS|HOTSPOT|INCLUDE|INVERSE|KEEPING|NO-ZERO|OBJECTS|OVERLAY|PADDING|PATTERN|PROGRAM|REFRESH|SECTION|SUMMING|TESTING|VERSION|WINDOWS|WITHOUT|BIT-NOT|BYTE-CA|BYTE-NA|CASTING|CONTEXT|COUNTRY|DYNAMIC|ENABLED|ENDLOOP|EXECUTE|FRIENDS|HANDLER|HEADING|INITIAL|\*-INPUT|LOGFILE|MAXIMUM|MINIMUM|NO-GAPS|NO-SIGN|PRAGMAS|PRIMARY|PRIVATE|REDUCED|REPLACE|REQUEST|RESULTS|UNICODE|WARNING|ALIASES|BYTE-CN|BYTE-NS|CALLING|COL_KEY|COLUMNS|CONNECT|ENDEXEC|ENTRIES|EXCLUDE|FILTERS|FURTHER|HELP-ID|LOGICAL|MAPPING|MESSAGE|NAMETAB|OPTIONS|PACKAGE|PERFORM|RECEIVE|STATICS|VARYING|BINDING|CHARLEN|GREATER|XSTRLEN|ACCEPT|APPEND|DETAIL|ELSEIF|ENDING|ENDTRY|FORMAT|FRAMES|GIVING|HASHED|HEADER|IMPORT|INSERT|MARGIN|MODULE|NATIVE|OBJECT|OFFSET|REMOTE|RESUME|SAVING|SIMPLE|SUBMIT|TABBED|TOKENS|UNIQUE|UNPACK|UPDATE|WINDOW|YELLOW|ACTUAL|ASPECT|CENTER|CURSOR|DELETE|DIALOG|DIVIDE|DURING|ERRORS|EVENTS|EXTEND|FILTER|HANDLE|HAVING|IGNORE|LITTLE|MEMORY|NO-GAP|OCCURS|OPTION|PERSON|PLACES|PUBLIC|REDUCE|REPORT|RESULT|SINGLE|SORTED|SWITCH|SYNTAX|TARGET|VALUES|WRITER|ASSERT|BLOCKS|BOUNDS|BUFFER|CHANGE|COLUMN|COMMIT|CONCAT|COPIES|CREATE|DDMMYY|DEFINE|ENDIAN|ESCAPE|EXPAND|KERNEL|LAYOUT|LEGACY|LEVELS|MMDDYY|NUMBER|OUTPUT|RANGES|READER|RETURN|SCREEN|SEARCH|SELECT|SHARED|SOURCE|STABLE|STATIC|SUBKEY|SUFFIX|TABLES|UNWIND|YYMMDD|ASSIGN|BACKUP|BEFORE|BINARY|BIT-OR|BLANKS|CLIENT|CODING|COMMON|DEMAND|DYNPRO|EXCEPT|EXISTS|EXPORT|FIELDS|GLOBAL|GROUPS|LENGTH|LOCALE|MEDIUM|METHOD|MODIFY|NESTED|OTHERS|REJECT|SCROLL|SUPPLY|SYMBOL|ENDFOR|STRLEN|ALIGN|BEGIN|BOUND|ENDAT|ENTRY|EVENT|FINAL|FLUSH|GRANT|INNER|SHORT|USING|WRITE|AFTER|BLACK|BLOCK|CLOCK|COLOR|COUNT|DUMMY|EMPTY|ENDDO|ENDON|GREEN|INDEX|INOUT|LEAVE|LEVEL|LINES|MODIF|ORDER|OUTER|RANGE|RESET|RETRY|RIGHT|SMART|SPLIT|STYLE|TABLE|THROW|UNDER|UNTIL|UPPER|UTF-8|WHERE|ALIAS|BLANK|CLEAR|CLOSE|EXACT|FETCH|FIRST|FOUND|GROUP|LLANG|LOCAL|OTHER|REGEX|SPOOL|TITLE|TYPES|VALID|WHILE|ALPHA|BOXED|CATCH|CHAIN|CHECK|CLASS|COVER|ENDIF|EQUIV|FIELD|FLOOR|FRAME|INPUT|LOWER|MATCH|NODES|PAGES|PRINT|RAISE|ROUND|SHIFT|SPACE|SPOTS|STAMP|STATE|TASKS|TIMES|TRMAC|ULINE|UNION|VALUE|WIDTH|EQUAL|LOG10|TRUNC|BLOB|CASE|CEIL|CLOB|COND|EXIT|FILE|GAPS|HOLD|INCL|INTO|KEEP|KEYS|LAST|LINE|LONG|LPAD|MAIL|MODE|OPEN|PINK|READ|ROWS|TEST|THEN|ZERO|AREA|BACK|BADI|BYTE|CAST|EDIT|EXEC|FAIL|FIND|FKEQ|FONT|FREE|GKEQ|HIDE|INIT|ITNO|LATE|LOOP|MAIN|MARK|MOVE|NEXT|NULL|RISK|ROLE|UNIT|WAIT|ZONE|BASE|CALL|CODE|DATA|DATE|FKGE|GKGE|HIGH|KIND|LEFT|LIST|MASK|MESH|NAME|NODE|PACK|PAGE|POOL|SEND|SIGN|SIZE|SOME|STOP|TASK|TEXT|TIME|USER|VARY|WITH|WORD|BLUE|CONV|COPY|DEEP|ELSE|FORM|FROM|HINT|ICON|JOIN|LIKE|LOAD|ONLY|PART|SCAN|SKIP|SORT|TYPE|UNIX|VIEW|WHEN|WORK|ACOS|ASIN|ATAN|COSH|EACH|FRAC|LESS|RTTI|SINH|SQRT|TANH|AVG|BIT|DIV|ISO|LET|OUT|PAD|SQL|ALL|CI_|CPI|END|LOB|LPI|MAX|MIN|NEW|OLE|RUN|SET|\?TO|YES|ABS|ADD|AND|BIG|FOR|HDB|JOB|LOW|NOT|SAP|TRY|VIA|XML|ANY|GET|IDS|KEY|MOD|OFF|PUT|RAW|RED|REF|SUM|TAB|XSD|CNT|COS|EXP|LOG|SIN|TAN|XOR|AT|CO|CP|DO|GT|ID|IF|NS|OR|BT|CA|CS|GE|NA|NB|EQ|IN|LT|NE|NO|OF|ON|PF|TO|AS|BY|CN|IS|LE|NP|UP|E|I|M|O|Z|C|X)\b/i,
+ pattern: /(\s|\.|^)(?:\*-INPUT|\?TO|ABAP-SOURCE|ABBREVIATED|ABS|ABSTRACT|ACCEPT|ACCEPTING|ACCESSPOLICY|ACCORDING|ACOS|ACTIVATION|ACTUAL|ADD|ADD-CORRESPONDING|ADJACENT|AFTER|ALIAS|ALIASES|ALIGN|ALL|ALLOCATE|ALPHA|ANALYSIS|ANALYZER|AND|ANY|APPEND|APPENDAGE|APPENDING|APPLICATION|ARCHIVE|AREA|ARITHMETIC|AS|ASCENDING|ASIN|ASPECT|ASSERT|ASSIGN|ASSIGNED|ASSIGNING|ASSOCIATION|ASYNCHRONOUS|AT|ATAN|ATTRIBUTES|AUTHORITY|AUTHORITY-CHECK|AVG|BACK|BACKGROUND|BACKUP|BACKWARD|BADI|BASE|BEFORE|BEGIN|BETWEEN|BIG|BINARY|BINDING|BIT|BIT-AND|BIT-NOT|BIT-OR|BIT-XOR|BLACK|BLANK|BLANKS|BLOB|BLOCK|BLOCKS|BLUE|BOUND|BOUNDARIES|BOUNDS|BOXED|BREAK-POINT|BT|BUFFER|BY|BYPASSING|BYTE|BYTE-CA|BYTE-CN|BYTE-CO|BYTE-CS|BYTE-NA|BYTE-NS|BYTE-ORDER|C|CA|CALL|CALLING|CASE|CAST|CASTING|CATCH|CEIL|CENTER|CENTERED|CHAIN|CHAIN-INPUT|CHAIN-REQUEST|CHANGE|CHANGING|CHANNELS|CHAR-TO-HEX|CHARACTER|CHARLEN|CHECK|CHECKBOX|CIRCULAR|CI_|CLASS|CLASS-CODING|CLASS-DATA|CLASS-EVENTS|CLASS-METHODS|CLASS-POOL|CLEANUP|CLEAR|CLIENT|CLOB|CLOCK|CLOSE|CN|CNT|CO|COALESCE|CODE|CODING|COLLECT|COLOR|COLUMN|COLUMNS|COL_BACKGROUND|COL_GROUP|COL_HEADING|COL_KEY|COL_NEGATIVE|COL_NORMAL|COL_POSITIVE|COL_TOTAL|COMMENT|COMMENTS|COMMIT|COMMON|COMMUNICATION|COMPARING|COMPONENT|COMPONENTS|COMPRESSION|COMPUTE|CONCAT|CONCATENATE|COND|CONDENSE|CONDITION|CONNECT|CONNECTION|CONSTANTS|CONTEXT|CONTEXTS|CONTINUE|CONTROL|CONTROLS|CONV|CONVERSION|CONVERT|COPIES|COPY|CORRESPONDING|COS|COSH|COUNT|COUNTRY|COVER|CP|CPI|CREATE|CREATING|CRITICAL|CS|CURRENCY|CURRENCY_CONVERSION|CURRENT|CURSOR|CURSOR-SELECTION|CUSTOMER|CUSTOMER-FUNCTION|DANGEROUS|DATA|DATABASE|DATAINFO|DATASET|DATE|DAYLIGHT|DBMAXLEN|DD\/MM\/YY|DD\/MM\/YYYY|DDMMYY|DEALLOCATE|DECIMALS|DECIMAL_SHIFT|DECLARATIONS|DEEP|DEFAULT|DEFERRED|DEFINE|DEFINING|DEFINITION|DELETE|DELETING|DEMAND|DEPARTMENT|DESCENDING|DESCRIBE|DESTINATION|DETAIL|DIALOG|DIRECTORY|DISCONNECT|DISPLAY|DISPLAY-MODE|DISTANCE|DISTINCT|DIV|DIVIDE|DIVIDE-CORRESPONDING|DIVISION|DO|DUMMY|DUPLICATE|DUPLICATES|DURATION|DURING|DYNAMIC|DYNPRO|E|EACH|EDIT|EDITOR-CALL|ELSE|ELSEIF|EMPTY|ENABLED|ENABLING|ENCODING|END|END-ENHANCEMENT-SECTION|END-LINES|END-OF-DEFINITION|END-OF-FILE|END-OF-PAGE|END-OF-SELECTION|ENDAT|ENDCASE|ENDCATCH|ENDCHAIN|ENDCLASS|ENDDO|ENDENHANCEMENT|ENDEXEC|ENDFOR|ENDFORM|ENDFUNCTION|ENDIAN|ENDIF|ENDING|ENDINTERFACE|ENDLOOP|ENDMETHOD|ENDMODULE|ENDON|ENDPROVIDE|ENDSELECT|ENDTRY|ENDWHILE|ENGINEERING|ENHANCEMENT|ENHANCEMENT-POINT|ENHANCEMENT-SECTION|ENHANCEMENTS|ENTRIES|ENTRY|ENVIRONMENT|EQ|EQUAL|EQUIV|ERRORMESSAGE|ERRORS|ESCAPE|ESCAPING|EVENT|EVENTS|EXACT|EXCEPT|EXCEPTION|EXCEPTION-TABLE|EXCEPTIONS|EXCLUDE|EXCLUDING|EXEC|EXECUTE|EXISTS|EXIT|EXIT-COMMAND|EXP|EXPAND|EXPANDING|EXPIRATION|EXPLICIT|EXPONENT|EXPORT|EXPORTING|EXTEND|EXTENDED|EXTENSION|EXTRACT|FAIL|FETCH|FIELD|FIELD-GROUPS|FIELD-SYMBOL|FIELD-SYMBOLS|FIELDS|FILE|FILTER|FILTER-TABLE|FILTERS|FINAL|FIND|FIRST|FIRST-LINE|FIXED-POINT|FKEQ|FKGE|FLOOR|FLUSH|FONT|FOR|FORM|FORMAT|FORWARD|FOUND|FRAC|FRAME|FRAMES|FREE|FRIENDS|FROM|FUNCTION|FUNCTION-POOL|FUNCTIONALITY|FURTHER|GAPS|GE|GENERATE|GET|GIVING|GKEQ|GKGE|GLOBAL|GRANT|GREATER|GREEN|GROUP|GROUPS|GT|HANDLE|HANDLER|HARMLESS|HASHED|HAVING|HDB|HEAD-LINES|HEADER|HEADERS|HEADING|HELP-ID|HELP-REQUEST|HIDE|HIGH|HINT|HOLD|HOTSPOT|I|ICON|ID|IDENTIFICATION|IDENTIFIER|IDS|IF|IGNORE|IGNORING|IMMEDIATELY|IMPLEMENTATION|IMPLEMENTATIONS|IMPLEMENTED|IMPLICIT|IMPORT|IMPORTING|IN|INACTIVE|INCL|INCLUDE|INCLUDES|INCLUDING|INCREMENT|INDEX|INDEX-LINE|INFOTYPES|INHERITING|INIT|INITIAL|INITIALIZATION|INNER|INOUT|INPUT|INSERT|INSTANCES|INTENSIFIED|INTERFACE|INTERFACE-POOL|INTERFACES|INTERNAL|INTERVALS|INTO|INVERSE|INVERTED-DATE|IS|ISO|ITERATOR|ITNO|JOB|JOIN|KEEP|KEEPING|KERNEL|KEY|KEYS|KEYWORDS|KIND|LANGUAGE|LAST|LATE|LAYOUT|LE|LEADING|LEAVE|LEFT|LEFT-JUSTIFIED|LEFTPLUS|LEFTSPACE|LEGACY|LENGTH|LESS|LET|LEVEL|LEVELS|LIKE|LINE|LINE-COUNT|LINE-SELECTION|LINE-SIZE|LINEFEED|LINES|LIST|LIST-PROCESSING|LISTBOX|LITTLE|LLANG|LOAD|LOAD-OF-PROGRAM|LOB|LOCAL|LOCALE|LOCATOR|LOG|LOG-POINT|LOG10|LOGFILE|LOGICAL|LONG|LOOP|LOW|LOWER|LPAD|LPI|LT|M|MAIL|MAIN|MAJOR-ID|MAPPING|MARGIN|MARK|MASK|MATCH|MATCHCODE|MAX|MAXIMUM|MEDIUM|MEMBERS|MEMORY|MESH|MESSAGE|MESSAGE-ID|MESSAGES|MESSAGING|METHOD|METHODS|MIN|MINIMUM|MINOR-ID|MM\/DD\/YY|MM\/DD\/YYYY|MMDDYY|MOD|MODE|MODIF|MODIFIER|MODIFY|MODULE|MOVE|MOVE-CORRESPONDING|MULTIPLY|MULTIPLY-CORRESPONDING|NA|NAME|NAMETAB|NATIVE|NB|NE|NESTED|NESTING|NEW|NEW-LINE|NEW-PAGE|NEW-SECTION|NEXT|NO|NO-DISPLAY|NO-EXTENSION|NO-GAP|NO-GAPS|NO-GROUPING|NO-HEADING|NO-SCROLLING|NO-SIGN|NO-TITLE|NO-TOPOFPAGE|NO-ZERO|NODE|NODES|NON-UNICODE|NON-UNIQUE|NOT|NP|NS|NULL|NUMBER|NUMOFCHAR|O|OBJECT|OBJECTS|OBLIGATORY|OCCURRENCE|OCCURRENCES|OCCURS|OF|OFF|OFFSET|OLE|ON|ONLY|OPEN|OPTION|OPTIONAL|OPTIONS|OR|ORDER|OTHER|OTHERS|OUT|OUTER|OUTPUT|OUTPUT-LENGTH|OVERFLOW|OVERLAY|PACK|PACKAGE|PAD|PADDING|PAGE|PAGES|PARAMETER|PARAMETER-TABLE|PARAMETERS|PART|PARTIALLY|PATTERN|PERCENTAGE|PERFORM|PERFORMING|PERSON|PF|PF-STATUS|PINK|PLACES|POOL|POSITION|POS_HIGH|POS_LOW|PRAGMAS|PRECOMPILED|PREFERRED|PRESERVING|PRIMARY|PRINT|PRINT-CONTROL|PRIORITY|PRIVATE|PROCEDURE|PROCESS|PROGRAM|PROPERTY|PROTECTED|PROVIDE|PUBLIC|PUSHBUTTON|PUT|QUEUE-ONLY|QUICKINFO|RADIOBUTTON|RAISE|RAISING|RANGE|RANGES|RAW|READ|READ-ONLY|READER|RECEIVE|RECEIVED|RECEIVER|RECEIVING|RED|REDEFINITION|REDUCE|REDUCED|REF|REFERENCE|REFRESH|REGEX|REJECT|REMOTE|RENAMING|REPLACE|REPLACEMENT|REPLACING|REPORT|REQUEST|REQUESTED|RESERVE|RESET|RESOLUTION|RESPECTING|RESPONSIBLE|RESULT|RESULTS|RESUMABLE|RESUME|RETRY|RETURN|RETURNCODE|RETURNING|RIGHT|RIGHT-JUSTIFIED|RIGHTPLUS|RIGHTSPACE|RISK|RMC_COMMUNICATION_FAILURE|RMC_INVALID_STATUS|RMC_SYSTEM_FAILURE|ROLE|ROLLBACK|ROUND|ROWS|RTTI|RUN|SAP|SAP-SPOOL|SAVING|SCALE_PRESERVING|SCALE_PRESERVING_SCIENTIFIC|SCAN|SCIENTIFIC|SCIENTIFIC_WITH_LEADING_ZERO|SCREEN|SCROLL|SCROLL-BOUNDARY|SCROLLING|SEARCH|SECONDARY|SECONDS|SECTION|SELECT|SELECT-OPTIONS|SELECTION|SELECTION-SCREEN|SELECTION-SET|SELECTION-SETS|SELECTION-TABLE|SELECTIONS|SELECTOR|SEND|SEPARATE|SEPARATED|SET|SHARED|SHIFT|SHORT|SHORTDUMP-ID|SIGN|SIGN_AS_POSTFIX|SIMPLE|SIN|SINGLE|SINH|SIZE|SKIP|SKIPPING|SMART|SOME|SORT|SORTABLE|SORTED|SOURCE|SPACE|SPECIFIED|SPLIT|SPOOL|SPOTS|SQL|SQLSCRIPT|SQRT|STABLE|STAMP|STANDARD|START-OF-SELECTION|STARTING|STATE|STATEMENT|STATEMENTS|STATIC|STATICS|STATUSINFO|STEP-LOOP|STOP|STRLEN|STRUCTURE|STRUCTURES|STYLE|SUBKEY|SUBMATCHES|SUBMIT|SUBROUTINE|SUBSCREEN|SUBSTRING|SUBTRACT|SUBTRACT-CORRESPONDING|SUFFIX|SUM|SUMMARY|SUMMING|SUPPLIED|SUPPLY|SUPPRESS|SWITCH|SWITCHSTATES|SYMBOL|SYNCPOINTS|SYNTAX|SYNTAX-CHECK|SYNTAX-TRACE|SYSTEM-CALL|SYSTEM-EXCEPTIONS|SYSTEM-EXIT|TAB|TABBED|TABLE|TABLES|TABLEVIEW|TABSTRIP|TAN|TANH|TARGET|TASK|TASKS|TEST|TESTING|TEXT|TEXTPOOL|THEN|THROW|TIME|TIMES|TIMESTAMP|TIMEZONE|TITLE|TITLE-LINES|TITLEBAR|TO|TOKENIZATION|TOKENS|TOP-LINES|TOP-OF-PAGE|TRACE-FILE|TRACE-TABLE|TRAILING|TRANSACTION|TRANSFER|TRANSFORMATION|TRANSLATE|TRANSPORTING|TRMAC|TRUNC|TRUNCATE|TRUNCATION|TRY|TYPE|TYPE-POOL|TYPE-POOLS|TYPES|ULINE|UNASSIGN|UNDER|UNICODE|UNION|UNIQUE|UNIT|UNIT_CONVERSION|UNIX|UNPACK|UNTIL|UNWIND|UP|UPDATE|UPPER|USER|USER-COMMAND|USING|UTF-8|VALID|VALUE|VALUE-REQUEST|VALUES|VARY|VARYING|VERIFICATION-MESSAGE|VERSION|VIA|VIEW|VISIBLE|WAIT|WARNING|WHEN|WHENEVER|WHERE|WHILE|WIDTH|WINDOW|WINDOWS|WITH|WITH-HEADING|WITH-TITLE|WITHOUT|WORD|WORK|WRITE|WRITER|X|XML|XOR|XSD|XSTRLEN|YELLOW|YES|YYMMDD|Z|ZERO|ZONE)(?![\w-])/i,
lookbehind: true
},
/* Numbers can be only integers. Decimal or Hex appear only as strings */
diff --git a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-abap.min.js b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-abap.min.js
index dd3bf65eea..d803a51ba0 100644
--- a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-abap.min.js
+++ b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-abap.min.js
@@ -1 +1 @@
-Prism.languages.abap={comment:/^\*.*/m,string:/(`|')(?:\\.|(?!\1)[^\\\r\n])*\1/,"string-template":{pattern:/([|}])(?:\\.|[^\\|{\r\n])*(?=[|{])/,lookbehind:!0,alias:"string"},"eol-comment":{pattern:/(^|\s)".*/m,lookbehind:!0,alias:"comment"},keyword:{pattern:/(\s|\.|^)(?:SCIENTIFIC_WITH_LEADING_ZERO|SCALE_PRESERVING_SCIENTIFIC|RMC_COMMUNICATION_FAILURE|END-ENHANCEMENT-SECTION|MULTIPLY-CORRESPONDING|SUBTRACT-CORRESPONDING|VERIFICATION-MESSAGE|DIVIDE-CORRESPONDING|ENHANCEMENT-SECTION|CURRENCY_CONVERSION|RMC_SYSTEM_FAILURE|START-OF-SELECTION|MOVE-CORRESPONDING|RMC_INVALID_STATUS|CUSTOMER-FUNCTION|END-OF-DEFINITION|ENHANCEMENT-POINT|SYSTEM-EXCEPTIONS|ADD-CORRESPONDING|SCALE_PRESERVING|SELECTION-SCREEN|CURSOR-SELECTION|END-OF-SELECTION|LOAD-OF-PROGRAM|SCROLL-BOUNDARY|SELECTION-TABLE|EXCEPTION-TABLE|IMPLEMENTATIONS|PARAMETER-TABLE|RIGHT-JUSTIFIED|UNIT_CONVERSION|AUTHORITY-CHECK|LIST-PROCESSING|SIGN_AS_POSTFIX|COL_BACKGROUND|IMPLEMENTATION|INTERFACE-POOL|TRANSFORMATION|IDENTIFICATION|ENDENHANCEMENT|LINE-SELECTION|INITIALIZATION|LEFT-JUSTIFIED|SELECT-OPTIONS|SELECTION-SETS|COMMUNICATION|CORRESPONDING|DECIMAL_SHIFT|PRINT-CONTROL|VALUE-REQUEST|CHAIN-REQUEST|FUNCTION-POOL|FIELD-SYMBOLS|FUNCTIONALITY|INVERTED-DATE|SELECTION-SET|CLASS-METHODS|OUTPUT-LENGTH|CLASS-CODING|COL_NEGATIVE|ERRORMESSAGE|FIELD-GROUPS|HELP-REQUEST|NO-EXTENSION|NO-TOPOFPAGE|REDEFINITION|DISPLAY-MODE|ENDINTERFACE|EXIT-COMMAND|FIELD-SYMBOL|NO-SCROLLING|SHORTDUMP-ID|ACCESSPOLICY|CLASS-EVENTS|COL_POSITIVE|DECLARATIONS|ENHANCEMENTS|FILTER-TABLE|SWITCHSTATES|SYNTAX-CHECK|TRANSPORTING|ASYNCHRONOUS|SYNTAX-TRACE|TOKENIZATION|USER-COMMAND|WITH-HEADING|ABAP-SOURCE|BREAK-POINT|CHAIN-INPUT|COMPRESSION|FIXED-POINT|NEW-SECTION|NON-UNICODE|OCCURRENCES|RESPONSIBLE|SYSTEM-CALL|TRACE-TABLE|ABBREVIATED|CHAR-TO-HEX|END-OF-FILE|ENDFUNCTION|ENVIRONMENT|ASSOCIATION|COL_HEADING|EDITOR-CALL|END-OF-PAGE|ENGINEERING|IMPLEMENTED|INTENSIFIED|RADIOBUTTON|SYSTEM-EXIT|TOP-OF-PAGE|TRANSACTION|APPLICATION|CONCATENATE|DESTINATION|ENHANCEMENT|IMMEDIATELY|NO-GROUPING|PRECOMPILED|REPLACEMENT|TITLE-LINES|ACTIVATION|BYTE-ORDER|CLASS-POOL|CONNECTION|CONVERSION|DEFINITION|DEPARTMENT|EXPIRATION|INHERITING|MESSAGE-ID|NO-HEADING|PERFORMING|QUEUE-ONLY|RIGHTSPACE|SCIENTIFIC|STATUSINFO|STRUCTURES|SYNCPOINTS|WITH-TITLE|ATTRIBUTES|BOUNDARIES|CLASS-DATA|COL_NORMAL|DD\/MM\/YYYY|DESCENDING|INTERFACES|LINE-COUNT|MM\/DD\/YYYY|NON-UNIQUE|PRESERVING|SELECTIONS|STATEMENTS|SUBROUTINE|TRUNCATION|TYPE-POOLS|ARITHMETIC|BACKGROUND|ENDPROVIDE|EXCEPTIONS|IDENTIFIER|INDEX-LINE|OBLIGATORY|PARAMETERS|PERCENTAGE|PUSHBUTTON|RESOLUTION|COMPONENTS|DEALLOCATE|DISCONNECT|DUPLICATES|FIRST-LINE|HEAD-LINES|NO-DISPLAY|OCCURRENCE|RESPECTING|RETURNCODE|SUBMATCHES|TRACE-FILE|ASCENDING|BYPASSING|ENDMODULE|EXCEPTION|EXCLUDING|EXPORTING|INCREMENT|MATCHCODE|PARAMETER|PARTIALLY|PREFERRED|REFERENCE|REPLACING|RETURNING|SELECTION|SEPARATED|SPECIFIED|STATEMENT|TIMESTAMP|TYPE-POOL|ACCEPTING|APPENDAGE|ASSIGNING|COL_GROUP|COMPARING|CONSTANTS|DANGEROUS|IMPORTING|INSTANCES|LEFTSPACE|LOG-POINT|QUICKINFO|READ-ONLY|SCROLLING|SQLSCRIPT|STEP-LOOP|TOP-LINES|TRANSLATE|APPENDING|AUTHORITY|CHARACTER|COMPONENT|CONDITION|DIRECTORY|DUPLICATE|MESSAGING|RECEIVING|SUBSCREEN|ACCORDING|COL_TOTAL|END-LINES|ENDMETHOD|ENDSELECT|EXPANDING|EXTENSION|INCLUDING|INFOTYPES|INTERFACE|INTERVALS|LINE-SIZE|PF-STATUS|PROCEDURE|PROTECTED|REQUESTED|RESUMABLE|RIGHTPLUS|SAP-SPOOL|SECONDARY|STRUCTURE|SUBSTRING|TABLEVIEW|NUMOFCHAR|ADJACENT|ANALYSIS|ASSIGNED|BACKWARD|CHANNELS|CHECKBOX|CONTINUE|CRITICAL|DATAINFO|DD\/MM\/YY|DURATION|ENCODING|ENDCLASS|FUNCTION|LEFTPLUS|LINEFEED|MM\/DD\/YY|OVERFLOW|RECEIVED|SKIPPING|SORTABLE|STANDARD|SUBTRACT|SUPPRESS|TABSTRIP|TITLEBAR|TRUNCATE|UNASSIGN|WHENEVER|ANALYZER|COALESCE|COMMENTS|CONDENSE|DECIMALS|DEFERRED|ENDWHILE|EXPLICIT|KEYWORDS|MESSAGES|POSITION|PRIORITY|RECEIVER|RENAMING|TIMEZONE|TRAILING|ALLOCATE|CENTERED|CIRCULAR|CONTROLS|CURRENCY|DELETING|DESCRIBE|DISTANCE|ENDCATCH|EXPONENT|EXTENDED|GENERATE|IGNORING|INCLUDES|INTERNAL|MAJOR-ID|MODIFIER|NEW-LINE|OPTIONAL|PROPERTY|ROLLBACK|STARTING|SUPPLIED|ABSTRACT|CHANGING|CONTEXTS|CREATING|CUSTOMER|DATABASE|DAYLIGHT|DEFINING|DISTINCT|DIVISION|ENABLING|ENDCHAIN|ESCAPING|HARMLESS|IMPLICIT|INACTIVE|LANGUAGE|MINOR-ID|MULTIPLY|NEW-PAGE|NO-TITLE|POS_HIGH|SEPARATE|TEXTPOOL|TRANSFER|SELECTOR|DBMAXLEN|ITERATOR|ARCHIVE|BIT-XOR|BYTE-CO|COLLECT|COMMENT|CURRENT|DEFAULT|DISPLAY|ENDFORM|EXTRACT|LEADING|LISTBOX|LOCATOR|MEMBERS|METHODS|NESTING|POS_LOW|PROCESS|PROVIDE|RAISING|RESERVE|SECONDS|SUMMARY|VISIBLE|BETWEEN|BIT-AND|BYTE-CS|CLEANUP|COMPUTE|CONTROL|CONVERT|DATASET|ENDCASE|FORWARD|HEADERS|HOTSPOT|INCLUDE|INVERSE|KEEPING|NO-ZERO|OBJECTS|OVERLAY|PADDING|PATTERN|PROGRAM|REFRESH|SECTION|SUMMING|TESTING|VERSION|WINDOWS|WITHOUT|BIT-NOT|BYTE-CA|BYTE-NA|CASTING|CONTEXT|COUNTRY|DYNAMIC|ENABLED|ENDLOOP|EXECUTE|FRIENDS|HANDLER|HEADING|INITIAL|\*-INPUT|LOGFILE|MAXIMUM|MINIMUM|NO-GAPS|NO-SIGN|PRAGMAS|PRIMARY|PRIVATE|REDUCED|REPLACE|REQUEST|RESULTS|UNICODE|WARNING|ALIASES|BYTE-CN|BYTE-NS|CALLING|COL_KEY|COLUMNS|CONNECT|ENDEXEC|ENTRIES|EXCLUDE|FILTERS|FURTHER|HELP-ID|LOGICAL|MAPPING|MESSAGE|NAMETAB|OPTIONS|PACKAGE|PERFORM|RECEIVE|STATICS|VARYING|BINDING|CHARLEN|GREATER|XSTRLEN|ACCEPT|APPEND|DETAIL|ELSEIF|ENDING|ENDTRY|FORMAT|FRAMES|GIVING|HASHED|HEADER|IMPORT|INSERT|MARGIN|MODULE|NATIVE|OBJECT|OFFSET|REMOTE|RESUME|SAVING|SIMPLE|SUBMIT|TABBED|TOKENS|UNIQUE|UNPACK|UPDATE|WINDOW|YELLOW|ACTUAL|ASPECT|CENTER|CURSOR|DELETE|DIALOG|DIVIDE|DURING|ERRORS|EVENTS|EXTEND|FILTER|HANDLE|HAVING|IGNORE|LITTLE|MEMORY|NO-GAP|OCCURS|OPTION|PERSON|PLACES|PUBLIC|REDUCE|REPORT|RESULT|SINGLE|SORTED|SWITCH|SYNTAX|TARGET|VALUES|WRITER|ASSERT|BLOCKS|BOUNDS|BUFFER|CHANGE|COLUMN|COMMIT|CONCAT|COPIES|CREATE|DDMMYY|DEFINE|ENDIAN|ESCAPE|EXPAND|KERNEL|LAYOUT|LEGACY|LEVELS|MMDDYY|NUMBER|OUTPUT|RANGES|READER|RETURN|SCREEN|SEARCH|SELECT|SHARED|SOURCE|STABLE|STATIC|SUBKEY|SUFFIX|TABLES|UNWIND|YYMMDD|ASSIGN|BACKUP|BEFORE|BINARY|BIT-OR|BLANKS|CLIENT|CODING|COMMON|DEMAND|DYNPRO|EXCEPT|EXISTS|EXPORT|FIELDS|GLOBAL|GROUPS|LENGTH|LOCALE|MEDIUM|METHOD|MODIFY|NESTED|OTHERS|REJECT|SCROLL|SUPPLY|SYMBOL|ENDFOR|STRLEN|ALIGN|BEGIN|BOUND|ENDAT|ENTRY|EVENT|FINAL|FLUSH|GRANT|INNER|SHORT|USING|WRITE|AFTER|BLACK|BLOCK|CLOCK|COLOR|COUNT|DUMMY|EMPTY|ENDDO|ENDON|GREEN|INDEX|INOUT|LEAVE|LEVEL|LINES|MODIF|ORDER|OUTER|RANGE|RESET|RETRY|RIGHT|SMART|SPLIT|STYLE|TABLE|THROW|UNDER|UNTIL|UPPER|UTF-8|WHERE|ALIAS|BLANK|CLEAR|CLOSE|EXACT|FETCH|FIRST|FOUND|GROUP|LLANG|LOCAL|OTHER|REGEX|SPOOL|TITLE|TYPES|VALID|WHILE|ALPHA|BOXED|CATCH|CHAIN|CHECK|CLASS|COVER|ENDIF|EQUIV|FIELD|FLOOR|FRAME|INPUT|LOWER|MATCH|NODES|PAGES|PRINT|RAISE|ROUND|SHIFT|SPACE|SPOTS|STAMP|STATE|TASKS|TIMES|TRMAC|ULINE|UNION|VALUE|WIDTH|EQUAL|LOG10|TRUNC|BLOB|CASE|CEIL|CLOB|COND|EXIT|FILE|GAPS|HOLD|INCL|INTO|KEEP|KEYS|LAST|LINE|LONG|LPAD|MAIL|MODE|OPEN|PINK|READ|ROWS|TEST|THEN|ZERO|AREA|BACK|BADI|BYTE|CAST|EDIT|EXEC|FAIL|FIND|FKEQ|FONT|FREE|GKEQ|HIDE|INIT|ITNO|LATE|LOOP|MAIN|MARK|MOVE|NEXT|NULL|RISK|ROLE|UNIT|WAIT|ZONE|BASE|CALL|CODE|DATA|DATE|FKGE|GKGE|HIGH|KIND|LEFT|LIST|MASK|MESH|NAME|NODE|PACK|PAGE|POOL|SEND|SIGN|SIZE|SOME|STOP|TASK|TEXT|TIME|USER|VARY|WITH|WORD|BLUE|CONV|COPY|DEEP|ELSE|FORM|FROM|HINT|ICON|JOIN|LIKE|LOAD|ONLY|PART|SCAN|SKIP|SORT|TYPE|UNIX|VIEW|WHEN|WORK|ACOS|ASIN|ATAN|COSH|EACH|FRAC|LESS|RTTI|SINH|SQRT|TANH|AVG|BIT|DIV|ISO|LET|OUT|PAD|SQL|ALL|CI_|CPI|END|LOB|LPI|MAX|MIN|NEW|OLE|RUN|SET|\?TO|YES|ABS|ADD|AND|BIG|FOR|HDB|JOB|LOW|NOT|SAP|TRY|VIA|XML|ANY|GET|IDS|KEY|MOD|OFF|PUT|RAW|RED|REF|SUM|TAB|XSD|CNT|COS|EXP|LOG|SIN|TAN|XOR|AT|CO|CP|DO|GT|ID|IF|NS|OR|BT|CA|CS|GE|NA|NB|EQ|IN|LT|NE|NO|OF|ON|PF|TO|AS|BY|CN|IS|LE|NP|UP|E|I|M|O|Z|C|X)\b/i,lookbehind:!0},number:/\b\d+\b/,operator:{pattern:/(\s)(?:\*\*?|<[=>]?|>=?|\?=|[-+\/=])(?=\s)/,lookbehind:!0},"string-operator":{pattern:/(\s)&&?(?=\s)/,lookbehind:!0,alias:"keyword"},"token-operator":[{pattern:/(\w)(?:->?|=>|[~|{}])(?=\w)/,lookbehind:!0,alias:"punctuation"},{pattern:/[|{}]/,alias:"punctuation"}],punctuation:/[,.:()]/};
\ No newline at end of file
+Prism.languages.abap={comment:/^\*.*/m,string:/(`|')(?:\\.|(?!\1)[^\\\r\n])*\1/,"string-template":{pattern:/([|}])(?:\\.|[^\\|{\r\n])*(?=[|{])/,lookbehind:!0,alias:"string"},"eol-comment":{pattern:/(^|\s)".*/m,lookbehind:!0,alias:"comment"},keyword:{pattern:/(\s|\.|^)(?:\*-INPUT|\?TO|ABAP-SOURCE|ABBREVIATED|ABS|ABSTRACT|ACCEPT|ACCEPTING|ACCESSPOLICY|ACCORDING|ACOS|ACTIVATION|ACTUAL|ADD|ADD-CORRESPONDING|ADJACENT|AFTER|ALIAS|ALIASES|ALIGN|ALL|ALLOCATE|ALPHA|ANALYSIS|ANALYZER|AND|ANY|APPEND|APPENDAGE|APPENDING|APPLICATION|ARCHIVE|AREA|ARITHMETIC|AS|ASCENDING|ASIN|ASPECT|ASSERT|ASSIGN|ASSIGNED|ASSIGNING|ASSOCIATION|ASYNCHRONOUS|AT|ATAN|ATTRIBUTES|AUTHORITY|AUTHORITY-CHECK|AVG|BACK|BACKGROUND|BACKUP|BACKWARD|BADI|BASE|BEFORE|BEGIN|BETWEEN|BIG|BINARY|BINDING|BIT|BIT-AND|BIT-NOT|BIT-OR|BIT-XOR|BLACK|BLANK|BLANKS|BLOB|BLOCK|BLOCKS|BLUE|BOUND|BOUNDARIES|BOUNDS|BOXED|BREAK-POINT|BT|BUFFER|BY|BYPASSING|BYTE|BYTE-CA|BYTE-CN|BYTE-CO|BYTE-CS|BYTE-NA|BYTE-NS|BYTE-ORDER|C|CA|CALL|CALLING|CASE|CAST|CASTING|CATCH|CEIL|CENTER|CENTERED|CHAIN|CHAIN-INPUT|CHAIN-REQUEST|CHANGE|CHANGING|CHANNELS|CHAR-TO-HEX|CHARACTER|CHARLEN|CHECK|CHECKBOX|CIRCULAR|CI_|CLASS|CLASS-CODING|CLASS-DATA|CLASS-EVENTS|CLASS-METHODS|CLASS-POOL|CLEANUP|CLEAR|CLIENT|CLOB|CLOCK|CLOSE|CN|CNT|CO|COALESCE|CODE|CODING|COLLECT|COLOR|COLUMN|COLUMNS|COL_BACKGROUND|COL_GROUP|COL_HEADING|COL_KEY|COL_NEGATIVE|COL_NORMAL|COL_POSITIVE|COL_TOTAL|COMMENT|COMMENTS|COMMIT|COMMON|COMMUNICATION|COMPARING|COMPONENT|COMPONENTS|COMPRESSION|COMPUTE|CONCAT|CONCATENATE|COND|CONDENSE|CONDITION|CONNECT|CONNECTION|CONSTANTS|CONTEXT|CONTEXTS|CONTINUE|CONTROL|CONTROLS|CONV|CONVERSION|CONVERT|COPIES|COPY|CORRESPONDING|COS|COSH|COUNT|COUNTRY|COVER|CP|CPI|CREATE|CREATING|CRITICAL|CS|CURRENCY|CURRENCY_CONVERSION|CURRENT|CURSOR|CURSOR-SELECTION|CUSTOMER|CUSTOMER-FUNCTION|DANGEROUS|DATA|DATABASE|DATAINFO|DATASET|DATE|DAYLIGHT|DBMAXLEN|DD\/MM\/YY|DD\/MM\/YYYY|DDMMYY|DEALLOCATE|DECIMALS|DECIMAL_SHIFT|DECLARATIONS|DEEP|DEFAULT|DEFERRED|DEFINE|DEFINING|DEFINITION|DELETE|DELETING|DEMAND|DEPARTMENT|DESCENDING|DESCRIBE|DESTINATION|DETAIL|DIALOG|DIRECTORY|DISCONNECT|DISPLAY|DISPLAY-MODE|DISTANCE|DISTINCT|DIV|DIVIDE|DIVIDE-CORRESPONDING|DIVISION|DO|DUMMY|DUPLICATE|DUPLICATES|DURATION|DURING|DYNAMIC|DYNPRO|E|EACH|EDIT|EDITOR-CALL|ELSE|ELSEIF|EMPTY|ENABLED|ENABLING|ENCODING|END|END-ENHANCEMENT-SECTION|END-LINES|END-OF-DEFINITION|END-OF-FILE|END-OF-PAGE|END-OF-SELECTION|ENDAT|ENDCASE|ENDCATCH|ENDCHAIN|ENDCLASS|ENDDO|ENDENHANCEMENT|ENDEXEC|ENDFOR|ENDFORM|ENDFUNCTION|ENDIAN|ENDIF|ENDING|ENDINTERFACE|ENDLOOP|ENDMETHOD|ENDMODULE|ENDON|ENDPROVIDE|ENDSELECT|ENDTRY|ENDWHILE|ENGINEERING|ENHANCEMENT|ENHANCEMENT-POINT|ENHANCEMENT-SECTION|ENHANCEMENTS|ENTRIES|ENTRY|ENVIRONMENT|EQ|EQUAL|EQUIV|ERRORMESSAGE|ERRORS|ESCAPE|ESCAPING|EVENT|EVENTS|EXACT|EXCEPT|EXCEPTION|EXCEPTION-TABLE|EXCEPTIONS|EXCLUDE|EXCLUDING|EXEC|EXECUTE|EXISTS|EXIT|EXIT-COMMAND|EXP|EXPAND|EXPANDING|EXPIRATION|EXPLICIT|EXPONENT|EXPORT|EXPORTING|EXTEND|EXTENDED|EXTENSION|EXTRACT|FAIL|FETCH|FIELD|FIELD-GROUPS|FIELD-SYMBOL|FIELD-SYMBOLS|FIELDS|FILE|FILTER|FILTER-TABLE|FILTERS|FINAL|FIND|FIRST|FIRST-LINE|FIXED-POINT|FKEQ|FKGE|FLOOR|FLUSH|FONT|FOR|FORM|FORMAT|FORWARD|FOUND|FRAC|FRAME|FRAMES|FREE|FRIENDS|FROM|FUNCTION|FUNCTION-POOL|FUNCTIONALITY|FURTHER|GAPS|GE|GENERATE|GET|GIVING|GKEQ|GKGE|GLOBAL|GRANT|GREATER|GREEN|GROUP|GROUPS|GT|HANDLE|HANDLER|HARMLESS|HASHED|HAVING|HDB|HEAD-LINES|HEADER|HEADERS|HEADING|HELP-ID|HELP-REQUEST|HIDE|HIGH|HINT|HOLD|HOTSPOT|I|ICON|ID|IDENTIFICATION|IDENTIFIER|IDS|IF|IGNORE|IGNORING|IMMEDIATELY|IMPLEMENTATION|IMPLEMENTATIONS|IMPLEMENTED|IMPLICIT|IMPORT|IMPORTING|IN|INACTIVE|INCL|INCLUDE|INCLUDES|INCLUDING|INCREMENT|INDEX|INDEX-LINE|INFOTYPES|INHERITING|INIT|INITIAL|INITIALIZATION|INNER|INOUT|INPUT|INSERT|INSTANCES|INTENSIFIED|INTERFACE|INTERFACE-POOL|INTERFACES|INTERNAL|INTERVALS|INTO|INVERSE|INVERTED-DATE|IS|ISO|ITERATOR|ITNO|JOB|JOIN|KEEP|KEEPING|KERNEL|KEY|KEYS|KEYWORDS|KIND|LANGUAGE|LAST|LATE|LAYOUT|LE|LEADING|LEAVE|LEFT|LEFT-JUSTIFIED|LEFTPLUS|LEFTSPACE|LEGACY|LENGTH|LESS|LET|LEVEL|LEVELS|LIKE|LINE|LINE-COUNT|LINE-SELECTION|LINE-SIZE|LINEFEED|LINES|LIST|LIST-PROCESSING|LISTBOX|LITTLE|LLANG|LOAD|LOAD-OF-PROGRAM|LOB|LOCAL|LOCALE|LOCATOR|LOG|LOG-POINT|LOG10|LOGFILE|LOGICAL|LONG|LOOP|LOW|LOWER|LPAD|LPI|LT|M|MAIL|MAIN|MAJOR-ID|MAPPING|MARGIN|MARK|MASK|MATCH|MATCHCODE|MAX|MAXIMUM|MEDIUM|MEMBERS|MEMORY|MESH|MESSAGE|MESSAGE-ID|MESSAGES|MESSAGING|METHOD|METHODS|MIN|MINIMUM|MINOR-ID|MM\/DD\/YY|MM\/DD\/YYYY|MMDDYY|MOD|MODE|MODIF|MODIFIER|MODIFY|MODULE|MOVE|MOVE-CORRESPONDING|MULTIPLY|MULTIPLY-CORRESPONDING|NA|NAME|NAMETAB|NATIVE|NB|NE|NESTED|NESTING|NEW|NEW-LINE|NEW-PAGE|NEW-SECTION|NEXT|NO|NO-DISPLAY|NO-EXTENSION|NO-GAP|NO-GAPS|NO-GROUPING|NO-HEADING|NO-SCROLLING|NO-SIGN|NO-TITLE|NO-TOPOFPAGE|NO-ZERO|NODE|NODES|NON-UNICODE|NON-UNIQUE|NOT|NP|NS|NULL|NUMBER|NUMOFCHAR|O|OBJECT|OBJECTS|OBLIGATORY|OCCURRENCE|OCCURRENCES|OCCURS|OF|OFF|OFFSET|OLE|ON|ONLY|OPEN|OPTION|OPTIONAL|OPTIONS|OR|ORDER|OTHER|OTHERS|OUT|OUTER|OUTPUT|OUTPUT-LENGTH|OVERFLOW|OVERLAY|PACK|PACKAGE|PAD|PADDING|PAGE|PAGES|PARAMETER|PARAMETER-TABLE|PARAMETERS|PART|PARTIALLY|PATTERN|PERCENTAGE|PERFORM|PERFORMING|PERSON|PF|PF-STATUS|PINK|PLACES|POOL|POSITION|POS_HIGH|POS_LOW|PRAGMAS|PRECOMPILED|PREFERRED|PRESERVING|PRIMARY|PRINT|PRINT-CONTROL|PRIORITY|PRIVATE|PROCEDURE|PROCESS|PROGRAM|PROPERTY|PROTECTED|PROVIDE|PUBLIC|PUSHBUTTON|PUT|QUEUE-ONLY|QUICKINFO|RADIOBUTTON|RAISE|RAISING|RANGE|RANGES|RAW|READ|READ-ONLY|READER|RECEIVE|RECEIVED|RECEIVER|RECEIVING|RED|REDEFINITION|REDUCE|REDUCED|REF|REFERENCE|REFRESH|REGEX|REJECT|REMOTE|RENAMING|REPLACE|REPLACEMENT|REPLACING|REPORT|REQUEST|REQUESTED|RESERVE|RESET|RESOLUTION|RESPECTING|RESPONSIBLE|RESULT|RESULTS|RESUMABLE|RESUME|RETRY|RETURN|RETURNCODE|RETURNING|RIGHT|RIGHT-JUSTIFIED|RIGHTPLUS|RIGHTSPACE|RISK|RMC_COMMUNICATION_FAILURE|RMC_INVALID_STATUS|RMC_SYSTEM_FAILURE|ROLE|ROLLBACK|ROUND|ROWS|RTTI|RUN|SAP|SAP-SPOOL|SAVING|SCALE_PRESERVING|SCALE_PRESERVING_SCIENTIFIC|SCAN|SCIENTIFIC|SCIENTIFIC_WITH_LEADING_ZERO|SCREEN|SCROLL|SCROLL-BOUNDARY|SCROLLING|SEARCH|SECONDARY|SECONDS|SECTION|SELECT|SELECT-OPTIONS|SELECTION|SELECTION-SCREEN|SELECTION-SET|SELECTION-SETS|SELECTION-TABLE|SELECTIONS|SELECTOR|SEND|SEPARATE|SEPARATED|SET|SHARED|SHIFT|SHORT|SHORTDUMP-ID|SIGN|SIGN_AS_POSTFIX|SIMPLE|SIN|SINGLE|SINH|SIZE|SKIP|SKIPPING|SMART|SOME|SORT|SORTABLE|SORTED|SOURCE|SPACE|SPECIFIED|SPLIT|SPOOL|SPOTS|SQL|SQLSCRIPT|SQRT|STABLE|STAMP|STANDARD|START-OF-SELECTION|STARTING|STATE|STATEMENT|STATEMENTS|STATIC|STATICS|STATUSINFO|STEP-LOOP|STOP|STRLEN|STRUCTURE|STRUCTURES|STYLE|SUBKEY|SUBMATCHES|SUBMIT|SUBROUTINE|SUBSCREEN|SUBSTRING|SUBTRACT|SUBTRACT-CORRESPONDING|SUFFIX|SUM|SUMMARY|SUMMING|SUPPLIED|SUPPLY|SUPPRESS|SWITCH|SWITCHSTATES|SYMBOL|SYNCPOINTS|SYNTAX|SYNTAX-CHECK|SYNTAX-TRACE|SYSTEM-CALL|SYSTEM-EXCEPTIONS|SYSTEM-EXIT|TAB|TABBED|TABLE|TABLES|TABLEVIEW|TABSTRIP|TAN|TANH|TARGET|TASK|TASKS|TEST|TESTING|TEXT|TEXTPOOL|THEN|THROW|TIME|TIMES|TIMESTAMP|TIMEZONE|TITLE|TITLE-LINES|TITLEBAR|TO|TOKENIZATION|TOKENS|TOP-LINES|TOP-OF-PAGE|TRACE-FILE|TRACE-TABLE|TRAILING|TRANSACTION|TRANSFER|TRANSFORMATION|TRANSLATE|TRANSPORTING|TRMAC|TRUNC|TRUNCATE|TRUNCATION|TRY|TYPE|TYPE-POOL|TYPE-POOLS|TYPES|ULINE|UNASSIGN|UNDER|UNICODE|UNION|UNIQUE|UNIT|UNIT_CONVERSION|UNIX|UNPACK|UNTIL|UNWIND|UP|UPDATE|UPPER|USER|USER-COMMAND|USING|UTF-8|VALID|VALUE|VALUE-REQUEST|VALUES|VARY|VARYING|VERIFICATION-MESSAGE|VERSION|VIA|VIEW|VISIBLE|WAIT|WARNING|WHEN|WHENEVER|WHERE|WHILE|WIDTH|WINDOW|WINDOWS|WITH|WITH-HEADING|WITH-TITLE|WITHOUT|WORD|WORK|WRITE|WRITER|X|XML|XOR|XSD|XSTRLEN|YELLOW|YES|YYMMDD|Z|ZERO|ZONE)(?![\w-])/i,lookbehind:!0},number:/\b\d+\b/,operator:{pattern:/(\s)(?:\*\*?|<[=>]?|>=?|\?=|[-+\/=])(?=\s)/,lookbehind:!0},"string-operator":{pattern:/(\s)&&?(?=\s)/,lookbehind:!0,alias:"keyword"},"token-operator":[{pattern:/(\w)(?:->?|=>|[~|{}])(?=\w)/,lookbehind:!0,alias:"punctuation"},{pattern:/[|{}]/,alias:"punctuation"}],punctuation:/[,.:()]/};
\ No newline at end of file
diff --git a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-abnf.min.js b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-abnf.min.js
index bc021e1f49..a57731024c 100644
--- a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-abnf.min.js
+++ b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-abnf.min.js
@@ -1 +1 @@
-!function(n){var i="(?:ALPHA|BIT|CHAR|CR|CRLF|CTL|DIGIT|DQUOTE|HEXDIG|HTAB|LF|LWSP|OCTET|SP|VCHAR|WSP)";Prism.languages.abnf={comment:/;.*/,string:{pattern:/(?:%[is])?"[^"\n\r]*"/,greedy:!0,inside:{punctuation:/^%[is]/}},range:{pattern:/%(?:b[01]+-[01]+|d\d+-\d+|x[A-F\d]+-[A-F\d]+)/i,alias:"number"},terminal:{pattern:/%(?:b[01]+(?:\.[01]+)*|d\d+(?:\.\d+)*|x[A-F\d]+(?:\.[A-F\d]+)*)/i,alias:"number"},repetition:{pattern:/(^|[^\w-])(?:\d*\*\d*|\d+)/,lookbehind:!0,alias:"operator"},definition:{pattern:/(^[ \t]*)(?:[a-z][\w-]*|<[^<>\r\n]*>)(?=\s*=)/m,lookbehind:!0,alias:"keyword",inside:{punctuation:/<|>/}},"core-rule":{pattern:RegExp("(?:(^|[^<\\w-])"+i+"|<"+i+">)(?![\\w-])","i"),lookbehind:!0,alias:["rule","constant"],inside:{punctuation:/<|>/}},rule:{pattern:/(^|[^<\w-])[a-z][\w-]*|<[^<>\r\n]*>/i,lookbehind:!0,inside:{punctuation:/<|>/}},operator:/=\/?|\//,punctuation:/[()\[\]]/}}();
\ No newline at end of file
+!function(n){var i="(?:ALPHA|BIT|CHAR|CR|CRLF|CTL|DIGIT|DQUOTE|HEXDIG|HTAB|LF|LWSP|OCTET|SP|VCHAR|WSP)";n.languages.abnf={comment:/;.*/,string:{pattern:/(?:%[is])?"[^"\n\r]*"/,greedy:!0,inside:{punctuation:/^%[is]/}},range:{pattern:/%(?:b[01]+-[01]+|d\d+-\d+|x[A-F\d]+-[A-F\d]+)/i,alias:"number"},terminal:{pattern:/%(?:b[01]+(?:\.[01]+)*|d\d+(?:\.\d+)*|x[A-F\d]+(?:\.[A-F\d]+)*)/i,alias:"number"},repetition:{pattern:/(^|[^\w-])(?:\d*\*\d*|\d+)/,lookbehind:!0,alias:"operator"},definition:{pattern:/(^[ \t]*)(?:[a-z][\w-]*|<[^<>\r\n]*>)(?=\s*=)/m,lookbehind:!0,alias:"keyword",inside:{punctuation:/<|>/}},"core-rule":{pattern:RegExp("(?:(^|[^<\\w-])"+i+"|<"+i+">)(?![\\w-])","i"),lookbehind:!0,alias:["rule","constant"],inside:{punctuation:/<|>/}},rule:{pattern:/(^|[^<\w-])[a-z][\w-]*|<[^<>\r\n]*>/i,lookbehind:!0,inside:{punctuation:/<|>/}},operator:/=\/?|\//,punctuation:/[()\[\]]/}}(Prism);
\ No newline at end of file
diff --git a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-ada.js b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-ada.js
index 21226f63a2..a537f39b0a 100644
--- a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-ada.js
+++ b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-ada.js
@@ -9,8 +9,11 @@ Prism.languages.ada = {
pattern: /\b\d(?:_?\d)*(?:\.\d(?:_?\d)*)?(?:E[+-]?\d(?:_?\d)*)?\b/i
}
],
- 'attr-name': /\b'\w+/,
- 'keyword': /\b(?:abort|abs|abstract|accept|access|aliased|all|and|array|at|begin|body|case|constant|declare|delay|delta|digits|do|else|elsif|end|entry|exception|exit|for|function|generic|goto|if|in|interface|is|limited|loop|mod|new|not|null|of|others|out|overriding|package|pragma|private|procedure|protected|raise|range|record|rem|renames|requeue|return|reverse|select|separate|some|subtype|synchronized|tagged|task|terminate|then|type|until|use|when|while|with|xor)\b/i,
+ 'attribute': {
+ pattern: /\b'\w+/,
+ alias: 'attr-name'
+ },
+ 'keyword': /\b(?:abort|abs|abstract|accept|access|aliased|all|and|array|at|begin|body|case|constant|declare|delay|delta|digits|do|else|elsif|end|entry|exception|exit|for|function|generic|goto|if|in|interface|is|limited|loop|mod|new|not|null|of|or|others|out|overriding|package|pragma|private|procedure|protected|raise|range|record|rem|renames|requeue|return|reverse|select|separate|some|subtype|synchronized|tagged|task|terminate|then|type|until|use|when|while|with|xor)\b/i,
'boolean': /\b(?:false|true)\b/i,
'operator': /<[=>]?|>=?|=>?|:=|\/=?|\*\*?|[&+-]/,
'punctuation': /\.\.?|[,;():]/,
diff --git a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-ada.min.js b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-ada.min.js
index f58b0ea9f3..57de170363 100644
--- a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-ada.min.js
+++ b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-ada.min.js
@@ -1 +1 @@
-Prism.languages.ada={comment:/--.*/,string:/"(?:""|[^"\r\f\n])*"/,number:[{pattern:/\b\d(?:_?\d)*#[\dA-F](?:_?[\dA-F])*(?:\.[\dA-F](?:_?[\dA-F])*)?#(?:E[+-]?\d(?:_?\d)*)?/i},{pattern:/\b\d(?:_?\d)*(?:\.\d(?:_?\d)*)?(?:E[+-]?\d(?:_?\d)*)?\b/i}],"attr-name":/\b'\w+/,keyword:/\b(?:abort|abs|abstract|accept|access|aliased|all|and|array|at|begin|body|case|constant|declare|delay|delta|digits|do|else|elsif|end|entry|exception|exit|for|function|generic|goto|if|in|interface|is|limited|loop|mod|new|not|null|of|others|out|overriding|package|pragma|private|procedure|protected|raise|range|record|rem|renames|requeue|return|reverse|select|separate|some|subtype|synchronized|tagged|task|terminate|then|type|until|use|when|while|with|xor)\b/i,boolean:/\b(?:false|true)\b/i,operator:/<[=>]?|>=?|=>?|:=|\/=?|\*\*?|[&+-]/,punctuation:/\.\.?|[,;():]/,char:/'.'/,variable:/\b[a-z](?:\w)*\b/i};
\ No newline at end of file
+Prism.languages.ada={comment:/--.*/,string:/"(?:""|[^"\r\f\n])*"/,number:[{pattern:/\b\d(?:_?\d)*#[\dA-F](?:_?[\dA-F])*(?:\.[\dA-F](?:_?[\dA-F])*)?#(?:E[+-]?\d(?:_?\d)*)?/i},{pattern:/\b\d(?:_?\d)*(?:\.\d(?:_?\d)*)?(?:E[+-]?\d(?:_?\d)*)?\b/i}],attribute:{pattern:/\b'\w+/,alias:"attr-name"},keyword:/\b(?:abort|abs|abstract|accept|access|aliased|all|and|array|at|begin|body|case|constant|declare|delay|delta|digits|do|else|elsif|end|entry|exception|exit|for|function|generic|goto|if|in|interface|is|limited|loop|mod|new|not|null|of|or|others|out|overriding|package|pragma|private|procedure|protected|raise|range|record|rem|renames|requeue|return|reverse|select|separate|some|subtype|synchronized|tagged|task|terminate|then|type|until|use|when|while|with|xor)\b/i,boolean:/\b(?:false|true)\b/i,operator:/<[=>]?|>=?|=>?|:=|\/=?|\*\*?|[&+-]/,punctuation:/\.\.?|[,;():]/,char:/'.'/,variable:/\b[a-z](?:\w)*\b/i};
\ No newline at end of file
diff --git a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-agda.min.js b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-agda.min.js
index a31d259c3a..62f8d1ca23 100644
--- a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-agda.min.js
+++ b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-agda.min.js
@@ -1 +1 @@
-Prism.languages.agda={comment:/\{-[\s\S]*?(?:-\}|$)|--.*/,string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^\\\r\n"])*"/,greedy:!0},punctuation:/[(){}⦃⦄.;@]/,"class-name":{pattern:/((?:data|record) +)\S+/,lookbehind:!0},function:{pattern:/(^[ \t]*)(?!\s)[^:\r\n]+(?=:)/m,lookbehind:!0},operator:{pattern:/(^\s*|\s)(?:[=|:∀→λ\\?_]|->)(?=\s)/,lookbehind:!0},keyword:/\b(?:Set|abstract|constructor|data|eta-equality|field|forall|hiding|import|in|inductive|infix|infixl|infixr|instance|let|macro|module|mutual|no-eta-equality|open|overlap|pattern|postulate|primitive|private|public|quote|quoteContext|quoteGoal|quoteTerm|record|renaming|rewrite|syntax|tactic|unquote|unquoteDecl|unquoteDef|using|variable|where|with)\b/};
\ No newline at end of file
+!function(t){t.languages.agda={comment:/\{-[\s\S]*?(?:-\}|$)|--.*/,string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^\\\r\n"])*"/,greedy:!0},punctuation:/[(){}⦃⦄.;@]/,"class-name":{pattern:/((?:data|record) +)\S+/,lookbehind:!0},function:{pattern:/(^[ \t]*)(?!\s)[^:\r\n]+(?=:)/m,lookbehind:!0},operator:{pattern:/(^\s*|\s)(?:[=|:∀→λ\\?_]|->)(?=\s)/,lookbehind:!0},keyword:/\b(?:Set|abstract|constructor|data|eta-equality|field|forall|hiding|import|in|inductive|infix|infixl|infixr|instance|let|macro|module|mutual|no-eta-equality|open|overlap|pattern|postulate|primitive|private|public|quote|quoteContext|quoteGoal|quoteTerm|record|renaming|rewrite|syntax|tactic|unquote|unquoteDecl|unquoteDef|using|variable|where|with)\b/}}(Prism);
\ No newline at end of file
diff --git a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-apex.min.js b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-apex.min.js
index ba2cdfabea..3cb0f96bec 100644
--- a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-apex.min.js
+++ b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-apex.min.js
@@ -1 +1 @@
-!function(e){var t=/\b(?:(?:after|before)(?=\s+[a-z])|abstract|activate|and|any|array|as|asc|autonomous|begin|bigdecimal|blob|boolean|break|bulk|by|byte|case|cast|catch|char|class|collect|commit|const|continue|currency|date|datetime|decimal|default|delete|desc|do|double|else|end|enum|exception|exit|export|extends|final|finally|float|for|from|get(?=\s*[{};])|global|goto|group|having|hint|if|implements|import|in|inner|insert|instanceof|int|integer|interface|into|join|like|limit|list|long|loop|map|merge|new|not|null|nulls|number|object|of|on|or|outer|override|package|parallel|pragma|private|protected|public|retrieve|return|rollback|select|set|short|sObject|sort|static|string|super|switch|synchronized|system|testmethod|then|this|throw|time|transaction|transient|trigger|try|undelete|update|upsert|using|virtual|void|webservice|when|where|while|(?:inherited|with|without)\s+sharing)\b/i,n="\\b(?:(?=[a-z_]\\w*\\s*[<\\[])|(?!))[A-Z_]\\w*(?:\\s*\\.\\s*[A-Z_]\\w*)*\\b(?:\\s*(?:\\[\\s*\\]|<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>))*".replace(//g,function(){return t.source});function i(e){return RegExp(e.replace(//g,function(){return n}),"i")}var a={keyword:t,punctuation:/[()\[\]{};,:.<>]/};e.languages.apex={comment:e.languages.clike.comment,string:e.languages.clike.string,sql:{pattern:/((?:[=,({:]|\breturn)\s*)\[[^\[\]]*\]/i,lookbehind:!0,greedy:!0,alias:"language-sql",inside:e.languages.sql},annotation:{pattern:/@\w+\b/,alias:"punctuation"},"class-name":[{pattern:i("(\\b(?:class|enum|extends|implements|instanceof|interface|new|trigger\\s+\\w+\\s+on)\\s+)"),lookbehind:!0,inside:a},{pattern:i("(\\(\\s*)(?=\\s*\\)\\s*[\\w(])"),lookbehind:!0,inside:a},{pattern:i("(?=\\s*\\w+\\s*[;=,(){:])"),inside:a}],trigger:{pattern:/(\btrigger\s+)\w+\b/i,lookbehind:!0,alias:"class-name"},keyword:t,function:/\b[a-z_]\w*(?=\s*\()/i,boolean:/\b(?:false|true)\b/i,number:/(?:\B\.\d+|\b\d+(?:\.\d+|L)?)\b/i,operator:/[!=](?:==?)?|\?\.?|&&|\|\||--|\+\+|[-+*/^&|]=?|:|<=?|>{1,3}=?/,punctuation:/[()\[\]{};,.]/}}(Prism);
\ No newline at end of file
+!function(e){var t=/\b(?:(?:after|before)(?=\s+[a-z])|abstract|activate|and|any|array|as|asc|autonomous|begin|bigdecimal|blob|boolean|break|bulk|by|byte|case|cast|catch|char|class|collect|commit|const|continue|currency|date|datetime|decimal|default|delete|desc|do|double|else|end|enum|exception|exit|export|extends|final|finally|float|for|from|get(?=\s*[{};])|global|goto|group|having|hint|if|implements|import|in|inner|insert|instanceof|int|integer|interface|into|join|like|limit|list|long|loop|map|merge|new|not|null|nulls|number|object|of|on|or|outer|override|package|parallel|pragma|private|protected|public|retrieve|return|rollback|select|set|short|sObject|sort|static|string|super|switch|synchronized|system|testmethod|then|this|throw|time|transaction|transient|trigger|try|undelete|update|upsert|using|virtual|void|webservice|when|where|while|(?:inherited|with|without)\s+sharing)\b/i,n="\\b(?:(?=[a-z_]\\w*\\s*[<\\[])|(?!))[A-Z_]\\w*(?:\\s*\\.\\s*[A-Z_]\\w*)*\\b(?:\\s*(?:\\[\\s*\\]|<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>))*".replace(//g,(function(){return t.source}));function i(e){return RegExp(e.replace(//g,(function(){return n})),"i")}var a={keyword:t,punctuation:/[()\[\]{};,:.<>]/};e.languages.apex={comment:e.languages.clike.comment,string:e.languages.clike.string,sql:{pattern:/((?:[=,({:]|\breturn)\s*)\[[^\[\]]*\]/i,lookbehind:!0,greedy:!0,alias:"language-sql",inside:e.languages.sql},annotation:{pattern:/@\w+\b/,alias:"punctuation"},"class-name":[{pattern:i("(\\b(?:class|enum|extends|implements|instanceof|interface|new|trigger\\s+\\w+\\s+on)\\s+)"),lookbehind:!0,inside:a},{pattern:i("(\\(\\s*)(?=\\s*\\)\\s*[\\w(])"),lookbehind:!0,inside:a},{pattern:i("(?=\\s*\\w+\\s*[;=,(){:])"),inside:a}],trigger:{pattern:/(\btrigger\s+)\w+\b/i,lookbehind:!0,alias:"class-name"},keyword:t,function:/\b[a-z_]\w*(?=\s*\()/i,boolean:/\b(?:false|true)\b/i,number:/(?:\B\.\d+|\b\d+(?:\.\d+|L)?)\b/i,operator:/[!=](?:==?)?|\?\.?|&&|\|\||--|\+\+|[-+*/^&|]=?|:|<=?|>{1,3}=?/,punctuation:/[()\[\]{};,.]/}}(Prism);
\ No newline at end of file
diff --git a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-armasm.js b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-armasm.js
new file mode 100644
index 0000000000..07e93221d4
--- /dev/null
+++ b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-armasm.js
@@ -0,0 +1,49 @@
+Prism.languages.armasm = {
+ 'comment': {
+ pattern: /;.*/,
+ greedy: true
+ },
+ 'string': {
+ pattern: /"(?:[^"\r\n]|"")*"/,
+ greedy: true,
+ inside: {
+ 'variable': {
+ pattern: /((?:^|[^$])(?:\${2})*)\$\w+/,
+ lookbehind: true
+ }
+ }
+ },
+ 'char': {
+ pattern: /'(?:[^'\r\n]{0,4}|'')'/,
+ greedy: true
+ },
+ 'version-symbol': {
+ pattern: /\|[\w@]+\|/,
+ greedy: true,
+ alias: 'property'
+ },
+
+ 'boolean': /\b(?:FALSE|TRUE)\b/,
+ 'directive': {
+ pattern: /\b(?:ALIAS|ALIGN|AREA|ARM|ASSERT|ATTR|CN|CODE|CODE16|CODE32|COMMON|CP|DATA|DCB|DCD|DCDO|DCDU|DCFD|DCFDU|DCI|DCQ|DCQU|DCW|DCWU|DN|ELIF|ELSE|END|ENDFUNC|ENDIF|ENDP|ENTRY|EQU|EXPORT|EXPORTAS|EXTERN|FIELD|FILL|FN|FUNCTION|GBLA|GBLL|GBLS|GET|GLOBAL|IF|IMPORT|INCBIN|INCLUDE|INFO|KEEP|LCLA|LCLL|LCLS|LTORG|MACRO|MAP|MEND|MEXIT|NOFP|OPT|PRESERVE8|PROC|QN|READONLY|RELOC|REQUIRE|REQUIRE8|RLIST|ROUT|SETA|SETL|SETS|SN|SPACE|SUBT|THUMB|THUMBX|TTL|WEND|WHILE)\b/,
+ alias: 'property'
+ },
+ 'instruction': {
+ pattern: /((?:^|(?:^|[^\\])(?:\r\n?|\n))[ \t]*(?:(?:[A-Z][A-Z0-9_]*[a-z]\w*|[a-z]\w*|\d+)[ \t]+)?)\b[A-Z.]+\b/,
+ lookbehind: true,
+ alias: 'keyword'
+ },
+ 'variable': /\$\w+/,
+
+ 'number': /(?:\b[2-9]_\d+|(?:\b\d+(?:\.\d+)?|\B\.\d+)(?:e-?\d+)?|\b0(?:[fd]_|x)[0-9a-f]+|&[0-9a-f]+)\b/i,
+
+ 'register': {
+ pattern: /\b(?:r\d|lr)\b/,
+ alias: 'symbol'
+ },
+
+ 'operator': /<>|<<|>>|&&|\|\||[=!<>/]=?|[+\-*%#?&|^]|:[A-Z]+:/,
+ 'punctuation': /[()[\],]/
+};
+
+Prism.languages['arm-asm'] = Prism.languages.armasm;
diff --git a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-armasm.min.js b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-armasm.min.js
new file mode 100644
index 0000000000..620549bd32
--- /dev/null
+++ b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-armasm.min.js
@@ -0,0 +1 @@
+Prism.languages.armasm={comment:{pattern:/;.*/,greedy:!0},string:{pattern:/"(?:[^"\r\n]|"")*"/,greedy:!0,inside:{variable:{pattern:/((?:^|[^$])(?:\${2})*)\$\w+/,lookbehind:!0}}},char:{pattern:/'(?:[^'\r\n]{0,4}|'')'/,greedy:!0},"version-symbol":{pattern:/\|[\w@]+\|/,greedy:!0,alias:"property"},boolean:/\b(?:FALSE|TRUE)\b/,directive:{pattern:/\b(?:ALIAS|ALIGN|AREA|ARM|ASSERT|ATTR|CN|CODE|CODE16|CODE32|COMMON|CP|DATA|DCB|DCD|DCDO|DCDU|DCFD|DCFDU|DCI|DCQ|DCQU|DCW|DCWU|DN|ELIF|ELSE|END|ENDFUNC|ENDIF|ENDP|ENTRY|EQU|EXPORT|EXPORTAS|EXTERN|FIELD|FILL|FN|FUNCTION|GBLA|GBLL|GBLS|GET|GLOBAL|IF|IMPORT|INCBIN|INCLUDE|INFO|KEEP|LCLA|LCLL|LCLS|LTORG|MACRO|MAP|MEND|MEXIT|NOFP|OPT|PRESERVE8|PROC|QN|READONLY|RELOC|REQUIRE|REQUIRE8|RLIST|ROUT|SETA|SETL|SETS|SN|SPACE|SUBT|THUMB|THUMBX|TTL|WEND|WHILE)\b/,alias:"property"},instruction:{pattern:/((?:^|(?:^|[^\\])(?:\r\n?|\n))[ \t]*(?:(?:[A-Z][A-Z0-9_]*[a-z]\w*|[a-z]\w*|\d+)[ \t]+)?)\b[A-Z.]+\b/,lookbehind:!0,alias:"keyword"},variable:/\$\w+/,number:/(?:\b[2-9]_\d+|(?:\b\d+(?:\.\d+)?|\B\.\d+)(?:e-?\d+)?|\b0(?:[fd]_|x)[0-9a-f]+|&[0-9a-f]+)\b/i,register:{pattern:/\b(?:r\d|lr)\b/,alias:"symbol"},operator:/<>|<<|>>|&&|\|\||[=!<>/]=?|[+\-*%#?&|^]|:[A-Z]+:/,punctuation:/[()[\],]/},Prism.languages["arm-asm"]=Prism.languages.armasm;
\ No newline at end of file
diff --git a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-arturo.js b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-arturo.js
new file mode 100644
index 0000000000..d09b5e27ef
--- /dev/null
+++ b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-arturo.js
@@ -0,0 +1,105 @@
+(function (Prism) {
+ /**
+ * @param {string} lang
+ * @param {string} pattern
+ */
+ var createLanguageString = function (lang, pattern) {
+ return {
+ pattern: RegExp(/\{!/.source + '(?:' + (pattern || lang) + ')' + /$[\s\S]*\}/.source, 'm'),
+ greedy: true,
+ inside: {
+ 'embedded': {
+ pattern: /(^\{!\w+\b)[\s\S]+(?=\}$)/,
+ lookbehind: true,
+ alias: 'language-' + lang,
+ inside: Prism.languages[lang]
+ },
+ 'string': /[\s\S]+/
+ }
+ };
+ };
+
+ Prism.languages.arturo = {
+ 'comment': {
+ pattern: /;.*/,
+ greedy: true
+ },
+
+ 'character': {
+ pattern: /`.`/,
+ alias: 'char',
+ greedy: true
+ },
+
+ 'number': {
+ pattern: /\b\d+(?:\.\d+(?:\.\d+(?:-[\w+-]+)?)?)?\b/,
+ },
+
+ 'string': {
+ pattern: /"(?:[^"\\\r\n]|\\.)*"/,
+ greedy: true
+ },
+
+ 'regex': {
+ pattern: /\{\/.*?\/\}/,
+ greedy: true
+ },
+
+ 'html-string': createLanguageString('html'),
+ 'css-string': createLanguageString('css'),
+ 'js-string': createLanguageString('js'),
+ 'md-string': createLanguageString('md'),
+ 'sql-string': createLanguageString('sql'),
+ 'sh-string': createLanguageString('shell', 'sh'),
+
+ 'multistring': {
+ pattern: /».*|\{:[\s\S]*?:\}|\{[\s\S]*?\}|^-{6}$[\s\S]*/m,
+ alias: 'string',
+ greedy: true
+ },
+
+ 'label': {
+ pattern: /\w+\b\??:/,
+ alias: 'property'
+ },
+
+ 'literal': {
+ pattern: /'(?:\w+\b\??:?)/,
+ alias: 'constant'
+ },
+
+ 'type': {
+ pattern: /:(?:\w+\b\??:?)/,
+ alias: 'class-name'
+ },
+
+ 'color': /#\w+/,
+
+ 'predicate': {
+ pattern: /\b(?:all|and|any|ascii|attr|attribute|attributeLabel|binary|block|char|contains|database|date|dictionary|empty|equal|even|every|exists|false|floating|function|greater|greaterOrEqual|if|in|inline|integer|is|key|label|leap|less|lessOrEqual|literal|logical|lower|nand|negative|nor|not|notEqual|null|numeric|odd|or|path|pathLabel|positive|prefix|prime|regex|same|set|some|sorted|standalone|string|subset|suffix|superset|symbol|symbolLiteral|true|try|type|unless|upper|when|whitespace|word|xnor|xor|zero)\?/,
+ alias: 'keyword'
+ },
+
+ 'builtin-function': {
+ pattern: /\b(?:abs|acos|acosh|acsec|acsech|actan|actanh|add|after|alert|alias|and|angle|append|arg|args|arity|array|as|asec|asech|asin|asinh|atan|atan2|atanh|attr|attrs|average|before|benchmark|blend|break|call|capitalize|case|ceil|chop|clear|clip|close|color|combine|conj|continue|copy|cos|cosh|crc|csec|csech|ctan|ctanh|cursor|darken|dec|decode|define|delete|desaturate|deviation|dialog|dictionary|difference|digest|digits|div|do|download|drop|dup|e|else|empty|encode|ensure|env|escape|execute|exit|exp|extend|extract|factors|fdiv|filter|first|flatten|floor|fold|from|function|gamma|gcd|get|goto|hash|hypot|if|inc|indent|index|infinity|info|input|insert|inspect|intersection|invert|jaro|join|keys|kurtosis|last|let|levenshtein|lighten|list|ln|log|loop|lower|mail|map|match|max|median|min|mod|module|mul|nand|neg|new|nor|normalize|not|now|null|open|or|outdent|pad|palette|panic|path|pause|permissions|permutate|pi|pop|popup|pow|powerset|powmod|prefix|print|prints|process|product|query|random|range|read|relative|remove|rename|render|repeat|replace|request|return|reverse|round|sample|saturate|script|sec|sech|select|serve|set|shl|shr|shuffle|sin|sinh|size|skewness|slice|sort|spin|split|sqrt|squeeze|stack|strip|sub|suffix|sum|switch|symbols|symlink|sys|take|tan|tanh|terminal|terminate|to|truncate|try|type|unclip|union|unique|unless|until|unzip|upper|values|var|variance|volume|webview|while|with|wordwrap|write|xnor|xor|zip)\b/,
+ alias: 'keyword'
+ },
+
+ 'sugar': {
+ pattern: /->|=>|\||::/,
+ alias: 'operator'
+ },
+
+ 'punctuation': /[()[\],]/,
+
+ 'symbol': {
+ pattern: /<:|-:|ø|@|#|\+|\||\*|\$|---|-|%|\/|\.\.|\^|~|=|<|>|\\/
+ },
+
+ 'boolean': {
+ pattern: /\b(?:false|maybe|true)\b/
+ }
+ };
+
+ Prism.languages.art = Prism.languages['arturo'];
+}(Prism));
diff --git a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-arturo.min.js b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-arturo.min.js
new file mode 100644
index 0000000000..f17b130a17
--- /dev/null
+++ b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-arturo.min.js
@@ -0,0 +1 @@
+!function(e){var a=function(a,t){return{pattern:RegExp("\\{!(?:"+(t||a)+")$[^]*\\}","m"),greedy:!0,inside:{embedded:{pattern:/(^\{!\w+\b)[\s\S]+(?=\}$)/,lookbehind:!0,alias:"language-"+a,inside:e.languages[a]},string:/[\s\S]+/}}};e.languages.arturo={comment:{pattern:/;.*/,greedy:!0},character:{pattern:/`.`/,alias:"char",greedy:!0},number:{pattern:/\b\d+(?:\.\d+(?:\.\d+(?:-[\w+-]+)?)?)?\b/},string:{pattern:/"(?:[^"\\\r\n]|\\.)*"/,greedy:!0},regex:{pattern:/\{\/.*?\/\}/,greedy:!0},"html-string":a("html"),"css-string":a("css"),"js-string":a("js"),"md-string":a("md"),"sql-string":a("sql"),"sh-string":a("shell","sh"),multistring:{pattern:/».*|\{:[\s\S]*?:\}|\{[\s\S]*?\}|^-{6}$[\s\S]*/m,alias:"string",greedy:!0},label:{pattern:/\w+\b\??:/,alias:"property"},literal:{pattern:/'(?:\w+\b\??:?)/,alias:"constant"},type:{pattern:/:(?:\w+\b\??:?)/,alias:"class-name"},color:/#\w+/,predicate:{pattern:/\b(?:all|and|any|ascii|attr|attribute|attributeLabel|binary|block|char|contains|database|date|dictionary|empty|equal|even|every|exists|false|floating|function|greater|greaterOrEqual|if|in|inline|integer|is|key|label|leap|less|lessOrEqual|literal|logical|lower|nand|negative|nor|not|notEqual|null|numeric|odd|or|path|pathLabel|positive|prefix|prime|regex|same|set|some|sorted|standalone|string|subset|suffix|superset|symbol|symbolLiteral|true|try|type|unless|upper|when|whitespace|word|xnor|xor|zero)\?/,alias:"keyword"},"builtin-function":{pattern:/\b(?:abs|acos|acosh|acsec|acsech|actan|actanh|add|after|alert|alias|and|angle|append|arg|args|arity|array|as|asec|asech|asin|asinh|atan|atan2|atanh|attr|attrs|average|before|benchmark|blend|break|call|capitalize|case|ceil|chop|clear|clip|close|color|combine|conj|continue|copy|cos|cosh|crc|csec|csech|ctan|ctanh|cursor|darken|dec|decode|define|delete|desaturate|deviation|dialog|dictionary|difference|digest|digits|div|do|download|drop|dup|e|else|empty|encode|ensure|env|escape|execute|exit|exp|extend|extract|factors|fdiv|filter|first|flatten|floor|fold|from|function|gamma|gcd|get|goto|hash|hypot|if|inc|indent|index|infinity|info|input|insert|inspect|intersection|invert|jaro|join|keys|kurtosis|last|let|levenshtein|lighten|list|ln|log|loop|lower|mail|map|match|max|median|min|mod|module|mul|nand|neg|new|nor|normalize|not|now|null|open|or|outdent|pad|palette|panic|path|pause|permissions|permutate|pi|pop|popup|pow|powerset|powmod|prefix|print|prints|process|product|query|random|range|read|relative|remove|rename|render|repeat|replace|request|return|reverse|round|sample|saturate|script|sec|sech|select|serve|set|shl|shr|shuffle|sin|sinh|size|skewness|slice|sort|spin|split|sqrt|squeeze|stack|strip|sub|suffix|sum|switch|symbols|symlink|sys|take|tan|tanh|terminal|terminate|to|truncate|try|type|unclip|union|unique|unless|until|unzip|upper|values|var|variance|volume|webview|while|with|wordwrap|write|xnor|xor|zip)\b/,alias:"keyword"},sugar:{pattern:/->|=>|\||::/,alias:"operator"},punctuation:/[()[\],]/,symbol:{pattern:/<:|-:|ø|@|#|\+|\||\*|\$|---|-|%|\/|\.\.|\^|~|=|<|>|\\/},boolean:{pattern:/\b(?:false|maybe|true)\b/}},e.languages.art=e.languages.arturo}(Prism);
\ No newline at end of file
diff --git a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-asciidoc.min.js b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-asciidoc.min.js
index ed45a7a251..e1badd1aac 100644
--- a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-asciidoc.min.js
+++ b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-asciidoc.min.js
@@ -1 +1 @@
-!function(t){var n={pattern:/(^[ \t]*)\[(?!\[)(?:(["'$`])(?:(?!\2)[^\\]|\\.)*\2|\[(?:[^\[\]\\]|\\.)*\]|[^\[\]\\"'$`]|\\.)*\]/m,lookbehind:!0,inside:{quoted:{pattern:/([$`])(?:(?!\1)[^\\]|\\.)*\1/,inside:{punctuation:/^[$`]|[$`]$/}},interpreted:{pattern:/'(?:[^'\\]|\\.)*'/,inside:{punctuation:/^'|'$/}},string:/"(?:[^"\\]|\\.)*"/,variable:/\w+(?==)/,punctuation:/^\[|\]$|,/,operator:/=/,"attr-value":/(?!^\s+$).+/}},a=t.languages.asciidoc={"comment-block":{pattern:/^(\/{4,})(?:\r?\n|\r)(?:[\s\S]*(?:\r?\n|\r))??\1/m,alias:"comment"},table:{pattern:/^\|={3,}(?:(?:\r?\n|\r(?!\n)).*)*?(?:\r?\n|\r)\|={3,}$/m,inside:{specifiers:{pattern:/(?:(?:(?:\d+(?:\.\d+)?|\.\d+)[+*](?:[<^>](?:\.[<^>])?|\.[<^>])?|[<^>](?:\.[<^>])?|\.[<^>])[a-z]*|[a-z]+)(?=\|)/,alias:"attr-value"},punctuation:{pattern:/(^|[^\\])[|!]=*/,lookbehind:!0}}},"passthrough-block":{pattern:/^(\+{4,})(?:\r?\n|\r)(?:[\s\S]*(?:\r?\n|\r))??\1$/m,inside:{punctuation:/^\++|\++$/}},"literal-block":{pattern:/^(-{4,}|\.{4,})(?:\r?\n|\r)(?:[\s\S]*(?:\r?\n|\r))??\1$/m,inside:{punctuation:/^(?:-+|\.+)|(?:-+|\.+)$/}},"other-block":{pattern:/^(--|\*{4,}|_{4,}|={4,})(?:\r?\n|\r)(?:[\s\S]*(?:\r?\n|\r))??\1$/m,inside:{punctuation:/^(?:-+|\*+|_+|=+)|(?:-+|\*+|_+|=+)$/}},"list-punctuation":{pattern:/(^[ \t]*)(?:-|\*{1,5}|\.{1,5}|(?:[a-z]|\d+)\.|[xvi]+\))(?= )/im,lookbehind:!0,alias:"punctuation"},"list-label":{pattern:/(^[ \t]*)[a-z\d].+(?::{2,4}|;;)(?=\s)/im,lookbehind:!0,alias:"symbol"},"indented-block":{pattern:/((\r?\n|\r)\2)([ \t]+)\S.*(?:(?:\r?\n|\r)\3.+)*(?=\2{2}|$)/,lookbehind:!0},comment:/^\/\/.*/m,title:{pattern:/^.+(?:\r?\n|\r)(?:={3,}|-{3,}|~{3,}|\^{3,}|\+{3,})$|^={1,5} .+|^\.(?![\s.]).*/m,alias:"important",inside:{punctuation:/^(?:\.|=+)|(?:=+|-+|~+|\^+|\++)$/}},"attribute-entry":{pattern:/^:[^:\r\n]+:(?: .*?(?: \+(?:\r?\n|\r).*?)*)?$/m,alias:"tag"},attributes:n,hr:{pattern:/^'{3,}$/m,alias:"punctuation"},"page-break":{pattern:/^<{3,}$/m,alias:"punctuation"},admonition:{pattern:/^(?:CAUTION|IMPORTANT|NOTE|TIP|WARNING):/m,alias:"keyword"},callout:[{pattern:/(^[ \t]*)\d*>/m,lookbehind:!0,alias:"symbol"},{pattern:/<\d+>/,alias:"symbol"}],macro:{pattern:/\b[a-z\d][a-z\d-]*::?(?:[^\s\[\]]*\[(?:[^\]\\"']|(["'])(?:(?!\1)[^\\]|\\.)*\1|\\.)*\])/,inside:{function:/^[a-z\d-]+(?=:)/,punctuation:/^::?/,attributes:{pattern:/(?:\[(?:[^\]\\"']|(["'])(?:(?!\1)[^\\]|\\.)*\1|\\.)*\])/,inside:n.inside}}},inline:{pattern:/(^|[^\\])(?:(?:\B\[(?:[^\]\\"']|(["'])(?:(?!\2)[^\\]|\\.)*\2|\\.)*\])?(?:\b_(?!\s)(?: _|[^_\\\r\n]|\\.)+(?:(?:\r?\n|\r)(?: _|[^_\\\r\n]|\\.)+)*_\b|\B``(?!\s).+?(?:(?:\r?\n|\r).+?)*''\B|\B`(?!\s)(?:[^`'\s]|\s+\S)+['`]\B|\B(['*+#])(?!\s)(?: \3|(?!\3)[^\\\r\n]|\\.)+(?:(?:\r?\n|\r)(?: \3|(?!\3)[^\\\r\n]|\\.)+)*\3\B)|(?:\[(?:[^\]\\"']|(["'])(?:(?!\4)[^\\]|\\.)*\4|\\.)*\])?(?:(__|\*\*|\+\+\+?|##|\$\$|[~^]).+?(?:(?:\r?\n|\r).+?)*\5|\{[^}\r\n]+\}|\[\[\[?.+?(?:(?:\r?\n|\r).+?)*\]?\]\]|<<.+?(?:(?:\r?\n|\r).+?)*>>|\(\(\(?.+?(?:(?:\r?\n|\r).+?)*\)?\)\)))/m,lookbehind:!0,inside:{attributes:n,url:{pattern:/^(?:\[\[\[?.+?\]?\]\]|<<.+?>>)$/,inside:{punctuation:/^(?:\[\[\[?|<<)|(?:\]\]\]?|>>)$/}},"attribute-ref":{pattern:/^\{.+\}$/,inside:{variable:{pattern:/(^\{)[a-z\d,+_-]+/,lookbehind:!0},operator:/^[=?!#%@$]|!(?=[:}])/,punctuation:/^\{|\}$|::?/}},italic:{pattern:/^(['_])[\s\S]+\1$/,inside:{punctuation:/^(?:''?|__?)|(?:''?|__?)$/}},bold:{pattern:/^\*[\s\S]+\*$/,inside:{punctuation:/^\*\*?|\*\*?$/}},punctuation:/^(?:``?|\+{1,3}|##?|\$\$|[~^]|\(\(\(?)|(?:''?|\+{1,3}|##?|\$\$|[~^`]|\)?\)\))$/}},replacement:{pattern:/\((?:C|R|TM)\)/,alias:"builtin"},entity:/?[\da-z]{1,8};/i,"line-continuation":{pattern:/(^| )\+$/m,lookbehind:!0,alias:"punctuation"}};function i(t){for(var n={},i=0,e=(t=t.split(" ")).length;i](?:\.[<^>])?|\.[<^>])?|[<^>](?:\.[<^>])?|\.[<^>])[a-z]*|[a-z]+)(?=\|)/,alias:"attr-value"},punctuation:{pattern:/(^|[^\\])[|!]=*/,lookbehind:!0}}},"passthrough-block":{pattern:/^(\+{4,})(?:\r?\n|\r)(?:[\s\S]*(?:\r?\n|\r))??\1$/m,inside:{punctuation:/^\++|\++$/}},"literal-block":{pattern:/^(-{4,}|\.{4,})(?:\r?\n|\r)(?:[\s\S]*(?:\r?\n|\r))??\1$/m,inside:{punctuation:/^(?:-+|\.+)|(?:-+|\.+)$/}},"other-block":{pattern:/^(--|\*{4,}|_{4,}|={4,})(?:\r?\n|\r)(?:[\s\S]*(?:\r?\n|\r))??\1$/m,inside:{punctuation:/^(?:-+|\*+|_+|=+)|(?:-+|\*+|_+|=+)$/}},"list-punctuation":{pattern:/(^[ \t]*)(?:-|\*{1,5}|\.{1,5}|(?:[a-z]|\d+)\.|[xvi]+\))(?= )/im,lookbehind:!0,alias:"punctuation"},"list-label":{pattern:/(^[ \t]*)[a-z\d].+(?::{2,4}|;;)(?=\s)/im,lookbehind:!0,alias:"symbol"},"indented-block":{pattern:/((\r?\n|\r)\2)([ \t]+)\S.*(?:(?:\r?\n|\r)\3.+)*(?=\2{2}|$)/,lookbehind:!0},comment:/^\/\/.*/m,title:{pattern:/^.+(?:\r?\n|\r)(?:={3,}|-{3,}|~{3,}|\^{3,}|\+{3,})$|^={1,5} .+|^\.(?![\s.]).*/m,alias:"important",inside:{punctuation:/^(?:\.|=+)|(?:=+|-+|~+|\^+|\++)$/}},"attribute-entry":{pattern:/^:[^:\r\n]+:(?: .*?(?: \+(?:\r?\n|\r).*?)*)?$/m,alias:"tag"},attributes:n,hr:{pattern:/^'{3,}$/m,alias:"punctuation"},"page-break":{pattern:/^<{3,}$/m,alias:"punctuation"},admonition:{pattern:/^(?:CAUTION|IMPORTANT|NOTE|TIP|WARNING):/m,alias:"keyword"},callout:[{pattern:/(^[ \t]*)\d*>/m,lookbehind:!0,alias:"symbol"},{pattern:/<\d+>/,alias:"symbol"}],macro:{pattern:/\b[a-z\d][a-z\d-]*::?(?:[^\s\[\]]*\[(?:[^\]\\"']|(["'])(?:(?!\1)[^\\]|\\.)*\1|\\.)*\])/,inside:{function:/^[a-z\d-]+(?=:)/,punctuation:/^::?/,attributes:{pattern:/(?:\[(?:[^\]\\"']|(["'])(?:(?!\1)[^\\]|\\.)*\1|\\.)*\])/,inside:n.inside}}},inline:{pattern:/(^|[^\\])(?:(?:\B\[(?:[^\]\\"']|(["'])(?:(?!\2)[^\\]|\\.)*\2|\\.)*\])?(?:\b_(?!\s)(?: _|[^_\\\r\n]|\\.)+(?:(?:\r?\n|\r)(?: _|[^_\\\r\n]|\\.)+)*_\b|\B``(?!\s).+?(?:(?:\r?\n|\r).+?)*''\B|\B`(?!\s)(?:[^`'\s]|\s+\S)+['`]\B|\B(['*+#])(?!\s)(?: \3|(?!\3)[^\\\r\n]|\\.)+(?:(?:\r?\n|\r)(?: \3|(?!\3)[^\\\r\n]|\\.)+)*\3\B)|(?:\[(?:[^\]\\"']|(["'])(?:(?!\4)[^\\]|\\.)*\4|\\.)*\])?(?:(__|\*\*|\+\+\+?|##|\$\$|[~^]).+?(?:(?:\r?\n|\r).+?)*\5|\{[^}\r\n]+\}|\[\[\[?.+?(?:(?:\r?\n|\r).+?)*\]?\]\]|<<.+?(?:(?:\r?\n|\r).+?)*>>|\(\(\(?.+?(?:(?:\r?\n|\r).+?)*\)?\)\)))/m,lookbehind:!0,inside:{attributes:n,url:{pattern:/^(?:\[\[\[?.+?\]?\]\]|<<.+?>>)$/,inside:{punctuation:/^(?:\[\[\[?|<<)|(?:\]\]\]?|>>)$/}},"attribute-ref":{pattern:/^\{.+\}$/,inside:{variable:{pattern:/(^\{)[a-z\d,+_-]+/,lookbehind:!0},operator:/^[=?!#%@$]|!(?=[:}])/,punctuation:/^\{|\}$|::?/}},italic:{pattern:/^(['_])[\s\S]+\1$/,inside:{punctuation:/^(?:''?|__?)|(?:''?|__?)$/}},bold:{pattern:/^\*[\s\S]+\*$/,inside:{punctuation:/^\*\*?|\*\*?$/}},punctuation:/^(?:``?|\+{1,3}|##?|\$\$|[~^]|\(\(\(?)|(?:''?|\+{1,3}|##?|\$\$|[~^`]|\)?\)\))$/}},replacement:{pattern:/\((?:C|R|TM)\)/,alias:"builtin"},entity:/?[\da-z]{1,8};/i,"line-continuation":{pattern:/(^| )\+$/m,lookbehind:!0,alias:"punctuation"}};function e(t){for(var n={},e=0,a=(t=t.split(" ")).length;e>=?|<<=?|&&?|\|\|?|[-+*/%&|^!=<>?]=?/,
+ 'operator': />>=?|<<=?|&[&=]?|\|[\|=]?|[-+*/%^!=<>?]=?/,
'punctuation': /[(),:]/
};
diff --git a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-asmatmel.min.js b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-asmatmel.min.js
index 6e6f8c6912..8c021f9ead 100644
--- a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-asmatmel.min.js
+++ b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-asmatmel.min.js
@@ -1 +1 @@
-Prism.languages.asmatmel={comment:{pattern:/;.*/,greedy:!0},string:{pattern:/(["'`])(?:\\.|(?!\1)[^\\\r\n])*\1/,greedy:!0},constant:/\b(?:PORT[A-Z]|DDR[A-Z]|(?:DD|P)[A-Z](?:\d|[0-2]\d|3[01]))\b/,directive:{pattern:/\.\w+(?= )/,alias:"property"},"r-register":{pattern:/\br(?:\d|[12]\d|3[01])\b/,alias:"variable"},"op-code":{pattern:/\b(?:ADC|ADD|ADIW|AND|ANDI|ASR|BCLR|BLD|BRBC|BRBS|BRCC|BRCS|BREAK|BREQ|BRGE|BRHC|BRHS|BRID|BRIE|BRLO|BRLT|BRMI|BRNE|BRPL|BRSH|BRTC|BRTS|BRVC|BRVS|BSET|BST|CALL|CBI|CBR|CLC|CLH|CLI|CLN|CLR|CLS|CLT|CLV|CLZ|COM|CP|CPC|CPI|CPSE|DEC|DES|EICALL|EIJMP|ELPM|EOR|FMUL|FMULS|FMULSU|ICALL|IJMP|IN|INC|JMP|LAC|LAS|LAT|LD|LD[A-Za-z0-9]|LPM|LSL|LSR|MOV|MOVW|MUL|MULS|MULSU|NEG|NOP|OR|ORI|OUT|POP|PUSH|RCALL|RET|RETI|RJMP|ROL|ROR|SBC|SBCI|SBI|SBIC|SBIS|SBIW|SBR|SBRC|SBRS|SEC|SEH|SEI|SEN|SER|SES|SET|SEV|SEZ|SLEEP|SPM|ST|ST[A-Z0-9]|SUB|SUBI|SWAP|TST|WDR|XCH|adc|add|adiw|and|andi|asr|bclr|bld|brbc|brbs|brcc|brcs|break|breq|brge|brhc|brhs|brid|brie|brlo|brlt|brmi|brne|brpl|brsh|brtc|brts|brvc|brvs|bset|bst|call|cbi|cbr|clc|clh|cli|cln|clr|cls|clt|clv|clz|com|cp|cpc|cpi|cpse|dec|des|eicall|eijmp|elpm|eor|fmul|fmuls|fmulsu|icall|ijmp|in|inc|jmp|lac|las|lat|ld|ld[a-z0-9]|lpm|lsl|lsr|mov|movw|mul|muls|mulsu|neg|nop|or|ori|out|pop|push|rcall|ret|reti|rjmp|rol|ror|sbc|sbci|sbi|sbic|sbis|sbiw|sbr|sbrc|sbrs|sec|seh|sei|sen|ser|ses|set|sev|sez|sleep|spm|st|st[a-zA-Z0-9]|sub|subi|swap|tst|wdr|xch)\b/,alias:"keyword"},"hex-number":{pattern:/#?\$[\da-f]{2,4}\b/i,alias:"number"},"binary-number":{pattern:/#?%[01]+\b/,alias:"number"},"decimal-number":{pattern:/#?\b\d+\b/,alias:"number"},register:{pattern:/\b[acznvshtixy]\b/i,alias:"variable"},operator:/>>=?|<<=?|&&?|\|\|?|[-+*/%&|^!=<>?]=?/,punctuation:/[(),:]/};
\ No newline at end of file
+Prism.languages.asmatmel={comment:{pattern:/;.*/,greedy:!0},string:{pattern:/(["'`])(?:\\.|(?!\1)[^\\\r\n])*\1/,greedy:!0},constant:/\b(?:PORT[A-Z]|DDR[A-Z]|(?:DD|P)[A-Z](?:\d|[0-2]\d|3[01]))\b/,directive:{pattern:/\.\w+(?= )/,alias:"property"},"r-register":{pattern:/\br(?:\d|[12]\d|3[01])\b/,alias:"variable"},"op-code":{pattern:/\b(?:ADC|ADD|ADIW|AND|ANDI|ASR|BCLR|BLD|BRBC|BRBS|BRCC|BRCS|BREAK|BREQ|BRGE|BRHC|BRHS|BRID|BRIE|BRLO|BRLT|BRMI|BRNE|BRPL|BRSH|BRTC|BRTS|BRVC|BRVS|BSET|BST|CALL|CBI|CBR|CLC|CLH|CLI|CLN|CLR|CLS|CLT|CLV|CLZ|COM|CP|CPC|CPI|CPSE|DEC|DES|EICALL|EIJMP|ELPM|EOR|FMUL|FMULS|FMULSU|ICALL|IJMP|IN|INC|JMP|LAC|LAS|LAT|LD|LD[A-Za-z0-9]|LPM|LSL|LSR|MOV|MOVW|MUL|MULS|MULSU|NEG|NOP|OR|ORI|OUT|POP|PUSH|RCALL|RET|RETI|RJMP|ROL|ROR|SBC|SBCI|SBI|SBIC|SBIS|SBIW|SBR|SBRC|SBRS|SEC|SEH|SEI|SEN|SER|SES|SET|SEV|SEZ|SLEEP|SPM|ST|ST[A-Z0-9]|SUB|SUBI|SWAP|TST|WDR|XCH|adc|add|adiw|and|andi|asr|bclr|bld|brbc|brbs|brcc|brcs|break|breq|brge|brhc|brhs|brid|brie|brlo|brlt|brmi|brne|brpl|brsh|brtc|brts|brvc|brvs|bset|bst|call|cbi|cbr|clc|clh|cli|cln|clr|cls|clt|clv|clz|com|cp|cpc|cpi|cpse|dec|des|eicall|eijmp|elpm|eor|fmul|fmuls|fmulsu|icall|ijmp|in|inc|jmp|lac|las|lat|ld|ld[a-z0-9]|lpm|lsl|lsr|mov|movw|mul|muls|mulsu|neg|nop|or|ori|out|pop|push|rcall|ret|reti|rjmp|rol|ror|sbc|sbci|sbi|sbic|sbis|sbiw|sbr|sbrc|sbrs|sec|seh|sei|sen|ser|ses|set|sev|sez|sleep|spm|st|st[a-zA-Z0-9]|sub|subi|swap|tst|wdr|xch)\b/,alias:"keyword"},"hex-number":{pattern:/#?\$[\da-f]{2,4}\b/i,alias:"number"},"binary-number":{pattern:/#?%[01]+\b/,alias:"number"},"decimal-number":{pattern:/#?\b\d+\b/,alias:"number"},register:{pattern:/\b[acznvshtixy]\b/i,alias:"variable"},operator:/>>=?|<<=?|&[&=]?|\|[\|=]?|[-+*/%^!=<>?]=?/,punctuation:/[(),:]/};
\ No newline at end of file
diff --git a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-autohotkey.js b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-autohotkey.js
index dbd0751c94..eb68d154d2 100644
--- a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-autohotkey.js
+++ b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-autohotkey.js
@@ -22,7 +22,10 @@ Prism.languages.autohotkey = {
'operator': /\?|\/\/?=?|:=|\|[=|]?|&[=&]?|\+[=+]?|-[=-]?|\*[=*]?|<(?:<=?|>|=)?|>>?=?|[.^!=~]=?|\b(?:AND|NOT|OR)\b/,
'boolean': /\b(?:false|true)\b/,
- 'selector': /\b(?:AutoTrim|BlockInput|Break|Click|ClipWait|Continue|Control|ControlClick|ControlFocus|ControlGet|ControlGetFocus|ControlGetPos|ControlGetText|ControlMove|ControlSend|ControlSendRaw|ControlSetText|CoordMode|Critical|DetectHiddenText|DetectHiddenWindows|Drive|DriveGet|DriveSpaceFree|EnvAdd|EnvDiv|EnvGet|EnvMult|EnvSet|EnvSub|EnvUpdate|Exit|ExitApp|FileAppend|FileCopy|FileCopyDir|FileCreateDir|FileCreateShortcut|FileDelete|FileEncoding|FileGetAttrib|FileGetShortcut|FileGetSize|FileGetTime|FileGetVersion|FileInstall|FileMove|FileMoveDir|FileRead|FileReadLine|FileRecycle|FileRecycleEmpty|FileRemoveDir|FileSelectFile|FileSelectFolder|FileSetAttrib|FileSetTime|FormatTime|GetKeyState|Gosub|Goto|GroupActivate|GroupAdd|GroupClose|GroupDeactivate|Gui|GuiControl|GuiControlGet|Hotkey|ImageSearch|IniDelete|IniRead|IniWrite|Input|InputBox|KeyWait|ListHotkeys|ListLines|ListVars|Loop|Menu|MouseClick|MouseClickDrag|MouseGetPos|MouseMove|MsgBox|OnExit|OutputDebug|Pause|PixelGetColor|PixelSearch|PostMessage|Process|Progress|Random|RegDelete|RegRead|RegWrite|Reload|Repeat|Return|Run|RunAs|RunWait|Send|SendEvent|SendInput|SendMessage|SendMode|SendPlay|SendRaw|SetBatchLines|SetCapslockState|SetControlDelay|SetDefaultMouseSpeed|SetEnv|SetFormat|SetKeyDelay|SetMouseDelay|SetNumlockState|SetRegView|SetScrollLockState|SetStoreCapslockMode|SetTimer|SetTitleMatchMode|SetWinDelay|SetWorkingDir|Shutdown|Sleep|Sort|SoundBeep|SoundGet|SoundGetWaveVolume|SoundPlay|SoundSet|SoundSetWaveVolume|SplashImage|SplashTextOff|SplashTextOn|SplitPath|StatusBarGetText|StatusBarWait|StringCaseSense|StringGetPos|StringLeft|StringLen|StringLower|StringMid|StringReplace|StringRight|StringSplit|StringTrimLeft|StringTrimRight|StringUpper|Suspend|SysGet|Thread|ToolTip|Transform|TrayTip|URLDownloadToFile|WinActivate|WinActivateBottom|WinClose|WinGet|WinGetActiveStats|WinGetActiveTitle|WinGetClass|WinGetPos|WinGetText|WinGetTitle|WinHide|WinKill|WinMaximize|WinMenuSelectItem|WinMinimize|WinMinimizeAll|WinMinimizeAllUndo|WinMove|WinRestore|WinSet|WinSetTitle|WinShow|WinWait|WinWaitActive|WinWaitClose|WinWaitNotActive)\b/i,
+ 'command': {
+ pattern: /\b(?:AutoTrim|BlockInput|Break|Click|ClipWait|Continue|Control|ControlClick|ControlFocus|ControlGet|ControlGetFocus|ControlGetPos|ControlGetText|ControlMove|ControlSend|ControlSendRaw|ControlSetText|CoordMode|Critical|DetectHiddenText|DetectHiddenWindows|Drive|DriveGet|DriveSpaceFree|EnvAdd|EnvDiv|EnvGet|EnvMult|EnvSet|EnvSub|EnvUpdate|Exit|ExitApp|FileAppend|FileCopy|FileCopyDir|FileCreateDir|FileCreateShortcut|FileDelete|FileEncoding|FileGetAttrib|FileGetShortcut|FileGetSize|FileGetTime|FileGetVersion|FileInstall|FileMove|FileMoveDir|FileRead|FileReadLine|FileRecycle|FileRecycleEmpty|FileRemoveDir|FileSelectFile|FileSelectFolder|FileSetAttrib|FileSetTime|FormatTime|GetKeyState|Gosub|Goto|GroupActivate|GroupAdd|GroupClose|GroupDeactivate|Gui|GuiControl|GuiControlGet|Hotkey|ImageSearch|IniDelete|IniRead|IniWrite|Input|InputBox|KeyWait|ListHotkeys|ListLines|ListVars|Loop|Menu|MouseClick|MouseClickDrag|MouseGetPos|MouseMove|MsgBox|OnExit|OutputDebug|Pause|PixelGetColor|PixelSearch|PostMessage|Process|Progress|Random|RegDelete|RegRead|RegWrite|Reload|Repeat|Return|Run|RunAs|RunWait|Send|SendEvent|SendInput|SendMessage|SendMode|SendPlay|SendRaw|SetBatchLines|SetCapslockState|SetControlDelay|SetDefaultMouseSpeed|SetEnv|SetFormat|SetKeyDelay|SetMouseDelay|SetNumlockState|SetRegView|SetScrollLockState|SetStoreCapslockMode|SetTimer|SetTitleMatchMode|SetWinDelay|SetWorkingDir|Shutdown|Sleep|Sort|SoundBeep|SoundGet|SoundGetWaveVolume|SoundPlay|SoundSet|SoundSetWaveVolume|SplashImage|SplashTextOff|SplashTextOn|SplitPath|StatusBarGetText|StatusBarWait|StringCaseSense|StringGetPos|StringLeft|StringLen|StringLower|StringMid|StringReplace|StringRight|StringSplit|StringTrimLeft|StringTrimRight|StringUpper|Suspend|SysGet|Thread|ToolTip|Transform|TrayTip|URLDownloadToFile|WinActivate|WinActivateBottom|WinClose|WinGet|WinGetActiveStats|WinGetActiveTitle|WinGetClass|WinGetPos|WinGetText|WinGetTitle|WinHide|WinKill|WinMaximize|WinMenuSelectItem|WinMinimize|WinMinimizeAll|WinMinimizeAllUndo|WinMove|WinRestore|WinSet|WinSetTitle|WinShow|WinWait|WinWaitActive|WinWaitClose|WinWaitNotActive)\b/i,
+ alias: 'selector'
+ },
'constant': /\b(?:a_ahkpath|a_ahkversion|a_appdata|a_appdatacommon|a_autotrim|a_batchlines|a_caretx|a_carety|a_computername|a_controldelay|a_cursor|a_dd|a_ddd|a_dddd|a_defaultmousespeed|a_desktop|a_desktopcommon|a_detecthiddentext|a_detecthiddenwindows|a_endchar|a_eventinfo|a_exitreason|a_fileencoding|a_formatfloat|a_formatinteger|a_gui|a_guicontrol|a_guicontrolevent|a_guievent|a_guiheight|a_guiwidth|a_guix|a_guiy|a_hour|a_iconfile|a_iconhidden|a_iconnumber|a_icontip|a_index|a_ipaddress1|a_ipaddress2|a_ipaddress3|a_ipaddress4|a_is64bitos|a_isadmin|a_iscompiled|a_iscritical|a_ispaused|a_issuspended|a_isunicode|a_keydelay|a_language|a_lasterror|a_linefile|a_linenumber|a_loopfield|a_loopfileattrib|a_loopfiledir|a_loopfileext|a_loopfilefullpath|a_loopfilelongpath|a_loopfilename|a_loopfileshortname|a_loopfileshortpath|a_loopfilesize|a_loopfilesizekb|a_loopfilesizemb|a_loopfiletimeaccessed|a_loopfiletimecreated|a_loopfiletimemodified|a_loopreadline|a_loopregkey|a_loopregname|a_loopregsubkey|a_loopregtimemodified|a_loopregtype|a_mday|a_min|a_mm|a_mmm|a_mmmm|a_mon|a_mousedelay|a_msec|a_mydocuments|a_now|a_nowutc|a_numbatchlines|a_ostype|a_osversion|a_priorhotkey|a_priorkey|a_programfiles|a_programs|a_programscommon|a_ptrsize|a_regview|a_screendpi|a_screenheight|a_screenwidth|a_scriptdir|a_scriptfullpath|a_scripthwnd|a_scriptname|a_sec|a_space|a_startmenu|a_startmenucommon|a_startup|a_startupcommon|a_stringcasesense|a_tab|a_temp|a_thisfunc|a_thishotkey|a_thislabel|a_thismenu|a_thismenuitem|a_thismenuitempos|a_tickcount|a_timeidle|a_timeidlephysical|a_timesincepriorhotkey|a_timesincethishotkey|a_titlematchmode|a_titlematchmodespeed|a_username|a_wday|a_windelay|a_windir|a_workingdir|a_yday|a_year|a_yweek|a_yyyy|clipboard|clipboardall|comspec|errorlevel|programfiles)\b/i,
@@ -30,7 +33,10 @@ Prism.languages.autohotkey = {
'symbol': /\b(?:alt|altdown|altup|appskey|backspace|browser_back|browser_favorites|browser_forward|browser_home|browser_refresh|browser_search|browser_stop|bs|capslock|ctrl|ctrlbreak|ctrldown|ctrlup|del|delete|down|end|enter|esc|escape|f1|f10|f11|f12|f13|f14|f15|f16|f17|f18|f19|f2|f20|f21|f22|f23|f24|f3|f4|f5|f6|f7|f8|f9|home|ins|insert|joy1|joy10|joy11|joy12|joy13|joy14|joy15|joy16|joy17|joy18|joy19|joy2|joy20|joy21|joy22|joy23|joy24|joy25|joy26|joy27|joy28|joy29|joy3|joy30|joy31|joy32|joy4|joy5|joy6|joy7|joy8|joy9|joyaxes|joybuttons|joyinfo|joyname|joypov|joyr|joyu|joyv|joyx|joyy|joyz|lalt|launch_app1|launch_app2|launch_mail|launch_media|lbutton|lcontrol|lctrl|left|lshift|lwin|lwindown|lwinup|mbutton|media_next|media_play_pause|media_prev|media_stop|numlock|numpad0|numpad1|numpad2|numpad3|numpad4|numpad5|numpad6|numpad7|numpad8|numpad9|numpadadd|numpadclear|numpaddel|numpaddiv|numpaddot|numpaddown|numpadend|numpadenter|numpadhome|numpadins|numpadleft|numpadmult|numpadpgdn|numpadpgup|numpadright|numpadsub|numpadup|pgdn|pgup|printscreen|ralt|rbutton|rcontrol|rctrl|right|rshift|rwin|rwindown|rwinup|scrolllock|shift|shiftdown|shiftup|space|tab|up|volume_down|volume_mute|volume_up|wheeldown|wheelleft|wheelright|wheelup|xbutton1|xbutton2)\b/i,
- 'important': /#\b(?:AllowSameLineComments|ClipboardTimeout|CommentFlag|DerefChar|ErrorStdOut|EscapeChar|HotkeyInterval|HotkeyModifierTimeout|Hotstring|If|IfTimeout|IfWinActive|IfWinExist|IfWinNotActive|IfWinNotExist|Include|IncludeAgain|InputLevel|InstallKeybdHook|InstallMouseHook|KeyHistory|MaxHotkeysPerInterval|MaxMem|MaxThreads|MaxThreadsBuffer|MaxThreadsPerHotkey|MenuMaskKey|NoEnv|NoTrayIcon|Persistent|SingleInstance|UseHook|Warn|WinActivateForce)\b/i,
+ 'directive': {
+ pattern: /#[a-z]+\b/i,
+ alias: 'important'
+ },
'keyword': /\b(?:Abort|AboveNormal|Add|ahk_class|ahk_exe|ahk_group|ahk_id|ahk_pid|All|Alnum|Alpha|AltSubmit|AltTab|AltTabAndMenu|AltTabMenu|AltTabMenuDismiss|AlwaysOnTop|AutoSize|Background|BackgroundTrans|BelowNormal|between|BitAnd|BitNot|BitOr|BitShiftLeft|BitShiftRight|BitXOr|Bold|Border|Button|ByRef|Catch|Checkbox|Checked|CheckedGray|Choose|ChooseString|Close|Color|ComboBox|Contains|ControlList|Count|Date|DateTime|Days|DDL|Default|DeleteAll|Delimiter|Deref|Destroy|Digit|Disable|Disabled|DropDownList|Edit|Eject|Else|Enable|Enabled|Error|Exist|Expand|ExStyle|FileSystem|Finally|First|Flash|Float|FloatFast|Focus|Font|for|global|Grid|Group|GroupBox|GuiClose|GuiContextMenu|GuiDropFiles|GuiEscape|GuiSize|Hdr|Hidden|Hide|High|HKCC|HKCR|HKCU|HKEY_CLASSES_ROOT|HKEY_CURRENT_CONFIG|HKEY_CURRENT_USER|HKEY_LOCAL_MACHINE|HKEY_USERS|HKLM|HKU|Hours|HScroll|Icon|IconSmall|ID|IDLast|If|IfEqual|IfExist|IfGreater|IfGreaterOrEqual|IfInString|IfLess|IfLessOrEqual|IfMsgBox|IfNotEqual|IfNotExist|IfNotInString|IfWinActive|IfWinExist|IfWinNotActive|IfWinNotExist|Ignore|ImageList|in|Integer|IntegerFast|Interrupt|is|italic|Join|Label|LastFound|LastFoundExist|Limit|Lines|List|ListBox|ListView|local|Lock|Logoff|Low|Lower|Lowercase|MainWindow|Margin|Maximize|MaximizeBox|MaxSize|Minimize|MinimizeBox|MinMax|MinSize|Minutes|MonthCal|Mouse|Move|Multi|NA|No|NoActivate|NoDefault|NoHide|NoIcon|NoMainWindow|norm|Normal|NoSort|NoSortHdr|NoStandard|Not|NoTab|NoTimers|Number|Off|Ok|On|OwnDialogs|Owner|Parse|Password|Picture|Pixel|Pos|Pow|Priority|ProcessName|Radio|Range|Read|ReadOnly|Realtime|Redraw|Region|REG_BINARY|REG_DWORD|REG_EXPAND_SZ|REG_MULTI_SZ|REG_SZ|Relative|Rename|Report|Resize|Restore|Retry|RGB|Screen|Seconds|Section|Serial|SetLabel|ShiftAltTab|Show|Single|Slider|SortDesc|Standard|static|Status|StatusBar|StatusCD|strike|Style|Submit|SysMenu|Tab2|TabStop|Text|Theme|Throw|Tile|ToggleCheck|ToggleEnable|ToolWindow|Top|Topmost|TransColor|Transparent|Tray|TreeView|Try|TryAgain|Type|UnCheck|underline|Unicode|Unlock|Until|UpDown|Upper|Uppercase|UseErrorLevel|Vis|VisFirst|Visible|VScroll|Wait|WaitClose|WantCtrlA|WantF2|WantReturn|While|Wrap|Xdigit|xm|xp|xs|Yes|ym|yp|ys)\b/i,
'function': /[^(); \t,\n+*\-=?>:\\\/<&%\[\]]+(?=\()/,
diff --git a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-autohotkey.min.js b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-autohotkey.min.js
index d7e1894410..79e06a1a4f 100644
--- a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-autohotkey.min.js
+++ b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-autohotkey.min.js
@@ -1 +1 @@
-Prism.languages.autohotkey={comment:[{pattern:/(^|\s);.*/,lookbehind:!0},{pattern:/(^[\t ]*)\/\*(?:[\r\n](?![ \t]*\*\/)|[^\r\n])*(?:[\r\n][ \t]*\*\/)?/m,lookbehind:!0,greedy:!0}],tag:{pattern:/^([ \t]*)[^\s,`":]+(?=:[ \t]*$)/m,lookbehind:!0},string:/"(?:[^"\n\r]|"")*"/,variable:/%\w+%/,number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee]-?\d+)?/,operator:/\?|\/\/?=?|:=|\|[=|]?|&[=&]?|\+[=+]?|-[=-]?|\*[=*]?|<(?:<=?|>|=)?|>>?=?|[.^!=~]=?|\b(?:AND|NOT|OR)\b/,boolean:/\b(?:false|true)\b/,selector:/\b(?:AutoTrim|BlockInput|Break|Click|ClipWait|Continue|Control|ControlClick|ControlFocus|ControlGet|ControlGetFocus|ControlGetPos|ControlGetText|ControlMove|ControlSend|ControlSendRaw|ControlSetText|CoordMode|Critical|DetectHiddenText|DetectHiddenWindows|Drive|DriveGet|DriveSpaceFree|EnvAdd|EnvDiv|EnvGet|EnvMult|EnvSet|EnvSub|EnvUpdate|Exit|ExitApp|FileAppend|FileCopy|FileCopyDir|FileCreateDir|FileCreateShortcut|FileDelete|FileEncoding|FileGetAttrib|FileGetShortcut|FileGetSize|FileGetTime|FileGetVersion|FileInstall|FileMove|FileMoveDir|FileRead|FileReadLine|FileRecycle|FileRecycleEmpty|FileRemoveDir|FileSelectFile|FileSelectFolder|FileSetAttrib|FileSetTime|FormatTime|GetKeyState|Gosub|Goto|GroupActivate|GroupAdd|GroupClose|GroupDeactivate|Gui|GuiControl|GuiControlGet|Hotkey|ImageSearch|IniDelete|IniRead|IniWrite|Input|InputBox|KeyWait|ListHotkeys|ListLines|ListVars|Loop|Menu|MouseClick|MouseClickDrag|MouseGetPos|MouseMove|MsgBox|OnExit|OutputDebug|Pause|PixelGetColor|PixelSearch|PostMessage|Process|Progress|Random|RegDelete|RegRead|RegWrite|Reload|Repeat|Return|Run|RunAs|RunWait|Send|SendEvent|SendInput|SendMessage|SendMode|SendPlay|SendRaw|SetBatchLines|SetCapslockState|SetControlDelay|SetDefaultMouseSpeed|SetEnv|SetFormat|SetKeyDelay|SetMouseDelay|SetNumlockState|SetRegView|SetScrollLockState|SetStoreCapslockMode|SetTimer|SetTitleMatchMode|SetWinDelay|SetWorkingDir|Shutdown|Sleep|Sort|SoundBeep|SoundGet|SoundGetWaveVolume|SoundPlay|SoundSet|SoundSetWaveVolume|SplashImage|SplashTextOff|SplashTextOn|SplitPath|StatusBarGetText|StatusBarWait|StringCaseSense|StringGetPos|StringLeft|StringLen|StringLower|StringMid|StringReplace|StringRight|StringSplit|StringTrimLeft|StringTrimRight|StringUpper|Suspend|SysGet|Thread|ToolTip|Transform|TrayTip|URLDownloadToFile|WinActivate|WinActivateBottom|WinClose|WinGet|WinGetActiveStats|WinGetActiveTitle|WinGetClass|WinGetPos|WinGetText|WinGetTitle|WinHide|WinKill|WinMaximize|WinMenuSelectItem|WinMinimize|WinMinimizeAll|WinMinimizeAllUndo|WinMove|WinRestore|WinSet|WinSetTitle|WinShow|WinWait|WinWaitActive|WinWaitClose|WinWaitNotActive)\b/i,constant:/\b(?:a_ahkpath|a_ahkversion|a_appdata|a_appdatacommon|a_autotrim|a_batchlines|a_caretx|a_carety|a_computername|a_controldelay|a_cursor|a_dd|a_ddd|a_dddd|a_defaultmousespeed|a_desktop|a_desktopcommon|a_detecthiddentext|a_detecthiddenwindows|a_endchar|a_eventinfo|a_exitreason|a_fileencoding|a_formatfloat|a_formatinteger|a_gui|a_guicontrol|a_guicontrolevent|a_guievent|a_guiheight|a_guiwidth|a_guix|a_guiy|a_hour|a_iconfile|a_iconhidden|a_iconnumber|a_icontip|a_index|a_ipaddress1|a_ipaddress2|a_ipaddress3|a_ipaddress4|a_is64bitos|a_isadmin|a_iscompiled|a_iscritical|a_ispaused|a_issuspended|a_isunicode|a_keydelay|a_language|a_lasterror|a_linefile|a_linenumber|a_loopfield|a_loopfileattrib|a_loopfiledir|a_loopfileext|a_loopfilefullpath|a_loopfilelongpath|a_loopfilename|a_loopfileshortname|a_loopfileshortpath|a_loopfilesize|a_loopfilesizekb|a_loopfilesizemb|a_loopfiletimeaccessed|a_loopfiletimecreated|a_loopfiletimemodified|a_loopreadline|a_loopregkey|a_loopregname|a_loopregsubkey|a_loopregtimemodified|a_loopregtype|a_mday|a_min|a_mm|a_mmm|a_mmmm|a_mon|a_mousedelay|a_msec|a_mydocuments|a_now|a_nowutc|a_numbatchlines|a_ostype|a_osversion|a_priorhotkey|a_priorkey|a_programfiles|a_programs|a_programscommon|a_ptrsize|a_regview|a_screendpi|a_screenheight|a_screenwidth|a_scriptdir|a_scriptfullpath|a_scripthwnd|a_scriptname|a_sec|a_space|a_startmenu|a_startmenucommon|a_startup|a_startupcommon|a_stringcasesense|a_tab|a_temp|a_thisfunc|a_thishotkey|a_thislabel|a_thismenu|a_thismenuitem|a_thismenuitempos|a_tickcount|a_timeidle|a_timeidlephysical|a_timesincepriorhotkey|a_timesincethishotkey|a_titlematchmode|a_titlematchmodespeed|a_username|a_wday|a_windelay|a_windir|a_workingdir|a_yday|a_year|a_yweek|a_yyyy|clipboard|clipboardall|comspec|errorlevel|programfiles)\b/i,builtin:/\b(?:abs|acos|asc|asin|atan|ceil|chr|class|comobjactive|comobjarray|comobjconnect|comobjcreate|comobjerror|comobjflags|comobjget|comobjquery|comobjtype|comobjvalue|cos|dllcall|exp|fileexist|Fileopen|floor|format|il_add|il_create|il_destroy|instr|isfunc|islabel|IsObject|ln|log|ltrim|lv_add|lv_delete|lv_deletecol|lv_getcount|lv_getnext|lv_gettext|lv_insert|lv_insertcol|lv_modify|lv_modifycol|lv_setimagelist|mod|numget|numput|onmessage|regexmatch|regexreplace|registercallback|round|rtrim|sb_seticon|sb_setparts|sb_settext|sin|sqrt|strlen|strreplace|strsplit|substr|tan|tv_add|tv_delete|tv_get|tv_getchild|tv_getcount|tv_getnext|tv_getparent|tv_getprev|tv_getselection|tv_gettext|tv_modify|varsetcapacity|winactive|winexist|__Call|__Get|__New|__Set)\b/i,symbol:/\b(?:alt|altdown|altup|appskey|backspace|browser_back|browser_favorites|browser_forward|browser_home|browser_refresh|browser_search|browser_stop|bs|capslock|ctrl|ctrlbreak|ctrldown|ctrlup|del|delete|down|end|enter|esc|escape|f1|f10|f11|f12|f13|f14|f15|f16|f17|f18|f19|f2|f20|f21|f22|f23|f24|f3|f4|f5|f6|f7|f8|f9|home|ins|insert|joy1|joy10|joy11|joy12|joy13|joy14|joy15|joy16|joy17|joy18|joy19|joy2|joy20|joy21|joy22|joy23|joy24|joy25|joy26|joy27|joy28|joy29|joy3|joy30|joy31|joy32|joy4|joy5|joy6|joy7|joy8|joy9|joyaxes|joybuttons|joyinfo|joyname|joypov|joyr|joyu|joyv|joyx|joyy|joyz|lalt|launch_app1|launch_app2|launch_mail|launch_media|lbutton|lcontrol|lctrl|left|lshift|lwin|lwindown|lwinup|mbutton|media_next|media_play_pause|media_prev|media_stop|numlock|numpad0|numpad1|numpad2|numpad3|numpad4|numpad5|numpad6|numpad7|numpad8|numpad9|numpadadd|numpadclear|numpaddel|numpaddiv|numpaddot|numpaddown|numpadend|numpadenter|numpadhome|numpadins|numpadleft|numpadmult|numpadpgdn|numpadpgup|numpadright|numpadsub|numpadup|pgdn|pgup|printscreen|ralt|rbutton|rcontrol|rctrl|right|rshift|rwin|rwindown|rwinup|scrolllock|shift|shiftdown|shiftup|space|tab|up|volume_down|volume_mute|volume_up|wheeldown|wheelleft|wheelright|wheelup|xbutton1|xbutton2)\b/i,important:/#\b(?:AllowSameLineComments|ClipboardTimeout|CommentFlag|DerefChar|ErrorStdOut|EscapeChar|HotkeyInterval|HotkeyModifierTimeout|Hotstring|If|IfTimeout|IfWinActive|IfWinExist|IfWinNotActive|IfWinNotExist|Include|IncludeAgain|InputLevel|InstallKeybdHook|InstallMouseHook|KeyHistory|MaxHotkeysPerInterval|MaxMem|MaxThreads|MaxThreadsBuffer|MaxThreadsPerHotkey|MenuMaskKey|NoEnv|NoTrayIcon|Persistent|SingleInstance|UseHook|Warn|WinActivateForce)\b/i,keyword:/\b(?:Abort|AboveNormal|Add|ahk_class|ahk_exe|ahk_group|ahk_id|ahk_pid|All|Alnum|Alpha|AltSubmit|AltTab|AltTabAndMenu|AltTabMenu|AltTabMenuDismiss|AlwaysOnTop|AutoSize|Background|BackgroundTrans|BelowNormal|between|BitAnd|BitNot|BitOr|BitShiftLeft|BitShiftRight|BitXOr|Bold|Border|Button|ByRef|Catch|Checkbox|Checked|CheckedGray|Choose|ChooseString|Close|Color|ComboBox|Contains|ControlList|Count|Date|DateTime|Days|DDL|Default|DeleteAll|Delimiter|Deref|Destroy|Digit|Disable|Disabled|DropDownList|Edit|Eject|Else|Enable|Enabled|Error|Exist|Expand|ExStyle|FileSystem|Finally|First|Flash|Float|FloatFast|Focus|Font|for|global|Grid|Group|GroupBox|GuiClose|GuiContextMenu|GuiDropFiles|GuiEscape|GuiSize|Hdr|Hidden|Hide|High|HKCC|HKCR|HKCU|HKEY_CLASSES_ROOT|HKEY_CURRENT_CONFIG|HKEY_CURRENT_USER|HKEY_LOCAL_MACHINE|HKEY_USERS|HKLM|HKU|Hours|HScroll|Icon|IconSmall|ID|IDLast|If|IfEqual|IfExist|IfGreater|IfGreaterOrEqual|IfInString|IfLess|IfLessOrEqual|IfMsgBox|IfNotEqual|IfNotExist|IfNotInString|IfWinActive|IfWinExist|IfWinNotActive|IfWinNotExist|Ignore|ImageList|in|Integer|IntegerFast|Interrupt|is|italic|Join|Label|LastFound|LastFoundExist|Limit|Lines|List|ListBox|ListView|local|Lock|Logoff|Low|Lower|Lowercase|MainWindow|Margin|Maximize|MaximizeBox|MaxSize|Minimize|MinimizeBox|MinMax|MinSize|Minutes|MonthCal|Mouse|Move|Multi|NA|No|NoActivate|NoDefault|NoHide|NoIcon|NoMainWindow|norm|Normal|NoSort|NoSortHdr|NoStandard|Not|NoTab|NoTimers|Number|Off|Ok|On|OwnDialogs|Owner|Parse|Password|Picture|Pixel|Pos|Pow|Priority|ProcessName|Radio|Range|Read|ReadOnly|Realtime|Redraw|Region|REG_BINARY|REG_DWORD|REG_EXPAND_SZ|REG_MULTI_SZ|REG_SZ|Relative|Rename|Report|Resize|Restore|Retry|RGB|Screen|Seconds|Section|Serial|SetLabel|ShiftAltTab|Show|Single|Slider|SortDesc|Standard|static|Status|StatusBar|StatusCD|strike|Style|Submit|SysMenu|Tab2|TabStop|Text|Theme|Throw|Tile|ToggleCheck|ToggleEnable|ToolWindow|Top|Topmost|TransColor|Transparent|Tray|TreeView|Try|TryAgain|Type|UnCheck|underline|Unicode|Unlock|Until|UpDown|Upper|Uppercase|UseErrorLevel|Vis|VisFirst|Visible|VScroll|Wait|WaitClose|WantCtrlA|WantF2|WantReturn|While|Wrap|Xdigit|xm|xp|xs|Yes|ym|yp|ys)\b/i,function:/[^(); \t,\n+*\-=?>:\\\/<&%\[\]]+(?=\()/,punctuation:/[{}[\]():,]/};
\ No newline at end of file
+Prism.languages.autohotkey={comment:[{pattern:/(^|\s);.*/,lookbehind:!0},{pattern:/(^[\t ]*)\/\*(?:[\r\n](?![ \t]*\*\/)|[^\r\n])*(?:[\r\n][ \t]*\*\/)?/m,lookbehind:!0,greedy:!0}],tag:{pattern:/^([ \t]*)[^\s,`":]+(?=:[ \t]*$)/m,lookbehind:!0},string:/"(?:[^"\n\r]|"")*"/,variable:/%\w+%/,number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee]-?\d+)?/,operator:/\?|\/\/?=?|:=|\|[=|]?|&[=&]?|\+[=+]?|-[=-]?|\*[=*]?|<(?:<=?|>|=)?|>>?=?|[.^!=~]=?|\b(?:AND|NOT|OR)\b/,boolean:/\b(?:false|true)\b/,command:{pattern:/\b(?:AutoTrim|BlockInput|Break|Click|ClipWait|Continue|Control|ControlClick|ControlFocus|ControlGet|ControlGetFocus|ControlGetPos|ControlGetText|ControlMove|ControlSend|ControlSendRaw|ControlSetText|CoordMode|Critical|DetectHiddenText|DetectHiddenWindows|Drive|DriveGet|DriveSpaceFree|EnvAdd|EnvDiv|EnvGet|EnvMult|EnvSet|EnvSub|EnvUpdate|Exit|ExitApp|FileAppend|FileCopy|FileCopyDir|FileCreateDir|FileCreateShortcut|FileDelete|FileEncoding|FileGetAttrib|FileGetShortcut|FileGetSize|FileGetTime|FileGetVersion|FileInstall|FileMove|FileMoveDir|FileRead|FileReadLine|FileRecycle|FileRecycleEmpty|FileRemoveDir|FileSelectFile|FileSelectFolder|FileSetAttrib|FileSetTime|FormatTime|GetKeyState|Gosub|Goto|GroupActivate|GroupAdd|GroupClose|GroupDeactivate|Gui|GuiControl|GuiControlGet|Hotkey|ImageSearch|IniDelete|IniRead|IniWrite|Input|InputBox|KeyWait|ListHotkeys|ListLines|ListVars|Loop|Menu|MouseClick|MouseClickDrag|MouseGetPos|MouseMove|MsgBox|OnExit|OutputDebug|Pause|PixelGetColor|PixelSearch|PostMessage|Process|Progress|Random|RegDelete|RegRead|RegWrite|Reload|Repeat|Return|Run|RunAs|RunWait|Send|SendEvent|SendInput|SendMessage|SendMode|SendPlay|SendRaw|SetBatchLines|SetCapslockState|SetControlDelay|SetDefaultMouseSpeed|SetEnv|SetFormat|SetKeyDelay|SetMouseDelay|SetNumlockState|SetRegView|SetScrollLockState|SetStoreCapslockMode|SetTimer|SetTitleMatchMode|SetWinDelay|SetWorkingDir|Shutdown|Sleep|Sort|SoundBeep|SoundGet|SoundGetWaveVolume|SoundPlay|SoundSet|SoundSetWaveVolume|SplashImage|SplashTextOff|SplashTextOn|SplitPath|StatusBarGetText|StatusBarWait|StringCaseSense|StringGetPos|StringLeft|StringLen|StringLower|StringMid|StringReplace|StringRight|StringSplit|StringTrimLeft|StringTrimRight|StringUpper|Suspend|SysGet|Thread|ToolTip|Transform|TrayTip|URLDownloadToFile|WinActivate|WinActivateBottom|WinClose|WinGet|WinGetActiveStats|WinGetActiveTitle|WinGetClass|WinGetPos|WinGetText|WinGetTitle|WinHide|WinKill|WinMaximize|WinMenuSelectItem|WinMinimize|WinMinimizeAll|WinMinimizeAllUndo|WinMove|WinRestore|WinSet|WinSetTitle|WinShow|WinWait|WinWaitActive|WinWaitClose|WinWaitNotActive)\b/i,alias:"selector"},constant:/\b(?:a_ahkpath|a_ahkversion|a_appdata|a_appdatacommon|a_autotrim|a_batchlines|a_caretx|a_carety|a_computername|a_controldelay|a_cursor|a_dd|a_ddd|a_dddd|a_defaultmousespeed|a_desktop|a_desktopcommon|a_detecthiddentext|a_detecthiddenwindows|a_endchar|a_eventinfo|a_exitreason|a_fileencoding|a_formatfloat|a_formatinteger|a_gui|a_guicontrol|a_guicontrolevent|a_guievent|a_guiheight|a_guiwidth|a_guix|a_guiy|a_hour|a_iconfile|a_iconhidden|a_iconnumber|a_icontip|a_index|a_ipaddress1|a_ipaddress2|a_ipaddress3|a_ipaddress4|a_is64bitos|a_isadmin|a_iscompiled|a_iscritical|a_ispaused|a_issuspended|a_isunicode|a_keydelay|a_language|a_lasterror|a_linefile|a_linenumber|a_loopfield|a_loopfileattrib|a_loopfiledir|a_loopfileext|a_loopfilefullpath|a_loopfilelongpath|a_loopfilename|a_loopfileshortname|a_loopfileshortpath|a_loopfilesize|a_loopfilesizekb|a_loopfilesizemb|a_loopfiletimeaccessed|a_loopfiletimecreated|a_loopfiletimemodified|a_loopreadline|a_loopregkey|a_loopregname|a_loopregsubkey|a_loopregtimemodified|a_loopregtype|a_mday|a_min|a_mm|a_mmm|a_mmmm|a_mon|a_mousedelay|a_msec|a_mydocuments|a_now|a_nowutc|a_numbatchlines|a_ostype|a_osversion|a_priorhotkey|a_priorkey|a_programfiles|a_programs|a_programscommon|a_ptrsize|a_regview|a_screendpi|a_screenheight|a_screenwidth|a_scriptdir|a_scriptfullpath|a_scripthwnd|a_scriptname|a_sec|a_space|a_startmenu|a_startmenucommon|a_startup|a_startupcommon|a_stringcasesense|a_tab|a_temp|a_thisfunc|a_thishotkey|a_thislabel|a_thismenu|a_thismenuitem|a_thismenuitempos|a_tickcount|a_timeidle|a_timeidlephysical|a_timesincepriorhotkey|a_timesincethishotkey|a_titlematchmode|a_titlematchmodespeed|a_username|a_wday|a_windelay|a_windir|a_workingdir|a_yday|a_year|a_yweek|a_yyyy|clipboard|clipboardall|comspec|errorlevel|programfiles)\b/i,builtin:/\b(?:abs|acos|asc|asin|atan|ceil|chr|class|comobjactive|comobjarray|comobjconnect|comobjcreate|comobjerror|comobjflags|comobjget|comobjquery|comobjtype|comobjvalue|cos|dllcall|exp|fileexist|Fileopen|floor|format|il_add|il_create|il_destroy|instr|isfunc|islabel|IsObject|ln|log|ltrim|lv_add|lv_delete|lv_deletecol|lv_getcount|lv_getnext|lv_gettext|lv_insert|lv_insertcol|lv_modify|lv_modifycol|lv_setimagelist|mod|numget|numput|onmessage|regexmatch|regexreplace|registercallback|round|rtrim|sb_seticon|sb_setparts|sb_settext|sin|sqrt|strlen|strreplace|strsplit|substr|tan|tv_add|tv_delete|tv_get|tv_getchild|tv_getcount|tv_getnext|tv_getparent|tv_getprev|tv_getselection|tv_gettext|tv_modify|varsetcapacity|winactive|winexist|__Call|__Get|__New|__Set)\b/i,symbol:/\b(?:alt|altdown|altup|appskey|backspace|browser_back|browser_favorites|browser_forward|browser_home|browser_refresh|browser_search|browser_stop|bs|capslock|ctrl|ctrlbreak|ctrldown|ctrlup|del|delete|down|end|enter|esc|escape|f1|f10|f11|f12|f13|f14|f15|f16|f17|f18|f19|f2|f20|f21|f22|f23|f24|f3|f4|f5|f6|f7|f8|f9|home|ins|insert|joy1|joy10|joy11|joy12|joy13|joy14|joy15|joy16|joy17|joy18|joy19|joy2|joy20|joy21|joy22|joy23|joy24|joy25|joy26|joy27|joy28|joy29|joy3|joy30|joy31|joy32|joy4|joy5|joy6|joy7|joy8|joy9|joyaxes|joybuttons|joyinfo|joyname|joypov|joyr|joyu|joyv|joyx|joyy|joyz|lalt|launch_app1|launch_app2|launch_mail|launch_media|lbutton|lcontrol|lctrl|left|lshift|lwin|lwindown|lwinup|mbutton|media_next|media_play_pause|media_prev|media_stop|numlock|numpad0|numpad1|numpad2|numpad3|numpad4|numpad5|numpad6|numpad7|numpad8|numpad9|numpadadd|numpadclear|numpaddel|numpaddiv|numpaddot|numpaddown|numpadend|numpadenter|numpadhome|numpadins|numpadleft|numpadmult|numpadpgdn|numpadpgup|numpadright|numpadsub|numpadup|pgdn|pgup|printscreen|ralt|rbutton|rcontrol|rctrl|right|rshift|rwin|rwindown|rwinup|scrolllock|shift|shiftdown|shiftup|space|tab|up|volume_down|volume_mute|volume_up|wheeldown|wheelleft|wheelright|wheelup|xbutton1|xbutton2)\b/i,directive:{pattern:/#[a-z]+\b/i,alias:"important"},keyword:/\b(?:Abort|AboveNormal|Add|ahk_class|ahk_exe|ahk_group|ahk_id|ahk_pid|All|Alnum|Alpha|AltSubmit|AltTab|AltTabAndMenu|AltTabMenu|AltTabMenuDismiss|AlwaysOnTop|AutoSize|Background|BackgroundTrans|BelowNormal|between|BitAnd|BitNot|BitOr|BitShiftLeft|BitShiftRight|BitXOr|Bold|Border|Button|ByRef|Catch|Checkbox|Checked|CheckedGray|Choose|ChooseString|Close|Color|ComboBox|Contains|ControlList|Count|Date|DateTime|Days|DDL|Default|DeleteAll|Delimiter|Deref|Destroy|Digit|Disable|Disabled|DropDownList|Edit|Eject|Else|Enable|Enabled|Error|Exist|Expand|ExStyle|FileSystem|Finally|First|Flash|Float|FloatFast|Focus|Font|for|global|Grid|Group|GroupBox|GuiClose|GuiContextMenu|GuiDropFiles|GuiEscape|GuiSize|Hdr|Hidden|Hide|High|HKCC|HKCR|HKCU|HKEY_CLASSES_ROOT|HKEY_CURRENT_CONFIG|HKEY_CURRENT_USER|HKEY_LOCAL_MACHINE|HKEY_USERS|HKLM|HKU|Hours|HScroll|Icon|IconSmall|ID|IDLast|If|IfEqual|IfExist|IfGreater|IfGreaterOrEqual|IfInString|IfLess|IfLessOrEqual|IfMsgBox|IfNotEqual|IfNotExist|IfNotInString|IfWinActive|IfWinExist|IfWinNotActive|IfWinNotExist|Ignore|ImageList|in|Integer|IntegerFast|Interrupt|is|italic|Join|Label|LastFound|LastFoundExist|Limit|Lines|List|ListBox|ListView|local|Lock|Logoff|Low|Lower|Lowercase|MainWindow|Margin|Maximize|MaximizeBox|MaxSize|Minimize|MinimizeBox|MinMax|MinSize|Minutes|MonthCal|Mouse|Move|Multi|NA|No|NoActivate|NoDefault|NoHide|NoIcon|NoMainWindow|norm|Normal|NoSort|NoSortHdr|NoStandard|Not|NoTab|NoTimers|Number|Off|Ok|On|OwnDialogs|Owner|Parse|Password|Picture|Pixel|Pos|Pow|Priority|ProcessName|Radio|Range|Read|ReadOnly|Realtime|Redraw|Region|REG_BINARY|REG_DWORD|REG_EXPAND_SZ|REG_MULTI_SZ|REG_SZ|Relative|Rename|Report|Resize|Restore|Retry|RGB|Screen|Seconds|Section|Serial|SetLabel|ShiftAltTab|Show|Single|Slider|SortDesc|Standard|static|Status|StatusBar|StatusCD|strike|Style|Submit|SysMenu|Tab2|TabStop|Text|Theme|Throw|Tile|ToggleCheck|ToggleEnable|ToolWindow|Top|Topmost|TransColor|Transparent|Tray|TreeView|Try|TryAgain|Type|UnCheck|underline|Unicode|Unlock|Until|UpDown|Upper|Uppercase|UseErrorLevel|Vis|VisFirst|Visible|VScroll|Wait|WaitClose|WantCtrlA|WantF2|WantReturn|While|Wrap|Xdigit|xm|xp|xs|Yes|ym|yp|ys)\b/i,function:/[^(); \t,\n+*\-=?>:\\\/<&%\[\]]+(?=\()/,punctuation:/[{}[\]():,]/};
\ No newline at end of file
diff --git a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-avisynth.min.js b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-avisynth.min.js
index 14a8b68e99..851807cf74 100644
--- a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-avisynth.min.js
+++ b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-avisynth.min.js
@@ -1 +1 @@
-!function(e){function a(e,a,r){return RegExp(function(e,r){return e.replace(/<<(\d+)>>/g,function(e,a){return r[+a]})}(e,a),r||"")}var r="bool|clip|float|int|string|val",t=[["is(?:bool|clip|float|int|string)|defined|(?:(?:internal)?function|var)?exists?","apply|assert|default|eval|import|nop|select|undefined","opt_(?:allowfloataudio|avipadscanlines|dwchannelmask|enable_(?:b64a|planartopackedrgb|v210|y3_10_10|y3_10_16)|usewaveextensible|vdubplanarhack)|set(?:cachemode|maxcpu|memorymax|planarlegacyalignment|workingdir)","hex(?:value)?|value","abs|ceil|continued(?:denominator|numerator)?|exp|floor|fmod|frac|log(?:10)?|max|min|muldiv|pi|pow|rand|round|sign|spline|sqrt","a?sinh?|a?cosh?|a?tan[2h]?","(?:bit(?:and|not|x?or|[lr]?shift[aslu]?|sh[lr]|sa[lr]|[lr]rotatel?|ro[rl]|te?st|set(?:count)?|cl(?:ea)?r|ch(?:an)?ge?))","average(?:[bgr]|chroma[uv]|luma)|(?:[rgb]|chroma[uv]|luma|rgb|[yuv](?=difference(?:fromprevious|tonext)))difference(?:fromprevious|tonext)?|[yuvrgb]plane(?:median|min|max|minmaxdifference)","getprocessinfo|logmsg|script(?:dir(?:utf8)?|file(?:utf8)?|name(?:utf8)?)|setlogparams","chr|(?:fill|find|left|mid|replace|rev|right)str|format|[lu]case|ord|str(?:cmpi?|fromutf8|len|toutf8)|time|trim(?:all|left|right)","isversionorgreater|version(?:number|string)","buildpixeltype|colorspacenametopixeltype","addautoloaddir|on(?:cpu|cuda)|prefetch|setfiltermtmode"].join("|"),["has(?:audio|video)","height|width","frame(?:count|rate)|framerate(?:denominator|numerator)","getparity|is(?:field|frame)based","bitspercomponent|componentsize|hasalpha|is(?:planar(?:rgba?)?|interleaved|rgb(?:24|32|48|64)?|y(?:8|u(?:va?|y2))?|yv(?:12|16|24|411)|420|422|444|packedrgb)|numcomponents|pixeltype","audio(?:bits|channels|duration|length(?:[fs]|hi|lo)?|rate)|isaudio(?:float|int)"].join("|"),["avi(?:file)?source|directshowsource|image(?:reader|source|sourceanim)|opendmlsource|segmented(?:avisource|directshowsource)|wavsource","coloryuv|convertbacktoyuy2|convertto(?:RGB(?:24|32|48|64)|(?:planar)?RGBA?|Y8?|YV(?:12|16|24|411)|YUVA?(?:411|420|422|444)|YUY2)|fixluminance|gr[ae]yscale|invert|levels|limiter|mergea?rgb|merge(?:chroma|luma)|rgbadjust|show(?:alpha|blue|green|red)|swapuv|tweak|[uv]toy8?|ytouv","(?:colorkey|reset)mask|layer|mask(?:hs)?|merge|overlay|subtract","addborders|(?:bicubic|bilinear|blackman|gauss|lanczos4|lanczos|point|sinc|spline(?:16|36|64))resize|crop(?:bottom)?|flip(?:horizontal|vertical)|(?:horizontal|vertical)?reduceby2|letterbox|skewrows|turn(?:180|left|right)","blur|fixbrokenchromaupsampling|generalconvolution|(?:spatial|temporal)soften|sharpen","trim|(?:un)?alignedsplice|(?:assume|assumescaled|change|convert)FPS|(?:delete|duplicate)frame|dissolve|fade(?:in|io|out)[02]?|freezeframe|interleave|loop|reverse|select(?:even|odd|(?:range)?every)","assume[bt]ff|assume(?:field|frame)based|bob|complementparity|doubleweave|peculiarblend|pulldown|separate(?:columns|fields|rows)|swapfields|weave(?:columns|rows)?","amplify(?:db)?|assumesamplerate|audiodub(?:ex)?|audiotrim|convertaudioto(?:(?:8|16|24|32)bit|float)|converttomono|delayaudio|ensurevbrmp3sync|get(?:left|right)?channel|kill(?:audio|video)|mergechannels|mixaudio|monotostereo|normalize|resampleaudio|ssrc|supereq|timestretch","animate|applyrange|conditional(?:filter|reader|select)|frameevaluate|scriptclip|tcp(?:server|source)|writefile(?:end|if|start)?","imagewriter","blackness|blankclip|colorbars(?:hd)?|compare|dumpfiltergraph|echo|histogram|info|messageclip|preroll|setgraphanalysis|show(?:framenumber|smpte|time)|showfiveversions|stack(?:horizontal|vertical)|subtitle|tone|version"].join("|")].join("|");e.languages.avisynth={comment:[{pattern:/(^|[^\\])\[\*(?:[^\[*]|\[(?!\*)|\*(?!\])|\[\*(?:[^\[*]|\[(?!\*)|\*(?!\]))*\*\])*\*\]/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\$])#.*/,lookbehind:!0,greedy:!0}],argument:{pattern:a('\\b(?:<<0>>)\\s+("?)\\w+\\1',[r],"i"),inside:{keyword:/^\w+/}},"argument-label":{pattern:/([,(][\s\\]*)\w+\s*=(?!=)/,lookbehind:!0,inside:{"argument-name":{pattern:/^\w+/,alias:"punctuation"},punctuation:/=$/}},string:[{pattern:/"""[\s\S]*?"""/,greedy:!0},{pattern:/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0,inside:{constant:{pattern:/\b(?:DEFAULT_MT_MODE|(?:MAINSCRIPT|PROGRAM|SCRIPT)DIR|(?:MACHINE|USER)_(?:CLASSIC|PLUS)_PLUGINS)\b/}}}],variable:/\b(?:last)\b/i,boolean:/\b(?:false|no|true|yes)\b/i,keyword:/\b(?:catch|else|for|function|global|if|return|try|while|__END__)\b/i,constant:/\bMT_(?:MULTI_INSTANCE|NICE_FILTER|SERIALIZED|SPECIAL_MT)\b/,"builtin-function":{pattern:a("\\b(?:<<0>>)\\b",[t],"i"),alias:"function"},"type-cast":{pattern:a("\\b(?:<<0>>)(?=\\s*\\()",[r],"i"),alias:"keyword"},function:{pattern:/\b[a-z_]\w*(?=\s*\()|(\.)[a-z_]\w*\b/i,lookbehind:!0},"line-continuation":{pattern:/(^[ \t]*)\\|\\(?=[ \t]*$)/m,lookbehind:!0,alias:"punctuation"},number:/\B\$(?:[\da-f]{6}|[\da-f]{8})\b|(?:(?:\b|\B-)\d+(?:\.\d*)?\b|\B\.\d+\b)/i,operator:/\+\+?|[!=<>]=?|&&|\|\||[?:*/%-]/,punctuation:/[{}\[\]();,.]/},e.languages.avs=e.languages.avisynth}(Prism);
\ No newline at end of file
+!function(e){function a(e,a,r){return RegExp(function(e,a){return e.replace(/<<(\d+)>>/g,(function(e,r){return a[+r]}))}(e,a),r||"")}var r="bool|clip|float|int|string|val",t=[["is(?:bool|clip|float|int|string)|defined|(?:(?:internal)?function|var)?exists?","apply|assert|default|eval|import|nop|select|undefined","opt_(?:allowfloataudio|avipadscanlines|dwchannelmask|enable_(?:b64a|planartopackedrgb|v210|y3_10_10|y3_10_16)|usewaveextensible|vdubplanarhack)|set(?:cachemode|maxcpu|memorymax|planarlegacyalignment|workingdir)","hex(?:value)?|value","abs|ceil|continued(?:denominator|numerator)?|exp|floor|fmod|frac|log(?:10)?|max|min|muldiv|pi|pow|rand|round|sign|spline|sqrt","a?sinh?|a?cosh?|a?tan[2h]?","(?:bit(?:and|not|x?or|[lr]?shift[aslu]?|sh[lr]|sa[lr]|[lr]rotatel?|ro[rl]|te?st|set(?:count)?|cl(?:ea)?r|ch(?:an)?ge?))","average(?:[bgr]|chroma[uv]|luma)|(?:[rgb]|chroma[uv]|luma|rgb|[yuv](?=difference(?:fromprevious|tonext)))difference(?:fromprevious|tonext)?|[yuvrgb]plane(?:median|min|max|minmaxdifference)","getprocessinfo|logmsg|script(?:dir(?:utf8)?|file(?:utf8)?|name(?:utf8)?)|setlogparams","chr|(?:fill|find|left|mid|replace|rev|right)str|format|[lu]case|ord|str(?:cmpi?|fromutf8|len|toutf8)|time|trim(?:all|left|right)","isversionorgreater|version(?:number|string)","buildpixeltype|colorspacenametopixeltype","addautoloaddir|on(?:cpu|cuda)|prefetch|setfiltermtmode"].join("|"),["has(?:audio|video)","height|width","frame(?:count|rate)|framerate(?:denominator|numerator)","getparity|is(?:field|frame)based","bitspercomponent|componentsize|hasalpha|is(?:planar(?:rgba?)?|interleaved|rgb(?:24|32|48|64)?|y(?:8|u(?:va?|y2))?|yv(?:12|16|24|411)|420|422|444|packedrgb)|numcomponents|pixeltype","audio(?:bits|channels|duration|length(?:[fs]|hi|lo)?|rate)|isaudio(?:float|int)"].join("|"),["avi(?:file)?source|directshowsource|image(?:reader|source|sourceanim)|opendmlsource|segmented(?:avisource|directshowsource)|wavsource","coloryuv|convertbacktoyuy2|convertto(?:RGB(?:24|32|48|64)|(?:planar)?RGBA?|Y8?|YV(?:12|16|24|411)|YUVA?(?:411|420|422|444)|YUY2)|fixluminance|gr[ae]yscale|invert|levels|limiter|mergea?rgb|merge(?:chroma|luma)|rgbadjust|show(?:alpha|blue|green|red)|swapuv|tweak|[uv]toy8?|ytouv","(?:colorkey|reset)mask|layer|mask(?:hs)?|merge|overlay|subtract","addborders|(?:bicubic|bilinear|blackman|gauss|lanczos4|lanczos|point|sinc|spline(?:16|36|64))resize|crop(?:bottom)?|flip(?:horizontal|vertical)|(?:horizontal|vertical)?reduceby2|letterbox|skewrows|turn(?:180|left|right)","blur|fixbrokenchromaupsampling|generalconvolution|(?:spatial|temporal)soften|sharpen","trim|(?:un)?alignedsplice|(?:assume|assumescaled|change|convert)FPS|(?:delete|duplicate)frame|dissolve|fade(?:in|io|out)[02]?|freezeframe|interleave|loop|reverse|select(?:even|odd|(?:range)?every)","assume[bt]ff|assume(?:field|frame)based|bob|complementparity|doubleweave|peculiarblend|pulldown|separate(?:columns|fields|rows)|swapfields|weave(?:columns|rows)?","amplify(?:db)?|assumesamplerate|audiodub(?:ex)?|audiotrim|convertaudioto(?:(?:8|16|24|32)bit|float)|converttomono|delayaudio|ensurevbrmp3sync|get(?:left|right)?channel|kill(?:audio|video)|mergechannels|mixaudio|monotostereo|normalize|resampleaudio|ssrc|supereq|timestretch","animate|applyrange|conditional(?:filter|reader|select)|frameevaluate|scriptclip|tcp(?:server|source)|writefile(?:end|if|start)?","imagewriter","blackness|blankclip|colorbars(?:hd)?|compare|dumpfiltergraph|echo|histogram|info|messageclip|preroll|setgraphanalysis|show(?:framenumber|smpte|time)|showfiveversions|stack(?:horizontal|vertical)|subtitle|tone|version"].join("|")].join("|");e.languages.avisynth={comment:[{pattern:/(^|[^\\])\[\*(?:[^\[*]|\[(?!\*)|\*(?!\])|\[\*(?:[^\[*]|\[(?!\*)|\*(?!\]))*\*\])*\*\]/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\$])#.*/,lookbehind:!0,greedy:!0}],argument:{pattern:a('\\b(?:<<0>>)\\s+("?)\\w+\\1',[r],"i"),inside:{keyword:/^\w+/}},"argument-label":{pattern:/([,(][\s\\]*)\w+\s*=(?!=)/,lookbehind:!0,inside:{"argument-name":{pattern:/^\w+/,alias:"punctuation"},punctuation:/=$/}},string:[{pattern:/"""[\s\S]*?"""/,greedy:!0},{pattern:/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0,inside:{constant:{pattern:/\b(?:DEFAULT_MT_MODE|(?:MAINSCRIPT|PROGRAM|SCRIPT)DIR|(?:MACHINE|USER)_(?:CLASSIC|PLUS)_PLUGINS)\b/}}}],variable:/\b(?:last)\b/i,boolean:/\b(?:false|no|true|yes)\b/i,keyword:/\b(?:catch|else|for|function|global|if|return|try|while|__END__)\b/i,constant:/\bMT_(?:MULTI_INSTANCE|NICE_FILTER|SERIALIZED|SPECIAL_MT)\b/,"builtin-function":{pattern:a("\\b(?:<<0>>)\\b",[t],"i"),alias:"function"},"type-cast":{pattern:a("\\b(?:<<0>>)(?=\\s*\\()",[r],"i"),alias:"keyword"},function:{pattern:/\b[a-z_]\w*(?=\s*\()|(\.)[a-z_]\w*\b/i,lookbehind:!0},"line-continuation":{pattern:/(^[ \t]*)\\|\\(?=[ \t]*$)/m,lookbehind:!0,alias:"punctuation"},number:/\B\$(?:[\da-f]{6}|[\da-f]{8})\b|(?:(?:\b|\B-)\d+(?:\.\d*)?\b|\B\.\d+\b)/i,operator:/\+\+?|[!=<>]=?|&&|\|\||[?:*/%-]/,punctuation:/[{}\[\]();,.]/},e.languages.avs=e.languages.avisynth}(Prism);
\ No newline at end of file
diff --git a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-awk.js b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-awk.js
new file mode 100644
index 0000000000..64cf2c0400
--- /dev/null
+++ b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-awk.js
@@ -0,0 +1,32 @@
+Prism.languages.awk = {
+ 'hashbang': {
+ pattern: /^#!.*/,
+ greedy: true,
+ alias: 'comment'
+ },
+ 'comment': {
+ pattern: /#.*/,
+ greedy: true
+ },
+ 'string': {
+ pattern: /(^|[^\\])"(?:[^\\"\r\n]|\\.)*"/,
+ lookbehind: true,
+ greedy: true
+ },
+ 'regex': {
+ pattern: /((?:^|[^\w\s)])\s*)\/(?:[^\/\\\r\n]|\\.)*\//,
+ lookbehind: true,
+ greedy: true
+ },
+
+ 'variable': /\$\w+/,
+ 'keyword': /\b(?:BEGIN|BEGINFILE|END|ENDFILE|break|case|continue|default|delete|do|else|exit|for|function|getline|if|in|next|nextfile|printf?|return|switch|while)\b|@(?:include|load)\b/,
+
+ 'function': /\b[a-z_]\w*(?=\s*\()/i,
+ 'number': /\b(?:\d+(?:\.\d+)?(?:e[+-]?\d+)?|0x[a-fA-F0-9]+)\b/,
+
+ 'operator': /--|\+\+|!?~|>&|>>|<<|(?:\*\*|[<>!=+\-*/%^])=?|&&|\|[|&]|[?:]/,
+ 'punctuation': /[()[\]{},;]/
+};
+
+Prism.languages.gawk = Prism.languages.awk;
diff --git a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-awk.min.js b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-awk.min.js
new file mode 100644
index 0000000000..c48925cdf3
--- /dev/null
+++ b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-awk.min.js
@@ -0,0 +1 @@
+Prism.languages.awk={hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},comment:{pattern:/#.*/,greedy:!0},string:{pattern:/(^|[^\\])"(?:[^\\"\r\n]|\\.)*"/,lookbehind:!0,greedy:!0},regex:{pattern:/((?:^|[^\w\s)])\s*)\/(?:[^\/\\\r\n]|\\.)*\//,lookbehind:!0,greedy:!0},variable:/\$\w+/,keyword:/\b(?:BEGIN|BEGINFILE|END|ENDFILE|break|case|continue|default|delete|do|else|exit|for|function|getline|if|in|next|nextfile|printf?|return|switch|while)\b|@(?:include|load)\b/,function:/\b[a-z_]\w*(?=\s*\()/i,number:/\b(?:\d+(?:\.\d+)?(?:e[+-]?\d+)?|0x[a-fA-F0-9]+)\b/,operator:/--|\+\+|!?~|>&|>>|<<|(?:\*\*|[<>!=+\-*/%^])=?|&&|\|[|&]|[?:]/,punctuation:/[()[\]{},;]/},Prism.languages.gawk=Prism.languages.awk;
\ No newline at end of file
diff --git a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-batch.min.js b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-batch.min.js
index f49a688dc4..886f10c7a2 100644
--- a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-batch.min.js
+++ b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-batch.min.js
@@ -1 +1 @@
-!function(e){var r=/%%?[~:\w]+%?|!\S+!/,t={pattern:/\/[a-z?]+(?=[ :]|$):?|-[a-z]\b|--[a-z-]+\b/im,alias:"attr-name",inside:{punctuation:/:/}},n=/"(?:[\\"]"|[^"])*"(?!")/,i=/(?:\b|-)\d+\b/;Prism.languages.batch={comment:[/^::.*/m,{pattern:/((?:^|[&(])[ \t]*)rem\b(?:[^^&)\r\n]|\^(?:\r\n|[\s\S]))*/im,lookbehind:!0}],label:{pattern:/^:.*/m,alias:"property"},command:[{pattern:/((?:^|[&(])[ \t]*)for(?: \/[a-z?](?:[ :](?:"[^"]*"|[^\s"/]\S*))?)* \S+ in \([^)]+\) do/im,lookbehind:!0,inside:{keyword:/\b(?:do|in)\b|^for\b/i,string:n,parameter:t,variable:r,number:i,punctuation:/[()',]/}},{pattern:/((?:^|[&(])[ \t]*)if(?: \/[a-z?](?:[ :](?:"[^"]*"|[^\s"/]\S*))?)* (?:not )?(?:cmdextversion \d+|defined \w+|errorlevel \d+|exist \S+|(?:"[^"]*"|(?!")(?:(?!==)\S)+)?(?:==| (?:equ|geq|gtr|leq|lss|neq) )(?:"[^"]*"|[^\s"]\S*))/im,lookbehind:!0,inside:{keyword:/\b(?:cmdextversion|defined|errorlevel|exist|not)\b|^if\b/i,string:n,parameter:t,variable:r,number:i,operator:/\^|==|\b(?:equ|geq|gtr|leq|lss|neq)\b/i}},{pattern:/((?:^|[&()])[ \t]*)else\b/im,lookbehind:!0,inside:{keyword:/^else\b/i}},{pattern:/((?:^|[&(])[ \t]*)set(?: \/[a-z](?:[ :](?:"[^"]*"|[^\s"/]\S*))?)* (?:[^^&)\r\n]|\^(?:\r\n|[\s\S]))*/im,lookbehind:!0,inside:{keyword:/^set\b/i,string:n,parameter:t,variable:[r,/\w+(?=(?:[*\/%+\-&^|]|<<|>>)?=)/],number:i,operator:/[*\/%+\-&^|]=?|<<=?|>>=?|[!~_=]/,punctuation:/[()',]/}},{pattern:/((?:^|[&(])[ \t]*@?)\w+\b(?:"(?:[\\"]"|[^"])*"(?!")|[^"^&)\r\n]|\^(?:\r\n|[\s\S]))*/m,lookbehind:!0,inside:{keyword:/^\w+\b/,string:n,parameter:t,label:{pattern:/(^\s*):\S+/m,lookbehind:!0,alias:"property"},variable:r,number:i,operator:/\^/}}],operator:/[&@]/,punctuation:/[()']/}}();
\ No newline at end of file
+!function(e){var r=/%%?[~:\w]+%?|!\S+!/,t={pattern:/\/[a-z?]+(?=[ :]|$):?|-[a-z]\b|--[a-z-]+\b/im,alias:"attr-name",inside:{punctuation:/:/}},n=/"(?:[\\"]"|[^"])*"(?!")/,i=/(?:\b|-)\d+\b/;e.languages.batch={comment:[/^::.*/m,{pattern:/((?:^|[&(])[ \t]*)rem\b(?:[^^&)\r\n]|\^(?:\r\n|[\s\S]))*/im,lookbehind:!0}],label:{pattern:/^:.*/m,alias:"property"},command:[{pattern:/((?:^|[&(])[ \t]*)for(?: \/[a-z?](?:[ :](?:"[^"]*"|[^\s"/]\S*))?)* \S+ in \([^)]+\) do/im,lookbehind:!0,inside:{keyword:/\b(?:do|in)\b|^for\b/i,string:n,parameter:t,variable:r,number:i,punctuation:/[()',]/}},{pattern:/((?:^|[&(])[ \t]*)if(?: \/[a-z?](?:[ :](?:"[^"]*"|[^\s"/]\S*))?)* (?:not )?(?:cmdextversion \d+|defined \w+|errorlevel \d+|exist \S+|(?:"[^"]*"|(?!")(?:(?!==)\S)+)?(?:==| (?:equ|geq|gtr|leq|lss|neq) )(?:"[^"]*"|[^\s"]\S*))/im,lookbehind:!0,inside:{keyword:/\b(?:cmdextversion|defined|errorlevel|exist|not)\b|^if\b/i,string:n,parameter:t,variable:r,number:i,operator:/\^|==|\b(?:equ|geq|gtr|leq|lss|neq)\b/i}},{pattern:/((?:^|[&()])[ \t]*)else\b/im,lookbehind:!0,inside:{keyword:/^else\b/i}},{pattern:/((?:^|[&(])[ \t]*)set(?: \/[a-z](?:[ :](?:"[^"]*"|[^\s"/]\S*))?)* (?:[^^&)\r\n]|\^(?:\r\n|[\s\S]))*/im,lookbehind:!0,inside:{keyword:/^set\b/i,string:n,parameter:t,variable:[r,/\w+(?=(?:[*\/%+\-&^|]|<<|>>)?=)/],number:i,operator:/[*\/%+\-&^|]=?|<<=?|>>=?|[!~_=]/,punctuation:/[()',]/}},{pattern:/((?:^|[&(])[ \t]*@?)\w+\b(?:"(?:[\\"]"|[^"])*"(?!")|[^"^&)\r\n]|\^(?:\r\n|[\s\S]))*/m,lookbehind:!0,inside:{keyword:/^\w+\b/,string:n,parameter:t,label:{pattern:/(^\s*):\S+/m,lookbehind:!0,alias:"property"},variable:r,number:i,operator:/\^/}}],operator:/[&@]/,punctuation:/[()']/}}(Prism);
\ No newline at end of file
diff --git a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-cfscript.js b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-cfscript.js
index e9fd550ec3..7f0cd97437 100644
--- a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-cfscript.js
+++ b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-cfscript.js
@@ -19,7 +19,7 @@ Prism.languages.cfscript = Prism.languages.extend('clike', {
],
'keyword': /\b(?:abstract|break|catch|component|continue|default|do|else|extends|final|finally|for|function|if|in|include|package|private|property|public|remote|required|rethrow|return|static|switch|throw|try|var|while|xml)\b(?!\s*=)/,
'operator': [
- /\+\+|--|&&|\|\||::|=>|[!=]==|<=?|>=?|[-+*/%&|^!=<>]=?|\?(?:\.|:)?|[?:]/,
+ /\+\+|--|&&|\|\||::|=>|[!=]==|[-+*/%&|^!=<>]=?|\?(?:\.|:)?|:/,
/\b(?:and|contains|eq|equal|eqv|gt|gte|imp|is|lt|lte|mod|not|or|xor)\b/
],
'scope': {
diff --git a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-cfscript.min.js b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-cfscript.min.js
index fcd8b79c7b..49dc2d0fef 100644
--- a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-cfscript.min.js
+++ b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-cfscript.min.js
@@ -1 +1 @@
-Prism.languages.cfscript=Prism.languages.extend("clike",{comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,inside:{annotation:{pattern:/(?:^|[^.])@[\w\.]+/,alias:"punctuation"}}},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],keyword:/\b(?:abstract|break|catch|component|continue|default|do|else|extends|final|finally|for|function|if|in|include|package|private|property|public|remote|required|rethrow|return|static|switch|throw|try|var|while|xml)\b(?!\s*=)/,operator:[/\+\+|--|&&|\|\||::|=>|[!=]==|<=?|>=?|[-+*/%&|^!=<>]=?|\?(?:\.|:)?|[?:]/,/\b(?:and|contains|eq|equal|eqv|gt|gte|imp|is|lt|lte|mod|not|or|xor)\b/],scope:{pattern:/\b(?:application|arguments|cgi|client|cookie|local|session|super|this|variables)\b/,alias:"global"},type:{pattern:/\b(?:any|array|binary|boolean|date|guid|numeric|query|string|struct|uuid|void|xml)\b/,alias:"builtin"}}),Prism.languages.insertBefore("cfscript","keyword",{"function-variable":{pattern:/[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"}}),delete Prism.languages.cfscript["class-name"],Prism.languages.cfc=Prism.languages.cfscript;
\ No newline at end of file
+Prism.languages.cfscript=Prism.languages.extend("clike",{comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,inside:{annotation:{pattern:/(?:^|[^.])@[\w\.]+/,alias:"punctuation"}}},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],keyword:/\b(?:abstract|break|catch|component|continue|default|do|else|extends|final|finally|for|function|if|in|include|package|private|property|public|remote|required|rethrow|return|static|switch|throw|try|var|while|xml)\b(?!\s*=)/,operator:[/\+\+|--|&&|\|\||::|=>|[!=]==|[-+*/%&|^!=<>]=?|\?(?:\.|:)?|:/,/\b(?:and|contains|eq|equal|eqv|gt|gte|imp|is|lt|lte|mod|not|or|xor)\b/],scope:{pattern:/\b(?:application|arguments|cgi|client|cookie|local|session|super|this|variables)\b/,alias:"global"},type:{pattern:/\b(?:any|array|binary|boolean|date|guid|numeric|query|string|struct|uuid|void|xml)\b/,alias:"builtin"}}),Prism.languages.insertBefore("cfscript","keyword",{"function-variable":{pattern:/[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"}}),delete Prism.languages.cfscript["class-name"],Prism.languages.cfc=Prism.languages.cfscript;
\ No newline at end of file
diff --git a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-cmake.js b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-cmake.js
index 464705bba7..4b71c84766 100644
--- a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-cmake.js
+++ b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-cmake.js
@@ -13,8 +13,8 @@ Prism.languages.cmake = {
}
}
},
- 'variable': /\b(?:CMAKE_\w+|\w+_(?:(?:BINARY|SOURCE)_DIR|DESCRIPTION|HOMEPAGE_URL|ROOT|VERSION(?:_MAJOR|_MINOR|_PATCH|_TWEAK)?)|(?:ANDROID|APPLE|BORLAND|BUILD_SHARED_LIBS|CACHE|CPACK_(?:ABSOLUTE_DESTINATION_FILES|COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY|ERROR_ON_ABSOLUTE_INSTALL_DESTINATION|INCLUDE_TOPLEVEL_DIRECTORY|INSTALL_DEFAULT_DIRECTORY_PERMISSIONS|INSTALL_SCRIPT|PACKAGING_INSTALL_PREFIX|SET_DESTDIR|WARN_ON_ABSOLUTE_INSTALL_DESTINATION)|CTEST_(?:BINARY_DIRECTORY|BUILD_COMMAND|BUILD_NAME|BZR_COMMAND|BZR_UPDATE_OPTIONS|CHANGE_ID|CHECKOUT_COMMAND|CONFIGURATION_TYPE|CONFIGURE_COMMAND|COVERAGE_COMMAND|COVERAGE_EXTRA_FLAGS|CURL_OPTIONS|CUSTOM_(?:COVERAGE_EXCLUDE|ERROR_EXCEPTION|ERROR_MATCH|ERROR_POST_CONTEXT|ERROR_PRE_CONTEXT|MAXIMUM_FAILED_TEST_OUTPUT_SIZE|MAXIMUM_NUMBER_OF_(?:ERRORS|WARNINGS)|MAXIMUM_PASSED_TEST_OUTPUT_SIZE|MEMCHECK_IGNORE|POST_MEMCHECK|POST_TEST|PRE_MEMCHECK|PRE_TEST|TESTS_IGNORE|WARNING_EXCEPTION|WARNING_MATCH)|CVS_CHECKOUT|CVS_COMMAND|CVS_UPDATE_OPTIONS|DROP_LOCATION|DROP_METHOD|DROP_SITE|DROP_SITE_CDASH|DROP_SITE_PASSWORD|DROP_SITE_USER|EXTRA_COVERAGE_GLOB|GIT_COMMAND|GIT_INIT_SUBMODULES|GIT_UPDATE_CUSTOM|GIT_UPDATE_OPTIONS|HG_COMMAND|HG_UPDATE_OPTIONS|LABELS_FOR_SUBPROJECTS|MEMORYCHECK_(?:COMMAND|COMMAND_OPTIONS|SANITIZER_OPTIONS|SUPPRESSIONS_FILE|TYPE)|NIGHTLY_START_TIME|P4_CLIENT|P4_COMMAND|P4_OPTIONS|P4_UPDATE_OPTIONS|RUN_CURRENT_SCRIPT|SCP_COMMAND|SITE|SOURCE_DIRECTORY|SUBMIT_URL|SVN_COMMAND|SVN_OPTIONS|SVN_UPDATE_OPTIONS|TEST_LOAD|TEST_TIMEOUT|TRIGGER_SITE|UPDATE_COMMAND|UPDATE_OPTIONS|UPDATE_VERSION_ONLY|USE_LAUNCHERS)|CYGWIN|ENV|EXECUTABLE_OUTPUT_PATH|GHS-MULTI|IOS|LIBRARY_OUTPUT_PATH|MINGW|MSVC(?:10|11|12|14|60|70|71|80|90|_IDE|_TOOLSET_VERSION|_VERSION)?|MSYS|PROJECT_(?:BINARY_DIR|DESCRIPTION|HOMEPAGE_URL|NAME|SOURCE_DIR|VERSION|VERSION_(?:MAJOR|MINOR|PATCH|TWEAK))|UNIX|WIN32|WINCE|WINDOWS_PHONE|WINDOWS_STORE|XCODE|XCODE_VERSION))\b/,
- 'property': /\b(?:cxx_\w+|(?:ARCHIVE_OUTPUT_(?:DIRECTORY|NAME)|COMPILE_DEFINITIONS|COMPILE_PDB_NAME|COMPILE_PDB_OUTPUT_DIRECTORY|EXCLUDE_FROM_DEFAULT_BUILD|IMPORTED_(?:IMPLIB|LIBNAME|LINK_DEPENDENT_LIBRARIES|LINK_INTERFACE_LANGUAGES|LINK_INTERFACE_LIBRARIES|LINK_INTERFACE_MULTIPLICITY|LOCATION|NO_SONAME|OBJECTS|SONAME)|INTERPROCEDURAL_OPTIMIZATION|LIBRARY_OUTPUT_DIRECTORY|LIBRARY_OUTPUT_NAME|LINK_FLAGS|LINK_INTERFACE_LIBRARIES|LINK_INTERFACE_MULTIPLICITY|LOCATION|MAP_IMPORTED_CONFIG|OSX_ARCHITECTURES|OUTPUT_NAME|PDB_NAME|PDB_OUTPUT_DIRECTORY|RUNTIME_OUTPUT_DIRECTORY|RUNTIME_OUTPUT_NAME|STATIC_LIBRARY_FLAGS|VS_CSHARP|VS_DOTNET_REFERENCEPROP|VS_DOTNET_REFERENCE|VS_GLOBAL_SECTION_POST|VS_GLOBAL_SECTION_PRE|VS_GLOBAL|XCODE_ATTRIBUTE)_\w+|\w+_(?:CLANG_TIDY|COMPILER_LAUNCHER|CPPCHECK|CPPLINT|INCLUDE_WHAT_YOU_USE|OUTPUT_NAME|POSTFIX|VISIBILITY_PRESET)|ABSTRACT|ADDITIONAL_MAKE_CLEAN_FILES|ADVANCED|ALIASED_TARGET|ALLOW_DUPLICATE_CUSTOM_TARGETS|ANDROID_(?:ANT_ADDITIONAL_OPTIONS|API|API_MIN|ARCH|ASSETS_DIRECTORIES|GUI|JAR_DEPENDENCIES|NATIVE_LIB_DEPENDENCIES|NATIVE_LIB_DIRECTORIES|PROCESS_MAX|PROGUARD|PROGUARD_CONFIG_PATH|SECURE_PROPS_PATH|SKIP_ANT_STEP|STL_TYPE)|ARCHIVE_OUTPUT_DIRECTORY|ATTACHED_FILES|ATTACHED_FILES_ON_FAIL|AUTOGEN_(?:BUILD_DIR|ORIGIN_DEPENDS|PARALLEL|SOURCE_GROUP|TARGETS_FOLDER|TARGET_DEPENDS)|AUTOMOC|AUTOMOC_(?:COMPILER_PREDEFINES|DEPEND_FILTERS|EXECUTABLE|MACRO_NAMES|MOC_OPTIONS|SOURCE_GROUP|TARGETS_FOLDER)|AUTORCC|AUTORCC_EXECUTABLE|AUTORCC_OPTIONS|AUTORCC_SOURCE_GROUP|AUTOUIC|AUTOUIC_EXECUTABLE|AUTOUIC_OPTIONS|AUTOUIC_SEARCH_PATHS|BINARY_DIR|BUILDSYSTEM_TARGETS|BUILD_RPATH|BUILD_RPATH_USE_ORIGIN|BUILD_WITH_INSTALL_NAME_DIR|BUILD_WITH_INSTALL_RPATH|BUNDLE|BUNDLE_EXTENSION|CACHE_VARIABLES|CLEAN_NO_CUSTOM|COMMON_LANGUAGE_RUNTIME|COMPATIBLE_INTERFACE_(?:BOOL|NUMBER_MAX|NUMBER_MIN|STRING)|COMPILE_(?:DEFINITIONS|FEATURES|FLAGS|OPTIONS|PDB_NAME|PDB_OUTPUT_DIRECTORY)|COST|CPACK_DESKTOP_SHORTCUTS|CPACK_NEVER_OVERWRITE|CPACK_PERMANENT|CPACK_STARTUP_SHORTCUTS|CPACK_START_MENU_SHORTCUTS|CPACK_WIX_ACL|CROSSCOMPILING_EMULATOR|CUDA_EXTENSIONS|CUDA_PTX_COMPILATION|CUDA_RESOLVE_DEVICE_SYMBOLS|CUDA_SEPARABLE_COMPILATION|CUDA_STANDARD|CUDA_STANDARD_REQUIRED|CXX_EXTENSIONS|CXX_STANDARD|CXX_STANDARD_REQUIRED|C_EXTENSIONS|C_STANDARD|C_STANDARD_REQUIRED|DEBUG_CONFIGURATIONS|DEFINE_SYMBOL|DEFINITIONS|DEPENDS|DEPLOYMENT_ADDITIONAL_FILES|DEPLOYMENT_REMOTE_DIRECTORY|DISABLED|DISABLED_FEATURES|ECLIPSE_EXTRA_CPROJECT_CONTENTS|ECLIPSE_EXTRA_NATURES|ENABLED_FEATURES|ENABLED_LANGUAGES|ENABLE_EXPORTS|ENVIRONMENT|EXCLUDE_FROM_ALL|EXCLUDE_FROM_DEFAULT_BUILD|EXPORT_NAME|EXPORT_PROPERTIES|EXTERNAL_OBJECT|EchoString|FAIL_REGULAR_EXPRESSION|FIND_LIBRARY_USE_LIB32_PATHS|FIND_LIBRARY_USE_LIB64_PATHS|FIND_LIBRARY_USE_LIBX32_PATHS|FIND_LIBRARY_USE_OPENBSD_VERSIONING|FIXTURES_CLEANUP|FIXTURES_REQUIRED|FIXTURES_SETUP|FOLDER|FRAMEWORK|Fortran_FORMAT|Fortran_MODULE_DIRECTORY|GENERATED|GENERATOR_FILE_NAME|GENERATOR_IS_MULTI_CONFIG|GHS_INTEGRITY_APP|GHS_NO_SOURCE_GROUP_FILE|GLOBAL_DEPENDS_DEBUG_MODE|GLOBAL_DEPENDS_NO_CYCLES|GNUtoMS|HAS_CXX|HEADER_FILE_ONLY|HELPSTRING|IMPLICIT_DEPENDS_INCLUDE_TRANSFORM|IMPORTED|IMPORTED_(?:COMMON_LANGUAGE_RUNTIME|CONFIGURATIONS|GLOBAL|IMPLIB|LIBNAME|LINK_DEPENDENT_LIBRARIES|LINK_INTERFACE_(?:LANGUAGES|LIBRARIES|MULTIPLICITY)|LOCATION|NO_SONAME|OBJECTS|SONAME)|IMPORT_PREFIX|IMPORT_SUFFIX|INCLUDE_DIRECTORIES|INCLUDE_REGULAR_EXPRESSION|INSTALL_NAME_DIR|INSTALL_RPATH|INSTALL_RPATH_USE_LINK_PATH|INTERFACE_(?:AUTOUIC_OPTIONS|COMPILE_DEFINITIONS|COMPILE_FEATURES|COMPILE_OPTIONS|INCLUDE_DIRECTORIES|LINK_DEPENDS|LINK_DIRECTORIES|LINK_LIBRARIES|LINK_OPTIONS|POSITION_INDEPENDENT_CODE|SOURCES|SYSTEM_INCLUDE_DIRECTORIES)|INTERPROCEDURAL_OPTIMIZATION|IN_TRY_COMPILE|IOS_INSTALL_COMBINED|JOB_POOLS|JOB_POOL_COMPILE|JOB_POOL_LINK|KEEP_EXTENSION|LABELS|LANGUAGE|LIBRARY_OUTPUT_DIRECTORY|LINKER_LANGUAGE|LINK_(?:DEPENDS|DEPENDS_NO_SHARED|DIRECTORIES|FLAGS|INTERFACE_LIBRARIES|INTERFACE_MULTIPLICITY|LIBRARIES|OPTIONS|SEARCH_END_STATIC|SEARCH_START_STATIC|WHAT_YOU_USE)|LISTFILE_STACK|LOCATION|MACOSX_BUNDLE|MACOSX_BUNDLE_INFO_PLIST|MACOSX_FRAMEWORK_INFO_PLIST|MACOSX_PACKAGE_LOCATION|MACOSX_RPATH|MACROS|MANUALLY_ADDED_DEPENDENCIES|MEASUREMENT|MODIFIED|NAME|NO_SONAME|NO_SYSTEM_FROM_IMPORTED|OBJECT_DEPENDS|OBJECT_OUTPUTS|OSX_ARCHITECTURES|OUTPUT_NAME|PACKAGES_FOUND|PACKAGES_NOT_FOUND|PARENT_DIRECTORY|PASS_REGULAR_EXPRESSION|PDB_NAME|PDB_OUTPUT_DIRECTORY|POSITION_INDEPENDENT_CODE|POST_INSTALL_SCRIPT|PREDEFINED_TARGETS_FOLDER|PREFIX|PRE_INSTALL_SCRIPT|PRIVATE_HEADER|PROCESSORS|PROCESSOR_AFFINITY|PROJECT_LABEL|PUBLIC_HEADER|REPORT_UNDEFINED_PROPERTIES|REQUIRED_FILES|RESOURCE|RESOURCE_LOCK|RULE_LAUNCH_COMPILE|RULE_LAUNCH_CUSTOM|RULE_LAUNCH_LINK|RULE_MESSAGES|RUNTIME_OUTPUT_DIRECTORY|RUN_SERIAL|SKIP_AUTOGEN|SKIP_AUTOMOC|SKIP_AUTORCC|SKIP_AUTOUIC|SKIP_BUILD_RPATH|SKIP_RETURN_CODE|SOURCES|SOURCE_DIR|SOVERSION|STATIC_LIBRARY_FLAGS|STATIC_LIBRARY_OPTIONS|STRINGS|SUBDIRECTORIES|SUFFIX|SYMBOLIC|TARGET_ARCHIVES_MAY_BE_SHARED_LIBS|TARGET_MESSAGES|TARGET_SUPPORTS_SHARED_LIBS|TESTS|TEST_INCLUDE_FILE|TEST_INCLUDE_FILES|TIMEOUT|TIMEOUT_AFTER_MATCH|TYPE|USE_FOLDERS|VALUE|VARIABLES|VERSION|VISIBILITY_INLINES_HIDDEN|VS_(?:CONFIGURATION_TYPE|COPY_TO_OUT_DIR|DEBUGGER_(?:COMMAND|COMMAND_ARGUMENTS|ENVIRONMENT|WORKING_DIRECTORY)|DEPLOYMENT_CONTENT|DEPLOYMENT_LOCATION|DOTNET_REFERENCES|DOTNET_REFERENCES_COPY_LOCAL|GLOBAL_KEYWORD|GLOBAL_PROJECT_TYPES|GLOBAL_ROOTNAMESPACE|INCLUDE_IN_VSIX|IOT_STARTUP_TASK|KEYWORD|RESOURCE_GENERATOR|SCC_AUXPATH|SCC_LOCALPATH|SCC_PROJECTNAME|SCC_PROVIDER|SDK_REFERENCES|SHADER_(?:DISABLE_OPTIMIZATIONS|ENABLE_DEBUG|ENTRYPOINT|FLAGS|MODEL|OBJECT_FILE_NAME|OUTPUT_HEADER_FILE|TYPE|VARIABLE_NAME)|STARTUP_PROJECT|TOOL_OVERRIDE|USER_PROPS|WINRT_COMPONENT|WINRT_EXTENSIONS|WINRT_REFERENCES|XAML_TYPE)|WILL_FAIL|WIN32_EXECUTABLE|WINDOWS_EXPORT_ALL_SYMBOLS|WORKING_DIRECTORY|WRAP_EXCLUDE|XCODE_(?:EMIT_EFFECTIVE_PLATFORM_NAME|EXPLICIT_FILE_TYPE|FILE_ATTRIBUTES|LAST_KNOWN_FILE_TYPE|PRODUCT_TYPE|SCHEME_(?:ADDRESS_SANITIZER|ADDRESS_SANITIZER_USE_AFTER_RETURN|ARGUMENTS|DISABLE_MAIN_THREAD_CHECKER|DYNAMIC_LIBRARY_LOADS|DYNAMIC_LINKER_API_USAGE|ENVIRONMENT|EXECUTABLE|GUARD_MALLOC|MAIN_THREAD_CHECKER_STOP|MALLOC_GUARD_EDGES|MALLOC_SCRIBBLE|MALLOC_STACK|THREAD_SANITIZER(?:_STOP)?|UNDEFINED_BEHAVIOUR_SANITIZER(?:_STOP)?|ZOMBIE_OBJECTS))|XCTEST)\b/,
+ 'variable': /\b(?:CMAKE_\w+|\w+_(?:(?:BINARY|SOURCE)_DIR|DESCRIPTION|HOMEPAGE_URL|ROOT|VERSION(?:_MAJOR|_MINOR|_PATCH|_TWEAK)?)|(?:ANDROID|APPLE|BORLAND|BUILD_SHARED_LIBS|CACHE|CPACK_(?:ABSOLUTE_DESTINATION_FILES|COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY|ERROR_ON_ABSOLUTE_INSTALL_DESTINATION|INCLUDE_TOPLEVEL_DIRECTORY|INSTALL_DEFAULT_DIRECTORY_PERMISSIONS|INSTALL_SCRIPT|PACKAGING_INSTALL_PREFIX|SET_DESTDIR|WARN_ON_ABSOLUTE_INSTALL_DESTINATION)|CTEST_(?:BINARY_DIRECTORY|BUILD_COMMAND|BUILD_NAME|BZR_COMMAND|BZR_UPDATE_OPTIONS|CHANGE_ID|CHECKOUT_COMMAND|CONFIGURATION_TYPE|CONFIGURE_COMMAND|COVERAGE_COMMAND|COVERAGE_EXTRA_FLAGS|CURL_OPTIONS|CUSTOM_(?:COVERAGE_EXCLUDE|ERROR_EXCEPTION|ERROR_MATCH|ERROR_POST_CONTEXT|ERROR_PRE_CONTEXT|MAXIMUM_FAILED_TEST_OUTPUT_SIZE|MAXIMUM_NUMBER_OF_(?:ERRORS|WARNINGS)|MAXIMUM_PASSED_TEST_OUTPUT_SIZE|MEMCHECK_IGNORE|POST_MEMCHECK|POST_TEST|PRE_MEMCHECK|PRE_TEST|TESTS_IGNORE|WARNING_EXCEPTION|WARNING_MATCH)|CVS_CHECKOUT|CVS_COMMAND|CVS_UPDATE_OPTIONS|DROP_LOCATION|DROP_METHOD|DROP_SITE|DROP_SITE_CDASH|DROP_SITE_PASSWORD|DROP_SITE_USER|EXTRA_COVERAGE_GLOB|GIT_COMMAND|GIT_INIT_SUBMODULES|GIT_UPDATE_CUSTOM|GIT_UPDATE_OPTIONS|HG_COMMAND|HG_UPDATE_OPTIONS|LABELS_FOR_SUBPROJECTS|MEMORYCHECK_(?:COMMAND|COMMAND_OPTIONS|SANITIZER_OPTIONS|SUPPRESSIONS_FILE|TYPE)|NIGHTLY_START_TIME|P4_CLIENT|P4_COMMAND|P4_OPTIONS|P4_UPDATE_OPTIONS|RUN_CURRENT_SCRIPT|SCP_COMMAND|SITE|SOURCE_DIRECTORY|SUBMIT_URL|SVN_COMMAND|SVN_OPTIONS|SVN_UPDATE_OPTIONS|TEST_LOAD|TEST_TIMEOUT|TRIGGER_SITE|UPDATE_COMMAND|UPDATE_OPTIONS|UPDATE_VERSION_ONLY|USE_LAUNCHERS)|CYGWIN|ENV|EXECUTABLE_OUTPUT_PATH|GHS-MULTI|IOS|LIBRARY_OUTPUT_PATH|MINGW|MSVC(?:10|11|12|14|60|70|71|80|90|_IDE|_TOOLSET_VERSION|_VERSION)?|MSYS|PROJECT_NAME|UNIX|WIN32|WINCE|WINDOWS_PHONE|WINDOWS_STORE|XCODE))\b/,
+ 'property': /\b(?:cxx_\w+|(?:ARCHIVE_OUTPUT_(?:DIRECTORY|NAME)|COMPILE_DEFINITIONS|COMPILE_PDB_NAME|COMPILE_PDB_OUTPUT_DIRECTORY|EXCLUDE_FROM_DEFAULT_BUILD|IMPORTED_(?:IMPLIB|LIBNAME|LINK_DEPENDENT_LIBRARIES|LINK_INTERFACE_LANGUAGES|LINK_INTERFACE_LIBRARIES|LINK_INTERFACE_MULTIPLICITY|LOCATION|NO_SONAME|OBJECTS|SONAME)|INTERPROCEDURAL_OPTIMIZATION|LIBRARY_OUTPUT_DIRECTORY|LIBRARY_OUTPUT_NAME|LINK_FLAGS|LINK_INTERFACE_LIBRARIES|LINK_INTERFACE_MULTIPLICITY|LOCATION|MAP_IMPORTED_CONFIG|OSX_ARCHITECTURES|OUTPUT_NAME|PDB_NAME|PDB_OUTPUT_DIRECTORY|RUNTIME_OUTPUT_DIRECTORY|RUNTIME_OUTPUT_NAME|STATIC_LIBRARY_FLAGS|VS_CSHARP|VS_DOTNET_REFERENCEPROP|VS_DOTNET_REFERENCE|VS_GLOBAL_SECTION_POST|VS_GLOBAL_SECTION_PRE|VS_GLOBAL|XCODE_ATTRIBUTE)_\w+|\w+_(?:CLANG_TIDY|COMPILER_LAUNCHER|CPPCHECK|CPPLINT|INCLUDE_WHAT_YOU_USE|OUTPUT_NAME|POSTFIX|VISIBILITY_PRESET)|ABSTRACT|ADDITIONAL_MAKE_CLEAN_FILES|ADVANCED|ALIASED_TARGET|ALLOW_DUPLICATE_CUSTOM_TARGETS|ANDROID_(?:ANT_ADDITIONAL_OPTIONS|API|API_MIN|ARCH|ASSETS_DIRECTORIES|GUI|JAR_DEPENDENCIES|NATIVE_LIB_DEPENDENCIES|NATIVE_LIB_DIRECTORIES|PROCESS_MAX|PROGUARD|PROGUARD_CONFIG_PATH|SECURE_PROPS_PATH|SKIP_ANT_STEP|STL_TYPE)|ARCHIVE_OUTPUT_DIRECTORY|ATTACHED_FILES|ATTACHED_FILES_ON_FAIL|AUTOGEN_(?:BUILD_DIR|ORIGIN_DEPENDS|PARALLEL|SOURCE_GROUP|TARGETS_FOLDER|TARGET_DEPENDS)|AUTOMOC|AUTOMOC_(?:COMPILER_PREDEFINES|DEPEND_FILTERS|EXECUTABLE|MACRO_NAMES|MOC_OPTIONS|SOURCE_GROUP|TARGETS_FOLDER)|AUTORCC|AUTORCC_EXECUTABLE|AUTORCC_OPTIONS|AUTORCC_SOURCE_GROUP|AUTOUIC|AUTOUIC_EXECUTABLE|AUTOUIC_OPTIONS|AUTOUIC_SEARCH_PATHS|BINARY_DIR|BUILDSYSTEM_TARGETS|BUILD_RPATH|BUILD_RPATH_USE_ORIGIN|BUILD_WITH_INSTALL_NAME_DIR|BUILD_WITH_INSTALL_RPATH|BUNDLE|BUNDLE_EXTENSION|CACHE_VARIABLES|CLEAN_NO_CUSTOM|COMMON_LANGUAGE_RUNTIME|COMPATIBLE_INTERFACE_(?:BOOL|NUMBER_MAX|NUMBER_MIN|STRING)|COMPILE_(?:DEFINITIONS|FEATURES|FLAGS|OPTIONS|PDB_NAME|PDB_OUTPUT_DIRECTORY)|COST|CPACK_DESKTOP_SHORTCUTS|CPACK_NEVER_OVERWRITE|CPACK_PERMANENT|CPACK_STARTUP_SHORTCUTS|CPACK_START_MENU_SHORTCUTS|CPACK_WIX_ACL|CROSSCOMPILING_EMULATOR|CUDA_EXTENSIONS|CUDA_PTX_COMPILATION|CUDA_RESOLVE_DEVICE_SYMBOLS|CUDA_SEPARABLE_COMPILATION|CUDA_STANDARD|CUDA_STANDARD_REQUIRED|CXX_EXTENSIONS|CXX_STANDARD|CXX_STANDARD_REQUIRED|C_EXTENSIONS|C_STANDARD|C_STANDARD_REQUIRED|DEBUG_CONFIGURATIONS|DEFINE_SYMBOL|DEFINITIONS|DEPENDS|DEPLOYMENT_ADDITIONAL_FILES|DEPLOYMENT_REMOTE_DIRECTORY|DISABLED|DISABLED_FEATURES|ECLIPSE_EXTRA_CPROJECT_CONTENTS|ECLIPSE_EXTRA_NATURES|ENABLED_FEATURES|ENABLED_LANGUAGES|ENABLE_EXPORTS|ENVIRONMENT|EXCLUDE_FROM_ALL|EXCLUDE_FROM_DEFAULT_BUILD|EXPORT_NAME|EXPORT_PROPERTIES|EXTERNAL_OBJECT|EchoString|FAIL_REGULAR_EXPRESSION|FIND_LIBRARY_USE_LIB32_PATHS|FIND_LIBRARY_USE_LIB64_PATHS|FIND_LIBRARY_USE_LIBX32_PATHS|FIND_LIBRARY_USE_OPENBSD_VERSIONING|FIXTURES_CLEANUP|FIXTURES_REQUIRED|FIXTURES_SETUP|FOLDER|FRAMEWORK|Fortran_FORMAT|Fortran_MODULE_DIRECTORY|GENERATED|GENERATOR_FILE_NAME|GENERATOR_IS_MULTI_CONFIG|GHS_INTEGRITY_APP|GHS_NO_SOURCE_GROUP_FILE|GLOBAL_DEPENDS_DEBUG_MODE|GLOBAL_DEPENDS_NO_CYCLES|GNUtoMS|HAS_CXX|HEADER_FILE_ONLY|HELPSTRING|IMPLICIT_DEPENDS_INCLUDE_TRANSFORM|IMPORTED|IMPORTED_(?:COMMON_LANGUAGE_RUNTIME|CONFIGURATIONS|GLOBAL|IMPLIB|LIBNAME|LINK_DEPENDENT_LIBRARIES|LINK_INTERFACE_(?:LANGUAGES|LIBRARIES|MULTIPLICITY)|LOCATION|NO_SONAME|OBJECTS|SONAME)|IMPORT_PREFIX|IMPORT_SUFFIX|INCLUDE_DIRECTORIES|INCLUDE_REGULAR_EXPRESSION|INSTALL_NAME_DIR|INSTALL_RPATH|INSTALL_RPATH_USE_LINK_PATH|INTERFACE_(?:AUTOUIC_OPTIONS|COMPILE_DEFINITIONS|COMPILE_FEATURES|COMPILE_OPTIONS|INCLUDE_DIRECTORIES|LINK_DEPENDS|LINK_DIRECTORIES|LINK_LIBRARIES|LINK_OPTIONS|POSITION_INDEPENDENT_CODE|SOURCES|SYSTEM_INCLUDE_DIRECTORIES)|INTERPROCEDURAL_OPTIMIZATION|IN_TRY_COMPILE|IOS_INSTALL_COMBINED|JOB_POOLS|JOB_POOL_COMPILE|JOB_POOL_LINK|KEEP_EXTENSION|LABELS|LANGUAGE|LIBRARY_OUTPUT_DIRECTORY|LINKER_LANGUAGE|LINK_(?:DEPENDS|DEPENDS_NO_SHARED|DIRECTORIES|FLAGS|INTERFACE_LIBRARIES|INTERFACE_MULTIPLICITY|LIBRARIES|OPTIONS|SEARCH_END_STATIC|SEARCH_START_STATIC|WHAT_YOU_USE)|LISTFILE_STACK|LOCATION|MACOSX_BUNDLE|MACOSX_BUNDLE_INFO_PLIST|MACOSX_FRAMEWORK_INFO_PLIST|MACOSX_PACKAGE_LOCATION|MACOSX_RPATH|MACROS|MANUALLY_ADDED_DEPENDENCIES|MEASUREMENT|MODIFIED|NAME|NO_SONAME|NO_SYSTEM_FROM_IMPORTED|OBJECT_DEPENDS|OBJECT_OUTPUTS|OSX_ARCHITECTURES|OUTPUT_NAME|PACKAGES_FOUND|PACKAGES_NOT_FOUND|PARENT_DIRECTORY|PASS_REGULAR_EXPRESSION|PDB_NAME|PDB_OUTPUT_DIRECTORY|POSITION_INDEPENDENT_CODE|POST_INSTALL_SCRIPT|PREDEFINED_TARGETS_FOLDER|PREFIX|PRE_INSTALL_SCRIPT|PRIVATE_HEADER|PROCESSORS|PROCESSOR_AFFINITY|PROJECT_LABEL|PUBLIC_HEADER|REPORT_UNDEFINED_PROPERTIES|REQUIRED_FILES|RESOURCE|RESOURCE_LOCK|RULE_LAUNCH_COMPILE|RULE_LAUNCH_CUSTOM|RULE_LAUNCH_LINK|RULE_MESSAGES|RUNTIME_OUTPUT_DIRECTORY|RUN_SERIAL|SKIP_AUTOGEN|SKIP_AUTOMOC|SKIP_AUTORCC|SKIP_AUTOUIC|SKIP_BUILD_RPATH|SKIP_RETURN_CODE|SOURCES|SOURCE_DIR|SOVERSION|STATIC_LIBRARY_FLAGS|STATIC_LIBRARY_OPTIONS|STRINGS|SUBDIRECTORIES|SUFFIX|SYMBOLIC|TARGET_ARCHIVES_MAY_BE_SHARED_LIBS|TARGET_MESSAGES|TARGET_SUPPORTS_SHARED_LIBS|TESTS|TEST_INCLUDE_FILE|TEST_INCLUDE_FILES|TIMEOUT|TIMEOUT_AFTER_MATCH|TYPE|USE_FOLDERS|VALUE|VARIABLES|VERSION|VISIBILITY_INLINES_HIDDEN|VS_(?:CONFIGURATION_TYPE|COPY_TO_OUT_DIR|DEBUGGER_(?:COMMAND|COMMAND_ARGUMENTS|ENVIRONMENT|WORKING_DIRECTORY)|DEPLOYMENT_CONTENT|DEPLOYMENT_LOCATION|DOTNET_REFERENCES|DOTNET_REFERENCES_COPY_LOCAL|INCLUDE_IN_VSIX|IOT_STARTUP_TASK|KEYWORD|RESOURCE_GENERATOR|SCC_AUXPATH|SCC_LOCALPATH|SCC_PROJECTNAME|SCC_PROVIDER|SDK_REFERENCES|SHADER_(?:DISABLE_OPTIMIZATIONS|ENABLE_DEBUG|ENTRYPOINT|FLAGS|MODEL|OBJECT_FILE_NAME|OUTPUT_HEADER_FILE|TYPE|VARIABLE_NAME)|STARTUP_PROJECT|TOOL_OVERRIDE|USER_PROPS|WINRT_COMPONENT|WINRT_EXTENSIONS|WINRT_REFERENCES|XAML_TYPE)|WILL_FAIL|WIN32_EXECUTABLE|WINDOWS_EXPORT_ALL_SYMBOLS|WORKING_DIRECTORY|WRAP_EXCLUDE|XCODE_(?:EMIT_EFFECTIVE_PLATFORM_NAME|EXPLICIT_FILE_TYPE|FILE_ATTRIBUTES|LAST_KNOWN_FILE_TYPE|PRODUCT_TYPE|SCHEME_(?:ADDRESS_SANITIZER|ADDRESS_SANITIZER_USE_AFTER_RETURN|ARGUMENTS|DISABLE_MAIN_THREAD_CHECKER|DYNAMIC_LIBRARY_LOADS|DYNAMIC_LINKER_API_USAGE|ENVIRONMENT|EXECUTABLE|GUARD_MALLOC|MAIN_THREAD_CHECKER_STOP|MALLOC_GUARD_EDGES|MALLOC_SCRIBBLE|MALLOC_STACK|THREAD_SANITIZER(?:_STOP)?|UNDEFINED_BEHAVIOUR_SANITIZER(?:_STOP)?|ZOMBIE_OBJECTS))|XCTEST)\b/,
'keyword': /\b(?:add_compile_definitions|add_compile_options|add_custom_command|add_custom_target|add_definitions|add_dependencies|add_executable|add_library|add_link_options|add_subdirectory|add_test|aux_source_directory|break|build_command|build_name|cmake_host_system_information|cmake_minimum_required|cmake_parse_arguments|cmake_policy|configure_file|continue|create_test_sourcelist|ctest_build|ctest_configure|ctest_coverage|ctest_empty_binary_directory|ctest_memcheck|ctest_read_custom_files|ctest_run_script|ctest_sleep|ctest_start|ctest_submit|ctest_test|ctest_update|ctest_upload|define_property|else|elseif|enable_language|enable_testing|endforeach|endfunction|endif|endmacro|endwhile|exec_program|execute_process|export|export_library_dependencies|file|find_file|find_library|find_package|find_path|find_program|fltk_wrap_ui|foreach|function|get_cmake_property|get_directory_property|get_filename_component|get_property|get_source_file_property|get_target_property|get_test_property|if|include|include_directories|include_external_msproject|include_guard|include_regular_expression|install|install_files|install_programs|install_targets|link_directories|link_libraries|list|load_cache|load_command|macro|make_directory|mark_as_advanced|math|message|option|output_required_files|project|qt_wrap_cpp|qt_wrap_ui|remove|remove_definitions|return|separate_arguments|set|set_directory_properties|set_property|set_source_files_properties|set_target_properties|set_tests_properties|site_name|source_group|string|subdir_depends|subdirs|target_compile_definitions|target_compile_features|target_compile_options|target_include_directories|target_link_directories|target_link_libraries|target_link_options|target_sources|try_compile|try_run|unset|use_mangled_mesa|utility_source|variable_requires|variable_watch|while|write_file)(?=\s*\()\b/,
'boolean': /\b(?:FALSE|OFF|ON|TRUE)\b/,
'namespace': /\b(?:INTERFACE|PRIVATE|PROPERTIES|PUBLIC|SHARED|STATIC|TARGET_OBJECTS)\b/,
diff --git a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-cmake.min.js b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-cmake.min.js
index 8455f5ccbf..a223df57be 100644
--- a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-cmake.min.js
+++ b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-cmake.min.js
@@ -1 +1 @@
-Prism.languages.cmake={comment:/#.*/,string:{pattern:/"(?:[^\\"]|\\.)*"/,greedy:!0,inside:{interpolation:{pattern:/\$\{(?:[^{}$]|\$\{[^{}$]*\})*\}/,inside:{punctuation:/\$\{|\}/,variable:/\w+/}}}},variable:/\b(?:CMAKE_\w+|\w+_(?:(?:BINARY|SOURCE)_DIR|DESCRIPTION|HOMEPAGE_URL|ROOT|VERSION(?:_MAJOR|_MINOR|_PATCH|_TWEAK)?)|(?:ANDROID|APPLE|BORLAND|BUILD_SHARED_LIBS|CACHE|CPACK_(?:ABSOLUTE_DESTINATION_FILES|COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY|ERROR_ON_ABSOLUTE_INSTALL_DESTINATION|INCLUDE_TOPLEVEL_DIRECTORY|INSTALL_DEFAULT_DIRECTORY_PERMISSIONS|INSTALL_SCRIPT|PACKAGING_INSTALL_PREFIX|SET_DESTDIR|WARN_ON_ABSOLUTE_INSTALL_DESTINATION)|CTEST_(?:BINARY_DIRECTORY|BUILD_COMMAND|BUILD_NAME|BZR_COMMAND|BZR_UPDATE_OPTIONS|CHANGE_ID|CHECKOUT_COMMAND|CONFIGURATION_TYPE|CONFIGURE_COMMAND|COVERAGE_COMMAND|COVERAGE_EXTRA_FLAGS|CURL_OPTIONS|CUSTOM_(?:COVERAGE_EXCLUDE|ERROR_EXCEPTION|ERROR_MATCH|ERROR_POST_CONTEXT|ERROR_PRE_CONTEXT|MAXIMUM_FAILED_TEST_OUTPUT_SIZE|MAXIMUM_NUMBER_OF_(?:ERRORS|WARNINGS)|MAXIMUM_PASSED_TEST_OUTPUT_SIZE|MEMCHECK_IGNORE|POST_MEMCHECK|POST_TEST|PRE_MEMCHECK|PRE_TEST|TESTS_IGNORE|WARNING_EXCEPTION|WARNING_MATCH)|CVS_CHECKOUT|CVS_COMMAND|CVS_UPDATE_OPTIONS|DROP_LOCATION|DROP_METHOD|DROP_SITE|DROP_SITE_CDASH|DROP_SITE_PASSWORD|DROP_SITE_USER|EXTRA_COVERAGE_GLOB|GIT_COMMAND|GIT_INIT_SUBMODULES|GIT_UPDATE_CUSTOM|GIT_UPDATE_OPTIONS|HG_COMMAND|HG_UPDATE_OPTIONS|LABELS_FOR_SUBPROJECTS|MEMORYCHECK_(?:COMMAND|COMMAND_OPTIONS|SANITIZER_OPTIONS|SUPPRESSIONS_FILE|TYPE)|NIGHTLY_START_TIME|P4_CLIENT|P4_COMMAND|P4_OPTIONS|P4_UPDATE_OPTIONS|RUN_CURRENT_SCRIPT|SCP_COMMAND|SITE|SOURCE_DIRECTORY|SUBMIT_URL|SVN_COMMAND|SVN_OPTIONS|SVN_UPDATE_OPTIONS|TEST_LOAD|TEST_TIMEOUT|TRIGGER_SITE|UPDATE_COMMAND|UPDATE_OPTIONS|UPDATE_VERSION_ONLY|USE_LAUNCHERS)|CYGWIN|ENV|EXECUTABLE_OUTPUT_PATH|GHS-MULTI|IOS|LIBRARY_OUTPUT_PATH|MINGW|MSVC(?:10|11|12|14|60|70|71|80|90|_IDE|_TOOLSET_VERSION|_VERSION)?|MSYS|PROJECT_(?:BINARY_DIR|DESCRIPTION|HOMEPAGE_URL|NAME|SOURCE_DIR|VERSION|VERSION_(?:MAJOR|MINOR|PATCH|TWEAK))|UNIX|WIN32|WINCE|WINDOWS_PHONE|WINDOWS_STORE|XCODE|XCODE_VERSION))\b/,property:/\b(?:cxx_\w+|(?:ARCHIVE_OUTPUT_(?:DIRECTORY|NAME)|COMPILE_DEFINITIONS|COMPILE_PDB_NAME|COMPILE_PDB_OUTPUT_DIRECTORY|EXCLUDE_FROM_DEFAULT_BUILD|IMPORTED_(?:IMPLIB|LIBNAME|LINK_DEPENDENT_LIBRARIES|LINK_INTERFACE_LANGUAGES|LINK_INTERFACE_LIBRARIES|LINK_INTERFACE_MULTIPLICITY|LOCATION|NO_SONAME|OBJECTS|SONAME)|INTERPROCEDURAL_OPTIMIZATION|LIBRARY_OUTPUT_DIRECTORY|LIBRARY_OUTPUT_NAME|LINK_FLAGS|LINK_INTERFACE_LIBRARIES|LINK_INTERFACE_MULTIPLICITY|LOCATION|MAP_IMPORTED_CONFIG|OSX_ARCHITECTURES|OUTPUT_NAME|PDB_NAME|PDB_OUTPUT_DIRECTORY|RUNTIME_OUTPUT_DIRECTORY|RUNTIME_OUTPUT_NAME|STATIC_LIBRARY_FLAGS|VS_CSHARP|VS_DOTNET_REFERENCEPROP|VS_DOTNET_REFERENCE|VS_GLOBAL_SECTION_POST|VS_GLOBAL_SECTION_PRE|VS_GLOBAL|XCODE_ATTRIBUTE)_\w+|\w+_(?:CLANG_TIDY|COMPILER_LAUNCHER|CPPCHECK|CPPLINT|INCLUDE_WHAT_YOU_USE|OUTPUT_NAME|POSTFIX|VISIBILITY_PRESET)|ABSTRACT|ADDITIONAL_MAKE_CLEAN_FILES|ADVANCED|ALIASED_TARGET|ALLOW_DUPLICATE_CUSTOM_TARGETS|ANDROID_(?:ANT_ADDITIONAL_OPTIONS|API|API_MIN|ARCH|ASSETS_DIRECTORIES|GUI|JAR_DEPENDENCIES|NATIVE_LIB_DEPENDENCIES|NATIVE_LIB_DIRECTORIES|PROCESS_MAX|PROGUARD|PROGUARD_CONFIG_PATH|SECURE_PROPS_PATH|SKIP_ANT_STEP|STL_TYPE)|ARCHIVE_OUTPUT_DIRECTORY|ATTACHED_FILES|ATTACHED_FILES_ON_FAIL|AUTOGEN_(?:BUILD_DIR|ORIGIN_DEPENDS|PARALLEL|SOURCE_GROUP|TARGETS_FOLDER|TARGET_DEPENDS)|AUTOMOC|AUTOMOC_(?:COMPILER_PREDEFINES|DEPEND_FILTERS|EXECUTABLE|MACRO_NAMES|MOC_OPTIONS|SOURCE_GROUP|TARGETS_FOLDER)|AUTORCC|AUTORCC_EXECUTABLE|AUTORCC_OPTIONS|AUTORCC_SOURCE_GROUP|AUTOUIC|AUTOUIC_EXECUTABLE|AUTOUIC_OPTIONS|AUTOUIC_SEARCH_PATHS|BINARY_DIR|BUILDSYSTEM_TARGETS|BUILD_RPATH|BUILD_RPATH_USE_ORIGIN|BUILD_WITH_INSTALL_NAME_DIR|BUILD_WITH_INSTALL_RPATH|BUNDLE|BUNDLE_EXTENSION|CACHE_VARIABLES|CLEAN_NO_CUSTOM|COMMON_LANGUAGE_RUNTIME|COMPATIBLE_INTERFACE_(?:BOOL|NUMBER_MAX|NUMBER_MIN|STRING)|COMPILE_(?:DEFINITIONS|FEATURES|FLAGS|OPTIONS|PDB_NAME|PDB_OUTPUT_DIRECTORY)|COST|CPACK_DESKTOP_SHORTCUTS|CPACK_NEVER_OVERWRITE|CPACK_PERMANENT|CPACK_STARTUP_SHORTCUTS|CPACK_START_MENU_SHORTCUTS|CPACK_WIX_ACL|CROSSCOMPILING_EMULATOR|CUDA_EXTENSIONS|CUDA_PTX_COMPILATION|CUDA_RESOLVE_DEVICE_SYMBOLS|CUDA_SEPARABLE_COMPILATION|CUDA_STANDARD|CUDA_STANDARD_REQUIRED|CXX_EXTENSIONS|CXX_STANDARD|CXX_STANDARD_REQUIRED|C_EXTENSIONS|C_STANDARD|C_STANDARD_REQUIRED|DEBUG_CONFIGURATIONS|DEFINE_SYMBOL|DEFINITIONS|DEPENDS|DEPLOYMENT_ADDITIONAL_FILES|DEPLOYMENT_REMOTE_DIRECTORY|DISABLED|DISABLED_FEATURES|ECLIPSE_EXTRA_CPROJECT_CONTENTS|ECLIPSE_EXTRA_NATURES|ENABLED_FEATURES|ENABLED_LANGUAGES|ENABLE_EXPORTS|ENVIRONMENT|EXCLUDE_FROM_ALL|EXCLUDE_FROM_DEFAULT_BUILD|EXPORT_NAME|EXPORT_PROPERTIES|EXTERNAL_OBJECT|EchoString|FAIL_REGULAR_EXPRESSION|FIND_LIBRARY_USE_LIB32_PATHS|FIND_LIBRARY_USE_LIB64_PATHS|FIND_LIBRARY_USE_LIBX32_PATHS|FIND_LIBRARY_USE_OPENBSD_VERSIONING|FIXTURES_CLEANUP|FIXTURES_REQUIRED|FIXTURES_SETUP|FOLDER|FRAMEWORK|Fortran_FORMAT|Fortran_MODULE_DIRECTORY|GENERATED|GENERATOR_FILE_NAME|GENERATOR_IS_MULTI_CONFIG|GHS_INTEGRITY_APP|GHS_NO_SOURCE_GROUP_FILE|GLOBAL_DEPENDS_DEBUG_MODE|GLOBAL_DEPENDS_NO_CYCLES|GNUtoMS|HAS_CXX|HEADER_FILE_ONLY|HELPSTRING|IMPLICIT_DEPENDS_INCLUDE_TRANSFORM|IMPORTED|IMPORTED_(?:COMMON_LANGUAGE_RUNTIME|CONFIGURATIONS|GLOBAL|IMPLIB|LIBNAME|LINK_DEPENDENT_LIBRARIES|LINK_INTERFACE_(?:LANGUAGES|LIBRARIES|MULTIPLICITY)|LOCATION|NO_SONAME|OBJECTS|SONAME)|IMPORT_PREFIX|IMPORT_SUFFIX|INCLUDE_DIRECTORIES|INCLUDE_REGULAR_EXPRESSION|INSTALL_NAME_DIR|INSTALL_RPATH|INSTALL_RPATH_USE_LINK_PATH|INTERFACE_(?:AUTOUIC_OPTIONS|COMPILE_DEFINITIONS|COMPILE_FEATURES|COMPILE_OPTIONS|INCLUDE_DIRECTORIES|LINK_DEPENDS|LINK_DIRECTORIES|LINK_LIBRARIES|LINK_OPTIONS|POSITION_INDEPENDENT_CODE|SOURCES|SYSTEM_INCLUDE_DIRECTORIES)|INTERPROCEDURAL_OPTIMIZATION|IN_TRY_COMPILE|IOS_INSTALL_COMBINED|JOB_POOLS|JOB_POOL_COMPILE|JOB_POOL_LINK|KEEP_EXTENSION|LABELS|LANGUAGE|LIBRARY_OUTPUT_DIRECTORY|LINKER_LANGUAGE|LINK_(?:DEPENDS|DEPENDS_NO_SHARED|DIRECTORIES|FLAGS|INTERFACE_LIBRARIES|INTERFACE_MULTIPLICITY|LIBRARIES|OPTIONS|SEARCH_END_STATIC|SEARCH_START_STATIC|WHAT_YOU_USE)|LISTFILE_STACK|LOCATION|MACOSX_BUNDLE|MACOSX_BUNDLE_INFO_PLIST|MACOSX_FRAMEWORK_INFO_PLIST|MACOSX_PACKAGE_LOCATION|MACOSX_RPATH|MACROS|MANUALLY_ADDED_DEPENDENCIES|MEASUREMENT|MODIFIED|NAME|NO_SONAME|NO_SYSTEM_FROM_IMPORTED|OBJECT_DEPENDS|OBJECT_OUTPUTS|OSX_ARCHITECTURES|OUTPUT_NAME|PACKAGES_FOUND|PACKAGES_NOT_FOUND|PARENT_DIRECTORY|PASS_REGULAR_EXPRESSION|PDB_NAME|PDB_OUTPUT_DIRECTORY|POSITION_INDEPENDENT_CODE|POST_INSTALL_SCRIPT|PREDEFINED_TARGETS_FOLDER|PREFIX|PRE_INSTALL_SCRIPT|PRIVATE_HEADER|PROCESSORS|PROCESSOR_AFFINITY|PROJECT_LABEL|PUBLIC_HEADER|REPORT_UNDEFINED_PROPERTIES|REQUIRED_FILES|RESOURCE|RESOURCE_LOCK|RULE_LAUNCH_COMPILE|RULE_LAUNCH_CUSTOM|RULE_LAUNCH_LINK|RULE_MESSAGES|RUNTIME_OUTPUT_DIRECTORY|RUN_SERIAL|SKIP_AUTOGEN|SKIP_AUTOMOC|SKIP_AUTORCC|SKIP_AUTOUIC|SKIP_BUILD_RPATH|SKIP_RETURN_CODE|SOURCES|SOURCE_DIR|SOVERSION|STATIC_LIBRARY_FLAGS|STATIC_LIBRARY_OPTIONS|STRINGS|SUBDIRECTORIES|SUFFIX|SYMBOLIC|TARGET_ARCHIVES_MAY_BE_SHARED_LIBS|TARGET_MESSAGES|TARGET_SUPPORTS_SHARED_LIBS|TESTS|TEST_INCLUDE_FILE|TEST_INCLUDE_FILES|TIMEOUT|TIMEOUT_AFTER_MATCH|TYPE|USE_FOLDERS|VALUE|VARIABLES|VERSION|VISIBILITY_INLINES_HIDDEN|VS_(?:CONFIGURATION_TYPE|COPY_TO_OUT_DIR|DEBUGGER_(?:COMMAND|COMMAND_ARGUMENTS|ENVIRONMENT|WORKING_DIRECTORY)|DEPLOYMENT_CONTENT|DEPLOYMENT_LOCATION|DOTNET_REFERENCES|DOTNET_REFERENCES_COPY_LOCAL|GLOBAL_KEYWORD|GLOBAL_PROJECT_TYPES|GLOBAL_ROOTNAMESPACE|INCLUDE_IN_VSIX|IOT_STARTUP_TASK|KEYWORD|RESOURCE_GENERATOR|SCC_AUXPATH|SCC_LOCALPATH|SCC_PROJECTNAME|SCC_PROVIDER|SDK_REFERENCES|SHADER_(?:DISABLE_OPTIMIZATIONS|ENABLE_DEBUG|ENTRYPOINT|FLAGS|MODEL|OBJECT_FILE_NAME|OUTPUT_HEADER_FILE|TYPE|VARIABLE_NAME)|STARTUP_PROJECT|TOOL_OVERRIDE|USER_PROPS|WINRT_COMPONENT|WINRT_EXTENSIONS|WINRT_REFERENCES|XAML_TYPE)|WILL_FAIL|WIN32_EXECUTABLE|WINDOWS_EXPORT_ALL_SYMBOLS|WORKING_DIRECTORY|WRAP_EXCLUDE|XCODE_(?:EMIT_EFFECTIVE_PLATFORM_NAME|EXPLICIT_FILE_TYPE|FILE_ATTRIBUTES|LAST_KNOWN_FILE_TYPE|PRODUCT_TYPE|SCHEME_(?:ADDRESS_SANITIZER|ADDRESS_SANITIZER_USE_AFTER_RETURN|ARGUMENTS|DISABLE_MAIN_THREAD_CHECKER|DYNAMIC_LIBRARY_LOADS|DYNAMIC_LINKER_API_USAGE|ENVIRONMENT|EXECUTABLE|GUARD_MALLOC|MAIN_THREAD_CHECKER_STOP|MALLOC_GUARD_EDGES|MALLOC_SCRIBBLE|MALLOC_STACK|THREAD_SANITIZER(?:_STOP)?|UNDEFINED_BEHAVIOUR_SANITIZER(?:_STOP)?|ZOMBIE_OBJECTS))|XCTEST)\b/,keyword:/\b(?:add_compile_definitions|add_compile_options|add_custom_command|add_custom_target|add_definitions|add_dependencies|add_executable|add_library|add_link_options|add_subdirectory|add_test|aux_source_directory|break|build_command|build_name|cmake_host_system_information|cmake_minimum_required|cmake_parse_arguments|cmake_policy|configure_file|continue|create_test_sourcelist|ctest_build|ctest_configure|ctest_coverage|ctest_empty_binary_directory|ctest_memcheck|ctest_read_custom_files|ctest_run_script|ctest_sleep|ctest_start|ctest_submit|ctest_test|ctest_update|ctest_upload|define_property|else|elseif|enable_language|enable_testing|endforeach|endfunction|endif|endmacro|endwhile|exec_program|execute_process|export|export_library_dependencies|file|find_file|find_library|find_package|find_path|find_program|fltk_wrap_ui|foreach|function|get_cmake_property|get_directory_property|get_filename_component|get_property|get_source_file_property|get_target_property|get_test_property|if|include|include_directories|include_external_msproject|include_guard|include_regular_expression|install|install_files|install_programs|install_targets|link_directories|link_libraries|list|load_cache|load_command|macro|make_directory|mark_as_advanced|math|message|option|output_required_files|project|qt_wrap_cpp|qt_wrap_ui|remove|remove_definitions|return|separate_arguments|set|set_directory_properties|set_property|set_source_files_properties|set_target_properties|set_tests_properties|site_name|source_group|string|subdir_depends|subdirs|target_compile_definitions|target_compile_features|target_compile_options|target_include_directories|target_link_directories|target_link_libraries|target_link_options|target_sources|try_compile|try_run|unset|use_mangled_mesa|utility_source|variable_requires|variable_watch|while|write_file)(?=\s*\()\b/,boolean:/\b(?:FALSE|OFF|ON|TRUE)\b/,namespace:/\b(?:INTERFACE|PRIVATE|PROPERTIES|PUBLIC|SHARED|STATIC|TARGET_OBJECTS)\b/,operator:/\b(?:AND|DEFINED|EQUAL|GREATER|LESS|MATCHES|NOT|OR|STREQUAL|STRGREATER|STRLESS|VERSION_EQUAL|VERSION_GREATER|VERSION_LESS)\b/,inserted:{pattern:/\b\w+::\w+\b/,alias:"class-name"},number:/\b\d+(?:\.\d+)*\b/,function:/\b[a-z_]\w*(?=\s*\()\b/i,punctuation:/[()>}]|\$[<{]/};
\ No newline at end of file
+Prism.languages.cmake={comment:/#.*/,string:{pattern:/"(?:[^\\"]|\\.)*"/,greedy:!0,inside:{interpolation:{pattern:/\$\{(?:[^{}$]|\$\{[^{}$]*\})*\}/,inside:{punctuation:/\$\{|\}/,variable:/\w+/}}}},variable:/\b(?:CMAKE_\w+|\w+_(?:(?:BINARY|SOURCE)_DIR|DESCRIPTION|HOMEPAGE_URL|ROOT|VERSION(?:_MAJOR|_MINOR|_PATCH|_TWEAK)?)|(?:ANDROID|APPLE|BORLAND|BUILD_SHARED_LIBS|CACHE|CPACK_(?:ABSOLUTE_DESTINATION_FILES|COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY|ERROR_ON_ABSOLUTE_INSTALL_DESTINATION|INCLUDE_TOPLEVEL_DIRECTORY|INSTALL_DEFAULT_DIRECTORY_PERMISSIONS|INSTALL_SCRIPT|PACKAGING_INSTALL_PREFIX|SET_DESTDIR|WARN_ON_ABSOLUTE_INSTALL_DESTINATION)|CTEST_(?:BINARY_DIRECTORY|BUILD_COMMAND|BUILD_NAME|BZR_COMMAND|BZR_UPDATE_OPTIONS|CHANGE_ID|CHECKOUT_COMMAND|CONFIGURATION_TYPE|CONFIGURE_COMMAND|COVERAGE_COMMAND|COVERAGE_EXTRA_FLAGS|CURL_OPTIONS|CUSTOM_(?:COVERAGE_EXCLUDE|ERROR_EXCEPTION|ERROR_MATCH|ERROR_POST_CONTEXT|ERROR_PRE_CONTEXT|MAXIMUM_FAILED_TEST_OUTPUT_SIZE|MAXIMUM_NUMBER_OF_(?:ERRORS|WARNINGS)|MAXIMUM_PASSED_TEST_OUTPUT_SIZE|MEMCHECK_IGNORE|POST_MEMCHECK|POST_TEST|PRE_MEMCHECK|PRE_TEST|TESTS_IGNORE|WARNING_EXCEPTION|WARNING_MATCH)|CVS_CHECKOUT|CVS_COMMAND|CVS_UPDATE_OPTIONS|DROP_LOCATION|DROP_METHOD|DROP_SITE|DROP_SITE_CDASH|DROP_SITE_PASSWORD|DROP_SITE_USER|EXTRA_COVERAGE_GLOB|GIT_COMMAND|GIT_INIT_SUBMODULES|GIT_UPDATE_CUSTOM|GIT_UPDATE_OPTIONS|HG_COMMAND|HG_UPDATE_OPTIONS|LABELS_FOR_SUBPROJECTS|MEMORYCHECK_(?:COMMAND|COMMAND_OPTIONS|SANITIZER_OPTIONS|SUPPRESSIONS_FILE|TYPE)|NIGHTLY_START_TIME|P4_CLIENT|P4_COMMAND|P4_OPTIONS|P4_UPDATE_OPTIONS|RUN_CURRENT_SCRIPT|SCP_COMMAND|SITE|SOURCE_DIRECTORY|SUBMIT_URL|SVN_COMMAND|SVN_OPTIONS|SVN_UPDATE_OPTIONS|TEST_LOAD|TEST_TIMEOUT|TRIGGER_SITE|UPDATE_COMMAND|UPDATE_OPTIONS|UPDATE_VERSION_ONLY|USE_LAUNCHERS)|CYGWIN|ENV|EXECUTABLE_OUTPUT_PATH|GHS-MULTI|IOS|LIBRARY_OUTPUT_PATH|MINGW|MSVC(?:10|11|12|14|60|70|71|80|90|_IDE|_TOOLSET_VERSION|_VERSION)?|MSYS|PROJECT_NAME|UNIX|WIN32|WINCE|WINDOWS_PHONE|WINDOWS_STORE|XCODE))\b/,property:/\b(?:cxx_\w+|(?:ARCHIVE_OUTPUT_(?:DIRECTORY|NAME)|COMPILE_DEFINITIONS|COMPILE_PDB_NAME|COMPILE_PDB_OUTPUT_DIRECTORY|EXCLUDE_FROM_DEFAULT_BUILD|IMPORTED_(?:IMPLIB|LIBNAME|LINK_DEPENDENT_LIBRARIES|LINK_INTERFACE_LANGUAGES|LINK_INTERFACE_LIBRARIES|LINK_INTERFACE_MULTIPLICITY|LOCATION|NO_SONAME|OBJECTS|SONAME)|INTERPROCEDURAL_OPTIMIZATION|LIBRARY_OUTPUT_DIRECTORY|LIBRARY_OUTPUT_NAME|LINK_FLAGS|LINK_INTERFACE_LIBRARIES|LINK_INTERFACE_MULTIPLICITY|LOCATION|MAP_IMPORTED_CONFIG|OSX_ARCHITECTURES|OUTPUT_NAME|PDB_NAME|PDB_OUTPUT_DIRECTORY|RUNTIME_OUTPUT_DIRECTORY|RUNTIME_OUTPUT_NAME|STATIC_LIBRARY_FLAGS|VS_CSHARP|VS_DOTNET_REFERENCEPROP|VS_DOTNET_REFERENCE|VS_GLOBAL_SECTION_POST|VS_GLOBAL_SECTION_PRE|VS_GLOBAL|XCODE_ATTRIBUTE)_\w+|\w+_(?:CLANG_TIDY|COMPILER_LAUNCHER|CPPCHECK|CPPLINT|INCLUDE_WHAT_YOU_USE|OUTPUT_NAME|POSTFIX|VISIBILITY_PRESET)|ABSTRACT|ADDITIONAL_MAKE_CLEAN_FILES|ADVANCED|ALIASED_TARGET|ALLOW_DUPLICATE_CUSTOM_TARGETS|ANDROID_(?:ANT_ADDITIONAL_OPTIONS|API|API_MIN|ARCH|ASSETS_DIRECTORIES|GUI|JAR_DEPENDENCIES|NATIVE_LIB_DEPENDENCIES|NATIVE_LIB_DIRECTORIES|PROCESS_MAX|PROGUARD|PROGUARD_CONFIG_PATH|SECURE_PROPS_PATH|SKIP_ANT_STEP|STL_TYPE)|ARCHIVE_OUTPUT_DIRECTORY|ATTACHED_FILES|ATTACHED_FILES_ON_FAIL|AUTOGEN_(?:BUILD_DIR|ORIGIN_DEPENDS|PARALLEL|SOURCE_GROUP|TARGETS_FOLDER|TARGET_DEPENDS)|AUTOMOC|AUTOMOC_(?:COMPILER_PREDEFINES|DEPEND_FILTERS|EXECUTABLE|MACRO_NAMES|MOC_OPTIONS|SOURCE_GROUP|TARGETS_FOLDER)|AUTORCC|AUTORCC_EXECUTABLE|AUTORCC_OPTIONS|AUTORCC_SOURCE_GROUP|AUTOUIC|AUTOUIC_EXECUTABLE|AUTOUIC_OPTIONS|AUTOUIC_SEARCH_PATHS|BINARY_DIR|BUILDSYSTEM_TARGETS|BUILD_RPATH|BUILD_RPATH_USE_ORIGIN|BUILD_WITH_INSTALL_NAME_DIR|BUILD_WITH_INSTALL_RPATH|BUNDLE|BUNDLE_EXTENSION|CACHE_VARIABLES|CLEAN_NO_CUSTOM|COMMON_LANGUAGE_RUNTIME|COMPATIBLE_INTERFACE_(?:BOOL|NUMBER_MAX|NUMBER_MIN|STRING)|COMPILE_(?:DEFINITIONS|FEATURES|FLAGS|OPTIONS|PDB_NAME|PDB_OUTPUT_DIRECTORY)|COST|CPACK_DESKTOP_SHORTCUTS|CPACK_NEVER_OVERWRITE|CPACK_PERMANENT|CPACK_STARTUP_SHORTCUTS|CPACK_START_MENU_SHORTCUTS|CPACK_WIX_ACL|CROSSCOMPILING_EMULATOR|CUDA_EXTENSIONS|CUDA_PTX_COMPILATION|CUDA_RESOLVE_DEVICE_SYMBOLS|CUDA_SEPARABLE_COMPILATION|CUDA_STANDARD|CUDA_STANDARD_REQUIRED|CXX_EXTENSIONS|CXX_STANDARD|CXX_STANDARD_REQUIRED|C_EXTENSIONS|C_STANDARD|C_STANDARD_REQUIRED|DEBUG_CONFIGURATIONS|DEFINE_SYMBOL|DEFINITIONS|DEPENDS|DEPLOYMENT_ADDITIONAL_FILES|DEPLOYMENT_REMOTE_DIRECTORY|DISABLED|DISABLED_FEATURES|ECLIPSE_EXTRA_CPROJECT_CONTENTS|ECLIPSE_EXTRA_NATURES|ENABLED_FEATURES|ENABLED_LANGUAGES|ENABLE_EXPORTS|ENVIRONMENT|EXCLUDE_FROM_ALL|EXCLUDE_FROM_DEFAULT_BUILD|EXPORT_NAME|EXPORT_PROPERTIES|EXTERNAL_OBJECT|EchoString|FAIL_REGULAR_EXPRESSION|FIND_LIBRARY_USE_LIB32_PATHS|FIND_LIBRARY_USE_LIB64_PATHS|FIND_LIBRARY_USE_LIBX32_PATHS|FIND_LIBRARY_USE_OPENBSD_VERSIONING|FIXTURES_CLEANUP|FIXTURES_REQUIRED|FIXTURES_SETUP|FOLDER|FRAMEWORK|Fortran_FORMAT|Fortran_MODULE_DIRECTORY|GENERATED|GENERATOR_FILE_NAME|GENERATOR_IS_MULTI_CONFIG|GHS_INTEGRITY_APP|GHS_NO_SOURCE_GROUP_FILE|GLOBAL_DEPENDS_DEBUG_MODE|GLOBAL_DEPENDS_NO_CYCLES|GNUtoMS|HAS_CXX|HEADER_FILE_ONLY|HELPSTRING|IMPLICIT_DEPENDS_INCLUDE_TRANSFORM|IMPORTED|IMPORTED_(?:COMMON_LANGUAGE_RUNTIME|CONFIGURATIONS|GLOBAL|IMPLIB|LIBNAME|LINK_DEPENDENT_LIBRARIES|LINK_INTERFACE_(?:LANGUAGES|LIBRARIES|MULTIPLICITY)|LOCATION|NO_SONAME|OBJECTS|SONAME)|IMPORT_PREFIX|IMPORT_SUFFIX|INCLUDE_DIRECTORIES|INCLUDE_REGULAR_EXPRESSION|INSTALL_NAME_DIR|INSTALL_RPATH|INSTALL_RPATH_USE_LINK_PATH|INTERFACE_(?:AUTOUIC_OPTIONS|COMPILE_DEFINITIONS|COMPILE_FEATURES|COMPILE_OPTIONS|INCLUDE_DIRECTORIES|LINK_DEPENDS|LINK_DIRECTORIES|LINK_LIBRARIES|LINK_OPTIONS|POSITION_INDEPENDENT_CODE|SOURCES|SYSTEM_INCLUDE_DIRECTORIES)|INTERPROCEDURAL_OPTIMIZATION|IN_TRY_COMPILE|IOS_INSTALL_COMBINED|JOB_POOLS|JOB_POOL_COMPILE|JOB_POOL_LINK|KEEP_EXTENSION|LABELS|LANGUAGE|LIBRARY_OUTPUT_DIRECTORY|LINKER_LANGUAGE|LINK_(?:DEPENDS|DEPENDS_NO_SHARED|DIRECTORIES|FLAGS|INTERFACE_LIBRARIES|INTERFACE_MULTIPLICITY|LIBRARIES|OPTIONS|SEARCH_END_STATIC|SEARCH_START_STATIC|WHAT_YOU_USE)|LISTFILE_STACK|LOCATION|MACOSX_BUNDLE|MACOSX_BUNDLE_INFO_PLIST|MACOSX_FRAMEWORK_INFO_PLIST|MACOSX_PACKAGE_LOCATION|MACOSX_RPATH|MACROS|MANUALLY_ADDED_DEPENDENCIES|MEASUREMENT|MODIFIED|NAME|NO_SONAME|NO_SYSTEM_FROM_IMPORTED|OBJECT_DEPENDS|OBJECT_OUTPUTS|OSX_ARCHITECTURES|OUTPUT_NAME|PACKAGES_FOUND|PACKAGES_NOT_FOUND|PARENT_DIRECTORY|PASS_REGULAR_EXPRESSION|PDB_NAME|PDB_OUTPUT_DIRECTORY|POSITION_INDEPENDENT_CODE|POST_INSTALL_SCRIPT|PREDEFINED_TARGETS_FOLDER|PREFIX|PRE_INSTALL_SCRIPT|PRIVATE_HEADER|PROCESSORS|PROCESSOR_AFFINITY|PROJECT_LABEL|PUBLIC_HEADER|REPORT_UNDEFINED_PROPERTIES|REQUIRED_FILES|RESOURCE|RESOURCE_LOCK|RULE_LAUNCH_COMPILE|RULE_LAUNCH_CUSTOM|RULE_LAUNCH_LINK|RULE_MESSAGES|RUNTIME_OUTPUT_DIRECTORY|RUN_SERIAL|SKIP_AUTOGEN|SKIP_AUTOMOC|SKIP_AUTORCC|SKIP_AUTOUIC|SKIP_BUILD_RPATH|SKIP_RETURN_CODE|SOURCES|SOURCE_DIR|SOVERSION|STATIC_LIBRARY_FLAGS|STATIC_LIBRARY_OPTIONS|STRINGS|SUBDIRECTORIES|SUFFIX|SYMBOLIC|TARGET_ARCHIVES_MAY_BE_SHARED_LIBS|TARGET_MESSAGES|TARGET_SUPPORTS_SHARED_LIBS|TESTS|TEST_INCLUDE_FILE|TEST_INCLUDE_FILES|TIMEOUT|TIMEOUT_AFTER_MATCH|TYPE|USE_FOLDERS|VALUE|VARIABLES|VERSION|VISIBILITY_INLINES_HIDDEN|VS_(?:CONFIGURATION_TYPE|COPY_TO_OUT_DIR|DEBUGGER_(?:COMMAND|COMMAND_ARGUMENTS|ENVIRONMENT|WORKING_DIRECTORY)|DEPLOYMENT_CONTENT|DEPLOYMENT_LOCATION|DOTNET_REFERENCES|DOTNET_REFERENCES_COPY_LOCAL|INCLUDE_IN_VSIX|IOT_STARTUP_TASK|KEYWORD|RESOURCE_GENERATOR|SCC_AUXPATH|SCC_LOCALPATH|SCC_PROJECTNAME|SCC_PROVIDER|SDK_REFERENCES|SHADER_(?:DISABLE_OPTIMIZATIONS|ENABLE_DEBUG|ENTRYPOINT|FLAGS|MODEL|OBJECT_FILE_NAME|OUTPUT_HEADER_FILE|TYPE|VARIABLE_NAME)|STARTUP_PROJECT|TOOL_OVERRIDE|USER_PROPS|WINRT_COMPONENT|WINRT_EXTENSIONS|WINRT_REFERENCES|XAML_TYPE)|WILL_FAIL|WIN32_EXECUTABLE|WINDOWS_EXPORT_ALL_SYMBOLS|WORKING_DIRECTORY|WRAP_EXCLUDE|XCODE_(?:EMIT_EFFECTIVE_PLATFORM_NAME|EXPLICIT_FILE_TYPE|FILE_ATTRIBUTES|LAST_KNOWN_FILE_TYPE|PRODUCT_TYPE|SCHEME_(?:ADDRESS_SANITIZER|ADDRESS_SANITIZER_USE_AFTER_RETURN|ARGUMENTS|DISABLE_MAIN_THREAD_CHECKER|DYNAMIC_LIBRARY_LOADS|DYNAMIC_LINKER_API_USAGE|ENVIRONMENT|EXECUTABLE|GUARD_MALLOC|MAIN_THREAD_CHECKER_STOP|MALLOC_GUARD_EDGES|MALLOC_SCRIBBLE|MALLOC_STACK|THREAD_SANITIZER(?:_STOP)?|UNDEFINED_BEHAVIOUR_SANITIZER(?:_STOP)?|ZOMBIE_OBJECTS))|XCTEST)\b/,keyword:/\b(?:add_compile_definitions|add_compile_options|add_custom_command|add_custom_target|add_definitions|add_dependencies|add_executable|add_library|add_link_options|add_subdirectory|add_test|aux_source_directory|break|build_command|build_name|cmake_host_system_information|cmake_minimum_required|cmake_parse_arguments|cmake_policy|configure_file|continue|create_test_sourcelist|ctest_build|ctest_configure|ctest_coverage|ctest_empty_binary_directory|ctest_memcheck|ctest_read_custom_files|ctest_run_script|ctest_sleep|ctest_start|ctest_submit|ctest_test|ctest_update|ctest_upload|define_property|else|elseif|enable_language|enable_testing|endforeach|endfunction|endif|endmacro|endwhile|exec_program|execute_process|export|export_library_dependencies|file|find_file|find_library|find_package|find_path|find_program|fltk_wrap_ui|foreach|function|get_cmake_property|get_directory_property|get_filename_component|get_property|get_source_file_property|get_target_property|get_test_property|if|include|include_directories|include_external_msproject|include_guard|include_regular_expression|install|install_files|install_programs|install_targets|link_directories|link_libraries|list|load_cache|load_command|macro|make_directory|mark_as_advanced|math|message|option|output_required_files|project|qt_wrap_cpp|qt_wrap_ui|remove|remove_definitions|return|separate_arguments|set|set_directory_properties|set_property|set_source_files_properties|set_target_properties|set_tests_properties|site_name|source_group|string|subdir_depends|subdirs|target_compile_definitions|target_compile_features|target_compile_options|target_include_directories|target_link_directories|target_link_libraries|target_link_options|target_sources|try_compile|try_run|unset|use_mangled_mesa|utility_source|variable_requires|variable_watch|while|write_file)(?=\s*\()\b/,boolean:/\b(?:FALSE|OFF|ON|TRUE)\b/,namespace:/\b(?:INTERFACE|PRIVATE|PROPERTIES|PUBLIC|SHARED|STATIC|TARGET_OBJECTS)\b/,operator:/\b(?:AND|DEFINED|EQUAL|GREATER|LESS|MATCHES|NOT|OR|STREQUAL|STRGREATER|STRLESS|VERSION_EQUAL|VERSION_GREATER|VERSION_LESS)\b/,inserted:{pattern:/\b\w+::\w+\b/,alias:"class-name"},number:/\b\d+(?:\.\d+)*\b/,function:/\b[a-z_]\w*(?=\s*\()\b/i,punctuation:/[()>}]|\$[<{]/};
\ No newline at end of file
diff --git a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-cooklang.js b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-cooklang.js
new file mode 100644
index 0000000000..cb49ed1260
--- /dev/null
+++ b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-cooklang.js
@@ -0,0 +1,146 @@
+(function (Prism) {
+
+ // see https://github.com/cooklang/spec/blob/main/EBNF.md
+
+ var single_token_suffix = /(?:(?!\s)[\d$+<=a-zA-Z\x80-\uFFFF])+/.source;
+ var multi_token_infix = /[^{}@#]+/.source;
+ var multi_token_suffix = /\{[^}#@]*\}/.source;
+
+ var multi_token = multi_token_infix + multi_token_suffix;
+
+ var timer_units = /(?:h|hours|hrs|m|min|minutes)/.source;
+
+ var amount_group_impl = {
+ pattern: /\{[^{}]*\}/,
+ inside: {
+ 'amount': {
+ pattern: /([\{|])[^{}|*%]+/,
+ lookbehind: true,
+ alias: 'number',
+ },
+ 'unit': {
+ pattern: /(%)[^}]+/,
+ lookbehind: true,
+ alias: 'symbol',
+ },
+ 'servings-scaler': {
+ pattern: /\*/,
+ alias: 'operator',
+ },
+ 'servings-alternative-separator': {
+ pattern: /\|/,
+ alias: 'operator',
+ },
+ 'unit-separator': {
+ pattern: /(?:%|(\*)%)/,
+ lookbehind: true,
+ alias: 'operator',
+ },
+ 'punctuation': /[{}]/,
+ }
+ };
+
+
+ Prism.languages.cooklang = {
+ 'comment': {
+ // [- comment -]
+ // -- comment
+ pattern: /\[-[\s\S]*?-\]|--.*/,
+ greedy: true,
+ },
+ 'meta': { // >> key: value
+ pattern: />>.*:.*/,
+ inside: {
+ 'property': { // key:
+ pattern: /(>>\s*)[^\s:](?:[^:]*[^\s:])?/,
+ lookbehind: true,
+ }
+ }
+ },
+ 'cookware-group': { // #...{...}, #...
+ pattern: new RegExp('#(?:'
+ + multi_token
+ + '|'
+ + single_token_suffix
+ + ')'
+ ),
+ inside: {
+ 'cookware': {
+ pattern: new RegExp('(^#)(?:'
+ + multi_token_infix
+ + ')'
+ ),
+ lookbehind: true,
+ alias: 'variable',
+ },
+ 'cookware-keyword': {
+ pattern: /^#/,
+ alias: 'keyword',
+ },
+ 'quantity-group': {
+ pattern: new RegExp(/\{[^{}@#]*\}/),
+ inside: {
+ 'quantity': {
+ pattern: new RegExp(/(^\{)/.source + multi_token_infix),
+ lookbehind: true,
+ alias: 'number',
+ },
+ 'punctuation': /[{}]/,
+ }
+ }
+ },
+ },
+ 'ingredient-group': { // @...{...}, @...
+ pattern: new RegExp('@(?:'
+ + multi_token
+ + '|'
+ + single_token_suffix
+ + ')'),
+ inside: {
+ 'ingredient': {
+ pattern: new RegExp('(^@)(?:'
+ + multi_token_infix
+ + ')'),
+ lookbehind: true,
+ alias: 'variable',
+ },
+ 'ingredient-keyword': {
+ pattern: /^@/,
+ alias: 'keyword',
+ },
+ 'amount-group': amount_group_impl,
+ }
+ },
+ 'timer-group': { // ~timer{...}
+ // eslint-disable-next-line regexp/sort-alternatives
+ pattern: /~(?!\s)[^@#~{}]*\{[^{}]*\}/,
+ inside: {
+ 'timer': {
+ pattern: /(^~)[^{]+/,
+ lookbehind: true,
+ alias: 'variable',
+ },
+ 'duration-group': { // {...}
+ pattern: /\{[^{}]*\}/,
+ inside: {
+ 'punctuation': /[{}]/,
+ 'unit': {
+ pattern: new RegExp(/(%\s*)/.source + timer_units + /\b/.source),
+ lookbehind: true,
+ alias: 'symbol',
+ },
+ 'operator': /%/,
+ 'duration': {
+ pattern: /\d+/,
+ alias: 'number',
+ },
+ }
+ },
+ 'timer-keyword': {
+ pattern: /^~/,
+ alias: 'keyword',
+ },
+ }
+ }
+ };
+}(Prism));
diff --git a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-cooklang.min.js b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-cooklang.min.js
new file mode 100644
index 0000000000..126fd8bfb1
--- /dev/null
+++ b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-cooklang.min.js
@@ -0,0 +1 @@
+!function(e){var a="(?:(?!\\s)[\\d$+<=a-zA-Z\\x80-\\uFFFF])+",t="[^{}@#]+\\{[^}#@]*\\}";e.languages.cooklang={comment:{pattern:/\[-[\s\S]*?-\]|--.*/,greedy:!0},meta:{pattern:/>>.*:.*/,inside:{property:{pattern:/(>>\s*)[^\s:](?:[^:]*[^\s:])?/,lookbehind:!0}}},"cookware-group":{pattern:new RegExp("#(?:"+t+"|"+a+")"),inside:{cookware:{pattern:new RegExp("(^#)(?:[^{}@#]+)"),lookbehind:!0,alias:"variable"},"cookware-keyword":{pattern:/^#/,alias:"keyword"},"quantity-group":{pattern:new RegExp(/\{[^{}@#]*\}/),inside:{quantity:{pattern:new RegExp("(^\\{)[^{}@#]+"),lookbehind:!0,alias:"number"},punctuation:/[{}]/}}}},"ingredient-group":{pattern:new RegExp("@(?:"+t+"|"+a+")"),inside:{ingredient:{pattern:new RegExp("(^@)(?:[^{}@#]+)"),lookbehind:!0,alias:"variable"},"ingredient-keyword":{pattern:/^@/,alias:"keyword"},"amount-group":{pattern:/\{[^{}]*\}/,inside:{amount:{pattern:/([\{|])[^{}|*%]+/,lookbehind:!0,alias:"number"},unit:{pattern:/(%)[^}]+/,lookbehind:!0,alias:"symbol"},"servings-scaler":{pattern:/\*/,alias:"operator"},"servings-alternative-separator":{pattern:/\|/,alias:"operator"},"unit-separator":{pattern:/(?:%|(\*)%)/,lookbehind:!0,alias:"operator"},punctuation:/[{}]/}}}},"timer-group":{pattern:/~(?!\s)[^@#~{}]*\{[^{}]*\}/,inside:{timer:{pattern:/(^~)[^{]+/,lookbehind:!0,alias:"variable"},"duration-group":{pattern:/\{[^{}]*\}/,inside:{punctuation:/[{}]/,unit:{pattern:new RegExp("(%\\s*)(?:h|hours|hrs|m|min|minutes)\\b"),lookbehind:!0,alias:"symbol"},operator:/%/,duration:{pattern:/\d+/,alias:"number"}}},"timer-keyword":{pattern:/^~/,alias:"keyword"}}}}}(Prism);
\ No newline at end of file
diff --git a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-coq.min.js b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-coq.min.js
index 8b297f5f07..c14f0027ab 100644
--- a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-coq.min.js
+++ b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-coq.min.js
@@ -1 +1 @@
-!function(e){for(var t="\\(\\*(?:[^(*]|\\((?!\\*)|\\*(?!\\))|)*\\*\\)",i=0;i<2;i++)t=t.replace(//g,function(){return t});t=t.replace(//g,"[]"),e.languages.coq={comment:RegExp(t),string:{pattern:/"(?:[^"]|"")*"(?!")/,greedy:!0},attribute:[{pattern:RegExp('#\\[(?:[^\\[\\]("]|"(?:[^"]|"")*"(?!")|\\((?!\\*)|)*\\]'.replace(//g,function(){return t})),greedy:!0,alias:"attr-name",inside:{comment:RegExp(t),string:{pattern:/"(?:[^"]|"")*"(?!")/,greedy:!0},operator:/=/,punctuation:/^#\[|\]$|[,()]/}},{pattern:/\b(?:Cumulative|Global|Local|Monomorphic|NonCumulative|Polymorphic|Private|Program)\b/,alias:"attr-name"}],keyword:/\b(?:Abort|About|Add|Admit|Admitted|All|Arguments|As|Assumptions|Axiom|Axioms|Back|BackTo|Backtrace|BinOp|BinOpSpec|BinRel|Bind|Blacklist|Canonical|Case|Cd|Check|Class|Classes|Close|CoFixpoint|CoInductive|Coercion|Coercions|Collection|Combined|Compute|Conjecture|Conjectures|Constant|Constants|Constraint|Constructors|Context|Corollary|Create|CstOp|Custom|Cut|Debug|Declare|Defined|Definition|Delimit|Dependencies|Dependent|Derive|Diffs|Drop|Elimination|End|Entry|Equality|Eval|Example|Existential|Existentials|Existing|Export|Extern|Extraction|Fact|Fail|Field|File|Firstorder|Fixpoint|Flags|Focus|From|Funclass|Function|Functional|GC|Generalizable|Goal|Grab|Grammar|Graph|Guarded|Haskell|Heap|Hide|Hint|HintDb|Hints|Hypotheses|Hypothesis|IF|Identity|Immediate|Implicit|Implicits|Import|Include|Induction|Inductive|Infix|Info|Initial|InjTyp|Inline|Inspect|Instance|Instances|Intro|Intros|Inversion|Inversion_clear|JSON|Language|Left|Lemma|Let|Lia|Libraries|Library|Load|LoadPath|Locate|Ltac|Ltac2|ML|Match|Method|Minimality|Module|Modules|Morphism|Next|NoInline|Notation|Number|OCaml|Obligation|Obligations|Opaque|Open|Optimize|Parameter|Parameters|Parametric|Path|Paths|Prenex|Preterm|Primitive|Print|Profile|Projections|Proof|Prop|PropBinOp|PropOp|PropUOp|Property|Proposition|Pwd|Qed|Quit|Rec|Record|Recursive|Redirect|Reduction|Register|Relation|Remark|Remove|Require|Reserved|Reset|Resolve|Restart|Rewrite|Right|Ring|Rings|SProp|Saturate|Save|Scheme|Scope|Scopes|Search|SearchHead|SearchPattern|SearchRewrite|Section|Separate|Set|Setoid|Show|Signatures|Solve|Solver|Sort|Sortclass|Sorted|Spec|Step|Strategies|Strategy|String|Structure|SubClass|Subgraph|SuchThat|Tactic|Term|TestCompile|Theorem|Time|Timeout|To|Transparent|Type|Typeclasses|Types|Typing|UnOp|UnOpSpec|Undelimit|Undo|Unfocus|Unfocused|Unfold|Universe|Universes|Unshelve|Variable|Variables|Variant|Verbose|View|Visibility|Zify|_|apply|as|at|by|cofix|else|end|exists|exists2|fix|for|forall|fun|if|in|let|match|measure|move|removed|return|struct|then|using|wf|where|with)\b/,number:/\b(?:0x[a-f0-9][a-f0-9_]*(?:\.[a-f0-9_]+)?(?:p[+-]?\d[\d_]*)?|\d[\d_]*(?:\.[\d_]+)?(?:e[+-]?\d[\d_]*)?)\b/i,punct:{pattern:/@\{|\{\||\[=|:>/,alias:"punctuation"},operator:/\/\\|\\\/|\.{2,3}|:{1,2}=|\*\*|[-=]>|<(?:->?|[+:=>]|<:)|>(?:=|->)|\|[-|]?|[-!%&*+/<=>?@^~']/,punctuation:/\.\(|`\(|@\{|`\{|\{\||\[=|:>|[:.,;(){}\[\]]/}}(Prism);
\ No newline at end of file
+!function(e){for(var t="\\(\\*(?:[^(*]|\\((?!\\*)|\\*(?!\\))|)*\\*\\)",i=0;i<2;i++)t=t.replace(//g,(function(){return t}));t=t.replace(//g,"[]"),e.languages.coq={comment:RegExp(t),string:{pattern:/"(?:[^"]|"")*"(?!")/,greedy:!0},attribute:[{pattern:RegExp('#\\[(?:[^\\[\\]("]|"(?:[^"]|"")*"(?!")|\\((?!\\*)|)*\\]'.replace(//g,(function(){return t}))),greedy:!0,alias:"attr-name",inside:{comment:RegExp(t),string:{pattern:/"(?:[^"]|"")*"(?!")/,greedy:!0},operator:/=/,punctuation:/^#\[|\]$|[,()]/}},{pattern:/\b(?:Cumulative|Global|Local|Monomorphic|NonCumulative|Polymorphic|Private|Program)\b/,alias:"attr-name"}],keyword:/\b(?:Abort|About|Add|Admit|Admitted|All|Arguments|As|Assumptions|Axiom|Axioms|Back|BackTo|Backtrace|BinOp|BinOpSpec|BinRel|Bind|Blacklist|Canonical|Case|Cd|Check|Class|Classes|Close|CoFixpoint|CoInductive|Coercion|Coercions|Collection|Combined|Compute|Conjecture|Conjectures|Constant|Constants|Constraint|Constructors|Context|Corollary|Create|CstOp|Custom|Cut|Debug|Declare|Defined|Definition|Delimit|Dependencies|Dependent|Derive|Diffs|Drop|Elimination|End|Entry|Equality|Eval|Example|Existential|Existentials|Existing|Export|Extern|Extraction|Fact|Fail|Field|File|Firstorder|Fixpoint|Flags|Focus|From|Funclass|Function|Functional|GC|Generalizable|Goal|Grab|Grammar|Graph|Guarded|Haskell|Heap|Hide|Hint|HintDb|Hints|Hypotheses|Hypothesis|IF|Identity|Immediate|Implicit|Implicits|Import|Include|Induction|Inductive|Infix|Info|Initial|InjTyp|Inline|Inspect|Instance|Instances|Intro|Intros|Inversion|Inversion_clear|JSON|Language|Left|Lemma|Let|Lia|Libraries|Library|Load|LoadPath|Locate|Ltac|Ltac2|ML|Match|Method|Minimality|Module|Modules|Morphism|Next|NoInline|Notation|Number|OCaml|Obligation|Obligations|Opaque|Open|Optimize|Parameter|Parameters|Parametric|Path|Paths|Prenex|Preterm|Primitive|Print|Profile|Projections|Proof|Prop|PropBinOp|PropOp|PropUOp|Property|Proposition|Pwd|Qed|Quit|Rec|Record|Recursive|Redirect|Reduction|Register|Relation|Remark|Remove|Require|Reserved|Reset|Resolve|Restart|Rewrite|Right|Ring|Rings|SProp|Saturate|Save|Scheme|Scope|Scopes|Search|SearchHead|SearchPattern|SearchRewrite|Section|Separate|Set|Setoid|Show|Signatures|Solve|Solver|Sort|Sortclass|Sorted|Spec|Step|Strategies|Strategy|String|Structure|SubClass|Subgraph|SuchThat|Tactic|Term|TestCompile|Theorem|Time|Timeout|To|Transparent|Type|Typeclasses|Types|Typing|UnOp|UnOpSpec|Undelimit|Undo|Unfocus|Unfocused|Unfold|Universe|Universes|Unshelve|Variable|Variables|Variant|Verbose|View|Visibility|Zify|_|apply|as|at|by|cofix|else|end|exists|exists2|fix|for|forall|fun|if|in|let|match|measure|move|removed|return|struct|then|using|wf|where|with)\b/,number:/\b(?:0x[a-f0-9][a-f0-9_]*(?:\.[a-f0-9_]+)?(?:p[+-]?\d[\d_]*)?|\d[\d_]*(?:\.[\d_]+)?(?:e[+-]?\d[\d_]*)?)\b/i,punct:{pattern:/@\{|\{\||\[=|:>/,alias:"punctuation"},operator:/\/\\|\\\/|\.{2,3}|:{1,2}=|\*\*|[-=]>|<(?:->?|[+:=>]|<:)|>(?:=|->)|\|[-|]?|[-!%&*+/<=>?@^~']/,punctuation:/\.\(|`\(|@\{|`\{|\{\||\[=|:>|[:.,;(){}\[\]]/}}(Prism);
\ No newline at end of file
diff --git a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-core.min.js b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-core.min.js
index eedbcf6e25..2e3ac2eefe 100644
--- a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-core.min.js
+++ b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-core.min.js
@@ -1 +1 @@
-var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(u){var t=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,n=0,e={},M={manual:u.Prism&&u.Prism.manual,disableWorkerMessageHandler:u.Prism&&u.Prism.disableWorkerMessageHandler,util:{encode:function e(n){return n instanceof W?new W(n.type,e(n.content),n.alias):Array.isArray(n)?n.map(e):n.replace(/&/g,"&").replace(/=l.reach);y+=m.value.length,m=m.next){var k=m.value;if(t.length>n.length)return;if(!(k instanceof W)){var x,b=1;if(h){if(!(x=z(p,y,n,f))||x.index>=n.length)break;var w=x.index,A=x.index+x[0].length,E=y;for(E+=m.value.length;E<=w;)m=m.next,E+=m.value.length;if(E-=m.value.length,y=E,m.value instanceof W)continue;for(var P=m;P!==t.tail&&(El.reach&&(l.reach=j);var C=m.prev;S&&(C=I(t,C,S),y+=S.length),T(t,C,b);var N=new W(o,g?M.tokenize(L,g):L,d,L);if(m=I(t,C,N),O&&I(t,m,O),1l.reach&&(l.reach=_.reach)}}}}}}(e,a,n,a.head,0),function(e){var n=[],t=e.head.next;for(;t!==e.tail;)n.push(t.value),t=t.next;return n}(a)},hooks:{all:{},add:function(e,n){var t=M.hooks.all;t[e]=t[e]||[],t[e].push(n)},run:function(e,n){var t=M.hooks.all[e];if(t&&t.length)for(var r,a=0;r=t[a++];)r(n)}},Token:W};function W(e,n,t,r){this.type=e,this.content=n,this.alias=t,this.length=0|(r||"").length}function z(e,n,t,r){e.lastIndex=n;var a=e.exec(t);if(a&&r&&a[1]){var i=a[1].length;a.index+=i,a[0]=a[0].slice(i)}return a}function i(){var e={value:null,prev:null,next:null},n={value:null,prev:e,next:null};e.next=n,this.head=e,this.tail=n,this.length=0}function I(e,n,t){var r=n.next,a={value:t,prev:n,next:r};return n.next=a,r.prev=a,e.length++,a}function T(e,n,t){for(var r=n.next,a=0;a"+a.content+""+a.tag+">"},!u.document)return u.addEventListener&&(M.disableWorkerMessageHandler||u.addEventListener("message",function(e){var n=JSON.parse(e.data),t=n.language,r=n.code,a=n.immediateClose;u.postMessage(M.highlight(r,M.languages[t],t)),a&&u.close()},!1)),M;var r=M.util.currentScript();function a(){M.manual||M.highlightAll()}if(r&&(M.filename=r.src,r.hasAttribute("data-manual")&&(M.manual=!0)),!M.manual){var l=document.readyState;"loading"===l||"interactive"===l&&r&&r.defer?document.addEventListener("DOMContentLoaded",a):window.requestAnimationFrame?window.requestAnimationFrame(a):window.setTimeout(a,16)}return M}(_self);"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism);
\ No newline at end of file
+var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(e){var n=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,t=0,r={},a={manual:e.Prism&&e.Prism.manual,disableWorkerMessageHandler:e.Prism&&e.Prism.disableWorkerMessageHandler,util:{encode:function e(n){return n instanceof i?new i(n.type,e(n.content),n.alias):Array.isArray(n)?n.map(e):n.replace(/&/g,"&").replace(/=g.reach);A+=w.value.length,w=w.next){var E=w.value;if(n.length>e.length)return;if(!(E instanceof i)){var P,L=1;if(y){if(!(P=l(b,A,e,m))||P.index>=e.length)break;var S=P.index,O=P.index+P[0].length,j=A;for(j+=w.value.length;S>=j;)j+=(w=w.next).value.length;if(A=j-=w.value.length,w.value instanceof i)continue;for(var C=w;C!==n.tail&&(jg.reach&&(g.reach=W);var z=w.prev;if(_&&(z=u(n,z,_),A+=_.length),c(n,z,L),w=u(n,z,new i(f,p?a.tokenize(N,p):N,k,N)),M&&u(n,w,M),L>1){var I={cause:f+","+d,reach:W};o(e,n,t,w.prev,A,I),g&&I.reach>g.reach&&(g.reach=I.reach)}}}}}}function s(){var e={value:null,prev:null,next:null},n={value:null,prev:e,next:null};e.next=n,this.head=e,this.tail=n,this.length=0}function u(e,n,t){var r=n.next,a={value:t,prev:n,next:r};return n.next=a,r.prev=a,e.length++,a}function c(e,n,t){for(var r=n.next,a=0;a"+i.content+""+i.tag+">"},!e.document)return e.addEventListener?(a.disableWorkerMessageHandler||e.addEventListener("message",(function(n){var t=JSON.parse(n.data),r=t.language,i=t.code,l=t.immediateClose;e.postMessage(a.highlight(i,a.languages[r],r)),l&&e.close()}),!1),a):a;var g=a.util.currentScript();function f(){a.manual||a.highlightAll()}if(g&&(a.filename=g.src,g.hasAttribute("data-manual")&&(a.manual=!0)),!a.manual){var h=document.readyState;"loading"===h||"interactive"===h&&g&&g.defer?document.addEventListener("DOMContentLoaded",f):window.requestAnimationFrame?window.requestAnimationFrame(f):window.setTimeout(f,16)}return a}(_self);"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism);
\ No newline at end of file
diff --git a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-cpp.min.js b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-cpp.min.js
index 128911e6f3..a7df36a603 100644
--- a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-cpp.min.js
+++ b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-cpp.min.js
@@ -1 +1 @@
-!function(e){var t=/\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|char8_t|class|co_await|co_return|co_yield|compl|concept|const|const_cast|consteval|constexpr|constinit|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|final|float|for|friend|goto|if|import|inline|int|int16_t|int32_t|int64_t|int8_t|long|module|mutable|namespace|new|noexcept|nullptr|operator|override|private|protected|public|register|reinterpret_cast|requires|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|uint16_t|uint32_t|uint64_t|uint8_t|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,n="\\b(?!)\\w+(?:\\s*\\.\\s*\\w+)*\\b".replace(//g,function(){return t.source});e.languages.cpp=e.languages.extend("c",{"class-name":[{pattern:RegExp("(\\b(?:class|concept|enum|struct|typename)\\s+)(?!)\\w+".replace(//g,function(){return t.source})),lookbehind:!0},/\b[A-Z]\w*(?=\s*::\s*\w+\s*\()/,/\b[A-Z_]\w*(?=\s*::\s*~\w+\s*\()/i,/\b\w+(?=\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*::\s*\w+\s*\()/],keyword:t,number:{pattern:/(?:\b0b[01']+|\b0x(?:[\da-f']+(?:\.[\da-f']*)?|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+(?:\.[\d']*)?|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]{0,4}/i,greedy:!0},operator:/>>=?|<<=?|->|--|\+\+|&&|\|\||[?:~]|<=>|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/,boolean:/\b(?:false|true)\b/}),e.languages.insertBefore("cpp","string",{module:{pattern:RegExp('(\\b(?:import|module)\\s+)(?:"(?:\\\\(?:\r\n|[^])|[^"\\\\\r\n])*"|<[^<>\r\n]*>|'+"(?:\\s*:\\s*)?|:\\s*".replace(//g,function(){return n})+")"),lookbehind:!0,greedy:!0,inside:{string:/^[<"][\s\S]+/,operator:/:/,punctuation:/\./}},"raw-string":{pattern:/R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,alias:"string",greedy:!0}}),e.languages.insertBefore("cpp","keyword",{"generic-function":{pattern:/\b(?!operator\b)[a-z_]\w*\s*<(?:[^<>]|<[^<>]*>)*>(?=\s*\()/i,inside:{function:/^\w+/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:e.languages.cpp}}}}),e.languages.insertBefore("cpp","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}}),e.languages.insertBefore("cpp","class-name",{"base-clause":{pattern:/(\b(?:class|struct)\s+\w+\s*:\s*)[^;{}"'\s]+(?:\s+[^;{}"'\s]+)*(?=\s*[;{])/,lookbehind:!0,greedy:!0,inside:e.languages.extend("cpp",{})}}),e.languages.insertBefore("inside","double-colon",{"class-name":/\b[a-z_]\w*\b(?!\s*::)/i},e.languages.cpp["base-clause"])}(Prism);
\ No newline at end of file
+!function(e){var t=/\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|char8_t|class|co_await|co_return|co_yield|compl|concept|const|const_cast|consteval|constexpr|constinit|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|final|float|for|friend|goto|if|import|inline|int|int16_t|int32_t|int64_t|int8_t|long|module|mutable|namespace|new|noexcept|nullptr|operator|override|private|protected|public|register|reinterpret_cast|requires|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|uint16_t|uint32_t|uint64_t|uint8_t|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,n="\\b(?!)\\w+(?:\\s*\\.\\s*\\w+)*\\b".replace(//g,(function(){return t.source}));e.languages.cpp=e.languages.extend("c",{"class-name":[{pattern:RegExp("(\\b(?:class|concept|enum|struct|typename)\\s+)(?!)\\w+".replace(//g,(function(){return t.source}))),lookbehind:!0},/\b[A-Z]\w*(?=\s*::\s*\w+\s*\()/,/\b[A-Z_]\w*(?=\s*::\s*~\w+\s*\()/i,/\b\w+(?=\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*::\s*\w+\s*\()/],keyword:t,number:{pattern:/(?:\b0b[01']+|\b0x(?:[\da-f']+(?:\.[\da-f']*)?|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+(?:\.[\d']*)?|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]{0,4}/i,greedy:!0},operator:/>>=?|<<=?|->|--|\+\+|&&|\|\||[?:~]|<=>|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/,boolean:/\b(?:false|true)\b/}),e.languages.insertBefore("cpp","string",{module:{pattern:RegExp('(\\b(?:import|module)\\s+)(?:"(?:\\\\(?:\r\n|[^])|[^"\\\\\r\n])*"|<[^<>\r\n]*>|'+"(?:\\s*:\\s*)?|:\\s*".replace(//g,(function(){return n}))+")"),lookbehind:!0,greedy:!0,inside:{string:/^[<"][\s\S]+/,operator:/:/,punctuation:/\./}},"raw-string":{pattern:/R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,alias:"string",greedy:!0}}),e.languages.insertBefore("cpp","keyword",{"generic-function":{pattern:/\b(?!operator\b)[a-z_]\w*\s*<(?:[^<>]|<[^<>]*>)*>(?=\s*\()/i,inside:{function:/^\w+/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:e.languages.cpp}}}}),e.languages.insertBefore("cpp","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}}),e.languages.insertBefore("cpp","class-name",{"base-clause":{pattern:/(\b(?:class|struct)\s+\w+\s*:\s*)[^;{}"'\s]+(?:\s+[^;{}"'\s]+)*(?=\s*[;{])/,lookbehind:!0,greedy:!0,inside:e.languages.extend("cpp",{})}}),e.languages.insertBefore("inside","double-colon",{"class-name":/\b[a-z_]\w*\b(?!\s*::)/i},e.languages.cpp["base-clause"])}(Prism);
\ No newline at end of file
diff --git a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-csharp.min.js b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-csharp.min.js
index bd9e804084..45bb0da898 100644
--- a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-csharp.min.js
+++ b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-csharp.min.js
@@ -1 +1 @@
-!function(s){function a(e,s){return e.replace(/<<(\d+)>>/g,function(e,n){return"(?:"+s[+n]+")"})}function t(e,n,s){return RegExp(a(e,n),s||"")}function e(e,n){for(var s=0;s>/g,function(){return"(?:"+e+")"});return e.replace(/<>/g,"[^\\s\\S]")}var n="bool byte char decimal double dynamic float int long object sbyte short string uint ulong ushort var void",r="class enum interface record struct",i="add alias and ascending async await by descending from(?=\\s*(?:\\w|$)) get global group into init(?=\\s*;) join let nameof not notnull on or orderby partial remove select set unmanaged value when where with(?=\\s*{)",o="abstract as base break case catch checked const continue default delegate do else event explicit extern finally fixed for foreach goto if implicit in internal is lock namespace new null operator out override params private protected public readonly ref return sealed sizeof stackalloc static switch this throw try typeof unchecked unsafe using virtual volatile while yield";function l(e){return"\\b(?:"+e.trim().replace(/ /g,"|")+")\\b"}var d=l(r),p=RegExp(l(n+" "+r+" "+i+" "+o)),c=l(r+" "+i+" "+o),u=l(n+" "+r+" "+o),g=e("<(?:[^<>;=+\\-*/%&|^]|<>)*>",2),b=e("\\((?:[^()]|<>)*\\)",2),h="@?\\b[A-Za-z_]\\w*\\b",f=a("<<0>>(?:\\s*<<1>>)?",[h,g]),m=a("(?!<<0>>)<<1>>(?:\\s*\\.\\s*<<1>>)*",[c,f]),k="\\[\\s*(?:,\\s*)*\\]",y=a("<<0>>(?:\\s*(?:\\?\\s*)?<<1>>)*(?:\\s*\\?)?",[m,k]),w=a("(?:<<0>>|<<1>>)(?:\\s*(?:\\?\\s*)?<<2>>)*(?:\\s*\\?)?",[a("\\(<<0>>+(?:,<<0>>+)+\\)",[a("[^,()<>[\\];=+\\-*/%&|^]|<<0>>|<<1>>|<<2>>",[g,b,k])]),m,k]),v={keyword:p,punctuation:/[<>()?,.:[\]]/},x="'(?:[^\r\n'\\\\]|\\\\.|\\\\[Uux][\\da-fA-F]{1,8})'",$='"(?:\\\\.|[^\\\\"\r\n])*"';s.languages.csharp=s.languages.extend("clike",{string:[{pattern:t("(^|[^$\\\\])<<0>>",['@"(?:""|\\\\[^]|[^\\\\"])*"(?!")']),lookbehind:!0,greedy:!0},{pattern:t("(^|[^@$\\\\])<<0>>",[$]),lookbehind:!0,greedy:!0}],"class-name":[{pattern:t("(\\busing\\s+static\\s+)<<0>>(?=\\s*;)",[m]),lookbehind:!0,inside:v},{pattern:t("(\\busing\\s+<<0>>\\s*=\\s*)<<1>>(?=\\s*;)",[h,w]),lookbehind:!0,inside:v},{pattern:t("(\\busing\\s+)<<0>>(?=\\s*=)",[h]),lookbehind:!0},{pattern:t("(\\b<<0>>\\s+)<<1>>",[d,f]),lookbehind:!0,inside:v},{pattern:t("(\\bcatch\\s*\\(\\s*)<<0>>",[m]),lookbehind:!0,inside:v},{pattern:t("(\\bwhere\\s+)<<0>>",[h]),lookbehind:!0},{pattern:t("(\\b(?:is(?:\\s+not)?|as)\\s+)<<0>>",[y]),lookbehind:!0,inside:v},{pattern:t("\\b<<0>>(?=\\s+(?!<<1>>|with\\s*\\{)<<2>>(?:\\s*[=,;:{)\\]]|\\s+(?:in|when)\\b))",[w,u,h]),inside:v}],keyword:p,number:/(?:\b0(?:x[\da-f_]*[\da-f]|b[01_]*[01])|(?:\B\.\d+(?:_+\d+)*|\b\d+(?:_+\d+)*(?:\.\d+(?:_+\d+)*)?)(?:e[-+]?\d+(?:_+\d+)*)?)(?:[dflmu]|lu|ul)?\b/i,operator:/>>=?|<<=?|[-=]>|([-+&|])\1|~|\?\?=?|[-+*/%&|^!=<>]=?/,punctuation:/\?\.?|::|[{}[\];(),.:]/}),s.languages.insertBefore("csharp","number",{range:{pattern:/\.\./,alias:"operator"}}),s.languages.insertBefore("csharp","punctuation",{"named-parameter":{pattern:t("([(,]\\s*)<<0>>(?=\\s*:)",[h]),lookbehind:!0,alias:"punctuation"}}),s.languages.insertBefore("csharp","class-name",{namespace:{pattern:t("(\\b(?:namespace|using)\\s+)<<0>>(?:\\s*\\.\\s*<<0>>)*(?=\\s*[;{])",[h]),lookbehind:!0,inside:{punctuation:/\./}},"type-expression":{pattern:t("(\\b(?:default|sizeof|typeof)\\s*\\(\\s*(?!\\s))(?:[^()\\s]|\\s(?!\\s)|<<0>>)*(?=\\s*\\))",[b]),lookbehind:!0,alias:"class-name",inside:v},"return-type":{pattern:t("<<0>>(?=\\s+(?:<<1>>\\s*(?:=>|[({]|\\.\\s*this\\s*\\[)|this\\s*\\[))",[w,m]),inside:v,alias:"class-name"},"constructor-invocation":{pattern:t("(\\bnew\\s+)<<0>>(?=\\s*[[({])",[w]),lookbehind:!0,inside:v,alias:"class-name"},"generic-method":{pattern:t("<<0>>\\s*<<1>>(?=\\s*\\()",[h,g]),inside:{function:t("^<<0>>",[h]),generic:{pattern:RegExp(g),alias:"class-name",inside:v}}},"type-list":{pattern:t("\\b((?:<<0>>\\s+<<1>>|record\\s+<<1>>\\s*<<5>>|where\\s+<<2>>)\\s*:\\s*)(?:<<3>>|<<4>>|<<1>>\\s*<<5>>|<<6>>)(?:\\s*,\\s*(?:<<3>>|<<4>>|<<6>>))*(?=\\s*(?:where|[{;]|=>|$))",[d,f,h,w,p.source,b,"\\bnew\\s*\\(\\s*\\)"]),lookbehind:!0,inside:{"record-arguments":{pattern:t("(^(?!new\\s*\\()<<0>>\\s*)<<1>>",[f,b]),lookbehind:!0,greedy:!0,inside:s.languages.csharp},keyword:p,"class-name":{pattern:RegExp(w),greedy:!0,inside:v},punctuation:/[,()]/}},preprocessor:{pattern:/(^[\t ]*)#.*/m,lookbehind:!0,alias:"property",inside:{directive:{pattern:/(#)\b(?:define|elif|else|endif|endregion|error|if|line|nullable|pragma|region|undef|warning)\b/,lookbehind:!0,alias:"keyword"}}}});var _=$+"|"+x,B=a("/(?![*/])|//[^\r\n]*[\r\n]|/\\*(?:[^*]|\\*(?!/))*\\*/|<<0>>",[_]),E=e(a("[^\"'/()]|<<0>>|\\(<>*\\)",[B]),2),R="\\b(?:assembly|event|field|method|module|param|property|return|type)\\b",z=a("<<0>>(?:\\s*\\(<<1>>*\\))?",[m,E]);s.languages.insertBefore("csharp","class-name",{attribute:{pattern:t("((?:^|[^\\s\\w>)?])\\s*\\[\\s*)(?:<<0>>\\s*:\\s*)?<<1>>(?:\\s*,\\s*<<1>>)*(?=\\s*\\])",[R,z]),lookbehind:!0,greedy:!0,inside:{target:{pattern:t("^<<0>>(?=\\s*:)",[R]),alias:"keyword"},"attribute-arguments":{pattern:t("\\(<<0>>*\\)",[E]),inside:s.languages.csharp},"class-name":{pattern:RegExp(m),inside:{punctuation:/\./}},punctuation:/[:,]/}}});var S=":[^}\r\n]+",j=e(a("[^\"'/()]|<<0>>|\\(<>*\\)",[B]),2),A=a("\\{(?!\\{)(?:(?![}:])<<0>>)*<<1>>?\\}",[j,S]),F=e(a("[^\"'/()]|/(?!\\*)|/\\*(?:[^*]|\\*(?!/))*\\*/|<<0>>|\\(<>*\\)",[_]),2),P=a("\\{(?!\\{)(?:(?![}:])<<0>>)*<<1>>?\\}",[F,S]);function U(e,n){return{interpolation:{pattern:t("((?:^|[^{])(?:\\{\\{)*)<<0>>",[e]),lookbehind:!0,inside:{"format-string":{pattern:t("(^\\{(?:(?![}:])<<0>>)*)<<1>>(?=\\}$)",[n,S]),lookbehind:!0,inside:{punctuation:/^:/}},punctuation:/^\{|\}$/,expression:{pattern:/[\s\S]+/,alias:"language-csharp",inside:s.languages.csharp}}},string:/[\s\S]+/}}s.languages.insertBefore("csharp","string",{"interpolation-string":[{pattern:t('(^|[^\\\\])(?:\\$@|@\\$)"(?:""|\\\\[^]|\\{\\{|<<0>>|[^\\\\{"])*"',[A]),lookbehind:!0,greedy:!0,inside:U(A,j)},{pattern:t('(^|[^@\\\\])\\$"(?:\\\\.|\\{\\{|<<0>>|[^\\\\"{])*"',[P]),lookbehind:!0,greedy:!0,inside:U(P,F)}],char:{pattern:RegExp(x),greedy:!0}}),s.languages.dotnet=s.languages.cs=s.languages.csharp}(Prism);
\ No newline at end of file
+!function(e){function n(e,n){return e.replace(/<<(\d+)>>/g,(function(e,s){return"(?:"+n[+s]+")"}))}function s(e,s,a){return RegExp(n(e,s),a||"")}function a(e,n){for(var s=0;s>/g,(function(){return"(?:"+e+")"}));return e.replace(/<>/g,"[^\\s\\S]")}var t="bool byte char decimal double dynamic float int long object sbyte short string uint ulong ushort var void",r="class enum interface record struct",i="add alias and ascending async await by descending from(?=\\s*(?:\\w|$)) get global group into init(?=\\s*;) join let nameof not notnull on or orderby partial remove select set unmanaged value when where with(?=\\s*{)",o="abstract as base break case catch checked const continue default delegate do else event explicit extern finally fixed for foreach goto if implicit in internal is lock namespace new null operator out override params private protected public readonly ref return sealed sizeof stackalloc static switch this throw try typeof unchecked unsafe using virtual volatile while yield";function l(e){return"\\b(?:"+e.trim().replace(/ /g,"|")+")\\b"}var d=l(r),p=RegExp(l(t+" "+r+" "+i+" "+o)),c=l(r+" "+i+" "+o),u=l(t+" "+r+" "+o),g=a("<(?:[^<>;=+\\-*/%&|^]|<>)*>",2),b=a("\\((?:[^()]|<>)*\\)",2),h="@?\\b[A-Za-z_]\\w*\\b",f=n("<<0>>(?:\\s*<<1>>)?",[h,g]),m=n("(?!<<0>>)<<1>>(?:\\s*\\.\\s*<<1>>)*",[c,f]),k="\\[\\s*(?:,\\s*)*\\]",y=n("<<0>>(?:\\s*(?:\\?\\s*)?<<1>>)*(?:\\s*\\?)?",[m,k]),w=n("[^,()<>[\\];=+\\-*/%&|^]|<<0>>|<<1>>|<<2>>",[g,b,k]),v=n("\\(<<0>>+(?:,<<0>>+)+\\)",[w]),x=n("(?:<<0>>|<<1>>)(?:\\s*(?:\\?\\s*)?<<2>>)*(?:\\s*\\?)?",[v,m,k]),$={keyword:p,punctuation:/[<>()?,.:[\]]/},_="'(?:[^\r\n'\\\\]|\\\\.|\\\\[Uux][\\da-fA-F]{1,8})'",B='"(?:\\\\.|[^\\\\"\r\n])*"';e.languages.csharp=e.languages.extend("clike",{string:[{pattern:s("(^|[^$\\\\])<<0>>",['@"(?:""|\\\\[^]|[^\\\\"])*"(?!")']),lookbehind:!0,greedy:!0},{pattern:s("(^|[^@$\\\\])<<0>>",[B]),lookbehind:!0,greedy:!0}],"class-name":[{pattern:s("(\\busing\\s+static\\s+)<<0>>(?=\\s*;)",[m]),lookbehind:!0,inside:$},{pattern:s("(\\busing\\s+<<0>>\\s*=\\s*)<<1>>(?=\\s*;)",[h,x]),lookbehind:!0,inside:$},{pattern:s("(\\busing\\s+)<<0>>(?=\\s*=)",[h]),lookbehind:!0},{pattern:s("(\\b<<0>>\\s+)<<1>>",[d,f]),lookbehind:!0,inside:$},{pattern:s("(\\bcatch\\s*\\(\\s*)<<0>>",[m]),lookbehind:!0,inside:$},{pattern:s("(\\bwhere\\s+)<<0>>",[h]),lookbehind:!0},{pattern:s("(\\b(?:is(?:\\s+not)?|as)\\s+)<<0>>",[y]),lookbehind:!0,inside:$},{pattern:s("\\b<<0>>(?=\\s+(?!<<1>>|with\\s*\\{)<<2>>(?:\\s*[=,;:{)\\]]|\\s+(?:in|when)\\b))",[x,u,h]),inside:$}],keyword:p,number:/(?:\b0(?:x[\da-f_]*[\da-f]|b[01_]*[01])|(?:\B\.\d+(?:_+\d+)*|\b\d+(?:_+\d+)*(?:\.\d+(?:_+\d+)*)?)(?:e[-+]?\d+(?:_+\d+)*)?)(?:[dflmu]|lu|ul)?\b/i,operator:/>>=?|<<=?|[-=]>|([-+&|])\1|~|\?\?=?|[-+*/%&|^!=<>]=?/,punctuation:/\?\.?|::|[{}[\];(),.:]/}),e.languages.insertBefore("csharp","number",{range:{pattern:/\.\./,alias:"operator"}}),e.languages.insertBefore("csharp","punctuation",{"named-parameter":{pattern:s("([(,]\\s*)<<0>>(?=\\s*:)",[h]),lookbehind:!0,alias:"punctuation"}}),e.languages.insertBefore("csharp","class-name",{namespace:{pattern:s("(\\b(?:namespace|using)\\s+)<<0>>(?:\\s*\\.\\s*<<0>>)*(?=\\s*[;{])",[h]),lookbehind:!0,inside:{punctuation:/\./}},"type-expression":{pattern:s("(\\b(?:default|sizeof|typeof)\\s*\\(\\s*(?!\\s))(?:[^()\\s]|\\s(?!\\s)|<<0>>)*(?=\\s*\\))",[b]),lookbehind:!0,alias:"class-name",inside:$},"return-type":{pattern:s("<<0>>(?=\\s+(?:<<1>>\\s*(?:=>|[({]|\\.\\s*this\\s*\\[)|this\\s*\\[))",[x,m]),inside:$,alias:"class-name"},"constructor-invocation":{pattern:s("(\\bnew\\s+)<<0>>(?=\\s*[[({])",[x]),lookbehind:!0,inside:$,alias:"class-name"},"generic-method":{pattern:s("<<0>>\\s*<<1>>(?=\\s*\\()",[h,g]),inside:{function:s("^<<0>>",[h]),generic:{pattern:RegExp(g),alias:"class-name",inside:$}}},"type-list":{pattern:s("\\b((?:<<0>>\\s+<<1>>|record\\s+<<1>>\\s*<<5>>|where\\s+<<2>>)\\s*:\\s*)(?:<<3>>|<<4>>|<<1>>\\s*<<5>>|<<6>>)(?:\\s*,\\s*(?:<<3>>|<<4>>|<<6>>))*(?=\\s*(?:where|[{;]|=>|$))",[d,f,h,x,p.source,b,"\\bnew\\s*\\(\\s*\\)"]),lookbehind:!0,inside:{"record-arguments":{pattern:s("(^(?!new\\s*\\()<<0>>\\s*)<<1>>",[f,b]),lookbehind:!0,greedy:!0,inside:e.languages.csharp},keyword:p,"class-name":{pattern:RegExp(x),greedy:!0,inside:$},punctuation:/[,()]/}},preprocessor:{pattern:/(^[\t ]*)#.*/m,lookbehind:!0,alias:"property",inside:{directive:{pattern:/(#)\b(?:define|elif|else|endif|endregion|error|if|line|nullable|pragma|region|undef|warning)\b/,lookbehind:!0,alias:"keyword"}}}});var E=B+"|"+_,R=n("/(?![*/])|//[^\r\n]*[\r\n]|/\\*(?:[^*]|\\*(?!/))*\\*/|<<0>>",[E]),z=a(n("[^\"'/()]|<<0>>|\\(<>*\\)",[R]),2),S="\\b(?:assembly|event|field|method|module|param|property|return|type)\\b",j=n("<<0>>(?:\\s*\\(<<1>>*\\))?",[m,z]);e.languages.insertBefore("csharp","class-name",{attribute:{pattern:s("((?:^|[^\\s\\w>)?])\\s*\\[\\s*)(?:<<0>>\\s*:\\s*)?<<1>>(?:\\s*,\\s*<<1>>)*(?=\\s*\\])",[S,j]),lookbehind:!0,greedy:!0,inside:{target:{pattern:s("^<<0>>(?=\\s*:)",[S]),alias:"keyword"},"attribute-arguments":{pattern:s("\\(<<0>>*\\)",[z]),inside:e.languages.csharp},"class-name":{pattern:RegExp(m),inside:{punctuation:/\./}},punctuation:/[:,]/}}});var A=":[^}\r\n]+",F=a(n("[^\"'/()]|<<0>>|\\(<>*\\)",[R]),2),P=n("\\{(?!\\{)(?:(?![}:])<<0>>)*<<1>>?\\}",[F,A]),U=a(n("[^\"'/()]|/(?!\\*)|/\\*(?:[^*]|\\*(?!/))*\\*/|<<0>>|\\(<>*\\)",[E]),2),Z=n("\\{(?!\\{)(?:(?![}:])<<0>>)*<<1>>?\\}",[U,A]);function q(n,a){return{interpolation:{pattern:s("((?:^|[^{])(?:\\{\\{)*)<<0>>",[n]),lookbehind:!0,inside:{"format-string":{pattern:s("(^\\{(?:(?![}:])<<0>>)*)<<1>>(?=\\}$)",[a,A]),lookbehind:!0,inside:{punctuation:/^:/}},punctuation:/^\{|\}$/,expression:{pattern:/[\s\S]+/,alias:"language-csharp",inside:e.languages.csharp}}},string:/[\s\S]+/}}e.languages.insertBefore("csharp","string",{"interpolation-string":[{pattern:s('(^|[^\\\\])(?:\\$@|@\\$)"(?:""|\\\\[^]|\\{\\{|<<0>>|[^\\\\{"])*"',[P]),lookbehind:!0,greedy:!0,inside:q(P,F)},{pattern:s('(^|[^@\\\\])\\$"(?:\\\\.|\\{\\{|<<0>>|[^\\\\"{])*"',[Z]),lookbehind:!0,greedy:!0,inside:q(Z,U)}],char:{pattern:RegExp(_),greedy:!0}}),e.languages.dotnet=e.languages.cs=e.languages.csharp}(Prism);
\ No newline at end of file
diff --git a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-cshtml.js b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-cshtml.js
index a917626aa0..4643710d3d 100644
--- a/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-cshtml.js
+++ b/modules/docs/app/VoloDocs.Web/wwwroot/libs/prismjs/components/prism-cshtml.js
@@ -28,9 +28,15 @@
}
var round = nested(/\((?:[^()'"@/]|||)*\)/.source, 2);
- var square = nested(/\[(?:[^\[\]'"@/]|||)*\]/.source, 2);
+ var square = nested(/\[(?:[^\[\]'"@/]|||)*\]/.source, 1);
var curly = nested(/\{(?:[^{}'"@/]|||)*\}/.source, 2);
- var angle = nested(/<(?:[^<>'"@/]|||)*>/.source, 2);
+ var angle = nested(/<(?:[^<>'"@/]||)*>/.source, 1);
+
+ var inlineCs = /@/.source +
+ /(?:await\b\s*)?/.source +
+ '(?:' + /(?!await\b)\w+\b/.source + '|' + round + ')' +
+ '(?:' + /[?!]?\.\w+\b/.source + '|' + '(?:' + angle + ')?' + round + '|' + square + ')*' +
+ /(?![?!\.(\[]|<(?!\/))/.source;
// Note about the above bracket patterns:
// They all ignore HTML expressions that might be in the C# code. This is a problem because HTML (like strings and
@@ -44,7 +50,14 @@
// To somewhat alleviate the problem a bit, the patterns for characters (e.g. 'a') is very permissive, it also
// allows invalid characters to support HTML expressions like this: