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 -[![Nuget package](https://img.shields.io/nuget/v/FreeMindLabs.KernelMemory.Elasticsearch)](https://www.nuget.org/packages/FreeMindLabs.KernelMemory.Elasticsearch/) +[![Nuget package](https://img.shields.io/nuget/v/Microsoft.KernelMemory.MemoryDb.Elasticsearch)](https://www.nuget.org/packages/Microsoft.KernelMemory.MemoryDb.Elasticsearch/) [![Discord](https://img.shields.io/discord/1063152441819942922?label=Discord&logo=discord&logoColor=white&color=d82679)](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 @@ +