diff --git a/Directory.Packages.props b/Directory.Packages.props
index 0934dcb9d..1885e9c77 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -8,6 +8,7 @@
+
diff --git a/KernelMemory.sln b/KernelMemory.sln
index 13710c907..d792f8139 100644
--- a/KernelMemory.sln
+++ b/KernelMemory.sln
@@ -1,59 +1,60 @@
-
Microsoft Visual Studio Solution File, Format Version 12.00
-
+# Visual Studio Version 17
+VisualStudioVersion = 17.9.34310.174
+MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "clients", "clients", "{371BB479-AA1C-41CB-BF07-24C363601289}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{7BA7F1B2-19E2-46EB-B000-513EE2F65769}"
ProjectSection(SolutionItems) = preProject
- docs\_config.local.yml = docs\_config.local.yml
- docs\_config.yml = docs\_config.yml
+ docs\404.html = docs\404.html
+ docs\concepts.md = docs\concepts.md
docs\csharp.png = docs\csharp.png
- docs\service.md = docs\service.md
- docs\serverless.md = docs\serverless.md
- docs\security.md = docs\security.md
- docs\run.cmd = docs\run.cmd
- docs\quickstart.md = docs\quickstart.md
- docs\quickstart-swagger.png = docs\quickstart-swagger.png
- docs\quickstart-dotnet-run.png = docs\quickstart-dotnet-run.png
- docs\python.png = docs\python.png
- docs\packages.md = docs\packages.md
- docs\network.png = docs\network.png
- docs\logo.png = docs\logo.png
- docs\java.png = docs\java.png
- docs\index.md = docs\index.md
- docs\how-tos.md = docs\how-tos.md
- docs\Gemfile.lock = docs\Gemfile.lock
- docs\Gemfile = docs\Gemfile
- docs\features.md = docs\features.md
- docs\favicon.png = docs\favicon.png
- docs\FAQ.md = docs\FAQ.md
docs\extensions.md = docs\extensions.md
- docs\concepts.md = docs\concepts.md
- docs\404.html = docs\404.html
+ docs\FAQ.md = docs\FAQ.md
+ docs\favicon.png = docs\favicon.png
+ docs\features.md = docs\features.md
+ docs\Gemfile = docs\Gemfile
+ docs\Gemfile.lock = docs\Gemfile.lock
+ docs\how-tos.md = docs\how-tos.md
+ docs\index.md = docs\index.md
+ docs\java.png = docs\java.png
+ docs\logo.png = docs\logo.png
+ docs\network.png = docs\network.png
+ docs\packages.md = docs\packages.md
+ docs\python.png = docs\python.png
+ docs\quickstart-dotnet-run.png = docs\quickstart-dotnet-run.png
+ docs\quickstart-swagger.png = docs\quickstart-swagger.png
+ docs\quickstart.md = docs\quickstart.md
+ docs\run.cmd = docs\run.cmd
+ docs\security.md = docs\security.md
+ docs\serverless.md = docs\serverless.md
+ docs\service.md = docs\service.md
+ docs\_config.local.yml = docs\_config.local.yml
+ docs\_config.yml = docs\_config.yml
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{0A43C65C-6007-4BB4-B3FE-8D439FC91841}"
ProjectSection(SolutionItems) = preProject
- examples\README.md = examples\README.md
examples\Directory.Build.props = examples\Directory.Build.props
+ examples\README.md = examples\README.md
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "000-notebooks", "000-notebooks", "{C93FCED9-808A-4B03-9B4C-0DBAE46D5BDD}"
ProjectSection(SolutionItems) = preProject
examples\000-notebooks\001-upload-and-ask.ipynb = examples\000-notebooks\001-upload-and-ask.ipynb
- examples\000-notebooks\appsettings.json = examples\000-notebooks\appsettings.json
examples\000-notebooks\002-semantic-kernel-plugin.ipynb = examples\000-notebooks\002-semantic-kernel-plugin.ipynb
+ examples\000-notebooks\appsettings.json = examples\000-notebooks\appsettings.json
examples\000-notebooks\NASA-news.pdf = examples\000-notebooks\NASA-news.pdf
examples\000-notebooks\sample-KM-Readme.pdf = examples\000-notebooks\sample-KM-Readme.pdf
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "006-curl-calling-webservice", "006-curl-calling-webservice", "{CA1D9162-D4C5-490D-AAD5-7A9A23092C28}"
ProjectSection(SolutionItems) = preProject
- examples\006-curl-calling-webservice\test.pdf = examples\006-curl-calling-webservice\test.pdf
- examples\006-curl-calling-webservice\README.md = examples\006-curl-calling-webservice\README.md
examples\006-curl-calling-webservice\ask-example.sh = examples\006-curl-calling-webservice\ask-example.sh
- examples\006-curl-calling-webservice\upload-example.sh = examples\006-curl-calling-webservice\upload-example.sh
+ examples\006-curl-calling-webservice\README.md = examples\006-curl-calling-webservice\README.md
examples\006-curl-calling-webservice\search-example.sh = examples\006-curl-calling-webservice\search-example.sh
+ examples\006-curl-calling-webservice\test.pdf = examples\006-curl-calling-webservice\test.pdf
+ examples\006-curl-calling-webservice\upload-example.sh = examples\006-curl-calling-webservice\upload-example.sh
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "200-dotnet-nl2sql", "200-dotnet-nl2sql", "{2C4D5F14-CCFC-4913-B884-B2FF9067BEFF}"
@@ -65,27 +66,27 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "extensions", "extensions",
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "root", "root", "{6EF76FD8-4C35-4370-8539-5DDF45357A50}"
ProjectSection(SolutionItems) = preProject
- README.md = README.md
- SECURITY.md = SECURITY.md
- LICENSE = LICENSE
- CONTRIBUTING.md = CONTRIBUTING.md
- COMMUNITY.md = COMMUNITY.md
- CODE_OF_CONDUCT.md = CODE_OF_CONDUCT.md
- .gitignore = .gitignore
- .gitattributes = .gitattributes
+ .dockerignore = .dockerignore
.editorconfig = .editorconfig
+ .gitattributes = .gitattributes
+ .gitignore = .gitignore
+ CODE_OF_CONDUCT.md = CODE_OF_CONDUCT.md
+ COMMUNITY.md = COMMUNITY.md
+ CONTRIBUTING.md = CONTRIBUTING.md
Directory.Build.props = Directory.Build.props
Directory.Packages.props = Directory.Packages.props
- nuget.config = nuget.config
Dockerfile = Dockerfile
- .dockerignore = .dockerignore
+ LICENSE = LICENSE
+ nuget.config = nuget.config
+ README.md = README.md
+ SECURITY.md = SECURITY.md
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github", ".github", "{B8976338-7CDC-47AE-8502-C2FBAFBEBD68}"
ProjectSection(SolutionItems) = preProject
- .github\_typos.toml = .github\_typos.toml
.github\dependabot.yml = .github\dependabot.yml
.github\pull_request_template.md = .github\pull_request_template.md
+ .github\_typos.toml = .github\_typos.toml
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{48E79819-1E9E-4075-90DA-BAEC761C89B2}"
@@ -103,145 +104,143 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "extensions", "extensions",
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tools", "tools", "{CA49F1A1-C3FA-4E99-ACB3-D7FF33D47976}"
ProjectSection(SolutionItems) = preProject
- tools\run-rabbitmq.sh = tools\run-rabbitmq.sh
- tools\upload-file.sh = tools\upload-file.sh
- tools\README.md = tools\README.md
tools\ask.sh = tools\ask.sh
- tools\search.sh = tools\search.sh
- tools\run-qdrant.sh = tools\run-qdrant.sh
tools\create-azure-webapp-publish-artifacts.sh = tools\create-azure-webapp-publish-artifacts.sh
- tools\run-redis.sh = tools\run-redis.sh
- tools\run-mssql.sh = tools\run-mssql.sh
+ tools\README.md = tools\README.md
tools\run-elasticsearch.sh = tools\run-elasticsearch.sh
tools\run-mongodb-atlas.sh = tools\run-mongodb-atlas.sh
+ tools\run-mssql.sh = tools\run-mssql.sh
+ tools\run-qdrant.sh = tools\run-qdrant.sh
+ tools\run-rabbitmq.sh = tools\run-rabbitmq.sh
+ tools\run-redis.sh = tools\run-redis.sh
+ tools\search.sh = tools\search.sh
+ tools\upload-file.sh = tools\upload-file.sh
EndProjectSection
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Abstractions", "service\Abstractions\Abstractions.csproj", "{8A9FA587-7EBA-4D43-BE47-38D798B1C74C}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Abstractions", "service\Abstractions\Abstractions.csproj", "{8A9FA587-7EBA-4D43-BE47-38D798B1C74C}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Abstractions.UnitTests", "service\tests\Abstractions.UnitTests\Abstractions.UnitTests.csproj", "{C4AFA538-8939-4525-A361-665833947F72}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Abstractions.UnitTests", "service\tests\Abstractions.UnitTests\Abstractions.UnitTests.csproj", "{C4AFA538-8939-4525-A361-665833947F72}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Core", "service\Core\Core.csproj", "{27910ADC-5A28-4EB4-A16E-974B91940758}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Core", "service\Core\Core.csproj", "{27910ADC-5A28-4EB4-A16E-974B91940758}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Core.UnitTests", "service\tests\Core.UnitTests\Core.UnitTests.csproj", "{4AE9DB51-2A22-4FB3-A780-838738566D18}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Core.UnitTests", "service\tests\Core.UnitTests\Core.UnitTests.csproj", "{4AE9DB51-2A22-4FB3-A780-838738566D18}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Core.FunctionalTests", "service\tests\Core.FunctionalTests\Core.FunctionalTests.csproj", "{3AAD973E-2FDC-4C89-94BA-4F6671C2F23A}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Core.FunctionalTests", "service\tests\Core.FunctionalTests\Core.FunctionalTests.csproj", "{3AAD973E-2FDC-4C89-94BA-4F6671C2F23A}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Service", "service\Service\Service.csproj", "{1071A8B6-ED76-4E46-A291-E0563B9C4575}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Service", "service\Service\Service.csproj", "{1071A8B6-ED76-4E46-A291-E0563B9C4575}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Service.FunctionalTests", "service\tests\Service.FunctionalTests\Service.FunctionalTests.csproj", "{BCD0255F-2F35-4B6D-BBF2-2FB43B6F95FA}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Service.FunctionalTests", "service\tests\Service.FunctionalTests\Service.FunctionalTests.csproj", "{BCD0255F-2F35-4B6D-BBF2-2FB43B6F95FA}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestHelpers", "service\tests\TestHelpers\TestHelpers.csproj", "{989061F4-164F-4D98-A3F9-601BC40EE216}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestHelpers", "service\tests\TestHelpers\TestHelpers.csproj", "{989061F4-164F-4D98-A3F9-601BC40EE216}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InteractiveSetup", "tools\InteractiveSetup\InteractiveSetup.csproj", "{C03BC9FE-5301-43EE-B912-1363F430DBA0}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "InteractiveSetup", "tools\InteractiveSetup\InteractiveSetup.csproj", "{C03BC9FE-5301-43EE-B912-1363F430DBA0}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SemanticKernelPlugin", "clients\dotnet\SemanticKernelPlugin\SemanticKernelPlugin.csproj", "{F7609330-E97E-422C-8983-EC501B2DDC52}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SemanticKernelPlugin", "clients\dotnet\SemanticKernelPlugin\SemanticKernelPlugin.csproj", "{F7609330-E97E-422C-8983-EC501B2DDC52}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebClient", "clients\dotnet\WebClient\WebClient.csproj", "{D04A01C0-EF1B-49B2-B6AB-8AC635566E6A}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebClient", "clients\dotnet\WebClient\WebClient.csproj", "{D04A01C0-EF1B-49B2-B6AB-8AC635566E6A}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "001-dotnet-WebClient", "examples\001-dotnet-WebClient\001-dotnet-WebClient.csproj", "{A77F639B-EA35-4519-9DBF-54687E5AC895}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "001-dotnet-WebClient", "examples\001-dotnet-WebClient\001-dotnet-WebClient.csproj", "{A77F639B-EA35-4519-9DBF-54687E5AC895}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "002-dotnet-Serverless", "examples\002-dotnet-Serverless\002-dotnet-Serverless.csproj", "{6627ACE2-14FA-4A8E-A03C-0E4710B5411E}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "002-dotnet-Serverless", "examples\002-dotnet-Serverless\002-dotnet-Serverless.csproj", "{6627ACE2-14FA-4A8E-A03C-0E4710B5411E}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "003-dotnet-SemanticKernel-plugin", "examples\003-dotnet-SemanticKernel-plugin\003-dotnet-SemanticKernel-plugin.csproj", "{BCBEE522-6B4F-4C79-9E91-A34F4CCBF036}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "003-dotnet-SemanticKernel-plugin", "examples\003-dotnet-SemanticKernel-plugin\003-dotnet-SemanticKernel-plugin.csproj", "{BCBEE522-6B4F-4C79-9E91-A34F4CCBF036}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "004-dotnet-serverless-custom-pipeline", "examples\004-dotnet-serverless-custom-pipeline\004-dotnet-serverless-custom-pipeline.csproj", "{158F5D5D-818B-4346-9A79-1C27C2F2144D}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "004-dotnet-serverless-custom-pipeline", "examples\004-dotnet-serverless-custom-pipeline\004-dotnet-serverless-custom-pipeline.csproj", "{158F5D5D-818B-4346-9A79-1C27C2F2144D}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "005-dotnet-async-memory-custom-pipeline", "examples\005-dotnet-async-memory-custom-pipeline\005-dotnet-async-memory-custom-pipeline.csproj", "{A5CE3CB2-F746-4832-B239-1A3226F9BD48}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "005-dotnet-async-memory-custom-pipeline", "examples\005-dotnet-async-memory-custom-pipeline\005-dotnet-async-memory-custom-pipeline.csproj", "{A5CE3CB2-F746-4832-B239-1A3226F9BD48}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "101-dotnet-custom-Prompts", "examples\101-dotnet-custom-Prompts\101-dotnet-custom-Prompts.csproj", "{6ABCC373-F472-4A34-9C78-4A324DDED207}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "101-dotnet-custom-Prompts", "examples\101-dotnet-custom-Prompts\101-dotnet-custom-Prompts.csproj", "{6ABCC373-F472-4A34-9C78-4A324DDED207}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "102-dotnet-custom-partitioning-options", "examples\102-dotnet-custom-partitioning-options\102-dotnet-custom-partitioning-options.csproj", "{5E727FC9-ACE2-4028-AAA7-5BCECCE5010B}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "102-dotnet-custom-partitioning-options", "examples\102-dotnet-custom-partitioning-options\102-dotnet-custom-partitioning-options.csproj", "{5E727FC9-ACE2-4028-AAA7-5BCECCE5010B}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "103-dotnet-custom-EmbeddingGenerator", "examples\103-dotnet-custom-EmbeddingGenerator\103-dotnet-custom-EmbeddingGenerator.csproj", "{55082AEB-0DEF-41F2-9616-DBDC22360379}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "103-dotnet-custom-EmbeddingGenerator", "examples\103-dotnet-custom-EmbeddingGenerator\103-dotnet-custom-EmbeddingGenerator.csproj", "{55082AEB-0DEF-41F2-9616-DBDC22360379}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "104-dotnet-custom-LLM", "examples\104-dotnet-custom-LLM\104-dotnet-custom-LLM.csproj", "{34FA6EE2-26FE-44D6-8F91-6A5E5A06074B}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "104-dotnet-custom-LLM", "examples\104-dotnet-custom-LLM\104-dotnet-custom-LLM.csproj", "{34FA6EE2-26FE-44D6-8F91-6A5E5A06074B}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "105-dotnet-serverless-llamasharp", "examples\105-dotnet-serverless-llamasharp\105-dotnet-serverless-llamasharp.csproj", "{E762B1C6-4B5B-487A-BF8C-C6870D6EACB7}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "105-dotnet-serverless-llamasharp", "examples\105-dotnet-serverless-llamasharp\105-dotnet-serverless-llamasharp.csproj", "{E762B1C6-4B5B-487A-BF8C-C6870D6EACB7}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "106-dotnet-retrieve-synthetics", "examples\106-dotnet-retrieve-synthetics\106-dotnet-retrieve-synthetics.csproj", "{EDFDA12E-BA10-4A00-BBE7-1C10A0B0F1A6}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "106-dotnet-retrieve-synthetics", "examples\106-dotnet-retrieve-synthetics\106-dotnet-retrieve-synthetics.csproj", "{EDFDA12E-BA10-4A00-BBE7-1C10A0B0F1A6}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "201-dotnet-serverless-custom-handler", "examples\201-dotnet-serverless-custom-handler\201-dotnet-serverless-custom-handler.csproj", "{791E3E2E-133C-4EB5-AB5E-10D31F0A9807}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "201-dotnet-serverless-custom-handler", "examples\201-dotnet-serverless-custom-handler\201-dotnet-serverless-custom-handler.csproj", "{791E3E2E-133C-4EB5-AB5E-10D31F0A9807}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "202-dotnet-custom-handler-as-a-service", "examples\202-dotnet-custom-handler-as-a-service\202-dotnet-custom-handler-as-a-service.csproj", "{DE115127-C77F-40FF-BA5A-E888A32F2289}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "202-dotnet-custom-handler-as-a-service", "examples\202-dotnet-custom-handler-as-a-service\202-dotnet-custom-handler-as-a-service.csproj", "{DE115127-C77F-40FF-BA5A-E888A32F2289}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "203-dotnet-using-core-nuget", "examples\203-dotnet-using-core-nuget\203-dotnet-using-core-nuget.csproj", "{1B41A9A1-0B57-4297-B579-D04FC0BA3227}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "203-dotnet-using-core-nuget", "examples\203-dotnet-using-core-nuget\203-dotnet-using-core-nuget.csproj", "{1B41A9A1-0B57-4297-B579-D04FC0BA3227}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "204-dotnet-ASP.NET-MVC-integration", "examples\204-dotnet-ASP.NET-MVC-integration\204-dotnet-ASP.NET-MVC-integration.csproj", "{10A6C940-AECC-4CEF-963E-9908DDA816B2}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "204-dotnet-ASP.NET-MVC-integration", "examples\204-dotnet-ASP.NET-MVC-integration\204-dotnet-ASP.NET-MVC-integration.csproj", "{10A6C940-AECC-4CEF-963E-9908DDA816B2}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "205-dotnet-extract-text-from-docs", "examples\205-dotnet-extract-text-from-docs\205-dotnet-extract-text-from-docs.csproj", "{9202380E-D793-4C3C-89B3-3BE790925029}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "205-dotnet-extract-text-from-docs", "examples\205-dotnet-extract-text-from-docs\205-dotnet-extract-text-from-docs.csproj", "{9202380E-D793-4C3C-89B3-3BE790925029}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "206-dotnet-configuration-and-logging", "examples\206-dotnet-configuration-and-logging\206-dotnet-configuration-and-logging.csproj", "{D7D8FCA0-BFC6-4B0E-9885-64C2EA90AA62}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "206-dotnet-configuration-and-logging", "examples\206-dotnet-configuration-and-logging\206-dotnet-configuration-and-logging.csproj", "{D7D8FCA0-BFC6-4B0E-9885-64C2EA90AA62}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "207-dotnet-expanding-chunks-on-retrieval", "examples\207-dotnet-expanding-chunks-on-retrieval\207-dotnet-expanding-chunks-on-retrieval.csproj", "{47CEEA8F-7858-4635-B902-4C704CF55EA0}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "207-dotnet-expanding-chunks-on-retrieval", "examples\207-dotnet-expanding-chunks-on-retrieval\207-dotnet-expanding-chunks-on-retrieval.csproj", "{47CEEA8F-7858-4635-B902-4C704CF55EA0}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AzureBlobs", "extensions\AzureBlobs\AzureBlobs.csproj", "{20FFF62D-5BA5-4126-A16C-C14E1FF35A4F}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AzureBlobs", "extensions\AzureBlobs\AzureBlobs.csproj", "{20FFF62D-5BA5-4126-A16C-C14E1FF35A4F}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AzureQueues", "extensions\AzureQueues\AzureQueues.csproj", "{40CB6452-68DD-4C78-9852-78281A161950}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AzureQueues", "extensions\AzureQueues\AzureQueues.csproj", "{40CB6452-68DD-4C78-9852-78281A161950}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AzureAIDocIntel", "extensions\AzureAIDocIntel\AzureAIDocIntel.csproj", "{CFE7C192-2561-40CC-8592-136293451EC1}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AzureAIDocIntel", "extensions\AzureAIDocIntel\AzureAIDocIntel.csproj", "{CFE7C192-2561-40CC-8592-136293451EC1}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AzureOpenAI", "extensions\AzureOpenAI\AzureOpenAI.csproj", "{93FA6DD6-D0B2-4751-8680-3F959E1F7AF2}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AzureOpenAI", "extensions\AzureOpenAI\AzureOpenAI.csproj", "{93FA6DD6-D0B2-4751-8680-3F959E1F7AF2}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AzureAISearch.TestApplication", "extensions\AzureAISearch\AzureAISearch.TestApplication\AzureAISearch.TestApplication.csproj", "{11445C36-1B94-4AFB-AC23-976C94924603}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AzureAISearch.TestApplication", "extensions\AzureAISearch\AzureAISearch.TestApplication\AzureAISearch.TestApplication.csproj", "{11445C36-1B94-4AFB-AC23-976C94924603}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AzureAISearch", "extensions\AzureAISearch\AzureAISearch\AzureAISearch.csproj", "{8F2185AB-F87C-4DD0-9DB8-E97920500A37}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AzureAISearch", "extensions\AzureAISearch\AzureAISearch\AzureAISearch.csproj", "{8F2185AB-F87C-4DD0-9DB8-E97920500A37}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AzureAISearch.FunctionalTests", "extensions\AzureAISearch\AzureAISearch.FunctionalTests\AzureAISearch.FunctionalTests.csproj", "{E2AD3323-42AA-47D5-87E4-1E90B0A7C6E9}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AzureAISearch.FunctionalTests", "extensions\AzureAISearch\AzureAISearch.FunctionalTests\AzureAISearch.FunctionalTests.csproj", "{E2AD3323-42AA-47D5-87E4-1E90B0A7C6E9}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AzureAISearch.UnitTests", "extensions\AzureAISearch\AzureAISearch.UnitTests\AzureAISearch.UnitTests.csproj", "{9F564F2D-EADD-47DE-9293-92B3E9CFFE36}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AzureAISearch.UnitTests", "extensions\AzureAISearch\AzureAISearch.UnitTests\AzureAISearch.UnitTests.csproj", "{9F564F2D-EADD-47DE-9293-92B3E9CFFE36}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Postgres", "extensions\Postgres\Postgres\Postgres.csproj", "{6577B501-E295-4DCE-B640-BF40C9881A00}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Postgres", "extensions\Postgres\Postgres\Postgres.csproj", "{6577B501-E295-4DCE-B640-BF40C9881A00}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Postgres.UnitTests", "extensions\Postgres\Postgres.UnitTests\Postgres.UnitTests.csproj", "{0675D9B5-B3BB-4C9A-A1A5-11540E2ED715}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Postgres.UnitTests", "extensions\Postgres\Postgres.UnitTests\Postgres.UnitTests.csproj", "{0675D9B5-B3BB-4C9A-A1A5-11540E2ED715}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Postgres.TestApplication", "extensions\Postgres\Postgres.TestApplication\Postgres.TestApplication.csproj", "{E9EAD4A8-05B8-4138-8B17-E33127C83CF4}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Postgres.TestApplication", "extensions\Postgres\Postgres.TestApplication\Postgres.TestApplication.csproj", "{E9EAD4A8-05B8-4138-8B17-E33127C83CF4}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Postgres.FunctionalTests", "extensions\Postgres\Postgres.FunctionalTests\Postgres.FunctionalTests.csproj", "{14106EE4-AB77-494D-B16A-3EC042539456}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Postgres.FunctionalTests", "extensions\Postgres\Postgres.FunctionalTests\Postgres.FunctionalTests.csproj", "{14106EE4-AB77-494D-B16A-3EC042539456}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LlamaSharp", "extensions\LlamaSharp\LlamaSharp\LlamaSharp.csproj", "{969625B8-039F-4E5E-A484-6A30DC417FBB}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LlamaSharp", "extensions\LlamaSharp\LlamaSharp\LlamaSharp.csproj", "{969625B8-039F-4E5E-A484-6A30DC417FBB}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LlamaSharp.FunctionalTests", "extensions\LlamaSharp\LlamaSharp.FunctionalTests\LlamaSharp.FunctionalTests.csproj", "{9D3C9277-648D-441D-834D-565076EE2E87}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LlamaSharp.FunctionalTests", "extensions\LlamaSharp\LlamaSharp.FunctionalTests\LlamaSharp.FunctionalTests.csproj", "{9D3C9277-648D-441D-834D-565076EE2E87}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Redis.TestApplication", "extensions\Redis\Redis.TestApplication\Redis.TestApplication.csproj", "{CCA96699-483E-4B2A-95DF-25F0C98E3BB6}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Redis.TestApplication", "extensions\Redis\Redis.TestApplication\Redis.TestApplication.csproj", "{CCA96699-483E-4B2A-95DF-25F0C98E3BB6}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Redis", "extensions\Redis\Redis\Redis.csproj", "{F25BC232-6161-4D45-8AFF-E92A52F0F85A}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Redis", "extensions\Redis\Redis\Redis.csproj", "{F25BC232-6161-4D45-8AFF-E92A52F0F85A}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Redis.FunctionalTests", "extensions\Redis\Redis.FunctionalTests\Redis.FunctionalTests.csproj", "{C8A18E8F-34CC-4226-9831-083335DAB21A}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Redis.FunctionalTests", "extensions\Redis\Redis.FunctionalTests\Redis.FunctionalTests.csproj", "{C8A18E8F-34CC-4226-9831-083335DAB21A}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Qdrant", "extensions\Qdrant\Qdrant\Qdrant.csproj", "{9D078C9B-42A3-4558-898A-2396F59A54D3}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Qdrant", "extensions\Qdrant\Qdrant\Qdrant.csproj", "{9D078C9B-42A3-4558-898A-2396F59A54D3}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Qdrant.UnitTests", "extensions\Qdrant\Qdrant.UnitTests\Qdrant.UnitTests.csproj", "{9FB79D60-E87E-420A-984D-C4D5DD2C3125}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Qdrant.UnitTests", "extensions\Qdrant\Qdrant.UnitTests\Qdrant.UnitTests.csproj", "{9FB79D60-E87E-420A-984D-C4D5DD2C3125}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Qdrant.TestApplication", "extensions\Qdrant\Qdrant.TestApplication\Qdrant.TestApplication.csproj", "{3897E2B7-85A3-4D69-B1C0-AEF41236F940}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Qdrant.TestApplication", "extensions\Qdrant\Qdrant.TestApplication\Qdrant.TestApplication.csproj", "{3897E2B7-85A3-4D69-B1C0-AEF41236F940}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Qdrant.FunctionalTests", "extensions\Qdrant\Qdrant.FunctionalTests\Qdrant.FunctionalTests.csproj", "{62B96766-AA6C-4CFF-A6FB-6370C89C2509}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Qdrant.FunctionalTests", "extensions\Qdrant\Qdrant.FunctionalTests\Qdrant.FunctionalTests.csproj", "{62B96766-AA6C-4CFF-A6FB-6370C89C2509}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RabbitMQ", "extensions\RabbitMQ\RabbitMQ.csproj", "{E3877E49-958E-4DC8-B5E8-834010F5C4B7}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RabbitMQ", "extensions\RabbitMQ\RabbitMQ.csproj", "{E3877E49-958E-4DC8-B5E8-834010F5C4B7}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenAI", "extensions\OpenAI\OpenAI.csproj", "{A6AE31A1-4F60-47B0-8534-7B083D68118C}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenAI", "extensions\OpenAI\OpenAI.csproj", "{A6AE31A1-4F60-47B0-8534-7B083D68118C}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SQLServer.FunctionalTests", "extensions\SQLServer\SQLServer.FunctionalTests\SQLServer.FunctionalTests.csproj", "{668A48B7-F600-4056-B47E-3200893C0404}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SQLServer.FunctionalTests", "extensions\SQLServer\SQLServer.FunctionalTests\SQLServer.FunctionalTests.csproj", "{668A48B7-F600-4056-B47E-3200893C0404}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elasticsearch.FunctionalTests", "extensions\Elasticsearch\Elasticsearch.FunctionalTests\Elasticsearch.FunctionalTests.csproj", "{C089DE42-9D39-4633-AC0C-5034BA0B98E1}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MongoDbAtlas", "extensions\MongoDbAtlas\MongoDbAtlas\MongoDbAtlas.csproj", "{4A539320-EB49-4688-82E1-4FA0ADBB3810}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MongoDbAtlas", "extensions\MongoDbAtlas\MongoDbAtlas\MongoDbAtlas.csproj", "{4A539320-EB49-4688-82E1-4FA0ADBB3810}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MongoDbAtlas.FunctionalTests", "extensions\MongoDbAtlas\MongoDbAtlas.FunctionalTests\MongoDbAtlas.FunctionalTests.csproj", "{8A602227-B291-4F1B-ACB8-237F49501B6A}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MongoDbAtlas.FunctionalTests", "extensions\MongoDbAtlas\MongoDbAtlas.FunctionalTests\MongoDbAtlas.FunctionalTests.csproj", "{8A602227-B291-4F1B-ACB8-237F49501B6A}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "107-dotnet-SemanticKernel-TextCompletion", "examples\107-dotnet-SemanticKernel-TextCompletion\107-dotnet-SemanticKernel-TextCompletion.csproj", "{494B8590-F0B2-4D40-A895-F9D7BDF26250}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "107-dotnet-SemanticKernel-TextCompletion", "examples\107-dotnet-SemanticKernel-TextCompletion\107-dotnet-SemanticKernel-TextCompletion.csproj", "{494B8590-F0B2-4D40-A895-F9D7BDF26250}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "208-dotnet-lmstudio", "examples\208-dotnet-lmstudio\208-dotnet-lmstudio.csproj", "{BC8057DA-CB40-4308-96FB-EF0100822BAD}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "208-dotnet-lmstudio", "examples\208-dotnet-lmstudio\208-dotnet-lmstudio.csproj", "{BC8057DA-CB40-4308-96FB-EF0100822BAD}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "108-dotnet-custom-content-decoders", "examples\108-dotnet-custom-content-decoders\108-dotnet-custom-content-decoders.csproj", "{A5D7FC55-C9AB-493C-83FD-1966A86542FB}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "108-dotnet-custom-content-decoders", "examples\108-dotnet-custom-content-decoders\108-dotnet-custom-content-decoders.csproj", "{A5D7FC55-C9AB-493C-83FD-1966A86542FB}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "109-dotnet-custom-webscraper", "examples\109-dotnet-custom-webscraper\109-dotnet-custom-webscraper.csproj", "{8FB12876-013D-44CB-9F0D-E926D9F0F4E3}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "109-dotnet-custom-webscraper", "examples\109-dotnet-custom-webscraper\109-dotnet-custom-webscraper.csproj", "{8FB12876-013D-44CB-9F0D-E926D9F0F4E3}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "infra", "infra", "{B488168B-AD86-4CC5-9D89-324B6EB743D9}"
ProjectSection(SolutionItems) = preProject
+ infra\build-main.json.sh = infra\build-main.json.sh
infra\main.bicep = infra\main.bicep
infra\main.json = infra\main.json
infra\README.md = infra\README.md
- infra\build-main.json.sh = infra\build-main.json.sh
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "modules", "modules", "{C2D3A947-B6F9-4306-BD42-21D8D1F42750}"
@@ -254,13 +253,13 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "modules", "modules", "{C2D3
infra\modules\storage.bicep = infra\modules\storage.bicep
EndProjectSection
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Service.AspNetCore", "service\Service.AspNetCore\Service.AspNetCore.csproj", "{A46B0BE1-03F2-4520-A3DA-FD845BA1FD69}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Service.AspNetCore", "service\Service.AspNetCore\Service.AspNetCore.csproj", "{A46B0BE1-03F2-4520-A3DA-FD845BA1FD69}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "111-dotnet-azure-ai-hybrid-search", "examples\111-dotnet-azure-ai-hybrid-search\111-dotnet-azure-ai-hybrid-search.csproj", "{28534545-CB39-446A-9EB9-A5ABBFE0CFD3}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "111-dotnet-azure-ai-hybrid-search", "examples\111-dotnet-azure-ai-hybrid-search\111-dotnet-azure-ai-hybrid-search.csproj", "{28534545-CB39-446A-9EB9-A5ABBFE0CFD3}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TikToken", "extensions\TikToken\TikToken\TikToken.csproj", "{91757AC4-4FE3-40FE-96D6-1DDEDFB4A830}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TikToken", "extensions\TikToken\TikToken\TikToken.csproj", "{91757AC4-4FE3-40FE-96D6-1DDEDFB4A830}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TikToken.UnitTests", "extensions\TikToken\TikToken.UnitTests\TikToken.UnitTests.csproj", "{8ADA17CD-B779-4817-B10A-E9D7B019088D}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TikToken.UnitTests", "extensions\TikToken\TikToken.UnitTests\TikToken.UnitTests.csproj", "{8ADA17CD-B779-4817-B10A-E9D7B019088D}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "dotnet", "dotnet", "{2165A553-E07E-4FF7-90DA-3F3643EA690D}"
ProjectSection(SolutionItems) = preProject
@@ -269,116 +268,53 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "dotnet", "dotnet", "{2165A5
infra\dotnet\nuget-package.props = infra\dotnet\nuget-package.props
EndProjectSection
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SQLServer", "extensions\SQLServer\SQLServer\SQLServer.csproj", "{B9BE1099-F78F-4A5F-A897-BF2C75E19C57}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SQLServer", "extensions\SQLServer\SQLServer\SQLServer.csproj", "{B9BE1099-F78F-4A5F-A897-BF2C75E19C57}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elasticsearch", "extensions\Elasticsearch\Elasticsearch\Elasticsearch.csproj", "{2E10420F-BF96-411C-8FE0-F6268F2EEB67}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elasticsearch.UnitTests", "extensions\Elasticsearch\Elasticsearch.FunctionalTests\Elasticsearch.FunctionalTests.csproj", "{C5E6B28C-F54D-423D-954D-A9EAEFB89732}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
- GlobalSection(NestedProjects) = preSolution
- {3AAD973E-2FDC-4C89-94BA-4F6671C2F23A} = {5E7DD43D-B5E7-4827-B57D-447E5B428589}
- {4AE9DB51-2A22-4FB3-A780-838738566D18} = {5E7DD43D-B5E7-4827-B57D-447E5B428589}
- {C03BC9FE-5301-43EE-B912-1363F430DBA0} = {CA49F1A1-C3FA-4E99-ACB3-D7FF33D47976}
- {F7609330-E97E-422C-8983-EC501B2DDC52} = {371BB479-AA1C-41CB-BF07-24C363601289}
- {D04A01C0-EF1B-49B2-B6AB-8AC635566E6A} = {371BB479-AA1C-41CB-BF07-24C363601289}
- {8A9FA587-7EBA-4D43-BE47-38D798B1C74C} = {87DEAE8D-138C-4FDD-B4C9-11C3A7817E8F}
- {27910ADC-5A28-4EB4-A16E-974B91940758} = {87DEAE8D-138C-4FDD-B4C9-11C3A7817E8F}
- {1071A8B6-ED76-4E46-A291-E0563B9C4575} = {87DEAE8D-138C-4FDD-B4C9-11C3A7817E8F}
- {CA1D9162-D4C5-490D-AAD5-7A9A23092C28} = {0A43C65C-6007-4BB4-B3FE-8D439FC91841}
- {C93FCED9-808A-4B03-9B4C-0DBAE46D5BDD} = {0A43C65C-6007-4BB4-B3FE-8D439FC91841}
- {2C4D5F14-CCFC-4913-B884-B2FF9067BEFF} = {0A43C65C-6007-4BB4-B3FE-8D439FC91841}
- {A77F639B-EA35-4519-9DBF-54687E5AC895} = {0A43C65C-6007-4BB4-B3FE-8D439FC91841}
- {BCBEE522-6B4F-4C79-9E91-A34F4CCBF036} = {0A43C65C-6007-4BB4-B3FE-8D439FC91841}
- {6627ACE2-14FA-4A8E-A03C-0E4710B5411E} = {0A43C65C-6007-4BB4-B3FE-8D439FC91841}
- {158F5D5D-818B-4346-9A79-1C27C2F2144D} = {0A43C65C-6007-4BB4-B3FE-8D439FC91841}
- {6ABCC373-F472-4A34-9C78-4A324DDED207} = {0A43C65C-6007-4BB4-B3FE-8D439FC91841}
- {5E727FC9-ACE2-4028-AAA7-5BCECCE5010B} = {0A43C65C-6007-4BB4-B3FE-8D439FC91841}
- {55082AEB-0DEF-41F2-9616-DBDC22360379} = {0A43C65C-6007-4BB4-B3FE-8D439FC91841}
- {34FA6EE2-26FE-44D6-8F91-6A5E5A06074B} = {0A43C65C-6007-4BB4-B3FE-8D439FC91841}
- {791E3E2E-133C-4EB5-AB5E-10D31F0A9807} = {0A43C65C-6007-4BB4-B3FE-8D439FC91841}
- {DE115127-C77F-40FF-BA5A-E888A32F2289} = {0A43C65C-6007-4BB4-B3FE-8D439FC91841}
- {1B41A9A1-0B57-4297-B579-D04FC0BA3227} = {0A43C65C-6007-4BB4-B3FE-8D439FC91841}
- {10A6C940-AECC-4CEF-963E-9908DDA816B2} = {0A43C65C-6007-4BB4-B3FE-8D439FC91841}
- {9202380E-D793-4C3C-89B3-3BE790925029} = {0A43C65C-6007-4BB4-B3FE-8D439FC91841}
- {E762B1C6-4B5B-487A-BF8C-C6870D6EACB7} = {0A43C65C-6007-4BB4-B3FE-8D439FC91841}
- {EDFDA12E-BA10-4A00-BBE7-1C10A0B0F1A6} = {0A43C65C-6007-4BB4-B3FE-8D439FC91841}
- {BCD0255F-2F35-4B6D-BBF2-2FB43B6F95FA} = {5E7DD43D-B5E7-4827-B57D-447E5B428589}
- {20FFF62D-5BA5-4126-A16C-C14E1FF35A4F} = {155DA079-E267-49AF-973A-D1D44681970F}
- {40CB6452-68DD-4C78-9852-78281A161950} = {155DA079-E267-49AF-973A-D1D44681970F}
- {E3877E49-958E-4DC8-B5E8-834010F5C4B7} = {155DA079-E267-49AF-973A-D1D44681970F}
- {6577B501-E295-4DCE-B640-BF40C9881A00} = {155DA079-E267-49AF-973A-D1D44681970F}
- {CFE7C192-2561-40CC-8592-136293451EC1} = {155DA079-E267-49AF-973A-D1D44681970F}
- {93FA6DD6-D0B2-4751-8680-3F959E1F7AF2} = {155DA079-E267-49AF-973A-D1D44681970F}
- {A6AE31A1-4F60-47B0-8534-7B083D68118C} = {155DA079-E267-49AF-973A-D1D44681970F}
- {969625B8-039F-4E5E-A484-6A30DC417FBB} = {155DA079-E267-49AF-973A-D1D44681970F}
- {F25BC232-6161-4D45-8AFF-E92A52F0F85A} = {155DA079-E267-49AF-973A-D1D44681970F}
- {C4AFA538-8939-4525-A361-665833947F72} = {5E7DD43D-B5E7-4827-B57D-447E5B428589}
- {9D078C9B-42A3-4558-898A-2396F59A54D3} = {155DA079-E267-49AF-973A-D1D44681970F}
- {8F2185AB-F87C-4DD0-9DB8-E97920500A37} = {155DA079-E267-49AF-973A-D1D44681970F}
- {3C17F42B-CFC8-4900-8CFB-88936311E919} = {5E7DD43D-B5E7-4827-B57D-447E5B428589}
- {11445C36-1B94-4AFB-AC23-976C94924603} = {3C17F42B-CFC8-4900-8CFB-88936311E919}
- {E2AD3323-42AA-47D5-87E4-1E90B0A7C6E9} = {3C17F42B-CFC8-4900-8CFB-88936311E919}
- {0675D9B5-B3BB-4C9A-A1A5-11540E2ED715} = {3C17F42B-CFC8-4900-8CFB-88936311E919}
- {E9EAD4A8-05B8-4138-8B17-E33127C83CF4} = {3C17F42B-CFC8-4900-8CFB-88936311E919}
- {14106EE4-AB77-494D-B16A-3EC042539456} = {3C17F42B-CFC8-4900-8CFB-88936311E919}
- {3897E2B7-85A3-4D69-B1C0-AEF41236F940} = {3C17F42B-CFC8-4900-8CFB-88936311E919}
- {9FB79D60-E87E-420A-984D-C4D5DD2C3125} = {3C17F42B-CFC8-4900-8CFB-88936311E919}
- {CCA96699-483E-4B2A-95DF-25F0C98E3BB6} = {3C17F42B-CFC8-4900-8CFB-88936311E919}
- {62B96766-AA6C-4CFF-A6FB-6370C89C2509} = {3C17F42B-CFC8-4900-8CFB-88936311E919}
- {989061F4-164F-4D98-A3F9-601BC40EE216} = {5E7DD43D-B5E7-4827-B57D-447E5B428589}
- {668A48B7-F600-4056-B47E-3200893C0404} = {3C17F42B-CFC8-4900-8CFB-88936311E919}
- {C8A18E8F-34CC-4226-9831-083335DAB21A} = {3C17F42B-CFC8-4900-8CFB-88936311E919}
- {9D3C9277-648D-441D-834D-565076EE2E87} = {3C17F42B-CFC8-4900-8CFB-88936311E919}
- {C089DE42-9D39-4633-AC0C-5034BA0B98E1} = {3C17F42B-CFC8-4900-8CFB-88936311E919}
- {9F564F2D-EADD-47DE-9293-92B3E9CFFE36} = {3C17F42B-CFC8-4900-8CFB-88936311E919}
- {B8976338-7CDC-47AE-8502-C2FBAFBEBD68} = {6EF76FD8-4C35-4370-8539-5DDF45357A50}
- {D7D8FCA0-BFC6-4B0E-9885-64C2EA90AA62} = {0A43C65C-6007-4BB4-B3FE-8D439FC91841}
- {47CEEA8F-7858-4635-B902-4C704CF55EA0} = {0A43C65C-6007-4BB4-B3FE-8D439FC91841}
- {48E79819-1E9E-4075-90DA-BAEC761C89B2} = {B8976338-7CDC-47AE-8502-C2FBAFBEBD68}
- {A5CE3CB2-F746-4832-B239-1A3226F9BD48} = {0A43C65C-6007-4BB4-B3FE-8D439FC91841}
- {4A539320-EB49-4688-82E1-4FA0ADBB3810} = {155DA079-E267-49AF-973A-D1D44681970F}
- {8A602227-B291-4F1B-ACB8-237F49501B6A} = {3C17F42B-CFC8-4900-8CFB-88936311E919}
- {494B8590-F0B2-4D40-A895-F9D7BDF26250} = {0A43C65C-6007-4BB4-B3FE-8D439FC91841}
- {BC8057DA-CB40-4308-96FB-EF0100822BAD} = {0A43C65C-6007-4BB4-B3FE-8D439FC91841}
- {A5D7FC55-C9AB-493C-83FD-1966A86542FB} = {0A43C65C-6007-4BB4-B3FE-8D439FC91841}
- {8FB12876-013D-44CB-9F0D-E926D9F0F4E3} = {0A43C65C-6007-4BB4-B3FE-8D439FC91841}
- {C2D3A947-B6F9-4306-BD42-21D8D1F42750} = {B488168B-AD86-4CC5-9D89-324B6EB743D9}
- {A46B0BE1-03F2-4520-A3DA-FD845BA1FD69} = {87DEAE8D-138C-4FDD-B4C9-11C3A7817E8F}
- {28534545-CB39-446A-9EB9-A5ABBFE0CFD3} = {0A43C65C-6007-4BB4-B3FE-8D439FC91841}
- {91757AC4-4FE3-40FE-96D6-1DDEDFB4A830} = {155DA079-E267-49AF-973A-D1D44681970F}
- {8ADA17CD-B779-4817-B10A-E9D7B019088D} = {3C17F42B-CFC8-4900-8CFB-88936311E919}
- {B488168B-AD86-4CC5-9D89-324B6EB743D9} = {6EF76FD8-4C35-4370-8539-5DDF45357A50}
- {2165A553-E07E-4FF7-90DA-3F3643EA690D} = {B488168B-AD86-4CC5-9D89-324B6EB743D9}
- {B9BE1099-F78F-4A5F-A897-BF2C75E19C57} = {155DA079-E267-49AF-973A-D1D44681970F}
- EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{8A9FA587-7EBA-4D43-BE47-38D798B1C74C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8A9FA587-7EBA-4D43-BE47-38D798B1C74C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8A9FA587-7EBA-4D43-BE47-38D798B1C74C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8A9FA587-7EBA-4D43-BE47-38D798B1C74C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C4AFA538-8939-4525-A361-665833947F72}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C4AFA538-8939-4525-A361-665833947F72}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C4AFA538-8939-4525-A361-665833947F72}.Release|Any CPU.ActiveCfg = Release|Any CPU
{27910ADC-5A28-4EB4-A16E-974B91940758}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{27910ADC-5A28-4EB4-A16E-974B91940758}.Debug|Any CPU.Build.0 = Debug|Any CPU
{27910ADC-5A28-4EB4-A16E-974B91940758}.Release|Any CPU.ActiveCfg = Release|Any CPU
{27910ADC-5A28-4EB4-A16E-974B91940758}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4AE9DB51-2A22-4FB3-A780-838738566D18}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4AE9DB51-2A22-4FB3-A780-838738566D18}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4AE9DB51-2A22-4FB3-A780-838738566D18}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3AAD973E-2FDC-4C89-94BA-4F6671C2F23A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3AAD973E-2FDC-4C89-94BA-4F6671C2F23A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3AAD973E-2FDC-4C89-94BA-4F6671C2F23A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1071A8B6-ED76-4E46-A291-E0563B9C4575}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1071A8B6-ED76-4E46-A291-E0563B9C4575}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1071A8B6-ED76-4E46-A291-E0563B9C4575}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1071A8B6-ED76-4E46-A291-E0563B9C4575}.Release|Any CPU.Build.0 = Release|Any CPU
- {3AAD973E-2FDC-4C89-94BA-4F6671C2F23A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {3AAD973E-2FDC-4C89-94BA-4F6671C2F23A}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {3AAD973E-2FDC-4C89-94BA-4F6671C2F23A}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {4AE9DB51-2A22-4FB3-A780-838738566D18}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {4AE9DB51-2A22-4FB3-A780-838738566D18}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {4AE9DB51-2A22-4FB3-A780-838738566D18}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {F7609330-E97E-422C-8983-EC501B2DDC52}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {F7609330-E97E-422C-8983-EC501B2DDC52}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {F7609330-E97E-422C-8983-EC501B2DDC52}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {F7609330-E97E-422C-8983-EC501B2DDC52}.Release|Any CPU.Build.0 = Release|Any CPU
+ {BCD0255F-2F35-4B6D-BBF2-2FB43B6F95FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {BCD0255F-2F35-4B6D-BBF2-2FB43B6F95FA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {BCD0255F-2F35-4B6D-BBF2-2FB43B6F95FA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {989061F4-164F-4D98-A3F9-601BC40EE216}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {989061F4-164F-4D98-A3F9-601BC40EE216}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {989061F4-164F-4D98-A3F9-601BC40EE216}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C03BC9FE-5301-43EE-B912-1363F430DBA0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C03BC9FE-5301-43EE-B912-1363F430DBA0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C03BC9FE-5301-43EE-B912-1363F430DBA0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C03BC9FE-5301-43EE-B912-1363F430DBA0}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F7609330-E97E-422C-8983-EC501B2DDC52}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F7609330-E97E-422C-8983-EC501B2DDC52}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F7609330-E97E-422C-8983-EC501B2DDC52}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F7609330-E97E-422C-8983-EC501B2DDC52}.Release|Any CPU.Build.0 = Release|Any CPU
{D04A01C0-EF1B-49B2-B6AB-8AC635566E6A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D04A01C0-EF1B-49B2-B6AB-8AC635566E6A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D04A01C0-EF1B-49B2-B6AB-8AC635566E6A}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -386,15 +322,18 @@ Global
{A77F639B-EA35-4519-9DBF-54687E5AC895}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A77F639B-EA35-4519-9DBF-54687E5AC895}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A77F639B-EA35-4519-9DBF-54687E5AC895}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {BCBEE522-6B4F-4C79-9E91-A34F4CCBF036}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {BCBEE522-6B4F-4C79-9E91-A34F4CCBF036}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {BCBEE522-6B4F-4C79-9E91-A34F4CCBF036}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6627ACE2-14FA-4A8E-A03C-0E4710B5411E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6627ACE2-14FA-4A8E-A03C-0E4710B5411E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6627ACE2-14FA-4A8E-A03C-0E4710B5411E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {BCBEE522-6B4F-4C79-9E91-A34F4CCBF036}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {BCBEE522-6B4F-4C79-9E91-A34F4CCBF036}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {BCBEE522-6B4F-4C79-9E91-A34F4CCBF036}.Release|Any CPU.ActiveCfg = Release|Any CPU
{158F5D5D-818B-4346-9A79-1C27C2F2144D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{158F5D5D-818B-4346-9A79-1C27C2F2144D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{158F5D5D-818B-4346-9A79-1C27C2F2144D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A5CE3CB2-F746-4832-B239-1A3226F9BD48}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A5CE3CB2-F746-4832-B239-1A3226F9BD48}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A5CE3CB2-F746-4832-B239-1A3226F9BD48}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6ABCC373-F472-4A34-9C78-4A324DDED207}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6ABCC373-F472-4A34-9C78-4A324DDED207}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6ABCC373-F472-4A34-9C78-4A324DDED207}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -407,6 +346,12 @@ Global
{34FA6EE2-26FE-44D6-8F91-6A5E5A06074B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{34FA6EE2-26FE-44D6-8F91-6A5E5A06074B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{34FA6EE2-26FE-44D6-8F91-6A5E5A06074B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E762B1C6-4B5B-487A-BF8C-C6870D6EACB7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E762B1C6-4B5B-487A-BF8C-C6870D6EACB7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E762B1C6-4B5B-487A-BF8C-C6870D6EACB7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {EDFDA12E-BA10-4A00-BBE7-1C10A0B0F1A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {EDFDA12E-BA10-4A00-BBE7-1C10A0B0F1A6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EDFDA12E-BA10-4A00-BBE7-1C10A0B0F1A6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{791E3E2E-133C-4EB5-AB5E-10D31F0A9807}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{791E3E2E-133C-4EB5-AB5E-10D31F0A9807}.Debug|Any CPU.Build.0 = Debug|Any CPU
{791E3E2E-133C-4EB5-AB5E-10D31F0A9807}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -422,15 +367,12 @@ Global
{9202380E-D793-4C3C-89B3-3BE790925029}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9202380E-D793-4C3C-89B3-3BE790925029}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9202380E-D793-4C3C-89B3-3BE790925029}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {E762B1C6-4B5B-487A-BF8C-C6870D6EACB7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {E762B1C6-4B5B-487A-BF8C-C6870D6EACB7}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {E762B1C6-4B5B-487A-BF8C-C6870D6EACB7}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {EDFDA12E-BA10-4A00-BBE7-1C10A0B0F1A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {EDFDA12E-BA10-4A00-BBE7-1C10A0B0F1A6}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {EDFDA12E-BA10-4A00-BBE7-1C10A0B0F1A6}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {BCD0255F-2F35-4B6D-BBF2-2FB43B6F95FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {BCD0255F-2F35-4B6D-BBF2-2FB43B6F95FA}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {BCD0255F-2F35-4B6D-BBF2-2FB43B6F95FA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D7D8FCA0-BFC6-4B0E-9885-64C2EA90AA62}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D7D8FCA0-BFC6-4B0E-9885-64C2EA90AA62}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D7D8FCA0-BFC6-4B0E-9885-64C2EA90AA62}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {47CEEA8F-7858-4635-B902-4C704CF55EA0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {47CEEA8F-7858-4635-B902-4C704CF55EA0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {47CEEA8F-7858-4635-B902-4C704CF55EA0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{20FFF62D-5BA5-4126-A16C-C14E1FF35A4F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{20FFF62D-5BA5-4126-A16C-C14E1FF35A4F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{20FFF62D-5BA5-4126-A16C-C14E1FF35A4F}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -439,14 +381,6 @@ Global
{40CB6452-68DD-4C78-9852-78281A161950}.Debug|Any CPU.Build.0 = Debug|Any CPU
{40CB6452-68DD-4C78-9852-78281A161950}.Release|Any CPU.ActiveCfg = Release|Any CPU
{40CB6452-68DD-4C78-9852-78281A161950}.Release|Any CPU.Build.0 = Release|Any CPU
- {E3877E49-958E-4DC8-B5E8-834010F5C4B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {E3877E49-958E-4DC8-B5E8-834010F5C4B7}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {E3877E49-958E-4DC8-B5E8-834010F5C4B7}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {E3877E49-958E-4DC8-B5E8-834010F5C4B7}.Release|Any CPU.Build.0 = Release|Any CPU
- {6577B501-E295-4DCE-B640-BF40C9881A00}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {6577B501-E295-4DCE-B640-BF40C9881A00}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {6577B501-E295-4DCE-B640-BF40C9881A00}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {6577B501-E295-4DCE-B640-BF40C9881A00}.Release|Any CPU.Build.0 = Release|Any CPU
{CFE7C192-2561-40CC-8592-136293451EC1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CFE7C192-2561-40CC-8592-136293451EC1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CFE7C192-2561-40CC-8592-136293451EC1}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -455,17 +389,39 @@ Global
{93FA6DD6-D0B2-4751-8680-3F959E1F7AF2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{93FA6DD6-D0B2-4751-8680-3F959E1F7AF2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{93FA6DD6-D0B2-4751-8680-3F959E1F7AF2}.Release|Any CPU.Build.0 = Release|Any CPU
- {A6AE31A1-4F60-47B0-8534-7B083D68118C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {A6AE31A1-4F60-47B0-8534-7B083D68118C}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {A6AE31A1-4F60-47B0-8534-7B083D68118C}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {A6AE31A1-4F60-47B0-8534-7B083D68118C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {11445C36-1B94-4AFB-AC23-976C94924603}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {11445C36-1B94-4AFB-AC23-976C94924603}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {11445C36-1B94-4AFB-AC23-976C94924603}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {8F2185AB-F87C-4DD0-9DB8-E97920500A37}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {8F2185AB-F87C-4DD0-9DB8-E97920500A37}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8F2185AB-F87C-4DD0-9DB8-E97920500A37}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {8F2185AB-F87C-4DD0-9DB8-E97920500A37}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E2AD3323-42AA-47D5-87E4-1E90B0A7C6E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E2AD3323-42AA-47D5-87E4-1E90B0A7C6E9}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E2AD3323-42AA-47D5-87E4-1E90B0A7C6E9}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9F564F2D-EADD-47DE-9293-92B3E9CFFE36}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9F564F2D-EADD-47DE-9293-92B3E9CFFE36}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9F564F2D-EADD-47DE-9293-92B3E9CFFE36}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6577B501-E295-4DCE-B640-BF40C9881A00}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6577B501-E295-4DCE-B640-BF40C9881A00}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6577B501-E295-4DCE-B640-BF40C9881A00}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6577B501-E295-4DCE-B640-BF40C9881A00}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0675D9B5-B3BB-4C9A-A1A5-11540E2ED715}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0675D9B5-B3BB-4C9A-A1A5-11540E2ED715}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0675D9B5-B3BB-4C9A-A1A5-11540E2ED715}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E9EAD4A8-05B8-4138-8B17-E33127C83CF4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E9EAD4A8-05B8-4138-8B17-E33127C83CF4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E9EAD4A8-05B8-4138-8B17-E33127C83CF4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {14106EE4-AB77-494D-B16A-3EC042539456}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {14106EE4-AB77-494D-B16A-3EC042539456}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {14106EE4-AB77-494D-B16A-3EC042539456}.Release|Any CPU.ActiveCfg = Release|Any CPU
{969625B8-039F-4E5E-A484-6A30DC417FBB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{969625B8-039F-4E5E-A484-6A30DC417FBB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{969625B8-039F-4E5E-A484-6A30DC417FBB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{969625B8-039F-4E5E-A484-6A30DC417FBB}.Release|Any CPU.Build.0 = Release|Any CPU
- {0675D9B5-B3BB-4C9A-A1A5-11540E2ED715}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {0675D9B5-B3BB-4C9A-A1A5-11540E2ED715}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {0675D9B5-B3BB-4C9A-A1A5-11540E2ED715}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9D3C9277-648D-441D-834D-565076EE2E87}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9D3C9277-648D-441D-834D-565076EE2E87}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9D3C9277-648D-441D-834D-565076EE2E87}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CCA96699-483E-4B2A-95DF-25F0C98E3BB6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CCA96699-483E-4B2A-95DF-25F0C98E3BB6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CCA96699-483E-4B2A-95DF-25F0C98E3BB6}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -473,12 +429,9 @@ Global
{F25BC232-6161-4D45-8AFF-E92A52F0F85A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F25BC232-6161-4D45-8AFF-E92A52F0F85A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F25BC232-6161-4D45-8AFF-E92A52F0F85A}.Release|Any CPU.Build.0 = Release|Any CPU
- {C4AFA538-8939-4525-A361-665833947F72}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {C4AFA538-8939-4525-A361-665833947F72}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {C4AFA538-8939-4525-A361-665833947F72}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {E9EAD4A8-05B8-4138-8B17-E33127C83CF4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {E9EAD4A8-05B8-4138-8B17-E33127C83CF4}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {E9EAD4A8-05B8-4138-8B17-E33127C83CF4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C8A18E8F-34CC-4226-9831-083335DAB21A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C8A18E8F-34CC-4226-9831-083335DAB21A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C8A18E8F-34CC-4226-9831-083335DAB21A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9D078C9B-42A3-4558-898A-2396F59A54D3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9D078C9B-42A3-4558-898A-2396F59A54D3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9D078C9B-42A3-4558-898A-2396F59A54D3}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -489,49 +442,20 @@ Global
{3897E2B7-85A3-4D69-B1C0-AEF41236F940}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3897E2B7-85A3-4D69-B1C0-AEF41236F940}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3897E2B7-85A3-4D69-B1C0-AEF41236F940}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {11445C36-1B94-4AFB-AC23-976C94924603}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {11445C36-1B94-4AFB-AC23-976C94924603}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {11445C36-1B94-4AFB-AC23-976C94924603}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {8F2185AB-F87C-4DD0-9DB8-E97920500A37}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {8F2185AB-F87C-4DD0-9DB8-E97920500A37}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {8F2185AB-F87C-4DD0-9DB8-E97920500A37}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {8F2185AB-F87C-4DD0-9DB8-E97920500A37}.Release|Any CPU.Build.0 = Release|Any CPU
- {14106EE4-AB77-494D-B16A-3EC042539456}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {14106EE4-AB77-494D-B16A-3EC042539456}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {14106EE4-AB77-494D-B16A-3EC042539456}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {E2AD3323-42AA-47D5-87E4-1E90B0A7C6E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {E2AD3323-42AA-47D5-87E4-1E90B0A7C6E9}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {E2AD3323-42AA-47D5-87E4-1E90B0A7C6E9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{62B96766-AA6C-4CFF-A6FB-6370C89C2509}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{62B96766-AA6C-4CFF-A6FB-6370C89C2509}.Debug|Any CPU.Build.0 = Debug|Any CPU
{62B96766-AA6C-4CFF-A6FB-6370C89C2509}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {989061F4-164F-4D98-A3F9-601BC40EE216}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {989061F4-164F-4D98-A3F9-601BC40EE216}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {989061F4-164F-4D98-A3F9-601BC40EE216}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E3877E49-958E-4DC8-B5E8-834010F5C4B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E3877E49-958E-4DC8-B5E8-834010F5C4B7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E3877E49-958E-4DC8-B5E8-834010F5C4B7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E3877E49-958E-4DC8-B5E8-834010F5C4B7}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A6AE31A1-4F60-47B0-8534-7B083D68118C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A6AE31A1-4F60-47B0-8534-7B083D68118C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A6AE31A1-4F60-47B0-8534-7B083D68118C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A6AE31A1-4F60-47B0-8534-7B083D68118C}.Release|Any CPU.Build.0 = Release|Any CPU
{668A48B7-F600-4056-B47E-3200893C0404}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{668A48B7-F600-4056-B47E-3200893C0404}.Debug|Any CPU.Build.0 = Debug|Any CPU
{668A48B7-F600-4056-B47E-3200893C0404}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {C8A18E8F-34CC-4226-9831-083335DAB21A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {C8A18E8F-34CC-4226-9831-083335DAB21A}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {C8A18E8F-34CC-4226-9831-083335DAB21A}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {9D3C9277-648D-441D-834D-565076EE2E87}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {9D3C9277-648D-441D-834D-565076EE2E87}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {9D3C9277-648D-441D-834D-565076EE2E87}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {C089DE42-9D39-4633-AC0C-5034BA0B98E1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {C089DE42-9D39-4633-AC0C-5034BA0B98E1}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {C089DE42-9D39-4633-AC0C-5034BA0B98E1}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {9F564F2D-EADD-47DE-9293-92B3E9CFFE36}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {9F564F2D-EADD-47DE-9293-92B3E9CFFE36}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {9F564F2D-EADD-47DE-9293-92B3E9CFFE36}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {D7D8FCA0-BFC6-4B0E-9885-64C2EA90AA62}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {D7D8FCA0-BFC6-4B0E-9885-64C2EA90AA62}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {D7D8FCA0-BFC6-4B0E-9885-64C2EA90AA62}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {47CEEA8F-7858-4635-B902-4C704CF55EA0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {47CEEA8F-7858-4635-B902-4C704CF55EA0}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {47CEEA8F-7858-4635-B902-4C704CF55EA0}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {A5CE3CB2-F746-4832-B239-1A3226F9BD48}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {A5CE3CB2-F746-4832-B239-1A3226F9BD48}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {A5CE3CB2-F746-4832-B239-1A3226F9BD48}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4A539320-EB49-4688-82E1-4FA0ADBB3810}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4A539320-EB49-4688-82E1-4FA0ADBB3810}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4A539320-EB49-4688-82E1-4FA0ADBB3810}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -569,5 +493,95 @@ Global
{B9BE1099-F78F-4A5F-A897-BF2C75E19C57}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B9BE1099-F78F-4A5F-A897-BF2C75E19C57}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B9BE1099-F78F-4A5F-A897-BF2C75E19C57}.Release|Any CPU.Build.0 = Release|Any CPU
+ {2E10420F-BF96-411C-8FE0-F6268F2EEB67}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2E10420F-BF96-411C-8FE0-F6268F2EEB67}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2E10420F-BF96-411C-8FE0-F6268F2EEB67}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2E10420F-BF96-411C-8FE0-F6268F2EEB67}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C5E6B28C-F54D-423D-954D-A9EAEFB89732}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C5E6B28C-F54D-423D-954D-A9EAEFB89732}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C5E6B28C-F54D-423D-954D-A9EAEFB89732}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {C93FCED9-808A-4B03-9B4C-0DBAE46D5BDD} = {0A43C65C-6007-4BB4-B3FE-8D439FC91841}
+ {CA1D9162-D4C5-490D-AAD5-7A9A23092C28} = {0A43C65C-6007-4BB4-B3FE-8D439FC91841}
+ {2C4D5F14-CCFC-4913-B884-B2FF9067BEFF} = {0A43C65C-6007-4BB4-B3FE-8D439FC91841}
+ {B8976338-7CDC-47AE-8502-C2FBAFBEBD68} = {6EF76FD8-4C35-4370-8539-5DDF45357A50}
+ {48E79819-1E9E-4075-90DA-BAEC761C89B2} = {B8976338-7CDC-47AE-8502-C2FBAFBEBD68}
+ {3C17F42B-CFC8-4900-8CFB-88936311E919} = {5E7DD43D-B5E7-4827-B57D-447E5B428589}
+ {8A9FA587-7EBA-4D43-BE47-38D798B1C74C} = {87DEAE8D-138C-4FDD-B4C9-11C3A7817E8F}
+ {C4AFA538-8939-4525-A361-665833947F72} = {5E7DD43D-B5E7-4827-B57D-447E5B428589}
+ {27910ADC-5A28-4EB4-A16E-974B91940758} = {87DEAE8D-138C-4FDD-B4C9-11C3A7817E8F}
+ {4AE9DB51-2A22-4FB3-A780-838738566D18} = {5E7DD43D-B5E7-4827-B57D-447E5B428589}
+ {3AAD973E-2FDC-4C89-94BA-4F6671C2F23A} = {5E7DD43D-B5E7-4827-B57D-447E5B428589}
+ {1071A8B6-ED76-4E46-A291-E0563B9C4575} = {87DEAE8D-138C-4FDD-B4C9-11C3A7817E8F}
+ {BCD0255F-2F35-4B6D-BBF2-2FB43B6F95FA} = {5E7DD43D-B5E7-4827-B57D-447E5B428589}
+ {989061F4-164F-4D98-A3F9-601BC40EE216} = {5E7DD43D-B5E7-4827-B57D-447E5B428589}
+ {C03BC9FE-5301-43EE-B912-1363F430DBA0} = {CA49F1A1-C3FA-4E99-ACB3-D7FF33D47976}
+ {F7609330-E97E-422C-8983-EC501B2DDC52} = {371BB479-AA1C-41CB-BF07-24C363601289}
+ {D04A01C0-EF1B-49B2-B6AB-8AC635566E6A} = {371BB479-AA1C-41CB-BF07-24C363601289}
+ {A77F639B-EA35-4519-9DBF-54687E5AC895} = {0A43C65C-6007-4BB4-B3FE-8D439FC91841}
+ {6627ACE2-14FA-4A8E-A03C-0E4710B5411E} = {0A43C65C-6007-4BB4-B3FE-8D439FC91841}
+ {BCBEE522-6B4F-4C79-9E91-A34F4CCBF036} = {0A43C65C-6007-4BB4-B3FE-8D439FC91841}
+ {158F5D5D-818B-4346-9A79-1C27C2F2144D} = {0A43C65C-6007-4BB4-B3FE-8D439FC91841}
+ {A5CE3CB2-F746-4832-B239-1A3226F9BD48} = {0A43C65C-6007-4BB4-B3FE-8D439FC91841}
+ {6ABCC373-F472-4A34-9C78-4A324DDED207} = {0A43C65C-6007-4BB4-B3FE-8D439FC91841}
+ {5E727FC9-ACE2-4028-AAA7-5BCECCE5010B} = {0A43C65C-6007-4BB4-B3FE-8D439FC91841}
+ {55082AEB-0DEF-41F2-9616-DBDC22360379} = {0A43C65C-6007-4BB4-B3FE-8D439FC91841}
+ {34FA6EE2-26FE-44D6-8F91-6A5E5A06074B} = {0A43C65C-6007-4BB4-B3FE-8D439FC91841}
+ {E762B1C6-4B5B-487A-BF8C-C6870D6EACB7} = {0A43C65C-6007-4BB4-B3FE-8D439FC91841}
+ {EDFDA12E-BA10-4A00-BBE7-1C10A0B0F1A6} = {0A43C65C-6007-4BB4-B3FE-8D439FC91841}
+ {791E3E2E-133C-4EB5-AB5E-10D31F0A9807} = {0A43C65C-6007-4BB4-B3FE-8D439FC91841}
+ {DE115127-C77F-40FF-BA5A-E888A32F2289} = {0A43C65C-6007-4BB4-B3FE-8D439FC91841}
+ {1B41A9A1-0B57-4297-B579-D04FC0BA3227} = {0A43C65C-6007-4BB4-B3FE-8D439FC91841}
+ {10A6C940-AECC-4CEF-963E-9908DDA816B2} = {0A43C65C-6007-4BB4-B3FE-8D439FC91841}
+ {9202380E-D793-4C3C-89B3-3BE790925029} = {0A43C65C-6007-4BB4-B3FE-8D439FC91841}
+ {D7D8FCA0-BFC6-4B0E-9885-64C2EA90AA62} = {0A43C65C-6007-4BB4-B3FE-8D439FC91841}
+ {47CEEA8F-7858-4635-B902-4C704CF55EA0} = {0A43C65C-6007-4BB4-B3FE-8D439FC91841}
+ {20FFF62D-5BA5-4126-A16C-C14E1FF35A4F} = {155DA079-E267-49AF-973A-D1D44681970F}
+ {40CB6452-68DD-4C78-9852-78281A161950} = {155DA079-E267-49AF-973A-D1D44681970F}
+ {CFE7C192-2561-40CC-8592-136293451EC1} = {155DA079-E267-49AF-973A-D1D44681970F}
+ {93FA6DD6-D0B2-4751-8680-3F959E1F7AF2} = {155DA079-E267-49AF-973A-D1D44681970F}
+ {11445C36-1B94-4AFB-AC23-976C94924603} = {3C17F42B-CFC8-4900-8CFB-88936311E919}
+ {8F2185AB-F87C-4DD0-9DB8-E97920500A37} = {155DA079-E267-49AF-973A-D1D44681970F}
+ {E2AD3323-42AA-47D5-87E4-1E90B0A7C6E9} = {3C17F42B-CFC8-4900-8CFB-88936311E919}
+ {9F564F2D-EADD-47DE-9293-92B3E9CFFE36} = {3C17F42B-CFC8-4900-8CFB-88936311E919}
+ {6577B501-E295-4DCE-B640-BF40C9881A00} = {155DA079-E267-49AF-973A-D1D44681970F}
+ {0675D9B5-B3BB-4C9A-A1A5-11540E2ED715} = {3C17F42B-CFC8-4900-8CFB-88936311E919}
+ {E9EAD4A8-05B8-4138-8B17-E33127C83CF4} = {3C17F42B-CFC8-4900-8CFB-88936311E919}
+ {14106EE4-AB77-494D-B16A-3EC042539456} = {3C17F42B-CFC8-4900-8CFB-88936311E919}
+ {969625B8-039F-4E5E-A484-6A30DC417FBB} = {155DA079-E267-49AF-973A-D1D44681970F}
+ {9D3C9277-648D-441D-834D-565076EE2E87} = {3C17F42B-CFC8-4900-8CFB-88936311E919}
+ {CCA96699-483E-4B2A-95DF-25F0C98E3BB6} = {3C17F42B-CFC8-4900-8CFB-88936311E919}
+ {F25BC232-6161-4D45-8AFF-E92A52F0F85A} = {155DA079-E267-49AF-973A-D1D44681970F}
+ {C8A18E8F-34CC-4226-9831-083335DAB21A} = {3C17F42B-CFC8-4900-8CFB-88936311E919}
+ {9D078C9B-42A3-4558-898A-2396F59A54D3} = {155DA079-E267-49AF-973A-D1D44681970F}
+ {9FB79D60-E87E-420A-984D-C4D5DD2C3125} = {3C17F42B-CFC8-4900-8CFB-88936311E919}
+ {3897E2B7-85A3-4D69-B1C0-AEF41236F940} = {3C17F42B-CFC8-4900-8CFB-88936311E919}
+ {62B96766-AA6C-4CFF-A6FB-6370C89C2509} = {3C17F42B-CFC8-4900-8CFB-88936311E919}
+ {E3877E49-958E-4DC8-B5E8-834010F5C4B7} = {155DA079-E267-49AF-973A-D1D44681970F}
+ {A6AE31A1-4F60-47B0-8534-7B083D68118C} = {155DA079-E267-49AF-973A-D1D44681970F}
+ {668A48B7-F600-4056-B47E-3200893C0404} = {3C17F42B-CFC8-4900-8CFB-88936311E919}
+ {4A539320-EB49-4688-82E1-4FA0ADBB3810} = {155DA079-E267-49AF-973A-D1D44681970F}
+ {8A602227-B291-4F1B-ACB8-237F49501B6A} = {3C17F42B-CFC8-4900-8CFB-88936311E919}
+ {494B8590-F0B2-4D40-A895-F9D7BDF26250} = {0A43C65C-6007-4BB4-B3FE-8D439FC91841}
+ {BC8057DA-CB40-4308-96FB-EF0100822BAD} = {0A43C65C-6007-4BB4-B3FE-8D439FC91841}
+ {A5D7FC55-C9AB-493C-83FD-1966A86542FB} = {0A43C65C-6007-4BB4-B3FE-8D439FC91841}
+ {8FB12876-013D-44CB-9F0D-E926D9F0F4E3} = {0A43C65C-6007-4BB4-B3FE-8D439FC91841}
+ {B488168B-AD86-4CC5-9D89-324B6EB743D9} = {6EF76FD8-4C35-4370-8539-5DDF45357A50}
+ {C2D3A947-B6F9-4306-BD42-21D8D1F42750} = {B488168B-AD86-4CC5-9D89-324B6EB743D9}
+ {A46B0BE1-03F2-4520-A3DA-FD845BA1FD69} = {87DEAE8D-138C-4FDD-B4C9-11C3A7817E8F}
+ {28534545-CB39-446A-9EB9-A5ABBFE0CFD3} = {0A43C65C-6007-4BB4-B3FE-8D439FC91841}
+ {91757AC4-4FE3-40FE-96D6-1DDEDFB4A830} = {155DA079-E267-49AF-973A-D1D44681970F}
+ {8ADA17CD-B779-4817-B10A-E9D7B019088D} = {3C17F42B-CFC8-4900-8CFB-88936311E919}
+ {2165A553-E07E-4FF7-90DA-3F3643EA690D} = {B488168B-AD86-4CC5-9D89-324B6EB743D9}
+ {B9BE1099-F78F-4A5F-A897-BF2C75E19C57} = {155DA079-E267-49AF-973A-D1D44681970F}
+ {2E10420F-BF96-411C-8FE0-F6268F2EEB67} = {155DA079-E267-49AF-973A-D1D44681970F}
+ {C5E6B28C-F54D-423D-954D-A9EAEFB89732} = {3C17F42B-CFC8-4900-8CFB-88936311E919}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {CC136C62-115C-41D1-B414-F9473EFF6EA8}
EndGlobalSection
EndGlobal
diff --git a/extensions/Elasticsearch/Elasticsearch.FunctionalTests/DefaultTests.cs b/extensions/Elasticsearch/Elasticsearch.FunctionalTests/DefaultTests.cs
index b9352c5a8..f4d6f65ec 100644
--- a/extensions/Elasticsearch/Elasticsearch.FunctionalTests/DefaultTests.cs
+++ b/extensions/Elasticsearch/Elasticsearch.FunctionalTests/DefaultTests.cs
@@ -1,23 +1,21 @@
// Copyright (c) Microsoft. All rights reserved.
-#if FALSE
-using FreeMindLabs.KernelMemory.Elasticsearch;
-using Microsoft.Core.FunctionalTests.DefaultTestCases;
using Microsoft.KernelMemory;
-using Microsoft.TestHelpers;
+using Microsoft.KM.Core.FunctionalTests.DefaultTestCases;
+using Microsoft.KM.TestHelpers;
namespace Microsoft.Elasticsearch.FunctionalTests;
public class DefaultTests : BaseFunctionalTestCase
{
private readonly MemoryServerless _memory;
- private readonly ElasticsearchConfig _elasticsearchConfig;
+ private readonly ElasticsearchConfig _esConfig;
public DefaultTests(IConfiguration cfg, ITestOutputHelper output) : base(cfg, output)
{
Assert.False(string.IsNullOrEmpty(this.OpenAiConfig.APIKey));
- this._elasticsearchConfig = cfg.GetSection("KernelMemory:Services:Elasticsearch").Get()!;
+ this._esConfig = cfg.GetSection("KernelMemory:Services:Elasticsearch").Get()!;
this._memory = new KernelMemoryBuilder()
.With(new KernelMemoryConfig { DefaultIndexName = "default4tests" })
@@ -25,7 +23,7 @@ public DefaultTests(IConfiguration cfg, ITestOutputHelper output) : base(cfg, ou
.WithOpenAI(this.OpenAiConfig)
// .WithAzureOpenAITextGeneration(this.AzureOpenAITextConfiguration)
// .WithAzureOpenAITextEmbeddingGeneration(this.AzureOpenAIEmbeddingConfiguration)
- .WithElasticsearch(this._elasticsearchConfig)
+ .WithElasticsearch(this._esConfig)
.Build();
}
@@ -106,4 +104,3 @@ public async Task ItSupportsTags()
await DocumentUploadTest.ItSupportsTags(this._memory, this.Log);
}
}
-#endif
diff --git a/extensions/Elasticsearch/Elasticsearch.FunctionalTests/Elasticsearch.FunctionalTests.csproj b/extensions/Elasticsearch/Elasticsearch.FunctionalTests/Elasticsearch.FunctionalTests.csproj
index 0677c9d63..b4e634e1a 100644
--- a/extensions/Elasticsearch/Elasticsearch.FunctionalTests/Elasticsearch.FunctionalTests.csproj
+++ b/extensions/Elasticsearch/Elasticsearch.FunctionalTests/Elasticsearch.FunctionalTests.csproj
@@ -9,7 +9,7 @@
enable
false
false
- $(NoWarn);CA1859;
+ $(NoWarn);
diff --git a/extensions/Elasticsearch/Elasticsearch.UnitTests/README.md b/extensions/Elasticsearch/Elasticsearch.UnitTests/README.md
deleted file mode 100644
index 5d6ae2174..000000000
--- a/extensions/Elasticsearch/Elasticsearch.UnitTests/README.md
+++ /dev/null
@@ -1 +0,0 @@
-Placeholder folder for the Elasticsearch memory extension
\ No newline at end of file
diff --git a/extensions/Elasticsearch/Elasticsearch/CREDITS.txt b/extensions/Elasticsearch/Elasticsearch/CREDITS.txt
new file mode 100644
index 000000000..ce44857d1
--- /dev/null
+++ b/extensions/Elasticsearch/Elasticsearch/CREDITS.txt
@@ -0,0 +1,6 @@
+Special credits to Free Mind Labs, Inc. and Alessandro Federici
+for their work on the Elasticsearch Memory connector.
+
+The Elasticsearch was originally developed at
+https://github.com/freemindlabsinc/FreeMindLabs.KernelMemory.Elasticsearch
+and kindly submitted to Kernel Memory repository.
\ No newline at end of file
diff --git a/extensions/Elasticsearch/Elasticsearch/ConfigurationException.cs b/extensions/Elasticsearch/Elasticsearch/ConfigurationException.cs
new file mode 100644
index 000000000..c7f76f06b
--- /dev/null
+++ b/extensions/Elasticsearch/Elasticsearch/ConfigurationException.cs
@@ -0,0 +1,18 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+namespace Microsoft.KernelMemory.MemoryDb.Elasticsearch;
+
+///
+/// Exception thrown when the Elasticsearch configuration is invalid in appSettings, secrets, etc.
+///
+public class ConfigurationException : ElasticsearchException
+{
+ ///
+ public ConfigurationException() { }
+
+ ///
+ public ConfigurationException(string message) : base(message) { }
+
+ ///
+ public ConfigurationException(string message, Exception? innerException) : base(message, innerException) { }
+}
diff --git a/extensions/Elasticsearch/Elasticsearch/DependencyInjection.cs b/extensions/Elasticsearch/Elasticsearch/DependencyInjection.cs
new file mode 100644
index 000000000..6dcdd670b
--- /dev/null
+++ b/extensions/Elasticsearch/Elasticsearch/DependencyInjection.cs
@@ -0,0 +1,94 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+using Elastic.Clients.Elasticsearch;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.KernelMemory.MemoryDb.Elasticsearch;
+using Microsoft.KernelMemory.MemoryDb.Elasticsearch.Internals;
+using Microsoft.KernelMemory.MemoryStorage;
+
+#pragma warning disable IDE0130 // reduce number of "using" statements
+// ReSharper disable once CheckNamespace - reduce number of "using" statements
+namespace Microsoft.KernelMemory;
+
+///
+/// DI pipelines for Elasticsearch Memory.
+///
+public static partial class KernelMemoryBuilderExtensions
+{
+ ///
+ /// Kernel Memory Builder extension method to add the Elasticsearch memory connector.
+ ///
+ /// KM builder instance
+ /// Elasticsearch configuration"
+ public static IKernelMemoryBuilder WithElasticsearch(
+ this IKernelMemoryBuilder builder,
+ ElasticsearchConfig configuration)
+ {
+ builder.Services.AddElasticsearchAsMemoryDb(configuration);
+
+ return builder;
+ }
+
+ ///
+ /// Extension method to add the Elasticsearch memory connector.
+ ///
+ /// KM builder instance
+ /// Action to configure Elasticsearch
+ public static IKernelMemoryBuilder WithElasticsearch(
+ this IKernelMemoryBuilder builder,
+ Action configure)
+ {
+ ArgumentNullExceptionEx.ThrowIfNull(configure, nameof(configure), "The configure action is NULL");
+
+ var cfg = new ElasticsearchConfigBuilder();
+ configure(cfg);
+
+ builder.Services.AddElasticsearchAsMemoryDb(cfg.Build());
+ return builder;
+ }
+}
+
+///
+/// Setup Elasticsearch memory within the DI service collection.
+///
+public static partial class DependencyInjection
+{
+ ///
+ /// Inject Elasticsearch as the default implementation of IMemoryDb
+ ///
+ public static IServiceCollection AddElasticsearchAsMemoryDb(
+ this IServiceCollection services,
+ ElasticsearchConfig config)
+ {
+ ArgumentNullExceptionEx.ThrowIfNull(config, nameof(config), "The configuration is NULL");
+
+ // The ElasticsearchClient type is thread-safe and can be shared and
+ // reused across multiple threads in consuming applications.
+ // See https://www.elastic.co/guide/en/elasticsearch/client/net-api/current/recommendations.html
+ services.AddSingleton(sp =>
+ {
+ var esConfig = sp.GetRequiredService();
+ return new ElasticsearchClient(esConfig.ToElasticsearchClientSettings());
+ });
+
+ return services
+ .AddSingleton()
+ .AddSingleton(config)
+ .AddSingleton();
+ }
+
+ ///
+ /// Inject Elasticsearch as the default implementation of IMemoryDb
+ ///
+ public static IServiceCollection AddElasticsearchAsMemoryDb(
+ this IServiceCollection services,
+ Action configure)
+ {
+ ArgumentNullExceptionEx.ThrowIfNull(configure, nameof(configure), "The configuration action is NULL");
+
+ var cfg = new ElasticsearchConfigBuilder();
+ configure(cfg);
+
+ return services.AddElasticsearchAsMemoryDb(cfg.Build());
+ }
+}
diff --git a/extensions/Elasticsearch/Elasticsearch/Elasticsearch.csproj b/extensions/Elasticsearch/Elasticsearch/Elasticsearch.csproj
new file mode 100644
index 000000000..43b305d82
--- /dev/null
+++ b/extensions/Elasticsearch/Elasticsearch/Elasticsearch.csproj
@@ -0,0 +1,37 @@
+
+
+
+ net8.0
+ LatestMajor
+ Microsoft.KernelMemory.MemoryDb.Elasticsearch
+ Microsoft.KernelMemory.MemoryDb.Elasticsearch
+ $(NoWarn);KMEXP00;KMEXP03;CS1591;CA1308;CA1724;CA1812;
+ enable
+ enable
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ Microsoft.KernelMemory.MemoryDb.Elasticsearch
+ Elasticsearch connector for Kernel Memory
+ Elasticsearch connector for Microsoft Kernel Memory, to store and search memory using Elasticsearch vector search and other Elasticsearch features.
+ Elasticsearch Memory, RAG, Kernel Memory, Elasticsearch, HNSW, AI, Artificial Intelligence, Embeddings, Vector DB, Vector Search, ETL
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/extensions/Elasticsearch/Elasticsearch/ElasticsearchConfig.cs b/extensions/Elasticsearch/Elasticsearch/ElasticsearchConfig.cs
new file mode 100644
index 000000000..99bd9f7fc
--- /dev/null
+++ b/extensions/Elasticsearch/Elasticsearch/ElasticsearchConfig.cs
@@ -0,0 +1,60 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+using Elastic.Clients.Elasticsearch.Mapping;
+using Microsoft.KernelMemory.MemoryDb.Elasticsearch;
+
+#pragma warning disable IDE0130 // reduce number of "using" statements
+// ReSharper disable once CheckNamespace - reduce number of "using" statements
+namespace Microsoft.KernelMemory;
+
+///
+/// The configuration for the Elasticsearch connector.
+/// Use to instantiate and configure this class.
+///
+public class ElasticsearchConfig
+{
+ public ElasticsearchConfig()
+ {
+ }
+
+ ///
+ /// The certificate fingerprint for the Elasticsearch instance.
+ /// See .
+ ///
+ public string CertificateFingerPrint { get; set; } = string.Empty;
+
+ ///
+ /// The Elasticsearch endpoint.
+ ///
+ public string Endpoint { get; set; } = string.Empty;
+
+ ///
+ /// The username used to connect to Elasticsearch.
+ ///
+ public string UserName { get; set; } = string.Empty;
+
+ ///
+ /// The password used to connect to Elasticsearch.
+ ///
+ public string Password { get; set; } = string.Empty;
+
+ ///
+ /// The prefix to be prepend to the index names in Elasticsearch.
+ ///
+ public string IndexPrefix { get; set; } = string.Empty;
+
+ ///
+ /// The number of shards to use for the Elasticsearch index.
+ ///
+ public int? ShardCount { get; set; } = 1;
+
+ ///
+ /// The number of replicas to use for the Elasticsearch index.
+ ///
+ public int? ReplicaCount { get; set; } = 0;
+
+ ///
+ /// A delegate to configure the Elasticsearch index properties.
+ ///
+ public Action>? ConfigureProperties { get; internal set; }
+}
diff --git a/extensions/Elasticsearch/Elasticsearch/ElasticsearchConfigBuilder.cs b/extensions/Elasticsearch/Elasticsearch/ElasticsearchConfigBuilder.cs
new file mode 100644
index 000000000..7d183ec1a
--- /dev/null
+++ b/extensions/Elasticsearch/Elasticsearch/ElasticsearchConfigBuilder.cs
@@ -0,0 +1,177 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+using Microsoft.Extensions.Configuration;
+
+namespace Microsoft.KernelMemory.MemoryDb.Elasticsearch;
+
+///
+/// The builder for ElasticsearchConfig.
+///
+public class ElasticsearchConfigBuilder
+{
+ ///
+ /// The default Elasticsearch endpoint.
+ ///
+ public const string DefaultEndpoint = "https://localhost:9200";
+
+ ///
+ /// The default Elasticsearch username.
+ ///
+ public const string DefaultUserName = "elastic";
+
+ ///
+ /// The name of the section that will contain the configuration for Elasticsearch
+ /// (e.g. appSettings.json, user secrets, etc.).
+ ///
+ public const string DefaultSettingsSection = "Elasticsearch";
+
+ ///
+ /// The default prefix to be prepend to the index names in Elasticsearch.
+ ///
+ public const string DefaultIndexPrefix = "km.";
+
+ private ElasticsearchConfig _config;
+
+ ///
+ /// The default constructor.
+ ///
+ public ElasticsearchConfigBuilder()
+ {
+ this._config = new ElasticsearchConfig();
+ this.WithEndpoint(DefaultEndpoint)
+ .WithIndexPrefix(DefaultIndexPrefix)
+ .WithCertificateFingerPrint(string.Empty)
+ .WithUserNameAndPassword(DefaultUserName, string.Empty);
+ }
+
+ ///
+ /// Sets Elasticsearch endpoint to connect to.
+ ///
+ ///
+ ///
+ public ElasticsearchConfigBuilder WithEndpoint(string endpoint)
+ {
+ // TODO: validate URL
+ this._config.Endpoint = endpoint;
+ return this;
+ }
+
+ ///
+ /// Sets the username and password used to connect to Elasticsearch.
+ ///
+ ///
+ ///
+ ///
+ public ElasticsearchConfigBuilder WithUserNameAndPassword(string userName, string password)
+ {
+ this._config.UserName = userName;
+ this._config.Password = password;
+ return this;
+ }
+
+ ///
+ /// Sets the certificate fingerprint used to communicate with Elasticsearch.
+ /// See .
+ ///
+ ///
+ ///
+ public ElasticsearchConfigBuilder WithCertificateFingerPrint(string certificateFingerPrint)
+ {
+ this._config.CertificateFingerPrint = certificateFingerPrint;
+ return this;
+ }
+
+ ///
+ /// Sets the prefix to be prepend to the index names in Elasticsearch.
+ ///
+ ///
+ ///
+ public ElasticsearchConfigBuilder WithIndexPrefix(string indexPrefix)
+ {
+ this._config.IndexPrefix = indexPrefix;
+ return this;
+ }
+
+ ///
+ /// Validates the Elasticsearch configuration.
+ ///
+ ///
+ public ElasticsearchConfigBuilder Validate()
+ {
+ // TODO: improve this at some point
+ const string Prefix = "Invalid Elasticsearch configuration: missing ";
+
+ if (string.IsNullOrWhiteSpace(this._config.Endpoint))
+ {
+ throw new ConfigurationException(Prefix + $"{nameof(ElasticsearchConfig.Endpoint)}.");
+ }
+
+ if (string.IsNullOrWhiteSpace(this._config.UserName))
+ {
+ throw new ConfigurationException(Prefix + $"{nameof(ElasticsearchConfig.UserName)}.");
+ }
+
+ if (string.IsNullOrWhiteSpace(this._config.Password))
+ {
+ throw new ConfigurationException(Prefix + $"{nameof(ElasticsearchConfig.Password)}.");
+ }
+
+ if (string.IsNullOrWhiteSpace(this._config.CertificateFingerPrint))
+ {
+ throw new ConfigurationException(Prefix + $"{nameof(ElasticsearchConfig.CertificateFingerPrint)}");
+ }
+
+ return this;
+ }
+
+ ///
+ /// Reads the Elasticsearch configuration from the Services section of KernelMemory's configuration.
+ ///
+ ///
+ ///
+ public ElasticsearchConfigBuilder WithConfiguration(IConfiguration configuration)
+ {
+ const string SectionPath = "KernelMemory:Services:Elasticsearch";
+
+ var kmSvcEsSection = configuration.GetSection(SectionPath);
+ if (!kmSvcEsSection.Exists())
+ {
+ throw new ConfigurationException($"Missing configuration section {SectionPath}.");
+ }
+
+ this._config = new ElasticsearchConfig();
+ kmSvcEsSection.Bind(this._config);
+
+ configuration.Bind(SectionPath, this._config);
+
+ return this;
+ }
+
+ ///
+ /// Sets the number of shards and replicas to use for the Elasticsearch index.
+ ///
+ ///
+ ///
+ ///
+ public ElasticsearchConfigBuilder WithShardsAndReplicas(int shards, int replicas)
+ {
+ this._config.ShardCount = shards;
+ this._config.ReplicaCount = replicas;
+ return this;
+ }
+
+ ///
+ /// Builds the ElasticsearchConfig.
+ ///
+ /// Indicates if validation should be skipped.
+ ///
+ public ElasticsearchConfig Build(bool skipValidation = false)
+ {
+ if (!skipValidation)
+ {
+ this.Validate();
+ }
+
+ return this._config;
+ }
+}
diff --git a/extensions/Elasticsearch/Elasticsearch/ElasticsearchException.cs b/extensions/Elasticsearch/Elasticsearch/ElasticsearchException.cs
new file mode 100644
index 000000000..70fbe565c
--- /dev/null
+++ b/extensions/Elasticsearch/Elasticsearch/ElasticsearchException.cs
@@ -0,0 +1,18 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+namespace Microsoft.KernelMemory.MemoryDb.Elasticsearch;
+
+///
+/// Base exception for all the exceptions thrown by the Elasticsearch connector for KernelMemory
+///
+public class ElasticsearchException : KernelMemoryException
+{
+ ///
+ public ElasticsearchException() { }
+
+ ///
+ public ElasticsearchException(string message) : base(message) { }
+
+ ///
+ public ElasticsearchException(string message, Exception? innerException) : base(message, innerException) { }
+}
diff --git a/extensions/Elasticsearch/Elasticsearch/ElasticsearchMemory.cs b/extensions/Elasticsearch/Elasticsearch/ElasticsearchMemory.cs
new file mode 100644
index 000000000..7be1ba168
--- /dev/null
+++ b/extensions/Elasticsearch/Elasticsearch/ElasticsearchMemory.cs
@@ -0,0 +1,386 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+using System.Runtime.CompilerServices;
+using Elastic.Clients.Elasticsearch;
+using Elastic.Clients.Elasticsearch.Mapping;
+using Elastic.Clients.Elasticsearch.QueryDsl;
+using Microsoft.Extensions.Logging;
+using Microsoft.KernelMemory.AI;
+using Microsoft.KernelMemory.Diagnostics;
+using Microsoft.KernelMemory.MemoryDb.Elasticsearch.Internals;
+using Microsoft.KernelMemory.MemoryStorage;
+
+namespace Microsoft.KernelMemory.MemoryDb.Elasticsearch;
+
+///
+/// Elasticsearch connector for Kernel Memory.
+///
+public class ElasticsearchMemory : IMemoryDb
+{
+ private readonly ITextEmbeddingGenerator _embeddingGenerator;
+ private readonly IIndexNameHelper _indexNameHelper;
+ private readonly ElasticsearchConfig _config;
+ private readonly ILogger _log;
+ private readonly ElasticsearchClient _client;
+
+ ///
+ /// Create a new instance of Elasticsearch KM connector
+ ///
+ /// Elasticsearch configuration
+ /// Elasticsearch client
+ /// Application logger
+ /// Embedding generator
+ /// Index name helper
+ public ElasticsearchMemory(
+ ElasticsearchConfig config,
+ ElasticsearchClient client,
+ ITextEmbeddingGenerator embeddingGenerator,
+ IIndexNameHelper indexNameHelper,
+ ILogger? log = null)
+ {
+ ArgumentNullExceptionEx.ThrowIfNull(embeddingGenerator, nameof(embeddingGenerator), "The embedding generator is NULL");
+ ArgumentNullExceptionEx.ThrowIfNull(indexNameHelper, nameof(indexNameHelper), "The index name helper is NULL");
+ ArgumentNullExceptionEx.ThrowIfNull(config, nameof(config), "The configuration is NULL");
+
+ this._embeddingGenerator = embeddingGenerator;
+ this._indexNameHelper = indexNameHelper;
+ this._config = config;
+ this._client = client; // new ElasticsearchClient(this._config.ToElasticsearchClientSettings()); // TODO: inject
+ this._log = log ?? DefaultLogger.Instance;
+ }
+
+ ///
+ public async Task CreateIndexAsync(
+ string index,
+ int vectorSize,
+ CancellationToken cancellationToken = default)
+ {
+ index = this._indexNameHelper.Convert(index);
+
+ var existsResponse = await this._client.Indices.ExistsAsync(index, cancellationToken).ConfigureAwait(false);
+ if (existsResponse.Exists)
+ {
+ this._log.LogTrace("Index {Index} already exists.", index);
+ return;
+ }
+
+ var createIdxResponse = await this._client.Indices.CreateAsync(index,
+ cfg =>
+ {
+ cfg.Settings(setts =>
+ {
+ setts.NumberOfShards(this._config.ShardCount);
+ setts.NumberOfReplicas(this._config.ReplicaCount);
+ });
+ },
+ cancellationToken).ConfigureAwait(false);
+
+ const int Dimensions = 1536; // TODO: make not hardcoded
+
+ var np = new NestedProperty()
+ {
+ Properties = new Properties()
+ {
+ { ElasticsearchTag.NameField, new KeywordProperty() },
+ { ElasticsearchTag.ValueField, new KeywordProperty() }
+ }
+ };
+
+ var mapResponse = await this._client.Indices.PutMappingAsync(index, x => x
+ .Properties(propDesc =>
+ {
+ propDesc.Keyword(x => x.Id);
+ propDesc.Nested(ElasticsearchMemoryRecord.TagsField, np);
+ propDesc.Text(x => x.Payload, pd => pd.Index(false));
+ propDesc.Text(x => x.Content);
+ propDesc.DenseVector(x => x.Vector, d => d.Index(true).Dims(Dimensions).Similarity("cosine"));
+
+ this._config.ConfigureProperties?.Invoke(propDesc);
+ }),
+ cancellationToken).ConfigureAwait(false);
+
+ this._log.LogTrace("Index {Index} created.", index);
+ }
+
+ ///
+ public async Task> GetIndexesAsync(
+ CancellationToken cancellationToken = default)
+ {
+ var resp = await this._client.Indices.GetAsync(this._config.IndexPrefix + "*", cancellationToken).ConfigureAwait(false);
+
+ var names = resp.Indices
+ .Select(x => x.Key.ToString().Replace(this._config.IndexPrefix, string.Empty, StringComparison.Ordinal))
+ .ToHashSet(StringComparer.OrdinalIgnoreCase);
+
+ this._log.LogTrace("Returned {IndexCount} indices: {Indices}.", names.Count, string.Join(", ", names));
+
+ return names;
+ }
+
+ ///
+ public async Task DeleteIndexAsync(
+ string index,
+ CancellationToken cancellationToken = default)
+ {
+ index = this._indexNameHelper.Convert(index);
+
+ var delResponse = await this._client.Indices.DeleteAsync(
+ index,
+ cancellationToken).ConfigureAwait(false);
+
+ if (delResponse.IsSuccess())
+ {
+ this._log.LogTrace("Index {Index} deleted.", index);
+ }
+ else
+ {
+ this._log.LogWarning("Index {Index} delete failed.", index);
+ }
+ }
+
+ ///
+ public async Task DeleteAsync(
+ string index,
+ MemoryRecord record,
+ CancellationToken cancellationToken = default)
+ {
+ ArgumentNullExceptionEx.ThrowIfNull(record, nameof(record), "The record is NULL");
+ index = this._indexNameHelper.Convert(index);
+
+ var delResponse = await this._client.DeleteAsync(
+ index,
+ record.Id,
+ (delReq) =>
+ {
+ delReq.Refresh(Refresh.WaitFor);
+ },
+ cancellationToken)
+ .ConfigureAwait(false);
+
+ if (delResponse.IsSuccess())
+ {
+ this._log.LogTrace("Record {RecordId} deleted.", record.Id);
+ }
+ else
+ {
+ this._log.LogWarning("Record {RecordId} delete failed.", record.Id);
+ }
+ }
+
+ ///
+ public async Task UpsertAsync(
+ string index,
+ MemoryRecord record,
+ CancellationToken cancellationToken = default)
+ {
+ index = this._indexNameHelper.Convert(index);
+
+ var memRec = ElasticsearchMemoryRecord.FromMemoryRecord(record);
+
+ var response = await this._client.UpdateAsync(
+ index,
+ memRec.Id,
+ (updateReq) =>
+ {
+ updateReq.Refresh(Refresh.WaitFor);
+
+ var memRec2 = memRec;
+ updateReq.Doc(memRec2);
+ updateReq.DocAsUpsert(true);
+ },
+ cancellationToken)
+ .ConfigureAwait(false);
+
+ if (response.IsSuccess())
+ {
+ this._log.LogTrace("Record {RecordId} upserted.", memRec.Id);
+ }
+ else
+ {
+ this._log.LogError("Record {RecordId} upsert failed.", memRec.Id);
+ }
+
+ return response.Id;
+ }
+
+ ///
+ public async IAsyncEnumerable<(MemoryRecord, double)> GetSimilarListAsync(
+ string index,
+ string text,
+ ICollection? filters = null,
+ double minRelevance = 0, int limit = 1, bool withEmbeddings = false, [EnumeratorCancellation] CancellationToken cancellationToken = default)
+ {
+ if (limit < 0)
+ {
+ limit = 10;
+ }
+
+ index = this._indexNameHelper.Convert(index);
+
+ this._log.LogTrace("Searching for '{Text}' on index '{IndexName}' with filters {Filters}. {MinRelevance} {Limit} {WithEmbeddings}",
+ text, index, filters.ToDebugString(), minRelevance, limit, withEmbeddings);
+
+ Embedding embedding = await this._embeddingGenerator.GenerateEmbeddingAsync(text, cancellationToken).ConfigureAwait(false);
+ var coll = embedding.Data.ToArray();
+
+ var resp = await this._client.SearchAsync(s =>
+ s.Index(index)
+ .Knn(qd =>
+ {
+ qd.k(limit)
+ .Filter(q => this.ConvertTagFilters(q, filters))
+ .NumCandidates(limit + 100)
+ .Field(x => x.Vector)
+ .QueryVector(coll);
+ }),
+ cancellationToken)
+ .ConfigureAwait(false);
+
+ if ((resp.HitsMetadata is null) || (resp.HitsMetadata.Hits is null))
+ {
+ this._log.LogWarning("The search returned a null result. Should retry?");
+ yield break;
+ }
+
+ foreach (var hit in resp.HitsMetadata.Hits)
+ {
+ if (hit?.Source == null)
+ {
+ continue;
+ }
+
+ this._log.LogTrace("Hit: {HitScore}, {HitId}", hit.Score, hit.Id);
+ yield return (hit.Source!.ToMemoryRecord(), hit.Score ?? 0);
+ }
+ }
+
+ ///
+ public async IAsyncEnumerable GetListAsync(
+ string index,
+ ICollection? filters = null,
+ int limit = 1,
+ bool withEmbeddings = false,
+ [EnumeratorCancellation] CancellationToken cancellationToken = default)
+ {
+ this._log.LogTrace("Querying index '{IndexName}' with filters {Filters}. {Limit} {WithEmbeddings}",
+ index, filters.ToDebugString(), limit, withEmbeddings);
+
+ if (limit < 0)
+ {
+ limit = 10;
+ }
+
+ index = this._indexNameHelper.Convert(index);
+
+ var resp = await this._client.SearchAsync(s =>
+ s.Index(index)
+ .Size(limit)
+ .Query(qd =>
+ {
+ this.ConvertTagFilters(qd, filters);
+ }),
+ cancellationToken)
+ .ConfigureAwait(false);
+
+ if ((resp.HitsMetadata is null) || (resp.HitsMetadata.Hits is null))
+ {
+ yield break;
+ }
+
+ foreach (var hit in resp.Hits)
+ {
+ if (hit?.Source == null)
+ {
+ continue;
+ }
+
+ this._log.LogTrace("Hit: {HitScore}, {HitId}", hit.Score, hit.Id);
+ yield return hit.Source!.ToMemoryRecord();
+ }
+ }
+
+ //private string ConvertIndexName(string index) => ESIndexName.Convert(this._config.IndexPrefix + index);
+
+ private QueryDescriptor ConvertTagFilters(
+ QueryDescriptor qd,
+ ICollection? filters = null)
+ {
+ if ((filters == null) || (filters.Count == 0))
+ {
+ qd.MatchAll();
+ return qd;
+ }
+
+ filters = filters.Where(f => f.Keys.Count > 0)
+ .ToList(); // Remove empty filters
+
+ if (filters.Count == 0)
+ {
+ qd.MatchAll();
+ return qd;
+ }
+
+ foreach (MemoryFilter filter in filters)
+ {
+ List all = new();
+
+ // Each tag collection is an element of a List>>
+ foreach (var tagName in filter.Keys)
+ {
+ List tagValues = filter[tagName];
+ List terms = tagValues.Select(x => (FieldValue)(x ?? FieldValue.Null))
+ .ToList();
+ // ----------------
+ Query newTagQuery = new TermQuery(ElasticsearchMemoryRecord.TagsName) { Value = tagName };
+ newTagQuery &= new TermsQuery()
+ {
+ Field = ElasticsearchMemoryRecord.TagsValue,
+ Terms = new TermsQueryField(terms)
+ };
+ var nestedQd = new NestedQuery();
+ nestedQd.Path = ElasticsearchMemoryRecord.TagsField;
+ nestedQd.Query = newTagQuery;
+
+ all.Add(nestedQd);
+ qd.Bool(bq => bq.Must(all.ToArray()));
+ }
+ }
+
+ // ---------------------
+
+ //qd.Nested(nqd =>
+ //{
+ // nqd.Path(ElasticsearchMemoryRecord.TagsField);
+
+ // nqd.Query(nq =>
+ // {
+ // // Each filter is a tag collection.
+ // foreach (MemoryFilter filter in filters)
+ // {
+ // List all = new();
+
+ // // Each tag collection is an element of a List>>
+ // foreach (var tagName in filter.Keys)
+ // {
+ // List tagValues = filter[tagName];
+ // List terms = tagValues.Select(x => (FieldValue)(x ?? FieldValue.Null))
+ // .ToList();
+ // // ----------------
+
+ // Query newTagQuery = new TermQuery(ElasticsearchMemoryRecord.Tags_Name) { Value = tagName };
+ // newTagQuery &= new TermsQuery() {
+ // Field = ElasticsearchMemoryRecord.Tags_Value,
+ // Terms = new TermsQueryField(terms)
+ // };
+
+ // all.Add(newTagQuery);
+ // }
+
+ // nq.Bool(bq => bq.Must(all.ToArray()));
+ // }
+ // });
+ //});
+
+ return qd;
+ }
+}
diff --git a/extensions/Elasticsearch/Elasticsearch/ElasticsearchMemoryRecord.cs b/extensions/Elasticsearch/Elasticsearch/ElasticsearchMemoryRecord.cs
new file mode 100644
index 000000000..fe19784ec
--- /dev/null
+++ b/extensions/Elasticsearch/Elasticsearch/ElasticsearchMemoryRecord.cs
@@ -0,0 +1,139 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+using System.Text.Json;
+using System.Text.Json.Serialization;
+using Microsoft.KernelMemory.MemoryStorage;
+
+namespace Microsoft.KernelMemory.MemoryDb.Elasticsearch;
+
+///
+/// Elasticsearch record.
+///
+public sealed class ElasticsearchMemoryRecord
+{
+ internal const string IdField = "id";
+ internal const string EmbeddingField = "embedding";
+
+ ///
+ public const string TagsField = "tags";
+
+ ///
+ internal static readonly string TagsName = TagsField + "." + nameof(ElasticsearchTag.Name).ToLowerInvariant();
+
+ ///
+ internal static readonly string TagsValue = TagsField + "." + nameof(ElasticsearchTag.Value).ToLowerInvariant();
+
+ private const string PayloadField = "payload";
+ private const string ContentField = "content";
+
+ private static readonly JsonSerializerOptions s_jsonOptions = new()
+ {
+ AllowTrailingCommas = true,
+ MaxDepth = 10,
+ PropertyNameCaseInsensitive = true,
+ ReadCommentHandling = JsonCommentHandling.Disallow,
+ WriteIndented = false
+ };
+
+ ///
+ /// TBC
+ ///
+ [JsonPropertyName(IdField)]
+ public string Id { get; set; } = string.Empty;
+
+ ///
+ /// TBC
+ ///
+ [JsonPropertyName(TagsField)]
+ public List Tags { get; set; } = new();
+
+ ///
+ /// TBC
+ ///
+ [JsonPropertyName(PayloadField)]
+ public string Payload { get; set; } = string.Empty;
+
+ ///
+ /// TBC
+ ///
+ [JsonPropertyName(ContentField)]
+ public string Content { get; set; } = string.Empty;
+
+ ///
+ /// TBC
+ ///
+ [JsonPropertyName(EmbeddingField)]
+ [JsonConverter(typeof(Embedding.JsonConverter))]
+ public Embedding Vector { get; set; } = new();
+
+ ///
+ /// TBC
+ ///
+ public MemoryRecord ToMemoryRecord(bool withEmbedding = true)
+ {
+ MemoryRecord result = new()
+ {
+ Id = this.Id,
+ Payload = JsonSerializer.Deserialize>(this.Payload, s_jsonOptions)
+ ?? new Dictionary()
+ };
+ // TODO: remove magic string
+ result.Payload["text"] = this.Content;
+
+ if (withEmbedding)
+ {
+ result.Vector = this.Vector;
+ }
+
+ foreach (var tag in this.Tags)
+ {
+ result.Tags.Add(tag.Name, tag.Value);
+ }
+
+ return result;
+ }
+
+ ///
+ /// TBC
+ ///
+ ///
+ ///
+ public static ElasticsearchMemoryRecord FromMemoryRecord(MemoryRecord record)
+ {
+ ArgumentNullExceptionEx.ThrowIfNull(record, nameof(record), "The record is NULL");
+
+ // TODO: remove magic strings
+ string content = record.Payload["text"]?.ToString() ?? string.Empty;
+ string documentId = record.Tags["__document_id"][0] ?? string.Empty;
+ string filePart = record.Tags["__file_part"][0] ?? string.Empty;
+ string betterId = $"{documentId}|{filePart}";
+
+ record.Payload.Remove("text"); // We move the text to the content field. No need to index twice.
+
+ ElasticsearchMemoryRecord result = new()
+ {
+ Id = record.Id,
+ Vector = record.Vector,
+ Payload = JsonSerializer.Serialize(record.Payload, s_jsonOptions),
+ Content = content
+ };
+
+ foreach (var tag in record.Tags)
+ {
+ if (tag.Value == null || tag.Value.Count == 0)
+ {
+ // Key only, with no values
+ result.Tags.Add(new ElasticsearchTag(name: tag.Key));
+ continue;
+ }
+
+ foreach (var value in tag.Value)
+ {
+ // Key with one or more values
+ result.Tags.Add(new ElasticsearchTag(name: tag.Key, value: value));
+ }
+ }
+
+ return result;
+ }
+}
diff --git a/extensions/Elasticsearch/Elasticsearch/ElasticsearchTag.cs b/extensions/Elasticsearch/Elasticsearch/ElasticsearchTag.cs
new file mode 100644
index 000000000..a2330b46e
--- /dev/null
+++ b/extensions/Elasticsearch/Elasticsearch/ElasticsearchTag.cs
@@ -0,0 +1,47 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+using System.Text.Json.Serialization;
+
+namespace Microsoft.KernelMemory.MemoryDb.Elasticsearch;
+
+///
+/// An Elasticsearch tag.
+///
+public class ElasticsearchTag
+{
+ public const string NameField = "name";
+
+ public const string ValueField = "value";
+
+ ///
+ /// Instantiates a new instance of .
+ ///
+ ///
+ ///
+ ///
+ public ElasticsearchTag(string name, string? value = default)
+ {
+ ArgumentNullExceptionEx.ThrowIfNullOrWhiteSpace(name, nameof(name), "The tag name is NULL");
+
+ this.Name = name;
+ this.Value = value;
+ }
+
+ ///
+ /// The name of this tag.
+ ///
+ [JsonPropertyName(NameField)]
+ public string Name { get; set; } = string.Empty;
+
+ ///
+ /// The value of this tag.
+ ///
+ [JsonPropertyName(ValueField)]
+ public string? Value { get; set; }
+
+ ///
+ public override string ToString()
+ {
+ return $"{this.Name}={this.Value}";
+ }
+}
diff --git a/extensions/Elasticsearch/Elasticsearch/IIndexNameHelper.cs b/extensions/Elasticsearch/Elasticsearch/IIndexNameHelper.cs
new file mode 100644
index 000000000..4ff4c056d
--- /dev/null
+++ b/extensions/Elasticsearch/Elasticsearch/IIndexNameHelper.cs
@@ -0,0 +1,27 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+namespace Microsoft.KernelMemory.MemoryDb.Elasticsearch;
+
+///
+/// A utility class to help with Elasticsearch index names.
+/// It applies
+///
+public interface IIndexNameHelper
+{
+ ///
+ /// Attempts to convert the given index name to a valid Elasticsearch index name.
+ ///
+ /// The index name to convert.
+ /// The result of the conversion. The result includes the converted index name if the conversion succeeded, or a list of errors if the conversion failed.
+ /// A structure containing the actual index name or a list of errors if the conversion failed.
+ ///
+ public bool TryConvert(string indexName, out (string ActualIndexName, IEnumerable Errors) result);
+
+ ///
+ /// Converts the given index name to a valid Elasticsearch index name.
+ /// It throws an exception if the conversion fails.
+ ///
+ /// The index name to convert.
+ /// The converted index name.
+ public string Convert(string indexName);
+}
diff --git a/extensions/Elasticsearch/Elasticsearch/Internals/ElasticsearchConfigExtensions.cs b/extensions/Elasticsearch/Elasticsearch/Internals/ElasticsearchConfigExtensions.cs
new file mode 100644
index 000000000..b59354dd8
--- /dev/null
+++ b/extensions/Elasticsearch/Elasticsearch/Internals/ElasticsearchConfigExtensions.cs
@@ -0,0 +1,39 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+using Elastic.Clients.Elasticsearch;
+using Elastic.Transport;
+
+namespace Microsoft.KernelMemory.MemoryDb.Elasticsearch.Internals;
+
+///
+/// Elasticsearch configuration extensions.
+///
+internal static class ElasticsearchConfigExtensions
+{
+ ///
+ /// Converts an ElasticsearchConfig to a ElasticsearchClientSettings that can be used
+ /// to instantiate .
+ ///
+ public static ElasticsearchClientSettings ToElasticsearchClientSettings(this ElasticsearchConfig config)
+ {
+ ArgumentNullExceptionEx.ThrowIfNull(config, nameof(config), "The configuration is NULL");
+
+ // TODO: figure out the Dispose issue. It does not feel right.
+ // See https://www.elastic.co/guide/en/elasticsearch/client/net-api/current/_options_on_elasticsearchclientsettings.html
+#pragma warning disable CA2000 // Dispose objects before losing scope
+ return new ElasticsearchClientSettings(new Uri(config.Endpoint))
+
+ // TODO: this needs to be more flexible.
+ .Authentication(new BasicAuthentication(config.UserName, config.Password))
+ .DisableDirectStreaming(true)
+ // TODO: Not sure why I need this. Verify configuration maybe?
+ .ServerCertificateValidationCallback((sender, certificate, chain, errors) => true)
+ .CertificateFingerprint(config.CertificateFingerPrint)
+ .ThrowExceptions(true) // Much easier to work with
+#if DEBUG
+ .DisableDirectStreaming(true)
+#endif
+ ;
+#pragma warning restore CA2000 // Dispose objects before losing scope
+ }
+}
diff --git a/extensions/Elasticsearch/Elasticsearch/Internals/IndexNameHelper.cs b/extensions/Elasticsearch/Elasticsearch/Internals/IndexNameHelper.cs
new file mode 100644
index 000000000..f4c59bbb1
--- /dev/null
+++ b/extensions/Elasticsearch/Elasticsearch/Internals/IndexNameHelper.cs
@@ -0,0 +1,81 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+namespace Microsoft.KernelMemory.MemoryDb.Elasticsearch.Internals;
+
+///
+internal sealed class IndexNameHelper : IIndexNameHelper
+{
+ public IndexNameHelper(ElasticsearchConfig config)
+ {
+ this.IndexPrefix = config.IndexPrefix;
+ }
+
+ ///
+ /// The prefix to use for all index names.
+ ///
+ public string IndexPrefix { get; }
+
+ ///
+ public bool TryConvert(string indexName, out (string ActualIndexName, IEnumerable Errors) result)
+ {
+ // Convert to lowercase and replace underscores with hyphens to
+ // have a consistent behavior with other storage types supported by Kernel Memory. (see #18)
+ indexName = (this.IndexPrefix + indexName)
+ .Replace("_", "-", StringComparison.Ordinal)
+ .Trim()
+ .ToLowerInvariant();
+
+ // Check for null or whitespace
+ if (string.IsNullOrWhiteSpace(indexName))
+ {
+ result = ("default", Array.Empty());
+ return true;
+ }
+
+ var errors = new List();
+
+ // Check for invalid start characters
+ if (indexName.StartsWith('-') || indexName.StartsWith('_'))
+ {
+ errors.Add("An index name cannot start with a hyphen (-) or underscore (_).");
+ }
+
+ // Check for invalid characters
+ if (indexName.Any(x => !char.IsLetterOrDigit(x) && x != '-'))
+ {
+ errors.Add("An index name can only contain letters, digits, and hyphens (-).");
+ }
+
+ // Check for length (max 255 bytes)
+ if (System.Text.Encoding.UTF8.GetByteCount(indexName) > 255)
+ {
+ errors.Add("An index name cannot be longer than 255 bytes.");
+ }
+
+ // Avoid names that are dot-only or dot and numbers
+ if (indexName.All(c => c == '.' || char.IsDigit(c)))
+ {
+ errors.Add("Index name cannot be only dots or dots and numbers.");
+ }
+
+ if (errors.Count > 0)
+ {
+ result = (string.Empty, errors);
+ return false;
+ }
+
+ result = (indexName, Array.Empty());
+ return true;
+ }
+
+ ///
+ public string Convert(string indexName)
+ {
+ if (!this.TryConvert(indexName, out var result))
+ {
+ throw new InvalidIndexNameException(result);
+ }
+
+ return result.ActualIndexName;
+ }
+}
diff --git a/extensions/Elasticsearch/Elasticsearch/Internals/MemoryFilterExtensions.cs b/extensions/Elasticsearch/Elasticsearch/Internals/MemoryFilterExtensions.cs
new file mode 100644
index 000000000..bf5ad69cf
--- /dev/null
+++ b/extensions/Elasticsearch/Elasticsearch/Internals/MemoryFilterExtensions.cs
@@ -0,0 +1,43 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+namespace Microsoft.KernelMemory.MemoryDb.Elasticsearch.Internals;
+
+///
+/// Extensions methods for MemoryFilter.
+///
+internal static class MemoryFilterExtensions
+{
+ ///
+ /// Displays the MemoryFilter in a human-readable format.
+ ///
+ ///
+ ///
+ public static string ToDebugString(this MemoryFilter? filter)
+ {
+ if (filter == null)
+ {
+ return string.Empty;
+ }
+
+ // Prints all the tags in the record
+ var tags = filter.Select(x => $"({x.Key}={string.Join("|", x.Value)})");
+ return string.Join(" & ", tags);
+ }
+
+ ///
+ /// Displays the MemoryFilter(s) in a human-readable format.
+ ///
+ ///
+ ///
+ public static string ToDebugString(this IEnumerable? filters)
+ {
+ if (filters == null)
+ {
+ return string.Empty;
+ }
+
+ // Prints all the tags in the record
+ var tags = filters.Select(x => x.ToDebugString());
+ return string.Join(" & ", tags);
+ }
+}
diff --git a/extensions/Elasticsearch/Elasticsearch/InvalidIndexNameException.cs b/extensions/Elasticsearch/Elasticsearch/InvalidIndexNameException.cs
new file mode 100644
index 000000000..7935c3f1d
--- /dev/null
+++ b/extensions/Elasticsearch/Elasticsearch/InvalidIndexNameException.cs
@@ -0,0 +1,33 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+namespace Microsoft.KernelMemory.MemoryDb.Elasticsearch;
+
+///
+/// Exception thrown when an index name does pass Elasticsearch validation.
+///
+public class InvalidIndexNameException : ElasticsearchException
+{
+ ///
+ public InvalidIndexNameException(string indexName, IEnumerable errors, Exception? innerException = default)
+ : base($"The given index name '{indexName}' is invalid. {string.Join(", ", errors)}", innerException)
+ {
+ this.IndexName = indexName;
+ this.Errors = errors;
+ }
+
+ ///
+ public InvalidIndexNameException(
+ (string IndexName, IEnumerable Errors) conversionResult,
+ Exception? innerException = default)
+ => (this.IndexName, this.Errors) = conversionResult;
+
+ ///
+ /// The index name that failed validation.
+ ///
+ public string IndexName { get; }
+
+ ///
+ /// The list of errors that caused the validation to fail.
+ ///
+ public IEnumerable Errors { get; }
+}
diff --git a/extensions/Elasticsearch/Elasticsearch/README.md b/extensions/Elasticsearch/Elasticsearch/README.md
deleted file mode 100644
index 5d6ae2174..000000000
--- a/extensions/Elasticsearch/Elasticsearch/README.md
+++ /dev/null
@@ -1 +0,0 @@
-Placeholder folder for the Elasticsearch memory extension
\ No newline at end of file
diff --git a/extensions/Elasticsearch/README.md b/extensions/Elasticsearch/README.md
index d53c411d4..47a634e57 100644
--- a/extensions/Elasticsearch/README.md
+++ b/extensions/Elasticsearch/README.md
@@ -1,10 +1,9 @@
# Kernel Memory with Elasticsearch
-[](https://www.nuget.org/packages/FreeMindLabs.KernelMemory.Elasticsearch/)
+[](https://www.nuget.org/packages/Microsoft.KernelMemory.MemoryDb.Elasticsearch/)
[](https://aka.ms/KMdiscord)
-This folder contains tests for the [Elastisearch](https://www.elastic.co/) extension for Kernel Memory
-maintained by [FreemindLabs](https://github.com/freemindlabsinc/FreeMindLabs.KernelMemory.Elasticsearch).
+This folder contains tests for the [Elastisearch](https://www.elastic.co/) extension for Kernel Memory.
Configuration (appsettings.json):
@@ -41,5 +40,4 @@ the values in `appsettings.development.json`. For example:
For more information about the Elasticsearch extension:
-- https://github.com/freemindlabsinc/FreeMindLabs.KernelMemory.Elasticsearch
- https://devblogs.microsoft.com/semantic-kernel/elasticsearch-kernelmemory
diff --git a/extensions/Postgres/Postgres.TestApplication/Program.cs b/extensions/Postgres/Postgres.TestApplication/Program.cs
index b98da5eaa..aa42a88b0 100644
--- a/extensions/Postgres/Postgres.TestApplication/Program.cs
+++ b/extensions/Postgres/Postgres.TestApplication/Program.cs
@@ -3,7 +3,6 @@
using Microsoft.KernelMemory;
using Microsoft.KernelMemory.ContentStorage.DevTools;
using Microsoft.KernelMemory.FileSystem.DevTools;
-using Microsoft.KernelMemory.Postgres;
namespace Postgres.TestApplication;
diff --git a/extensions/Postgres/Postgres/DependencyInjection.cs b/extensions/Postgres/Postgres/DependencyInjection.cs
index cdce4c035..4c5d8e773 100644
--- a/extensions/Postgres/Postgres/DependencyInjection.cs
+++ b/extensions/Postgres/Postgres/DependencyInjection.cs
@@ -2,8 +2,11 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.KernelMemory.MemoryStorage;
+using Microsoft.KernelMemory.Postgres;
-namespace Microsoft.KernelMemory.Postgres;
+#pragma warning disable IDE0130 // reduce number of "using" statements
+// ReSharper disable once CheckNamespace - reduce number of "using" statements
+namespace Microsoft.KernelMemory;
///
/// Extensions for KernelMemoryBuilder
diff --git a/extensions/Redis/Redis/DependencyInjection.cs b/extensions/Redis/Redis/DependencyInjection.cs
index cc7171b2e..2069d7824 100644
--- a/extensions/Redis/Redis/DependencyInjection.cs
+++ b/extensions/Redis/Redis/DependencyInjection.cs
@@ -42,7 +42,7 @@ public static IKernelMemoryBuilder WithRedisMemoryDb(
}
///
-/// setup Redis memory within the semantic kernel
+/// Setup Redis memory within the DI service collection
///
public static partial class DependencyInjection
{
diff --git a/service/Service/ServiceConfiguration.cs b/service/Service/ServiceConfiguration.cs
index 67d2cb8bc..8f7ba3b54 100644
--- a/service/Service/ServiceConfiguration.cs
+++ b/service/Service/ServiceConfiguration.cs
@@ -11,7 +11,6 @@
using Microsoft.KernelMemory.MemoryStorage.DevTools;
using Microsoft.KernelMemory.MongoDbAtlas;
using Microsoft.KernelMemory.Pipeline.Queue.DevTools;
-using Microsoft.KernelMemory.Postgres;
namespace Microsoft.KernelMemory.Service;
diff --git a/service/tests/TestHelpers/TestHelpers.csproj b/service/tests/TestHelpers/TestHelpers.csproj
index b6acda00d..783508034 100644
--- a/service/tests/TestHelpers/TestHelpers.csproj
+++ b/service/tests/TestHelpers/TestHelpers.csproj
@@ -17,6 +17,7 @@
+