diff --git a/AzureMcp.sln b/AzureMcp.sln new file mode 100644 index 0000000000..ba92595839 --- /dev/null +++ b/AzureMcp.sln @@ -0,0 +1,2403 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31903.59 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "core", "core", "{FBF56CC3-7AE6-AD2D-3F14-7F97FD322CD6}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Azure.Mcp.Core", "Azure.Mcp.Core", "{60ACCE40-218A-70DA-E578-61113823C3D1}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{7905BE8B-130A-154F-744E-8F5C373BB4A4}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Core", "core\Azure.Mcp.Core\src\Azure.Mcp.Core.csproj", "{8904FD57-96C7-434D-B4CD-99D2A7637ED3}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Microsoft.Mcp.Core", "Microsoft.Mcp.Core", "{D9C18059-AC6D-4A51-C1D3-5F3385C91125}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{1032D52E-0A23-303A-285B-3E580F3BFBA1}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Mcp.Core", "core\Microsoft.Mcp.Core\src\Microsoft.Mcp.Core.csproj", "{F849CD08-D4E4-4CDA-AB6F-D776EAFCD0E2}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{8F8E4A0B-9BF7-9BD7-A493-72F2DCAF9D32}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Core.LiveTests", "core\Azure.Mcp.Core\tests\Azure.Mcp.Core.LiveTests\Azure.Mcp.Core.LiveTests.csproj", "{F9FD0819-F62F-4979-81EF-0093CE31EEA7}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tests", "core\Azure.Mcp.Core\tests\Azure.Mcp.Tests\Azure.Mcp.Tests.csproj", "{5EEB08B8-FBBE-45ED-AB55-E5073308226B}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "servers", "servers", "{769B9289-B2AF-0079-2183-40A0D5B6CA35}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Azure.Mcp.Server", "Azure.Mcp.Server", "{F7E192D1-DE6C-42A2-B52F-02849D482450}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{143983D8-FD06-8E1F-BA6B-2BC51EF88F6F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Server", "servers\Azure.Mcp.Server\src\Azure.Mcp.Server.csproj", "{C7A151C3-2C9C-4C0F-8D07-0BB6630E821C}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tools", "tools", "{07C2787E-EAC7-C090-1BA3-A61EC2A24D84}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Azure.Mcp.Tools.Acr", "Azure.Mcp.Tools.Acr", "{157D81C5-4B8F-A378-5D75-7BAB039D1DC1}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{667E7915-06AD-1B48-0150-8A7F70E56563}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Acr", "tools\Azure.Mcp.Tools.Acr\src\Azure.Mcp.Tools.Acr.csproj", "{6EEBF2DB-8E44-4FB2-9157-2B46E23AD086}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Azure.Mcp.Tools.Aks", "Azure.Mcp.Tools.Aks", "{42698EC0-FB39-C569-8E8D-B1280AAEC8EB}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{12ABC2B4-C2CC-FC16-AE04-E7611E7F2628}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Aks", "tools\Azure.Mcp.Tools.Aks\src\Azure.Mcp.Tools.Aks.csproj", "{7C89F911-9624-4CC8-9268-57824064FCA7}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Azure.Mcp.Tools.AppConfig", "Azure.Mcp.Tools.AppConfig", "{A3A9055D-A201-082F-4C76-F1268653F9BB}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{25222008-2AE0-B613-C5A2-1843DE1A0697}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.AppConfig", "tools\Azure.Mcp.Tools.AppConfig\src\Azure.Mcp.Tools.AppConfig.csproj", "{AF90B213-1A45-477A-A958-2B9187AEAF54}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Azure.Mcp.Tools.AppLens", "Azure.Mcp.Tools.AppLens", "{F875D02C-2C2B-3465-24BB-4957ACDF70AD}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{BB85F6EF-A9D2-63B8-1A53-B68D57B18799}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.AppLens", "tools\Azure.Mcp.Tools.AppLens\src\Azure.Mcp.Tools.AppLens.csproj", "{3D4E5F6A-7B8C-9D0E-1F2A-3B4C5D6E7F8A}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Azure.Mcp.Tools.ApplicationInsights", "Azure.Mcp.Tools.ApplicationInsights", "{E19EB0A0-F682-2D4D-E69C-FF5DD6980CB7}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{EC9869D6-5301-5ADB-CC59-9E37821F5203}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.ApplicationInsights", "tools\Azure.Mcp.Tools.ApplicationInsights\src\Azure.Mcp.Tools.ApplicationInsights.csproj", "{E2C2A3E4-1D5F-4F6E-9A7F-1C2E54F893AB}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Azure.Mcp.Tools.AppService", "Azure.Mcp.Tools.AppService", "{03B49640-8ED6-23C8-1C29-10AEAF3F6973}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{A0C524B1-9E68-5D79-F404-7E079F138486}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.AppService", "tools\Azure.Mcp.Tools.AppService\src\Azure.Mcp.Tools.AppService.csproj", "{7828AB14-5E8B-4E60-B8AA-988E70573684}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Azure.Mcp.Tools.Authorization", "Azure.Mcp.Tools.Authorization", "{859FD998-B283-526A-0D29-2BE9DB23F127}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{DDC67B88-003A-BF20-18CC-988992D9F2DA}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Authorization", "tools\Azure.Mcp.Tools.Authorization\src\Azure.Mcp.Tools.Authorization.csproj", "{55FF4834-F1FE-47C1-AA8C-24DC4C3F171A}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Azure.Mcp.Tools.AzureBestPractices", "Azure.Mcp.Tools.AzureBestPractices", "{E98DC7CA-7D6E-CD95-7C38-7EC54C49A4BA}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{9ECC55D0-7405-7BFD-C0DD-D432F1A7556E}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.AzureBestPractices", "tools\Azure.Mcp.Tools.AzureBestPractices\src\Azure.Mcp.Tools.AzureBestPractices.csproj", "{DFDDA723-3307-4330-A154-A0F337A5E8EF}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Azure.Mcp.Tools.AzureIsv", "Azure.Mcp.Tools.AzureIsv", "{527E7737-8178-1F7B-CC32-0B66418AAAE3}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{AABD2F22-45E6-D373-CACB-1E42EBBB89E4}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.AzureIsv", "tools\Azure.Mcp.Tools.AzureIsv\src\Azure.Mcp.Tools.AzureIsv.csproj", "{51FF959C-5452-4611-B3DF-671D5D2FEF1E}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Azure.Mcp.Tools.ManagedLustre", "Azure.Mcp.Tools.ManagedLustre", "{9B70BA7E-5CCA-8859-C252-AF72C051F264}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{72886DEE-EE65-CAB4-D88E-95639D81D7B4}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.ManagedLustre", "tools\Azure.Mcp.Tools.ManagedLustre\src\Azure.Mcp.Tools.ManagedLustre.csproj", "{38EF7AE0-C6B0-4809-85EE-27A2C4F8F83B}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Azure.Mcp.Tools.AzureTerraformBestPractices", "Azure.Mcp.Tools.AzureTerraformBestPractices", "{3050869B-5B38-A2E1-E211-FDD96922C0D8}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{9E83E5D7-427F-F90E-BAF8-110976D8882A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.AzureTerraformBestPractices", "tools\Azure.Mcp.Tools.AzureTerraformBestPractices\src\Azure.Mcp.Tools.AzureTerraformBestPractices.csproj", "{F6B9B9A5-3A77-44F6-A349-50A751B46904}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Azure.Mcp.Tools.BicepSchema", "Azure.Mcp.Tools.BicepSchema", "{A6722C15-810E-881D-D81D-B31AFB74E906}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{BBC3EE4A-E86F-DF79-071D-BFF25E371E68}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.BicepSchema", "tools\Azure.Mcp.Tools.BicepSchema\src\Azure.Mcp.Tools.BicepSchema.csproj", "{744989A9-972B-4076-81FE-BFAB39EE899A}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Azure.Mcp.Tools.CloudArchitect", "Azure.Mcp.Tools.CloudArchitect", "{9E20BC7A-4871-E449-D7C1-4770293578A3}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{7C4CD8CB-4CAB-A05D-EBA1-82911CA4C7BB}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.CloudArchitect", "tools\Azure.Mcp.Tools.CloudArchitect\src\Azure.Mcp.Tools.CloudArchitect.csproj", "{E77DA2D5-7AFD-43D6-B77A-C22A1167B856}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Azure.Mcp.Tools.Communication", "Azure.Mcp.Tools.Communication", "{C512965D-7BB0-9820-B548-85E6E27E777F}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{63ADDEB0-FC34-0EAE-BA79-5E41D9CAA086}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Communication", "tools\Azure.Mcp.Tools.Communication\src\Azure.Mcp.Tools.Communication.csproj", "{D7B16F40-8636-4EE4-9F9A-77DF5A92EE03}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Azure.Mcp.Tools.ConfidentialLedger", "Azure.Mcp.Tools.ConfidentialLedger", "{59CA5914-CD73-F72D-5AE2-2588F9749673}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{6B5A97A9-D4ED-154B-D06B-95186CD1FF1C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.ConfidentialLedger", "tools\Azure.Mcp.Tools.ConfidentialLedger\src\Azure.Mcp.Tools.ConfidentialLedger.csproj", "{359D3A43-1DFB-4541-AC72-E63EF0D6B3C9}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Azure.Mcp.Tools.Cosmos", "Azure.Mcp.Tools.Cosmos", "{C3450695-99A5-5CF8-F6BD-D2019CEF67AE}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{5DDB903B-9950-F24C-C972-E88A4AADF5AC}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Cosmos", "tools\Azure.Mcp.Tools.Cosmos\src\Azure.Mcp.Tools.Cosmos.csproj", "{C8612FFE-7E8F-4EC4-B158-A4C2167A9AD5}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Azure.Mcp.Tools.Deploy", "Azure.Mcp.Tools.Deploy", "{19B1C41E-6924-9335-E5C4-0D3E2A03D547}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{D9515F83-9B0C-5D25-5D20-CC78FE8837D0}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Deploy", "tools\Azure.Mcp.Tools.Deploy\src\Azure.Mcp.Tools.Deploy.csproj", "{9924AEB8-EEB1-40EC-943B-DA1B9E610767}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Azure.Mcp.Tools.EventGrid", "Azure.Mcp.Tools.EventGrid", "{C0D09155-BD9F-CB19-962D-DAF1E886BDCF}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{33C33874-E52E-07CC-0DDA-2389CB6FF63D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.EventGrid", "tools\Azure.Mcp.Tools.EventGrid\src\Azure.Mcp.Tools.EventGrid.csproj", "{E1234567-1234-1234-1234-123456789012}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Azure.Mcp.Tools.EventHubs", "Azure.Mcp.Tools.EventHubs", "{8CB42B58-89CF-D92F-E189-16F031184C0B}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{40DBA547-7429-3933-14A0-AA798EF058C1}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.EventHubs", "tools\Azure.Mcp.Tools.EventHubs\src\Azure.Mcp.Tools.EventHubs.csproj", "{632DF404-7E5D-56B7-808D-816A3AB773A4}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Azure.Mcp.Tools.Extension", "Azure.Mcp.Tools.Extension", "{0D319E14-6DDE-C12F-A5B0-76EED797D651}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{917EE497-2381-F55E-88F6-47586FC57241}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Extension", "tools\Azure.Mcp.Tools.Extension\src\Azure.Mcp.Tools.Extension.csproj", "{2DF5CFE5-EF8D-4BE4-96D0-C256F2B52011}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Azure.Mcp.Tools.Foundry", "Azure.Mcp.Tools.Foundry", "{4179CBCC-D958-52F0-A182-FBFEBF000264}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{70CADE69-D2B1-ED23-4BCD-2FABD273428B}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Foundry", "tools\Azure.Mcp.Tools.Foundry\src\Azure.Mcp.Tools.Foundry.csproj", "{BA7AC885-A065-41F2-98FF-281C82994F7C}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Azure.Mcp.Tools.FunctionApp", "Azure.Mcp.Tools.FunctionApp", "{E938B49F-87B3-0DAA-220C-07320FBA6C2A}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{BF79F913-D6F2-E657-45D9-277597840EFA}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.FunctionApp", "tools\Azure.Mcp.Tools.FunctionApp\src\Azure.Mcp.Tools.FunctionApp.csproj", "{65F5AE53-C77A-4818-ADE1-B2D6973A68B9}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Azure.Mcp.Tools.Grafana", "Azure.Mcp.Tools.Grafana", "{0BD17E58-AFC9-6F1A-D335-FEEF8A424ECB}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{05E18918-DF6D-B73A-4C4A-4AEF98A73A1A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Grafana", "tools\Azure.Mcp.Tools.Grafana\src\Azure.Mcp.Tools.Grafana.csproj", "{E13EEC3A-6DEB-403D-98F5-E143A16F6E9D}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Azure.Mcp.Tools.KeyVault", "Azure.Mcp.Tools.KeyVault", "{F9BCFF5A-BB96-6495-0B41-71CBBD75CCD0}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{5C936215-2BB8-E193-B185-29FE7BBEA33F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.KeyVault", "tools\Azure.Mcp.Tools.KeyVault\src\Azure.Mcp.Tools.KeyVault.csproj", "{1DE3EF01-EB07-412F-82C9-9709D1981C77}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Azure.Mcp.Tools.Kusto", "Azure.Mcp.Tools.Kusto", "{E4043D9D-4D2E-D8B5-F79E-057177808F38}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{FFA8D48E-F9A9-6089-AB62-C90A740EA21E}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Kusto", "tools\Azure.Mcp.Tools.Kusto\src\Azure.Mcp.Tools.Kusto.csproj", "{3025876C-E9AF-4D37-98D2-4A7B56CAD3B1}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Azure.Mcp.Tools.LoadTesting", "Azure.Mcp.Tools.LoadTesting", "{2DD519C6-9156-B8C4-11E9-4269216495AD}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{96640177-9FE5-9698-15FE-FA6086540707}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.LoadTesting", "tools\Azure.Mcp.Tools.LoadTesting\src\Azure.Mcp.Tools.LoadTesting.csproj", "{19631370-84E9-45A5-B98F-0359499DB2FA}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Azure.Mcp.Tools.Marketplace", "Azure.Mcp.Tools.Marketplace", "{EB5334E6-670B-EC92-68F3-634AA8C9020E}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{59B172EF-E666-A44A-A88A-206F6A63264A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Marketplace", "tools\Azure.Mcp.Tools.Marketplace\src\Azure.Mcp.Tools.Marketplace.csproj", "{1F58262C-B95C-4EC3-95BF-469D7A56480E}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Azure.Mcp.Tools.Monitor", "Azure.Mcp.Tools.Monitor", "{3DC51C40-03E9-5066-4FB5-FF3E41C97E1F}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{F894982B-4C93-0C62-D6DA-E27C0A3503E4}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Monitor", "tools\Azure.Mcp.Tools.Monitor\src\Azure.Mcp.Tools.Monitor.csproj", "{168BAD1F-6D9B-4A41-9A40-CAA2766110EF}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Azure.Mcp.Tools.MySql", "Azure.Mcp.Tools.MySql", "{F4CC2172-46F8-04D7-FF11-4F95DDBB59E2}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{065991D2-6F8C-6F65-0E72-DC96953B87D8}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.MySql", "tools\Azure.Mcp.Tools.MySql\src\Azure.Mcp.Tools.MySql.csproj", "{916DF4C9-3EB7-4D2B-B727-6EEEBB049A80}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Azure.Mcp.Tools.Postgres", "Azure.Mcp.Tools.Postgres", "{898C8C6E-FC1C-58E1-FB62-BBE77ED42888}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{C1148A03-1886-DC1A-65F9-2AE3D2752F84}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Postgres", "tools\Azure.Mcp.Tools.Postgres\src\Azure.Mcp.Tools.Postgres.csproj", "{9CF26119-BE08-4C57-945B-2844481F6141}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Azure.Mcp.Tools.Quota", "Azure.Mcp.Tools.Quota", "{4CBFCE90-00AC-3F19-DC8C-C81357708F76}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{435A0E5F-27FA-99FA-C842-A91B522B4C1E}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Quota", "tools\Azure.Mcp.Tools.Quota\src\Azure.Mcp.Tools.Quota.csproj", "{A7A089BD-3128-48F8-8B18-E467BBA8C7FB}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Azure.Mcp.Tools.Redis", "Azure.Mcp.Tools.Redis", "{557B0DD6-D749-3FB3-AE6F-6C9843ACC451}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{C6D1966B-40C4-EADA-2021-D62EB362BC5D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Redis", "tools\Azure.Mcp.Tools.Redis\src\Azure.Mcp.Tools.Redis.csproj", "{9A740958-5F01-4121-84E6-6D05B369AE94}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Azure.Mcp.Tools.ResourceHealth", "Azure.Mcp.Tools.ResourceHealth", "{C6CEF4FB-0C38-F8A1-C3A9-84AA43EDFA2E}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{050FD842-8358-E96B-7D60-52669EEB9D25}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.ResourceHealth", "tools\Azure.Mcp.Tools.ResourceHealth\src\Azure.Mcp.Tools.ResourceHealth.csproj", "{C484A6D7-7798-4C8B-91DC-EA9909D627C8}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Azure.Mcp.Tools.Search", "Azure.Mcp.Tools.Search", "{38F57492-853E-43AB-A96A-0D16B88231B6}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{6B343355-29B5-2BBE-C966-B4AB2FB51F8E}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Search", "tools\Azure.Mcp.Tools.Search\src\Azure.Mcp.Tools.Search.csproj", "{9CCACC42-070F-4BB5-A06C-D5B7A1ABD519}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Azure.Mcp.Tools.ServiceBus", "Azure.Mcp.Tools.ServiceBus", "{1ED11E6E-94A0-E908-ACE4-8E9BD19CC7E1}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{075C408B-AC75-B3AA-88FB-1AE42826BD50}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.ServiceBus", "tools\Azure.Mcp.Tools.ServiceBus\src\Azure.Mcp.Tools.ServiceBus.csproj", "{F575C6A0-59AF-455D-8B7A-5421D4BAAA2F}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Azure.Mcp.Tools.SignalR", "Azure.Mcp.Tools.SignalR", "{84B02E00-2E23-1547-B733-D86A059C7EE0}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{717ED564-5195-F490-103F-F6C7788C6E34}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.SignalR", "tools\Azure.Mcp.Tools.SignalR\src\Azure.Mcp.Tools.SignalR.csproj", "{9B667E4D-C905-4CA4-B640-0F3B89293CA8}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Azure.Mcp.Tools.Speech", "Azure.Mcp.Tools.Speech", "{AB4067EC-C276-E50A-4A3C-F9DDFC3B9D29}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{7AC89CF8-E7AC-9EE9-D7AA-392DECC2CF04}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Speech", "tools\Azure.Mcp.Tools.Speech\src\Azure.Mcp.Tools.Speech.csproj", "{C3D4E5F6-7890-ABCD-EF12-345678901234}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Azure.Mcp.Tools.Sql", "Azure.Mcp.Tools.Sql", "{C64ABA23-B3DB-4B75-3019-7CBBB134BB29}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{04A069BA-F670-FF57-4260-3772155E86F2}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Sql", "tools\Azure.Mcp.Tools.Sql\src\Azure.Mcp.Tools.Sql.csproj", "{C84A54B1-BFF9-4394-A6BF-135C2FC37A64}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Azure.Mcp.Tools.Storage", "Azure.Mcp.Tools.Storage", "{ED9D3D4A-502F-41A4-BBCC-970E65472F33}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{0131AD4F-3934-F56E-5081-42129AD09143}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Storage", "tools\Azure.Mcp.Tools.Storage\src\Azure.Mcp.Tools.Storage.csproj", "{DE1B4312-1A4F-4774-B7EB-B1EC77F80D5E}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Azure.Mcp.Tools.VirtualDesktop", "Azure.Mcp.Tools.VirtualDesktop", "{B28A9B67-1C09-C756-C02A-7AC1895F9584}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{E38B6DEF-57A1-6CCA-498B-5697FF0B466C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.VirtualDesktop", "tools\Azure.Mcp.Tools.VirtualDesktop\src\Azure.Mcp.Tools.VirtualDesktop.csproj", "{3156A400-78C7-410A-9B79-9CDFFD5B94E3}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Azure.Mcp.Tools.Workbooks", "Azure.Mcp.Tools.Workbooks", "{90CD12FE-21C2-5151-E041-9FB96A3D0773}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{A9F0731A-101C-4664-E960-D159F9998165}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Workbooks", "tools\Azure.Mcp.Tools.Workbooks\src\Azure.Mcp.Tools.Workbooks.csproj", "{FCEFF719-E5F5-4BB6-83EF-17201FB14FF2}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Core.UnitTests", "core\Azure.Mcp.Core\tests\Azure.Mcp.Core.UnitTests\Azure.Mcp.Core.UnitTests.csproj", "{AE9E8273-2844-41A7-AE84-36E2F8B1B3DE}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Microsoft.Fabric.Mcp.Core", "Microsoft.Fabric.Mcp.Core", "{4BBEE4C4-18FC-AB55-A8B3-4C6BF70DF9AD}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{44C29C35-3F02-ECB8-1C42-1E60EABFA6B5}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Fabric.Mcp.Core", "core\Microsoft.Fabric.Mcp.Core\src\Microsoft.Fabric.Mcp.Core.csproj", "{B7418A46-E05D-4605-9BAE-8308BEF25641}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Template.Mcp.Core", "Template.Mcp.Core", "{1D0F574F-F118-FD2E-5A10-1304F36167C2}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{F04579C5-27C8-AFEE-B183-2AA2B0A14285}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Template.Mcp.Core", "core\Template.Mcp.Core\src\Template.Mcp.Core.csproj", "{E3F17DAA-1EFB-40F3-9F16-F77AF18893F2}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "eng", "eng", "{7525B257-249C-EE79-B10A-65D0BC27ABA9}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tools", "tools", "{DAAE2FFB-70A9-DCEF-23A0-0ABAED0A9720}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ToolDescriptionEvaluator", "eng\tools\ToolDescriptionEvaluator\ToolDescriptionEvaluator.csproj", "{1CB18013-ABED-48C1-8576-1E8ABCD70293}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Fabric.Mcp.Server", "Fabric.Mcp.Server", "{F4EFF172-8E25-E6E4-AFDD-640B2A635C0F}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{46F805EC-2E15-E63F-1946-C3BCA0EBE9E3}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Fabric.Mcp.Server", "servers\Fabric.Mcp.Server\src\Fabric.Mcp.Server.csproj", "{56650789-168A-427A-A354-7AF969417C47}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Fabric.Mcp.Tools.PublicApi", "Fabric.Mcp.Tools.PublicApi", "{9072C7AF-9EB2-E481-3974-77957587AC76}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{828CD049-D774-9906-6209-B6F1F7428EAF}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Fabric.Mcp.Tools.PublicApi", "tools\Fabric.Mcp.Tools.PublicApi\src\Fabric.Mcp.Tools.PublicApi.csproj", "{C11ED240-7ADE-43A2-7C2C-04463E5CCAA8}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Template.Mcp.Server", "Template.Mcp.Server", "{C761690B-E036-150F-CCBF-007CA2728C9D}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{C2F07CB4-6560-5C65-21A5-FF4953BB8CD9}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Template.Mcp.Server", "servers\Template.Mcp.Server\src\Template.Mcp.Server.csproj", "{7C56FC56-343A-4C68-AD1A-8C2CBC5DED74}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{15C060E2-796E-E031-E908-89DE5CD569D8}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Acr.LiveTests", "tools\Azure.Mcp.Tools.Acr\tests\Azure.Mcp.Tools.Acr.LiveTests\Azure.Mcp.Tools.Acr.LiveTests.csproj", "{8C5CED5B-ECB8-4847-9435-B7954055A530}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Acr.UnitTests", "tools\Azure.Mcp.Tools.Acr\tests\Azure.Mcp.Tools.Acr.UnitTests\Azure.Mcp.Tools.Acr.UnitTests.csproj", "{9131BD5D-B459-46AE-809D-F066B2FD119A}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{2F7EC3CB-1734-6B7C-0B17-6303A1B67019}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Aks.LiveTests", "tools\Azure.Mcp.Tools.Aks\tests\Azure.Mcp.Tools.Aks.LiveTests\Azure.Mcp.Tools.Aks.LiveTests.csproj", "{492A0B4A-C7EA-4469-814E-373B3DD90E6E}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Aks.UnitTests", "tools\Azure.Mcp.Tools.Aks\tests\Azure.Mcp.Tools.Aks.UnitTests\Azure.Mcp.Tools.Aks.UnitTests.csproj", "{9EB26D07-4530-44BA-BB2F-F5A20B86EF08}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{06C3F726-79B1-E9B3-C592-70534457DCBA}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.AppConfig.LiveTests", "tools\Azure.Mcp.Tools.AppConfig\tests\Azure.Mcp.Tools.AppConfig.LiveTests\Azure.Mcp.Tools.AppConfig.LiveTests.csproj", "{AACC56D7-3738-4C63-835F-A8373A084CFA}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.AppConfig.UnitTests", "tools\Azure.Mcp.Tools.AppConfig\tests\Azure.Mcp.Tools.AppConfig.UnitTests\Azure.Mcp.Tools.AppConfig.UnitTests.csproj", "{57C9E70F-2035-4217-8D35-C5498103E52C}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{6F99F316-9387-9CAC-AEB4-15F1E9D669C8}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.AppLens.UnitTests", "tools\Azure.Mcp.Tools.AppLens\tests\Azure.Mcp.Tools.AppLens.UnitTests\Azure.Mcp.Tools.AppLens.UnitTests.csproj", "{B2C3D4E5-F6A7-8901-BCDE-F23456789012}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{FA658F27-CA29-C4FC-A436-483AE994B789}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.ApplicationInsights.UnitTests", "tools\Azure.Mcp.Tools.ApplicationInsights\tests\Azure.Mcp.Tools.ApplicationInsights.UnitTests\Azure.Mcp.Tools.ApplicationInsights.UnitTests.csproj", "{C0F9D8F5-3F6D-4D46-9E6D-8A7E4EDC0E11}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{047042FC-DF09-5707-F2AE-666AE9547EAC}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.AppService.LiveTests", "tools\Azure.Mcp.Tools.AppService\tests\Azure.Mcp.Tools.AppService.LiveTests\Azure.Mcp.Tools.AppService.LiveTests.csproj", "{10E02570-BC66-4389-AD30-2E19CB9BD700}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.AppService.UnitTests", "tools\Azure.Mcp.Tools.AppService\tests\Azure.Mcp.Tools.AppService.UnitTests\Azure.Mcp.Tools.AppService.UnitTests.csproj", "{9D157338-0F03-4A4C-AD84-39E04B6368BF}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{D3FC126D-7888-673A-FB5D-D6AF5DE9603B}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Authorization.LiveTests", "tools\Azure.Mcp.Tools.Authorization\tests\Azure.Mcp.Tools.Authorization.LiveTests\Azure.Mcp.Tools.Authorization.LiveTests.csproj", "{55B6007F-5F58-4F33-91A5-677859BAE2D6}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Authorization.UnitTests", "tools\Azure.Mcp.Tools.Authorization\tests\Azure.Mcp.Tools.Authorization.UnitTests\Azure.Mcp.Tools.Authorization.UnitTests.csproj", "{1A9485FE-242C-4627-AC8D-9B36512162C4}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{53133BE3-FE0F-4EF8-8B39-42F749686075}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.AzureBestPractices.UnitTests", "tools\Azure.Mcp.Tools.AzureBestPractices\tests\Azure.Mcp.Tools.AzureBestPractices.UnitTests\Azure.Mcp.Tools.AzureBestPractices.UnitTests.csproj", "{AAF964F7-6902-4A7C-9F52-59FF502920D5}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{BEEC386F-2B6A-A601-7DF0-FDB8FC583F0B}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.AzureIsv.LiveTests", "tools\Azure.Mcp.Tools.AzureIsv\tests\Azure.Mcp.Tools.AzureIsv.LiveTests\Azure.Mcp.Tools.AzureIsv.LiveTests.csproj", "{FFA1F834-6049-474C-9EED-72E1A3F9646E}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.AzureIsv.UnitTests", "tools\Azure.Mcp.Tools.AzureIsv\tests\Azure.Mcp.Tools.AzureIsv.UnitTests\Azure.Mcp.Tools.AzureIsv.UnitTests.csproj", "{D3348F94-9831-4A3D-8E79-844900B88287}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{D80CC604-369B-AC81-8F7A-C731A7ABD68E}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.ManagedLustre.LiveTests", "tools\Azure.Mcp.Tools.ManagedLustre\tests\Azure.Mcp.Tools.ManagedLustre.LiveTests\Azure.Mcp.Tools.ManagedLustre.LiveTests.csproj", "{75A5A87C-BF04-4ABE-B466-874074D37C8D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.ManagedLustre.UnitTests", "tools\Azure.Mcp.Tools.ManagedLustre\tests\Azure.Mcp.Tools.ManagedLustre.UnitTests\Azure.Mcp.Tools.ManagedLustre.UnitTests.csproj", "{D1BCD822-AC8A-408F-A71A-9205DB29A9D2}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{A8D0F127-6ACB-380E-8423-B6B6EA1AF2DC}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.AzureTerraformBestPractices.UnitTests", "tools\Azure.Mcp.Tools.AzureTerraformBestPractices\tests\Azure.Mcp.Tools.AzureTerraformBestPractices.UnitTests\Azure.Mcp.Tools.AzureTerraformBestPractices.UnitTests.csproj", "{A99D3C27-65B7-4ADF-AB54-6D8649D1E7C7}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{18221FA7-BAC2-07BA-D54F-D567400B25DA}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.BicepSchema.UnitTests", "tools\Azure.Mcp.Tools.BicepSchema\tests\Azure.Mcp.Tools.BicepSchema.UnitTests\Azure.Mcp.Tools.BicepSchema.UnitTests.csproj", "{88780872-11A6-4014-B575-75C960EC0968}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{D03EF84F-1D93-1805-F24E-6781FF2EE6D9}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.CloudArchitect.UnitTests", "tools\Azure.Mcp.Tools.CloudArchitect\tests\Azure.Mcp.Tools.CloudArchitect.UnitTests\Azure.Mcp.Tools.CloudArchitect.UnitTests.csproj", "{2135A527-3910-44B5-A778-C5467D0A6148}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{FCBD2AD5-0A0E-7EFF-287B-AA167C8934A9}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Communication.LiveTests", "tools\Azure.Mcp.Tools.Communication\tests\Azure.Mcp.Tools.Communication.LiveTests\Azure.Mcp.Tools.Communication.LiveTests.csproj", "{02276871-6582-4A21-B629-83527FD90559}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Communication.UnitTests", "tools\Azure.Mcp.Tools.Communication\tests\Azure.Mcp.Tools.Communication.UnitTests\Azure.Mcp.Tools.Communication.UnitTests.csproj", "{DDF0DC50-766B-4E49-AA46-8D7F2370465A}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{6449F0B7-FD03-89F1-ED21-7DE8FE1BCD0A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.ConfidentialLedger.LiveTests", "tools\Azure.Mcp.Tools.ConfidentialLedger\tests\Azure.Mcp.Tools.ConfidentialLedger.LiveTests\Azure.Mcp.Tools.ConfidentialLedger.LiveTests.csproj", "{8F8153F8-6BED-4026-89A5-FEE2FEF7D379}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.ConfidentialLedger.UnitTests", "tools\Azure.Mcp.Tools.ConfidentialLedger\tests\Azure.Mcp.Tools.ConfidentialLedger.UnitTests\Azure.Mcp.Tools.ConfidentialLedger.UnitTests.csproj", "{FD1A0CD2-19BF-443E-9687-83E5B9E438EE}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{399EB16B-AE75-8AFC-99AF-1927C5624042}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Cosmos.LiveTests", "tools\Azure.Mcp.Tools.Cosmos\tests\Azure.Mcp.Tools.Cosmos.LiveTests\Azure.Mcp.Tools.Cosmos.LiveTests.csproj", "{F3AD707A-5E2D-4F58-BA21-691B4C7D1BA5}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Cosmos.UnitTests", "tools\Azure.Mcp.Tools.Cosmos\tests\Azure.Mcp.Tools.Cosmos.UnitTests\Azure.Mcp.Tools.Cosmos.UnitTests.csproj", "{B73E94EA-256E-4C1C-956B-0D4E67B5C82F}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{5629B6E3-0318-880C-B9FB-171A66E3835B}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Deploy.LiveTests", "tools\Azure.Mcp.Tools.Deploy\tests\Azure.Mcp.Tools.Deploy.LiveTests\Azure.Mcp.Tools.Deploy.LiveTests.csproj", "{BBE0307D-17C0-4A0A-9D7A-D8E9328A3CF7}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Deploy.UnitTests", "tools\Azure.Mcp.Tools.Deploy\tests\Azure.Mcp.Tools.Deploy.UnitTests\Azure.Mcp.Tools.Deploy.UnitTests.csproj", "{56B04873-1F4B-402E-88C0-528F006E3914}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{FD32D82B-24D4-2B38-C449-6062D56010E9}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.EventGrid.LiveTests", "tools\Azure.Mcp.Tools.EventGrid\tests\Azure.Mcp.Tools.EventGrid.LiveTests\Azure.Mcp.Tools.EventGrid.LiveTests.csproj", "{D4ADBF73-AE37-4614-9C07-8C71DC85F8EA}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.EventGrid.UnitTests", "tools\Azure.Mcp.Tools.EventGrid\tests\Azure.Mcp.Tools.EventGrid.UnitTests\Azure.Mcp.Tools.EventGrid.UnitTests.csproj", "{E1234569-1234-1234-1234-1234567890AE}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{DF6A3634-B09B-FAAE-C9A7-03F46588271A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.EventHubs.LiveTests", "tools\Azure.Mcp.Tools.EventHubs\tests\Azure.Mcp.Tools.EventHubs.LiveTests\Azure.Mcp.Tools.EventHubs.LiveTests.csproj", "{760CAD28-4792-44B8-77D1-0F42F47BD303}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.EventHubs.UnitTests", "tools\Azure.Mcp.Tools.EventHubs\tests\Azure.Mcp.Tools.EventHubs.UnitTests\Azure.Mcp.Tools.EventHubs.UnitTests.csproj", "{459CFD26-F5BC-B3C8-0632-DE7EA1504AD3}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{81E3F68B-68AA-1E51-D1D2-DE3FA9DB90AD}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Extension.UnitTests", "tools\Azure.Mcp.Tools.Extension\tests\Azure.Mcp.Tools.Extension.UnitTests\Azure.Mcp.Tools.Extension.UnitTests.csproj", "{CE923FCF-F208-4BC5-8C9B-AA54E2930993}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{2BABADA8-D4EC-AEA2-C105-00C894829DE1}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Foundry.LiveTests", "tools\Azure.Mcp.Tools.Foundry\tests\Azure.Mcp.Tools.Foundry.LiveTests\Azure.Mcp.Tools.Foundry.LiveTests.csproj", "{EB564D80-A767-4431-9918-16BE87407068}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Foundry.UnitTests", "tools\Azure.Mcp.Tools.Foundry\tests\Azure.Mcp.Tools.Foundry.UnitTests\Azure.Mcp.Tools.Foundry.UnitTests.csproj", "{DCC2034C-2F4A-4C72-A39C-58E108055E70}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{3749EF6E-907A-D4F8-B2FD-A6C27C0C1C55}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.FunctionApp.LiveTests", "tools\Azure.Mcp.Tools.FunctionApp\tests\Azure.Mcp.Tools.FunctionApp.LiveTests\Azure.Mcp.Tools.FunctionApp.LiveTests.csproj", "{E6AD3B7D-5ED5-43E6-A139-607A3F03FF00}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.FunctionApp.UnitTests", "tools\Azure.Mcp.Tools.FunctionApp\tests\Azure.Mcp.Tools.FunctionApp.UnitTests\Azure.Mcp.Tools.FunctionApp.UnitTests.csproj", "{C3327B63-4141-4D49-AE04-FA6A36FBDC9F}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{97BD5054-B44C-2CB3-7133-19D3965C6D42}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Grafana.LiveTests", "tools\Azure.Mcp.Tools.Grafana\tests\Azure.Mcp.Tools.Grafana.LiveTests\Azure.Mcp.Tools.Grafana.LiveTests.csproj", "{AE374EE8-1500-46BF-92C1-AA921B679E19}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Grafana.UnitTests", "tools\Azure.Mcp.Tools.Grafana\tests\Azure.Mcp.Tools.Grafana.UnitTests\Azure.Mcp.Tools.Grafana.UnitTests.csproj", "{05C411F3-C725-47EC-9441-650DA9DEB322}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{949474CC-6E94-7345-61BC-6D63A88C0FCD}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.KeyVault.LiveTests", "tools\Azure.Mcp.Tools.KeyVault\tests\Azure.Mcp.Tools.KeyVault.LiveTests\Azure.Mcp.Tools.KeyVault.LiveTests.csproj", "{666D3414-8801-4BB9-B49A-656D5D65ADC9}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.KeyVault.UnitTests", "tools\Azure.Mcp.Tools.KeyVault\tests\Azure.Mcp.Tools.KeyVault.UnitTests\Azure.Mcp.Tools.KeyVault.UnitTests.csproj", "{B82ECFF7-7F47-44A8-B947-1AC4E1AAB952}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{5BB0F909-6B8E-7953-568A-56247A9BE7D9}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Kusto.LiveTests", "tools\Azure.Mcp.Tools.Kusto\tests\Azure.Mcp.Tools.Kusto.LiveTests\Azure.Mcp.Tools.Kusto.LiveTests.csproj", "{223D1AA3-8756-4394-BDB8-0C20737C36F4}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Kusto.UnitTests", "tools\Azure.Mcp.Tools.Kusto\tests\Azure.Mcp.Tools.Kusto.UnitTests\Azure.Mcp.Tools.Kusto.UnitTests.csproj", "{746C9DFE-3D0E-4D4D-9AE2-D85D7250075F}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{FB0433B6-88B8-3F40-695F-E02336F620D7}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.LoadTesting.LiveTests", "tools\Azure.Mcp.Tools.LoadTesting\tests\Azure.Mcp.Tools.LoadTesting.LiveTests\Azure.Mcp.Tools.LoadTesting.LiveTests.csproj", "{6B594222-0B9E-4CDE-A49E-C3CCB65815FD}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.LoadTesting.UnitTests", "tools\Azure.Mcp.Tools.LoadTesting\tests\Azure.Mcp.Tools.LoadTesting.UnitTests\Azure.Mcp.Tools.LoadTesting.UnitTests.csproj", "{F009F428-7BBE-41FE-AD55-D19B4947E978}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{D5394AFD-90BE-8F1D-1BC6-C1A4C372E9EC}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Marketplace.LiveTests", "tools\Azure.Mcp.Tools.Marketplace\tests\Azure.Mcp.Tools.Marketplace.LiveTests\Azure.Mcp.Tools.Marketplace.LiveTests.csproj", "{751F96A2-DB60-4B40-A415-0924FEEFFD9C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Marketplace.UnitTests", "tools\Azure.Mcp.Tools.Marketplace\tests\Azure.Mcp.Tools.Marketplace.UnitTests\Azure.Mcp.Tools.Marketplace.UnitTests.csproj", "{4D7B1DE3-D04E-48A2-A904-A3288F0A519C}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{33685B87-9DF7-C305-879A-BD3EFDA3A055}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Monitor.LiveTests", "tools\Azure.Mcp.Tools.Monitor\tests\Azure.Mcp.Tools.Monitor.LiveTests\Azure.Mcp.Tools.Monitor.LiveTests.csproj", "{57832DF2-FD7F-4E26-AD7C-5D6608582978}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Monitor.UnitTests", "tools\Azure.Mcp.Tools.Monitor\tests\Azure.Mcp.Tools.Monitor.UnitTests\Azure.Mcp.Tools.Monitor.UnitTests.csproj", "{A3143C31-7C1C-4D7C-8819-3901238942C4}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{BE4DDD77-798F-8692-0C2A-2A9637256ED2}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.MySql.UnitTests", "tools\Azure.Mcp.Tools.MySql\tests\Azure.Mcp.Tools.MySql.UnitTests\Azure.Mcp.Tools.MySql.UnitTests.csproj", "{7C1FC1A3-5E52-45A8-B136-0934ADD5580C}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{37B0CE47-14C8-F5BF-BDDD-13EEBE580A88}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Postgres.UnitTests", "tools\Azure.Mcp.Tools.Postgres\tests\Azure.Mcp.Tools.Postgres.UnitTests\Azure.Mcp.Tools.Postgres.UnitTests.csproj", "{6CFDFF50-A41A-4A5E-A66A-670DB707495F}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{7F099BC4-FAF9-0D5C-A860-45BB7185CE13}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Quota.LiveTests", "tools\Azure.Mcp.Tools.Quota\tests\Azure.Mcp.Tools.Quota.LiveTests\Azure.Mcp.Tools.Quota.LiveTests.csproj", "{2C7B96D1-085F-4BCA-8D7D-3047765E3492}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Quota.UnitTests", "tools\Azure.Mcp.Tools.Quota\tests\Azure.Mcp.Tools.Quota.UnitTests\Azure.Mcp.Tools.Quota.UnitTests.csproj", "{B3167A7D-CF85-4A5F-B1CF-F14013782F1D}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{1801FC80-908A-890E-88E4-ACF8F9AFE528}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Redis.LiveTests", "tools\Azure.Mcp.Tools.Redis\tests\Azure.Mcp.Tools.Redis.LiveTests\Azure.Mcp.Tools.Redis.LiveTests.csproj", "{73372025-CB29-4EF4-95A9-0CAF91D94439}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Redis.UnitTests", "tools\Azure.Mcp.Tools.Redis\tests\Azure.Mcp.Tools.Redis.UnitTests\Azure.Mcp.Tools.Redis.UnitTests.csproj", "{35D2CE3D-B792-49E1-BB6D-532313196821}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{D8A7DFC5-CCD4-4A12-4328-1AC572B64833}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.ResourceHealth.UnitTests", "tools\Azure.Mcp.Tools.ResourceHealth\tests\Azure.Mcp.Tools.ResourceHealth.UnitTests\Azure.Mcp.Tools.ResourceHealth.UnitTests.csproj", "{A2F1FFAF-0BE1-4020-B09B-3DFB91B48816}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{29F1A95F-AE4F-0723-BE37-14C42415E8D9}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Search.LiveTests", "tools\Azure.Mcp.Tools.Search\tests\Azure.Mcp.Tools.Search.LiveTests\Azure.Mcp.Tools.Search.LiveTests.csproj", "{3D69D7BE-8C92-4690-B4B2-5EC6F439A2A2}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Search.UnitTests", "tools\Azure.Mcp.Tools.Search\tests\Azure.Mcp.Tools.Search.UnitTests\Azure.Mcp.Tools.Search.UnitTests.csproj", "{6233A7A4-85F2-4458-A14A-BF35117347B0}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{0F04000E-CD22-741D-E99C-16D60B397F54}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.ServiceBus.LiveTests", "tools\Azure.Mcp.Tools.ServiceBus\tests\Azure.Mcp.Tools.ServiceBus.LiveTests\Azure.Mcp.Tools.ServiceBus.LiveTests.csproj", "{9BE18521-31F9-45AD-A6EE-74695754EC0C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.ServiceBus.UnitTests", "tools\Azure.Mcp.Tools.ServiceBus\tests\Azure.Mcp.Tools.ServiceBus.UnitTests\Azure.Mcp.Tools.ServiceBus.UnitTests.csproj", "{F90633BA-133F-42E3-88D5-EE4DE0FB0586}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{7331D996-A74A-CB9F-1FD5-3D31CD825A37}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.SignalR.LiveTests", "tools\Azure.Mcp.Tools.SignalR\tests\Azure.Mcp.Tools.SignalR.LiveTests\Azure.Mcp.Tools.SignalR.LiveTests.csproj", "{DE85A82A-CC7A-4743-B6FE-7259B152EF26}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.SignalR.UnitTests", "tools\Azure.Mcp.Tools.SignalR\tests\Azure.Mcp.Tools.SignalR.UnitTests\Azure.Mcp.Tools.SignalR.UnitTests.csproj", "{8066FB34-4946-4A49-B3EC-E0E1D28760D1}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{1474C41C-43C3-EE73-1D18-99B5FE232042}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Speech.LiveTests", "tools\Azure.Mcp.Tools.Speech\tests\Azure.Mcp.Tools.Speech.LiveTests\Azure.Mcp.Tools.Speech.LiveTests.csproj", "{E5F6A7B8-90CD-EF12-3456-7890ABCDEF01}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Speech.UnitTests", "tools\Azure.Mcp.Tools.Speech\tests\Azure.Mcp.Tools.Speech.UnitTests\Azure.Mcp.Tools.Speech.UnitTests.csproj", "{F6A7B890-CDEF-1234-5678-90ABCDEF0123}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{AE64BB99-52FC-85C8-81F2-9C84ECFCBB2D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Sql.LiveTests", "tools\Azure.Mcp.Tools.Sql\tests\Azure.Mcp.Tools.Sql.LiveTests\Azure.Mcp.Tools.Sql.LiveTests.csproj", "{8EAD1CA0-DD5D-493A-A6A4-45DD8E6835EA}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Sql.UnitTests", "tools\Azure.Mcp.Tools.Sql\tests\Azure.Mcp.Tools.Sql.UnitTests\Azure.Mcp.Tools.Sql.UnitTests.csproj", "{9457321A-9019-41E8-9E80-309D76EF2BAF}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{E03D2171-C4AB-45A3-681D-A2A2EBBB122A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Storage.LiveTests", "tools\Azure.Mcp.Tools.Storage\tests\Azure.Mcp.Tools.Storage.LiveTests\Azure.Mcp.Tools.Storage.LiveTests.csproj", "{9A72A0E3-091A-4C64-AE66-ADAA5B46B1E8}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Storage.UnitTests", "tools\Azure.Mcp.Tools.Storage\tests\Azure.Mcp.Tools.Storage.UnitTests\Azure.Mcp.Tools.Storage.UnitTests.csproj", "{F3F49C7E-9106-4FF7-A71D-442022D63F7B}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{D38B6103-E564-8894-9748-4CF0C62984DB}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.VirtualDesktop.LiveTests", "tools\Azure.Mcp.Tools.VirtualDesktop\tests\Azure.Mcp.Tools.VirtualDesktop.LiveTests\Azure.Mcp.Tools.VirtualDesktop.LiveTests.csproj", "{0A09784C-BB49-44E8-B07A-DA4EEEC1184E}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.VirtualDesktop.UnitTests", "tools\Azure.Mcp.Tools.VirtualDesktop\tests\Azure.Mcp.Tools.VirtualDesktop.UnitTests\Azure.Mcp.Tools.VirtualDesktop.UnitTests.csproj", "{F5980D17-1A14-4DD9-82DF-6496E0C4B70D}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{447CAF13-A1DE-A946-989B-DD6CAA0CDF92}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Workbooks.LiveTests", "tools\Azure.Mcp.Tools.Workbooks\tests\Azure.Mcp.Tools.Workbooks.LiveTests\Azure.Mcp.Tools.Workbooks.LiveTests.csproj", "{4F0C9315-FBE2-4A98-9FD1-66F508398DEF}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Workbooks.UnitTests", "tools\Azure.Mcp.Tools.Workbooks\tests\Azure.Mcp.Tools.Workbooks.UnitTests\Azure.Mcp.Tools.Workbooks.UnitTests.csproj", "{C031D592-96D6-44D0-BF31-33CCE5CAABA1}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{294AC723-70DA-F50A-2C7A-AC6C0AEA0A62}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Fabric.Mcp.Tools.PublicApi.UnitTests", "tools\Fabric.Mcp.Tools.PublicApi\tests\Fabric.Mcp.Tools.PublicApi.UnitTests\Fabric.Mcp.Tools.PublicApi.UnitTests.csproj", "{D3F46C2D-3AFD-FD9C-9C6A-180B1514DD2F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Postgres.LiveTests", "tools\Azure.Mcp.Tools.Postgres\tests\Azure.Mcp.Tools.Postgres.LiveTests\Azure.Mcp.Tools.Postgres.LiveTests.csproj", "{BF0354AE-3748-A8DC-F79D-B21FDDEDDFAE}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Azure.Mcp.Tools.Policy", "Azure.Mcp.Tools.Policy", "{3A04D5F6-EC54-0CD0-A628-F5EFBCB2AD91}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{73BD3F55-13D5-9E06-C2A4-90F58F874C43}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Policy", "tools\Azure.Mcp.Tools.Policy\src\Azure.Mcp.Tools.Policy.csproj", "{5CF09A5B-85A2-41B2-8A51-E7F2ED03B77A}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{F7BA6D31-5AD0-005E-585A-02B38D7B7DEE}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.Policy.UnitTests", "tools\Azure.Mcp.Tools.Policy\tests\Azure.Mcp.Tools.Policy.UnitTests\Azure.Mcp.Tools.Policy.UnitTests.csproj", "{A5B0CAC9-2FCF-4AA2-9C02-655035284FCD}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {8904FD57-96C7-434D-B4CD-99D2A7637ED3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8904FD57-96C7-434D-B4CD-99D2A7637ED3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8904FD57-96C7-434D-B4CD-99D2A7637ED3}.Debug|x64.ActiveCfg = Debug|Any CPU + {8904FD57-96C7-434D-B4CD-99D2A7637ED3}.Debug|x64.Build.0 = Debug|Any CPU + {8904FD57-96C7-434D-B4CD-99D2A7637ED3}.Debug|x86.ActiveCfg = Debug|Any CPU + {8904FD57-96C7-434D-B4CD-99D2A7637ED3}.Debug|x86.Build.0 = Debug|Any CPU + {8904FD57-96C7-434D-B4CD-99D2A7637ED3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8904FD57-96C7-434D-B4CD-99D2A7637ED3}.Release|Any CPU.Build.0 = Release|Any CPU + {8904FD57-96C7-434D-B4CD-99D2A7637ED3}.Release|x64.ActiveCfg = Release|Any CPU + {8904FD57-96C7-434D-B4CD-99D2A7637ED3}.Release|x64.Build.0 = Release|Any CPU + {8904FD57-96C7-434D-B4CD-99D2A7637ED3}.Release|x86.ActiveCfg = Release|Any CPU + {8904FD57-96C7-434D-B4CD-99D2A7637ED3}.Release|x86.Build.0 = Release|Any CPU + {F849CD08-D4E4-4CDA-AB6F-D776EAFCD0E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F849CD08-D4E4-4CDA-AB6F-D776EAFCD0E2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F849CD08-D4E4-4CDA-AB6F-D776EAFCD0E2}.Debug|x64.ActiveCfg = Debug|Any CPU + {F849CD08-D4E4-4CDA-AB6F-D776EAFCD0E2}.Debug|x64.Build.0 = Debug|Any CPU + {F849CD08-D4E4-4CDA-AB6F-D776EAFCD0E2}.Debug|x86.ActiveCfg = Debug|Any CPU + {F849CD08-D4E4-4CDA-AB6F-D776EAFCD0E2}.Debug|x86.Build.0 = Debug|Any CPU + {F849CD08-D4E4-4CDA-AB6F-D776EAFCD0E2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F849CD08-D4E4-4CDA-AB6F-D776EAFCD0E2}.Release|Any CPU.Build.0 = Release|Any CPU + {F849CD08-D4E4-4CDA-AB6F-D776EAFCD0E2}.Release|x64.ActiveCfg = Release|Any CPU + {F849CD08-D4E4-4CDA-AB6F-D776EAFCD0E2}.Release|x64.Build.0 = Release|Any CPU + {F849CD08-D4E4-4CDA-AB6F-D776EAFCD0E2}.Release|x86.ActiveCfg = Release|Any CPU + {F849CD08-D4E4-4CDA-AB6F-D776EAFCD0E2}.Release|x86.Build.0 = Release|Any CPU + {F9FD0819-F62F-4979-81EF-0093CE31EEA7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F9FD0819-F62F-4979-81EF-0093CE31EEA7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F9FD0819-F62F-4979-81EF-0093CE31EEA7}.Debug|x64.ActiveCfg = Debug|Any CPU + {F9FD0819-F62F-4979-81EF-0093CE31EEA7}.Debug|x64.Build.0 = Debug|Any CPU + {F9FD0819-F62F-4979-81EF-0093CE31EEA7}.Debug|x86.ActiveCfg = Debug|Any CPU + {F9FD0819-F62F-4979-81EF-0093CE31EEA7}.Debug|x86.Build.0 = Debug|Any CPU + {F9FD0819-F62F-4979-81EF-0093CE31EEA7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F9FD0819-F62F-4979-81EF-0093CE31EEA7}.Release|Any CPU.Build.0 = Release|Any CPU + {F9FD0819-F62F-4979-81EF-0093CE31EEA7}.Release|x64.ActiveCfg = Release|Any CPU + {F9FD0819-F62F-4979-81EF-0093CE31EEA7}.Release|x64.Build.0 = Release|Any CPU + {F9FD0819-F62F-4979-81EF-0093CE31EEA7}.Release|x86.ActiveCfg = Release|Any CPU + {F9FD0819-F62F-4979-81EF-0093CE31EEA7}.Release|x86.Build.0 = Release|Any CPU + {5EEB08B8-FBBE-45ED-AB55-E5073308226B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5EEB08B8-FBBE-45ED-AB55-E5073308226B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5EEB08B8-FBBE-45ED-AB55-E5073308226B}.Debug|x64.ActiveCfg = Debug|Any CPU + {5EEB08B8-FBBE-45ED-AB55-E5073308226B}.Debug|x64.Build.0 = Debug|Any CPU + {5EEB08B8-FBBE-45ED-AB55-E5073308226B}.Debug|x86.ActiveCfg = Debug|Any CPU + {5EEB08B8-FBBE-45ED-AB55-E5073308226B}.Debug|x86.Build.0 = Debug|Any CPU + {5EEB08B8-FBBE-45ED-AB55-E5073308226B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5EEB08B8-FBBE-45ED-AB55-E5073308226B}.Release|Any CPU.Build.0 = Release|Any CPU + {5EEB08B8-FBBE-45ED-AB55-E5073308226B}.Release|x64.ActiveCfg = Release|Any CPU + {5EEB08B8-FBBE-45ED-AB55-E5073308226B}.Release|x64.Build.0 = Release|Any CPU + {5EEB08B8-FBBE-45ED-AB55-E5073308226B}.Release|x86.ActiveCfg = Release|Any CPU + {5EEB08B8-FBBE-45ED-AB55-E5073308226B}.Release|x86.Build.0 = Release|Any CPU + {C7A151C3-2C9C-4C0F-8D07-0BB6630E821C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C7A151C3-2C9C-4C0F-8D07-0BB6630E821C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C7A151C3-2C9C-4C0F-8D07-0BB6630E821C}.Debug|x64.ActiveCfg = Debug|Any CPU + {C7A151C3-2C9C-4C0F-8D07-0BB6630E821C}.Debug|x64.Build.0 = Debug|Any CPU + {C7A151C3-2C9C-4C0F-8D07-0BB6630E821C}.Debug|x86.ActiveCfg = Debug|Any CPU + {C7A151C3-2C9C-4C0F-8D07-0BB6630E821C}.Debug|x86.Build.0 = Debug|Any CPU + {C7A151C3-2C9C-4C0F-8D07-0BB6630E821C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C7A151C3-2C9C-4C0F-8D07-0BB6630E821C}.Release|Any CPU.Build.0 = Release|Any CPU + {C7A151C3-2C9C-4C0F-8D07-0BB6630E821C}.Release|x64.ActiveCfg = Release|Any CPU + {C7A151C3-2C9C-4C0F-8D07-0BB6630E821C}.Release|x64.Build.0 = Release|Any CPU + {C7A151C3-2C9C-4C0F-8D07-0BB6630E821C}.Release|x86.ActiveCfg = Release|Any CPU + {C7A151C3-2C9C-4C0F-8D07-0BB6630E821C}.Release|x86.Build.0 = Release|Any CPU + {6EEBF2DB-8E44-4FB2-9157-2B46E23AD086}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6EEBF2DB-8E44-4FB2-9157-2B46E23AD086}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6EEBF2DB-8E44-4FB2-9157-2B46E23AD086}.Debug|x64.ActiveCfg = Debug|Any CPU + {6EEBF2DB-8E44-4FB2-9157-2B46E23AD086}.Debug|x64.Build.0 = Debug|Any CPU + {6EEBF2DB-8E44-4FB2-9157-2B46E23AD086}.Debug|x86.ActiveCfg = Debug|Any CPU + {6EEBF2DB-8E44-4FB2-9157-2B46E23AD086}.Debug|x86.Build.0 = Debug|Any CPU + {6EEBF2DB-8E44-4FB2-9157-2B46E23AD086}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6EEBF2DB-8E44-4FB2-9157-2B46E23AD086}.Release|Any CPU.Build.0 = Release|Any CPU + {6EEBF2DB-8E44-4FB2-9157-2B46E23AD086}.Release|x64.ActiveCfg = Release|Any CPU + {6EEBF2DB-8E44-4FB2-9157-2B46E23AD086}.Release|x64.Build.0 = Release|Any CPU + {6EEBF2DB-8E44-4FB2-9157-2B46E23AD086}.Release|x86.ActiveCfg = Release|Any CPU + {6EEBF2DB-8E44-4FB2-9157-2B46E23AD086}.Release|x86.Build.0 = Release|Any CPU + {7C89F911-9624-4CC8-9268-57824064FCA7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7C89F911-9624-4CC8-9268-57824064FCA7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7C89F911-9624-4CC8-9268-57824064FCA7}.Debug|x64.ActiveCfg = Debug|Any CPU + {7C89F911-9624-4CC8-9268-57824064FCA7}.Debug|x64.Build.0 = Debug|Any CPU + {7C89F911-9624-4CC8-9268-57824064FCA7}.Debug|x86.ActiveCfg = Debug|Any CPU + {7C89F911-9624-4CC8-9268-57824064FCA7}.Debug|x86.Build.0 = Debug|Any CPU + {7C89F911-9624-4CC8-9268-57824064FCA7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7C89F911-9624-4CC8-9268-57824064FCA7}.Release|Any CPU.Build.0 = Release|Any CPU + {7C89F911-9624-4CC8-9268-57824064FCA7}.Release|x64.ActiveCfg = Release|Any CPU + {7C89F911-9624-4CC8-9268-57824064FCA7}.Release|x64.Build.0 = Release|Any CPU + {7C89F911-9624-4CC8-9268-57824064FCA7}.Release|x86.ActiveCfg = Release|Any CPU + {7C89F911-9624-4CC8-9268-57824064FCA7}.Release|x86.Build.0 = Release|Any CPU + {AF90B213-1A45-477A-A958-2B9187AEAF54}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AF90B213-1A45-477A-A958-2B9187AEAF54}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AF90B213-1A45-477A-A958-2B9187AEAF54}.Debug|x64.ActiveCfg = Debug|Any CPU + {AF90B213-1A45-477A-A958-2B9187AEAF54}.Debug|x64.Build.0 = Debug|Any CPU + {AF90B213-1A45-477A-A958-2B9187AEAF54}.Debug|x86.ActiveCfg = Debug|Any CPU + {AF90B213-1A45-477A-A958-2B9187AEAF54}.Debug|x86.Build.0 = Debug|Any CPU + {AF90B213-1A45-477A-A958-2B9187AEAF54}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AF90B213-1A45-477A-A958-2B9187AEAF54}.Release|Any CPU.Build.0 = Release|Any CPU + {AF90B213-1A45-477A-A958-2B9187AEAF54}.Release|x64.ActiveCfg = Release|Any CPU + {AF90B213-1A45-477A-A958-2B9187AEAF54}.Release|x64.Build.0 = Release|Any CPU + {AF90B213-1A45-477A-A958-2B9187AEAF54}.Release|x86.ActiveCfg = Release|Any CPU + {AF90B213-1A45-477A-A958-2B9187AEAF54}.Release|x86.Build.0 = Release|Any CPU + {3D4E5F6A-7B8C-9D0E-1F2A-3B4C5D6E7F8A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3D4E5F6A-7B8C-9D0E-1F2A-3B4C5D6E7F8A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3D4E5F6A-7B8C-9D0E-1F2A-3B4C5D6E7F8A}.Debug|x64.ActiveCfg = Debug|Any CPU + {3D4E5F6A-7B8C-9D0E-1F2A-3B4C5D6E7F8A}.Debug|x64.Build.0 = Debug|Any CPU + {3D4E5F6A-7B8C-9D0E-1F2A-3B4C5D6E7F8A}.Debug|x86.ActiveCfg = Debug|Any CPU + {3D4E5F6A-7B8C-9D0E-1F2A-3B4C5D6E7F8A}.Debug|x86.Build.0 = Debug|Any CPU + {3D4E5F6A-7B8C-9D0E-1F2A-3B4C5D6E7F8A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3D4E5F6A-7B8C-9D0E-1F2A-3B4C5D6E7F8A}.Release|Any CPU.Build.0 = Release|Any CPU + {3D4E5F6A-7B8C-9D0E-1F2A-3B4C5D6E7F8A}.Release|x64.ActiveCfg = Release|Any CPU + {3D4E5F6A-7B8C-9D0E-1F2A-3B4C5D6E7F8A}.Release|x64.Build.0 = Release|Any CPU + {3D4E5F6A-7B8C-9D0E-1F2A-3B4C5D6E7F8A}.Release|x86.ActiveCfg = Release|Any CPU + {3D4E5F6A-7B8C-9D0E-1F2A-3B4C5D6E7F8A}.Release|x86.Build.0 = Release|Any CPU + {E2C2A3E4-1D5F-4F6E-9A7F-1C2E54F893AB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E2C2A3E4-1D5F-4F6E-9A7F-1C2E54F893AB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E2C2A3E4-1D5F-4F6E-9A7F-1C2E54F893AB}.Debug|x64.ActiveCfg = Debug|Any CPU + {E2C2A3E4-1D5F-4F6E-9A7F-1C2E54F893AB}.Debug|x64.Build.0 = Debug|Any CPU + {E2C2A3E4-1D5F-4F6E-9A7F-1C2E54F893AB}.Debug|x86.ActiveCfg = Debug|Any CPU + {E2C2A3E4-1D5F-4F6E-9A7F-1C2E54F893AB}.Debug|x86.Build.0 = Debug|Any CPU + {E2C2A3E4-1D5F-4F6E-9A7F-1C2E54F893AB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E2C2A3E4-1D5F-4F6E-9A7F-1C2E54F893AB}.Release|Any CPU.Build.0 = Release|Any CPU + {E2C2A3E4-1D5F-4F6E-9A7F-1C2E54F893AB}.Release|x64.ActiveCfg = Release|Any CPU + {E2C2A3E4-1D5F-4F6E-9A7F-1C2E54F893AB}.Release|x64.Build.0 = Release|Any CPU + {E2C2A3E4-1D5F-4F6E-9A7F-1C2E54F893AB}.Release|x86.ActiveCfg = Release|Any CPU + {E2C2A3E4-1D5F-4F6E-9A7F-1C2E54F893AB}.Release|x86.Build.0 = Release|Any CPU + {7828AB14-5E8B-4E60-B8AA-988E70573684}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7828AB14-5E8B-4E60-B8AA-988E70573684}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7828AB14-5E8B-4E60-B8AA-988E70573684}.Debug|x64.ActiveCfg = Debug|Any CPU + {7828AB14-5E8B-4E60-B8AA-988E70573684}.Debug|x64.Build.0 = Debug|Any CPU + {7828AB14-5E8B-4E60-B8AA-988E70573684}.Debug|x86.ActiveCfg = Debug|Any CPU + {7828AB14-5E8B-4E60-B8AA-988E70573684}.Debug|x86.Build.0 = Debug|Any CPU + {7828AB14-5E8B-4E60-B8AA-988E70573684}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7828AB14-5E8B-4E60-B8AA-988E70573684}.Release|Any CPU.Build.0 = Release|Any CPU + {7828AB14-5E8B-4E60-B8AA-988E70573684}.Release|x64.ActiveCfg = Release|Any CPU + {7828AB14-5E8B-4E60-B8AA-988E70573684}.Release|x64.Build.0 = Release|Any CPU + {7828AB14-5E8B-4E60-B8AA-988E70573684}.Release|x86.ActiveCfg = Release|Any CPU + {7828AB14-5E8B-4E60-B8AA-988E70573684}.Release|x86.Build.0 = Release|Any CPU + {55FF4834-F1FE-47C1-AA8C-24DC4C3F171A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {55FF4834-F1FE-47C1-AA8C-24DC4C3F171A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {55FF4834-F1FE-47C1-AA8C-24DC4C3F171A}.Debug|x64.ActiveCfg = Debug|Any CPU + {55FF4834-F1FE-47C1-AA8C-24DC4C3F171A}.Debug|x64.Build.0 = Debug|Any CPU + {55FF4834-F1FE-47C1-AA8C-24DC4C3F171A}.Debug|x86.ActiveCfg = Debug|Any CPU + {55FF4834-F1FE-47C1-AA8C-24DC4C3F171A}.Debug|x86.Build.0 = Debug|Any CPU + {55FF4834-F1FE-47C1-AA8C-24DC4C3F171A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {55FF4834-F1FE-47C1-AA8C-24DC4C3F171A}.Release|Any CPU.Build.0 = Release|Any CPU + {55FF4834-F1FE-47C1-AA8C-24DC4C3F171A}.Release|x64.ActiveCfg = Release|Any CPU + {55FF4834-F1FE-47C1-AA8C-24DC4C3F171A}.Release|x64.Build.0 = Release|Any CPU + {55FF4834-F1FE-47C1-AA8C-24DC4C3F171A}.Release|x86.ActiveCfg = Release|Any CPU + {55FF4834-F1FE-47C1-AA8C-24DC4C3F171A}.Release|x86.Build.0 = Release|Any CPU + {DFDDA723-3307-4330-A154-A0F337A5E8EF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DFDDA723-3307-4330-A154-A0F337A5E8EF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DFDDA723-3307-4330-A154-A0F337A5E8EF}.Debug|x64.ActiveCfg = Debug|Any CPU + {DFDDA723-3307-4330-A154-A0F337A5E8EF}.Debug|x64.Build.0 = Debug|Any CPU + {DFDDA723-3307-4330-A154-A0F337A5E8EF}.Debug|x86.ActiveCfg = Debug|Any CPU + {DFDDA723-3307-4330-A154-A0F337A5E8EF}.Debug|x86.Build.0 = Debug|Any CPU + {DFDDA723-3307-4330-A154-A0F337A5E8EF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DFDDA723-3307-4330-A154-A0F337A5E8EF}.Release|Any CPU.Build.0 = Release|Any CPU + {DFDDA723-3307-4330-A154-A0F337A5E8EF}.Release|x64.ActiveCfg = Release|Any CPU + {DFDDA723-3307-4330-A154-A0F337A5E8EF}.Release|x64.Build.0 = Release|Any CPU + {DFDDA723-3307-4330-A154-A0F337A5E8EF}.Release|x86.ActiveCfg = Release|Any CPU + {DFDDA723-3307-4330-A154-A0F337A5E8EF}.Release|x86.Build.0 = Release|Any CPU + {51FF959C-5452-4611-B3DF-671D5D2FEF1E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {51FF959C-5452-4611-B3DF-671D5D2FEF1E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {51FF959C-5452-4611-B3DF-671D5D2FEF1E}.Debug|x64.ActiveCfg = Debug|Any CPU + {51FF959C-5452-4611-B3DF-671D5D2FEF1E}.Debug|x64.Build.0 = Debug|Any CPU + {51FF959C-5452-4611-B3DF-671D5D2FEF1E}.Debug|x86.ActiveCfg = Debug|Any CPU + {51FF959C-5452-4611-B3DF-671D5D2FEF1E}.Debug|x86.Build.0 = Debug|Any CPU + {51FF959C-5452-4611-B3DF-671D5D2FEF1E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {51FF959C-5452-4611-B3DF-671D5D2FEF1E}.Release|Any CPU.Build.0 = Release|Any CPU + {51FF959C-5452-4611-B3DF-671D5D2FEF1E}.Release|x64.ActiveCfg = Release|Any CPU + {51FF959C-5452-4611-B3DF-671D5D2FEF1E}.Release|x64.Build.0 = Release|Any CPU + {51FF959C-5452-4611-B3DF-671D5D2FEF1E}.Release|x86.ActiveCfg = Release|Any CPU + {51FF959C-5452-4611-B3DF-671D5D2FEF1E}.Release|x86.Build.0 = Release|Any CPU + {38EF7AE0-C6B0-4809-85EE-27A2C4F8F83B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {38EF7AE0-C6B0-4809-85EE-27A2C4F8F83B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {38EF7AE0-C6B0-4809-85EE-27A2C4F8F83B}.Debug|x64.ActiveCfg = Debug|Any CPU + {38EF7AE0-C6B0-4809-85EE-27A2C4F8F83B}.Debug|x64.Build.0 = Debug|Any CPU + {38EF7AE0-C6B0-4809-85EE-27A2C4F8F83B}.Debug|x86.ActiveCfg = Debug|Any CPU + {38EF7AE0-C6B0-4809-85EE-27A2C4F8F83B}.Debug|x86.Build.0 = Debug|Any CPU + {38EF7AE0-C6B0-4809-85EE-27A2C4F8F83B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {38EF7AE0-C6B0-4809-85EE-27A2C4F8F83B}.Release|Any CPU.Build.0 = Release|Any CPU + {38EF7AE0-C6B0-4809-85EE-27A2C4F8F83B}.Release|x64.ActiveCfg = Release|Any CPU + {38EF7AE0-C6B0-4809-85EE-27A2C4F8F83B}.Release|x64.Build.0 = Release|Any CPU + {38EF7AE0-C6B0-4809-85EE-27A2C4F8F83B}.Release|x86.ActiveCfg = Release|Any CPU + {38EF7AE0-C6B0-4809-85EE-27A2C4F8F83B}.Release|x86.Build.0 = Release|Any CPU + {F6B9B9A5-3A77-44F6-A349-50A751B46904}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F6B9B9A5-3A77-44F6-A349-50A751B46904}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F6B9B9A5-3A77-44F6-A349-50A751B46904}.Debug|x64.ActiveCfg = Debug|Any CPU + {F6B9B9A5-3A77-44F6-A349-50A751B46904}.Debug|x64.Build.0 = Debug|Any CPU + {F6B9B9A5-3A77-44F6-A349-50A751B46904}.Debug|x86.ActiveCfg = Debug|Any CPU + {F6B9B9A5-3A77-44F6-A349-50A751B46904}.Debug|x86.Build.0 = Debug|Any CPU + {F6B9B9A5-3A77-44F6-A349-50A751B46904}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F6B9B9A5-3A77-44F6-A349-50A751B46904}.Release|Any CPU.Build.0 = Release|Any CPU + {F6B9B9A5-3A77-44F6-A349-50A751B46904}.Release|x64.ActiveCfg = Release|Any CPU + {F6B9B9A5-3A77-44F6-A349-50A751B46904}.Release|x64.Build.0 = Release|Any CPU + {F6B9B9A5-3A77-44F6-A349-50A751B46904}.Release|x86.ActiveCfg = Release|Any CPU + {F6B9B9A5-3A77-44F6-A349-50A751B46904}.Release|x86.Build.0 = Release|Any CPU + {744989A9-972B-4076-81FE-BFAB39EE899A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {744989A9-972B-4076-81FE-BFAB39EE899A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {744989A9-972B-4076-81FE-BFAB39EE899A}.Debug|x64.ActiveCfg = Debug|Any CPU + {744989A9-972B-4076-81FE-BFAB39EE899A}.Debug|x64.Build.0 = Debug|Any CPU + {744989A9-972B-4076-81FE-BFAB39EE899A}.Debug|x86.ActiveCfg = Debug|Any CPU + {744989A9-972B-4076-81FE-BFAB39EE899A}.Debug|x86.Build.0 = Debug|Any CPU + {744989A9-972B-4076-81FE-BFAB39EE899A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {744989A9-972B-4076-81FE-BFAB39EE899A}.Release|Any CPU.Build.0 = Release|Any CPU + {744989A9-972B-4076-81FE-BFAB39EE899A}.Release|x64.ActiveCfg = Release|Any CPU + {744989A9-972B-4076-81FE-BFAB39EE899A}.Release|x64.Build.0 = Release|Any CPU + {744989A9-972B-4076-81FE-BFAB39EE899A}.Release|x86.ActiveCfg = Release|Any CPU + {744989A9-972B-4076-81FE-BFAB39EE899A}.Release|x86.Build.0 = Release|Any CPU + {E77DA2D5-7AFD-43D6-B77A-C22A1167B856}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E77DA2D5-7AFD-43D6-B77A-C22A1167B856}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E77DA2D5-7AFD-43D6-B77A-C22A1167B856}.Debug|x64.ActiveCfg = Debug|Any CPU + {E77DA2D5-7AFD-43D6-B77A-C22A1167B856}.Debug|x64.Build.0 = Debug|Any CPU + {E77DA2D5-7AFD-43D6-B77A-C22A1167B856}.Debug|x86.ActiveCfg = Debug|Any CPU + {E77DA2D5-7AFD-43D6-B77A-C22A1167B856}.Debug|x86.Build.0 = Debug|Any CPU + {E77DA2D5-7AFD-43D6-B77A-C22A1167B856}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E77DA2D5-7AFD-43D6-B77A-C22A1167B856}.Release|Any CPU.Build.0 = Release|Any CPU + {E77DA2D5-7AFD-43D6-B77A-C22A1167B856}.Release|x64.ActiveCfg = Release|Any CPU + {E77DA2D5-7AFD-43D6-B77A-C22A1167B856}.Release|x64.Build.0 = Release|Any CPU + {E77DA2D5-7AFD-43D6-B77A-C22A1167B856}.Release|x86.ActiveCfg = Release|Any CPU + {E77DA2D5-7AFD-43D6-B77A-C22A1167B856}.Release|x86.Build.0 = Release|Any CPU + {D7B16F40-8636-4EE4-9F9A-77DF5A92EE03}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D7B16F40-8636-4EE4-9F9A-77DF5A92EE03}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D7B16F40-8636-4EE4-9F9A-77DF5A92EE03}.Debug|x64.ActiveCfg = Debug|Any CPU + {D7B16F40-8636-4EE4-9F9A-77DF5A92EE03}.Debug|x64.Build.0 = Debug|Any CPU + {D7B16F40-8636-4EE4-9F9A-77DF5A92EE03}.Debug|x86.ActiveCfg = Debug|Any CPU + {D7B16F40-8636-4EE4-9F9A-77DF5A92EE03}.Debug|x86.Build.0 = Debug|Any CPU + {D7B16F40-8636-4EE4-9F9A-77DF5A92EE03}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D7B16F40-8636-4EE4-9F9A-77DF5A92EE03}.Release|Any CPU.Build.0 = Release|Any CPU + {D7B16F40-8636-4EE4-9F9A-77DF5A92EE03}.Release|x64.ActiveCfg = Release|Any CPU + {D7B16F40-8636-4EE4-9F9A-77DF5A92EE03}.Release|x64.Build.0 = Release|Any CPU + {D7B16F40-8636-4EE4-9F9A-77DF5A92EE03}.Release|x86.ActiveCfg = Release|Any CPU + {D7B16F40-8636-4EE4-9F9A-77DF5A92EE03}.Release|x86.Build.0 = Release|Any CPU + {359D3A43-1DFB-4541-AC72-E63EF0D6B3C9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {359D3A43-1DFB-4541-AC72-E63EF0D6B3C9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {359D3A43-1DFB-4541-AC72-E63EF0D6B3C9}.Debug|x64.ActiveCfg = Debug|Any CPU + {359D3A43-1DFB-4541-AC72-E63EF0D6B3C9}.Debug|x64.Build.0 = Debug|Any CPU + {359D3A43-1DFB-4541-AC72-E63EF0D6B3C9}.Debug|x86.ActiveCfg = Debug|Any CPU + {359D3A43-1DFB-4541-AC72-E63EF0D6B3C9}.Debug|x86.Build.0 = Debug|Any CPU + {359D3A43-1DFB-4541-AC72-E63EF0D6B3C9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {359D3A43-1DFB-4541-AC72-E63EF0D6B3C9}.Release|Any CPU.Build.0 = Release|Any CPU + {359D3A43-1DFB-4541-AC72-E63EF0D6B3C9}.Release|x64.ActiveCfg = Release|Any CPU + {359D3A43-1DFB-4541-AC72-E63EF0D6B3C9}.Release|x64.Build.0 = Release|Any CPU + {359D3A43-1DFB-4541-AC72-E63EF0D6B3C9}.Release|x86.ActiveCfg = Release|Any CPU + {359D3A43-1DFB-4541-AC72-E63EF0D6B3C9}.Release|x86.Build.0 = Release|Any CPU + {C8612FFE-7E8F-4EC4-B158-A4C2167A9AD5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C8612FFE-7E8F-4EC4-B158-A4C2167A9AD5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C8612FFE-7E8F-4EC4-B158-A4C2167A9AD5}.Debug|x64.ActiveCfg = Debug|Any CPU + {C8612FFE-7E8F-4EC4-B158-A4C2167A9AD5}.Debug|x64.Build.0 = Debug|Any CPU + {C8612FFE-7E8F-4EC4-B158-A4C2167A9AD5}.Debug|x86.ActiveCfg = Debug|Any CPU + {C8612FFE-7E8F-4EC4-B158-A4C2167A9AD5}.Debug|x86.Build.0 = Debug|Any CPU + {C8612FFE-7E8F-4EC4-B158-A4C2167A9AD5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C8612FFE-7E8F-4EC4-B158-A4C2167A9AD5}.Release|Any CPU.Build.0 = Release|Any CPU + {C8612FFE-7E8F-4EC4-B158-A4C2167A9AD5}.Release|x64.ActiveCfg = Release|Any CPU + {C8612FFE-7E8F-4EC4-B158-A4C2167A9AD5}.Release|x64.Build.0 = Release|Any CPU + {C8612FFE-7E8F-4EC4-B158-A4C2167A9AD5}.Release|x86.ActiveCfg = Release|Any CPU + {C8612FFE-7E8F-4EC4-B158-A4C2167A9AD5}.Release|x86.Build.0 = Release|Any CPU + {9924AEB8-EEB1-40EC-943B-DA1B9E610767}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9924AEB8-EEB1-40EC-943B-DA1B9E610767}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9924AEB8-EEB1-40EC-943B-DA1B9E610767}.Debug|x64.ActiveCfg = Debug|Any CPU + {9924AEB8-EEB1-40EC-943B-DA1B9E610767}.Debug|x64.Build.0 = Debug|Any CPU + {9924AEB8-EEB1-40EC-943B-DA1B9E610767}.Debug|x86.ActiveCfg = Debug|Any CPU + {9924AEB8-EEB1-40EC-943B-DA1B9E610767}.Debug|x86.Build.0 = Debug|Any CPU + {9924AEB8-EEB1-40EC-943B-DA1B9E610767}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9924AEB8-EEB1-40EC-943B-DA1B9E610767}.Release|Any CPU.Build.0 = Release|Any CPU + {9924AEB8-EEB1-40EC-943B-DA1B9E610767}.Release|x64.ActiveCfg = Release|Any CPU + {9924AEB8-EEB1-40EC-943B-DA1B9E610767}.Release|x64.Build.0 = Release|Any CPU + {9924AEB8-EEB1-40EC-943B-DA1B9E610767}.Release|x86.ActiveCfg = Release|Any CPU + {9924AEB8-EEB1-40EC-943B-DA1B9E610767}.Release|x86.Build.0 = Release|Any CPU + {E1234567-1234-1234-1234-123456789012}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E1234567-1234-1234-1234-123456789012}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E1234567-1234-1234-1234-123456789012}.Debug|x64.ActiveCfg = Debug|Any CPU + {E1234567-1234-1234-1234-123456789012}.Debug|x64.Build.0 = Debug|Any CPU + {E1234567-1234-1234-1234-123456789012}.Debug|x86.ActiveCfg = Debug|Any CPU + {E1234567-1234-1234-1234-123456789012}.Debug|x86.Build.0 = Debug|Any CPU + {E1234567-1234-1234-1234-123456789012}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E1234567-1234-1234-1234-123456789012}.Release|Any CPU.Build.0 = Release|Any CPU + {E1234567-1234-1234-1234-123456789012}.Release|x64.ActiveCfg = Release|Any CPU + {E1234567-1234-1234-1234-123456789012}.Release|x64.Build.0 = Release|Any CPU + {E1234567-1234-1234-1234-123456789012}.Release|x86.ActiveCfg = Release|Any CPU + {E1234567-1234-1234-1234-123456789012}.Release|x86.Build.0 = Release|Any CPU + {632DF404-7E5D-56B7-808D-816A3AB773A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {632DF404-7E5D-56B7-808D-816A3AB773A4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {632DF404-7E5D-56B7-808D-816A3AB773A4}.Debug|x64.ActiveCfg = Debug|Any CPU + {632DF404-7E5D-56B7-808D-816A3AB773A4}.Debug|x64.Build.0 = Debug|Any CPU + {632DF404-7E5D-56B7-808D-816A3AB773A4}.Debug|x86.ActiveCfg = Debug|Any CPU + {632DF404-7E5D-56B7-808D-816A3AB773A4}.Debug|x86.Build.0 = Debug|Any CPU + {632DF404-7E5D-56B7-808D-816A3AB773A4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {632DF404-7E5D-56B7-808D-816A3AB773A4}.Release|Any CPU.Build.0 = Release|Any CPU + {632DF404-7E5D-56B7-808D-816A3AB773A4}.Release|x64.ActiveCfg = Release|Any CPU + {632DF404-7E5D-56B7-808D-816A3AB773A4}.Release|x64.Build.0 = Release|Any CPU + {632DF404-7E5D-56B7-808D-816A3AB773A4}.Release|x86.ActiveCfg = Release|Any CPU + {632DF404-7E5D-56B7-808D-816A3AB773A4}.Release|x86.Build.0 = Release|Any CPU + {2DF5CFE5-EF8D-4BE4-96D0-C256F2B52011}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2DF5CFE5-EF8D-4BE4-96D0-C256F2B52011}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2DF5CFE5-EF8D-4BE4-96D0-C256F2B52011}.Debug|x64.ActiveCfg = Debug|Any CPU + {2DF5CFE5-EF8D-4BE4-96D0-C256F2B52011}.Debug|x64.Build.0 = Debug|Any CPU + {2DF5CFE5-EF8D-4BE4-96D0-C256F2B52011}.Debug|x86.ActiveCfg = Debug|Any CPU + {2DF5CFE5-EF8D-4BE4-96D0-C256F2B52011}.Debug|x86.Build.0 = Debug|Any CPU + {2DF5CFE5-EF8D-4BE4-96D0-C256F2B52011}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2DF5CFE5-EF8D-4BE4-96D0-C256F2B52011}.Release|Any CPU.Build.0 = Release|Any CPU + {2DF5CFE5-EF8D-4BE4-96D0-C256F2B52011}.Release|x64.ActiveCfg = Release|Any CPU + {2DF5CFE5-EF8D-4BE4-96D0-C256F2B52011}.Release|x64.Build.0 = Release|Any CPU + {2DF5CFE5-EF8D-4BE4-96D0-C256F2B52011}.Release|x86.ActiveCfg = Release|Any CPU + {2DF5CFE5-EF8D-4BE4-96D0-C256F2B52011}.Release|x86.Build.0 = Release|Any CPU + {BA7AC885-A065-41F2-98FF-281C82994F7C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BA7AC885-A065-41F2-98FF-281C82994F7C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BA7AC885-A065-41F2-98FF-281C82994F7C}.Debug|x64.ActiveCfg = Debug|Any CPU + {BA7AC885-A065-41F2-98FF-281C82994F7C}.Debug|x64.Build.0 = Debug|Any CPU + {BA7AC885-A065-41F2-98FF-281C82994F7C}.Debug|x86.ActiveCfg = Debug|Any CPU + {BA7AC885-A065-41F2-98FF-281C82994F7C}.Debug|x86.Build.0 = Debug|Any CPU + {BA7AC885-A065-41F2-98FF-281C82994F7C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BA7AC885-A065-41F2-98FF-281C82994F7C}.Release|Any CPU.Build.0 = Release|Any CPU + {BA7AC885-A065-41F2-98FF-281C82994F7C}.Release|x64.ActiveCfg = Release|Any CPU + {BA7AC885-A065-41F2-98FF-281C82994F7C}.Release|x64.Build.0 = Release|Any CPU + {BA7AC885-A065-41F2-98FF-281C82994F7C}.Release|x86.ActiveCfg = Release|Any CPU + {BA7AC885-A065-41F2-98FF-281C82994F7C}.Release|x86.Build.0 = Release|Any CPU + {65F5AE53-C77A-4818-ADE1-B2D6973A68B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {65F5AE53-C77A-4818-ADE1-B2D6973A68B9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {65F5AE53-C77A-4818-ADE1-B2D6973A68B9}.Debug|x64.ActiveCfg = Debug|Any CPU + {65F5AE53-C77A-4818-ADE1-B2D6973A68B9}.Debug|x64.Build.0 = Debug|Any CPU + {65F5AE53-C77A-4818-ADE1-B2D6973A68B9}.Debug|x86.ActiveCfg = Debug|Any CPU + {65F5AE53-C77A-4818-ADE1-B2D6973A68B9}.Debug|x86.Build.0 = Debug|Any CPU + {65F5AE53-C77A-4818-ADE1-B2D6973A68B9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {65F5AE53-C77A-4818-ADE1-B2D6973A68B9}.Release|Any CPU.Build.0 = Release|Any CPU + {65F5AE53-C77A-4818-ADE1-B2D6973A68B9}.Release|x64.ActiveCfg = Release|Any CPU + {65F5AE53-C77A-4818-ADE1-B2D6973A68B9}.Release|x64.Build.0 = Release|Any CPU + {65F5AE53-C77A-4818-ADE1-B2D6973A68B9}.Release|x86.ActiveCfg = Release|Any CPU + {65F5AE53-C77A-4818-ADE1-B2D6973A68B9}.Release|x86.Build.0 = Release|Any CPU + {E13EEC3A-6DEB-403D-98F5-E143A16F6E9D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E13EEC3A-6DEB-403D-98F5-E143A16F6E9D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E13EEC3A-6DEB-403D-98F5-E143A16F6E9D}.Debug|x64.ActiveCfg = Debug|Any CPU + {E13EEC3A-6DEB-403D-98F5-E143A16F6E9D}.Debug|x64.Build.0 = Debug|Any CPU + {E13EEC3A-6DEB-403D-98F5-E143A16F6E9D}.Debug|x86.ActiveCfg = Debug|Any CPU + {E13EEC3A-6DEB-403D-98F5-E143A16F6E9D}.Debug|x86.Build.0 = Debug|Any CPU + {E13EEC3A-6DEB-403D-98F5-E143A16F6E9D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E13EEC3A-6DEB-403D-98F5-E143A16F6E9D}.Release|Any CPU.Build.0 = Release|Any CPU + {E13EEC3A-6DEB-403D-98F5-E143A16F6E9D}.Release|x64.ActiveCfg = Release|Any CPU + {E13EEC3A-6DEB-403D-98F5-E143A16F6E9D}.Release|x64.Build.0 = Release|Any CPU + {E13EEC3A-6DEB-403D-98F5-E143A16F6E9D}.Release|x86.ActiveCfg = Release|Any CPU + {E13EEC3A-6DEB-403D-98F5-E143A16F6E9D}.Release|x86.Build.0 = Release|Any CPU + {1DE3EF01-EB07-412F-82C9-9709D1981C77}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1DE3EF01-EB07-412F-82C9-9709D1981C77}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1DE3EF01-EB07-412F-82C9-9709D1981C77}.Debug|x64.ActiveCfg = Debug|Any CPU + {1DE3EF01-EB07-412F-82C9-9709D1981C77}.Debug|x64.Build.0 = Debug|Any CPU + {1DE3EF01-EB07-412F-82C9-9709D1981C77}.Debug|x86.ActiveCfg = Debug|Any CPU + {1DE3EF01-EB07-412F-82C9-9709D1981C77}.Debug|x86.Build.0 = Debug|Any CPU + {1DE3EF01-EB07-412F-82C9-9709D1981C77}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1DE3EF01-EB07-412F-82C9-9709D1981C77}.Release|Any CPU.Build.0 = Release|Any CPU + {1DE3EF01-EB07-412F-82C9-9709D1981C77}.Release|x64.ActiveCfg = Release|Any CPU + {1DE3EF01-EB07-412F-82C9-9709D1981C77}.Release|x64.Build.0 = Release|Any CPU + {1DE3EF01-EB07-412F-82C9-9709D1981C77}.Release|x86.ActiveCfg = Release|Any CPU + {1DE3EF01-EB07-412F-82C9-9709D1981C77}.Release|x86.Build.0 = Release|Any CPU + {3025876C-E9AF-4D37-98D2-4A7B56CAD3B1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3025876C-E9AF-4D37-98D2-4A7B56CAD3B1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3025876C-E9AF-4D37-98D2-4A7B56CAD3B1}.Debug|x64.ActiveCfg = Debug|Any CPU + {3025876C-E9AF-4D37-98D2-4A7B56CAD3B1}.Debug|x64.Build.0 = Debug|Any CPU + {3025876C-E9AF-4D37-98D2-4A7B56CAD3B1}.Debug|x86.ActiveCfg = Debug|Any CPU + {3025876C-E9AF-4D37-98D2-4A7B56CAD3B1}.Debug|x86.Build.0 = Debug|Any CPU + {3025876C-E9AF-4D37-98D2-4A7B56CAD3B1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3025876C-E9AF-4D37-98D2-4A7B56CAD3B1}.Release|Any CPU.Build.0 = Release|Any CPU + {3025876C-E9AF-4D37-98D2-4A7B56CAD3B1}.Release|x64.ActiveCfg = Release|Any CPU + {3025876C-E9AF-4D37-98D2-4A7B56CAD3B1}.Release|x64.Build.0 = Release|Any CPU + {3025876C-E9AF-4D37-98D2-4A7B56CAD3B1}.Release|x86.ActiveCfg = Release|Any CPU + {3025876C-E9AF-4D37-98D2-4A7B56CAD3B1}.Release|x86.Build.0 = Release|Any CPU + {19631370-84E9-45A5-B98F-0359499DB2FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {19631370-84E9-45A5-B98F-0359499DB2FA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {19631370-84E9-45A5-B98F-0359499DB2FA}.Debug|x64.ActiveCfg = Debug|Any CPU + {19631370-84E9-45A5-B98F-0359499DB2FA}.Debug|x64.Build.0 = Debug|Any CPU + {19631370-84E9-45A5-B98F-0359499DB2FA}.Debug|x86.ActiveCfg = Debug|Any CPU + {19631370-84E9-45A5-B98F-0359499DB2FA}.Debug|x86.Build.0 = Debug|Any CPU + {19631370-84E9-45A5-B98F-0359499DB2FA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {19631370-84E9-45A5-B98F-0359499DB2FA}.Release|Any CPU.Build.0 = Release|Any CPU + {19631370-84E9-45A5-B98F-0359499DB2FA}.Release|x64.ActiveCfg = Release|Any CPU + {19631370-84E9-45A5-B98F-0359499DB2FA}.Release|x64.Build.0 = Release|Any CPU + {19631370-84E9-45A5-B98F-0359499DB2FA}.Release|x86.ActiveCfg = Release|Any CPU + {19631370-84E9-45A5-B98F-0359499DB2FA}.Release|x86.Build.0 = Release|Any CPU + {1F58262C-B95C-4EC3-95BF-469D7A56480E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1F58262C-B95C-4EC3-95BF-469D7A56480E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1F58262C-B95C-4EC3-95BF-469D7A56480E}.Debug|x64.ActiveCfg = Debug|Any CPU + {1F58262C-B95C-4EC3-95BF-469D7A56480E}.Debug|x64.Build.0 = Debug|Any CPU + {1F58262C-B95C-4EC3-95BF-469D7A56480E}.Debug|x86.ActiveCfg = Debug|Any CPU + {1F58262C-B95C-4EC3-95BF-469D7A56480E}.Debug|x86.Build.0 = Debug|Any CPU + {1F58262C-B95C-4EC3-95BF-469D7A56480E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1F58262C-B95C-4EC3-95BF-469D7A56480E}.Release|Any CPU.Build.0 = Release|Any CPU + {1F58262C-B95C-4EC3-95BF-469D7A56480E}.Release|x64.ActiveCfg = Release|Any CPU + {1F58262C-B95C-4EC3-95BF-469D7A56480E}.Release|x64.Build.0 = Release|Any CPU + {1F58262C-B95C-4EC3-95BF-469D7A56480E}.Release|x86.ActiveCfg = Release|Any CPU + {1F58262C-B95C-4EC3-95BF-469D7A56480E}.Release|x86.Build.0 = Release|Any CPU + {168BAD1F-6D9B-4A41-9A40-CAA2766110EF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {168BAD1F-6D9B-4A41-9A40-CAA2766110EF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {168BAD1F-6D9B-4A41-9A40-CAA2766110EF}.Debug|x64.ActiveCfg = Debug|Any CPU + {168BAD1F-6D9B-4A41-9A40-CAA2766110EF}.Debug|x64.Build.0 = Debug|Any CPU + {168BAD1F-6D9B-4A41-9A40-CAA2766110EF}.Debug|x86.ActiveCfg = Debug|Any CPU + {168BAD1F-6D9B-4A41-9A40-CAA2766110EF}.Debug|x86.Build.0 = Debug|Any CPU + {168BAD1F-6D9B-4A41-9A40-CAA2766110EF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {168BAD1F-6D9B-4A41-9A40-CAA2766110EF}.Release|Any CPU.Build.0 = Release|Any CPU + {168BAD1F-6D9B-4A41-9A40-CAA2766110EF}.Release|x64.ActiveCfg = Release|Any CPU + {168BAD1F-6D9B-4A41-9A40-CAA2766110EF}.Release|x64.Build.0 = Release|Any CPU + {168BAD1F-6D9B-4A41-9A40-CAA2766110EF}.Release|x86.ActiveCfg = Release|Any CPU + {168BAD1F-6D9B-4A41-9A40-CAA2766110EF}.Release|x86.Build.0 = Release|Any CPU + {916DF4C9-3EB7-4D2B-B727-6EEEBB049A80}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {916DF4C9-3EB7-4D2B-B727-6EEEBB049A80}.Debug|Any CPU.Build.0 = Debug|Any CPU + {916DF4C9-3EB7-4D2B-B727-6EEEBB049A80}.Debug|x64.ActiveCfg = Debug|Any CPU + {916DF4C9-3EB7-4D2B-B727-6EEEBB049A80}.Debug|x64.Build.0 = Debug|Any CPU + {916DF4C9-3EB7-4D2B-B727-6EEEBB049A80}.Debug|x86.ActiveCfg = Debug|Any CPU + {916DF4C9-3EB7-4D2B-B727-6EEEBB049A80}.Debug|x86.Build.0 = Debug|Any CPU + {916DF4C9-3EB7-4D2B-B727-6EEEBB049A80}.Release|Any CPU.ActiveCfg = Release|Any CPU + {916DF4C9-3EB7-4D2B-B727-6EEEBB049A80}.Release|Any CPU.Build.0 = Release|Any CPU + {916DF4C9-3EB7-4D2B-B727-6EEEBB049A80}.Release|x64.ActiveCfg = Release|Any CPU + {916DF4C9-3EB7-4D2B-B727-6EEEBB049A80}.Release|x64.Build.0 = Release|Any CPU + {916DF4C9-3EB7-4D2B-B727-6EEEBB049A80}.Release|x86.ActiveCfg = Release|Any CPU + {916DF4C9-3EB7-4D2B-B727-6EEEBB049A80}.Release|x86.Build.0 = Release|Any CPU + {9CF26119-BE08-4C57-945B-2844481F6141}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9CF26119-BE08-4C57-945B-2844481F6141}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9CF26119-BE08-4C57-945B-2844481F6141}.Debug|x64.ActiveCfg = Debug|Any CPU + {9CF26119-BE08-4C57-945B-2844481F6141}.Debug|x64.Build.0 = Debug|Any CPU + {9CF26119-BE08-4C57-945B-2844481F6141}.Debug|x86.ActiveCfg = Debug|Any CPU + {9CF26119-BE08-4C57-945B-2844481F6141}.Debug|x86.Build.0 = Debug|Any CPU + {9CF26119-BE08-4C57-945B-2844481F6141}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9CF26119-BE08-4C57-945B-2844481F6141}.Release|Any CPU.Build.0 = Release|Any CPU + {9CF26119-BE08-4C57-945B-2844481F6141}.Release|x64.ActiveCfg = Release|Any CPU + {9CF26119-BE08-4C57-945B-2844481F6141}.Release|x64.Build.0 = Release|Any CPU + {9CF26119-BE08-4C57-945B-2844481F6141}.Release|x86.ActiveCfg = Release|Any CPU + {9CF26119-BE08-4C57-945B-2844481F6141}.Release|x86.Build.0 = Release|Any CPU + {A7A089BD-3128-48F8-8B18-E467BBA8C7FB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A7A089BD-3128-48F8-8B18-E467BBA8C7FB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A7A089BD-3128-48F8-8B18-E467BBA8C7FB}.Debug|x64.ActiveCfg = Debug|Any CPU + {A7A089BD-3128-48F8-8B18-E467BBA8C7FB}.Debug|x64.Build.0 = Debug|Any CPU + {A7A089BD-3128-48F8-8B18-E467BBA8C7FB}.Debug|x86.ActiveCfg = Debug|Any CPU + {A7A089BD-3128-48F8-8B18-E467BBA8C7FB}.Debug|x86.Build.0 = Debug|Any CPU + {A7A089BD-3128-48F8-8B18-E467BBA8C7FB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A7A089BD-3128-48F8-8B18-E467BBA8C7FB}.Release|Any CPU.Build.0 = Release|Any CPU + {A7A089BD-3128-48F8-8B18-E467BBA8C7FB}.Release|x64.ActiveCfg = Release|Any CPU + {A7A089BD-3128-48F8-8B18-E467BBA8C7FB}.Release|x64.Build.0 = Release|Any CPU + {A7A089BD-3128-48F8-8B18-E467BBA8C7FB}.Release|x86.ActiveCfg = Release|Any CPU + {A7A089BD-3128-48F8-8B18-E467BBA8C7FB}.Release|x86.Build.0 = Release|Any CPU + {9A740958-5F01-4121-84E6-6D05B369AE94}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9A740958-5F01-4121-84E6-6D05B369AE94}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9A740958-5F01-4121-84E6-6D05B369AE94}.Debug|x64.ActiveCfg = Debug|Any CPU + {9A740958-5F01-4121-84E6-6D05B369AE94}.Debug|x64.Build.0 = Debug|Any CPU + {9A740958-5F01-4121-84E6-6D05B369AE94}.Debug|x86.ActiveCfg = Debug|Any CPU + {9A740958-5F01-4121-84E6-6D05B369AE94}.Debug|x86.Build.0 = Debug|Any CPU + {9A740958-5F01-4121-84E6-6D05B369AE94}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9A740958-5F01-4121-84E6-6D05B369AE94}.Release|Any CPU.Build.0 = Release|Any CPU + {9A740958-5F01-4121-84E6-6D05B369AE94}.Release|x64.ActiveCfg = Release|Any CPU + {9A740958-5F01-4121-84E6-6D05B369AE94}.Release|x64.Build.0 = Release|Any CPU + {9A740958-5F01-4121-84E6-6D05B369AE94}.Release|x86.ActiveCfg = Release|Any CPU + {9A740958-5F01-4121-84E6-6D05B369AE94}.Release|x86.Build.0 = Release|Any CPU + {C484A6D7-7798-4C8B-91DC-EA9909D627C8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C484A6D7-7798-4C8B-91DC-EA9909D627C8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C484A6D7-7798-4C8B-91DC-EA9909D627C8}.Debug|x64.ActiveCfg = Debug|Any CPU + {C484A6D7-7798-4C8B-91DC-EA9909D627C8}.Debug|x64.Build.0 = Debug|Any CPU + {C484A6D7-7798-4C8B-91DC-EA9909D627C8}.Debug|x86.ActiveCfg = Debug|Any CPU + {C484A6D7-7798-4C8B-91DC-EA9909D627C8}.Debug|x86.Build.0 = Debug|Any CPU + {C484A6D7-7798-4C8B-91DC-EA9909D627C8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C484A6D7-7798-4C8B-91DC-EA9909D627C8}.Release|Any CPU.Build.0 = Release|Any CPU + {C484A6D7-7798-4C8B-91DC-EA9909D627C8}.Release|x64.ActiveCfg = Release|Any CPU + {C484A6D7-7798-4C8B-91DC-EA9909D627C8}.Release|x64.Build.0 = Release|Any CPU + {C484A6D7-7798-4C8B-91DC-EA9909D627C8}.Release|x86.ActiveCfg = Release|Any CPU + {C484A6D7-7798-4C8B-91DC-EA9909D627C8}.Release|x86.Build.0 = Release|Any CPU + {9CCACC42-070F-4BB5-A06C-D5B7A1ABD519}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9CCACC42-070F-4BB5-A06C-D5B7A1ABD519}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9CCACC42-070F-4BB5-A06C-D5B7A1ABD519}.Debug|x64.ActiveCfg = Debug|Any CPU + {9CCACC42-070F-4BB5-A06C-D5B7A1ABD519}.Debug|x64.Build.0 = Debug|Any CPU + {9CCACC42-070F-4BB5-A06C-D5B7A1ABD519}.Debug|x86.ActiveCfg = Debug|Any CPU + {9CCACC42-070F-4BB5-A06C-D5B7A1ABD519}.Debug|x86.Build.0 = Debug|Any CPU + {9CCACC42-070F-4BB5-A06C-D5B7A1ABD519}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9CCACC42-070F-4BB5-A06C-D5B7A1ABD519}.Release|Any CPU.Build.0 = Release|Any CPU + {9CCACC42-070F-4BB5-A06C-D5B7A1ABD519}.Release|x64.ActiveCfg = Release|Any CPU + {9CCACC42-070F-4BB5-A06C-D5B7A1ABD519}.Release|x64.Build.0 = Release|Any CPU + {9CCACC42-070F-4BB5-A06C-D5B7A1ABD519}.Release|x86.ActiveCfg = Release|Any CPU + {9CCACC42-070F-4BB5-A06C-D5B7A1ABD519}.Release|x86.Build.0 = Release|Any CPU + {F575C6A0-59AF-455D-8B7A-5421D4BAAA2F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F575C6A0-59AF-455D-8B7A-5421D4BAAA2F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F575C6A0-59AF-455D-8B7A-5421D4BAAA2F}.Debug|x64.ActiveCfg = Debug|Any CPU + {F575C6A0-59AF-455D-8B7A-5421D4BAAA2F}.Debug|x64.Build.0 = Debug|Any CPU + {F575C6A0-59AF-455D-8B7A-5421D4BAAA2F}.Debug|x86.ActiveCfg = Debug|Any CPU + {F575C6A0-59AF-455D-8B7A-5421D4BAAA2F}.Debug|x86.Build.0 = Debug|Any CPU + {F575C6A0-59AF-455D-8B7A-5421D4BAAA2F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F575C6A0-59AF-455D-8B7A-5421D4BAAA2F}.Release|Any CPU.Build.0 = Release|Any CPU + {F575C6A0-59AF-455D-8B7A-5421D4BAAA2F}.Release|x64.ActiveCfg = Release|Any CPU + {F575C6A0-59AF-455D-8B7A-5421D4BAAA2F}.Release|x64.Build.0 = Release|Any CPU + {F575C6A0-59AF-455D-8B7A-5421D4BAAA2F}.Release|x86.ActiveCfg = Release|Any CPU + {F575C6A0-59AF-455D-8B7A-5421D4BAAA2F}.Release|x86.Build.0 = Release|Any CPU + {9B667E4D-C905-4CA4-B640-0F3B89293CA8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9B667E4D-C905-4CA4-B640-0F3B89293CA8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9B667E4D-C905-4CA4-B640-0F3B89293CA8}.Debug|x64.ActiveCfg = Debug|Any CPU + {9B667E4D-C905-4CA4-B640-0F3B89293CA8}.Debug|x64.Build.0 = Debug|Any CPU + {9B667E4D-C905-4CA4-B640-0F3B89293CA8}.Debug|x86.ActiveCfg = Debug|Any CPU + {9B667E4D-C905-4CA4-B640-0F3B89293CA8}.Debug|x86.Build.0 = Debug|Any CPU + {9B667E4D-C905-4CA4-B640-0F3B89293CA8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9B667E4D-C905-4CA4-B640-0F3B89293CA8}.Release|Any CPU.Build.0 = Release|Any CPU + {9B667E4D-C905-4CA4-B640-0F3B89293CA8}.Release|x64.ActiveCfg = Release|Any CPU + {9B667E4D-C905-4CA4-B640-0F3B89293CA8}.Release|x64.Build.0 = Release|Any CPU + {9B667E4D-C905-4CA4-B640-0F3B89293CA8}.Release|x86.ActiveCfg = Release|Any CPU + {9B667E4D-C905-4CA4-B640-0F3B89293CA8}.Release|x86.Build.0 = Release|Any CPU + {C3D4E5F6-7890-ABCD-EF12-345678901234}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C3D4E5F6-7890-ABCD-EF12-345678901234}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C3D4E5F6-7890-ABCD-EF12-345678901234}.Debug|x64.ActiveCfg = Debug|Any CPU + {C3D4E5F6-7890-ABCD-EF12-345678901234}.Debug|x64.Build.0 = Debug|Any CPU + {C3D4E5F6-7890-ABCD-EF12-345678901234}.Debug|x86.ActiveCfg = Debug|Any CPU + {C3D4E5F6-7890-ABCD-EF12-345678901234}.Debug|x86.Build.0 = Debug|Any CPU + {C3D4E5F6-7890-ABCD-EF12-345678901234}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C3D4E5F6-7890-ABCD-EF12-345678901234}.Release|Any CPU.Build.0 = Release|Any CPU + {C3D4E5F6-7890-ABCD-EF12-345678901234}.Release|x64.ActiveCfg = Release|Any CPU + {C3D4E5F6-7890-ABCD-EF12-345678901234}.Release|x64.Build.0 = Release|Any CPU + {C3D4E5F6-7890-ABCD-EF12-345678901234}.Release|x86.ActiveCfg = Release|Any CPU + {C3D4E5F6-7890-ABCD-EF12-345678901234}.Release|x86.Build.0 = Release|Any CPU + {C84A54B1-BFF9-4394-A6BF-135C2FC37A64}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C84A54B1-BFF9-4394-A6BF-135C2FC37A64}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C84A54B1-BFF9-4394-A6BF-135C2FC37A64}.Debug|x64.ActiveCfg = Debug|Any CPU + {C84A54B1-BFF9-4394-A6BF-135C2FC37A64}.Debug|x64.Build.0 = Debug|Any CPU + {C84A54B1-BFF9-4394-A6BF-135C2FC37A64}.Debug|x86.ActiveCfg = Debug|Any CPU + {C84A54B1-BFF9-4394-A6BF-135C2FC37A64}.Debug|x86.Build.0 = Debug|Any CPU + {C84A54B1-BFF9-4394-A6BF-135C2FC37A64}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C84A54B1-BFF9-4394-A6BF-135C2FC37A64}.Release|Any CPU.Build.0 = Release|Any CPU + {C84A54B1-BFF9-4394-A6BF-135C2FC37A64}.Release|x64.ActiveCfg = Release|Any CPU + {C84A54B1-BFF9-4394-A6BF-135C2FC37A64}.Release|x64.Build.0 = Release|Any CPU + {C84A54B1-BFF9-4394-A6BF-135C2FC37A64}.Release|x86.ActiveCfg = Release|Any CPU + {C84A54B1-BFF9-4394-A6BF-135C2FC37A64}.Release|x86.Build.0 = Release|Any CPU + {DE1B4312-1A4F-4774-B7EB-B1EC77F80D5E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DE1B4312-1A4F-4774-B7EB-B1EC77F80D5E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DE1B4312-1A4F-4774-B7EB-B1EC77F80D5E}.Debug|x64.ActiveCfg = Debug|Any CPU + {DE1B4312-1A4F-4774-B7EB-B1EC77F80D5E}.Debug|x64.Build.0 = Debug|Any CPU + {DE1B4312-1A4F-4774-B7EB-B1EC77F80D5E}.Debug|x86.ActiveCfg = Debug|Any CPU + {DE1B4312-1A4F-4774-B7EB-B1EC77F80D5E}.Debug|x86.Build.0 = Debug|Any CPU + {DE1B4312-1A4F-4774-B7EB-B1EC77F80D5E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DE1B4312-1A4F-4774-B7EB-B1EC77F80D5E}.Release|Any CPU.Build.0 = Release|Any CPU + {DE1B4312-1A4F-4774-B7EB-B1EC77F80D5E}.Release|x64.ActiveCfg = Release|Any CPU + {DE1B4312-1A4F-4774-B7EB-B1EC77F80D5E}.Release|x64.Build.0 = Release|Any CPU + {DE1B4312-1A4F-4774-B7EB-B1EC77F80D5E}.Release|x86.ActiveCfg = Release|Any CPU + {DE1B4312-1A4F-4774-B7EB-B1EC77F80D5E}.Release|x86.Build.0 = Release|Any CPU + {3156A400-78C7-410A-9B79-9CDFFD5B94E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3156A400-78C7-410A-9B79-9CDFFD5B94E3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3156A400-78C7-410A-9B79-9CDFFD5B94E3}.Debug|x64.ActiveCfg = Debug|Any CPU + {3156A400-78C7-410A-9B79-9CDFFD5B94E3}.Debug|x64.Build.0 = Debug|Any CPU + {3156A400-78C7-410A-9B79-9CDFFD5B94E3}.Debug|x86.ActiveCfg = Debug|Any CPU + {3156A400-78C7-410A-9B79-9CDFFD5B94E3}.Debug|x86.Build.0 = Debug|Any CPU + {3156A400-78C7-410A-9B79-9CDFFD5B94E3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3156A400-78C7-410A-9B79-9CDFFD5B94E3}.Release|Any CPU.Build.0 = Release|Any CPU + {3156A400-78C7-410A-9B79-9CDFFD5B94E3}.Release|x64.ActiveCfg = Release|Any CPU + {3156A400-78C7-410A-9B79-9CDFFD5B94E3}.Release|x64.Build.0 = Release|Any CPU + {3156A400-78C7-410A-9B79-9CDFFD5B94E3}.Release|x86.ActiveCfg = Release|Any CPU + {3156A400-78C7-410A-9B79-9CDFFD5B94E3}.Release|x86.Build.0 = Release|Any CPU + {FCEFF719-E5F5-4BB6-83EF-17201FB14FF2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FCEFF719-E5F5-4BB6-83EF-17201FB14FF2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FCEFF719-E5F5-4BB6-83EF-17201FB14FF2}.Debug|x64.ActiveCfg = Debug|Any CPU + {FCEFF719-E5F5-4BB6-83EF-17201FB14FF2}.Debug|x64.Build.0 = Debug|Any CPU + {FCEFF719-E5F5-4BB6-83EF-17201FB14FF2}.Debug|x86.ActiveCfg = Debug|Any CPU + {FCEFF719-E5F5-4BB6-83EF-17201FB14FF2}.Debug|x86.Build.0 = Debug|Any CPU + {FCEFF719-E5F5-4BB6-83EF-17201FB14FF2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FCEFF719-E5F5-4BB6-83EF-17201FB14FF2}.Release|Any CPU.Build.0 = Release|Any CPU + {FCEFF719-E5F5-4BB6-83EF-17201FB14FF2}.Release|x64.ActiveCfg = Release|Any CPU + {FCEFF719-E5F5-4BB6-83EF-17201FB14FF2}.Release|x64.Build.0 = Release|Any CPU + {FCEFF719-E5F5-4BB6-83EF-17201FB14FF2}.Release|x86.ActiveCfg = Release|Any CPU + {FCEFF719-E5F5-4BB6-83EF-17201FB14FF2}.Release|x86.Build.0 = Release|Any CPU + {AE9E8273-2844-41A7-AE84-36E2F8B1B3DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AE9E8273-2844-41A7-AE84-36E2F8B1B3DE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AE9E8273-2844-41A7-AE84-36E2F8B1B3DE}.Debug|x64.ActiveCfg = Debug|Any CPU + {AE9E8273-2844-41A7-AE84-36E2F8B1B3DE}.Debug|x64.Build.0 = Debug|Any CPU + {AE9E8273-2844-41A7-AE84-36E2F8B1B3DE}.Debug|x86.ActiveCfg = Debug|Any CPU + {AE9E8273-2844-41A7-AE84-36E2F8B1B3DE}.Debug|x86.Build.0 = Debug|Any CPU + {AE9E8273-2844-41A7-AE84-36E2F8B1B3DE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AE9E8273-2844-41A7-AE84-36E2F8B1B3DE}.Release|Any CPU.Build.0 = Release|Any CPU + {AE9E8273-2844-41A7-AE84-36E2F8B1B3DE}.Release|x64.ActiveCfg = Release|Any CPU + {AE9E8273-2844-41A7-AE84-36E2F8B1B3DE}.Release|x64.Build.0 = Release|Any CPU + {AE9E8273-2844-41A7-AE84-36E2F8B1B3DE}.Release|x86.ActiveCfg = Release|Any CPU + {AE9E8273-2844-41A7-AE84-36E2F8B1B3DE}.Release|x86.Build.0 = Release|Any CPU + {B7418A46-E05D-4605-9BAE-8308BEF25641}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B7418A46-E05D-4605-9BAE-8308BEF25641}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B7418A46-E05D-4605-9BAE-8308BEF25641}.Debug|x64.ActiveCfg = Debug|Any CPU + {B7418A46-E05D-4605-9BAE-8308BEF25641}.Debug|x64.Build.0 = Debug|Any CPU + {B7418A46-E05D-4605-9BAE-8308BEF25641}.Debug|x86.ActiveCfg = Debug|Any CPU + {B7418A46-E05D-4605-9BAE-8308BEF25641}.Debug|x86.Build.0 = Debug|Any CPU + {B7418A46-E05D-4605-9BAE-8308BEF25641}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B7418A46-E05D-4605-9BAE-8308BEF25641}.Release|Any CPU.Build.0 = Release|Any CPU + {B7418A46-E05D-4605-9BAE-8308BEF25641}.Release|x64.ActiveCfg = Release|Any CPU + {B7418A46-E05D-4605-9BAE-8308BEF25641}.Release|x64.Build.0 = Release|Any CPU + {B7418A46-E05D-4605-9BAE-8308BEF25641}.Release|x86.ActiveCfg = Release|Any CPU + {B7418A46-E05D-4605-9BAE-8308BEF25641}.Release|x86.Build.0 = Release|Any CPU + {E3F17DAA-1EFB-40F3-9F16-F77AF18893F2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E3F17DAA-1EFB-40F3-9F16-F77AF18893F2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E3F17DAA-1EFB-40F3-9F16-F77AF18893F2}.Debug|x64.ActiveCfg = Debug|Any CPU + {E3F17DAA-1EFB-40F3-9F16-F77AF18893F2}.Debug|x64.Build.0 = Debug|Any CPU + {E3F17DAA-1EFB-40F3-9F16-F77AF18893F2}.Debug|x86.ActiveCfg = Debug|Any CPU + {E3F17DAA-1EFB-40F3-9F16-F77AF18893F2}.Debug|x86.Build.0 = Debug|Any CPU + {E3F17DAA-1EFB-40F3-9F16-F77AF18893F2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E3F17DAA-1EFB-40F3-9F16-F77AF18893F2}.Release|Any CPU.Build.0 = Release|Any CPU + {E3F17DAA-1EFB-40F3-9F16-F77AF18893F2}.Release|x64.ActiveCfg = Release|Any CPU + {E3F17DAA-1EFB-40F3-9F16-F77AF18893F2}.Release|x64.Build.0 = Release|Any CPU + {E3F17DAA-1EFB-40F3-9F16-F77AF18893F2}.Release|x86.ActiveCfg = Release|Any CPU + {E3F17DAA-1EFB-40F3-9F16-F77AF18893F2}.Release|x86.Build.0 = Release|Any CPU + {1CB18013-ABED-48C1-8576-1E8ABCD70293}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1CB18013-ABED-48C1-8576-1E8ABCD70293}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1CB18013-ABED-48C1-8576-1E8ABCD70293}.Debug|x64.ActiveCfg = Debug|Any CPU + {1CB18013-ABED-48C1-8576-1E8ABCD70293}.Debug|x64.Build.0 = Debug|Any CPU + {1CB18013-ABED-48C1-8576-1E8ABCD70293}.Debug|x86.ActiveCfg = Debug|Any CPU + {1CB18013-ABED-48C1-8576-1E8ABCD70293}.Debug|x86.Build.0 = Debug|Any CPU + {1CB18013-ABED-48C1-8576-1E8ABCD70293}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1CB18013-ABED-48C1-8576-1E8ABCD70293}.Release|Any CPU.Build.0 = Release|Any CPU + {1CB18013-ABED-48C1-8576-1E8ABCD70293}.Release|x64.ActiveCfg = Release|Any CPU + {1CB18013-ABED-48C1-8576-1E8ABCD70293}.Release|x64.Build.0 = Release|Any CPU + {1CB18013-ABED-48C1-8576-1E8ABCD70293}.Release|x86.ActiveCfg = Release|Any CPU + {1CB18013-ABED-48C1-8576-1E8ABCD70293}.Release|x86.Build.0 = Release|Any CPU + {56650789-168A-427A-A354-7AF969417C47}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {56650789-168A-427A-A354-7AF969417C47}.Debug|Any CPU.Build.0 = Debug|Any CPU + {56650789-168A-427A-A354-7AF969417C47}.Debug|x64.ActiveCfg = Debug|Any CPU + {56650789-168A-427A-A354-7AF969417C47}.Debug|x64.Build.0 = Debug|Any CPU + {56650789-168A-427A-A354-7AF969417C47}.Debug|x86.ActiveCfg = Debug|Any CPU + {56650789-168A-427A-A354-7AF969417C47}.Debug|x86.Build.0 = Debug|Any CPU + {56650789-168A-427A-A354-7AF969417C47}.Release|Any CPU.ActiveCfg = Release|Any CPU + {56650789-168A-427A-A354-7AF969417C47}.Release|Any CPU.Build.0 = Release|Any CPU + {56650789-168A-427A-A354-7AF969417C47}.Release|x64.ActiveCfg = Release|Any CPU + {56650789-168A-427A-A354-7AF969417C47}.Release|x64.Build.0 = Release|Any CPU + {56650789-168A-427A-A354-7AF969417C47}.Release|x86.ActiveCfg = Release|Any CPU + {56650789-168A-427A-A354-7AF969417C47}.Release|x86.Build.0 = Release|Any CPU + {C11ED240-7ADE-43A2-7C2C-04463E5CCAA8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C11ED240-7ADE-43A2-7C2C-04463E5CCAA8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C11ED240-7ADE-43A2-7C2C-04463E5CCAA8}.Debug|x64.ActiveCfg = Debug|Any CPU + {C11ED240-7ADE-43A2-7C2C-04463E5CCAA8}.Debug|x64.Build.0 = Debug|Any CPU + {C11ED240-7ADE-43A2-7C2C-04463E5CCAA8}.Debug|x86.ActiveCfg = Debug|Any CPU + {C11ED240-7ADE-43A2-7C2C-04463E5CCAA8}.Debug|x86.Build.0 = Debug|Any CPU + {C11ED240-7ADE-43A2-7C2C-04463E5CCAA8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C11ED240-7ADE-43A2-7C2C-04463E5CCAA8}.Release|Any CPU.Build.0 = Release|Any CPU + {C11ED240-7ADE-43A2-7C2C-04463E5CCAA8}.Release|x64.ActiveCfg = Release|Any CPU + {C11ED240-7ADE-43A2-7C2C-04463E5CCAA8}.Release|x64.Build.0 = Release|Any CPU + {C11ED240-7ADE-43A2-7C2C-04463E5CCAA8}.Release|x86.ActiveCfg = Release|Any CPU + {C11ED240-7ADE-43A2-7C2C-04463E5CCAA8}.Release|x86.Build.0 = Release|Any CPU + {7C56FC56-343A-4C68-AD1A-8C2CBC5DED74}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7C56FC56-343A-4C68-AD1A-8C2CBC5DED74}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7C56FC56-343A-4C68-AD1A-8C2CBC5DED74}.Debug|x64.ActiveCfg = Debug|Any CPU + {7C56FC56-343A-4C68-AD1A-8C2CBC5DED74}.Debug|x64.Build.0 = Debug|Any CPU + {7C56FC56-343A-4C68-AD1A-8C2CBC5DED74}.Debug|x86.ActiveCfg = Debug|Any CPU + {7C56FC56-343A-4C68-AD1A-8C2CBC5DED74}.Debug|x86.Build.0 = Debug|Any CPU + {7C56FC56-343A-4C68-AD1A-8C2CBC5DED74}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7C56FC56-343A-4C68-AD1A-8C2CBC5DED74}.Release|Any CPU.Build.0 = Release|Any CPU + {7C56FC56-343A-4C68-AD1A-8C2CBC5DED74}.Release|x64.ActiveCfg = Release|Any CPU + {7C56FC56-343A-4C68-AD1A-8C2CBC5DED74}.Release|x64.Build.0 = Release|Any CPU + {7C56FC56-343A-4C68-AD1A-8C2CBC5DED74}.Release|x86.ActiveCfg = Release|Any CPU + {7C56FC56-343A-4C68-AD1A-8C2CBC5DED74}.Release|x86.Build.0 = Release|Any CPU + {8C5CED5B-ECB8-4847-9435-B7954055A530}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8C5CED5B-ECB8-4847-9435-B7954055A530}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8C5CED5B-ECB8-4847-9435-B7954055A530}.Debug|x64.ActiveCfg = Debug|Any CPU + {8C5CED5B-ECB8-4847-9435-B7954055A530}.Debug|x64.Build.0 = Debug|Any CPU + {8C5CED5B-ECB8-4847-9435-B7954055A530}.Debug|x86.ActiveCfg = Debug|Any CPU + {8C5CED5B-ECB8-4847-9435-B7954055A530}.Debug|x86.Build.0 = Debug|Any CPU + {8C5CED5B-ECB8-4847-9435-B7954055A530}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8C5CED5B-ECB8-4847-9435-B7954055A530}.Release|Any CPU.Build.0 = Release|Any CPU + {8C5CED5B-ECB8-4847-9435-B7954055A530}.Release|x64.ActiveCfg = Release|Any CPU + {8C5CED5B-ECB8-4847-9435-B7954055A530}.Release|x64.Build.0 = Release|Any CPU + {8C5CED5B-ECB8-4847-9435-B7954055A530}.Release|x86.ActiveCfg = Release|Any CPU + {8C5CED5B-ECB8-4847-9435-B7954055A530}.Release|x86.Build.0 = Release|Any CPU + {9131BD5D-B459-46AE-809D-F066B2FD119A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9131BD5D-B459-46AE-809D-F066B2FD119A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9131BD5D-B459-46AE-809D-F066B2FD119A}.Debug|x64.ActiveCfg = Debug|Any CPU + {9131BD5D-B459-46AE-809D-F066B2FD119A}.Debug|x64.Build.0 = Debug|Any CPU + {9131BD5D-B459-46AE-809D-F066B2FD119A}.Debug|x86.ActiveCfg = Debug|Any CPU + {9131BD5D-B459-46AE-809D-F066B2FD119A}.Debug|x86.Build.0 = Debug|Any CPU + {9131BD5D-B459-46AE-809D-F066B2FD119A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9131BD5D-B459-46AE-809D-F066B2FD119A}.Release|Any CPU.Build.0 = Release|Any CPU + {9131BD5D-B459-46AE-809D-F066B2FD119A}.Release|x64.ActiveCfg = Release|Any CPU + {9131BD5D-B459-46AE-809D-F066B2FD119A}.Release|x64.Build.0 = Release|Any CPU + {9131BD5D-B459-46AE-809D-F066B2FD119A}.Release|x86.ActiveCfg = Release|Any CPU + {9131BD5D-B459-46AE-809D-F066B2FD119A}.Release|x86.Build.0 = Release|Any CPU + {492A0B4A-C7EA-4469-814E-373B3DD90E6E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {492A0B4A-C7EA-4469-814E-373B3DD90E6E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {492A0B4A-C7EA-4469-814E-373B3DD90E6E}.Debug|x64.ActiveCfg = Debug|Any CPU + {492A0B4A-C7EA-4469-814E-373B3DD90E6E}.Debug|x64.Build.0 = Debug|Any CPU + {492A0B4A-C7EA-4469-814E-373B3DD90E6E}.Debug|x86.ActiveCfg = Debug|Any CPU + {492A0B4A-C7EA-4469-814E-373B3DD90E6E}.Debug|x86.Build.0 = Debug|Any CPU + {492A0B4A-C7EA-4469-814E-373B3DD90E6E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {492A0B4A-C7EA-4469-814E-373B3DD90E6E}.Release|Any CPU.Build.0 = Release|Any CPU + {492A0B4A-C7EA-4469-814E-373B3DD90E6E}.Release|x64.ActiveCfg = Release|Any CPU + {492A0B4A-C7EA-4469-814E-373B3DD90E6E}.Release|x64.Build.0 = Release|Any CPU + {492A0B4A-C7EA-4469-814E-373B3DD90E6E}.Release|x86.ActiveCfg = Release|Any CPU + {492A0B4A-C7EA-4469-814E-373B3DD90E6E}.Release|x86.Build.0 = Release|Any CPU + {9EB26D07-4530-44BA-BB2F-F5A20B86EF08}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9EB26D07-4530-44BA-BB2F-F5A20B86EF08}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9EB26D07-4530-44BA-BB2F-F5A20B86EF08}.Debug|x64.ActiveCfg = Debug|Any CPU + {9EB26D07-4530-44BA-BB2F-F5A20B86EF08}.Debug|x64.Build.0 = Debug|Any CPU + {9EB26D07-4530-44BA-BB2F-F5A20B86EF08}.Debug|x86.ActiveCfg = Debug|Any CPU + {9EB26D07-4530-44BA-BB2F-F5A20B86EF08}.Debug|x86.Build.0 = Debug|Any CPU + {9EB26D07-4530-44BA-BB2F-F5A20B86EF08}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9EB26D07-4530-44BA-BB2F-F5A20B86EF08}.Release|Any CPU.Build.0 = Release|Any CPU + {9EB26D07-4530-44BA-BB2F-F5A20B86EF08}.Release|x64.ActiveCfg = Release|Any CPU + {9EB26D07-4530-44BA-BB2F-F5A20B86EF08}.Release|x64.Build.0 = Release|Any CPU + {9EB26D07-4530-44BA-BB2F-F5A20B86EF08}.Release|x86.ActiveCfg = Release|Any CPU + {9EB26D07-4530-44BA-BB2F-F5A20B86EF08}.Release|x86.Build.0 = Release|Any CPU + {AACC56D7-3738-4C63-835F-A8373A084CFA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AACC56D7-3738-4C63-835F-A8373A084CFA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AACC56D7-3738-4C63-835F-A8373A084CFA}.Debug|x64.ActiveCfg = Debug|Any CPU + {AACC56D7-3738-4C63-835F-A8373A084CFA}.Debug|x64.Build.0 = Debug|Any CPU + {AACC56D7-3738-4C63-835F-A8373A084CFA}.Debug|x86.ActiveCfg = Debug|Any CPU + {AACC56D7-3738-4C63-835F-A8373A084CFA}.Debug|x86.Build.0 = Debug|Any CPU + {AACC56D7-3738-4C63-835F-A8373A084CFA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AACC56D7-3738-4C63-835F-A8373A084CFA}.Release|Any CPU.Build.0 = Release|Any CPU + {AACC56D7-3738-4C63-835F-A8373A084CFA}.Release|x64.ActiveCfg = Release|Any CPU + {AACC56D7-3738-4C63-835F-A8373A084CFA}.Release|x64.Build.0 = Release|Any CPU + {AACC56D7-3738-4C63-835F-A8373A084CFA}.Release|x86.ActiveCfg = Release|Any CPU + {AACC56D7-3738-4C63-835F-A8373A084CFA}.Release|x86.Build.0 = Release|Any CPU + {57C9E70F-2035-4217-8D35-C5498103E52C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {57C9E70F-2035-4217-8D35-C5498103E52C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {57C9E70F-2035-4217-8D35-C5498103E52C}.Debug|x64.ActiveCfg = Debug|Any CPU + {57C9E70F-2035-4217-8D35-C5498103E52C}.Debug|x64.Build.0 = Debug|Any CPU + {57C9E70F-2035-4217-8D35-C5498103E52C}.Debug|x86.ActiveCfg = Debug|Any CPU + {57C9E70F-2035-4217-8D35-C5498103E52C}.Debug|x86.Build.0 = Debug|Any CPU + {57C9E70F-2035-4217-8D35-C5498103E52C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {57C9E70F-2035-4217-8D35-C5498103E52C}.Release|Any CPU.Build.0 = Release|Any CPU + {57C9E70F-2035-4217-8D35-C5498103E52C}.Release|x64.ActiveCfg = Release|Any CPU + {57C9E70F-2035-4217-8D35-C5498103E52C}.Release|x64.Build.0 = Release|Any CPU + {57C9E70F-2035-4217-8D35-C5498103E52C}.Release|x86.ActiveCfg = Release|Any CPU + {57C9E70F-2035-4217-8D35-C5498103E52C}.Release|x86.Build.0 = Release|Any CPU + {B2C3D4E5-F6A7-8901-BCDE-F23456789012}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B2C3D4E5-F6A7-8901-BCDE-F23456789012}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B2C3D4E5-F6A7-8901-BCDE-F23456789012}.Debug|x64.ActiveCfg = Debug|Any CPU + {B2C3D4E5-F6A7-8901-BCDE-F23456789012}.Debug|x64.Build.0 = Debug|Any CPU + {B2C3D4E5-F6A7-8901-BCDE-F23456789012}.Debug|x86.ActiveCfg = Debug|Any CPU + {B2C3D4E5-F6A7-8901-BCDE-F23456789012}.Debug|x86.Build.0 = Debug|Any CPU + {B2C3D4E5-F6A7-8901-BCDE-F23456789012}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B2C3D4E5-F6A7-8901-BCDE-F23456789012}.Release|Any CPU.Build.0 = Release|Any CPU + {B2C3D4E5-F6A7-8901-BCDE-F23456789012}.Release|x64.ActiveCfg = Release|Any CPU + {B2C3D4E5-F6A7-8901-BCDE-F23456789012}.Release|x64.Build.0 = Release|Any CPU + {B2C3D4E5-F6A7-8901-BCDE-F23456789012}.Release|x86.ActiveCfg = Release|Any CPU + {B2C3D4E5-F6A7-8901-BCDE-F23456789012}.Release|x86.Build.0 = Release|Any CPU + {C0F9D8F5-3F6D-4D46-9E6D-8A7E4EDC0E11}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C0F9D8F5-3F6D-4D46-9E6D-8A7E4EDC0E11}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C0F9D8F5-3F6D-4D46-9E6D-8A7E4EDC0E11}.Debug|x64.ActiveCfg = Debug|Any CPU + {C0F9D8F5-3F6D-4D46-9E6D-8A7E4EDC0E11}.Debug|x64.Build.0 = Debug|Any CPU + {C0F9D8F5-3F6D-4D46-9E6D-8A7E4EDC0E11}.Debug|x86.ActiveCfg = Debug|Any CPU + {C0F9D8F5-3F6D-4D46-9E6D-8A7E4EDC0E11}.Debug|x86.Build.0 = Debug|Any CPU + {C0F9D8F5-3F6D-4D46-9E6D-8A7E4EDC0E11}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C0F9D8F5-3F6D-4D46-9E6D-8A7E4EDC0E11}.Release|Any CPU.Build.0 = Release|Any CPU + {C0F9D8F5-3F6D-4D46-9E6D-8A7E4EDC0E11}.Release|x64.ActiveCfg = Release|Any CPU + {C0F9D8F5-3F6D-4D46-9E6D-8A7E4EDC0E11}.Release|x64.Build.0 = Release|Any CPU + {C0F9D8F5-3F6D-4D46-9E6D-8A7E4EDC0E11}.Release|x86.ActiveCfg = Release|Any CPU + {C0F9D8F5-3F6D-4D46-9E6D-8A7E4EDC0E11}.Release|x86.Build.0 = Release|Any CPU + {10E02570-BC66-4389-AD30-2E19CB9BD700}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {10E02570-BC66-4389-AD30-2E19CB9BD700}.Debug|Any CPU.Build.0 = Debug|Any CPU + {10E02570-BC66-4389-AD30-2E19CB9BD700}.Debug|x64.ActiveCfg = Debug|Any CPU + {10E02570-BC66-4389-AD30-2E19CB9BD700}.Debug|x64.Build.0 = Debug|Any CPU + {10E02570-BC66-4389-AD30-2E19CB9BD700}.Debug|x86.ActiveCfg = Debug|Any CPU + {10E02570-BC66-4389-AD30-2E19CB9BD700}.Debug|x86.Build.0 = Debug|Any CPU + {10E02570-BC66-4389-AD30-2E19CB9BD700}.Release|Any CPU.ActiveCfg = Release|Any CPU + {10E02570-BC66-4389-AD30-2E19CB9BD700}.Release|Any CPU.Build.0 = Release|Any CPU + {10E02570-BC66-4389-AD30-2E19CB9BD700}.Release|x64.ActiveCfg = Release|Any CPU + {10E02570-BC66-4389-AD30-2E19CB9BD700}.Release|x64.Build.0 = Release|Any CPU + {10E02570-BC66-4389-AD30-2E19CB9BD700}.Release|x86.ActiveCfg = Release|Any CPU + {10E02570-BC66-4389-AD30-2E19CB9BD700}.Release|x86.Build.0 = Release|Any CPU + {9D157338-0F03-4A4C-AD84-39E04B6368BF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9D157338-0F03-4A4C-AD84-39E04B6368BF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9D157338-0F03-4A4C-AD84-39E04B6368BF}.Debug|x64.ActiveCfg = Debug|Any CPU + {9D157338-0F03-4A4C-AD84-39E04B6368BF}.Debug|x64.Build.0 = Debug|Any CPU + {9D157338-0F03-4A4C-AD84-39E04B6368BF}.Debug|x86.ActiveCfg = Debug|Any CPU + {9D157338-0F03-4A4C-AD84-39E04B6368BF}.Debug|x86.Build.0 = Debug|Any CPU + {9D157338-0F03-4A4C-AD84-39E04B6368BF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9D157338-0F03-4A4C-AD84-39E04B6368BF}.Release|Any CPU.Build.0 = Release|Any CPU + {9D157338-0F03-4A4C-AD84-39E04B6368BF}.Release|x64.ActiveCfg = Release|Any CPU + {9D157338-0F03-4A4C-AD84-39E04B6368BF}.Release|x64.Build.0 = Release|Any CPU + {9D157338-0F03-4A4C-AD84-39E04B6368BF}.Release|x86.ActiveCfg = Release|Any CPU + {9D157338-0F03-4A4C-AD84-39E04B6368BF}.Release|x86.Build.0 = Release|Any CPU + {55B6007F-5F58-4F33-91A5-677859BAE2D6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {55B6007F-5F58-4F33-91A5-677859BAE2D6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {55B6007F-5F58-4F33-91A5-677859BAE2D6}.Debug|x64.ActiveCfg = Debug|Any CPU + {55B6007F-5F58-4F33-91A5-677859BAE2D6}.Debug|x64.Build.0 = Debug|Any CPU + {55B6007F-5F58-4F33-91A5-677859BAE2D6}.Debug|x86.ActiveCfg = Debug|Any CPU + {55B6007F-5F58-4F33-91A5-677859BAE2D6}.Debug|x86.Build.0 = Debug|Any CPU + {55B6007F-5F58-4F33-91A5-677859BAE2D6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {55B6007F-5F58-4F33-91A5-677859BAE2D6}.Release|Any CPU.Build.0 = Release|Any CPU + {55B6007F-5F58-4F33-91A5-677859BAE2D6}.Release|x64.ActiveCfg = Release|Any CPU + {55B6007F-5F58-4F33-91A5-677859BAE2D6}.Release|x64.Build.0 = Release|Any CPU + {55B6007F-5F58-4F33-91A5-677859BAE2D6}.Release|x86.ActiveCfg = Release|Any CPU + {55B6007F-5F58-4F33-91A5-677859BAE2D6}.Release|x86.Build.0 = Release|Any CPU + {1A9485FE-242C-4627-AC8D-9B36512162C4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1A9485FE-242C-4627-AC8D-9B36512162C4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1A9485FE-242C-4627-AC8D-9B36512162C4}.Debug|x64.ActiveCfg = Debug|Any CPU + {1A9485FE-242C-4627-AC8D-9B36512162C4}.Debug|x64.Build.0 = Debug|Any CPU + {1A9485FE-242C-4627-AC8D-9B36512162C4}.Debug|x86.ActiveCfg = Debug|Any CPU + {1A9485FE-242C-4627-AC8D-9B36512162C4}.Debug|x86.Build.0 = Debug|Any CPU + {1A9485FE-242C-4627-AC8D-9B36512162C4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1A9485FE-242C-4627-AC8D-9B36512162C4}.Release|Any CPU.Build.0 = Release|Any CPU + {1A9485FE-242C-4627-AC8D-9B36512162C4}.Release|x64.ActiveCfg = Release|Any CPU + {1A9485FE-242C-4627-AC8D-9B36512162C4}.Release|x64.Build.0 = Release|Any CPU + {1A9485FE-242C-4627-AC8D-9B36512162C4}.Release|x86.ActiveCfg = Release|Any CPU + {1A9485FE-242C-4627-AC8D-9B36512162C4}.Release|x86.Build.0 = Release|Any CPU + {AAF964F7-6902-4A7C-9F52-59FF502920D5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AAF964F7-6902-4A7C-9F52-59FF502920D5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AAF964F7-6902-4A7C-9F52-59FF502920D5}.Debug|x64.ActiveCfg = Debug|Any CPU + {AAF964F7-6902-4A7C-9F52-59FF502920D5}.Debug|x64.Build.0 = Debug|Any CPU + {AAF964F7-6902-4A7C-9F52-59FF502920D5}.Debug|x86.ActiveCfg = Debug|Any CPU + {AAF964F7-6902-4A7C-9F52-59FF502920D5}.Debug|x86.Build.0 = Debug|Any CPU + {AAF964F7-6902-4A7C-9F52-59FF502920D5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AAF964F7-6902-4A7C-9F52-59FF502920D5}.Release|Any CPU.Build.0 = Release|Any CPU + {AAF964F7-6902-4A7C-9F52-59FF502920D5}.Release|x64.ActiveCfg = Release|Any CPU + {AAF964F7-6902-4A7C-9F52-59FF502920D5}.Release|x64.Build.0 = Release|Any CPU + {AAF964F7-6902-4A7C-9F52-59FF502920D5}.Release|x86.ActiveCfg = Release|Any CPU + {AAF964F7-6902-4A7C-9F52-59FF502920D5}.Release|x86.Build.0 = Release|Any CPU + {FFA1F834-6049-474C-9EED-72E1A3F9646E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FFA1F834-6049-474C-9EED-72E1A3F9646E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FFA1F834-6049-474C-9EED-72E1A3F9646E}.Debug|x64.ActiveCfg = Debug|Any CPU + {FFA1F834-6049-474C-9EED-72E1A3F9646E}.Debug|x64.Build.0 = Debug|Any CPU + {FFA1F834-6049-474C-9EED-72E1A3F9646E}.Debug|x86.ActiveCfg = Debug|Any CPU + {FFA1F834-6049-474C-9EED-72E1A3F9646E}.Debug|x86.Build.0 = Debug|Any CPU + {FFA1F834-6049-474C-9EED-72E1A3F9646E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FFA1F834-6049-474C-9EED-72E1A3F9646E}.Release|Any CPU.Build.0 = Release|Any CPU + {FFA1F834-6049-474C-9EED-72E1A3F9646E}.Release|x64.ActiveCfg = Release|Any CPU + {FFA1F834-6049-474C-9EED-72E1A3F9646E}.Release|x64.Build.0 = Release|Any CPU + {FFA1F834-6049-474C-9EED-72E1A3F9646E}.Release|x86.ActiveCfg = Release|Any CPU + {FFA1F834-6049-474C-9EED-72E1A3F9646E}.Release|x86.Build.0 = Release|Any CPU + {D3348F94-9831-4A3D-8E79-844900B88287}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D3348F94-9831-4A3D-8E79-844900B88287}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D3348F94-9831-4A3D-8E79-844900B88287}.Debug|x64.ActiveCfg = Debug|Any CPU + {D3348F94-9831-4A3D-8E79-844900B88287}.Debug|x64.Build.0 = Debug|Any CPU + {D3348F94-9831-4A3D-8E79-844900B88287}.Debug|x86.ActiveCfg = Debug|Any CPU + {D3348F94-9831-4A3D-8E79-844900B88287}.Debug|x86.Build.0 = Debug|Any CPU + {D3348F94-9831-4A3D-8E79-844900B88287}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D3348F94-9831-4A3D-8E79-844900B88287}.Release|Any CPU.Build.0 = Release|Any CPU + {D3348F94-9831-4A3D-8E79-844900B88287}.Release|x64.ActiveCfg = Release|Any CPU + {D3348F94-9831-4A3D-8E79-844900B88287}.Release|x64.Build.0 = Release|Any CPU + {D3348F94-9831-4A3D-8E79-844900B88287}.Release|x86.ActiveCfg = Release|Any CPU + {D3348F94-9831-4A3D-8E79-844900B88287}.Release|x86.Build.0 = Release|Any CPU + {75A5A87C-BF04-4ABE-B466-874074D37C8D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {75A5A87C-BF04-4ABE-B466-874074D37C8D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {75A5A87C-BF04-4ABE-B466-874074D37C8D}.Debug|x64.ActiveCfg = Debug|Any CPU + {75A5A87C-BF04-4ABE-B466-874074D37C8D}.Debug|x64.Build.0 = Debug|Any CPU + {75A5A87C-BF04-4ABE-B466-874074D37C8D}.Debug|x86.ActiveCfg = Debug|Any CPU + {75A5A87C-BF04-4ABE-B466-874074D37C8D}.Debug|x86.Build.0 = Debug|Any CPU + {75A5A87C-BF04-4ABE-B466-874074D37C8D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {75A5A87C-BF04-4ABE-B466-874074D37C8D}.Release|Any CPU.Build.0 = Release|Any CPU + {75A5A87C-BF04-4ABE-B466-874074D37C8D}.Release|x64.ActiveCfg = Release|Any CPU + {75A5A87C-BF04-4ABE-B466-874074D37C8D}.Release|x64.Build.0 = Release|Any CPU + {75A5A87C-BF04-4ABE-B466-874074D37C8D}.Release|x86.ActiveCfg = Release|Any CPU + {75A5A87C-BF04-4ABE-B466-874074D37C8D}.Release|x86.Build.0 = Release|Any CPU + {D1BCD822-AC8A-408F-A71A-9205DB29A9D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D1BCD822-AC8A-408F-A71A-9205DB29A9D2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D1BCD822-AC8A-408F-A71A-9205DB29A9D2}.Debug|x64.ActiveCfg = Debug|Any CPU + {D1BCD822-AC8A-408F-A71A-9205DB29A9D2}.Debug|x64.Build.0 = Debug|Any CPU + {D1BCD822-AC8A-408F-A71A-9205DB29A9D2}.Debug|x86.ActiveCfg = Debug|Any CPU + {D1BCD822-AC8A-408F-A71A-9205DB29A9D2}.Debug|x86.Build.0 = Debug|Any CPU + {D1BCD822-AC8A-408F-A71A-9205DB29A9D2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D1BCD822-AC8A-408F-A71A-9205DB29A9D2}.Release|Any CPU.Build.0 = Release|Any CPU + {D1BCD822-AC8A-408F-A71A-9205DB29A9D2}.Release|x64.ActiveCfg = Release|Any CPU + {D1BCD822-AC8A-408F-A71A-9205DB29A9D2}.Release|x64.Build.0 = Release|Any CPU + {D1BCD822-AC8A-408F-A71A-9205DB29A9D2}.Release|x86.ActiveCfg = Release|Any CPU + {D1BCD822-AC8A-408F-A71A-9205DB29A9D2}.Release|x86.Build.0 = Release|Any CPU + {A99D3C27-65B7-4ADF-AB54-6D8649D1E7C7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A99D3C27-65B7-4ADF-AB54-6D8649D1E7C7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A99D3C27-65B7-4ADF-AB54-6D8649D1E7C7}.Debug|x64.ActiveCfg = Debug|Any CPU + {A99D3C27-65B7-4ADF-AB54-6D8649D1E7C7}.Debug|x64.Build.0 = Debug|Any CPU + {A99D3C27-65B7-4ADF-AB54-6D8649D1E7C7}.Debug|x86.ActiveCfg = Debug|Any CPU + {A99D3C27-65B7-4ADF-AB54-6D8649D1E7C7}.Debug|x86.Build.0 = Debug|Any CPU + {A99D3C27-65B7-4ADF-AB54-6D8649D1E7C7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A99D3C27-65B7-4ADF-AB54-6D8649D1E7C7}.Release|Any CPU.Build.0 = Release|Any CPU + {A99D3C27-65B7-4ADF-AB54-6D8649D1E7C7}.Release|x64.ActiveCfg = Release|Any CPU + {A99D3C27-65B7-4ADF-AB54-6D8649D1E7C7}.Release|x64.Build.0 = Release|Any CPU + {A99D3C27-65B7-4ADF-AB54-6D8649D1E7C7}.Release|x86.ActiveCfg = Release|Any CPU + {A99D3C27-65B7-4ADF-AB54-6D8649D1E7C7}.Release|x86.Build.0 = Release|Any CPU + {88780872-11A6-4014-B575-75C960EC0968}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {88780872-11A6-4014-B575-75C960EC0968}.Debug|Any CPU.Build.0 = Debug|Any CPU + {88780872-11A6-4014-B575-75C960EC0968}.Debug|x64.ActiveCfg = Debug|Any CPU + {88780872-11A6-4014-B575-75C960EC0968}.Debug|x64.Build.0 = Debug|Any CPU + {88780872-11A6-4014-B575-75C960EC0968}.Debug|x86.ActiveCfg = Debug|Any CPU + {88780872-11A6-4014-B575-75C960EC0968}.Debug|x86.Build.0 = Debug|Any CPU + {88780872-11A6-4014-B575-75C960EC0968}.Release|Any CPU.ActiveCfg = Release|Any CPU + {88780872-11A6-4014-B575-75C960EC0968}.Release|Any CPU.Build.0 = Release|Any CPU + {88780872-11A6-4014-B575-75C960EC0968}.Release|x64.ActiveCfg = Release|Any CPU + {88780872-11A6-4014-B575-75C960EC0968}.Release|x64.Build.0 = Release|Any CPU + {88780872-11A6-4014-B575-75C960EC0968}.Release|x86.ActiveCfg = Release|Any CPU + {88780872-11A6-4014-B575-75C960EC0968}.Release|x86.Build.0 = Release|Any CPU + {2135A527-3910-44B5-A778-C5467D0A6148}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2135A527-3910-44B5-A778-C5467D0A6148}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2135A527-3910-44B5-A778-C5467D0A6148}.Debug|x64.ActiveCfg = Debug|Any CPU + {2135A527-3910-44B5-A778-C5467D0A6148}.Debug|x64.Build.0 = Debug|Any CPU + {2135A527-3910-44B5-A778-C5467D0A6148}.Debug|x86.ActiveCfg = Debug|Any CPU + {2135A527-3910-44B5-A778-C5467D0A6148}.Debug|x86.Build.0 = Debug|Any CPU + {2135A527-3910-44B5-A778-C5467D0A6148}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2135A527-3910-44B5-A778-C5467D0A6148}.Release|Any CPU.Build.0 = Release|Any CPU + {2135A527-3910-44B5-A778-C5467D0A6148}.Release|x64.ActiveCfg = Release|Any CPU + {2135A527-3910-44B5-A778-C5467D0A6148}.Release|x64.Build.0 = Release|Any CPU + {2135A527-3910-44B5-A778-C5467D0A6148}.Release|x86.ActiveCfg = Release|Any CPU + {2135A527-3910-44B5-A778-C5467D0A6148}.Release|x86.Build.0 = Release|Any CPU + {02276871-6582-4A21-B629-83527FD90559}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {02276871-6582-4A21-B629-83527FD90559}.Debug|Any CPU.Build.0 = Debug|Any CPU + {02276871-6582-4A21-B629-83527FD90559}.Debug|x64.ActiveCfg = Debug|Any CPU + {02276871-6582-4A21-B629-83527FD90559}.Debug|x64.Build.0 = Debug|Any CPU + {02276871-6582-4A21-B629-83527FD90559}.Debug|x86.ActiveCfg = Debug|Any CPU + {02276871-6582-4A21-B629-83527FD90559}.Debug|x86.Build.0 = Debug|Any CPU + {02276871-6582-4A21-B629-83527FD90559}.Release|Any CPU.ActiveCfg = Release|Any CPU + {02276871-6582-4A21-B629-83527FD90559}.Release|Any CPU.Build.0 = Release|Any CPU + {02276871-6582-4A21-B629-83527FD90559}.Release|x64.ActiveCfg = Release|Any CPU + {02276871-6582-4A21-B629-83527FD90559}.Release|x64.Build.0 = Release|Any CPU + {02276871-6582-4A21-B629-83527FD90559}.Release|x86.ActiveCfg = Release|Any CPU + {02276871-6582-4A21-B629-83527FD90559}.Release|x86.Build.0 = Release|Any CPU + {DDF0DC50-766B-4E49-AA46-8D7F2370465A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DDF0DC50-766B-4E49-AA46-8D7F2370465A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DDF0DC50-766B-4E49-AA46-8D7F2370465A}.Debug|x64.ActiveCfg = Debug|Any CPU + {DDF0DC50-766B-4E49-AA46-8D7F2370465A}.Debug|x64.Build.0 = Debug|Any CPU + {DDF0DC50-766B-4E49-AA46-8D7F2370465A}.Debug|x86.ActiveCfg = Debug|Any CPU + {DDF0DC50-766B-4E49-AA46-8D7F2370465A}.Debug|x86.Build.0 = Debug|Any CPU + {DDF0DC50-766B-4E49-AA46-8D7F2370465A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DDF0DC50-766B-4E49-AA46-8D7F2370465A}.Release|Any CPU.Build.0 = Release|Any CPU + {DDF0DC50-766B-4E49-AA46-8D7F2370465A}.Release|x64.ActiveCfg = Release|Any CPU + {DDF0DC50-766B-4E49-AA46-8D7F2370465A}.Release|x64.Build.0 = Release|Any CPU + {DDF0DC50-766B-4E49-AA46-8D7F2370465A}.Release|x86.ActiveCfg = Release|Any CPU + {DDF0DC50-766B-4E49-AA46-8D7F2370465A}.Release|x86.Build.0 = Release|Any CPU + {8F8153F8-6BED-4026-89A5-FEE2FEF7D379}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8F8153F8-6BED-4026-89A5-FEE2FEF7D379}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8F8153F8-6BED-4026-89A5-FEE2FEF7D379}.Debug|x64.ActiveCfg = Debug|Any CPU + {8F8153F8-6BED-4026-89A5-FEE2FEF7D379}.Debug|x64.Build.0 = Debug|Any CPU + {8F8153F8-6BED-4026-89A5-FEE2FEF7D379}.Debug|x86.ActiveCfg = Debug|Any CPU + {8F8153F8-6BED-4026-89A5-FEE2FEF7D379}.Debug|x86.Build.0 = Debug|Any CPU + {8F8153F8-6BED-4026-89A5-FEE2FEF7D379}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8F8153F8-6BED-4026-89A5-FEE2FEF7D379}.Release|Any CPU.Build.0 = Release|Any CPU + {8F8153F8-6BED-4026-89A5-FEE2FEF7D379}.Release|x64.ActiveCfg = Release|Any CPU + {8F8153F8-6BED-4026-89A5-FEE2FEF7D379}.Release|x64.Build.0 = Release|Any CPU + {8F8153F8-6BED-4026-89A5-FEE2FEF7D379}.Release|x86.ActiveCfg = Release|Any CPU + {8F8153F8-6BED-4026-89A5-FEE2FEF7D379}.Release|x86.Build.0 = Release|Any CPU + {FD1A0CD2-19BF-443E-9687-83E5B9E438EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FD1A0CD2-19BF-443E-9687-83E5B9E438EE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FD1A0CD2-19BF-443E-9687-83E5B9E438EE}.Debug|x64.ActiveCfg = Debug|Any CPU + {FD1A0CD2-19BF-443E-9687-83E5B9E438EE}.Debug|x64.Build.0 = Debug|Any CPU + {FD1A0CD2-19BF-443E-9687-83E5B9E438EE}.Debug|x86.ActiveCfg = Debug|Any CPU + {FD1A0CD2-19BF-443E-9687-83E5B9E438EE}.Debug|x86.Build.0 = Debug|Any CPU + {FD1A0CD2-19BF-443E-9687-83E5B9E438EE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FD1A0CD2-19BF-443E-9687-83E5B9E438EE}.Release|Any CPU.Build.0 = Release|Any CPU + {FD1A0CD2-19BF-443E-9687-83E5B9E438EE}.Release|x64.ActiveCfg = Release|Any CPU + {FD1A0CD2-19BF-443E-9687-83E5B9E438EE}.Release|x64.Build.0 = Release|Any CPU + {FD1A0CD2-19BF-443E-9687-83E5B9E438EE}.Release|x86.ActiveCfg = Release|Any CPU + {FD1A0CD2-19BF-443E-9687-83E5B9E438EE}.Release|x86.Build.0 = Release|Any CPU + {F3AD707A-5E2D-4F58-BA21-691B4C7D1BA5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F3AD707A-5E2D-4F58-BA21-691B4C7D1BA5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F3AD707A-5E2D-4F58-BA21-691B4C7D1BA5}.Debug|x64.ActiveCfg = Debug|Any CPU + {F3AD707A-5E2D-4F58-BA21-691B4C7D1BA5}.Debug|x64.Build.0 = Debug|Any CPU + {F3AD707A-5E2D-4F58-BA21-691B4C7D1BA5}.Debug|x86.ActiveCfg = Debug|Any CPU + {F3AD707A-5E2D-4F58-BA21-691B4C7D1BA5}.Debug|x86.Build.0 = Debug|Any CPU + {F3AD707A-5E2D-4F58-BA21-691B4C7D1BA5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F3AD707A-5E2D-4F58-BA21-691B4C7D1BA5}.Release|Any CPU.Build.0 = Release|Any CPU + {F3AD707A-5E2D-4F58-BA21-691B4C7D1BA5}.Release|x64.ActiveCfg = Release|Any CPU + {F3AD707A-5E2D-4F58-BA21-691B4C7D1BA5}.Release|x64.Build.0 = Release|Any CPU + {F3AD707A-5E2D-4F58-BA21-691B4C7D1BA5}.Release|x86.ActiveCfg = Release|Any CPU + {F3AD707A-5E2D-4F58-BA21-691B4C7D1BA5}.Release|x86.Build.0 = Release|Any CPU + {B73E94EA-256E-4C1C-956B-0D4E67B5C82F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B73E94EA-256E-4C1C-956B-0D4E67B5C82F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B73E94EA-256E-4C1C-956B-0D4E67B5C82F}.Debug|x64.ActiveCfg = Debug|Any CPU + {B73E94EA-256E-4C1C-956B-0D4E67B5C82F}.Debug|x64.Build.0 = Debug|Any CPU + {B73E94EA-256E-4C1C-956B-0D4E67B5C82F}.Debug|x86.ActiveCfg = Debug|Any CPU + {B73E94EA-256E-4C1C-956B-0D4E67B5C82F}.Debug|x86.Build.0 = Debug|Any CPU + {B73E94EA-256E-4C1C-956B-0D4E67B5C82F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B73E94EA-256E-4C1C-956B-0D4E67B5C82F}.Release|Any CPU.Build.0 = Release|Any CPU + {B73E94EA-256E-4C1C-956B-0D4E67B5C82F}.Release|x64.ActiveCfg = Release|Any CPU + {B73E94EA-256E-4C1C-956B-0D4E67B5C82F}.Release|x64.Build.0 = Release|Any CPU + {B73E94EA-256E-4C1C-956B-0D4E67B5C82F}.Release|x86.ActiveCfg = Release|Any CPU + {B73E94EA-256E-4C1C-956B-0D4E67B5C82F}.Release|x86.Build.0 = Release|Any CPU + {BBE0307D-17C0-4A0A-9D7A-D8E9328A3CF7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BBE0307D-17C0-4A0A-9D7A-D8E9328A3CF7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BBE0307D-17C0-4A0A-9D7A-D8E9328A3CF7}.Debug|x64.ActiveCfg = Debug|Any CPU + {BBE0307D-17C0-4A0A-9D7A-D8E9328A3CF7}.Debug|x64.Build.0 = Debug|Any CPU + {BBE0307D-17C0-4A0A-9D7A-D8E9328A3CF7}.Debug|x86.ActiveCfg = Debug|Any CPU + {BBE0307D-17C0-4A0A-9D7A-D8E9328A3CF7}.Debug|x86.Build.0 = Debug|Any CPU + {BBE0307D-17C0-4A0A-9D7A-D8E9328A3CF7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BBE0307D-17C0-4A0A-9D7A-D8E9328A3CF7}.Release|Any CPU.Build.0 = Release|Any CPU + {BBE0307D-17C0-4A0A-9D7A-D8E9328A3CF7}.Release|x64.ActiveCfg = Release|Any CPU + {BBE0307D-17C0-4A0A-9D7A-D8E9328A3CF7}.Release|x64.Build.0 = Release|Any CPU + {BBE0307D-17C0-4A0A-9D7A-D8E9328A3CF7}.Release|x86.ActiveCfg = Release|Any CPU + {BBE0307D-17C0-4A0A-9D7A-D8E9328A3CF7}.Release|x86.Build.0 = Release|Any CPU + {56B04873-1F4B-402E-88C0-528F006E3914}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {56B04873-1F4B-402E-88C0-528F006E3914}.Debug|Any CPU.Build.0 = Debug|Any CPU + {56B04873-1F4B-402E-88C0-528F006E3914}.Debug|x64.ActiveCfg = Debug|Any CPU + {56B04873-1F4B-402E-88C0-528F006E3914}.Debug|x64.Build.0 = Debug|Any CPU + {56B04873-1F4B-402E-88C0-528F006E3914}.Debug|x86.ActiveCfg = Debug|Any CPU + {56B04873-1F4B-402E-88C0-528F006E3914}.Debug|x86.Build.0 = Debug|Any CPU + {56B04873-1F4B-402E-88C0-528F006E3914}.Release|Any CPU.ActiveCfg = Release|Any CPU + {56B04873-1F4B-402E-88C0-528F006E3914}.Release|Any CPU.Build.0 = Release|Any CPU + {56B04873-1F4B-402E-88C0-528F006E3914}.Release|x64.ActiveCfg = Release|Any CPU + {56B04873-1F4B-402E-88C0-528F006E3914}.Release|x64.Build.0 = Release|Any CPU + {56B04873-1F4B-402E-88C0-528F006E3914}.Release|x86.ActiveCfg = Release|Any CPU + {56B04873-1F4B-402E-88C0-528F006E3914}.Release|x86.Build.0 = Release|Any CPU + {D4ADBF73-AE37-4614-9C07-8C71DC85F8EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D4ADBF73-AE37-4614-9C07-8C71DC85F8EA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D4ADBF73-AE37-4614-9C07-8C71DC85F8EA}.Debug|x64.ActiveCfg = Debug|Any CPU + {D4ADBF73-AE37-4614-9C07-8C71DC85F8EA}.Debug|x64.Build.0 = Debug|Any CPU + {D4ADBF73-AE37-4614-9C07-8C71DC85F8EA}.Debug|x86.ActiveCfg = Debug|Any CPU + {D4ADBF73-AE37-4614-9C07-8C71DC85F8EA}.Debug|x86.Build.0 = Debug|Any CPU + {D4ADBF73-AE37-4614-9C07-8C71DC85F8EA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D4ADBF73-AE37-4614-9C07-8C71DC85F8EA}.Release|Any CPU.Build.0 = Release|Any CPU + {D4ADBF73-AE37-4614-9C07-8C71DC85F8EA}.Release|x64.ActiveCfg = Release|Any CPU + {D4ADBF73-AE37-4614-9C07-8C71DC85F8EA}.Release|x64.Build.0 = Release|Any CPU + {D4ADBF73-AE37-4614-9C07-8C71DC85F8EA}.Release|x86.ActiveCfg = Release|Any CPU + {D4ADBF73-AE37-4614-9C07-8C71DC85F8EA}.Release|x86.Build.0 = Release|Any CPU + {E1234569-1234-1234-1234-1234567890AE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E1234569-1234-1234-1234-1234567890AE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E1234569-1234-1234-1234-1234567890AE}.Debug|x64.ActiveCfg = Debug|Any CPU + {E1234569-1234-1234-1234-1234567890AE}.Debug|x64.Build.0 = Debug|Any CPU + {E1234569-1234-1234-1234-1234567890AE}.Debug|x86.ActiveCfg = Debug|Any CPU + {E1234569-1234-1234-1234-1234567890AE}.Debug|x86.Build.0 = Debug|Any CPU + {E1234569-1234-1234-1234-1234567890AE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E1234569-1234-1234-1234-1234567890AE}.Release|Any CPU.Build.0 = Release|Any CPU + {E1234569-1234-1234-1234-1234567890AE}.Release|x64.ActiveCfg = Release|Any CPU + {E1234569-1234-1234-1234-1234567890AE}.Release|x64.Build.0 = Release|Any CPU + {E1234569-1234-1234-1234-1234567890AE}.Release|x86.ActiveCfg = Release|Any CPU + {E1234569-1234-1234-1234-1234567890AE}.Release|x86.Build.0 = Release|Any CPU + {760CAD28-4792-44B8-77D1-0F42F47BD303}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {760CAD28-4792-44B8-77D1-0F42F47BD303}.Debug|Any CPU.Build.0 = Debug|Any CPU + {760CAD28-4792-44B8-77D1-0F42F47BD303}.Debug|x64.ActiveCfg = Debug|Any CPU + {760CAD28-4792-44B8-77D1-0F42F47BD303}.Debug|x64.Build.0 = Debug|Any CPU + {760CAD28-4792-44B8-77D1-0F42F47BD303}.Debug|x86.ActiveCfg = Debug|Any CPU + {760CAD28-4792-44B8-77D1-0F42F47BD303}.Debug|x86.Build.0 = Debug|Any CPU + {760CAD28-4792-44B8-77D1-0F42F47BD303}.Release|Any CPU.ActiveCfg = Release|Any CPU + {760CAD28-4792-44B8-77D1-0F42F47BD303}.Release|Any CPU.Build.0 = Release|Any CPU + {760CAD28-4792-44B8-77D1-0F42F47BD303}.Release|x64.ActiveCfg = Release|Any CPU + {760CAD28-4792-44B8-77D1-0F42F47BD303}.Release|x64.Build.0 = Release|Any CPU + {760CAD28-4792-44B8-77D1-0F42F47BD303}.Release|x86.ActiveCfg = Release|Any CPU + {760CAD28-4792-44B8-77D1-0F42F47BD303}.Release|x86.Build.0 = Release|Any CPU + {459CFD26-F5BC-B3C8-0632-DE7EA1504AD3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {459CFD26-F5BC-B3C8-0632-DE7EA1504AD3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {459CFD26-F5BC-B3C8-0632-DE7EA1504AD3}.Debug|x64.ActiveCfg = Debug|Any CPU + {459CFD26-F5BC-B3C8-0632-DE7EA1504AD3}.Debug|x64.Build.0 = Debug|Any CPU + {459CFD26-F5BC-B3C8-0632-DE7EA1504AD3}.Debug|x86.ActiveCfg = Debug|Any CPU + {459CFD26-F5BC-B3C8-0632-DE7EA1504AD3}.Debug|x86.Build.0 = Debug|Any CPU + {459CFD26-F5BC-B3C8-0632-DE7EA1504AD3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {459CFD26-F5BC-B3C8-0632-DE7EA1504AD3}.Release|Any CPU.Build.0 = Release|Any CPU + {459CFD26-F5BC-B3C8-0632-DE7EA1504AD3}.Release|x64.ActiveCfg = Release|Any CPU + {459CFD26-F5BC-B3C8-0632-DE7EA1504AD3}.Release|x64.Build.0 = Release|Any CPU + {459CFD26-F5BC-B3C8-0632-DE7EA1504AD3}.Release|x86.ActiveCfg = Release|Any CPU + {459CFD26-F5BC-B3C8-0632-DE7EA1504AD3}.Release|x86.Build.0 = Release|Any CPU + {CE923FCF-F208-4BC5-8C9B-AA54E2930993}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CE923FCF-F208-4BC5-8C9B-AA54E2930993}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CE923FCF-F208-4BC5-8C9B-AA54E2930993}.Debug|x64.ActiveCfg = Debug|Any CPU + {CE923FCF-F208-4BC5-8C9B-AA54E2930993}.Debug|x64.Build.0 = Debug|Any CPU + {CE923FCF-F208-4BC5-8C9B-AA54E2930993}.Debug|x86.ActiveCfg = Debug|Any CPU + {CE923FCF-F208-4BC5-8C9B-AA54E2930993}.Debug|x86.Build.0 = Debug|Any CPU + {CE923FCF-F208-4BC5-8C9B-AA54E2930993}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CE923FCF-F208-4BC5-8C9B-AA54E2930993}.Release|Any CPU.Build.0 = Release|Any CPU + {CE923FCF-F208-4BC5-8C9B-AA54E2930993}.Release|x64.ActiveCfg = Release|Any CPU + {CE923FCF-F208-4BC5-8C9B-AA54E2930993}.Release|x64.Build.0 = Release|Any CPU + {CE923FCF-F208-4BC5-8C9B-AA54E2930993}.Release|x86.ActiveCfg = Release|Any CPU + {CE923FCF-F208-4BC5-8C9B-AA54E2930993}.Release|x86.Build.0 = Release|Any CPU + {EB564D80-A767-4431-9918-16BE87407068}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EB564D80-A767-4431-9918-16BE87407068}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EB564D80-A767-4431-9918-16BE87407068}.Debug|x64.ActiveCfg = Debug|Any CPU + {EB564D80-A767-4431-9918-16BE87407068}.Debug|x64.Build.0 = Debug|Any CPU + {EB564D80-A767-4431-9918-16BE87407068}.Debug|x86.ActiveCfg = Debug|Any CPU + {EB564D80-A767-4431-9918-16BE87407068}.Debug|x86.Build.0 = Debug|Any CPU + {EB564D80-A767-4431-9918-16BE87407068}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EB564D80-A767-4431-9918-16BE87407068}.Release|Any CPU.Build.0 = Release|Any CPU + {EB564D80-A767-4431-9918-16BE87407068}.Release|x64.ActiveCfg = Release|Any CPU + {EB564D80-A767-4431-9918-16BE87407068}.Release|x64.Build.0 = Release|Any CPU + {EB564D80-A767-4431-9918-16BE87407068}.Release|x86.ActiveCfg = Release|Any CPU + {EB564D80-A767-4431-9918-16BE87407068}.Release|x86.Build.0 = Release|Any CPU + {DCC2034C-2F4A-4C72-A39C-58E108055E70}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DCC2034C-2F4A-4C72-A39C-58E108055E70}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DCC2034C-2F4A-4C72-A39C-58E108055E70}.Debug|x64.ActiveCfg = Debug|Any CPU + {DCC2034C-2F4A-4C72-A39C-58E108055E70}.Debug|x64.Build.0 = Debug|Any CPU + {DCC2034C-2F4A-4C72-A39C-58E108055E70}.Debug|x86.ActiveCfg = Debug|Any CPU + {DCC2034C-2F4A-4C72-A39C-58E108055E70}.Debug|x86.Build.0 = Debug|Any CPU + {DCC2034C-2F4A-4C72-A39C-58E108055E70}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DCC2034C-2F4A-4C72-A39C-58E108055E70}.Release|Any CPU.Build.0 = Release|Any CPU + {DCC2034C-2F4A-4C72-A39C-58E108055E70}.Release|x64.ActiveCfg = Release|Any CPU + {DCC2034C-2F4A-4C72-A39C-58E108055E70}.Release|x64.Build.0 = Release|Any CPU + {DCC2034C-2F4A-4C72-A39C-58E108055E70}.Release|x86.ActiveCfg = Release|Any CPU + {DCC2034C-2F4A-4C72-A39C-58E108055E70}.Release|x86.Build.0 = Release|Any CPU + {E6AD3B7D-5ED5-43E6-A139-607A3F03FF00}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E6AD3B7D-5ED5-43E6-A139-607A3F03FF00}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E6AD3B7D-5ED5-43E6-A139-607A3F03FF00}.Debug|x64.ActiveCfg = Debug|Any CPU + {E6AD3B7D-5ED5-43E6-A139-607A3F03FF00}.Debug|x64.Build.0 = Debug|Any CPU + {E6AD3B7D-5ED5-43E6-A139-607A3F03FF00}.Debug|x86.ActiveCfg = Debug|Any CPU + {E6AD3B7D-5ED5-43E6-A139-607A3F03FF00}.Debug|x86.Build.0 = Debug|Any CPU + {E6AD3B7D-5ED5-43E6-A139-607A3F03FF00}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E6AD3B7D-5ED5-43E6-A139-607A3F03FF00}.Release|Any CPU.Build.0 = Release|Any CPU + {E6AD3B7D-5ED5-43E6-A139-607A3F03FF00}.Release|x64.ActiveCfg = Release|Any CPU + {E6AD3B7D-5ED5-43E6-A139-607A3F03FF00}.Release|x64.Build.0 = Release|Any CPU + {E6AD3B7D-5ED5-43E6-A139-607A3F03FF00}.Release|x86.ActiveCfg = Release|Any CPU + {E6AD3B7D-5ED5-43E6-A139-607A3F03FF00}.Release|x86.Build.0 = Release|Any CPU + {C3327B63-4141-4D49-AE04-FA6A36FBDC9F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C3327B63-4141-4D49-AE04-FA6A36FBDC9F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C3327B63-4141-4D49-AE04-FA6A36FBDC9F}.Debug|x64.ActiveCfg = Debug|Any CPU + {C3327B63-4141-4D49-AE04-FA6A36FBDC9F}.Debug|x64.Build.0 = Debug|Any CPU + {C3327B63-4141-4D49-AE04-FA6A36FBDC9F}.Debug|x86.ActiveCfg = Debug|Any CPU + {C3327B63-4141-4D49-AE04-FA6A36FBDC9F}.Debug|x86.Build.0 = Debug|Any CPU + {C3327B63-4141-4D49-AE04-FA6A36FBDC9F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C3327B63-4141-4D49-AE04-FA6A36FBDC9F}.Release|Any CPU.Build.0 = Release|Any CPU + {C3327B63-4141-4D49-AE04-FA6A36FBDC9F}.Release|x64.ActiveCfg = Release|Any CPU + {C3327B63-4141-4D49-AE04-FA6A36FBDC9F}.Release|x64.Build.0 = Release|Any CPU + {C3327B63-4141-4D49-AE04-FA6A36FBDC9F}.Release|x86.ActiveCfg = Release|Any CPU + {C3327B63-4141-4D49-AE04-FA6A36FBDC9F}.Release|x86.Build.0 = Release|Any CPU + {AE374EE8-1500-46BF-92C1-AA921B679E19}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AE374EE8-1500-46BF-92C1-AA921B679E19}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AE374EE8-1500-46BF-92C1-AA921B679E19}.Debug|x64.ActiveCfg = Debug|Any CPU + {AE374EE8-1500-46BF-92C1-AA921B679E19}.Debug|x64.Build.0 = Debug|Any CPU + {AE374EE8-1500-46BF-92C1-AA921B679E19}.Debug|x86.ActiveCfg = Debug|Any CPU + {AE374EE8-1500-46BF-92C1-AA921B679E19}.Debug|x86.Build.0 = Debug|Any CPU + {AE374EE8-1500-46BF-92C1-AA921B679E19}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AE374EE8-1500-46BF-92C1-AA921B679E19}.Release|Any CPU.Build.0 = Release|Any CPU + {AE374EE8-1500-46BF-92C1-AA921B679E19}.Release|x64.ActiveCfg = Release|Any CPU + {AE374EE8-1500-46BF-92C1-AA921B679E19}.Release|x64.Build.0 = Release|Any CPU + {AE374EE8-1500-46BF-92C1-AA921B679E19}.Release|x86.ActiveCfg = Release|Any CPU + {AE374EE8-1500-46BF-92C1-AA921B679E19}.Release|x86.Build.0 = Release|Any CPU + {05C411F3-C725-47EC-9441-650DA9DEB322}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {05C411F3-C725-47EC-9441-650DA9DEB322}.Debug|Any CPU.Build.0 = Debug|Any CPU + {05C411F3-C725-47EC-9441-650DA9DEB322}.Debug|x64.ActiveCfg = Debug|Any CPU + {05C411F3-C725-47EC-9441-650DA9DEB322}.Debug|x64.Build.0 = Debug|Any CPU + {05C411F3-C725-47EC-9441-650DA9DEB322}.Debug|x86.ActiveCfg = Debug|Any CPU + {05C411F3-C725-47EC-9441-650DA9DEB322}.Debug|x86.Build.0 = Debug|Any CPU + {05C411F3-C725-47EC-9441-650DA9DEB322}.Release|Any CPU.ActiveCfg = Release|Any CPU + {05C411F3-C725-47EC-9441-650DA9DEB322}.Release|Any CPU.Build.0 = Release|Any CPU + {05C411F3-C725-47EC-9441-650DA9DEB322}.Release|x64.ActiveCfg = Release|Any CPU + {05C411F3-C725-47EC-9441-650DA9DEB322}.Release|x64.Build.0 = Release|Any CPU + {05C411F3-C725-47EC-9441-650DA9DEB322}.Release|x86.ActiveCfg = Release|Any CPU + {05C411F3-C725-47EC-9441-650DA9DEB322}.Release|x86.Build.0 = Release|Any CPU + {666D3414-8801-4BB9-B49A-656D5D65ADC9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {666D3414-8801-4BB9-B49A-656D5D65ADC9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {666D3414-8801-4BB9-B49A-656D5D65ADC9}.Debug|x64.ActiveCfg = Debug|Any CPU + {666D3414-8801-4BB9-B49A-656D5D65ADC9}.Debug|x64.Build.0 = Debug|Any CPU + {666D3414-8801-4BB9-B49A-656D5D65ADC9}.Debug|x86.ActiveCfg = Debug|Any CPU + {666D3414-8801-4BB9-B49A-656D5D65ADC9}.Debug|x86.Build.0 = Debug|Any CPU + {666D3414-8801-4BB9-B49A-656D5D65ADC9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {666D3414-8801-4BB9-B49A-656D5D65ADC9}.Release|Any CPU.Build.0 = Release|Any CPU + {666D3414-8801-4BB9-B49A-656D5D65ADC9}.Release|x64.ActiveCfg = Release|Any CPU + {666D3414-8801-4BB9-B49A-656D5D65ADC9}.Release|x64.Build.0 = Release|Any CPU + {666D3414-8801-4BB9-B49A-656D5D65ADC9}.Release|x86.ActiveCfg = Release|Any CPU + {666D3414-8801-4BB9-B49A-656D5D65ADC9}.Release|x86.Build.0 = Release|Any CPU + {B82ECFF7-7F47-44A8-B947-1AC4E1AAB952}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B82ECFF7-7F47-44A8-B947-1AC4E1AAB952}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B82ECFF7-7F47-44A8-B947-1AC4E1AAB952}.Debug|x64.ActiveCfg = Debug|Any CPU + {B82ECFF7-7F47-44A8-B947-1AC4E1AAB952}.Debug|x64.Build.0 = Debug|Any CPU + {B82ECFF7-7F47-44A8-B947-1AC4E1AAB952}.Debug|x86.ActiveCfg = Debug|Any CPU + {B82ECFF7-7F47-44A8-B947-1AC4E1AAB952}.Debug|x86.Build.0 = Debug|Any CPU + {B82ECFF7-7F47-44A8-B947-1AC4E1AAB952}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B82ECFF7-7F47-44A8-B947-1AC4E1AAB952}.Release|Any CPU.Build.0 = Release|Any CPU + {B82ECFF7-7F47-44A8-B947-1AC4E1AAB952}.Release|x64.ActiveCfg = Release|Any CPU + {B82ECFF7-7F47-44A8-B947-1AC4E1AAB952}.Release|x64.Build.0 = Release|Any CPU + {B82ECFF7-7F47-44A8-B947-1AC4E1AAB952}.Release|x86.ActiveCfg = Release|Any CPU + {B82ECFF7-7F47-44A8-B947-1AC4E1AAB952}.Release|x86.Build.0 = Release|Any CPU + {223D1AA3-8756-4394-BDB8-0C20737C36F4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {223D1AA3-8756-4394-BDB8-0C20737C36F4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {223D1AA3-8756-4394-BDB8-0C20737C36F4}.Debug|x64.ActiveCfg = Debug|Any CPU + {223D1AA3-8756-4394-BDB8-0C20737C36F4}.Debug|x64.Build.0 = Debug|Any CPU + {223D1AA3-8756-4394-BDB8-0C20737C36F4}.Debug|x86.ActiveCfg = Debug|Any CPU + {223D1AA3-8756-4394-BDB8-0C20737C36F4}.Debug|x86.Build.0 = Debug|Any CPU + {223D1AA3-8756-4394-BDB8-0C20737C36F4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {223D1AA3-8756-4394-BDB8-0C20737C36F4}.Release|Any CPU.Build.0 = Release|Any CPU + {223D1AA3-8756-4394-BDB8-0C20737C36F4}.Release|x64.ActiveCfg = Release|Any CPU + {223D1AA3-8756-4394-BDB8-0C20737C36F4}.Release|x64.Build.0 = Release|Any CPU + {223D1AA3-8756-4394-BDB8-0C20737C36F4}.Release|x86.ActiveCfg = Release|Any CPU + {223D1AA3-8756-4394-BDB8-0C20737C36F4}.Release|x86.Build.0 = Release|Any CPU + {746C9DFE-3D0E-4D4D-9AE2-D85D7250075F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {746C9DFE-3D0E-4D4D-9AE2-D85D7250075F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {746C9DFE-3D0E-4D4D-9AE2-D85D7250075F}.Debug|x64.ActiveCfg = Debug|Any CPU + {746C9DFE-3D0E-4D4D-9AE2-D85D7250075F}.Debug|x64.Build.0 = Debug|Any CPU + {746C9DFE-3D0E-4D4D-9AE2-D85D7250075F}.Debug|x86.ActiveCfg = Debug|Any CPU + {746C9DFE-3D0E-4D4D-9AE2-D85D7250075F}.Debug|x86.Build.0 = Debug|Any CPU + {746C9DFE-3D0E-4D4D-9AE2-D85D7250075F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {746C9DFE-3D0E-4D4D-9AE2-D85D7250075F}.Release|Any CPU.Build.0 = Release|Any CPU + {746C9DFE-3D0E-4D4D-9AE2-D85D7250075F}.Release|x64.ActiveCfg = Release|Any CPU + {746C9DFE-3D0E-4D4D-9AE2-D85D7250075F}.Release|x64.Build.0 = Release|Any CPU + {746C9DFE-3D0E-4D4D-9AE2-D85D7250075F}.Release|x86.ActiveCfg = Release|Any CPU + {746C9DFE-3D0E-4D4D-9AE2-D85D7250075F}.Release|x86.Build.0 = Release|Any CPU + {6B594222-0B9E-4CDE-A49E-C3CCB65815FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6B594222-0B9E-4CDE-A49E-C3CCB65815FD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6B594222-0B9E-4CDE-A49E-C3CCB65815FD}.Debug|x64.ActiveCfg = Debug|Any CPU + {6B594222-0B9E-4CDE-A49E-C3CCB65815FD}.Debug|x64.Build.0 = Debug|Any CPU + {6B594222-0B9E-4CDE-A49E-C3CCB65815FD}.Debug|x86.ActiveCfg = Debug|Any CPU + {6B594222-0B9E-4CDE-A49E-C3CCB65815FD}.Debug|x86.Build.0 = Debug|Any CPU + {6B594222-0B9E-4CDE-A49E-C3CCB65815FD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6B594222-0B9E-4CDE-A49E-C3CCB65815FD}.Release|Any CPU.Build.0 = Release|Any CPU + {6B594222-0B9E-4CDE-A49E-C3CCB65815FD}.Release|x64.ActiveCfg = Release|Any CPU + {6B594222-0B9E-4CDE-A49E-C3CCB65815FD}.Release|x64.Build.0 = Release|Any CPU + {6B594222-0B9E-4CDE-A49E-C3CCB65815FD}.Release|x86.ActiveCfg = Release|Any CPU + {6B594222-0B9E-4CDE-A49E-C3CCB65815FD}.Release|x86.Build.0 = Release|Any CPU + {F009F428-7BBE-41FE-AD55-D19B4947E978}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F009F428-7BBE-41FE-AD55-D19B4947E978}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F009F428-7BBE-41FE-AD55-D19B4947E978}.Debug|x64.ActiveCfg = Debug|Any CPU + {F009F428-7BBE-41FE-AD55-D19B4947E978}.Debug|x64.Build.0 = Debug|Any CPU + {F009F428-7BBE-41FE-AD55-D19B4947E978}.Debug|x86.ActiveCfg = Debug|Any CPU + {F009F428-7BBE-41FE-AD55-D19B4947E978}.Debug|x86.Build.0 = Debug|Any CPU + {F009F428-7BBE-41FE-AD55-D19B4947E978}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F009F428-7BBE-41FE-AD55-D19B4947E978}.Release|Any CPU.Build.0 = Release|Any CPU + {F009F428-7BBE-41FE-AD55-D19B4947E978}.Release|x64.ActiveCfg = Release|Any CPU + {F009F428-7BBE-41FE-AD55-D19B4947E978}.Release|x64.Build.0 = Release|Any CPU + {F009F428-7BBE-41FE-AD55-D19B4947E978}.Release|x86.ActiveCfg = Release|Any CPU + {F009F428-7BBE-41FE-AD55-D19B4947E978}.Release|x86.Build.0 = Release|Any CPU + {751F96A2-DB60-4B40-A415-0924FEEFFD9C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {751F96A2-DB60-4B40-A415-0924FEEFFD9C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {751F96A2-DB60-4B40-A415-0924FEEFFD9C}.Debug|x64.ActiveCfg = Debug|Any CPU + {751F96A2-DB60-4B40-A415-0924FEEFFD9C}.Debug|x64.Build.0 = Debug|Any CPU + {751F96A2-DB60-4B40-A415-0924FEEFFD9C}.Debug|x86.ActiveCfg = Debug|Any CPU + {751F96A2-DB60-4B40-A415-0924FEEFFD9C}.Debug|x86.Build.0 = Debug|Any CPU + {751F96A2-DB60-4B40-A415-0924FEEFFD9C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {751F96A2-DB60-4B40-A415-0924FEEFFD9C}.Release|Any CPU.Build.0 = Release|Any CPU + {751F96A2-DB60-4B40-A415-0924FEEFFD9C}.Release|x64.ActiveCfg = Release|Any CPU + {751F96A2-DB60-4B40-A415-0924FEEFFD9C}.Release|x64.Build.0 = Release|Any CPU + {751F96A2-DB60-4B40-A415-0924FEEFFD9C}.Release|x86.ActiveCfg = Release|Any CPU + {751F96A2-DB60-4B40-A415-0924FEEFFD9C}.Release|x86.Build.0 = Release|Any CPU + {4D7B1DE3-D04E-48A2-A904-A3288F0A519C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4D7B1DE3-D04E-48A2-A904-A3288F0A519C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4D7B1DE3-D04E-48A2-A904-A3288F0A519C}.Debug|x64.ActiveCfg = Debug|Any CPU + {4D7B1DE3-D04E-48A2-A904-A3288F0A519C}.Debug|x64.Build.0 = Debug|Any CPU + {4D7B1DE3-D04E-48A2-A904-A3288F0A519C}.Debug|x86.ActiveCfg = Debug|Any CPU + {4D7B1DE3-D04E-48A2-A904-A3288F0A519C}.Debug|x86.Build.0 = Debug|Any CPU + {4D7B1DE3-D04E-48A2-A904-A3288F0A519C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4D7B1DE3-D04E-48A2-A904-A3288F0A519C}.Release|Any CPU.Build.0 = Release|Any CPU + {4D7B1DE3-D04E-48A2-A904-A3288F0A519C}.Release|x64.ActiveCfg = Release|Any CPU + {4D7B1DE3-D04E-48A2-A904-A3288F0A519C}.Release|x64.Build.0 = Release|Any CPU + {4D7B1DE3-D04E-48A2-A904-A3288F0A519C}.Release|x86.ActiveCfg = Release|Any CPU + {4D7B1DE3-D04E-48A2-A904-A3288F0A519C}.Release|x86.Build.0 = Release|Any CPU + {57832DF2-FD7F-4E26-AD7C-5D6608582978}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {57832DF2-FD7F-4E26-AD7C-5D6608582978}.Debug|Any CPU.Build.0 = Debug|Any CPU + {57832DF2-FD7F-4E26-AD7C-5D6608582978}.Debug|x64.ActiveCfg = Debug|Any CPU + {57832DF2-FD7F-4E26-AD7C-5D6608582978}.Debug|x64.Build.0 = Debug|Any CPU + {57832DF2-FD7F-4E26-AD7C-5D6608582978}.Debug|x86.ActiveCfg = Debug|Any CPU + {57832DF2-FD7F-4E26-AD7C-5D6608582978}.Debug|x86.Build.0 = Debug|Any CPU + {57832DF2-FD7F-4E26-AD7C-5D6608582978}.Release|Any CPU.ActiveCfg = Release|Any CPU + {57832DF2-FD7F-4E26-AD7C-5D6608582978}.Release|Any CPU.Build.0 = Release|Any CPU + {57832DF2-FD7F-4E26-AD7C-5D6608582978}.Release|x64.ActiveCfg = Release|Any CPU + {57832DF2-FD7F-4E26-AD7C-5D6608582978}.Release|x64.Build.0 = Release|Any CPU + {57832DF2-FD7F-4E26-AD7C-5D6608582978}.Release|x86.ActiveCfg = Release|Any CPU + {57832DF2-FD7F-4E26-AD7C-5D6608582978}.Release|x86.Build.0 = Release|Any CPU + {A3143C31-7C1C-4D7C-8819-3901238942C4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A3143C31-7C1C-4D7C-8819-3901238942C4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A3143C31-7C1C-4D7C-8819-3901238942C4}.Debug|x64.ActiveCfg = Debug|Any CPU + {A3143C31-7C1C-4D7C-8819-3901238942C4}.Debug|x64.Build.0 = Debug|Any CPU + {A3143C31-7C1C-4D7C-8819-3901238942C4}.Debug|x86.ActiveCfg = Debug|Any CPU + {A3143C31-7C1C-4D7C-8819-3901238942C4}.Debug|x86.Build.0 = Debug|Any CPU + {A3143C31-7C1C-4D7C-8819-3901238942C4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A3143C31-7C1C-4D7C-8819-3901238942C4}.Release|Any CPU.Build.0 = Release|Any CPU + {A3143C31-7C1C-4D7C-8819-3901238942C4}.Release|x64.ActiveCfg = Release|Any CPU + {A3143C31-7C1C-4D7C-8819-3901238942C4}.Release|x64.Build.0 = Release|Any CPU + {A3143C31-7C1C-4D7C-8819-3901238942C4}.Release|x86.ActiveCfg = Release|Any CPU + {A3143C31-7C1C-4D7C-8819-3901238942C4}.Release|x86.Build.0 = Release|Any CPU + {7C1FC1A3-5E52-45A8-B136-0934ADD5580C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7C1FC1A3-5E52-45A8-B136-0934ADD5580C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7C1FC1A3-5E52-45A8-B136-0934ADD5580C}.Debug|x64.ActiveCfg = Debug|Any CPU + {7C1FC1A3-5E52-45A8-B136-0934ADD5580C}.Debug|x64.Build.0 = Debug|Any CPU + {7C1FC1A3-5E52-45A8-B136-0934ADD5580C}.Debug|x86.ActiveCfg = Debug|Any CPU + {7C1FC1A3-5E52-45A8-B136-0934ADD5580C}.Debug|x86.Build.0 = Debug|Any CPU + {7C1FC1A3-5E52-45A8-B136-0934ADD5580C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7C1FC1A3-5E52-45A8-B136-0934ADD5580C}.Release|Any CPU.Build.0 = Release|Any CPU + {7C1FC1A3-5E52-45A8-B136-0934ADD5580C}.Release|x64.ActiveCfg = Release|Any CPU + {7C1FC1A3-5E52-45A8-B136-0934ADD5580C}.Release|x64.Build.0 = Release|Any CPU + {7C1FC1A3-5E52-45A8-B136-0934ADD5580C}.Release|x86.ActiveCfg = Release|Any CPU + {7C1FC1A3-5E52-45A8-B136-0934ADD5580C}.Release|x86.Build.0 = Release|Any CPU + {6CFDFF50-A41A-4A5E-A66A-670DB707495F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6CFDFF50-A41A-4A5E-A66A-670DB707495F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6CFDFF50-A41A-4A5E-A66A-670DB707495F}.Debug|x64.ActiveCfg = Debug|Any CPU + {6CFDFF50-A41A-4A5E-A66A-670DB707495F}.Debug|x64.Build.0 = Debug|Any CPU + {6CFDFF50-A41A-4A5E-A66A-670DB707495F}.Debug|x86.ActiveCfg = Debug|Any CPU + {6CFDFF50-A41A-4A5E-A66A-670DB707495F}.Debug|x86.Build.0 = Debug|Any CPU + {6CFDFF50-A41A-4A5E-A66A-670DB707495F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6CFDFF50-A41A-4A5E-A66A-670DB707495F}.Release|Any CPU.Build.0 = Release|Any CPU + {6CFDFF50-A41A-4A5E-A66A-670DB707495F}.Release|x64.ActiveCfg = Release|Any CPU + {6CFDFF50-A41A-4A5E-A66A-670DB707495F}.Release|x64.Build.0 = Release|Any CPU + {6CFDFF50-A41A-4A5E-A66A-670DB707495F}.Release|x86.ActiveCfg = Release|Any CPU + {6CFDFF50-A41A-4A5E-A66A-670DB707495F}.Release|x86.Build.0 = Release|Any CPU + {2C7B96D1-085F-4BCA-8D7D-3047765E3492}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2C7B96D1-085F-4BCA-8D7D-3047765E3492}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2C7B96D1-085F-4BCA-8D7D-3047765E3492}.Debug|x64.ActiveCfg = Debug|Any CPU + {2C7B96D1-085F-4BCA-8D7D-3047765E3492}.Debug|x64.Build.0 = Debug|Any CPU + {2C7B96D1-085F-4BCA-8D7D-3047765E3492}.Debug|x86.ActiveCfg = Debug|Any CPU + {2C7B96D1-085F-4BCA-8D7D-3047765E3492}.Debug|x86.Build.0 = Debug|Any CPU + {2C7B96D1-085F-4BCA-8D7D-3047765E3492}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2C7B96D1-085F-4BCA-8D7D-3047765E3492}.Release|Any CPU.Build.0 = Release|Any CPU + {2C7B96D1-085F-4BCA-8D7D-3047765E3492}.Release|x64.ActiveCfg = Release|Any CPU + {2C7B96D1-085F-4BCA-8D7D-3047765E3492}.Release|x64.Build.0 = Release|Any CPU + {2C7B96D1-085F-4BCA-8D7D-3047765E3492}.Release|x86.ActiveCfg = Release|Any CPU + {2C7B96D1-085F-4BCA-8D7D-3047765E3492}.Release|x86.Build.0 = Release|Any CPU + {B3167A7D-CF85-4A5F-B1CF-F14013782F1D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B3167A7D-CF85-4A5F-B1CF-F14013782F1D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B3167A7D-CF85-4A5F-B1CF-F14013782F1D}.Debug|x64.ActiveCfg = Debug|Any CPU + {B3167A7D-CF85-4A5F-B1CF-F14013782F1D}.Debug|x64.Build.0 = Debug|Any CPU + {B3167A7D-CF85-4A5F-B1CF-F14013782F1D}.Debug|x86.ActiveCfg = Debug|Any CPU + {B3167A7D-CF85-4A5F-B1CF-F14013782F1D}.Debug|x86.Build.0 = Debug|Any CPU + {B3167A7D-CF85-4A5F-B1CF-F14013782F1D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B3167A7D-CF85-4A5F-B1CF-F14013782F1D}.Release|Any CPU.Build.0 = Release|Any CPU + {B3167A7D-CF85-4A5F-B1CF-F14013782F1D}.Release|x64.ActiveCfg = Release|Any CPU + {B3167A7D-CF85-4A5F-B1CF-F14013782F1D}.Release|x64.Build.0 = Release|Any CPU + {B3167A7D-CF85-4A5F-B1CF-F14013782F1D}.Release|x86.ActiveCfg = Release|Any CPU + {B3167A7D-CF85-4A5F-B1CF-F14013782F1D}.Release|x86.Build.0 = Release|Any CPU + {73372025-CB29-4EF4-95A9-0CAF91D94439}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {73372025-CB29-4EF4-95A9-0CAF91D94439}.Debug|Any CPU.Build.0 = Debug|Any CPU + {73372025-CB29-4EF4-95A9-0CAF91D94439}.Debug|x64.ActiveCfg = Debug|Any CPU + {73372025-CB29-4EF4-95A9-0CAF91D94439}.Debug|x64.Build.0 = Debug|Any CPU + {73372025-CB29-4EF4-95A9-0CAF91D94439}.Debug|x86.ActiveCfg = Debug|Any CPU + {73372025-CB29-4EF4-95A9-0CAF91D94439}.Debug|x86.Build.0 = Debug|Any CPU + {73372025-CB29-4EF4-95A9-0CAF91D94439}.Release|Any CPU.ActiveCfg = Release|Any CPU + {73372025-CB29-4EF4-95A9-0CAF91D94439}.Release|Any CPU.Build.0 = Release|Any CPU + {73372025-CB29-4EF4-95A9-0CAF91D94439}.Release|x64.ActiveCfg = Release|Any CPU + {73372025-CB29-4EF4-95A9-0CAF91D94439}.Release|x64.Build.0 = Release|Any CPU + {73372025-CB29-4EF4-95A9-0CAF91D94439}.Release|x86.ActiveCfg = Release|Any CPU + {73372025-CB29-4EF4-95A9-0CAF91D94439}.Release|x86.Build.0 = Release|Any CPU + {35D2CE3D-B792-49E1-BB6D-532313196821}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {35D2CE3D-B792-49E1-BB6D-532313196821}.Debug|Any CPU.Build.0 = Debug|Any CPU + {35D2CE3D-B792-49E1-BB6D-532313196821}.Debug|x64.ActiveCfg = Debug|Any CPU + {35D2CE3D-B792-49E1-BB6D-532313196821}.Debug|x64.Build.0 = Debug|Any CPU + {35D2CE3D-B792-49E1-BB6D-532313196821}.Debug|x86.ActiveCfg = Debug|Any CPU + {35D2CE3D-B792-49E1-BB6D-532313196821}.Debug|x86.Build.0 = Debug|Any CPU + {35D2CE3D-B792-49E1-BB6D-532313196821}.Release|Any CPU.ActiveCfg = Release|Any CPU + {35D2CE3D-B792-49E1-BB6D-532313196821}.Release|Any CPU.Build.0 = Release|Any CPU + {35D2CE3D-B792-49E1-BB6D-532313196821}.Release|x64.ActiveCfg = Release|Any CPU + {35D2CE3D-B792-49E1-BB6D-532313196821}.Release|x64.Build.0 = Release|Any CPU + {35D2CE3D-B792-49E1-BB6D-532313196821}.Release|x86.ActiveCfg = Release|Any CPU + {35D2CE3D-B792-49E1-BB6D-532313196821}.Release|x86.Build.0 = Release|Any CPU + {A2F1FFAF-0BE1-4020-B09B-3DFB91B48816}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A2F1FFAF-0BE1-4020-B09B-3DFB91B48816}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A2F1FFAF-0BE1-4020-B09B-3DFB91B48816}.Debug|x64.ActiveCfg = Debug|Any CPU + {A2F1FFAF-0BE1-4020-B09B-3DFB91B48816}.Debug|x64.Build.0 = Debug|Any CPU + {A2F1FFAF-0BE1-4020-B09B-3DFB91B48816}.Debug|x86.ActiveCfg = Debug|Any CPU + {A2F1FFAF-0BE1-4020-B09B-3DFB91B48816}.Debug|x86.Build.0 = Debug|Any CPU + {A2F1FFAF-0BE1-4020-B09B-3DFB91B48816}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A2F1FFAF-0BE1-4020-B09B-3DFB91B48816}.Release|Any CPU.Build.0 = Release|Any CPU + {A2F1FFAF-0BE1-4020-B09B-3DFB91B48816}.Release|x64.ActiveCfg = Release|Any CPU + {A2F1FFAF-0BE1-4020-B09B-3DFB91B48816}.Release|x64.Build.0 = Release|Any CPU + {A2F1FFAF-0BE1-4020-B09B-3DFB91B48816}.Release|x86.ActiveCfg = Release|Any CPU + {A2F1FFAF-0BE1-4020-B09B-3DFB91B48816}.Release|x86.Build.0 = Release|Any CPU + {3D69D7BE-8C92-4690-B4B2-5EC6F439A2A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3D69D7BE-8C92-4690-B4B2-5EC6F439A2A2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3D69D7BE-8C92-4690-B4B2-5EC6F439A2A2}.Debug|x64.ActiveCfg = Debug|Any CPU + {3D69D7BE-8C92-4690-B4B2-5EC6F439A2A2}.Debug|x64.Build.0 = Debug|Any CPU + {3D69D7BE-8C92-4690-B4B2-5EC6F439A2A2}.Debug|x86.ActiveCfg = Debug|Any CPU + {3D69D7BE-8C92-4690-B4B2-5EC6F439A2A2}.Debug|x86.Build.0 = Debug|Any CPU + {3D69D7BE-8C92-4690-B4B2-5EC6F439A2A2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3D69D7BE-8C92-4690-B4B2-5EC6F439A2A2}.Release|Any CPU.Build.0 = Release|Any CPU + {3D69D7BE-8C92-4690-B4B2-5EC6F439A2A2}.Release|x64.ActiveCfg = Release|Any CPU + {3D69D7BE-8C92-4690-B4B2-5EC6F439A2A2}.Release|x64.Build.0 = Release|Any CPU + {3D69D7BE-8C92-4690-B4B2-5EC6F439A2A2}.Release|x86.ActiveCfg = Release|Any CPU + {3D69D7BE-8C92-4690-B4B2-5EC6F439A2A2}.Release|x86.Build.0 = Release|Any CPU + {6233A7A4-85F2-4458-A14A-BF35117347B0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6233A7A4-85F2-4458-A14A-BF35117347B0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6233A7A4-85F2-4458-A14A-BF35117347B0}.Debug|x64.ActiveCfg = Debug|Any CPU + {6233A7A4-85F2-4458-A14A-BF35117347B0}.Debug|x64.Build.0 = Debug|Any CPU + {6233A7A4-85F2-4458-A14A-BF35117347B0}.Debug|x86.ActiveCfg = Debug|Any CPU + {6233A7A4-85F2-4458-A14A-BF35117347B0}.Debug|x86.Build.0 = Debug|Any CPU + {6233A7A4-85F2-4458-A14A-BF35117347B0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6233A7A4-85F2-4458-A14A-BF35117347B0}.Release|Any CPU.Build.0 = Release|Any CPU + {6233A7A4-85F2-4458-A14A-BF35117347B0}.Release|x64.ActiveCfg = Release|Any CPU + {6233A7A4-85F2-4458-A14A-BF35117347B0}.Release|x64.Build.0 = Release|Any CPU + {6233A7A4-85F2-4458-A14A-BF35117347B0}.Release|x86.ActiveCfg = Release|Any CPU + {6233A7A4-85F2-4458-A14A-BF35117347B0}.Release|x86.Build.0 = Release|Any CPU + {9BE18521-31F9-45AD-A6EE-74695754EC0C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9BE18521-31F9-45AD-A6EE-74695754EC0C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9BE18521-31F9-45AD-A6EE-74695754EC0C}.Debug|x64.ActiveCfg = Debug|Any CPU + {9BE18521-31F9-45AD-A6EE-74695754EC0C}.Debug|x64.Build.0 = Debug|Any CPU + {9BE18521-31F9-45AD-A6EE-74695754EC0C}.Debug|x86.ActiveCfg = Debug|Any CPU + {9BE18521-31F9-45AD-A6EE-74695754EC0C}.Debug|x86.Build.0 = Debug|Any CPU + {9BE18521-31F9-45AD-A6EE-74695754EC0C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9BE18521-31F9-45AD-A6EE-74695754EC0C}.Release|Any CPU.Build.0 = Release|Any CPU + {9BE18521-31F9-45AD-A6EE-74695754EC0C}.Release|x64.ActiveCfg = Release|Any CPU + {9BE18521-31F9-45AD-A6EE-74695754EC0C}.Release|x64.Build.0 = Release|Any CPU + {9BE18521-31F9-45AD-A6EE-74695754EC0C}.Release|x86.ActiveCfg = Release|Any CPU + {9BE18521-31F9-45AD-A6EE-74695754EC0C}.Release|x86.Build.0 = Release|Any CPU + {F90633BA-133F-42E3-88D5-EE4DE0FB0586}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F90633BA-133F-42E3-88D5-EE4DE0FB0586}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F90633BA-133F-42E3-88D5-EE4DE0FB0586}.Debug|x64.ActiveCfg = Debug|Any CPU + {F90633BA-133F-42E3-88D5-EE4DE0FB0586}.Debug|x64.Build.0 = Debug|Any CPU + {F90633BA-133F-42E3-88D5-EE4DE0FB0586}.Debug|x86.ActiveCfg = Debug|Any CPU + {F90633BA-133F-42E3-88D5-EE4DE0FB0586}.Debug|x86.Build.0 = Debug|Any CPU + {F90633BA-133F-42E3-88D5-EE4DE0FB0586}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F90633BA-133F-42E3-88D5-EE4DE0FB0586}.Release|Any CPU.Build.0 = Release|Any CPU + {F90633BA-133F-42E3-88D5-EE4DE0FB0586}.Release|x64.ActiveCfg = Release|Any CPU + {F90633BA-133F-42E3-88D5-EE4DE0FB0586}.Release|x64.Build.0 = Release|Any CPU + {F90633BA-133F-42E3-88D5-EE4DE0FB0586}.Release|x86.ActiveCfg = Release|Any CPU + {F90633BA-133F-42E3-88D5-EE4DE0FB0586}.Release|x86.Build.0 = Release|Any CPU + {DE85A82A-CC7A-4743-B6FE-7259B152EF26}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DE85A82A-CC7A-4743-B6FE-7259B152EF26}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DE85A82A-CC7A-4743-B6FE-7259B152EF26}.Debug|x64.ActiveCfg = Debug|Any CPU + {DE85A82A-CC7A-4743-B6FE-7259B152EF26}.Debug|x64.Build.0 = Debug|Any CPU + {DE85A82A-CC7A-4743-B6FE-7259B152EF26}.Debug|x86.ActiveCfg = Debug|Any CPU + {DE85A82A-CC7A-4743-B6FE-7259B152EF26}.Debug|x86.Build.0 = Debug|Any CPU + {DE85A82A-CC7A-4743-B6FE-7259B152EF26}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DE85A82A-CC7A-4743-B6FE-7259B152EF26}.Release|Any CPU.Build.0 = Release|Any CPU + {DE85A82A-CC7A-4743-B6FE-7259B152EF26}.Release|x64.ActiveCfg = Release|Any CPU + {DE85A82A-CC7A-4743-B6FE-7259B152EF26}.Release|x64.Build.0 = Release|Any CPU + {DE85A82A-CC7A-4743-B6FE-7259B152EF26}.Release|x86.ActiveCfg = Release|Any CPU + {DE85A82A-CC7A-4743-B6FE-7259B152EF26}.Release|x86.Build.0 = Release|Any CPU + {8066FB34-4946-4A49-B3EC-E0E1D28760D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8066FB34-4946-4A49-B3EC-E0E1D28760D1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8066FB34-4946-4A49-B3EC-E0E1D28760D1}.Debug|x64.ActiveCfg = Debug|Any CPU + {8066FB34-4946-4A49-B3EC-E0E1D28760D1}.Debug|x64.Build.0 = Debug|Any CPU + {8066FB34-4946-4A49-B3EC-E0E1D28760D1}.Debug|x86.ActiveCfg = Debug|Any CPU + {8066FB34-4946-4A49-B3EC-E0E1D28760D1}.Debug|x86.Build.0 = Debug|Any CPU + {8066FB34-4946-4A49-B3EC-E0E1D28760D1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8066FB34-4946-4A49-B3EC-E0E1D28760D1}.Release|Any CPU.Build.0 = Release|Any CPU + {8066FB34-4946-4A49-B3EC-E0E1D28760D1}.Release|x64.ActiveCfg = Release|Any CPU + {8066FB34-4946-4A49-B3EC-E0E1D28760D1}.Release|x64.Build.0 = Release|Any CPU + {8066FB34-4946-4A49-B3EC-E0E1D28760D1}.Release|x86.ActiveCfg = Release|Any CPU + {8066FB34-4946-4A49-B3EC-E0E1D28760D1}.Release|x86.Build.0 = Release|Any CPU + {E5F6A7B8-90CD-EF12-3456-7890ABCDEF01}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E5F6A7B8-90CD-EF12-3456-7890ABCDEF01}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E5F6A7B8-90CD-EF12-3456-7890ABCDEF01}.Debug|x64.ActiveCfg = Debug|Any CPU + {E5F6A7B8-90CD-EF12-3456-7890ABCDEF01}.Debug|x64.Build.0 = Debug|Any CPU + {E5F6A7B8-90CD-EF12-3456-7890ABCDEF01}.Debug|x86.ActiveCfg = Debug|Any CPU + {E5F6A7B8-90CD-EF12-3456-7890ABCDEF01}.Debug|x86.Build.0 = Debug|Any CPU + {E5F6A7B8-90CD-EF12-3456-7890ABCDEF01}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E5F6A7B8-90CD-EF12-3456-7890ABCDEF01}.Release|Any CPU.Build.0 = Release|Any CPU + {E5F6A7B8-90CD-EF12-3456-7890ABCDEF01}.Release|x64.ActiveCfg = Release|Any CPU + {E5F6A7B8-90CD-EF12-3456-7890ABCDEF01}.Release|x64.Build.0 = Release|Any CPU + {E5F6A7B8-90CD-EF12-3456-7890ABCDEF01}.Release|x86.ActiveCfg = Release|Any CPU + {E5F6A7B8-90CD-EF12-3456-7890ABCDEF01}.Release|x86.Build.0 = Release|Any CPU + {F6A7B890-CDEF-1234-5678-90ABCDEF0123}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F6A7B890-CDEF-1234-5678-90ABCDEF0123}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F6A7B890-CDEF-1234-5678-90ABCDEF0123}.Debug|x64.ActiveCfg = Debug|Any CPU + {F6A7B890-CDEF-1234-5678-90ABCDEF0123}.Debug|x64.Build.0 = Debug|Any CPU + {F6A7B890-CDEF-1234-5678-90ABCDEF0123}.Debug|x86.ActiveCfg = Debug|Any CPU + {F6A7B890-CDEF-1234-5678-90ABCDEF0123}.Debug|x86.Build.0 = Debug|Any CPU + {F6A7B890-CDEF-1234-5678-90ABCDEF0123}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F6A7B890-CDEF-1234-5678-90ABCDEF0123}.Release|Any CPU.Build.0 = Release|Any CPU + {F6A7B890-CDEF-1234-5678-90ABCDEF0123}.Release|x64.ActiveCfg = Release|Any CPU + {F6A7B890-CDEF-1234-5678-90ABCDEF0123}.Release|x64.Build.0 = Release|Any CPU + {F6A7B890-CDEF-1234-5678-90ABCDEF0123}.Release|x86.ActiveCfg = Release|Any CPU + {F6A7B890-CDEF-1234-5678-90ABCDEF0123}.Release|x86.Build.0 = Release|Any CPU + {8EAD1CA0-DD5D-493A-A6A4-45DD8E6835EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8EAD1CA0-DD5D-493A-A6A4-45DD8E6835EA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8EAD1CA0-DD5D-493A-A6A4-45DD8E6835EA}.Debug|x64.ActiveCfg = Debug|Any CPU + {8EAD1CA0-DD5D-493A-A6A4-45DD8E6835EA}.Debug|x64.Build.0 = Debug|Any CPU + {8EAD1CA0-DD5D-493A-A6A4-45DD8E6835EA}.Debug|x86.ActiveCfg = Debug|Any CPU + {8EAD1CA0-DD5D-493A-A6A4-45DD8E6835EA}.Debug|x86.Build.0 = Debug|Any CPU + {8EAD1CA0-DD5D-493A-A6A4-45DD8E6835EA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8EAD1CA0-DD5D-493A-A6A4-45DD8E6835EA}.Release|Any CPU.Build.0 = Release|Any CPU + {8EAD1CA0-DD5D-493A-A6A4-45DD8E6835EA}.Release|x64.ActiveCfg = Release|Any CPU + {8EAD1CA0-DD5D-493A-A6A4-45DD8E6835EA}.Release|x64.Build.0 = Release|Any CPU + {8EAD1CA0-DD5D-493A-A6A4-45DD8E6835EA}.Release|x86.ActiveCfg = Release|Any CPU + {8EAD1CA0-DD5D-493A-A6A4-45DD8E6835EA}.Release|x86.Build.0 = Release|Any CPU + {9457321A-9019-41E8-9E80-309D76EF2BAF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9457321A-9019-41E8-9E80-309D76EF2BAF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9457321A-9019-41E8-9E80-309D76EF2BAF}.Debug|x64.ActiveCfg = Debug|Any CPU + {9457321A-9019-41E8-9E80-309D76EF2BAF}.Debug|x64.Build.0 = Debug|Any CPU + {9457321A-9019-41E8-9E80-309D76EF2BAF}.Debug|x86.ActiveCfg = Debug|Any CPU + {9457321A-9019-41E8-9E80-309D76EF2BAF}.Debug|x86.Build.0 = Debug|Any CPU + {9457321A-9019-41E8-9E80-309D76EF2BAF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9457321A-9019-41E8-9E80-309D76EF2BAF}.Release|Any CPU.Build.0 = Release|Any CPU + {9457321A-9019-41E8-9E80-309D76EF2BAF}.Release|x64.ActiveCfg = Release|Any CPU + {9457321A-9019-41E8-9E80-309D76EF2BAF}.Release|x64.Build.0 = Release|Any CPU + {9457321A-9019-41E8-9E80-309D76EF2BAF}.Release|x86.ActiveCfg = Release|Any CPU + {9457321A-9019-41E8-9E80-309D76EF2BAF}.Release|x86.Build.0 = Release|Any CPU + {9A72A0E3-091A-4C64-AE66-ADAA5B46B1E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9A72A0E3-091A-4C64-AE66-ADAA5B46B1E8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9A72A0E3-091A-4C64-AE66-ADAA5B46B1E8}.Debug|x64.ActiveCfg = Debug|Any CPU + {9A72A0E3-091A-4C64-AE66-ADAA5B46B1E8}.Debug|x64.Build.0 = Debug|Any CPU + {9A72A0E3-091A-4C64-AE66-ADAA5B46B1E8}.Debug|x86.ActiveCfg = Debug|Any CPU + {9A72A0E3-091A-4C64-AE66-ADAA5B46B1E8}.Debug|x86.Build.0 = Debug|Any CPU + {9A72A0E3-091A-4C64-AE66-ADAA5B46B1E8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9A72A0E3-091A-4C64-AE66-ADAA5B46B1E8}.Release|Any CPU.Build.0 = Release|Any CPU + {9A72A0E3-091A-4C64-AE66-ADAA5B46B1E8}.Release|x64.ActiveCfg = Release|Any CPU + {9A72A0E3-091A-4C64-AE66-ADAA5B46B1E8}.Release|x64.Build.0 = Release|Any CPU + {9A72A0E3-091A-4C64-AE66-ADAA5B46B1E8}.Release|x86.ActiveCfg = Release|Any CPU + {9A72A0E3-091A-4C64-AE66-ADAA5B46B1E8}.Release|x86.Build.0 = Release|Any CPU + {F3F49C7E-9106-4FF7-A71D-442022D63F7B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F3F49C7E-9106-4FF7-A71D-442022D63F7B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F3F49C7E-9106-4FF7-A71D-442022D63F7B}.Debug|x64.ActiveCfg = Debug|Any CPU + {F3F49C7E-9106-4FF7-A71D-442022D63F7B}.Debug|x64.Build.0 = Debug|Any CPU + {F3F49C7E-9106-4FF7-A71D-442022D63F7B}.Debug|x86.ActiveCfg = Debug|Any CPU + {F3F49C7E-9106-4FF7-A71D-442022D63F7B}.Debug|x86.Build.0 = Debug|Any CPU + {F3F49C7E-9106-4FF7-A71D-442022D63F7B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F3F49C7E-9106-4FF7-A71D-442022D63F7B}.Release|Any CPU.Build.0 = Release|Any CPU + {F3F49C7E-9106-4FF7-A71D-442022D63F7B}.Release|x64.ActiveCfg = Release|Any CPU + {F3F49C7E-9106-4FF7-A71D-442022D63F7B}.Release|x64.Build.0 = Release|Any CPU + {F3F49C7E-9106-4FF7-A71D-442022D63F7B}.Release|x86.ActiveCfg = Release|Any CPU + {F3F49C7E-9106-4FF7-A71D-442022D63F7B}.Release|x86.Build.0 = Release|Any CPU + {0A09784C-BB49-44E8-B07A-DA4EEEC1184E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0A09784C-BB49-44E8-B07A-DA4EEEC1184E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0A09784C-BB49-44E8-B07A-DA4EEEC1184E}.Debug|x64.ActiveCfg = Debug|Any CPU + {0A09784C-BB49-44E8-B07A-DA4EEEC1184E}.Debug|x64.Build.0 = Debug|Any CPU + {0A09784C-BB49-44E8-B07A-DA4EEEC1184E}.Debug|x86.ActiveCfg = Debug|Any CPU + {0A09784C-BB49-44E8-B07A-DA4EEEC1184E}.Debug|x86.Build.0 = Debug|Any CPU + {0A09784C-BB49-44E8-B07A-DA4EEEC1184E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0A09784C-BB49-44E8-B07A-DA4EEEC1184E}.Release|Any CPU.Build.0 = Release|Any CPU + {0A09784C-BB49-44E8-B07A-DA4EEEC1184E}.Release|x64.ActiveCfg = Release|Any CPU + {0A09784C-BB49-44E8-B07A-DA4EEEC1184E}.Release|x64.Build.0 = Release|Any CPU + {0A09784C-BB49-44E8-B07A-DA4EEEC1184E}.Release|x86.ActiveCfg = Release|Any CPU + {0A09784C-BB49-44E8-B07A-DA4EEEC1184E}.Release|x86.Build.0 = Release|Any CPU + {F5980D17-1A14-4DD9-82DF-6496E0C4B70D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F5980D17-1A14-4DD9-82DF-6496E0C4B70D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F5980D17-1A14-4DD9-82DF-6496E0C4B70D}.Debug|x64.ActiveCfg = Debug|Any CPU + {F5980D17-1A14-4DD9-82DF-6496E0C4B70D}.Debug|x64.Build.0 = Debug|Any CPU + {F5980D17-1A14-4DD9-82DF-6496E0C4B70D}.Debug|x86.ActiveCfg = Debug|Any CPU + {F5980D17-1A14-4DD9-82DF-6496E0C4B70D}.Debug|x86.Build.0 = Debug|Any CPU + {F5980D17-1A14-4DD9-82DF-6496E0C4B70D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F5980D17-1A14-4DD9-82DF-6496E0C4B70D}.Release|Any CPU.Build.0 = Release|Any CPU + {F5980D17-1A14-4DD9-82DF-6496E0C4B70D}.Release|x64.ActiveCfg = Release|Any CPU + {F5980D17-1A14-4DD9-82DF-6496E0C4B70D}.Release|x64.Build.0 = Release|Any CPU + {F5980D17-1A14-4DD9-82DF-6496E0C4B70D}.Release|x86.ActiveCfg = Release|Any CPU + {F5980D17-1A14-4DD9-82DF-6496E0C4B70D}.Release|x86.Build.0 = Release|Any CPU + {4F0C9315-FBE2-4A98-9FD1-66F508398DEF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4F0C9315-FBE2-4A98-9FD1-66F508398DEF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4F0C9315-FBE2-4A98-9FD1-66F508398DEF}.Debug|x64.ActiveCfg = Debug|Any CPU + {4F0C9315-FBE2-4A98-9FD1-66F508398DEF}.Debug|x64.Build.0 = Debug|Any CPU + {4F0C9315-FBE2-4A98-9FD1-66F508398DEF}.Debug|x86.ActiveCfg = Debug|Any CPU + {4F0C9315-FBE2-4A98-9FD1-66F508398DEF}.Debug|x86.Build.0 = Debug|Any CPU + {4F0C9315-FBE2-4A98-9FD1-66F508398DEF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4F0C9315-FBE2-4A98-9FD1-66F508398DEF}.Release|Any CPU.Build.0 = Release|Any CPU + {4F0C9315-FBE2-4A98-9FD1-66F508398DEF}.Release|x64.ActiveCfg = Release|Any CPU + {4F0C9315-FBE2-4A98-9FD1-66F508398DEF}.Release|x64.Build.0 = Release|Any CPU + {4F0C9315-FBE2-4A98-9FD1-66F508398DEF}.Release|x86.ActiveCfg = Release|Any CPU + {4F0C9315-FBE2-4A98-9FD1-66F508398DEF}.Release|x86.Build.0 = Release|Any CPU + {C031D592-96D6-44D0-BF31-33CCE5CAABA1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C031D592-96D6-44D0-BF31-33CCE5CAABA1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C031D592-96D6-44D0-BF31-33CCE5CAABA1}.Debug|x64.ActiveCfg = Debug|Any CPU + {C031D592-96D6-44D0-BF31-33CCE5CAABA1}.Debug|x64.Build.0 = Debug|Any CPU + {C031D592-96D6-44D0-BF31-33CCE5CAABA1}.Debug|x86.ActiveCfg = Debug|Any CPU + {C031D592-96D6-44D0-BF31-33CCE5CAABA1}.Debug|x86.Build.0 = Debug|Any CPU + {C031D592-96D6-44D0-BF31-33CCE5CAABA1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C031D592-96D6-44D0-BF31-33CCE5CAABA1}.Release|Any CPU.Build.0 = Release|Any CPU + {C031D592-96D6-44D0-BF31-33CCE5CAABA1}.Release|x64.ActiveCfg = Release|Any CPU + {C031D592-96D6-44D0-BF31-33CCE5CAABA1}.Release|x64.Build.0 = Release|Any CPU + {C031D592-96D6-44D0-BF31-33CCE5CAABA1}.Release|x86.ActiveCfg = Release|Any CPU + {C031D592-96D6-44D0-BF31-33CCE5CAABA1}.Release|x86.Build.0 = Release|Any CPU + {D3F46C2D-3AFD-FD9C-9C6A-180B1514DD2F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D3F46C2D-3AFD-FD9C-9C6A-180B1514DD2F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D3F46C2D-3AFD-FD9C-9C6A-180B1514DD2F}.Debug|x64.ActiveCfg = Debug|Any CPU + {D3F46C2D-3AFD-FD9C-9C6A-180B1514DD2F}.Debug|x64.Build.0 = Debug|Any CPU + {D3F46C2D-3AFD-FD9C-9C6A-180B1514DD2F}.Debug|x86.ActiveCfg = Debug|Any CPU + {D3F46C2D-3AFD-FD9C-9C6A-180B1514DD2F}.Debug|x86.Build.0 = Debug|Any CPU + {D3F46C2D-3AFD-FD9C-9C6A-180B1514DD2F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D3F46C2D-3AFD-FD9C-9C6A-180B1514DD2F}.Release|Any CPU.Build.0 = Release|Any CPU + {D3F46C2D-3AFD-FD9C-9C6A-180B1514DD2F}.Release|x64.ActiveCfg = Release|Any CPU + {D3F46C2D-3AFD-FD9C-9C6A-180B1514DD2F}.Release|x64.Build.0 = Release|Any CPU + {D3F46C2D-3AFD-FD9C-9C6A-180B1514DD2F}.Release|x86.ActiveCfg = Release|Any CPU + {D3F46C2D-3AFD-FD9C-9C6A-180B1514DD2F}.Release|x86.Build.0 = Release|Any CPU + {BF0354AE-3748-A8DC-F79D-B21FDDEDDFAE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BF0354AE-3748-A8DC-F79D-B21FDDEDDFAE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BF0354AE-3748-A8DC-F79D-B21FDDEDDFAE}.Debug|x64.ActiveCfg = Debug|Any CPU + {BF0354AE-3748-A8DC-F79D-B21FDDEDDFAE}.Debug|x64.Build.0 = Debug|Any CPU + {BF0354AE-3748-A8DC-F79D-B21FDDEDDFAE}.Debug|x86.ActiveCfg = Debug|Any CPU + {BF0354AE-3748-A8DC-F79D-B21FDDEDDFAE}.Debug|x86.Build.0 = Debug|Any CPU + {BF0354AE-3748-A8DC-F79D-B21FDDEDDFAE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BF0354AE-3748-A8DC-F79D-B21FDDEDDFAE}.Release|Any CPU.Build.0 = Release|Any CPU + {BF0354AE-3748-A8DC-F79D-B21FDDEDDFAE}.Release|x64.ActiveCfg = Release|Any CPU + {BF0354AE-3748-A8DC-F79D-B21FDDEDDFAE}.Release|x64.Build.0 = Release|Any CPU + {BF0354AE-3748-A8DC-F79D-B21FDDEDDFAE}.Release|x86.ActiveCfg = Release|Any CPU + {BF0354AE-3748-A8DC-F79D-B21FDDEDDFAE}.Release|x86.Build.0 = Release|Any CPU + {5CF09A5B-85A2-41B2-8A51-E7F2ED03B77A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5CF09A5B-85A2-41B2-8A51-E7F2ED03B77A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5CF09A5B-85A2-41B2-8A51-E7F2ED03B77A}.Debug|x64.ActiveCfg = Debug|Any CPU + {5CF09A5B-85A2-41B2-8A51-E7F2ED03B77A}.Debug|x64.Build.0 = Debug|Any CPU + {5CF09A5B-85A2-41B2-8A51-E7F2ED03B77A}.Debug|x86.ActiveCfg = Debug|Any CPU + {5CF09A5B-85A2-41B2-8A51-E7F2ED03B77A}.Debug|x86.Build.0 = Debug|Any CPU + {5CF09A5B-85A2-41B2-8A51-E7F2ED03B77A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5CF09A5B-85A2-41B2-8A51-E7F2ED03B77A}.Release|Any CPU.Build.0 = Release|Any CPU + {5CF09A5B-85A2-41B2-8A51-E7F2ED03B77A}.Release|x64.ActiveCfg = Release|Any CPU + {5CF09A5B-85A2-41B2-8A51-E7F2ED03B77A}.Release|x64.Build.0 = Release|Any CPU + {5CF09A5B-85A2-41B2-8A51-E7F2ED03B77A}.Release|x86.ActiveCfg = Release|Any CPU + {5CF09A5B-85A2-41B2-8A51-E7F2ED03B77A}.Release|x86.Build.0 = Release|Any CPU + {A5B0CAC9-2FCF-4AA2-9C02-655035284FCD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A5B0CAC9-2FCF-4AA2-9C02-655035284FCD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A5B0CAC9-2FCF-4AA2-9C02-655035284FCD}.Debug|x64.ActiveCfg = Debug|Any CPU + {A5B0CAC9-2FCF-4AA2-9C02-655035284FCD}.Debug|x64.Build.0 = Debug|Any CPU + {A5B0CAC9-2FCF-4AA2-9C02-655035284FCD}.Debug|x86.ActiveCfg = Debug|Any CPU + {A5B0CAC9-2FCF-4AA2-9C02-655035284FCD}.Debug|x86.Build.0 = Debug|Any CPU + {A5B0CAC9-2FCF-4AA2-9C02-655035284FCD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A5B0CAC9-2FCF-4AA2-9C02-655035284FCD}.Release|Any CPU.Build.0 = Release|Any CPU + {A5B0CAC9-2FCF-4AA2-9C02-655035284FCD}.Release|x64.ActiveCfg = Release|Any CPU + {A5B0CAC9-2FCF-4AA2-9C02-655035284FCD}.Release|x64.Build.0 = Release|Any CPU + {A5B0CAC9-2FCF-4AA2-9C02-655035284FCD}.Release|x86.ActiveCfg = Release|Any CPU + {A5B0CAC9-2FCF-4AA2-9C02-655035284FCD}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {60ACCE40-218A-70DA-E578-61113823C3D1} = {FBF56CC3-7AE6-AD2D-3F14-7F97FD322CD6} + {7905BE8B-130A-154F-744E-8F5C373BB4A4} = {60ACCE40-218A-70DA-E578-61113823C3D1} + {8904FD57-96C7-434D-B4CD-99D2A7637ED3} = {7905BE8B-130A-154F-744E-8F5C373BB4A4} + {D9C18059-AC6D-4A51-C1D3-5F3385C91125} = {FBF56CC3-7AE6-AD2D-3F14-7F97FD322CD6} + {1032D52E-0A23-303A-285B-3E580F3BFBA1} = {D9C18059-AC6D-4A51-C1D3-5F3385C91125} + {F849CD08-D4E4-4CDA-AB6F-D776EAFCD0E2} = {1032D52E-0A23-303A-285B-3E580F3BFBA1} + {8F8E4A0B-9BF7-9BD7-A493-72F2DCAF9D32} = {60ACCE40-218A-70DA-E578-61113823C3D1} + {F9FD0819-F62F-4979-81EF-0093CE31EEA7} = {8F8E4A0B-9BF7-9BD7-A493-72F2DCAF9D32} + {5EEB08B8-FBBE-45ED-AB55-E5073308226B} = {8F8E4A0B-9BF7-9BD7-A493-72F2DCAF9D32} + {F7E192D1-DE6C-42A2-B52F-02849D482450} = {769B9289-B2AF-0079-2183-40A0D5B6CA35} + {143983D8-FD06-8E1F-BA6B-2BC51EF88F6F} = {F7E192D1-DE6C-42A2-B52F-02849D482450} + {C7A151C3-2C9C-4C0F-8D07-0BB6630E821C} = {143983D8-FD06-8E1F-BA6B-2BC51EF88F6F} + {157D81C5-4B8F-A378-5D75-7BAB039D1DC1} = {07C2787E-EAC7-C090-1BA3-A61EC2A24D84} + {667E7915-06AD-1B48-0150-8A7F70E56563} = {157D81C5-4B8F-A378-5D75-7BAB039D1DC1} + {6EEBF2DB-8E44-4FB2-9157-2B46E23AD086} = {667E7915-06AD-1B48-0150-8A7F70E56563} + {42698EC0-FB39-C569-8E8D-B1280AAEC8EB} = {07C2787E-EAC7-C090-1BA3-A61EC2A24D84} + {12ABC2B4-C2CC-FC16-AE04-E7611E7F2628} = {42698EC0-FB39-C569-8E8D-B1280AAEC8EB} + {7C89F911-9624-4CC8-9268-57824064FCA7} = {12ABC2B4-C2CC-FC16-AE04-E7611E7F2628} + {A3A9055D-A201-082F-4C76-F1268653F9BB} = {07C2787E-EAC7-C090-1BA3-A61EC2A24D84} + {25222008-2AE0-B613-C5A2-1843DE1A0697} = {A3A9055D-A201-082F-4C76-F1268653F9BB} + {AF90B213-1A45-477A-A958-2B9187AEAF54} = {25222008-2AE0-B613-C5A2-1843DE1A0697} + {F875D02C-2C2B-3465-24BB-4957ACDF70AD} = {07C2787E-EAC7-C090-1BA3-A61EC2A24D84} + {BB85F6EF-A9D2-63B8-1A53-B68D57B18799} = {F875D02C-2C2B-3465-24BB-4957ACDF70AD} + {3D4E5F6A-7B8C-9D0E-1F2A-3B4C5D6E7F8A} = {BB85F6EF-A9D2-63B8-1A53-B68D57B18799} + {E19EB0A0-F682-2D4D-E69C-FF5DD6980CB7} = {07C2787E-EAC7-C090-1BA3-A61EC2A24D84} + {EC9869D6-5301-5ADB-CC59-9E37821F5203} = {E19EB0A0-F682-2D4D-E69C-FF5DD6980CB7} + {E2C2A3E4-1D5F-4F6E-9A7F-1C2E54F893AB} = {EC9869D6-5301-5ADB-CC59-9E37821F5203} + {03B49640-8ED6-23C8-1C29-10AEAF3F6973} = {07C2787E-EAC7-C090-1BA3-A61EC2A24D84} + {A0C524B1-9E68-5D79-F404-7E079F138486} = {03B49640-8ED6-23C8-1C29-10AEAF3F6973} + {7828AB14-5E8B-4E60-B8AA-988E70573684} = {A0C524B1-9E68-5D79-F404-7E079F138486} + {859FD998-B283-526A-0D29-2BE9DB23F127} = {07C2787E-EAC7-C090-1BA3-A61EC2A24D84} + {DDC67B88-003A-BF20-18CC-988992D9F2DA} = {859FD998-B283-526A-0D29-2BE9DB23F127} + {55FF4834-F1FE-47C1-AA8C-24DC4C3F171A} = {DDC67B88-003A-BF20-18CC-988992D9F2DA} + {E98DC7CA-7D6E-CD95-7C38-7EC54C49A4BA} = {07C2787E-EAC7-C090-1BA3-A61EC2A24D84} + {9ECC55D0-7405-7BFD-C0DD-D432F1A7556E} = {E98DC7CA-7D6E-CD95-7C38-7EC54C49A4BA} + {DFDDA723-3307-4330-A154-A0F337A5E8EF} = {9ECC55D0-7405-7BFD-C0DD-D432F1A7556E} + {527E7737-8178-1F7B-CC32-0B66418AAAE3} = {07C2787E-EAC7-C090-1BA3-A61EC2A24D84} + {AABD2F22-45E6-D373-CACB-1E42EBBB89E4} = {527E7737-8178-1F7B-CC32-0B66418AAAE3} + {51FF959C-5452-4611-B3DF-671D5D2FEF1E} = {AABD2F22-45E6-D373-CACB-1E42EBBB89E4} + {9B70BA7E-5CCA-8859-C252-AF72C051F264} = {07C2787E-EAC7-C090-1BA3-A61EC2A24D84} + {72886DEE-EE65-CAB4-D88E-95639D81D7B4} = {9B70BA7E-5CCA-8859-C252-AF72C051F264} + {38EF7AE0-C6B0-4809-85EE-27A2C4F8F83B} = {72886DEE-EE65-CAB4-D88E-95639D81D7B4} + {3050869B-5B38-A2E1-E211-FDD96922C0D8} = {07C2787E-EAC7-C090-1BA3-A61EC2A24D84} + {9E83E5D7-427F-F90E-BAF8-110976D8882A} = {3050869B-5B38-A2E1-E211-FDD96922C0D8} + {F6B9B9A5-3A77-44F6-A349-50A751B46904} = {9E83E5D7-427F-F90E-BAF8-110976D8882A} + {A6722C15-810E-881D-D81D-B31AFB74E906} = {07C2787E-EAC7-C090-1BA3-A61EC2A24D84} + {BBC3EE4A-E86F-DF79-071D-BFF25E371E68} = {A6722C15-810E-881D-D81D-B31AFB74E906} + {744989A9-972B-4076-81FE-BFAB39EE899A} = {BBC3EE4A-E86F-DF79-071D-BFF25E371E68} + {9E20BC7A-4871-E449-D7C1-4770293578A3} = {07C2787E-EAC7-C090-1BA3-A61EC2A24D84} + {7C4CD8CB-4CAB-A05D-EBA1-82911CA4C7BB} = {9E20BC7A-4871-E449-D7C1-4770293578A3} + {E77DA2D5-7AFD-43D6-B77A-C22A1167B856} = {7C4CD8CB-4CAB-A05D-EBA1-82911CA4C7BB} + {C512965D-7BB0-9820-B548-85E6E27E777F} = {07C2787E-EAC7-C090-1BA3-A61EC2A24D84} + {63ADDEB0-FC34-0EAE-BA79-5E41D9CAA086} = {C512965D-7BB0-9820-B548-85E6E27E777F} + {D7B16F40-8636-4EE4-9F9A-77DF5A92EE03} = {63ADDEB0-FC34-0EAE-BA79-5E41D9CAA086} + {59CA5914-CD73-F72D-5AE2-2588F9749673} = {07C2787E-EAC7-C090-1BA3-A61EC2A24D84} + {6B5A97A9-D4ED-154B-D06B-95186CD1FF1C} = {59CA5914-CD73-F72D-5AE2-2588F9749673} + {359D3A43-1DFB-4541-AC72-E63EF0D6B3C9} = {6B5A97A9-D4ED-154B-D06B-95186CD1FF1C} + {C3450695-99A5-5CF8-F6BD-D2019CEF67AE} = {07C2787E-EAC7-C090-1BA3-A61EC2A24D84} + {5DDB903B-9950-F24C-C972-E88A4AADF5AC} = {C3450695-99A5-5CF8-F6BD-D2019CEF67AE} + {C8612FFE-7E8F-4EC4-B158-A4C2167A9AD5} = {5DDB903B-9950-F24C-C972-E88A4AADF5AC} + {19B1C41E-6924-9335-E5C4-0D3E2A03D547} = {07C2787E-EAC7-C090-1BA3-A61EC2A24D84} + {D9515F83-9B0C-5D25-5D20-CC78FE8837D0} = {19B1C41E-6924-9335-E5C4-0D3E2A03D547} + {9924AEB8-EEB1-40EC-943B-DA1B9E610767} = {D9515F83-9B0C-5D25-5D20-CC78FE8837D0} + {C0D09155-BD9F-CB19-962D-DAF1E886BDCF} = {07C2787E-EAC7-C090-1BA3-A61EC2A24D84} + {33C33874-E52E-07CC-0DDA-2389CB6FF63D} = {C0D09155-BD9F-CB19-962D-DAF1E886BDCF} + {E1234567-1234-1234-1234-123456789012} = {33C33874-E52E-07CC-0DDA-2389CB6FF63D} + {8CB42B58-89CF-D92F-E189-16F031184C0B} = {07C2787E-EAC7-C090-1BA3-A61EC2A24D84} + {40DBA547-7429-3933-14A0-AA798EF058C1} = {8CB42B58-89CF-D92F-E189-16F031184C0B} + {632DF404-7E5D-56B7-808D-816A3AB773A4} = {40DBA547-7429-3933-14A0-AA798EF058C1} + {0D319E14-6DDE-C12F-A5B0-76EED797D651} = {07C2787E-EAC7-C090-1BA3-A61EC2A24D84} + {917EE497-2381-F55E-88F6-47586FC57241} = {0D319E14-6DDE-C12F-A5B0-76EED797D651} + {2DF5CFE5-EF8D-4BE4-96D0-C256F2B52011} = {917EE497-2381-F55E-88F6-47586FC57241} + {4179CBCC-D958-52F0-A182-FBFEBF000264} = {07C2787E-EAC7-C090-1BA3-A61EC2A24D84} + {70CADE69-D2B1-ED23-4BCD-2FABD273428B} = {4179CBCC-D958-52F0-A182-FBFEBF000264} + {BA7AC885-A065-41F2-98FF-281C82994F7C} = {70CADE69-D2B1-ED23-4BCD-2FABD273428B} + {E938B49F-87B3-0DAA-220C-07320FBA6C2A} = {07C2787E-EAC7-C090-1BA3-A61EC2A24D84} + {BF79F913-D6F2-E657-45D9-277597840EFA} = {E938B49F-87B3-0DAA-220C-07320FBA6C2A} + {65F5AE53-C77A-4818-ADE1-B2D6973A68B9} = {BF79F913-D6F2-E657-45D9-277597840EFA} + {0BD17E58-AFC9-6F1A-D335-FEEF8A424ECB} = {07C2787E-EAC7-C090-1BA3-A61EC2A24D84} + {05E18918-DF6D-B73A-4C4A-4AEF98A73A1A} = {0BD17E58-AFC9-6F1A-D335-FEEF8A424ECB} + {E13EEC3A-6DEB-403D-98F5-E143A16F6E9D} = {05E18918-DF6D-B73A-4C4A-4AEF98A73A1A} + {F9BCFF5A-BB96-6495-0B41-71CBBD75CCD0} = {07C2787E-EAC7-C090-1BA3-A61EC2A24D84} + {5C936215-2BB8-E193-B185-29FE7BBEA33F} = {F9BCFF5A-BB96-6495-0B41-71CBBD75CCD0} + {1DE3EF01-EB07-412F-82C9-9709D1981C77} = {5C936215-2BB8-E193-B185-29FE7BBEA33F} + {E4043D9D-4D2E-D8B5-F79E-057177808F38} = {07C2787E-EAC7-C090-1BA3-A61EC2A24D84} + {FFA8D48E-F9A9-6089-AB62-C90A740EA21E} = {E4043D9D-4D2E-D8B5-F79E-057177808F38} + {3025876C-E9AF-4D37-98D2-4A7B56CAD3B1} = {FFA8D48E-F9A9-6089-AB62-C90A740EA21E} + {2DD519C6-9156-B8C4-11E9-4269216495AD} = {07C2787E-EAC7-C090-1BA3-A61EC2A24D84} + {96640177-9FE5-9698-15FE-FA6086540707} = {2DD519C6-9156-B8C4-11E9-4269216495AD} + {19631370-84E9-45A5-B98F-0359499DB2FA} = {96640177-9FE5-9698-15FE-FA6086540707} + {EB5334E6-670B-EC92-68F3-634AA8C9020E} = {07C2787E-EAC7-C090-1BA3-A61EC2A24D84} + {59B172EF-E666-A44A-A88A-206F6A63264A} = {EB5334E6-670B-EC92-68F3-634AA8C9020E} + {1F58262C-B95C-4EC3-95BF-469D7A56480E} = {59B172EF-E666-A44A-A88A-206F6A63264A} + {3DC51C40-03E9-5066-4FB5-FF3E41C97E1F} = {07C2787E-EAC7-C090-1BA3-A61EC2A24D84} + {F894982B-4C93-0C62-D6DA-E27C0A3503E4} = {3DC51C40-03E9-5066-4FB5-FF3E41C97E1F} + {168BAD1F-6D9B-4A41-9A40-CAA2766110EF} = {F894982B-4C93-0C62-D6DA-E27C0A3503E4} + {F4CC2172-46F8-04D7-FF11-4F95DDBB59E2} = {07C2787E-EAC7-C090-1BA3-A61EC2A24D84} + {065991D2-6F8C-6F65-0E72-DC96953B87D8} = {F4CC2172-46F8-04D7-FF11-4F95DDBB59E2} + {916DF4C9-3EB7-4D2B-B727-6EEEBB049A80} = {065991D2-6F8C-6F65-0E72-DC96953B87D8} + {898C8C6E-FC1C-58E1-FB62-BBE77ED42888} = {07C2787E-EAC7-C090-1BA3-A61EC2A24D84} + {C1148A03-1886-DC1A-65F9-2AE3D2752F84} = {898C8C6E-FC1C-58E1-FB62-BBE77ED42888} + {9CF26119-BE08-4C57-945B-2844481F6141} = {C1148A03-1886-DC1A-65F9-2AE3D2752F84} + {4CBFCE90-00AC-3F19-DC8C-C81357708F76} = {07C2787E-EAC7-C090-1BA3-A61EC2A24D84} + {435A0E5F-27FA-99FA-C842-A91B522B4C1E} = {4CBFCE90-00AC-3F19-DC8C-C81357708F76} + {A7A089BD-3128-48F8-8B18-E467BBA8C7FB} = {435A0E5F-27FA-99FA-C842-A91B522B4C1E} + {557B0DD6-D749-3FB3-AE6F-6C9843ACC451} = {07C2787E-EAC7-C090-1BA3-A61EC2A24D84} + {C6D1966B-40C4-EADA-2021-D62EB362BC5D} = {557B0DD6-D749-3FB3-AE6F-6C9843ACC451} + {9A740958-5F01-4121-84E6-6D05B369AE94} = {C6D1966B-40C4-EADA-2021-D62EB362BC5D} + {C6CEF4FB-0C38-F8A1-C3A9-84AA43EDFA2E} = {07C2787E-EAC7-C090-1BA3-A61EC2A24D84} + {050FD842-8358-E96B-7D60-52669EEB9D25} = {C6CEF4FB-0C38-F8A1-C3A9-84AA43EDFA2E} + {C484A6D7-7798-4C8B-91DC-EA9909D627C8} = {050FD842-8358-E96B-7D60-52669EEB9D25} + {38F57492-853E-43AB-A96A-0D16B88231B6} = {07C2787E-EAC7-C090-1BA3-A61EC2A24D84} + {6B343355-29B5-2BBE-C966-B4AB2FB51F8E} = {38F57492-853E-43AB-A96A-0D16B88231B6} + {9CCACC42-070F-4BB5-A06C-D5B7A1ABD519} = {6B343355-29B5-2BBE-C966-B4AB2FB51F8E} + {1ED11E6E-94A0-E908-ACE4-8E9BD19CC7E1} = {07C2787E-EAC7-C090-1BA3-A61EC2A24D84} + {075C408B-AC75-B3AA-88FB-1AE42826BD50} = {1ED11E6E-94A0-E908-ACE4-8E9BD19CC7E1} + {F575C6A0-59AF-455D-8B7A-5421D4BAAA2F} = {075C408B-AC75-B3AA-88FB-1AE42826BD50} + {84B02E00-2E23-1547-B733-D86A059C7EE0} = {07C2787E-EAC7-C090-1BA3-A61EC2A24D84} + {717ED564-5195-F490-103F-F6C7788C6E34} = {84B02E00-2E23-1547-B733-D86A059C7EE0} + {9B667E4D-C905-4CA4-B640-0F3B89293CA8} = {717ED564-5195-F490-103F-F6C7788C6E34} + {AB4067EC-C276-E50A-4A3C-F9DDFC3B9D29} = {07C2787E-EAC7-C090-1BA3-A61EC2A24D84} + {7AC89CF8-E7AC-9EE9-D7AA-392DECC2CF04} = {AB4067EC-C276-E50A-4A3C-F9DDFC3B9D29} + {C3D4E5F6-7890-ABCD-EF12-345678901234} = {7AC89CF8-E7AC-9EE9-D7AA-392DECC2CF04} + {C64ABA23-B3DB-4B75-3019-7CBBB134BB29} = {07C2787E-EAC7-C090-1BA3-A61EC2A24D84} + {04A069BA-F670-FF57-4260-3772155E86F2} = {C64ABA23-B3DB-4B75-3019-7CBBB134BB29} + {C84A54B1-BFF9-4394-A6BF-135C2FC37A64} = {04A069BA-F670-FF57-4260-3772155E86F2} + {ED9D3D4A-502F-41A4-BBCC-970E65472F33} = {07C2787E-EAC7-C090-1BA3-A61EC2A24D84} + {0131AD4F-3934-F56E-5081-42129AD09143} = {ED9D3D4A-502F-41A4-BBCC-970E65472F33} + {DE1B4312-1A4F-4774-B7EB-B1EC77F80D5E} = {0131AD4F-3934-F56E-5081-42129AD09143} + {B28A9B67-1C09-C756-C02A-7AC1895F9584} = {07C2787E-EAC7-C090-1BA3-A61EC2A24D84} + {E38B6DEF-57A1-6CCA-498B-5697FF0B466C} = {B28A9B67-1C09-C756-C02A-7AC1895F9584} + {3156A400-78C7-410A-9B79-9CDFFD5B94E3} = {E38B6DEF-57A1-6CCA-498B-5697FF0B466C} + {90CD12FE-21C2-5151-E041-9FB96A3D0773} = {07C2787E-EAC7-C090-1BA3-A61EC2A24D84} + {A9F0731A-101C-4664-E960-D159F9998165} = {90CD12FE-21C2-5151-E041-9FB96A3D0773} + {FCEFF719-E5F5-4BB6-83EF-17201FB14FF2} = {A9F0731A-101C-4664-E960-D159F9998165} + {AE9E8273-2844-41A7-AE84-36E2F8B1B3DE} = {8F8E4A0B-9BF7-9BD7-A493-72F2DCAF9D32} + {4BBEE4C4-18FC-AB55-A8B3-4C6BF70DF9AD} = {FBF56CC3-7AE6-AD2D-3F14-7F97FD322CD6} + {44C29C35-3F02-ECB8-1C42-1E60EABFA6B5} = {4BBEE4C4-18FC-AB55-A8B3-4C6BF70DF9AD} + {B7418A46-E05D-4605-9BAE-8308BEF25641} = {44C29C35-3F02-ECB8-1C42-1E60EABFA6B5} + {1D0F574F-F118-FD2E-5A10-1304F36167C2} = {FBF56CC3-7AE6-AD2D-3F14-7F97FD322CD6} + {F04579C5-27C8-AFEE-B183-2AA2B0A14285} = {1D0F574F-F118-FD2E-5A10-1304F36167C2} + {E3F17DAA-1EFB-40F3-9F16-F77AF18893F2} = {F04579C5-27C8-AFEE-B183-2AA2B0A14285} + {DAAE2FFB-70A9-DCEF-23A0-0ABAED0A9720} = {7525B257-249C-EE79-B10A-65D0BC27ABA9} + {1CB18013-ABED-48C1-8576-1E8ABCD70293} = {DAAE2FFB-70A9-DCEF-23A0-0ABAED0A9720} + {F4EFF172-8E25-E6E4-AFDD-640B2A635C0F} = {769B9289-B2AF-0079-2183-40A0D5B6CA35} + {46F805EC-2E15-E63F-1946-C3BCA0EBE9E3} = {F4EFF172-8E25-E6E4-AFDD-640B2A635C0F} + {56650789-168A-427A-A354-7AF969417C47} = {46F805EC-2E15-E63F-1946-C3BCA0EBE9E3} + {9072C7AF-9EB2-E481-3974-77957587AC76} = {07C2787E-EAC7-C090-1BA3-A61EC2A24D84} + {828CD049-D774-9906-6209-B6F1F7428EAF} = {9072C7AF-9EB2-E481-3974-77957587AC76} + {C11ED240-7ADE-43A2-7C2C-04463E5CCAA8} = {828CD049-D774-9906-6209-B6F1F7428EAF} + {C761690B-E036-150F-CCBF-007CA2728C9D} = {769B9289-B2AF-0079-2183-40A0D5B6CA35} + {C2F07CB4-6560-5C65-21A5-FF4953BB8CD9} = {C761690B-E036-150F-CCBF-007CA2728C9D} + {7C56FC56-343A-4C68-AD1A-8C2CBC5DED74} = {C2F07CB4-6560-5C65-21A5-FF4953BB8CD9} + {15C060E2-796E-E031-E908-89DE5CD569D8} = {157D81C5-4B8F-A378-5D75-7BAB039D1DC1} + {8C5CED5B-ECB8-4847-9435-B7954055A530} = {15C060E2-796E-E031-E908-89DE5CD569D8} + {9131BD5D-B459-46AE-809D-F066B2FD119A} = {15C060E2-796E-E031-E908-89DE5CD569D8} + {2F7EC3CB-1734-6B7C-0B17-6303A1B67019} = {42698EC0-FB39-C569-8E8D-B1280AAEC8EB} + {492A0B4A-C7EA-4469-814E-373B3DD90E6E} = {2F7EC3CB-1734-6B7C-0B17-6303A1B67019} + {9EB26D07-4530-44BA-BB2F-F5A20B86EF08} = {2F7EC3CB-1734-6B7C-0B17-6303A1B67019} + {06C3F726-79B1-E9B3-C592-70534457DCBA} = {A3A9055D-A201-082F-4C76-F1268653F9BB} + {AACC56D7-3738-4C63-835F-A8373A084CFA} = {06C3F726-79B1-E9B3-C592-70534457DCBA} + {57C9E70F-2035-4217-8D35-C5498103E52C} = {06C3F726-79B1-E9B3-C592-70534457DCBA} + {6F99F316-9387-9CAC-AEB4-15F1E9D669C8} = {F875D02C-2C2B-3465-24BB-4957ACDF70AD} + {B2C3D4E5-F6A7-8901-BCDE-F23456789012} = {6F99F316-9387-9CAC-AEB4-15F1E9D669C8} + {FA658F27-CA29-C4FC-A436-483AE994B789} = {E19EB0A0-F682-2D4D-E69C-FF5DD6980CB7} + {C0F9D8F5-3F6D-4D46-9E6D-8A7E4EDC0E11} = {FA658F27-CA29-C4FC-A436-483AE994B789} + {047042FC-DF09-5707-F2AE-666AE9547EAC} = {03B49640-8ED6-23C8-1C29-10AEAF3F6973} + {10E02570-BC66-4389-AD30-2E19CB9BD700} = {047042FC-DF09-5707-F2AE-666AE9547EAC} + {9D157338-0F03-4A4C-AD84-39E04B6368BF} = {047042FC-DF09-5707-F2AE-666AE9547EAC} + {D3FC126D-7888-673A-FB5D-D6AF5DE9603B} = {859FD998-B283-526A-0D29-2BE9DB23F127} + {55B6007F-5F58-4F33-91A5-677859BAE2D6} = {D3FC126D-7888-673A-FB5D-D6AF5DE9603B} + {1A9485FE-242C-4627-AC8D-9B36512162C4} = {D3FC126D-7888-673A-FB5D-D6AF5DE9603B} + {53133BE3-FE0F-4EF8-8B39-42F749686075} = {E98DC7CA-7D6E-CD95-7C38-7EC54C49A4BA} + {AAF964F7-6902-4A7C-9F52-59FF502920D5} = {53133BE3-FE0F-4EF8-8B39-42F749686075} + {BEEC386F-2B6A-A601-7DF0-FDB8FC583F0B} = {527E7737-8178-1F7B-CC32-0B66418AAAE3} + {FFA1F834-6049-474C-9EED-72E1A3F9646E} = {BEEC386F-2B6A-A601-7DF0-FDB8FC583F0B} + {D3348F94-9831-4A3D-8E79-844900B88287} = {BEEC386F-2B6A-A601-7DF0-FDB8FC583F0B} + {D80CC604-369B-AC81-8F7A-C731A7ABD68E} = {9B70BA7E-5CCA-8859-C252-AF72C051F264} + {75A5A87C-BF04-4ABE-B466-874074D37C8D} = {D80CC604-369B-AC81-8F7A-C731A7ABD68E} + {D1BCD822-AC8A-408F-A71A-9205DB29A9D2} = {D80CC604-369B-AC81-8F7A-C731A7ABD68E} + {A8D0F127-6ACB-380E-8423-B6B6EA1AF2DC} = {3050869B-5B38-A2E1-E211-FDD96922C0D8} + {A99D3C27-65B7-4ADF-AB54-6D8649D1E7C7} = {A8D0F127-6ACB-380E-8423-B6B6EA1AF2DC} + {18221FA7-BAC2-07BA-D54F-D567400B25DA} = {A6722C15-810E-881D-D81D-B31AFB74E906} + {88780872-11A6-4014-B575-75C960EC0968} = {18221FA7-BAC2-07BA-D54F-D567400B25DA} + {D03EF84F-1D93-1805-F24E-6781FF2EE6D9} = {9E20BC7A-4871-E449-D7C1-4770293578A3} + {2135A527-3910-44B5-A778-C5467D0A6148} = {D03EF84F-1D93-1805-F24E-6781FF2EE6D9} + {FCBD2AD5-0A0E-7EFF-287B-AA167C8934A9} = {C512965D-7BB0-9820-B548-85E6E27E777F} + {02276871-6582-4A21-B629-83527FD90559} = {FCBD2AD5-0A0E-7EFF-287B-AA167C8934A9} + {DDF0DC50-766B-4E49-AA46-8D7F2370465A} = {FCBD2AD5-0A0E-7EFF-287B-AA167C8934A9} + {6449F0B7-FD03-89F1-ED21-7DE8FE1BCD0A} = {59CA5914-CD73-F72D-5AE2-2588F9749673} + {8F8153F8-6BED-4026-89A5-FEE2FEF7D379} = {6449F0B7-FD03-89F1-ED21-7DE8FE1BCD0A} + {FD1A0CD2-19BF-443E-9687-83E5B9E438EE} = {6449F0B7-FD03-89F1-ED21-7DE8FE1BCD0A} + {399EB16B-AE75-8AFC-99AF-1927C5624042} = {C3450695-99A5-5CF8-F6BD-D2019CEF67AE} + {F3AD707A-5E2D-4F58-BA21-691B4C7D1BA5} = {399EB16B-AE75-8AFC-99AF-1927C5624042} + {B73E94EA-256E-4C1C-956B-0D4E67B5C82F} = {399EB16B-AE75-8AFC-99AF-1927C5624042} + {5629B6E3-0318-880C-B9FB-171A66E3835B} = {19B1C41E-6924-9335-E5C4-0D3E2A03D547} + {BBE0307D-17C0-4A0A-9D7A-D8E9328A3CF7} = {5629B6E3-0318-880C-B9FB-171A66E3835B} + {56B04873-1F4B-402E-88C0-528F006E3914} = {5629B6E3-0318-880C-B9FB-171A66E3835B} + {FD32D82B-24D4-2B38-C449-6062D56010E9} = {C0D09155-BD9F-CB19-962D-DAF1E886BDCF} + {D4ADBF73-AE37-4614-9C07-8C71DC85F8EA} = {FD32D82B-24D4-2B38-C449-6062D56010E9} + {E1234569-1234-1234-1234-1234567890AE} = {FD32D82B-24D4-2B38-C449-6062D56010E9} + {DF6A3634-B09B-FAAE-C9A7-03F46588271A} = {8CB42B58-89CF-D92F-E189-16F031184C0B} + {760CAD28-4792-44B8-77D1-0F42F47BD303} = {DF6A3634-B09B-FAAE-C9A7-03F46588271A} + {459CFD26-F5BC-B3C8-0632-DE7EA1504AD3} = {DF6A3634-B09B-FAAE-C9A7-03F46588271A} + {81E3F68B-68AA-1E51-D1D2-DE3FA9DB90AD} = {0D319E14-6DDE-C12F-A5B0-76EED797D651} + {CE923FCF-F208-4BC5-8C9B-AA54E2930993} = {81E3F68B-68AA-1E51-D1D2-DE3FA9DB90AD} + {2BABADA8-D4EC-AEA2-C105-00C894829DE1} = {4179CBCC-D958-52F0-A182-FBFEBF000264} + {EB564D80-A767-4431-9918-16BE87407068} = {2BABADA8-D4EC-AEA2-C105-00C894829DE1} + {DCC2034C-2F4A-4C72-A39C-58E108055E70} = {2BABADA8-D4EC-AEA2-C105-00C894829DE1} + {3749EF6E-907A-D4F8-B2FD-A6C27C0C1C55} = {E938B49F-87B3-0DAA-220C-07320FBA6C2A} + {E6AD3B7D-5ED5-43E6-A139-607A3F03FF00} = {3749EF6E-907A-D4F8-B2FD-A6C27C0C1C55} + {C3327B63-4141-4D49-AE04-FA6A36FBDC9F} = {3749EF6E-907A-D4F8-B2FD-A6C27C0C1C55} + {97BD5054-B44C-2CB3-7133-19D3965C6D42} = {0BD17E58-AFC9-6F1A-D335-FEEF8A424ECB} + {AE374EE8-1500-46BF-92C1-AA921B679E19} = {97BD5054-B44C-2CB3-7133-19D3965C6D42} + {05C411F3-C725-47EC-9441-650DA9DEB322} = {97BD5054-B44C-2CB3-7133-19D3965C6D42} + {949474CC-6E94-7345-61BC-6D63A88C0FCD} = {F9BCFF5A-BB96-6495-0B41-71CBBD75CCD0} + {666D3414-8801-4BB9-B49A-656D5D65ADC9} = {949474CC-6E94-7345-61BC-6D63A88C0FCD} + {B82ECFF7-7F47-44A8-B947-1AC4E1AAB952} = {949474CC-6E94-7345-61BC-6D63A88C0FCD} + {5BB0F909-6B8E-7953-568A-56247A9BE7D9} = {E4043D9D-4D2E-D8B5-F79E-057177808F38} + {223D1AA3-8756-4394-BDB8-0C20737C36F4} = {5BB0F909-6B8E-7953-568A-56247A9BE7D9} + {746C9DFE-3D0E-4D4D-9AE2-D85D7250075F} = {5BB0F909-6B8E-7953-568A-56247A9BE7D9} + {FB0433B6-88B8-3F40-695F-E02336F620D7} = {2DD519C6-9156-B8C4-11E9-4269216495AD} + {6B594222-0B9E-4CDE-A49E-C3CCB65815FD} = {FB0433B6-88B8-3F40-695F-E02336F620D7} + {F009F428-7BBE-41FE-AD55-D19B4947E978} = {FB0433B6-88B8-3F40-695F-E02336F620D7} + {D5394AFD-90BE-8F1D-1BC6-C1A4C372E9EC} = {EB5334E6-670B-EC92-68F3-634AA8C9020E} + {751F96A2-DB60-4B40-A415-0924FEEFFD9C} = {D5394AFD-90BE-8F1D-1BC6-C1A4C372E9EC} + {4D7B1DE3-D04E-48A2-A904-A3288F0A519C} = {D5394AFD-90BE-8F1D-1BC6-C1A4C372E9EC} + {33685B87-9DF7-C305-879A-BD3EFDA3A055} = {3DC51C40-03E9-5066-4FB5-FF3E41C97E1F} + {57832DF2-FD7F-4E26-AD7C-5D6608582978} = {33685B87-9DF7-C305-879A-BD3EFDA3A055} + {A3143C31-7C1C-4D7C-8819-3901238942C4} = {33685B87-9DF7-C305-879A-BD3EFDA3A055} + {BE4DDD77-798F-8692-0C2A-2A9637256ED2} = {F4CC2172-46F8-04D7-FF11-4F95DDBB59E2} + {7C1FC1A3-5E52-45A8-B136-0934ADD5580C} = {BE4DDD77-798F-8692-0C2A-2A9637256ED2} + {37B0CE47-14C8-F5BF-BDDD-13EEBE580A88} = {898C8C6E-FC1C-58E1-FB62-BBE77ED42888} + {6CFDFF50-A41A-4A5E-A66A-670DB707495F} = {37B0CE47-14C8-F5BF-BDDD-13EEBE580A88} + {7F099BC4-FAF9-0D5C-A860-45BB7185CE13} = {4CBFCE90-00AC-3F19-DC8C-C81357708F76} + {2C7B96D1-085F-4BCA-8D7D-3047765E3492} = {7F099BC4-FAF9-0D5C-A860-45BB7185CE13} + {B3167A7D-CF85-4A5F-B1CF-F14013782F1D} = {7F099BC4-FAF9-0D5C-A860-45BB7185CE13} + {1801FC80-908A-890E-88E4-ACF8F9AFE528} = {557B0DD6-D749-3FB3-AE6F-6C9843ACC451} + {73372025-CB29-4EF4-95A9-0CAF91D94439} = {1801FC80-908A-890E-88E4-ACF8F9AFE528} + {35D2CE3D-B792-49E1-BB6D-532313196821} = {1801FC80-908A-890E-88E4-ACF8F9AFE528} + {D8A7DFC5-CCD4-4A12-4328-1AC572B64833} = {C6CEF4FB-0C38-F8A1-C3A9-84AA43EDFA2E} + {A2F1FFAF-0BE1-4020-B09B-3DFB91B48816} = {D8A7DFC5-CCD4-4A12-4328-1AC572B64833} + {29F1A95F-AE4F-0723-BE37-14C42415E8D9} = {38F57492-853E-43AB-A96A-0D16B88231B6} + {3D69D7BE-8C92-4690-B4B2-5EC6F439A2A2} = {29F1A95F-AE4F-0723-BE37-14C42415E8D9} + {6233A7A4-85F2-4458-A14A-BF35117347B0} = {29F1A95F-AE4F-0723-BE37-14C42415E8D9} + {0F04000E-CD22-741D-E99C-16D60B397F54} = {1ED11E6E-94A0-E908-ACE4-8E9BD19CC7E1} + {9BE18521-31F9-45AD-A6EE-74695754EC0C} = {0F04000E-CD22-741D-E99C-16D60B397F54} + {F90633BA-133F-42E3-88D5-EE4DE0FB0586} = {0F04000E-CD22-741D-E99C-16D60B397F54} + {7331D996-A74A-CB9F-1FD5-3D31CD825A37} = {84B02E00-2E23-1547-B733-D86A059C7EE0} + {DE85A82A-CC7A-4743-B6FE-7259B152EF26} = {7331D996-A74A-CB9F-1FD5-3D31CD825A37} + {8066FB34-4946-4A49-B3EC-E0E1D28760D1} = {7331D996-A74A-CB9F-1FD5-3D31CD825A37} + {1474C41C-43C3-EE73-1D18-99B5FE232042} = {AB4067EC-C276-E50A-4A3C-F9DDFC3B9D29} + {E5F6A7B8-90CD-EF12-3456-7890ABCDEF01} = {1474C41C-43C3-EE73-1D18-99B5FE232042} + {F6A7B890-CDEF-1234-5678-90ABCDEF0123} = {1474C41C-43C3-EE73-1D18-99B5FE232042} + {AE64BB99-52FC-85C8-81F2-9C84ECFCBB2D} = {C64ABA23-B3DB-4B75-3019-7CBBB134BB29} + {8EAD1CA0-DD5D-493A-A6A4-45DD8E6835EA} = {AE64BB99-52FC-85C8-81F2-9C84ECFCBB2D} + {9457321A-9019-41E8-9E80-309D76EF2BAF} = {AE64BB99-52FC-85C8-81F2-9C84ECFCBB2D} + {E03D2171-C4AB-45A3-681D-A2A2EBBB122A} = {ED9D3D4A-502F-41A4-BBCC-970E65472F33} + {9A72A0E3-091A-4C64-AE66-ADAA5B46B1E8} = {E03D2171-C4AB-45A3-681D-A2A2EBBB122A} + {F3F49C7E-9106-4FF7-A71D-442022D63F7B} = {E03D2171-C4AB-45A3-681D-A2A2EBBB122A} + {D38B6103-E564-8894-9748-4CF0C62984DB} = {B28A9B67-1C09-C756-C02A-7AC1895F9584} + {0A09784C-BB49-44E8-B07A-DA4EEEC1184E} = {D38B6103-E564-8894-9748-4CF0C62984DB} + {F5980D17-1A14-4DD9-82DF-6496E0C4B70D} = {D38B6103-E564-8894-9748-4CF0C62984DB} + {447CAF13-A1DE-A946-989B-DD6CAA0CDF92} = {90CD12FE-21C2-5151-E041-9FB96A3D0773} + {4F0C9315-FBE2-4A98-9FD1-66F508398DEF} = {447CAF13-A1DE-A946-989B-DD6CAA0CDF92} + {C031D592-96D6-44D0-BF31-33CCE5CAABA1} = {447CAF13-A1DE-A946-989B-DD6CAA0CDF92} + {294AC723-70DA-F50A-2C7A-AC6C0AEA0A62} = {9072C7AF-9EB2-E481-3974-77957587AC76} + {D3F46C2D-3AFD-FD9C-9C6A-180B1514DD2F} = {294AC723-70DA-F50A-2C7A-AC6C0AEA0A62} + {BF0354AE-3748-A8DC-F79D-B21FDDEDDFAE} = {37B0CE47-14C8-F5BF-BDDD-13EEBE580A88} + {3A04D5F6-EC54-0CD0-A628-F5EFBCB2AD91} = {07C2787E-EAC7-C090-1BA3-A61EC2A24D84} + {73BD3F55-13D5-9E06-C2A4-90F58F874C43} = {3A04D5F6-EC54-0CD0-A628-F5EFBCB2AD91} + {5CF09A5B-85A2-41B2-8A51-E7F2ED03B77A} = {73BD3F55-13D5-9E06-C2A4-90F58F874C43} + {F7BA6D31-5AD0-005E-585A-02B38D7B7DEE} = {3A04D5F6-EC54-0CD0-A628-F5EFBCB2AD91} + {A5B0CAC9-2FCF-4AA2-9C02-655035284FCD} = {F7BA6D31-5AD0-005E-585A-02B38D7B7DEE} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {926577F9-9246-44E4-BCE9-25DB003F1C51} + EndGlobalSection +EndGlobal diff --git a/servers/Azure.Mcp.Server/docs/azmcp-commands.md b/servers/Azure.Mcp.Server/docs/azmcp-commands.md index 965e40b45c..1ed7a1fb65 100644 --- a/servers/Azure.Mcp.Server/docs/azmcp-commands.md +++ b/servers/Azure.Mcp.Server/docs/azmcp-commands.md @@ -1059,10 +1059,9 @@ azmcp deploy iac rules get --deployment-tool \ # Get the ci/cd pipeline guidance # ❌ Destructive | ✅ Idempotent | ❌ OpenWorld | ✅ ReadOnly | ❌ Secret | ❌ LocalRequired -azmcp deploy pipeline guidance get [--use-azd-pipeline-config ] \ - [--organization-name ] \ - [--repository-name ] \ - [--github-environment-name ] +azmcp deploy pipeline guidance get [--is-azd-project ] \ + [--pipeline-platform ] \ + [--deploy-option ] # Get a deployment plan for a specific project # ❌ Destructive | ✅ Idempotent | ❌ OpenWorld | ✅ ReadOnly | ❌ Secret | ❌ LocalRequired @@ -1070,7 +1069,7 @@ azmcp deploy plan get --workspace-folder \ --project-name \ --target-app-service \ --provisioning-tool \ - [--azd-iac-options ] + [--iac-options ] ``` ### Azure Event Grid Operations diff --git a/servers/Azure.Mcp.Server/docs/e2eTestPrompts.md b/servers/Azure.Mcp.Server/docs/e2eTestPrompts.md index 9c4a4a98ab..c32383aeae 100644 --- a/servers/Azure.Mcp.Server/docs/e2eTestPrompts.md +++ b/servers/Azure.Mcp.Server/docs/e2eTestPrompts.md @@ -268,9 +268,9 @@ This file contains prompts used for end-to-end testing to ensure each tool is in |:----------|:----------| | deploy_app_logs_get | Show me the log of the application deployed by azd | | deploy_architecture_diagram_generate | Generate the azure architecture diagram for this application | -| deploy_iac_rules_get | Show me the rules to generate bicep scripts | -| deploy_pipeline_guidance_get | How can I create a CI/CD pipeline to deploy this app to Azure? | -| deploy_plan_get | Create a plan to deploy this application to azure | +| deploy_iac_rules_get | Show me the rules to generate bicep scripts for \ | +| deploy_pipeline_guidance_get | Help me set up a CI/CD pipeline to deploy to Azure. | +| deploy_plan_get | Scan my project carefully to identify all Azure-relevant resources, programming languages, frameworks, dependencies, and configuration files needed for deployment. Develop a provision-and-deploy plan and follow it to deploy my application to Azure. deployTool: azcli, IacType: Terraform, hosting service: Container Apps.| ## Azure Event Grid diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Azure.Mcp.Tools.Deploy.csproj b/tools/Azure.Mcp.Tools.Deploy/src/Azure.Mcp.Tools.Deploy.csproj index 542abb6976..12c5fbcd50 100644 --- a/tools/Azure.Mcp.Tools.Deploy/src/Azure.Mcp.Tools.Deploy.csproj +++ b/tools/Azure.Mcp.Tools.Deploy/src/Azure.Mcp.Tools.Deploy.csproj @@ -9,7 +9,6 @@ - @@ -20,7 +19,7 @@ - + diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Commands/Infrastructure/RulesGetCommand.cs b/tools/Azure.Mcp.Tools.Deploy/src/Commands/Infrastructure/RulesGetCommand.cs index 4d680b9a51..0be633d0e2 100644 --- a/tools/Azure.Mcp.Tools.Deploy/src/Commands/Infrastructure/RulesGetCommand.cs +++ b/tools/Azure.Mcp.Tools.Deploy/src/Commands/Infrastructure/RulesGetCommand.cs @@ -33,7 +33,7 @@ public sealed class RulesGetCommand(ILogger logger) public override string Description => """ - This tool offers guidelines for creating Bicep/Terraform files to deploy applications on Azure. The guidelines outline rules to improve the quality of Infrastructure as Code files, ensuring they are compatible with the azd tool and adhere to best practices. + This tool offers guidelines for creating Bicep/Terraform files to deploy applications on Azure as well as general Azure Resource Rules. The guidelines outline rules to improve the quality of Infrastructure as Code files and resource configurations, ensuring they are compatible with the azd tool or az cli and adhere to best practices. """; protected override void RegisterOptions(Command command) @@ -70,7 +70,7 @@ public override Task ExecuteAsync(CommandContext context, Parse .AddTag(DeployTelemetryTags.ComputeHostResources, options.ResourceTypes); var resourceTypes = options.ResourceTypes.Split(',') - .Select(rt => rt.Trim()) + .Select(rt => rt.Trim().ToLowerInvariant()) .Where(rt => !string.IsNullOrWhiteSpace(rt)) .ToArray(); diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Commands/Pipeline/GuidanceGetCommand.cs b/tools/Azure.Mcp.Tools.Deploy/src/Commands/Pipeline/GuidanceGetCommand.cs index d0a93809e3..01b7b273cd 100644 --- a/tools/Azure.Mcp.Tools.Deploy/src/Commands/Pipeline/GuidanceGetCommand.cs +++ b/tools/Azure.Mcp.Tools.Deploy/src/Commands/Pipeline/GuidanceGetCommand.cs @@ -24,7 +24,7 @@ public sealed class GuidanceGetCommand(ILogger logger) public override string Description => """ - Guidance to create a CI/CD pipeline which provision Azure resources and build and deploy applications to Azure. Use this tool BEFORE generating/creating a Github actions workflow file for DEPLOYMENT on Azure. Infrastructure files should be ready and the application should be ready to be containerized. + This tool helps create a CI/CD pipeline to deploy a project to Azure. BEFORE calling this tool, you MUST confirm with user 1. if they want to use Github Actions or ADO pipeline 2. if they have existing Azure resources to deploy for different environments. If user has existing Azure resources, *ASK* for subscription ID, resource groups, environments, Azure hosting service TYPEs. If user does not have existing resources, *ASK* whether to include provision in the pipeline. *DO NOT call this tool UNTIL you made these confirmations with user*. """; public override string Title => CommandTitle; @@ -41,19 +41,17 @@ public sealed class GuidanceGetCommand(ILogger logger) protected override void RegisterOptions(Command command) { base.RegisterOptions(command); - command.Options.Add(DeployOptionDefinitions.PipelineGenerateOptions.UseAZDPipelineConfig); - command.Options.Add(DeployOptionDefinitions.PipelineGenerateOptions.OrganizationName); - command.Options.Add(DeployOptionDefinitions.PipelineGenerateOptions.RepositoryName); - command.Options.Add(DeployOptionDefinitions.PipelineGenerateOptions.GithubEnvironmentName); + command.Options.Add(DeployOptionDefinitions.PipelineGenerateOptions.isAZDProject); + command.Options.Add(DeployOptionDefinitions.PipelineGenerateOptions.pipelinePlatform); + command.Options.Add(DeployOptionDefinitions.PipelineGenerateOptions.deployOption); } protected override GuidanceGetOptions BindOptions(ParseResult parseResult) { var options = base.BindOptions(parseResult); - options.UseAZDPipelineConfig = parseResult.GetValueOrDefault(DeployOptionDefinitions.PipelineGenerateOptions.UseAZDPipelineConfig.Name); - options.OrganizationName = parseResult.GetValueOrDefault(DeployOptionDefinitions.PipelineGenerateOptions.OrganizationName.Name); - options.RepositoryName = parseResult.GetValueOrDefault(DeployOptionDefinitions.PipelineGenerateOptions.RepositoryName.Name); - options.GithubEnvironmentName = parseResult.GetValueOrDefault(DeployOptionDefinitions.PipelineGenerateOptions.GithubEnvironmentName.Name); + options.IsAZDProject = parseResult.GetValueOrDefault(DeployOptionDefinitions.PipelineGenerateOptions.isAZDProject.Name); + options.PipelinePlatform = parseResult.GetValueOrDefault(DeployOptionDefinitions.PipelineGenerateOptions.pipelinePlatform.Name); + options.DeployOption = parseResult.GetValueOrDefault(DeployOptionDefinitions.PipelineGenerateOptions.deployOption.Name); return options; } diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Commands/Plan/GetCommand.cs b/tools/Azure.Mcp.Tools.Deploy/src/Commands/Plan/GetCommand.cs index 635aa28648..d3de119571 100644 --- a/tools/Azure.Mcp.Tools.Deploy/src/Commands/Plan/GetCommand.cs +++ b/tools/Azure.Mcp.Tools.Deploy/src/Commands/Plan/GetCommand.cs @@ -26,7 +26,7 @@ public sealed class GetCommand(ILogger logger) public override string Description => """ - Generates a deployment plan to construct the infrastructure and deploy the application on Azure. Agent should read its output and generate a deploy plan in '.azure/plan.copilotmd' for execution steps, recommended azure services based on the information agent detected from project. Before calling this tool, please scan this workspace to detect the services to deploy and their dependent services. + Entry point to help the agent deploy a service to the cloud. Agent should read its output and generate a deploy plan in '.azure/plan.${COPILOT_MD_EXTENSION}' for execution steps, recommended Azure services based on the information agent detected from project. Before calling this tool, scan this workspace to detect the services to deploy and their dependent services. If user has existing resources and only wants to deploy to existing resources, agent MUST first help user to pick existing Azure resources's ARM ID with Az CLI command or prompt user to provide! """; public override string Title => CommandTitle; @@ -47,7 +47,10 @@ protected override void RegisterOptions(Command command) command.Options.Add(DeployOptionDefinitions.PlanGet.ProjectName); command.Options.Add(DeployOptionDefinitions.PlanGet.TargetAppService); command.Options.Add(DeployOptionDefinitions.PlanGet.ProvisioningTool); - command.Options.Add(DeployOptionDefinitions.PlanGet.AzdIacOptions); + command.Options.Add(DeployOptionDefinitions.PlanGet.IacOptions); + command.Options.Add(DeployOptionDefinitions.PlanGet.SourceType); + command.Options.Add(DeployOptionDefinitions.PlanGet.DeployOption); + command.Options.Add(DeployOptionDefinitions.PlanGet.ResourceGroupName); } protected override GetOptions BindOptions(ParseResult parseResult) @@ -58,7 +61,10 @@ protected override GetOptions BindOptions(ParseResult parseResult) ProjectName = parseResult.GetValueOrDefault(DeployOptionDefinitions.PlanGet.ProjectName.Name) ?? string.Empty, TargetAppService = parseResult.GetValueOrDefault(DeployOptionDefinitions.PlanGet.TargetAppService.Name) ?? string.Empty, ProvisioningTool = parseResult.GetValueOrDefault(DeployOptionDefinitions.PlanGet.ProvisioningTool.Name) ?? string.Empty, - AzdIacOptions = parseResult.GetValueOrDefault(DeployOptionDefinitions.PlanGet.AzdIacOptions.Name) ?? string.Empty + IacOptions = parseResult.GetValueOrDefault(DeployOptionDefinitions.PlanGet.IacOptions.Name) ?? string.Empty, + SourceType = parseResult.GetValueOrDefault(DeployOptionDefinitions.PlanGet.SourceType.Name) ?? string.Empty, + DeployOption = parseResult.GetValueOrDefault(DeployOptionDefinitions.PlanGet.DeployOption.Name) ?? string.Empty, + ResourceGroupName = parseResult.GetValueOrDefault(DeployOptionDefinitions.PlanGet.ResourceGroupName.Name) ?? string.Empty }; } @@ -81,9 +87,11 @@ public override Task ExecuteAsync(CommandContext context, Parse context.Activity? .AddTag(DeployTelemetryTags.ComputeHostResources, options.TargetAppService) .AddTag(DeployTelemetryTags.DeploymentTool, options.ProvisioningTool) - .AddTag(DeployTelemetryTags.IacType, options.AzdIacOptions ?? string.Empty); + .AddTag(DeployTelemetryTags.IacType, options.IacOptions ?? string.Empty) + .AddTag(DeployTelemetryTags.DeployOption, options.DeployOption ?? string.Empty) + .AddTag(DeployTelemetryTags.SourceType, options.SourceType ?? string.Empty); - var planTemplate = DeploymentPlanTemplateUtil.GetPlanTemplate(options.ProjectName, options.TargetAppService, options.ProvisioningTool, options.AzdIacOptions); + var planTemplate = DeploymentPlanTemplateUtil.GetPlanTemplate(options.ProjectName, options.TargetAppService, options.ProvisioningTool, options.SourceType ?? string.Empty, options.DeployOption ?? string.Empty, options.IacOptions, options.Subscription, options.ResourceGroupName); context.Response.Message = planTemplate; context.Response.Status = HttpStatusCode.OK; diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Models/Consts.cs b/tools/Azure.Mcp.Tools.Deploy/src/Models/Consts.cs index 9d9374ceb4..cdc852f285 100644 --- a/tools/Azure.Mcp.Tools.Deploy/src/Models/Consts.cs +++ b/tools/Azure.Mcp.Tools.Deploy/src/Models/Consts.cs @@ -48,6 +48,8 @@ public static class DeployTelemetryTags public static readonly string ComputeHostResources = AddPrefix("ComputeHostResources"); public static readonly string DeploymentTool = AddPrefix("DeploymentTool"); public static readonly string IacType = AddPrefix("IacType"); + public static readonly string DeployOption = AddPrefix("DeployOption"); + public static readonly string SourceType = AddPrefix("SourceType"); public static readonly string ProjectName = AddPrefix("ProjectName"); public static readonly string ServiceCount = AddPrefix("ServiceCount"); public static readonly string BackingServiceResources = AddPrefix("BackingServiceResources"); diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Models/IaCRulesParameters.cs b/tools/Azure.Mcp.Tools.Deploy/src/Models/IaCRulesParameters.cs index a44221ea4d..c1c11f4a09 100644 --- a/tools/Azure.Mcp.Tools.Deploy/src/Models/IaCRulesParameters.cs +++ b/tools/Azure.Mcp.Tools.Deploy/src/Models/IaCRulesParameters.cs @@ -7,6 +7,13 @@ public static class DeploymentTool public const string AzCli = "AzCli"; } +public static class SourceType +{ + public const string FromAzure = "from-azure"; + public const string FromProject = "from-project"; + public const string FromContext = "from-context"; +} + public static class IacType { public const string Bicep = "bicep"; @@ -18,5 +25,11 @@ public static class AzureServiceNames public const string AzureContainerApp = "containerapp"; public const string AzureAppService = "appservice"; public const string AzureFunctionApp = "function"; - public const string AzureStorage = "storage"; + public const string AzureKubernetesService = "aks"; + public const string AzureDatabaseForPostgreSql = "azuredatabaseforpostgresql"; + public const string AzureDatabaseForMySql = "azuredatabaseformysql"; + public const string AzureSqlDatabase = "azuresqldatabase"; + public const string AzureCosmosDb = "azurecosmosdb"; + public const string AzureStorageAccount = "azurestorageaccount"; + public const string AzureKeyVault = "azurekeyvault"; } diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Models/PipelineParameters.cs b/tools/Azure.Mcp.Tools.Deploy/src/Models/PipelineParameters.cs new file mode 100644 index 0000000000..014c61e7d1 --- /dev/null +++ b/tools/Azure.Mcp.Tools.Deploy/src/Models/PipelineParameters.cs @@ -0,0 +1,14 @@ +namespace Azure.Mcp.Tools.Deploy.Models; + +public static class DeployOption +{ + public const string ProvisionAndDeploy = "provision-and-deploy"; + public const string DeployOnly = "deploy-only"; + public const string ProvisionOnly = "provision-only"; +} + +public static class PipelinePlatform +{ + public const string GitHubActions = "github-actions"; + public const string AzureDevOps = "azure-devops"; +} diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Models/Templates/CLIExecutionStepsTemplateParameters.cs b/tools/Azure.Mcp.Tools.Deploy/src/Models/Templates/CLIExecutionStepsTemplateParameters.cs new file mode 100644 index 0000000000..2c57c218ea --- /dev/null +++ b/tools/Azure.Mcp.Tools.Deploy/src/Models/Templates/CLIExecutionStepsTemplateParameters.cs @@ -0,0 +1,52 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +namespace Azure.Mcp.Tools.Deploy.Models.Templates; + +/// +/// Parameters for generating deployment plan templates. +/// +public sealed class CLIExecutionStepsTemplateParameters +{ + /// + /// The azure compute host display name. + /// + public string AzureComputeHost { get; set; } = string.Empty; + + /// + /// The azure cli command group title + /// + public string TargetAppCommandTitle { get; set; } = string.Empty; + + /// + /// The deployment steps + /// + public string DeploymentSteps { get; set; } = string.Empty; + + /// + /// The IaC type + /// + public string IaCType { get; set; } = string.Empty; + + /// + /// The step to check ACR dependencies + /// + public string ACRDependencyCheck { get; set; } = string.Empty; + + + /// + /// Converts the parameters to a dictionary for template processing. + /// + /// A dictionary with parameter names as keys and their values. + public Dictionary ToDictionary() + { + return new Dictionary + { + { nameof(IaCType), IaCType }, + { nameof(AzureComputeHost), AzureComputeHost }, + { nameof(TargetAppCommandTitle), TargetAppCommandTitle }, + { nameof(DeploymentSteps), DeploymentSteps }, + { nameof(ACRDependencyCheck), ACRDependencyCheck } + }; + } +} diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Models/Templates/DeploymentPlanTemplateParameters.cs b/tools/Azure.Mcp.Tools.Deploy/src/Models/Templates/DeploymentPlanTemplateParameters.cs index 323cb04694..b374c2a952 100644 --- a/tools/Azure.Mcp.Tools.Deploy/src/Models/Templates/DeploymentPlanTemplateParameters.cs +++ b/tools/Azure.Mcp.Tools.Deploy/src/Models/Templates/DeploymentPlanTemplateParameters.cs @@ -43,6 +43,32 @@ public sealed class DeploymentPlanTemplateParameters /// public string ExecutionSteps { get; set; } = string.Empty; + + /// + /// The source of the plan to generate from. + /// + public string SourceType { get; set; } = string.Empty; + + /// + /// The deploy option selected. + /// + public string DeployOption { get; set; } = string.Empty; + + /// + /// The deployment goal of the plan + /// + public string Goal { get; set; } = string.Empty; + + /// + /// The recommended resources or the existing(missing) resources + /// + public string ResourceInfo { get; set; } = string.Empty; + + /// + /// The sample mermaid diagram for the deployment plan. + /// + public string SampleMermaid { get; set; } = string.Empty; + /// /// Converts the parameters to a dictionary for template processing. /// @@ -58,6 +84,11 @@ public Dictionary ToDictionary() { nameof(IacType), IacType }, { nameof(AzureComputeHost), AzureComputeHost }, { nameof(ExecutionSteps), ExecutionSteps }, + { nameof(SourceType), SourceType }, + { nameof(DeployOption), DeployOption }, + { nameof(Goal), Goal }, + { nameof(ResourceInfo), ResourceInfo }, + { nameof(SampleMermaid), SampleMermaid } }; } } diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Models/Templates/IaCRulesTemplateParameters.cs b/tools/Azure.Mcp.Tools.Deploy/src/Models/Templates/IaCRulesTemplateParameters.cs index 590dd56fc8..905f943dcd 100644 --- a/tools/Azure.Mcp.Tools.Deploy/src/Models/Templates/IaCRulesTemplateParameters.cs +++ b/tools/Azure.Mcp.Tools.Deploy/src/Models/Templates/IaCRulesTemplateParameters.cs @@ -18,13 +18,6 @@ public sealed class IaCRulesTemplateParameters public string FinalInstructions { get; set; } = string.Empty; public string RequiredTools { get; set; } = string.Empty; public string AdditionalNotes { get; set; } = string.Empty; - public string OutputFileName { get; set; } = string.Empty; - public string ContainerRegistryOutput { get; set; } = string.Empty; - public string RoleAssignmentResource { get; set; } = string.Empty; - public string ImageProperty { get; set; } = string.Empty; - public string CorsConfiguration { get; set; } = string.Empty; - public string LogAnalyticsConfiguration { get; set; } = string.Empty; - public string DiagnosticSettingsResource { get; set; } = string.Empty; /// /// Converts the parameters to a dictionary for template processing. @@ -42,14 +35,7 @@ public Dictionary ToDictionary() { nameof(ResourceSpecificRules), ResourceSpecificRules }, { nameof(FinalInstructions), FinalInstructions }, { nameof(RequiredTools), RequiredTools }, - { nameof(AdditionalNotes), AdditionalNotes }, - { nameof(OutputFileName), OutputFileName }, - { nameof(ContainerRegistryOutput), ContainerRegistryOutput }, - { nameof(RoleAssignmentResource), RoleAssignmentResource }, - { nameof(ImageProperty), ImageProperty }, - { nameof(CorsConfiguration), CorsConfiguration }, - { nameof(LogAnalyticsConfiguration), LogAnalyticsConfiguration }, - { nameof(DiagnosticSettingsResource), DiagnosticSettingsResource }, + { nameof(AdditionalNotes), AdditionalNotes } }; } } diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Models/Templates/PipelineTemplateParameters.cs b/tools/Azure.Mcp.Tools.Deploy/src/Models/Templates/PipelineTemplateParameters.cs index 58f03ecd1e..27fc91967a 100644 --- a/tools/Azure.Mcp.Tools.Deploy/src/Models/Templates/PipelineTemplateParameters.cs +++ b/tools/Azure.Mcp.Tools.Deploy/src/Models/Templates/PipelineTemplateParameters.cs @@ -8,30 +8,19 @@ namespace Azure.Mcp.Tools.Deploy.Models.Templates; /// public sealed class PipelineTemplateParameters { - /// - /// Environment name prompt text. - /// - public string EnvironmentNamePrompt { get; set; } = string.Empty; + public string DeploymentTool { get; set; } = string.Empty; - /// - /// Subscription ID prompt text. - /// - public string SubscriptionIdPrompt { get; set; } = string.Empty; + public string PipelinePlatform { get; set; } = string.Empty; - /// - /// GitHub environment create command. - /// - public string EnvironmentCreateCommand { get; set; } = string.Empty; + public string PrerequisiteChecksPrompt { get; set; } = string.Empty; - /// - /// JSON parameters for federated credentials. - /// - public string JsonParameters { get; set; } = string.Empty; + public string PipelineFilePrompt { get; set; } = string.Empty; - /// - /// Environment argument for GitHub CLI commands. - /// - public string EnvironmentArg { get; set; } = string.Empty; + public string SetupMethodPrompt { get; set; } = string.Empty; + + public string AzureAuthConfigPrompt { get; set; } = string.Empty; + + public string EnvironmentSetupPrompt { get; set; } = string.Empty; /// /// Converts the parameters to a dictionary for template processing. @@ -41,11 +30,13 @@ public Dictionary ToDictionary() { return new Dictionary { - { nameof(EnvironmentNamePrompt), EnvironmentNamePrompt }, - { nameof(SubscriptionIdPrompt), SubscriptionIdPrompt }, - { nameof(EnvironmentCreateCommand), EnvironmentCreateCommand }, - { nameof(JsonParameters), JsonParameters }, - { nameof(EnvironmentArg), EnvironmentArg } + { nameof(DeploymentTool), DeploymentTool }, + { nameof(PipelinePlatform), PipelinePlatform }, + { nameof(PrerequisiteChecksPrompt), PrerequisiteChecksPrompt }, + { nameof(PipelineFilePrompt), PipelineFilePrompt }, + { nameof(SetupMethodPrompt), SetupMethodPrompt }, + { nameof(AzureAuthConfigPrompt), AzureAuthConfigPrompt }, + { nameof(EnvironmentSetupPrompt), EnvironmentSetupPrompt } }; } } diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Options/DeployOptionDefinitions.cs b/tools/Azure.Mcp.Tools.Deploy/src/Options/DeployOptionDefinitions.cs index df7c550a41..c6c2a8042f 100644 --- a/tools/Azure.Mcp.Tools.Deploy/src/Options/DeployOptionDefinitions.cs +++ b/tools/Azure.Mcp.Tools.Deploy/src/Options/DeployOptionDefinitions.cs @@ -56,53 +56,49 @@ public class AzdAppLogOptions : SubscriptionOptions public class PipelineGenerateOptions : SubscriptionOptions { - public const string UseAZDPipelineConfigName = "use-azd-pipeline-config"; - public const string OrganizationNameName = "organization-name"; - public const string RepositoryNameName = "repository-name"; - public const string GithubEnvironmentNameName = "github-environment-name"; + public const string isAZDProjectName = "is-azd-project"; + public const string PipelinePlatformName = "pipeline-platform"; - public static readonly Option UseAZDPipelineConfig = new( - $"--{UseAZDPipelineConfigName}" - ) - { - Description = "Whether to use azd tool to set up the deployment pipeline. Set to true ONLY if azure.yaml is provided or the context suggests AZD tools.", - DefaultValueFactory = _ => false, - Required = false - }; + public const string DeployOptionName = "deploy-option"; - public static readonly Option OrganizationName = new( - $"--{OrganizationNameName}" + public static readonly Option isAZDProject = new( + $"--{isAZDProjectName}" ) { - Description = "The name of the organization or the user account name of the current Github repository. DO NOT fill this in if you're not sure.", - Required = false + Description = "Whether to use azd tool in the deployment pipeline. Set to true ONLY if azure.yaml is provided or the context suggests AZD tools.", + DefaultValueFactory = _ => false, + Required = true }; - public static readonly Option RepositoryName = new( - $"--{RepositoryNameName}" + public static readonly Option pipelinePlatform = new( + $"--{PipelinePlatformName}" ) { - Description = "The name of the current Github repository. DO NOT fill this in if you're not sure.", - Required = false + Description = "The platform for the deployment pipeline. Valid values: github-actions, azure-devops.", + DefaultValueFactory = _ => "github-actions", + Required = true, }; - public static readonly Option GithubEnvironmentName = new( - $"--{GithubEnvironmentNameName}" + public static readonly Option deployOption = new( + $"--{DeployOptionName}" ) { - Description = "The name of the environment to which the deployment pipeline will be deployed. DO NOT fill this in if you're not sure.", - Required = false + Description = "Valid values: deploy-only, provision-and-deploy. Default to deploy-only. Set to 'provision-and-deploy' ONLY WHEN user explicitly wants infra provisioning pipeline using local provisioning scripts.", + DefaultValueFactory = _ => "deploy-only", + Required = true }; - } - public static class PlanGet + public class PlanGet : SubscriptionOptions { public const string WorkspaceFolderName = "workspace-folder"; public const string ProjectNameName = "project-name"; public const string TargetAppServiceName = "target-app-service"; public const string ProvisioningToolName = "provisioning-tool"; - public const string AzdIacOptionsName = "azd-iac-options"; + public const string IacOptionsName = "iac-options"; + public const string SourceTypeName = "source-type"; + public const string DeployOptionName = "deploy-option"; + public const string ResourceGroupNameName = "resource-group-name"; public static readonly Option WorkspaceFolder = new( $"--{WorkspaceFolderName}" @@ -132,15 +128,42 @@ public static class PlanGet $"--{ProvisioningToolName}" ) { - Description = "The tool to use for provisioning Azure resources. Valid values: AZD, AzCli. Use AzCli if TargetAppService is AKS.", + Description = "The tool to use for provisioning Azure resources. Valid values: AzCli, AZD.", + Required = true, + DefaultValueFactory = _ => "AzCli" + }; + + public static readonly Option IacOptions = new( + $"--{IacOptionsName}" + ) + { + Description = "The Infrastructure as Code option. Valid values: bicep, terraform. Leave empty if user wants to use azcli command script.", + Required = false + }; + + public static readonly Option SourceType = new( + $"--{SourceTypeName}" + ) + { + Description = "The source of the plan to generate from. Valid values: 'from-project', 'from-azure', 'from-context'. If user doesn't have existing resources, set 'from-project' and generating deploy plan based on the project files in the workspace. If user mentions Azure resources exist, set 'from-azure' and ask for existing Azure resources details to generate plan. If the user have no existing resource but declare the expected Azure resources, use 'from-context' and the deploy plan should be based on the user's input.", + DefaultValueFactory = _ => "from-project", Required = true }; - public static readonly Option AzdIacOptions = new( - $"--{AzdIacOptionsName}" + public static readonly Option DeployOption = new( + $"--{DeployOptionName}" ) { - Description = "The Infrastructure as Code option for azd. Valid values: bicep, terraform. Leave empty if Deployment tool is AzCli.", + Description = "Set the value based on project and user's input. Valid values: 'provision-and-deploy', 'deploy-only', 'provision-only'. Use 'deploy-only' if user mentions they want to deploy to existing Azure resources or Iac files already exist in project, get Azure resource group from project files or from user. Use 'provision-only' if user only wants to provision Azure resource. Use 'provision-and-deploy' if user wants to deploy application and doesn't have existing infrastructure resources, or are starting from an empty resource group.", + DefaultValueFactory = _ => "provision-and-deploy", + Required = true + }; + + public static readonly Option ResourceGroupName = new( + $"--{ResourceGroupNameName}" + ) + { + Description = "The Azure resource group name to use for the deployment. If user has existing resources, agent must use existing resource's resource group, ask for user's confirmation before using its resource group name. Don't use a placeholder or mock a value.", Required = false }; } @@ -150,7 +173,7 @@ public static class IaCRules public static readonly Option DeploymentTool = new( "--deployment-tool") { - Description = "The deployment tool to use. Valid values: AZD, AzCli", + Description = "The deployment tool to use. Valid values: AzCli, AZD", Required = true }; @@ -158,16 +181,14 @@ public static class IaCRules "--iac-type" ) { - Description = "The Infrastructure as Code type. Valid values: bicep, terraform. Leave empty if deployment-tool is AzCli.", + Description = "The type of IaC file used for deployment. Valid values: bicep, terraform. Leave empty ONLY if user wants to use AzCli command script and no IaC file.", Required = false - - }; public static readonly Option ResourceTypes = new( "--resource-types") { - Description = "Specifies the Azure resource types to retrieve IaC rules for. It should be comma-separated. Supported values are: 'appservice', 'containerapp', 'function', 'aks', 'storage'. If none of these services are used, this parameter can be left empty.", + Description = "List of Azure resource types to generate rules for. Get the value from context and use the same resources defined in plan. Valid value: 'appservice','containerapp','function','aks','azuredatabaseforpostgresql','azuredatabaseformysql','azuresqldatabase','azurecosmosdb','azurestorageaccount','azurekeyvault'", Required = false, AllowMultipleArgumentsPerToken = true }; diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Options/Pipeline/GuidanceGetOptions.cs b/tools/Azure.Mcp.Tools.Deploy/src/Options/Pipeline/GuidanceGetOptions.cs index 01767dd4da..6bca3909b8 100644 --- a/tools/Azure.Mcp.Tools.Deploy/src/Options/Pipeline/GuidanceGetOptions.cs +++ b/tools/Azure.Mcp.Tools.Deploy/src/Options/Pipeline/GuidanceGetOptions.cs @@ -8,15 +8,12 @@ namespace Azure.Mcp.Tools.Deploy.Options.Pipeline; public class GuidanceGetOptions : SubscriptionOptions { - [JsonPropertyName("useAZDPipelineConfig")] - public bool UseAZDPipelineConfig { get; set; } + [JsonPropertyName("isAZDProject")] + public bool IsAZDProject { get; set; } - [JsonPropertyName("organizationName")] - public string? OrganizationName { get; set; } + [JsonPropertyName("pipelinePlatform")] + public string? PipelinePlatform { get; set; } - [JsonPropertyName("repositoryName")] - public string? RepositoryName { get; set; } - - [JsonPropertyName("githubEnvironmentName")] - public string? GithubEnvironmentName { get; set; } + [JsonPropertyName("deployOption")] + public string? DeployOption { get; set; } } diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Options/Plan/GetOptions.cs b/tools/Azure.Mcp.Tools.Deploy/src/Options/Plan/GetOptions.cs index ec2c7c2c97..ce71b6d666 100644 --- a/tools/Azure.Mcp.Tools.Deploy/src/Options/Plan/GetOptions.cs +++ b/tools/Azure.Mcp.Tools.Deploy/src/Options/Plan/GetOptions.cs @@ -2,10 +2,11 @@ // Licensed under the MIT License. using System.Text.Json.Serialization; +using Azure.Mcp.Core.Options; namespace Azure.Mcp.Tools.Deploy.Options.Plan; -public sealed class GetOptions +public sealed class GetOptions : SubscriptionOptions { [JsonPropertyName("workspaceFolder")] public string WorkspaceFolder { get; set; } = string.Empty; @@ -19,6 +20,15 @@ public sealed class GetOptions [JsonPropertyName("provisioningTool")] public string ProvisioningTool { get; set; } = string.Empty; - [JsonPropertyName("azdIacOptions")] - public string? AzdIacOptions { get; set; } = string.Empty; + [JsonPropertyName("sourceType")] + public string SourceType { get; set; } = string.Empty; + + [JsonPropertyName("deployOption")] + public string DeployOption { get; set; } = string.Empty; + + [JsonPropertyName("iacOptions")] + public string? IacOptions { get; set; } = string.Empty; + + [JsonPropertyName("resourceGroupName")] + public string? ResourceGroupName { get; set; } = string.Empty; } diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Services/Util/DeploymentPlanTemplateUtil.cs b/tools/Azure.Mcp.Tools.Deploy/src/Services/Util/DeploymentPlanTemplateUtil.cs index 142e7252c6..9c27b36e8f 100644 --- a/tools/Azure.Mcp.Tools.Deploy/src/Services/Util/DeploymentPlanTemplateUtil.cs +++ b/tools/Azure.Mcp.Tools.Deploy/src/Services/Util/DeploymentPlanTemplateUtil.cs @@ -18,20 +18,22 @@ public static class DeploymentPlanTemplateUtil /// The name of the project. Can be null or empty. /// The target Azure service. /// The provisioning tool. - /// The Infrastructure as Code options for AZD. + /// The Infrastructure as Code options for AZD. /// A formatted deployment plan template string. - public static string GetPlanTemplate(string projectName, string targetAppService, string provisioningTool, string? azdIacOptions = "") + public static string GetPlanTemplate(string projectName, string targetAppService, string provisioningTool, string sourceType, string deployOption, string? iacOptions, string? subscriptionId, string? resourceGroupName) { // Default values for optional parameters - if (provisioningTool == "azd" && string.IsNullOrWhiteSpace(azdIacOptions)) + if (provisioningTool == "azd" && string.IsNullOrWhiteSpace(iacOptions)) { - azdIacOptions = "bicep"; + iacOptions = "bicep"; } - DeploymentPlanTemplateParameters parameters = CreateTemplateParameters(projectName, targetAppService, provisioningTool, azdIacOptions); + DeploymentPlanTemplateParameters parameters = CreateTemplateParameters(projectName, targetAppService, provisioningTool, sourceType, deployOption, iacOptions, subscriptionId, resourceGroupName); + var resourceInfo = GenerateResourceInfo(parameters); var executionSteps = GenerateExecutionSteps(parameters); parameters.ExecutionSteps = executionSteps; + parameters.ResourceInfo = resourceInfo; return TemplateService.ProcessTemplate("Plan/deployment-plan-base", parameters.ToDictionary()); } @@ -43,21 +45,66 @@ private static DeploymentPlanTemplateParameters CreateTemplateParameters( string projectName, string targetAppService, string provisioningTool, - string? azdIacOptions) + string sourceType, + string deployOption, + string? iacOptions, + string? subscriptionId, + string? resourceGroupName) { var azureComputeHost = GetAzureComputeHost(targetAppService); var title = string.IsNullOrWhiteSpace(projectName) ? "Azure Deployment Plan" : $"Azure Deployment Plan for {projectName} Project"; + if (deployOption == DeployOption.DeployOnly) + { + provisioningTool = DeploymentTool.AzCli; + sourceType = SourceType.FromAzure; + } + + if (deployOption == DeployOption.ProvisionOnly) + { + provisioningTool = DeploymentTool.AzCli; + } + + var fallbackIaCTypeDescription = ""; + if (string.IsNullOrEmpty(iacOptions) && (deployOption == DeployOption.ProvisionOnly || deployOption == DeployOption.ProvisionAndDeploy)) + { + iacOptions = targetAppService.ToLowerInvariant() == "aks" ? IacType.Terraform : IacType.Bicep; + fallbackIaCTypeDescription = $" Since the IaC option is not specified, we will use ${iacOptions} as the IaC option based on the target app services."; + } + + var goal = sourceType == SourceType.FromAzure ? + $"Based on the project to provide a plan to deploy the project to Azure ${targetAppService} in resource group ${resourceGroupName ?? "YOUR RG"} and subscription ${subscriptionId ?? "YOUR SUBSCRIPTION"} with tool ${provisioningTool.ToUpperInvariant()}.${fallbackIaCTypeDescription}" : + $"Based on the project to provide a plan to deploy the project to Azure using ${provisioningTool.ToUpperInvariant()}.${fallbackIaCTypeDescription}"; + + if (deployOption == DeployOption.ProvisionOnly) + { + goal = $"Provide a plan to provision Azure resources for the project with ${provisioningTool.ToUpperInvariant()}${(string.IsNullOrEmpty(iacOptions) ? "" : " and " + iacOptions)}.${fallbackIaCTypeDescription}"; + } + + var sampleMermaid = ""; + if (targetAppService.ToLowerInvariant() == "aks") + { + sampleMermaid = TemplateService.LoadTemplate("Plan/sample-aks-mermaid"); + } + else + { + sampleMermaid = TemplateService.LoadTemplate("Plan/sample-app-mermaid"); + } + return new DeploymentPlanTemplateParameters { Title = title, ProjectName = projectName, TargetAppService = targetAppService, ProvisioningTool = provisioningTool, - IacType = azdIacOptions ?? "bicep", + IacType = iacOptions ?? "", AzureComputeHost = azureComputeHost, + SourceType = sourceType, + DeployOption = deployOption, + Goal = goal, + SampleMermaid = sampleMermaid }; } @@ -136,39 +183,78 @@ private static List GenerateAzdSteps(DeploymentPlanTemplateParameters pa private static List GenerateAzCliSteps(DeploymentPlanTemplateParameters parameters, bool isAks) { var steps = new List(); - - steps.Add(TemplateService.LoadTemplate("Plan/azcli-steps")); - if (isAks) { - steps.Add(TemplateService.LoadTemplate("Plan/aks-steps")); + if (parameters.DeployOption == DeployOption.DeployOnly) + { + steps.Add(TemplateService.LoadTemplate("Plan/aks-deploy-only-steps")); + } + else + { + steps.Add(TemplateService.LoadTemplate("Plan/aks-provision-steps")); + if (parameters.DeployOption == DeployOption.ProvisionAndDeploy) + { + steps.Add(TemplateService.LoadTemplate("Plan/aks-deployment-steps")); + } + } } else { - var isContainerApp = parameters.TargetAppService.ToLowerInvariant() == "containerapp"; - if (isContainerApp) + var cliDeploymentSteps = ""; + if (parameters.TargetAppService.ToLowerInvariant() == "containerapp" && parameters.DeployOption != DeployOption.ProvisionOnly) { - var containerAppReplacements = new Dictionary - { - { "AzureComputeHost", parameters.AzureComputeHost } - }; - steps.Add(TemplateService.ProcessTemplate("Plan/containerapp-steps", containerAppReplacements)); + steps.Add(TemplateService.LoadTemplate("Plan/containerization-steps")); + cliDeploymentSteps = "1. Create deploy script (build + push image to ACR, deploy to Azure Container App).\n2. Run the script and fix it until it works."; + } + else + { + cliDeploymentSteps = "1. Create deploy script to deploy the application with Azure CLI."; + } + + var cliParameters = new CLIExecutionStepsTemplateParameters + { + IaCType = parameters.IacType.ToLowerInvariant(), + AzureComputeHost = parameters.AzureComputeHost, + TargetAppCommandTitle = parameters.TargetAppService, + DeploymentSteps = cliDeploymentSteps, + ACRDependencyCheck = parameters.TargetAppService.ToLowerInvariant() == "containerapp" + ? "- Check Azure Container Registry:\n- login server: <>. Check with \'az acr show -o json\'." + : "" + }; + + if (parameters.DeployOption == DeployOption.DeployOnly) + { + steps.Add(TemplateService.ProcessTemplate("Plan/azcli-deploy-only-steps", cliParameters.ToDictionary())); } else { - // For other app services, generate basic deployment steps - var basicSteps = $""" - 2. Build and Deploy the Application: - 1. Deploy to {parameters.AzureComputeHost}: Use Azure CLI command to deploy the application - 3. Validation: - 1. Verify command output to ensure the application is deployed successfully - """; - steps.Add(basicSteps); + steps.Add(TemplateService.ProcessTemplate("Plan/azcli-provision-steps", cliParameters.ToDictionary())); + if (parameters.DeployOption == DeployOption.ProvisionAndDeploy) + { + steps.Add(TemplateService.ProcessTemplate("Plan/azcli-deployment-steps", cliParameters.ToDictionary())); + } } } - steps.Add(TemplateService.ProcessTemplate("Plan/summary-steps", new Dictionary { { "StepNumber", "4" } })); + steps.Add(TemplateService.LoadTemplate("Plan/summary-steps")); return steps; + + } + + private static string GenerateResourceInfo(DeploymentPlanTemplateParameters parameters) + { + if (parameters.DeployOption == DeployOption.DeployOnly) + { + return TemplateService.LoadTemplate("Plan/existing-resource-info"); + } + else + { + return TemplateService.ProcessTemplate("Plan/provision-info", new Dictionary + { + { "ProjectName", parameters.ProjectName }, + { "AzureComputeHost", parameters.AzureComputeHost } + }); + } } } diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Services/Util/IaCRulesTemplateUtil.cs b/tools/Azure.Mcp.Tools.Deploy/src/Services/Util/IaCRulesTemplateUtil.cs index 27456bc731..b0a132852b 100644 --- a/tools/Azure.Mcp.Tools.Deploy/src/Services/Util/IaCRulesTemplateUtil.cs +++ b/tools/Azure.Mcp.Tools.Deploy/src/Services/Util/IaCRulesTemplateUtil.cs @@ -4,6 +4,9 @@ using Azure.Mcp.Tools.Deploy.Models; using Azure.Mcp.Tools.Deploy.Models.Templates; using Azure.Mcp.Tools.Deploy.Services.Templates; +using Microsoft.AspNetCore.DataProtection; +using ModelContextProtocol.Protocol; +using YamlDotNet.Core.Tokens; namespace Azure.Mcp.Tools.Deploy.Services.Util; @@ -12,6 +15,8 @@ namespace Azure.Mcp.Tools.Deploy.Services.Util; /// public static class IaCRulesTemplateUtil { + private static string databaseCommonRules = TemplateService.LoadTemplate("IaCRules/database-common-rules"); + /// /// Generates IaC rules using embedded templates. /// @@ -22,12 +27,8 @@ public static class IaCRulesTemplateUtil public static string GetIaCRules(string deploymentTool, string iacType, string[] resourceTypes) { var parameters = CreateTemplateParameters(deploymentTool, iacType, resourceTypes); - if (deploymentTool.Equals(DeploymentTool.AzCli, StringComparison.OrdinalIgnoreCase)) - { - return TemplateService.LoadTemplate("IaCRules/azcli-rules"); - } // Default values for optional parameters - if (string.IsNullOrWhiteSpace(iacType)) + if (deploymentTool.Equals(DeploymentTool.Azd, StringComparison.OrdinalIgnoreCase) && string.IsNullOrWhiteSpace(iacType)) { iacType = "bicep"; } @@ -58,49 +59,9 @@ private static IaCRulesTemplateParameters CreateTemplateParameters( ResourceTypesDisplay = string.Join(", ", resourceTypes) }; - // Set IaC type specific parameters - SetIaCTypeSpecificParameters(parameters); - return parameters; } - /// - /// Sets IaC type specific parameters. - /// - private static void SetIaCTypeSpecificParameters(IaCRulesTemplateParameters parameters) - { - parameters.OutputFileName = parameters.IacType == IacType.Bicep ? "main.bicep" : "outputs.tf"; - parameters.RoleAssignmentResource = parameters.IacType == IacType.Bicep - ? "Microsoft.Authorization/roleAssignments" - : "azurerm_role_assignment"; - parameters.ImageProperty = parameters.IacType == IacType.Bicep - ? "properties.template.containers.image" - : "azurerm_container_app.template.container.image"; - parameters.DiagnosticSettingsResource = parameters.IacType == IacType.Bicep - ? "Microsoft.Insights/diagnosticSettings" - : "azurerm_monitor_diagnostic_setting"; - - // Set CORS configuration based on IaC type - if (parameters.IacType == IacType.Bicep) - { - parameters.CorsConfiguration = "- Enable CORS via properties.configuration.ingress.corsPolicy."; - } - else if (parameters.IacType == IacType.Terraform) - { - parameters.CorsConfiguration = "- Create an ***azapi_resource_action*** resource using :type `Microsoft.App/containerApps`, method `PATCH`, and body `properties.configuration.ingress.corsPolicy` property to enable CORS for all origins, headers, and methods. Use 'azure/azapi' provider version *2.0*. DO NOT use jsonencode() for the body."; - } - - // Set Log Analytics configuration based on IaC type - if (parameters.IacType == IacType.Bicep) - { - parameters.LogAnalyticsConfiguration = "- Container App Environment must be connected to Log Analytics Workspace. Use logAnalyticsConfiguration -> customerId=logAnalytics.properties.customerId and sharedKey=logAnalytics.listKeys().primarySharedKey."; - } - else - { - parameters.LogAnalyticsConfiguration = "- Container App Environment must be connected to Log Analytics Workspace. Use logs_destination=\"log-analytics\" azurerm_container_app_environment.log_analytics_workspace_id = azurerm_log_analytics_workspace..id."; - } - } - /// /// Generates deployment tool specific rules. /// @@ -113,7 +74,12 @@ private static string GenerateDeploymentToolRules(IaCRulesTemplateParameters par } else if (parameters.DeploymentTool.Equals(DeploymentTool.AzCli, StringComparison.OrdinalIgnoreCase)) { - return TemplateService.LoadTemplate("IaCRules/azcli-rules"); + var kubernetesYamlNamingRule = "- Kubernetes (K8s) YAML naming: only Lowercase letters (a-z), digits (0-9), hyphens (-) is allowed. Must start and end with a letter or digit. Less than 20 characters."; + return TemplateService.ProcessTemplate("IaCRules/azcli-rules", new Dictionary + { + { "KubernetesYamlNamingRule", kubernetesYamlNamingRule }, + { "AzCliScriptRules", TemplateService.LoadTemplate("IaCRules/azcli-script-rules") } + }); } return string.Empty; @@ -126,9 +92,9 @@ private static string GenerateIaCTypeRules(IaCRulesTemplateParameters parameters { return parameters.IacType switch { - IacType.Bicep => "", + IacType.Bicep => TemplateService.LoadTemplate("IaCRules/bicep-rules"), IacType.Terraform => TemplateService.LoadTemplate("IaCRules/terraform-rules"), - _ => string.Empty + _ => "No IaC is used. Review the rules for Az CLI scripts." }; } @@ -141,27 +107,136 @@ private static string GenerateResourceSpecificRules(IaCRulesTemplateParameters p if (parameters.ResourceTypes.Contains(AzureServiceNames.AzureContainerApp)) { - rules.Add(TemplateService.ProcessTemplate("IaCRules/containerapp-rules", parameters.ToDictionary())); + rules.Add(GenerateContainerAppRules(parameters)); } if (parameters.ResourceTypes.Contains(AzureServiceNames.AzureAppService)) { - rules.Add(TemplateService.ProcessTemplate("IaCRules/appservice-rules", parameters.ToDictionary())); + rules.Add(GenerateAppServiceRules(parameters)); } if (parameters.ResourceTypes.Contains(AzureServiceNames.AzureFunctionApp)) { - rules.Add(TemplateService.ProcessTemplate("IaCRules/functionapp-rules", parameters.ToDictionary())); + rules.Add(GenerateFunctionAppRules(parameters)); } - if (parameters.ResourceTypes.Contains(AzureServiceNames.AzureStorage)) + if (parameters.ResourceTypes.Contains(AzureServiceNames.AzureKubernetesService)) { - rules.Add(TemplateService.ProcessTemplate("IaCRules/storage-rules", parameters.ToDictionary())); + rules.Add(GenerateAKSRules(parameters)); } + if (parameters.ResourceTypes.Contains(AzureServiceNames.AzureDatabaseForPostgreSql)) + { + rules.Add(GeneratePostgreSqlRules(parameters)); + } + + if (parameters.ResourceTypes.Contains(AzureServiceNames.AzureDatabaseForMySql)) + { + rules.Add(GenerateMySqlRules(parameters)); + } + + if (parameters.ResourceTypes.Contains(AzureServiceNames.AzureCosmosDb)) + { + rules.Add(GenerateCosmosDbRules(parameters)); + } + + if (parameters.ResourceTypes.Contains(AzureServiceNames.AzureStorageAccount)) + { + rules.Add(GenerateStorageRules(parameters)); + } + + rules.Add(GenerateKeyVaultRules(parameters)); + return string.Join(Environment.NewLine, rules); } + private static string GetToolSpecificResourceRules(string iacType, string? bicepRules, string? tfRules, string? cliRules) + { + return iacType switch + { + IacType.Bicep => bicepRules ?? string.Empty, + IacType.Terraform => tfRules ?? string.Empty, + _ => cliRules ?? string.Empty, + }; + } + + private static string GenerateContainerAppRules(IaCRulesTemplateParameters parameters) + { + var bicepRules = TemplateService.LoadTemplate("IaCRules/containerapp-bicep-rules"); + var tfRules = TemplateService.LoadTemplate("IaCRules/containerapp-tf-rules"); + return TemplateService.ProcessTemplate("IaCRules/containerapp-rules", new Dictionary { + { "ToolSpecificRules", GetToolSpecificResourceRules(parameters.IacType, bicepRules, tfRules, null)} + }); + } + + private static string GenerateAppServiceRules(IaCRulesTemplateParameters parameters) + { + var bicepRules = TemplateService.LoadTemplate("IaCRules/appservice-bicep-rules"); + var tfRules = TemplateService.LoadTemplate("IaCRules/appservice-tf-rules"); + return TemplateService.ProcessTemplate("IaCRules/appservice-rules", new Dictionary { + { "ToolSpecificRules", GetToolSpecificResourceRules(parameters.IacType, bicepRules, tfRules, null)} + }); + } + + private static string GenerateFunctionAppRules(IaCRulesTemplateParameters parameters) + { + var bicepRules = TemplateService.LoadTemplate("IaCRules/functionapp-bicep-rules"); + var tfRules = TemplateService.LoadTemplate("IaCRules/functionapp-tf-rules"); + return TemplateService.ProcessTemplate("IaCRules/functionapp-rules", new Dictionary { + { "ToolSpecificRules", GetToolSpecificResourceRules(parameters.IacType, bicepRules, tfRules, null)} + }); + } + + private static string GenerateAKSRules(IaCRulesTemplateParameters parameters) + { + var bicepRules = TemplateService.LoadTemplate("IaCRules/aks-bicep-rules"); + var tfRules = TemplateService.LoadTemplate("IaCRules/aks-tf-rules"); + var cliRules = TemplateService.LoadTemplate("IaCRules/aks-cli-rules"); + return TemplateService.ProcessTemplate("IaCRules/aks-rules", new Dictionary { + { "ToolSpecificRules", GetToolSpecificResourceRules(parameters.IacType, bicepRules, tfRules, cliRules)}, + { "KeyvaultIntegrationRules", TemplateService.LoadTemplate("IaCRules/aks-kv-integration-rules") } + }); + } + + private static string GeneratePostgreSqlRules(IaCRulesTemplateParameters parameters) + { + var versionRules = parameters.IacType.Equals(IacType.Terraform, StringComparison.OrdinalIgnoreCase) + ? "- PostgreSQL SKU name format: B_Standard_B1ms(Burstable tier), GP_Standard_D2s_v3(GeneralPurpose), MO_Standard_E4s_v3(MemoryOptimized)\n- For version, prefer to use '16'." + : "For version, use '17' or higher."; + var cliRules = "- If PostgreSQL server uses Azure AD authentication, use '--microsoft-entra-auth Enabled' when creating.\n- Azure CLI uses parameters '--name --rule-name ' for firewall rules creation.\n- IMPORTANT: **If using Azure AD authentication, you MUST ADD a database USER for the managed identity and GRANT all privileges to make the connection work.** Use 'az postgres flexible-server execute' command to run SQL commands to create the user and grant privileges."; + return TemplateService.ProcessTemplate("IaCRules/postgresql-rules", new Dictionary { + { "VersionRules", versionRules }, + { "DatabaseCommonRules", databaseCommonRules}, + { "ToolSpecificRules", GetToolSpecificResourceRules(parameters.IacType, null, null, cliRules)} + }); + } + + private static string GenerateMySqlRules(IaCRulesTemplateParameters parameters) + { + var databaseCommonRules = TemplateService.LoadTemplate("IaCRules/database-common-rules"); + return TemplateService.ProcessTemplate("IaCRules/mysql-rules", new Dictionary { { "DatabaseCommonRules", databaseCommonRules } }); + } + + private static string GenerateCosmosDbRules(IaCRulesTemplateParameters parameters) + { + return TemplateService.ProcessTemplate("IaCRules/cosmosdb-rules", new Dictionary { { "ToolSpecificRules", GetToolSpecificResourceRules(parameters.IacType, null, null, null) } }); + } + + private static string GenerateStorageRules(IaCRulesTemplateParameters parameters) + { + var tfRules = "- Add `storage_use_azuread = true` in azurerm provider."; + return TemplateService.ProcessTemplate("IaCRules/storage-rules", new Dictionary { { "ToolSpecificRules", GetToolSpecificResourceRules(parameters.IacType, null, tfRules, null) } }); + } + + private static string GenerateKeyVaultRules(IaCRulesTemplateParameters parameters) + { + var bicepRules = "- Allow public access from all networks(set publicNetworkAccess = Enabled)."; + var tfRules = "- Assign role 'Key Vault Secrets Officer (b86a8fe4-44ce-4948-aee5-eccb2c155cd7)' to current user.This is the dependency for key vault secret creation."; + var cliRules = "- IMPORTANT: Assign Key Vault Secrets Officer to current user. Add delay after RBAC role assignment to allow propagation before creating secrets."; + + return TemplateService.ProcessTemplate("IaCRules/key-vault-rules", new Dictionary { { "ToolSpecificRules", GetToolSpecificResourceRules(parameters.IacType, bicepRules, tfRules, cliRules) } }); + } + /// /// Generates final instructions for the IaC rules. /// diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Services/Util/PipelineGenerationUtil.cs b/tools/Azure.Mcp.Tools.Deploy/src/Services/Util/PipelineGenerationUtil.cs index cc9ac9fb41..a3100542d9 100644 --- a/tools/Azure.Mcp.Tools.Deploy/src/Services/Util/PipelineGenerationUtil.cs +++ b/tools/Azure.Mcp.Tools.Deploy/src/Services/Util/PipelineGenerationUtil.cs @@ -1,9 +1,18 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. +using System.Collections.Generic; +using System.Net; +using System.Security.Cryptography; +using System.Text.RegularExpressions; using Azure.Mcp.Tools.Deploy.Models.Templates; using Azure.Mcp.Tools.Deploy.Options.Pipeline; using Azure.Mcp.Tools.Deploy.Services.Templates; +using Azure.ResourceManager.Network.Models; +using Microsoft.AspNetCore.Http.HttpResults; +using OpenTelemetry; +using static System.Net.Mime.MediaTypeNames; +using static System.Runtime.InteropServices.JavaScript.JSType; namespace Azure.Mcp.Tools.Deploy.Services.Util; @@ -19,55 +28,121 @@ public static class PipelineGenerationUtil /// A formatted pipeline guidelines string. public static string GeneratePipelineGuidelines(GuidanceGetOptions options) { - if (options.UseAZDPipelineConfig) + var parameters = CreatePipelineParameters(options); + return TemplateService.ProcessTemplate("Pipeline/pipeline-to-azure", parameters.ToDictionary()); + } + + private static string GeneratePrerequisiteChecksPrompt(GuidanceGetOptions options) + { + var prompt = ""; + if (options.DeployOption == Models.DeployOption.DeployOnly) { - return "Run `azd pipeline config` to help the user create a deployment pipeline."; + prompt += "- When user confirms that Azure resources are ready for deployment, you need to know at least two things: the resource groups (with environments, e.g., dev, prod) and the hosting service TYPE(e.g., AKS, Azure Container Apps, App Service).\n"; } - else + else if (options.DeployOption == Models.DeployOption.ProvisionAndDeploy) { - var parameters = CreatePipelineParameters(options); - return TemplateService.ProcessTemplate("Pipeline/azcli-pipeline", parameters.ToDictionary()); + prompt += "- When user wants to include provisioning, check if there are available infra files. If not, first run Get Iac(Infrastructure as Code) Rules to create infra-provisioning files.\n"; } + if (options.IsAZDProject) + { + prompt += "- AZD IaC check: if Bicep is using resource group scope, resource group should be created in advance.\n"; + } + return prompt; } - /// - /// Creates pipeline template parameters from the provided options. - /// - private static PipelineTemplateParameters CreatePipelineParameters(GuidanceGetOptions options) + + private static string GeneratePipelineFilePrompts(GuidanceGetOptions options) { - const string defaultEnvironment = "dev"; - var environmentNamePrompt = !string.IsNullOrEmpty(options.GithubEnvironmentName) - ? $"Use {options.GithubEnvironmentName} for environment name of the deployment job." - : $"Use '{defaultEnvironment}' for the $environment for the deployment job."; + var prompt = ""; + if (options.PipelinePlatform == Models.PipelinePlatform.GitHubActions) + { + prompt += "- Use User-assigned Managed Identity with OIDC for login to Azure in the pipeline.\n" + + "- Use azure/login@v2 action to set up OIDC authentication in Github Actions. Add 'id-token: write' permission.\n" + + "- Use variables and secrets for specific values. Do NOT hardcode any values like service names.\n"; + } + else if (options.PipelinePlatform == Models.PipelinePlatform.AzureDevOps) + { + prompt += "- Use Service Principal(app registration) with workflow identity federation to login to Azure in the pipeline.\n"; + } - var subscriptionIdPrompt = !string.IsNullOrEmpty(options.Subscription) && CheckGUIDFormat(options.Subscription) - ? $"User is deploying to subscription {options.Subscription}" - : "Use \"az account show --query id -o tsv\" as default subscription ID."; + if (options.IsAZDProject) + { + prompt += "- Use 'azd deploy --no-prompt' to skip provisioning in CD pipeline.\n"; + } + if (options.DeployOption == Models.DeployOption.ProvisionAndDeploy) + { + prompt += "- Add a SEPARATE infra-deploy pipeline file to provision Azure resources.\n"; + } + return prompt; + } - var organizationName = !string.IsNullOrEmpty(options.OrganizationName) ? options.OrganizationName : "{$organization-of-repo}"; - var repositoryName = !string.IsNullOrEmpty(options.RepositoryName) ? options.RepositoryName : "{$repository-name}"; - var environmentName = !string.IsNullOrEmpty(options.GithubEnvironmentName) ? options.GithubEnvironmentName : defaultEnvironment; + private static string GenerateSetUpMethodPrompts(GuidanceGetOptions options) + { + var prompt = ""; + if (options.PipelinePlatform == Models.PipelinePlatform.GitHubActions) + { + prompt += "- Create a setup-azure-auth-for-pipeline.sh or setup-azure-auth-for-pipeline.ps1 script to automate the auth configuration. Include detailed commands or UI instructions according to the pipeline platform.\n"; + } + return prompt; + } - var subjectConfig = $"repo:{organizationName}/{repositoryName}:environment:{environmentName}"; - var environmentArg = !string.IsNullOrEmpty(options.GithubEnvironmentName) ? $"--env {options.GithubEnvironmentName}" : "--env dev"; - var environmentCreateCommand = $"gh api --method PUT -H \"Accept: application/vnd.github+json\" repos/{organizationName}/{repositoryName}/environments/{environmentName}"; - var jsonParameters = $"{{\"name\":\"github-federated\",\"issuer\":\"https://token.actions.githubusercontent.com\",\"subject\":\"{subjectConfig}\",\"audiences\":[\"api://AzureADTokenExchange\"]}}"; + private static string GenerateAzureAuthConfigPrompt(GuidanceGetOptions options) + { + var prompt = ""; + if (options.PipelinePlatform == Models.PipelinePlatform.GitHubActions) + { + prompt += "- Create a new **User-assigned Managed Identity** in a SEPARATE resource group.\n" + + "- This Managed Identity works for the pipeline. DO NOT CONFUSE it with any existing Managed Identity used by the application.\n" + + "- Set up Managed Identity with federated credentials and RBAC(e.g.contributor to resource groups and AcrPull) to authenticate(azure login with OIDC), push images and deploy applications to Azure in the pipeline for different environments.\n" + + "- Federated credentials should be set with proper subject * *to different environments * *(instead of branch), issuer, and audience. Description is NOT a valid property.\n"; + } + else if (options.PipelinePlatform == Models.PipelinePlatform.AzureDevOps) + { + prompt += "Set up Service Connection in Azure DevOps using app registration with workflow identity federation.\n" + + "Use RBAC (e.g. contributor to resource groups and AcrPull) to the app registration to authenticate, push images and deploy applications to Azure in the pipeline for different environments.\n"; + } + return prompt; + } - return new PipelineTemplateParameters + private static string GenerateEnvironmentSetupPrompt(GuidanceGetOptions options) + { + var prompt = ""; + if (options.PipelinePlatform == Models.PipelinePlatform.GitHubActions) { - EnvironmentNamePrompt = environmentNamePrompt, - SubscriptionIdPrompt = subscriptionIdPrompt, - EnvironmentCreateCommand = environmentCreateCommand, - JsonParameters = jsonParameters, - EnvironmentArg = environmentArg - }; + prompt += "- Create Github environments and set up approval checks in ALL environments.\n" + + "- Configure the Github Actions variables and secrets needed for the deployment pipeline for *different environments*.\n" + + "- Refer to the managed identity created in the 'Azure Authentication Configuration Guidance' section for OIDC setup.\n" + + "- You can use Github CLI and Github CLI or guide user to use UI to finish the setup.\n"; + } + else if (options.PipelinePlatform == Models.PipelinePlatform.AzureDevOps) + { + prompt += "- Configure the Azure DevOps pipeline variables and service connections needed for the deployment pipeline.\n" + + "- Set up the ADO environment and set up deployment approvals and checks.\n"; + } + if (options.IsAZDProject) + { + prompt += "- AZD IaC check: if Bicep is using resource group scope, AZURE_RESOURCE_GROUP variable should be set to the environment.\n"; + } + return prompt; } /// - /// Checks if the provided string is a valid GUID format. + /// Creates pipeline template parameters from the provided options. /// - private static bool CheckGUIDFormat(string input) + private static PipelineTemplateParameters CreatePipelineParameters(GuidanceGetOptions options) { - return Guid.TryParse(input, out _); + options.PipelinePlatform ??= Models.PipelinePlatform.GitHubActions; + options.DeployOption ??= Models.DeployOption.DeployOnly; + + return new PipelineTemplateParameters + { + DeploymentTool = options.IsAZDProject ? "AZD" : "Azure CLI", + PipelinePlatform = options.PipelinePlatform.ToString(), + PrerequisiteChecksPrompt = GeneratePrerequisiteChecksPrompt(options), + PipelineFilePrompt = GeneratePipelineFilePrompts(options), + SetupMethodPrompt = GenerateSetUpMethodPrompts(options), + AzureAuthConfigPrompt = GenerateAzureAuthConfigPrompt(options), + EnvironmentSetupPrompt = GenerateEnvironmentSetupPrompt(options) + }; } } diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/aks-bicep-rules.md b/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/aks-bicep-rules.md new file mode 100644 index 0000000000..ef2b2f22fc --- /dev/null +++ b/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/aks-bicep-rules.md @@ -0,0 +1,4 @@ +- Set AKS cluster with 'identity.type = "SystemAssigned"'. +- DO NOT use auto scale ('agentPoolProfiles.enableAutoScaling'). +- Assign AcrPull role to the kubelet identity for pulling images from ACR. Add 'dependsOn' aks resource to ensure AKS managed identity exists before creating the role assignment. +- Enable 'addonProfiles.azureKeyvaultSecretsProvider' to access KeyVault. diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/aks-cli-rules.md b/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/aks-cli-rules.md new file mode 100644 index 0000000000..11ffdb0dde --- /dev/null +++ b/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/aks-cli-rules.md @@ -0,0 +1,3 @@ +- Attach ACR to AKS cluster for pulling images using 'az aks update --attach-acr'. +- Set up AKS workload identity with user-assigned managed identity by creating aks with '--enable-oidc-issuer --enable-workload-identity' AND CREATE a federated identity credential to link the managed identity with the Kubernetes service account. +- Use existing workspace resource needs '--enable-addons monitoring'. diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/aks-kv-integration-rules.md b/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/aks-kv-integration-rules.md new file mode 100644 index 0000000000..a429d67a6e --- /dev/null +++ b/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/aks-kv-integration-rules.md @@ -0,0 +1,58 @@ +- To Access Key Vault secrets in AKS cluster, you need to export some configuration, then set them in env variables to create some Kubernetes resources. Example: +1) Create a SecretProviderClass. Example: +``` +apiVersion: secrets-store.csi.x-k8s.io/v1 +kind: SecretProviderClass +metadata: + name: azure-kvname-user-msi +spec: + provider: azure + parameters: + usePodIdentity: "false" + useVMManagedIdentity: "true" # Set to true for using managed identity + userAssignedIdentityID: ${AKS_KV_IDENTITY_CLIENT_ID} # The clientID of the AKS Key Vault Secrets Provider identity, it can be got after AKS creation + keyvaultName: ${KEY_VAULT_NAME} # The name of the Key Vault + objects: | + array: + - | + objectName: postgres-connection-string + objectType: secret # object types: secret, key, or cert + tenantId: ${TENANT_ID} # The tenant ID of the key vault + secretObjects: + - secretName: test-secrets-obj1 # it will create a Kubernetes secret in cluster with the name 'test-secrets-obj1' + type: Opaque + data: + - objectName: postgres-connection-string # must use the same objectName as above + key: postgres-connection-string +``` +2) In the deployment YAML file, mount the secret to pod. Example: +``` +kind: Pod +apiVersion: v1 +metadata: + name: busybox-secrets-store-inline-user-msi +spec: + containers: + - name: busybox + image: registry.k8s.io/e2e-test-images/busybox:1.29-4 + command: + - "/bin/sleep" + - "10000" + env: + - name: SPRING_DATASOURCE_URL # Important: set the env variable to use the secret + valueFrom: + secretKeyRef: + name: test-secrets-obj1 # use the secretName defined in secretObjects above + key: postgres-connection-string # use the objectName defined in secretObjects above + volumeMounts: # Important: mount the volume + - name: secrets-store01-inline + mountPath: "/mnt/secrets-store" + readOnly: true + volumes: # Important: define the volume + - name: secrets-store01-inline + csi: + driver: secrets-store.csi.k8s.io + readOnly: true + volumeAttributes: + secretProviderClass: "azure-kvname-user-msi" # Use the SecretProviderClass name defined above +``` diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/aks-rules.md b/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/aks-rules.md new file mode 100644 index 0000000000..12da75d30f --- /dev/null +++ b/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/aks-rules.md @@ -0,0 +1,7 @@ +=== Additional requirements for Azure Kubernetes Service (AKS): +- **CRITICAL** PREREQUISITE: You MUST use a stable kubernetesVersion, get by `az aks get-versions --query 'values[?isDefault].version' --location <> -o tsv`. +- For SKU, set based on appmod-get-available-region-sku output to get available VM size in the region, e.g. Standard_D2ds_v5. +- Node pool names must be 6 characters or less (e.g., 'sys', 'user', 'win01'). +- For AKS connections to other Azure services (storage, databases, etc.) EXCEPT ACR, use connection strings/secrets directly instead of workload identity or service account, etc. +{{ToolSpecificRules}} +{{KeyvaultIntegrationRules}} diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/aks-tf-rules.md b/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/aks-tf-rules.md new file mode 100644 index 0000000000..9545a66775 --- /dev/null +++ b/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/aks-tf-rules.md @@ -0,0 +1,57 @@ +- DO NOT use auto scale ('auto_scaling_enabled'). +- AKS terraform Example: +``` +resource "azurerm_kubernetes_cluster" "aks" { + name = azurecaf_name.aks.result + location = azurerm_resource_group.rg.location + resource_group_name = azurerm_resource_group.rg.name + kubernetes_version = var.kubernetes_version // Use a stable version from `az aks get-versions --query 'values[?isDefault].version' --location <> -o tsv` + + default_node_pool { + name = "default" + node_count = 2 + vm_size = "Standard_D2s_v3" + os_disk_size_gb = 30 + vnet_subnet_id = null + } + + identity { + type = "SystemAssigned" // Use SystemAssigned identity for AKS + } + + network_profile { + network_plugin = "kubenet" + load_balancer_sku = "standard" + } + + key_vault_secrets_provider { // Add if using Key Vault + secret_rotation_enabled = true + } + + tags = { + Environment = var.environment + } + + depends_on = [ + ] +} + +# AcrPull role assignment for AKS identity +resource "azurerm_role_assignment" "aks_acr_pull" { + principal_id = azurerm_kubernetes_cluster.aks.kubelet_identity[0].object_id + role_definition_id = "/subscriptions/{subscription_id}/providers/Microsoft.Authorization/roleDefinitions/7f951dda-4ed3-4680-a7ca-43fe172d538d" + scope = azurerm_container_registry.acr.id + skip_service_principal_aad_check = true + depends_on = [ azurerm_kubernetes_cluster.aks ] // Important +} +``` + +``` +# Key Vault Secrets User role assignment for AKS managed identity +resource "azurerm_role_assignment" "secret_user" { + scope = azurerm_key_vault.keyvault.id + role_definition_name = "Key Vault Secrets User" + principal_id = azurerm_kubernetes_cluster.aks.key_vault_secrets_provider[0].secret_identity[0].object_id + depends_on = [ azurerm_kubernetes_cluster.aks ] +} +``` diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/appservice-bicep-rules.md b/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/appservice-bicep-rules.md new file mode 100644 index 0000000000..b139ea86bb --- /dev/null +++ b/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/appservice-bicep-rules.md @@ -0,0 +1,4 @@ +- Enable application insights via environment variable APPLICATIONINSIGHTS_CONNECTION_STRING. +- Enable CORS in SiteConfig.cors. +- Must define diagnostic settings (type: "Microsoft.Insights/diagnosticSettings"). +- On the App Service Plan (Microsoft.Web/serverfarms), properties.reserved must be 'true' for Linux, and 'false' for Windows. diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/appservice-rules.md b/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/appservice-rules.md index e28d5a7cc6..eee029d94c 100644 --- a/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/appservice-rules.md +++ b/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/appservice-rules.md @@ -1,2 +1,3 @@ -App Service Rules: -- App Service Site Extension (Microsoft.Web/sites/siteextensions) is required for App Service deployments. +=== Additional requirements for App Service: +- Must attach user-assigned managed identity. +{{ToolSpecificRules}} diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/appservice-tf-rules.md b/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/appservice-tf-rules.md new file mode 100644 index 0000000000..c41f7e040e --- /dev/null +++ b/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/appservice-tf-rules.md @@ -0,0 +1,2 @@ +- Use "azurerm_monitor_diagnostic_setting" resource to send app service logs to Log Analytics Workspace. +- On the App Service Plan, reserved must be 'true' for Linux, and 'false' for Windows. diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/azcli-rules.md b/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/azcli-rules.md index f7ff53fc20..754ce74e09 100644 --- a/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/azcli-rules.md +++ b/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/azcli-rules.md @@ -1,4 +1,5 @@ -- If creating AzCli script, the script should stop if any command fails. Fix the error before proceeding. -- Azure resource Naming: All resources should be named like {resourcePrefix}{resourceToken}{instance}. Alphanumeric only! Don't use special characters! resourcePrefix is a prefix for the resource (ex. 'kv' for key vault) and <= 3 characters. resourceToken is a random string and = 5 characters. It should be used for all azure resources in a resource group. instance is a number that can be used when there are multiple resource with the same type. For example, resourceToken=abcde, then resource name: myRg(resource group), myKv(keyvault), myServer(sql), myApp1(container app 1), myApp2(container app 2). Full resource name must be less than 32 characters. -- Kubernetes (K8s) YAML naming: only Lowercase letters (a-z), digits (0-9), hyphens (-) is allowed. Must start and end with a letter or digit. Less than 20 characters. - +- Use .ps1 extension for PowerShell scripts and .sh extension for Bash scripts. +- Ensure all the steps have been executed successfully. Fix the script and RERUN if ANY step fails. +{{KubernetesYamlNamingRule}} +- Validate PowerShell script syntax: ensure proper brace matching, string termination, and valid PowerShell syntax before execution. +{{AzCliScriptRules}} diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/azcli-script-rules.md b/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/azcli-script-rules.md new file mode 100644 index 0000000000..2c4dd91817 --- /dev/null +++ b/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/azcli-script-rules.md @@ -0,0 +1,5 @@ +- The script should be idempotent, i.e. it should check for resource existence first and only create resources that don't exist, making it safe to rerun. Check resource existence using '$exist = az show 2>$null' for ps1. Use '$ErrorActionPreference = "Continue"' to avoid breaking existence check. +- Set up an optional input *resourceToken* for the script. This is a random alphanumeric string of <= 5 characters with lowercase letters only. E.g. `abcde`. +- Azure resource Naming: All resources should be named like {resourcePrefix}{*resourceToken*}{instance}. Alphanumeric only! Don't use special characters! resourcePrefix is a prefix for the resource (ex. 'kv' for key vault) and <= 3 characters. instance is a number for multiple resource with the same type. E.g. rgabcde(resource group), kvabcde (key vault), sqlabcde(sql server), appabcde1(container app 1), appabcde2 (container app 2). +- Use '--yes' or equivalent flags to avoid interactive prompts. +- Use the SAME resourceToken params as the failed run when rerunning the script. diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/base-iac-rules.md b/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/base-iac-rules.md index 4ea1663a73..58a0adeeed 100644 --- a/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/base-iac-rules.md +++ b/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/base-iac-rules.md @@ -1,5 +1,8 @@ Mandatory rules for deployment. You must implement every rule exactly as stated, with no exceptions or omissions, even if it is not a common pattern or seems redundant. Do not use your own judgment to simplify, skip, or modify any rule. If a rule is present, it must be enforced in the code, regardless of context. Adjust {{IacType}} files to align with these rules. +[IMPORTANT] Call quota tools first to get available regions and SKU quota for each resources. Resource region can be different with resource group, set each resource location accordingly! +[IMPORTANT] If current region for a resource is not available, 1)choose an available region and 2)add an index to the resource name suffix to avoid naming conflict. Don't change other resources' region in the resource group. + ## Deployment Tool {{DeploymentTool}} rules: {{DeploymentToolRules}} diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/bicep-rules.md b/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/bicep-rules.md new file mode 100644 index 0000000000..d32982022d --- /dev/null +++ b/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/bicep-rules.md @@ -0,0 +1,3 @@ +- Expected files: main.bicep, main.parameters.json (with parameters from main.bicep). +- Resource token format: 'uniqueString(subscription().id, resourceGroup().id, location, environmentName)' (scope = resourceGroup) or 'uniqueString(subscription().id, location, environmentName)' (scope = subscription). +- All resources should be named like az{resourcePrefix}{resourceToken}, where resourcePrefix is a prefix for the resource (ex. 'kv' for key vault) and <= 3 characters. Alphanumeric only. ResourceToken is the string generated by uniqueString as per earlier. Apply this to ALL resources as well as newly written resources. diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/containerapp-bicep-rules.md b/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/containerapp-bicep-rules.md new file mode 100644 index 0000000000..9549ea6a8a --- /dev/null +++ b/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/containerapp-bicep-rules.md @@ -0,0 +1,10 @@ +- MANDATORY: Add a Microsoft.Authorization/roleAssignments resource to assign the AcrPull (7f951dda-4ed3-4680-a7ca-43fe172d538d) role to the user-assigned managed identity (Only one instance is required per-container registry. Define this BEFORE any container apps.) +- Use this identity (NOT system) to connect to the container registry. A registry connection needs to be created even if we are using a template base image. +- Container Apps MUST use base container image mcr.microsoft.com/azuredocs/containerapps-helloworld:latest. The property is set via properties.template.containers.image. +- Use 'properties.configuration.registries' to set the container registry connection. +- Enable CORS via properties.configuration.ingress.corsPolicy. +- Define all used secrets; Use Key Vault if possible. +- MANDATORY: You MUST add Key Vault secrets and their related role assignment in explicit dependencies to use these secrets. +- IMPORTANT NOTES: If you meet deployment error: "Field 'configuration.secrets' is invalid with details: Invalid value: : unable to get value using managed identity". DO NOT use key vault references first, use connection string directly in container app environment variable and deploy. + After deployment is successful, get IP from the container app, switch to use key vault references in secrets, and 1) add the IP to key vault network rules 2) set defaultAction: 'Deny'. This is a workaround for the issue that managed identity cannot access key vault when key vault has network rules enabled. +- Container App Environment must be connected to Log Analytics Workspace. Use logAnalyticsConfiguration -> customerId=logAnalytics.properties.customerId and sharedKey=logAnalytics.listKeys().primarySharedKey. diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/containerapp-rules.md b/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/containerapp-rules.md index 1d0e10b61f..593aca4fdd 100644 --- a/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/containerapp-rules.md +++ b/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/containerapp-rules.md @@ -1,9 +1,3 @@ === Additional requirements for Container Apps: - Attach User-Assigned Managed Identity. -- MANDATORY: Add a {{RoleAssignmentResource}} resource to assign the AcrPull (7f951dda-4ed3-4680-a7ca-43fe172d538d) role to the user-assigned managed identity (Only one instance is required per-container registry. Define this BEFORE any container apps.). -- Use this identity (NOT system) to connect to the container registry. A registry connection needs to be created even if we are using a template base image. -- Container Apps MUST use base container image mcr.microsoft.com/azuredocs/containerapps-helloworld:latest. The property is set via {{ImageProperty}}. -{{CorsConfiguration}} -- Define all used secrets; Use Key Vault if possible. -{{LogAnalyticsConfiguration}} -=== +{{ToolSpecificRules}} diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/containerapp-tf-rules.md b/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/containerapp-tf-rules.md new file mode 100644 index 0000000000..f178683e15 --- /dev/null +++ b/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/containerapp-tf-rules.md @@ -0,0 +1,9 @@ +- MANDATORY: Add a azurerm_role_assignment resource to assign the AcrPull (7f951dda-4ed3-4680-a7ca-43fe172d538d) role to the user-assigned managed identity (Only one instance is required per-container registry. Define this BEFORE any container apps.) +- Use this identity (NOT system) to connect to the container registry. A registry connection needs to be created even if we are using a template base image. +- Container Apps MUST use base container image mcr.microsoft.com/azuredocs/containerapps-helloworld:latest. The property is set via azurerm_container_app.template.container.image. +- Create an ***azapi_resource_action*** resource using :type `Microsoft.App/containerApps`, method `PATCH`, and body `properties.configuration.ingress.corsPolicy` property to enable CORS for all origins, headers, and methods. Use 'azure/azapi' provider version *2.0*. DO NOT use jsonencode() for the body. +- Define all used secrets; Use Key Vault if possible. +- MANDATORY: You MUST add Key Vault secrets and their related role assignment in explicit dependencies to use these secrets. +- IMPORTANT NOTES: If you meet deployment error: "Field 'configuration.secrets' is invalid with details: Invalid value: : unable to get value using managed identity". DO NOT use key vault references first, use connection string directly in container app environment variable and deploy. + After deployment is successful, get IP from the container app, switch to use key vault references in secrets, and 1) add the IP to key vault network rules 2) set defaultAction: 'Deny'. This is a workaround for the issue that managed identity cannot access key vault when key vault has network rules enabled. +- Container App Environment must be connected to Log Analytics Workspace. Use logs_destination="log-analytics" azurerm_container_app_environment.log_analytics_workspace_id = azurerm_log_analytics_workspace..id. diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/cosmosdb-rules.md b/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/cosmosdb-rules.md new file mode 100644 index 0000000000..b1e287ca4b --- /dev/null +++ b/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/cosmosdb-rules.md @@ -0,0 +1,2 @@ +=== Additional requirements for CosmosDB: +- Add firewall rules to allow traffic from Azure Services (allow IP 0.0.0.0). diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/database-common-rules.md b/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/database-common-rules.md new file mode 100644 index 0000000000..6634be9d81 --- /dev/null +++ b/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/database-common-rules.md @@ -0,0 +1,9 @@ +- Add firewall rules to allow traffic from Azure Services (allow IP 0.0.0.0). +- If username and password are required, you MUST leave them as params. +- Create secrets in Key Vault to store the connection string or credentials, and assign `Key Vault Secrets User` role to the user-assigned managed identity. +- If app used Managed Identity to connect the database, MUST add a post-provision step to use Service Connector create a connection between containerapp and database: + 1) Prerequisites: Ensure the Service Connector extension installed in local environment: 'az extension add --name serviceconnector-passwordless'. Check if the app uses user-assigned managed identity or system-assigned managed identity. + 2) Run Command: az containerapp connection create mysql-flexible/postgres-flexible/sql --connection connectionname --user-identity client-id=XX subs-id=XX --source-id --tg --server servername --database dbname -y. + 3) Command parameter: use '--user-identity client-id=$clientId subs-id=$subsId' or '--system-identity' based on the container app's configuration. Don't use both. For param '--client-type', it can be 'springBoot, java, nodejs, dotnet, python, none'. For container app, add param '-c containername'. For AKS, add '--kube-namespace <>' and use the deployment's namespace. Don't mock and add param in command that doesn't exist. + 4) Check command output: 'configurations.name' property name means an env variable name and you should use it in your application to connect to the database. + 5) If app is Java spring boot app connected to database with Managed Identity, Service Connector connection will set the database configuration automatically, don't add SPRING_DATASOURCE env variable in container app. diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/functionapp-bicep-rules.md b/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/functionapp-bicep-rules.md new file mode 100644 index 0000000000..a4080407b9 --- /dev/null +++ b/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/functionapp-bicep-rules.md @@ -0,0 +1,8 @@ +- MANDATORY: Add a Microsoft.Authorization/roleAssignments resource to assign the Storage Blob Data Owner (b7e6dc6d-f1e8-4753-8033-0f276bb0955b) role to the user-assigned managed identity +- MANDATORY: Add a Microsoft.Authorization/roleAssignments resource to assign the Storage Blob Data Contributor (ba92f5b4-2d11-453d-a403-e96b0029c9fe) role to the user-assigned managed identity +- MANDATORY: Add a Microsoft.Authorization/roleAssignments resource to assign the Storage Queue Data Contributor (974c5e8b-45b9-4653-ba55-5f855dd0fb88) role to the user-assigned managed identity +- MANDATORY: Add a Microsoft.Authorization/roleAssignments resource to assign the Storage Table Data Contributor (0a9a7e1f-b9d0-4cc4-a60d-0319b160aaa3) role to the user-assigned managed identity +- MANDATORY: Add a Microsoft.Authorization/roleAssignments resource to assign the Monitoring Metrics Publisher (3913510d-42f4-4e42-8a64-420c390055eb) role to the user-assigned managed identity +- Create a storage account and connect to the function app. +- Always use a V1 storage account to create file shares, V2 storage accounts are not supported. +- Define diagnostic settings to save logs. The resource type is Microsoft.Insights/diagnosticSettings. diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/functionapp-rules.md b/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/functionapp-rules.md index aac1181e8b..3437d8b861 100644 --- a/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/functionapp-rules.md +++ b/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/functionapp-rules.md @@ -1,10 +1,5 @@ === Additional requirements for Function Apps: - Attach User-Assigned Managed Identity. -- MANDATORY: Add a {{RoleAssignmentResource}} resource to assign the Storage Blob Data Owner (b7e6dc6d-f1e8-4753-8033-0f276bb0955b) role to the user-assigned managed identity. -- MANDATORY: Add a {{RoleAssignmentResource}} resource to assign the Storage Blob Data Contributor (ba92f5b4-2d11-453d-a403-e96b0029c9fe) role to the user-assigned managed identity. -- MANDATORY: Add a {{RoleAssignmentResource}} resource to assign the Storage Queue Data Contributor (974c5e8b-45b9-4653-ba55-5f855dd0fb88) role to the user-assigned managed identity. -- MANDATORY: Add a {{RoleAssignmentResource}} resource to assign the Storage Table Data Contributor (0a9a7e1f-b9d0-4cc4-a60d-0319b160aaa3) role to the user-assigned managed identity. -- MANDATORY: Add a {{RoleAssignmentResource}} resource to assign the Monitoring Metrics Publisher (3913510d-42f4-4e42-8a64-420c390055eb) role to the user-assigned managed identity. -- Create a storage account and connect to the function app. -- Define diagnostic settings to save logs. The resource type is {{DiagnosticSettingsResource}}. -=== +{{ToolSpecificRules}} +- Do not add `node_modules` to `.funcignore` when using the Flex Consumption plan. This must not be ignored. +- Include `function.json` files. This is part of the older paradigm, but Copilot may not yet support the newer approach fully. diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/functionapp-tf-rules.md b/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/functionapp-tf-rules.md new file mode 100644 index 0000000000..78df4b6a97 --- /dev/null +++ b/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/functionapp-tf-rules.md @@ -0,0 +1,8 @@ +- MANDATORY: Add a azurerm_role_assignment resource to assign the Storage Blob Data Owner (b7e6dc6d-f1e8-4753-8033-0f276bb0955b) role to the user-assigned managed identity +- MANDATORY: Add a azurerm_role_assignment resource to assign the Storage Blob Data Contributor (ba92f5b4-2d11-453d-a403-e96b0029c9fe) role to the user-assigned managed identity +- MANDATORY: Add a azurerm_role_assignment resource to assign the Storage Queue Data Contributor (974c5e8b-45b9-4653-ba55-5f855dd0fb88) role to the user-assigned managed identity +- MANDATORY: Add a azurerm_role_assignment resource to assign the Storage Table Data Contributor (0a9a7e1f-b9d0-4cc4-a60d-0319b160aaa3) role to the user-assigned managed identity +- MANDATORY: Add a azurerm_role_assignment resource to assign the Monitoring Metrics Publisher (3913510d-42f4-4e42-8a64-420c390055eb) role to the user-assigned managed identity +- Create a storage account and connect to the function app. +- Always use a V1 storage account to create file shares, V2 storage accounts are not supported. +- Define diagnostic settings to save logs. The resource type is azurerm_monitor_diagnostic_setting. diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/key-vault-rules.md b/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/key-vault-rules.md new file mode 100644 index 0000000000..85f9f2a269 --- /dev/null +++ b/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/key-vault-rules.md @@ -0,0 +1,4 @@ +=== Additional requirements for Key Vault: +- - Use RBAC authentication. +- Assign role 'Key Vault Secrets Officer (b86a8fe4-44ce-4948-aee5-eccb2c155cd7)' to managed identity. Add dependencies to ensure role assignment is finished before application accesses secrets. +{{ToolSpecificRules}} diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/mysql-rules.md b/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/mysql-rules.md new file mode 100644 index 0000000000..a474f0fed7 --- /dev/null +++ b/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/mysql-rules.md @@ -0,0 +1,2 @@ +- Choose model based on appmod-get-available-region-sku output to make sure the model is available in the region. For DTU Model (Basic/Standard/Premium), check ServerQuota only. For vCore Model (GP/BC/HS), you must check both ServerQuota and vCore. For FreeDatabase, make sure SubscriptionFreeDatabaseCount quota is sufficient. +{{DatabaseCommonRules}} diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/postgresql-rules.md b/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/postgresql-rules.md new file mode 100644 index 0000000000..dea5bb7ff9 --- /dev/null +++ b/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/postgresql-rules.md @@ -0,0 +1,6 @@ +=== Additional requirements for PostgreSQL: +{{VersionRules}} +- Don't create a database naming postgres, it's a built-in db. +- If you have error provisioning a PostgreSQL flexible server: 'An unexpected error while processing the request'. Check quota for Microsoft.DBforPostgreSQL/flexibleServers in the region with tool. If current region is not available, 1)choose an available region and 2)add an index to the postgresql name suffix and retry. +{{DatabaseCommonRules}} +{{ToolSpecificRules}} diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/storage-rules.md b/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/storage-rules.md index f194e3fe97..9269339f57 100644 --- a/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/storage-rules.md +++ b/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/storage-rules.md @@ -1,3 +1,4 @@ === Additional requirements for Storage Accounts: - By default, disable storage account local auth (key access). -- By default, disable public access to storage blob. \ No newline at end of file +- By default, disable public access to storage blob. +{{ToolSpecificRules}} diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/terraform-rules.md b/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/terraform-rules.md index 25eeae4676..5c7299de76 100644 --- a/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/terraform-rules.md +++ b/tools/Azure.Mcp.Tools.Deploy/src/Templates/IaCRules/terraform-rules.md @@ -1,2 +1,4 @@ - Expected files: main.tf, main.tfvars.json (with the minimally required parameters), outputs.tf. - Resource names should use Azure CAF naming convention. This is required for deployments. Add aztfmod/azurecaf in the required provider. DO NOT use random_length. NO suffixes needed. +- Avoid duplicate definitions across all Terraform files (e.g., main.tf and variables.tf). +- Configure subscription ID for azurerm provider. diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Templates/Pipeline/azcli-pipeline.md b/tools/Azure.Mcp.Tools.Deploy/src/Templates/Pipeline/azcli-pipeline.md deleted file mode 100644 index 24fb17f913..0000000000 --- a/tools/Azure.Mcp.Tools.Deploy/src/Templates/Pipeline/azcli-pipeline.md +++ /dev/null @@ -1,21 +0,0 @@ -Help the user to set up a CI/CD pipeline to deploy to Azure with the following steps IN ORDER. **RUN the commands directly and DO NOT just give instructions. DO NOT ask user to provide information.** - - 1. First generate a Github Actions workflow file to deploy to Azure. {{EnvironmentNamePrompt}} The pipeline at least contains these steps in order: - a. Azure login: login with a service principal using OIDC. DO NOT use secret. - b. Docker build - c. Deploy infrastructure: Use AZ CLI "az deployment sub/group create" command. Use "az deployment sub/group wait" to wait the deployment to finish. Refer to the infra files to set the correct parameters. - d. Azure Container Registry login: login into the container registry created in the previous step. Use "az acr list" to get the correct registry name if you are not sure. - e. Push app images to ACR - f. Deploy to hosting service. Use the infra deployment output or AZ CLI to list hosting resources. Find the name or ID of the hosting resources from "az list" if you are not sure. - - Pay attention to the name of the branches to which the pipeline is triggered. - - 2. Run '{{EnvironmentCreateCommand}}' to create the environment in the repository. - - 3. - {{SubscriptionIdPrompt}} - - Run "az ad sp create-for-rbac" command to create a service principal. Grant the service principal *Contributor* role of the subscription. Also grant the service principal *User Access Administrator* - **Use Federated credentials in order to authenticate to Azure services from GitHub Actions workflows. The command is **az ad app federated-credential create --id <$service-principal-app-id> --parameters '{{JsonParameters}}'**. You MUST use ' and \"(DO NOT forget the slash \) in the command. Use the current Github org/repo to fill in the subject property. - - 4. Run command "gh secret set --body {{EnvironmentArg}}" to configure the AZURE_CLIENT_ID, AZURE_TENANT_ID and AZURE_SUBSCRIPTION_ID of the service principal in Github secrets using Github CLI. - - ** DO NOT prompt user for any information. Find them on your own. ** diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Templates/Pipeline/pipeline-to-azure.md b/tools/Azure.Mcp.Tools.Deploy/src/Templates/Pipeline/pipeline-to-azure.md new file mode 100644 index 0000000000..7c737572c0 --- /dev/null +++ b/tools/Azure.Mcp.Tools.Deploy/src/Templates/Pipeline/pipeline-to-azure.md @@ -0,0 +1,20 @@ +Follow ALL of the following rules to provide CI/CD pipeline files and configuration setup instructions: +*Prerequisite Checks*: +{{PrerequisiteChecksPrompt}} +*Pipeline File Generation Guidance*: +- Generate a CI/CD pipeline file using {{DeploymentTool}} for {{PipelinePlatform}}. +- The CI part should include build (and test if applicable). CI should NOT include Azure-related steps, for example, pushing images to ACR. +- The CD part should include multi-environment deployment steps. Images, if applicable, should be pushed to ACR in different environments. +- **'pull_request' should not start CD(deployment).** +- Use different environments according to user-provided Azure resources. Default to use 'dev', 'staging', and 'production' IF NOT SPECIFIED by user. *If user states specific environments, use those.* +- Pay attention to the dependency order among build and multi-environment deployments. +{{PipelineFilePrompt}} +- **You should ONLY care about deployment-related variables like hosting services' names. Ignore application-level variables like connection strings.** +*How you do configurations*: +- Configure Azure authentication and environment setup for the pipeline as per the instructions below. +- You should use a .azure/pipeline-setup.md file to outline the steps. The file should contain the steps and explain the tasks to be done by the user. +{{SetupMethodPrompt}} +*Azure Authentication Configuration Guidance*: +{{AzureAuthConfigPrompt}} +*Pipeline Environment Setup Guidance*: +{{EnvironmentSetupPrompt}} diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Templates/Plan/aks-deploy-only-steps.md b/tools/Azure.Mcp.Tools.Deploy/src/Templates/Plan/aks-deploy-only-steps.md new file mode 100644 index 0000000000..ec4d826b3e --- /dev/null +++ b/tools/Azure.Mcp.Tools.Deploy/src/Templates/Plan/aks-deploy-only-steps.md @@ -0,0 +1,28 @@ +1. Env setup for Azure CLI: + 1. Install Azure CLI if not installed. + 2. Ensure there is a default subscription set. If provided, override the default subscription with the provided subscription ID. + 3. Subscription ID: Use default subscription +2. Check Azure resources existence: + 1. Azure Kubernetes Service: + - AKS cluster name: <>, resource group: <>, subscription: <>, provisioningState: Succeeded, node count: <>, vmSize: , osType: . Check with 'az aks show' + - Check dependencies existence for all the resources connected to this service in the following format: + 1. : name: <>, resource group: <>. + 2. : name: <>, database: <>, resource group: <>. connection string: <>. + If not exists, ask if user want to 1) create a built-in resource in Kubernetes cluster (default). 2) have an Azure resource and provide its id, then get the resource information with Azure CLI command + 2. Azure Container Registry: + - login server: <>. Check with 'az acr show -o json' + 3. Create missing resources: + - If any resource is missing, ask user to provide the resource id or create a new one, then get the resource information with Azure CLI command + - If user want to create new resources, generate a script to do so using Azure CLI command. Run the script and confirms all resources are ready. +3. Deployment: + 1. Azure Kubernetes Service Deployment: + 1. If Kubernetes manifests/Helm charts exist: + - Existing file paths: + - Check if the existing files match what we required in the plan and list the necessary changes, e.g. using Azure Container Registry for image + 2. If expected files do not exist: + - Check if the project prefer to use Kubernetes Manifests(default) or Helm charts, and create the files accordingly. + 3. Prepare the deployment script (build + push image to ACR, deploy to AKS with kubectl/helm). + 4. Deploy with the files and verify the output. If errors occur, **fix the files until it works** + 5. Output: Kubernetes YAML files/Helm Charts, deployment script + 2. Deployment Validation: + 1. Check the deployed application is running. diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Templates/Plan/aks-deployment-steps.md b/tools/Azure.Mcp.Tools.Deploy/src/Templates/Plan/aks-deployment-steps.md new file mode 100644 index 0000000000..a0097596bd --- /dev/null +++ b/tools/Azure.Mcp.Tools.Deploy/src/Templates/Plan/aks-deployment-steps.md @@ -0,0 +1,12 @@ +4. Deployment: + 1. Azure Kubernetes Service Deployment: + 1. If Kubernetes manifests/Helm charts exist: + - Existing file paths: + - Check if the existing files match what we required in the plan and list the necessary changes, e.g. using Azure Container Registry for image + 2. If expected files do not exist: + - Check if the project prefer to use Kubernetes Manifests(default) or Helm charts, and create the files accordingly. + 3. Prepare the deployment script (build + push image to ACR, deploy to AKS with kubectl/helm). + 4. Deploy with the files and verify the output. If errors occur, **fix the files until it works** + 5. Output: Kubernetes YAML files/Helm Charts, deployment script + 2. Deployment Validation: + 1. Check the deployed application is running. diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Templates/Plan/aks-provision-steps.md b/tools/Azure.Mcp.Tools.Deploy/src/Templates/Plan/aks-provision-steps.md new file mode 100644 index 0000000000..9a309f86cd --- /dev/null +++ b/tools/Azure.Mcp.Tools.Deploy/src/Templates/Plan/aks-provision-steps.md @@ -0,0 +1,30 @@ +1. Containerization: + - If Dockerfiles exist, list their paths. + - If missing: Create dockerfiles for each application/service. + - Define a valid base image based on the project's language. + - Copy the required files into the container. + - Set the working directory. + - Install dependencies and build the project. + - Expose the listening ports. + - Define an entrypoint + - Create .dockerignore if required. + - Ensure the dockerfiles can be built using 'docker build'. Keep track of each dockerfile created, and its required docker build context path. Agent must create Dockerfile first before deployment! + - Output: Docker artifacts +2. Env setup for Azure CLI: + 1. Install Azure CLI if not installed. + 2. Ensure there is a default subscription set. If provided, override the default subscription with the provided subscription ID. + 3. Subscription ID: Use default subscription +3. Provision Azure Infrastructure with Azure CLI: + 1. Provisioning tool: Azure CLI. Expected files: terraform. + 2. Grab current subscriptionID, call tool quota_region_availability_list and quota_usage_check to get available region and SKUs for all needed Azure resource types in this project.You must check Microsoft.Compute/virtualMachines quota is available for AKS nodes. + 3. If expected files exist, please follow the below steps: + - Existing file paths: + - Check if the Azure resources in the existing files match what we required in the plan. If not, add steps to update the existing files with missing Azure resource. + 4. If expected files do not exist, please follow the below steps: + - Generate the terraform files in infra/ folder. Call tool deploy_iac_rules_get to get IaC rules + - Add a provisioning script to provision resources with `terraform` command. + - Ensure to run `terraform init` and `terraform validate` before `terraform apply` to initialize the working directory. + 5. Validate all generated files to ensure they are runnable and free of syntax errors: + - Call 'get_errors' on all generated files and iterate until all errors are resolved. + - Call 'terraform validate' and fix any errors. + 6. Run the generated Terraform script to provision the resources and confirm the result. diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Templates/Plan/azcli-deploy-only-steps.md b/tools/Azure.Mcp.Tools.Deploy/src/Templates/Plan/azcli-deploy-only-steps.md new file mode 100644 index 0000000000..aac3253f7c --- /dev/null +++ b/tools/Azure.Mcp.Tools.Deploy/src/Templates/Plan/azcli-deploy-only-steps.md @@ -0,0 +1,22 @@ +1. Env setup for AzCLI: + 1. Install AZ CLI if not installed. + 2. Ensure there is a default subscription set. If provided, override the default subscription with the provided subscription ID. + 3. Subscription ID: Use default subscription + (ONLY WHEN the project is using passwordless connection to mysql-flexible/postgres-flexible/sql) 4. Install Service Connector AzCLI extension: az extension add --name serviceconnector-passwordless --upgrade +2. Check Azure resources existence: + 1. For each service in this project, check {{AzureComputeHost}} for app : + - name: <>, resource group: <>, subscription: <>, provisioningState: Succeeded, runningStatus: Running. Check with 'az {{TargetAppCommandTitle}} show -o json' + - Check dependencies existence for all the resources connected to this service in the following format: + 1. : name: <>, resource group: <>. + 2. : name: <>, database: <>, resource group: <>. + {{ACRDependencyCheck}} + 2. Create missing resources: + - If any resource is missing, ask user to provide the resource id or create a new one, then get the resource information with Az CLI command + - If user want to create new resources, generate a script to do so using Azure CLI command. Run the script and confirms all resources are ready. +3. Deployment: + 1. {{AzureComputeHost}} Deployment: + {{DeploymentSteps}} + 2. Deployment Validation: + 1. Check the deployed application is running. +4. Summarize Result: + 1. Generate files: .azure/summary.copilotmd to summarize the deployment result. diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Templates/Plan/azcli-deployment-steps.md b/tools/Azure.Mcp.Tools.Deploy/src/Templates/Plan/azcli-deployment-steps.md new file mode 100644 index 0000000000..e9a7272b2e --- /dev/null +++ b/tools/Azure.Mcp.Tools.Deploy/src/Templates/Plan/azcli-deployment-steps.md @@ -0,0 +1,6 @@ +3. Deployment: + 1. {{AzureComputeHost}} Deployment: + {{DeploymentSteps}} + 2. Output: Azure CLI scripts + 2. Deployment Validation: + 1. Check the deployed application is running. diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Templates/Plan/azcli-provision-steps.md b/tools/Azure.Mcp.Tools.Deploy/src/Templates/Plan/azcli-provision-steps.md new file mode 100644 index 0000000000..bbbffafbf1 --- /dev/null +++ b/tools/Azure.Mcp.Tools.Deploy/src/Templates/Plan/azcli-provision-steps.md @@ -0,0 +1,21 @@ +1. Env setup for Azure CLI: + 1. Install Azure CLI if not installed. + 2. Ensure there is a default subscription set. If provided, override the default subscription with the provided subscription ID. + 3. Subscription ID: Use default subscription + (ONLY WHEN the project is using passwordless connection to mysql-flexible/postgres-flexible/sql) 4. Install Service Connector Azure CLI extension: az extension add --name serviceconnector-passwordless --upgrade +2. Provision Azure Infrastructure with Azure CLI: + 1. Provisioning tool: azcli. Expected files: {{IaCType}}. + 2. Grab current subscriptionID, call tool quota_region_availability_list and quota_usage_check to get available region and SKUs for all needed Azure resource types used in this project. + 3. If expected files exist, please follow the below steps: + - Existing file paths: + - Check if the Azure resources in the existing files match what we required in the project. If not, add steps to update the existing files with missing Azure resource. + 4. If expected files do not exist, please follow the below steps: + - Generate the {{IaCType}} files in infra/ folder. Call tool deploy_iac_rules_get to get IaC rules + 5. Validate all generated files to ensure they are runnable and free of syntax errors: + - Call 'get_errors' on all generated files and iterate until all errors are resolved. + 6. Provision resources with Az CLI `az deployment sub create`(targetScope = 'subscription') or `az deployment group create`(targetScope = 'resourceGroup'). + (ONLY WHEN the project is using passwordless connection to mysql-flexible/postgres-flexible/sql) 7. Post-provisioning steps ONLY WHEN the project is using passwordless connection to mysql-flexible/postgres-flexible/sql: + - Build connection between the database and {{AzureComputeHost}} with Managed Identity. + - Create the connection using Service Connector: az {{TargetAppCommandTitle}} connection create mysql-flexible/postgres-flexible/sql --connection connectionname --user-identity client-id=XX subs-id=XX --source-id --tg --server servername --database dbname -y. + - Check the connection with 'az {{TargetAppCommandTitle}} connection show -g AppRG -n MyApp --connection MyConnection -o json'. + - Check the 'configurations' property in the output. Each name means an env variable name and you should use it in your application to connect to the database. diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Templates/Plan/azcli-steps.md b/tools/Azure.Mcp.Tools.Deploy/src/Templates/Plan/azcli-steps.md deleted file mode 100644 index f24f6fc26f..0000000000 --- a/tools/Azure.Mcp.Tools.Deploy/src/Templates/Plan/azcli-steps.md +++ /dev/null @@ -1,4 +0,0 @@ -1. Provision Azure Infrastructure: - 1. Generate Azure CLI scripts for required azure resources based on the plan. - 2. Check and fix the generated Azure CLI scripts for grammar errors. - 3. Run the Azure CLI scripts to provision the resources and confirm each resource is created or already exists diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Templates/Plan/containerapp-steps.md b/tools/Azure.Mcp.Tools.Deploy/src/Templates/Plan/containerapp-steps.md deleted file mode 100644 index 976dd0eb15..0000000000 --- a/tools/Azure.Mcp.Tools.Deploy/src/Templates/Plan/containerapp-steps.md +++ /dev/null @@ -1,5 +0,0 @@ -2. Build and Deploy the Application: - 1. Build and Push Docker Image: Agent should check if Dockerfile exists, if not add the step: 'generate a Dockerfile for the application deployment', if it does, list the Dockerfile path - 2. Deploy to {{AzureComputeHost}}: Use Azure CLI command to deploy the application -3. Validation: - 1. Verify command output to ensure the application is deployed successfully diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Templates/Plan/containerization-steps.md b/tools/Azure.Mcp.Tools.Deploy/src/Templates/Plan/containerization-steps.md new file mode 100644 index 0000000000..c6fe4579a6 --- /dev/null +++ b/tools/Azure.Mcp.Tools.Deploy/src/Templates/Plan/containerization-steps.md @@ -0,0 +1,12 @@ +Additional. Containerization: + - If Dockerfiles exist, list their paths. + - If missing: Create dockerfiles for each application/service. + - Define a valid base image based on the project's language. + - Copy the required files into the container. + - Set the working directory. + - Install dependencies and build the project. + - Expose the listening ports. + - Define an entrypoint + - Create .dockerignore if required. + - Ensure the dockerfiles can be built using 'docker build'. Keep track of each dockerfile created, and its required docker build context path. Agent must create Dockerfile first before deployment! + - Output: Docker artifacts diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Templates/Plan/deployment-plan-base.md b/tools/Azure.Mcp.Tools.Deploy/src/Templates/Plan/deployment-plan-base.md index 786bb780a2..3e6675cff7 100644 --- a/tools/Azure.Mcp.Tools.Deploy/src/Templates/Plan/deployment-plan-base.md +++ b/tools/Azure.Mcp.Tools.Deploy/src/Templates/Plan/deployment-plan-base.md @@ -3,7 +3,7 @@ {Agent should fill in and polish the markdown template below to generate a deployment plan for the project. Then save it to '.azure/plan.copilotmd' file. Don't add cost estimation! Don't add extra validation steps unless it is required! Don't change the tool name!} ## **Goal** -Based on the project to provide a plan to deploy the project to {{AzureComputeHost}} using {{ProvisioningTool}}. +{{Goal}} ## **Project Information** { @@ -24,38 +24,10 @@ List how data flows between the services, example: - The container app gets its image from the Azure Container Registry. - The container app gets requests and interacts with the Azure SQL Database for data storage and retrieval. } +Sample mermaid: +{{SampleMermaid}} -## **Recommended Azure Resources** - -Recommended App service hosting the project //agent should fulfill this for each app instance -- Application {{ProjectName}} - - Hosting Service Type: {{AzureComputeHost}} // it can be Azure Container Apps, Web App Service, Azure Functions, Azure Kubernetes Service. Recommend one based on the project. - - SKU // recommend a sku based on the project, show its performance. Don't estimate the cost. - - Configuration: - - language: {language} //detect from the project, it can be nodejs, python, dotnet, etc. - - dockerFilePath: {dockerFilePath}// fulfill this if service.azureComputeHost is ContainerApp - - dockerContext: {dockerContext}// fulfill this if service.azureComputeHost is ContainerApp - - Environment Variables: [] // the env variables that are used in the project/required by service - - Dependencies Resource - - Dependency Name - - SKU // recommend a sku, show its performance. - - Service Type // it can be Azure SQL, Azure Cosmos DB, Azure Storage, etc. - - Connection Type // it can be connection string, managed identity, etc. - - Environment Variables: [] // the env variables that are used in the project/required by dependency - -Recommended Supporting Services -- Application Insights -- Log Analytics Workspace: set all app service to connect to this -- Key Vault(Optional): If there are dependencies such as postgresql/sql/mysql, create a Key Vault to store connection string. If not, the resource should not show. -If there is a Container App, the following resources are required: -- Container Registry - - -Recommended Security Configurations -If there is a Container App -- User managed identity: Must be assigned to the container app. -- AcrPull role assignment: User managed identity must have **AcrPull** role ("7f951dda-4ed3-4680-a7ca-43fe172d538d") assigned to the container registry. - +{{ResourceInfo}} ## **Execution Step** > **Below are the steps for Copilot to follow; ask Copilot to update or execute this plan.** {{ExecutionSteps}} diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Templates/Plan/existing-resource-info.md b/tools/Azure.Mcp.Tools.Deploy/src/Templates/Plan/existing-resource-info.md new file mode 100644 index 0000000000..c18332e8e9 --- /dev/null +++ b/tools/Azure.Mcp.Tools.Deploy/src/Templates/Plan/existing-resource-info.md @@ -0,0 +1,9 @@ +## **Existing Azure Resources** +| Resource Type | Name | SKU | Purpose | +|---------------|------|-----|--------| +| Container App | myapp | Consumption | Used to deploy project1 | +| Log Analytics | mylog | Standard | Not used | + + +** Missing resource** +{List required but missing resources.} diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Templates/Plan/provision-info.md b/tools/Azure.Mcp.Tools.Deploy/src/Templates/Plan/provision-info.md new file mode 100644 index 0000000000..1a91934c8a --- /dev/null +++ b/tools/Azure.Mcp.Tools.Deploy/src/Templates/Plan/provision-info.md @@ -0,0 +1,30 @@ +## **Recommended Azure Resources** + +Recommended App service hosting the project //agent should fulfill this for each app instance +- Application {{ProjectName}} + - Hosting Service Type: {{AzureComputeHost}} // it can be Azure Container Apps, Web App Service, Azure Functions, Azure Kubernetes Service. Recommend one based on the project. + - SKU // recommend a sku based on the project, show its performance. Don't estimate the cost. + - Configuration: + - language: {language} //detect from the project, it can be nodejs, python, dotnet, etc. + - dockerFilePath: {dockerFilePath}// fulfill this if service.azureComputeHost is ContainerApp + - dockerContext: {dockerContext}// fulfill this if service.azureComputeHost is ContainerApp + - Environment Variables: [] // the env variables that are used in the project/required by service + - Dependencies Resource + - Dependency Name + - SKU // recommend a sku, show its performance. + - Service Type // it can be Azure SQL, Azure Cosmos DB, Azure Storage, etc. + - Connection Type // it can be connection string, managed identity, etc. + - Environment Variables: [] // the env variables that are used in the project/required by dependency + +Recommended Supporting Services +- Application Insights +- Log Analytics Workspace: set all app service to connect to this +- Key Vault(Optional): If there are dependencies such as postgresql/sql/mysql, create a Key Vault to store connection string. If not, the resource should not show. +If there is a Container App, the following resources are required: +- Container Registry + + +Recommended Security Configurations +If there is a Container App +- User managed identity: Must be assigned to the container app. +- AcrPull role assignment: User managed identity must have **AcrPull** role ("7f951dda-4ed3-4680-a7ca-43fe172d538d") assigned to the container registry. diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Templates/Plan/sample-aks-mermaid.md b/tools/Azure.Mcp.Tools.Deploy/src/Templates/Plan/sample-aks-mermaid.md new file mode 100644 index 0000000000..c4ce4af4fe --- /dev/null +++ b/tools/Azure.Mcp.Tools.Deploy/src/Templates/Plan/sample-aks-mermaid.md @@ -0,0 +1,23 @@ +```mermaid +graph TD +%% Services +svcazurekubernetesservice_fakeservice0["`Name: fakeservice0 +Path: ..\test\project\fakeservice1 +Language: js`"] +subgraph "Compute Resources" +%% Resources +subgraph akscluster["Azure Kubernetes Service (AKS) Cluster"] +azurekubernetesservice_fakeservice0("`fakeservice0 (Containerized Service)`") +end +akscluster:::cluster +end +subgraph "Dependency Resources" +%% Dependency Resources +azurecosmosdb_db0["`db0 (Azure Cosmos DB)`"] +azuresqldatabase_db1["`db1 (Azure SQL Database)`"] +end +%% Relationships +svcazurekubernetesservice_fakeservice0 --> |"hosted on"| azurekubernetesservice_fakeservice0 +azurekubernetesservice_fakeservice0 -.-> |"secret"| azurecosmosdb_db0 +azurekubernetesservice_fakeservice0 -.-> |"secret"| azuresqldatabase_db1 +``` diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Templates/Plan/sample-app-mermaid.md b/tools/Azure.Mcp.Tools.Deploy/src/Templates/Plan/sample-app-mermaid.md new file mode 100644 index 0000000000..071b787b22 --- /dev/null +++ b/tools/Azure.Mcp.Tools.Deploy/src/Templates/Plan/sample-app-mermaid.md @@ -0,0 +1,29 @@ +```mermaid +graph TD +%% Services +svcazurecontainerapps_fakeservice0["`Name: fakeservice0 +Path: ..\test\project\fakeservice1 +Language: js`"] +svcazurecontainerapps_fakeservice1["`Name: fakeservice1 +Path: ..\test\project\fakeservice2 +Language: js`"] +subgraph "Compute Resources" +%% Resources +subgraph containerappenv["Azure Container Apps (ACA) Environment"] +azurecontainerapps_fakeservice0("`fakeservice0 (Azure Container App)`") +azurecontainerapps_fakeservice1("`fakeservice1 (Azure Container App)`") +end +containerappenv:::cluster +end +subgraph "Dependency Resources" +%% Dependency Resources +azurecosmosdb_db0["`db0 (Azure Cosmos DB)`"] +azuresqldatabase_db1["`db1 (Azure SQL Database)`"] +end +%% Relationships +svcazurecontainerapps_fakeservice0 --> |"hosted on"| azurecontainerapps_fakeservice0 +azurecontainerapps_fakeservice0 -.-> |"secret"| azurecosmosdb_db0 +azurecontainerapps_fakeservice0 -.-> |"user-identity"| azuresqldatabase_db1 +svcazurecontainerapps_fakeservice1 --> |"hosted on"| azurecontainerapps_fakeservice1 +azurecontainerapps_fakeservice1 -.-> |"http"| azurecontainerapps_fakeservice0 +``` diff --git a/tools/Azure.Mcp.Tools.Deploy/src/Templates/Plan/summary-steps.md b/tools/Azure.Mcp.Tools.Deploy/src/Templates/Plan/summary-steps.md index 5ab29e67f9..13e5bae99c 100644 --- a/tools/Azure.Mcp.Tools.Deploy/src/Templates/Plan/summary-steps.md +++ b/tools/Azure.Mcp.Tools.Deploy/src/Templates/Plan/summary-steps.md @@ -1,2 +1,2 @@ -{{StepNumber}}: Summary: +Final. Summary: 1. Summarize the deployment result and save to '.azure/summary.copilotmd'. It should list all changes deployment files and brief description of each file. Then have a diagram showing the provisioned azure resource. diff --git a/tools/Azure.Mcp.Tools.Deploy/tests/Azure.Mcp.Tools.Deploy.LiveTests/DeployCommandTests.cs b/tools/Azure.Mcp.Tools.Deploy/tests/Azure.Mcp.Tools.Deploy.LiveTests/DeployCommandTests.cs index c1b73ce2bf..74432596d6 100644 --- a/tools/Azure.Mcp.Tools.Deploy/tests/Azure.Mcp.Tools.Deploy.LiveTests/DeployCommandTests.cs +++ b/tools/Azure.Mcp.Tools.Deploy/tests/Azure.Mcp.Tools.Deploy.LiveTests/DeployCommandTests.cs @@ -31,7 +31,7 @@ public async Task Should_get_plan() { "project-name", "django" }, { "target-app-service", "ContainerApp" }, { "provisioning-tool", "AZD" }, - { "azd-iac-options", "bicep" } + { "iac-options", "bicep" } }); // assert Assert.StartsWith("# Azure Deployment Plan for django Project", result); @@ -79,11 +79,11 @@ public async Task Should_generate_pipeline() new() { { "subscription", _subscriptionId }, - { "use-azd-pipeline-config", true } + { "is-azd-project", true } }); // assert - Assert.Contains("Run `azd pipeline config` to help the user create a deployment pipeline.", result); + Assert.Contains("Use 'azd deploy --no-prompt' to skip provisioning in CD pipeline.", result); } [Fact] @@ -95,14 +95,13 @@ public async Task Should_generate_pipeline_with_github_details() new() { { "subscription", _subscriptionId }, - { "use-azd-pipeline-config", false }, - { "organization-name", "test-org" }, - { "repository-name", "test-repo" }, - { "github-environment-name", "production" } + { "is-azd-project", false }, + { "pipeline-platform", "github-actions" }, + { "deploy-option", "deploy-only" } }); // assert - Assert.StartsWith("Help the user to set up a CI/CD pipeline", result ?? string.Empty); + Assert.Contains("When user confirms that Azure resources are ready for deployment, you need to know at least two things", result ?? string.Empty); } // skip as this test need local files diff --git a/tools/Azure.Mcp.Tools.Deploy/tests/Azure.Mcp.Tools.Deploy.UnitTests/Commands/Infrastructure/RulesGetCommandTests.cs b/tools/Azure.Mcp.Tools.Deploy/tests/Azure.Mcp.Tools.Deploy.UnitTests/Commands/Infrastructure/RulesGetCommandTests.cs index 654f8dc86e..62c77293ad 100644 --- a/tools/Azure.Mcp.Tools.Deploy/tests/Azure.Mcp.Tools.Deploy.UnitTests/Commands/Infrastructure/RulesGetCommandTests.cs +++ b/tools/Azure.Mcp.Tools.Deploy/tests/Azure.Mcp.Tools.Deploy.UnitTests/Commands/Infrastructure/RulesGetCommandTests.cs @@ -131,7 +131,7 @@ public async Task Should_get_infrastructure_rules_for_azcli_deployment_tool() Assert.NotNull(result); Assert.Equal(HttpStatusCode.OK, result.Status); Assert.NotNull(result.Message); - Assert.Contains("If creating AzCli script, the script should stop if any command fails.", result.Message, StringComparison.OrdinalIgnoreCase); + Assert.Contains("The script should be idempotent", result.Message, StringComparison.OrdinalIgnoreCase); } [Fact] @@ -175,8 +175,30 @@ public async Task Should_handle_multiple_resource_types() Assert.Equal(HttpStatusCode.OK, result.Status); Assert.NotNull(result.Message); Assert.Contains("Resources: appservice, containerapp, function", result.Message, StringComparison.OrdinalIgnoreCase); - Assert.Contains("App Service Rules", result.Message, StringComparison.OrdinalIgnoreCase); + Assert.Contains("Additional requirements for App Service", result.Message, StringComparison.OrdinalIgnoreCase); Assert.Contains("Additional requirements for Container Apps", result.Message, StringComparison.OrdinalIgnoreCase); Assert.Contains("Additional requirements for Function Apps", result.Message, StringComparison.OrdinalIgnoreCase); } + + [Fact] + public async Task Should_handle_azcli_terraform_all_resource_types() + { + // arrange + var args = _commandDefinition.Parse([ + "--deployment-tool", "AzCli", + "--iac-type", "terraform", + "--resource-types", "appservice,containerapp,function,aks,azuredatabaseforpostgresql,azuredatabaseformysql,azuresqldatabase,azurecosmosdb,azurestorageaccount,azurekeyvault" + ]); + + // act + var result = await _command.ExecuteAsync(_context, args, TestContext.Current.CancellationToken); + + // assert + Assert.NotNull(result); + Assert.Equal(HttpStatusCode.OK, result.Status); + Assert.NotNull(result.Message); + Assert.Contains("Resources: appservice, containerapp, function, aks, azuredatabaseforpostgresql, azuredatabaseformysql, azuresqldatabase, azurecosmosdb, azurestorageaccount, azurekeyvault", result.Message, StringComparison.OrdinalIgnoreCase); + Assert.DoesNotContain("{{", result.Message, StringComparison.OrdinalIgnoreCase); + Assert.DoesNotContain("}}", result.Message, StringComparison.OrdinalIgnoreCase); + } } diff --git a/tools/Azure.Mcp.Tools.Deploy/tests/Azure.Mcp.Tools.Deploy.UnitTests/Commands/Pipeline/GuidanceGetCommandTests.cs b/tools/Azure.Mcp.Tools.Deploy/tests/Azure.Mcp.Tools.Deploy.UnitTests/Commands/Pipeline/GuidanceGetCommandTests.cs index 86860a1e76..1f86aa7c8d 100644 --- a/tools/Azure.Mcp.Tools.Deploy/tests/Azure.Mcp.Tools.Deploy.UnitTests/Commands/Pipeline/GuidanceGetCommandTests.cs +++ b/tools/Azure.Mcp.Tools.Deploy/tests/Azure.Mcp.Tools.Deploy.UnitTests/Commands/Pipeline/GuidanceGetCommandTests.cs @@ -36,50 +36,6 @@ public GuidanceGetCommandTests() public async Task Should_generate_pipeline() { // arrange - var args = _commandDefinition.Parse([ - "--subscription", "test-subscription-id", - "--use-azd-pipeline-config", "true" - ]); - - // act - var result = await _command.ExecuteAsync(_context, args, TestContext.Current.CancellationToken); - - // assert - Assert.NotNull(result); - Assert.Equal(HttpStatusCode.OK, result.Status); - Assert.NotNull(result.Message); - Assert.Contains("Run `azd pipeline config` to help the user create a deployment pipeline.", result.Message); - } - - [Fact] - public async Task Should_generate_pipeline_with_github_details() - { - // arrange - var args = _commandDefinition.Parse([ - "--subscription", "test-subscription-id", - "--use-azd-pipeline-config", "false", - "--organization-name", "test-org", - "--repository-name", "test-repo", - "--github-environment-name", "production" - ]); - - // act - var result = await _command.ExecuteAsync(_context, args, TestContext.Current.CancellationToken); - - // assert - Assert.NotNull(result); - Assert.Equal(HttpStatusCode.OK, result.Status); - Assert.NotNull(result.Message); - Assert.Contains("Help the user to set up a CI/CD pipeline", result.Message); - Assert.Contains("test-org", result.Message); - Assert.Contains("test-repo", result.Message); - Assert.Contains("production", result.Message); - } - - [Fact] - public async Task Should_generate_pipeline_with_default_azd_pipeline_config() - { - // arrange - not providing use-azd-pipeline-config should default to false var args = _commandDefinition.Parse([ "--subscription", "test-subscription-id" ]); @@ -91,40 +47,21 @@ public async Task Should_generate_pipeline_with_default_azd_pipeline_config() Assert.NotNull(result); Assert.Equal(HttpStatusCode.OK, result.Status); Assert.NotNull(result.Message); - Assert.Contains("Help the user to set up a CI/CD pipeline", result.Message); - Assert.Contains("Github Actions workflow", result.Message); + Assert.Contains("When user confirms that Azure resources are ready for deployment", result.Message); + Assert.Contains("Create a setup-azure-auth-for-pipeline.sh or setup-azure-auth-for-pipeline.ps1 script to automate the auth configuration.", result.Message); + Assert.Contains("Create Github environments and set up approval checks in ALL environments.", result.Message); + Assert.Contains("Use User-assigned Managed Identity with OIDC for login to Azure in the pipeline.", result.Message); } [Fact] - public async Task Should_generate_pipeline_with_minimal_github_info() + public async Task Should_generate_pipeline_with_github_actions() { // arrange var args = _commandDefinition.Parse([ "--subscription", "test-subscription-id", - "--use-azd-pipeline-config", "false" - ]); - - // act - var result = await _command.ExecuteAsync(_context, args, TestContext.Current.CancellationToken); - - // assert - Assert.NotNull(result); - Assert.Equal(HttpStatusCode.OK, result.Status); - Assert.NotNull(result.Message); - Assert.Contains("Help the user to set up a CI/CD pipeline", result.Message); - Assert.Contains("{$organization-of-repo}", result.Message); - Assert.Contains("{$repository-name}", result.Message); - Assert.Contains("dev", result.Message); // default environment - } - - [Fact] - public async Task Should_handle_guid_subscription_id() - { - // arrange - var guidSubscriptionId = "12345678-1234-1234-1234-123456789abc"; - var args = _commandDefinition.Parse([ - "--subscription", guidSubscriptionId, - "--use-azd-pipeline-config", "false" + "--is-azd-project", "false", + "--pipeline-platform", "github-actions", + "--deploy-option", "deploy-only", ]); // act @@ -134,16 +71,21 @@ public async Task Should_handle_guid_subscription_id() Assert.NotNull(result); Assert.Equal(HttpStatusCode.OK, result.Status); Assert.NotNull(result.Message); - Assert.Contains($"User is deploying to subscription {guidSubscriptionId}", result.Message); + Assert.Contains("When user confirms that Azure resources are ready for deployment", result.Message); + Assert.Contains("Create a setup-azure-auth-for-pipeline.sh or setup-azure-auth-for-pipeline.ps1 script to automate the auth configuration.", result.Message); + Assert.Contains("Create Github environments and set up approval checks in ALL environments.", result.Message); + Assert.Contains("Use User-assigned Managed Identity with OIDC for login to Azure in the pipeline.", result.Message); } [Fact] - public async Task Should_handle_non_guid_subscription_id() + public async Task Should_generate_pipeline_with_azure_devops() { - // arrange + // arrange - not providing is-azd-project should default to false var args = _commandDefinition.Parse([ - "--subscription", "my-subscription-name", - "--use-azd-pipeline-config", "false" + "--subscription", "test-subscription-id", + "--is-azd-project", "false", + "--pipeline-platform", "azure-devops", + "--deploy-option", "deploy-only", ]); // act @@ -153,16 +95,20 @@ public async Task Should_handle_non_guid_subscription_id() Assert.NotNull(result); Assert.Equal(HttpStatusCode.OK, result.Status); Assert.NotNull(result.Message); - Assert.Contains("az account show --query id -o tsv", result.Message); + Assert.Contains("When user confirms that Azure resources are ready for deployment", result.Message); + Assert.Contains("You should use a .azure/pipeline-setup.md file to outline the steps.", result.Message); + Assert.Contains("Use Service Principal(app registration) with workflow identity federation to login to Azure in the pipeline.", result.Message); + Assert.Contains("Set up Service Connection in Azure DevOps using app registration with workflow identity federation.", result.Message); } [Fact] - public async Task Should_include_service_principal_creation_steps() + public async Task Should_generate_pipeline_with_provision_and_deploy() { // arrange var args = _commandDefinition.Parse([ "--subscription", "test-subscription-id", - "--use-azd-pipeline-config", "false" + "--is-azd-project", "false", + "--deploy-option", "provision-and-deploy", ]); // act @@ -172,8 +118,6 @@ public async Task Should_include_service_principal_creation_steps() Assert.NotNull(result); Assert.Equal(HttpStatusCode.OK, result.Status); Assert.NotNull(result.Message); - Assert.Contains("az ad sp create-for-rbac", result.Message); - Assert.Contains("federated-credential create", result.Message); - Assert.Contains("gh secret set", result.Message); + Assert.Contains("When user wants to include provisioning", result.Message); } } diff --git a/tools/Azure.Mcp.Tools.Deploy/tests/Azure.Mcp.Tools.Deploy.UnitTests/Commands/Plan/GetCommandTests.cs b/tools/Azure.Mcp.Tools.Deploy/tests/Azure.Mcp.Tools.Deploy.UnitTests/Commands/Plan/GetCommandTests.cs index d35005ae1a..772e3835b4 100644 --- a/tools/Azure.Mcp.Tools.Deploy/tests/Azure.Mcp.Tools.Deploy.UnitTests/Commands/Plan/GetCommandTests.cs +++ b/tools/Azure.Mcp.Tools.Deploy/tests/Azure.Mcp.Tools.Deploy.UnitTests/Commands/Plan/GetCommandTests.cs @@ -41,7 +41,7 @@ public async Task GetPlan_Should_Return_Expected_Result() "--project-name", "django", "--target-app-service", "ContainerApp", "--provisioning-tool", "AZD", - "--azd-iac-options", "bicep" + "--iac-options", "bicep" ]); // act @@ -64,7 +64,7 @@ public async Task Should_get_plan_with_default_iac_options() "--project-name", "myapp", "--target-app-service", "WebApp", "--provisioning-tool", "azd" - // No azd-iac-options provided - should default to "bicep" + // No iac-options provided - should default to "bicep" ]); // act @@ -98,6 +98,9 @@ public async Task Should_get_plan_for_kubernetes() Assert.NotNull(result.Message); Assert.Contains("# Azure Deployment Plan for k8s-app Project", result.Message); Assert.Contains("Azure Kubernetes Service", result.Message); + Assert.Contains("Provision Azure Infrastructure with Azure CLI", result.Message); + Assert.Contains("terraform", result.Message); // Default IaC option for aks + Assert.Contains("Azure Kubernetes Service Deployment", result.Message); } [Fact] @@ -120,4 +123,30 @@ public async Task Should_get_plan_with_default_target_service() Assert.Contains("# Azure Deployment Plan for default-app Project", result.Message); Assert.Contains("Azure Container Apps", result.Message); // Should default to Container Apps } + + [Fact] + public async Task Should_get_deploy_only_plan() + { + var args = _commandDefinition.Parse([ + "--workspace-folder", "C:/", + "--project-name", "default-app", + "--target-app-service", "ContainerApp", + "--provisioning-tool", "AzCli", + "--deploy-option", "deploy-only", + "--source-type", "from-azure", + "--resource-group-name", "DefaultRG" + ]); + var result = await _command.ExecuteAsync(_context, args, TestContext.Current.CancellationToken); + + // assert + Assert.NotNull(result); + Assert.Equal(HttpStatusCode.OK, result.Status); + Assert.NotNull(result.Message); + Assert.Contains("# Azure Deployment Plan for default-app Project", result.Message); + Assert.Contains("Azure Container Apps", result.Message); // Should default to Container Apps + Assert.Contains("Containerization", result.Message); + Assert.Contains("Check Azure resources existence", result.Message); + Assert.Contains("Azure Container Registry", result.Message); + Assert.Contains("**Existing Azure Resources**", result.Message); + } } diff --git a/tools/Azure.Mcp.Tools.Deploy/tests/Azure.Mcp.Tools.Deploy.UnitTests/DeploymentPlanTemplateUtilV2Tests.cs b/tools/Azure.Mcp.Tools.Deploy/tests/Azure.Mcp.Tools.Deploy.UnitTests/DeploymentPlanTemplateUtilV2Tests.cs index ebe58ba858..4d74fece45 100644 --- a/tools/Azure.Mcp.Tools.Deploy/tests/Azure.Mcp.Tools.Deploy.UnitTests/DeploymentPlanTemplateUtilV2Tests.cs +++ b/tools/Azure.Mcp.Tools.Deploy/tests/Azure.Mcp.Tools.Deploy.UnitTests/DeploymentPlanTemplateUtilV2Tests.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. +using Azure.Mcp.Tools.Deploy.Models; using Azure.Mcp.Tools.Deploy.Services.Util; using Xunit; @@ -9,21 +10,28 @@ namespace Azure.Mcp.Tools.Deploy.UnitTests; public sealed class DeploymentPlanTemplateUtilV2Tests { [Theory] - [InlineData("TestProject", "ContainerApp", "AZD", "bicep")] - [InlineData("", "WebApp", "AzCli", "")] - [InlineData("MyApp", "AKS", "AZD", "terraform")] + [InlineData("TestProject", "ContainerApp", "AZD", "from-project", "provision-and-deploy", "bicep")] + [InlineData("", "WebApp", "AzCli", "from-azure", "deploy-only", "")] + [InlineData("MyApp", "AKS", "AzCli", "from-project", "provision-and-deploy", "terraform")] + [InlineData("TestProject1", "ContainerApp", "AzCli", "from-project", "provision-only", "bicep")] public void GetPlanTemplate_ValidInputs_ReturnsFormattedTemplate( string projectName, string targetAppService, string provisioningTool, - string azdIacOptions) + string sourceType, + string deployOption, + string iacOptions) { // Act var result = DeploymentPlanTemplateUtil.GetPlanTemplate( projectName, targetAppService, provisioningTool, - azdIacOptions); + sourceType, + deployOption, + iacOptions, + "", + "myRG"); // Assert Assert.NotNull(result); @@ -33,12 +41,31 @@ public void GetPlanTemplate_ValidInputs_ReturnsFormattedTemplate( Assert.Contains("## **Goal**", result); Assert.Contains("## **Project Information**", result); Assert.Contains("## **Azure Resources Architecture**", result); - Assert.Contains("## **Recommended Azure Resources**", result); + // Sample mermaid diagram check + if (targetAppService.ToLowerInvariant() == "aks") + { + Assert.Contains("svcazurekubernetesservice", result); + } + else + { + Assert.Contains("svcazurecontainerapps", result); + } + if (deployOption == DeployOption.DeployOnly) + { + Assert.Contains("## **Existing Azure Resources**", result); + } + else + { + Assert.Contains("## **Recommended Azure Resources**", result); + } Assert.Contains("## **Execution Step**", result); // Should not contain unprocessed placeholders for main content Assert.DoesNotContain("{{Title}}", result); Assert.DoesNotContain("{{ProvisioningTool}}", result); + Assert.DoesNotContain("{{AzureComputeHost}}", result); + Assert.DoesNotContain("{{ProjectName}}", result); + Assert.DoesNotContain("{{Goal}}", result); // Should contain appropriate provisioning tool if (provisioningTool.ToLowerInvariant() == "azd") @@ -59,7 +86,9 @@ public void GetPlanTemplate_EmptyProjectName_UsesDefaultTitle() "", "ContainerApp", "AZD", - "bicep"); + "from-project", + "provision-and-deploy", + "bicep", null, null); // Assert Assert.Contains("Azure Deployment Plan", result); @@ -77,7 +106,9 @@ public void GetPlanTemplate_WithProjectName_UsesProjectSpecificTitle() projectName, "ContainerApp", "AZD", - "bicep"); + "from-project", + "provision-and-deploy", + "bicep", null, null); // Assert Assert.Contains($"Azure Deployment Plan for {projectName} Project", result); @@ -98,7 +129,9 @@ public void GetPlanTemplate_DifferentTargetServices_MapsToCorrectAzureHost( "TestProject", targetAppService, "AZD", - "bicep"); + "from-project", + "provision-and-deploy", + "bicep", null, null); // Assert Assert.Contains(expectedAzureHost, result); @@ -112,7 +145,9 @@ public void GetPlanTemplate_AzdWithoutIacOptions_DefaultsToBicep() "TestProject", "ContainerApp", "azd", - ""); + "from-project", + "provision-and-deploy", + "", null, null); // Assert Assert.Contains("bicep", result); @@ -126,7 +161,8 @@ public void GetPlanTemplate_AksTarget_IncludesKubernetesSteps() "TestProject", "AKS", "AZD", - "bicep"); + "from-project", + "provision-and-deploy", "bicep", null, null); // Assert Assert.Contains("kubectl apply", result); @@ -142,10 +178,12 @@ public void GetPlanTemplate_ContainerAppWithAzCli_IncludesDockerSteps() "TestProject", "ContainerApp", "AzCli", - ""); + "from-project", + "provision-and-deploy", + "", null, null); // Assert - Assert.Contains("Build and Push Docker Image", result); + Assert.Contains("build + push image to ACR", result); Assert.Contains("Dockerfile", result); } } diff --git a/tools/Azure.Mcp.Tools.Deploy/tests/Azure.Mcp.Tools.Deploy.UnitTests/TemplateServiceTests.cs b/tools/Azure.Mcp.Tools.Deploy/tests/Azure.Mcp.Tools.Deploy.UnitTests/TemplateServiceTests.cs index a290a30b26..5f3468dc50 100644 --- a/tools/Azure.Mcp.Tools.Deploy/tests/Azure.Mcp.Tools.Deploy.UnitTests/TemplateServiceTests.cs +++ b/tools/Azure.Mcp.Tools.Deploy/tests/Azure.Mcp.Tools.Deploy.UnitTests/TemplateServiceTests.cs @@ -21,7 +21,10 @@ public void LoadTemplate_ValidTemplate_ReturnsContent() Assert.NotNull(result); Assert.NotEmpty(result); Assert.Contains("{{Title}}", result); - Assert.Contains("{{ProjectName}}", result); + Assert.Contains("{{Goal}}", result); + Assert.Contains("{{SampleMermaid}}", result); + Assert.Contains("{{ResourceInfo}}", result); + Assert.Contains("{{ExecutionSteps}}", result); } [Fact] @@ -42,8 +45,10 @@ public void ProcessTemplate_WithReplacements_ReplacesPlaceholders() var replacements = new Dictionary { { "Title", "Test Deployment Plan" }, - { "ProjectName", "TestProject" }, - { "ProvisioningTool", "AZD" } + { "Goal", "Deploy TestProject to Azure" }, + { "SampleMermaid", "" }, + { "ResourceInfo", "Azure existing resources" }, + { "ExecutionSteps", "" } }; // Act @@ -52,10 +57,14 @@ public void ProcessTemplate_WithReplacements_ReplacesPlaceholders() // Assert Assert.Contains("Test Deployment Plan", result); Assert.Contains("TestProject", result); - Assert.Contains("AZD", result); + Assert.Contains("", result); + Assert.Contains("Azure existing resources", result); + Assert.Contains("", result); Assert.DoesNotContain("{{Title}}", result); - Assert.DoesNotContain("{{ProjectName}}", result); - Assert.DoesNotContain("{{ProvisioningTool}}", result); + Assert.DoesNotContain("{{Goal}}", result); + Assert.DoesNotContain("{{SampleMermaid}}", result); + Assert.DoesNotContain("{{ResourceInfo}}", result); + Assert.DoesNotContain("{{ExecutionSteps}}", result); } [Fact] diff --git a/tools/Azure.Mcp.Tools.Quota/src/Azure.Mcp.Tools.Quota.csproj b/tools/Azure.Mcp.Tools.Quota/src/Azure.Mcp.Tools.Quota.csproj index b549c385e4..797bfa0f1d 100644 --- a/tools/Azure.Mcp.Tools.Quota/src/Azure.Mcp.Tools.Quota.csproj +++ b/tools/Azure.Mcp.Tools.Quota/src/Azure.Mcp.Tools.Quota.csproj @@ -26,7 +26,10 @@ + + + - \ No newline at end of file + diff --git a/tools/Azure.Mcp.Tools.Quota/src/Services/Util/AzureRegionChecker.cs b/tools/Azure.Mcp.Tools.Quota/src/Services/Util/AzureRegionChecker.cs index 4639778b8d..92319a4b86 100644 --- a/tools/Azure.Mcp.Tools.Quota/src/Services/Util/AzureRegionChecker.cs +++ b/tools/Azure.Mcp.Tools.Quota/src/Services/Util/AzureRegionChecker.cs @@ -6,8 +6,13 @@ using Azure.ResourceManager; using Azure.ResourceManager.CognitiveServices; using Azure.ResourceManager.CognitiveServices.Models; +using Azure.ResourceManager.Compute; +using Azure.ResourceManager.CosmosDB; +using Azure.ResourceManager.MySql.FlexibleServers; +using Azure.ResourceManager.MySql.FlexibleServers.Models; using Azure.ResourceManager.PostgreSql.FlexibleServers; using Azure.ResourceManager.PostgreSql.FlexibleServers.Models; +using Azure.ResourceManager.Sql; using Microsoft.Extensions.Logging; namespace Azure.Mcp.Tools.Quota.Services.Util; @@ -173,6 +178,154 @@ public override async Task> GetAvailableRegionsAsync(string resourc } } + +public class SQLRegionChecker(ArmClient armClient, string subscriptionId, ILogger logger) : AzureRegionChecker(armClient, subscriptionId, logger) +{ + public override async Task> GetAvailableRegionsAsync(string resourceType, CancellationToken cancellationToken) + { + var parts = resourceType.Split('/'); + var providerNamespace = parts[0]; + var resourceTypeName = parts[1]; + + var subscription = ResourceClient.GetSubscriptionResource(new ResourceIdentifier($"/subscriptions/{SubscriptionId}")); + var provider = await subscription.GetResourceProviderAsync(providerNamespace, cancellationToken: cancellationToken); + var regions = provider?.Value?.Data?.ResourceTypes? + .FirstOrDefault(rt => rt.ResourceType.Equals(resourceTypeName, StringComparison.OrdinalIgnoreCase)) + ?.Locations? + .Select(location => location.Replace(" ", "").ToLowerInvariant()) + .ToList() ?? []; + + var tasks = regions.Select(async region => + { + try + { + var location = new AzureLocation(region); + var capabilities = await subscription.GetCapabilitiesByLocationAsync(location, cancellationToken: cancellationToken); + + if (capabilities?.Value?.SupportedServerVersions?.Any() == true) + { + return region; + } + } + catch (Exception error) + { + Logger.LogWarning("Error checking SQL capabilities for region {Region}: {Error}", region, error.Message); + } + return null; + }); + + var results = await Task.WhenAll(tasks); + return results.Where(region => region != null).ToList()!; + } +} + + +public class MySQLRegionChecker(ArmClient armClient, string subscriptionId, ILogger logger) : AzureRegionChecker(armClient, subscriptionId, logger) +{ + public override async Task> GetAvailableRegionsAsync(string resourceType, CancellationToken cancellationToken) + { + var parts = resourceType.Split('/'); + var providerNamespace = parts[0]; + var resourceTypeName = parts[1]; + + var subscription = ResourceClient.GetSubscriptionResource(new ResourceIdentifier($"/subscriptions/{SubscriptionId}")); + var provider = await subscription.GetResourceProviderAsync(providerNamespace, cancellationToken: cancellationToken); + var regions = provider?.Value?.Data?.ResourceTypes? + .FirstOrDefault(rt => rt.ResourceType.Equals(resourceTypeName, StringComparison.OrdinalIgnoreCase)) + ?.Locations? + .Select(location => location.Replace(" ", "").ToLowerInvariant()) + .ToList() ?? []; + + var tasks = regions.Select(async region => + { + try + { + var location = new AzureLocation(region); + AsyncPageable result = subscription.GetLocationBasedCapabilitiesAsync(location, cancellationToken: cancellationToken); + await foreach (var capability in result) + { + // Check if the capability has supported flexible server editions + if (capability.SupportedFlexibleServerEditions?.Any() == true) + { + return region; + } + } + } + catch (Exception error) + { + Logger.LogWarning("Error checking MySQL capabilities for region {Region}: {Error}", region, error.Message); + } + return null; + }); + + var results = await Task.WhenAll(tasks); + return results.Where(region => region != null).ToList()!; + } +} + +public class DocumentDBRegionChecker(ArmClient armClient, string subscriptionId, ILogger logger) : AzureRegionChecker(armClient, subscriptionId, logger) +{ + public override async Task> GetAvailableRegionsAsync(string resourceType, CancellationToken cancellationToken) + { + var subscription = ResourceClient.GetSubscriptionResource(new ResourceIdentifier($"/subscriptions/{SubscriptionId}")); + var regions = new List(); + + try + { + var locationsCollection = subscription.GetCosmosDBLocations(); + await foreach (var location in locationsCollection.GetAllAsync(cancellationToken)) + { + if (location?.Data?.Properties?.IsSubscriptionRegionAccessAllowedForRegular == true) + { + var regionName = location.Data.Name?.Replace(" ", "").ToLowerInvariant(); + if (!string.IsNullOrEmpty(regionName)) + { + regions.Add(regionName); + } + } + } + } + catch (Exception error) + { + Logger.LogWarning("Error checking DocumentDB locations: {Error}", error.Message); + } + + return regions; + } +} + +public class ComputeRegionChecker(ArmClient armClient, string subscriptionId, ILogger logger) : AzureRegionChecker(armClient, subscriptionId, logger) +{ + public override async Task> GetAvailableRegionsAsync(string resourceType, CancellationToken cancellationToken) + { + var subscription = ResourceClient.GetSubscriptionResource(new ResourceIdentifier($"/subscriptions/{SubscriptionId}")); + var availableRegions = new HashSet(); + + try + { + await foreach (var sku in subscription.GetComputeResourceSkusAsync(cancellationToken: cancellationToken)) + { + if (sku?.Locations == null) + { + continue; + } + + foreach (var location in sku.Locations) + { + var normalizedLocation = location.Name.Replace(" ", "").ToLowerInvariant(); + availableRegions.Add(normalizedLocation); + } + } + } + catch (Exception error) + { + Logger.LogWarning("Error fetching compute regions for resource type {ResourceType}: {Error}", resourceType, error.Message); + } + + return [.. availableRegions.Order()]; + } +} + public static class RegionCheckerFactory { public static IRegionChecker CreateRegionChecker( @@ -197,6 +350,22 @@ public static IRegionChecker CreateRegionChecker( armClient, subscriptionId, loggerFactory.CreateLogger()), + "microsoft.sql" => new SQLRegionChecker( + armClient, + subscriptionId, + loggerFactory.CreateLogger()), + "microsoft.dbformysql" => new MySQLRegionChecker( + armClient, + subscriptionId, + loggerFactory.CreateLogger()), + "microsoft.documentdb" => new DocumentDBRegionChecker( + armClient, + subscriptionId, + loggerFactory.CreateLogger()), + "microsoft.compute" => new ComputeRegionChecker( + armClient, + subscriptionId, + loggerFactory.CreateLogger()), _ => new DefaultRegionChecker( armClient, subscriptionId, diff --git a/tools/Azure.Mcp.Tools.Quota/src/Services/Util/AzureUsageChecker.cs b/tools/Azure.Mcp.Tools.Quota/src/Services/Util/AzureUsageChecker.cs index 852b62c07d..d12258a04f 100644 --- a/tools/Azure.Mcp.Tools.Quota/src/Services/Util/AzureUsageChecker.cs +++ b/tools/Azure.Mcp.Tools.Quota/src/Services/Util/AzureUsageChecker.cs @@ -27,7 +27,8 @@ public enum ResourceProvider PostgreSQL, HDInsight, Search, - ContainerInstance + ContainerInstance, + SQL, } public record UsageInfo( @@ -78,6 +79,7 @@ public static class UsageCheckerFactory { "Microsoft.DBforPostgreSQL", ResourceProvider.PostgreSQL }, { "Microsoft.HDInsight", ResourceProvider.HDInsight }, { "Microsoft.Search", ResourceProvider.Search }, + { "Microsoft.Sql", ResourceProvider.SQL }, { "Microsoft.ContainerInstance", ResourceProvider.ContainerInstance } }; @@ -100,6 +102,7 @@ public static IUsageChecker CreateUsageChecker(TokenCredential credential, strin ResourceProvider.HDInsight => new HDInsightUsageChecker(credential, subscriptionId, loggerFactory.CreateLogger()), ResourceProvider.Search => new SearchUsageChecker(credential, subscriptionId, loggerFactory.CreateLogger()), ResourceProvider.ContainerInstance => new ContainerInstanceUsageChecker(credential, subscriptionId, loggerFactory.CreateLogger()), + ResourceProvider.SQL => new SQLUsageChecker(credential, subscriptionId, loggerFactory.CreateLogger(), httpClientFactory), _ => throw new ArgumentException($"No implementation for provider: {provider}") }; } diff --git a/tools/Azure.Mcp.Tools.Quota/src/Services/Util/Usage/ComputeUsageChecker.cs b/tools/Azure.Mcp.Tools.Quota/src/Services/Util/Usage/ComputeUsageChecker.cs index 4117e7ff75..b75eb5e49e 100644 --- a/tools/Azure.Mcp.Tools.Quota/src/Services/Util/Usage/ComputeUsageChecker.cs +++ b/tools/Azure.Mcp.Tools.Quota/src/Services/Util/Usage/ComputeUsageChecker.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. +using System.Text.RegularExpressions; using Azure.Core; using Azure.ResourceManager.Compute; using Azure.ResourceManager.Compute.Models; @@ -8,31 +9,146 @@ namespace Azure.Mcp.Tools.Quota.Services.Util.Usage; -public class ComputeUsageChecker(TokenCredential credential, string subscriptionId, ILogger logger) : AzureUsageChecker(credential, subscriptionId, logger) +public partial class ComputeUsageChecker(TokenCredential credential, string subscriptionId, ILogger logger) : AzureUsageChecker(credential, subscriptionId, logger) { + private const string VirtualMachinesMagicString = "virtualmachines"; + private const string CoresMagicString = "cores"; + private const string VCpusCapabilityName = "vCPUs"; + private const int MaxSkusPerFamily = 3; + + [GeneratedRegex(@"\s+")] + private static partial Regex WhitespaceRegex(); + + private async Task> GetUsagesForLocationAsync(string location, CancellationToken cancellationToken) + { + var subscription = ResourceClient.GetSubscriptionResource(new ResourceIdentifier($"/subscriptions/{SubscriptionId}")); + var usages = subscription.GetUsagesAsync(location, cancellationToken); + + var usageMap = new Dictionary(); + + await foreach (ComputeUsage usage in usages) + { + if (usage.Name?.Value is not null) + { + // Normalize family name + var familyName = NormalizeName(usage.Name.Value); + usageMap[familyName] = ((int)usage.Limit, usage.CurrentValue); + } + } + + return usageMap; + } + public override async Task> GetUsageForLocationAsync(string location, CancellationToken cancellationToken) { try { - var subscription = ResourceClient.GetSubscriptionResource(new ResourceIdentifier($"/subscriptions/{SubscriptionId}")); - var usages = subscription.GetUsagesAsync(location, cancellationToken); + var skus = ResourceClient.GetSubscriptionResource(new ResourceIdentifier($"/subscriptions/{SubscriptionId}")) + .GetComputeResourceSkusAsync(cancellationToken: cancellationToken); + var usageMap = await GetUsagesForLocationAsync(location, cancellationToken); var result = new List(); - await foreach (ComputeUsage item in usages.WithCancellation(cancellationToken)) + if (usageMap.TryGetValue(VirtualMachinesMagicString, out var vmUsage)) + { + if (vmUsage.Limit - vmUsage.Used <= 0) + { + Logger.LogWarning("No virtualMachines quota available for location: {Location}", location); + return CreateEmptyQuotaInfo(); + } + } + else + { + Logger.LogWarning("No virtualMachines usage info found for location: {Location}", location); + return CreateEmptyQuotaInfo(); + } + + // Track SKU count per family + var familySkuCount = new Dictionary(); + + await foreach (var sku in skus) + { + // Filter SKUs by location + if (sku.Locations is null || !sku.Locations.Any(l => l.Name.Equals(location, StringComparison.OrdinalIgnoreCase))) + { + continue; + } + + // Only process VirtualMachines resource type + if (!string.Equals(sku.ResourceType, "virtualMachines", StringComparison.OrdinalIgnoreCase)) + { + continue; + } + + if (sku.Family is not null && sku.Name is not null) + { + var normalizedFamily = NormalizeName(sku.Family); + + if (!usageMap.TryGetValue(normalizedFamily, out var usageInfo)) + { + continue; + } + + // Only keep 3 SKUs per family + var currentCount = familySkuCount.GetValueOrDefault(normalizedFamily, 0); + if (currentCount >= MaxSkusPerFamily) + { + continue; + } + + // Get vCPUs (cores) required by this SKU from capabilities + var vCpusCapability = sku.Capabilities?.FirstOrDefault(cap => + string.Equals(cap.Name, VCpusCapabilityName, StringComparison.OrdinalIgnoreCase)); + var requiredCores = 0; + if (vCpusCapability?.Value is not null) + { + _ = int.TryParse(vCpusCapability.Value, out requiredCores); + } + + // Get total cores usage info + var availableCores = 0; + if (usageMap.TryGetValue(CoresMagicString, out var coresUsageInfo)) + { + availableCores = coresUsageInfo.Limit - coresUsageInfo.Used; + } + + // Only add SKU if required cores is less than available cores + if (requiredCores > 0 && requiredCores <= availableCores) + { + result.Add(new UsageInfo( + Name: sku.Name, + Limit: usageInfo.Limit, + Used: usageInfo.Used + )); + + Logger.LogDebug( + "name: {SkuName}, required cores: {RequiredCores}, available cores: {AvailableCores}, family limit: {FamilyLimit}, family used: {FamilyUsed}", + sku.Name, requiredCores, availableCores, usageInfo.Limit, usageInfo.Used); + + familySkuCount[normalizedFamily] = currentCount + 1; + } + } + } + + // Use a default one to indicate no sku available + if (result.Count == 0) { - result.Add(new UsageInfo( - Name: item.Name?.LocalizedValue ?? item.Name?.Value ?? string.Empty, - Limit: (int)item.Limit, - Used: item.CurrentValue, - Unit: item.Unit.ToString() - )); + return CreateEmptyQuotaInfo(); } return result; } catch (Exception error) { - throw new InvalidOperationException("Failed to fetch Compute quotas. Please check your subscription permissions and service availability.", error); + Logger.LogError(error, "Error fetching compute quotas"); + throw new InvalidOperationException($"Failed to fetch Compute quotas. {error.Message}", error); } } + + private static string NormalizeName(string name) => + WhitespaceRegex().Replace(name, string.Empty).ToLowerInvariant(); + + private static List CreateEmptyQuotaInfo() => + [ + new UsageInfo(Name: "No SKU available", Limit: 0, Used: 0) + ]; } diff --git a/tools/Azure.Mcp.Tools.Quota/src/Services/Util/Usage/PostgreSQLUsageChecker.cs b/tools/Azure.Mcp.Tools.Quota/src/Services/Util/Usage/PostgreSQLUsageChecker.cs index 15bda15836..ca8c8265dc 100644 --- a/tools/Azure.Mcp.Tools.Quota/src/Services/Util/Usage/PostgreSQLUsageChecker.cs +++ b/tools/Azure.Mcp.Tools.Quota/src/Services/Util/Usage/PostgreSQLUsageChecker.cs @@ -10,6 +10,9 @@ namespace Azure.Mcp.Tools.Quota.Services.Util.Usage; public class PostgreSQLUsageChecker(TokenCredential credential, string subscriptionId, ILogger logger, IHttpClientFactory httpClientFactory) : AzureUsageChecker(credential, subscriptionId, logger) { + private const string CoresMagicString = "cores"; + private const int MinimumCoresRequired = 2; + private readonly IHttpClientFactory _httpClientFactory = httpClientFactory ?? throw new ArgumentNullException(nameof(httpClientFactory)); public override async Task> GetUsageForLocationAsync(string location, CancellationToken cancellationToken) @@ -21,7 +24,26 @@ public override async Task> GetUsageForLocationAsync(string loca if (rawResponse?.RootElement.TryGetProperty("value", out var valueElement) != true) { - return []; + return CreateEmptyQuotaInfo(); + } + + foreach (var item in valueElement.EnumerateArray()) + { + if (item.TryGetProperty("name", out var nameElement) && + nameElement.TryGetProperty("value", out var nameValue) && + nameValue.GetStringSafe() == CoresMagicString) + { + var limit = item.TryGetProperty("limit", out var limitElement) ? limitElement.GetInt32() : 0; + var used = item.TryGetProperty("currentValue", out var usedElement) ? usedElement.GetInt32() : 0; + + if (limit - used < MinimumCoresRequired) + { + Logger.LogWarning("Insufficient cores quota for PostgreSQL in location: {Location}", location); + return CreateEmptyQuotaInfo(); + } + + break; + } } var result = new List(); @@ -52,17 +74,57 @@ public override async Task> GetUsageForLocationAsync(string loca unit = unitElement.GetStringSafe(); } - result.Add(new UsageInfo(name, limit, used, unit)); + // Format name with SKU details + var displayName = GetSkuDetail(name, limit - used); + result.Add(new UsageInfo(displayName, limit, used, unit)); } return result; } catch (Exception error) { - throw new InvalidOperationException("Failed to fetch PostgreSQL quotas. Please check your subscription permissions and network connectivity.", error); + Logger.LogError(error, "Error fetching PostgreSQL quotas"); + return []; } } + // Microsoft.DBforPostgreSQL/flexibleServers: cores, standardBSFamily, standardDADSv5Family, standardDDSv4Family, standardDDSv5Family, standardDSv3Family, standardEADSv5Family, standardEDSv4Family, standardEDSv5Family, standardESv3Family + private static string GetSkuDetail(string name, int remainingQuota) + { + if (name.StartsWith("standardB", StringComparison.OrdinalIgnoreCase)) + { + return $"{name} (Burstable tier)"; + } + + if (name.StartsWith("standardD", StringComparison.OrdinalIgnoreCase)) + { + var skuParts = name[9..].Split("Family")[0]; + var prefix = skuParts[..^2].ToLowerInvariant(); + var suffix = skuParts[^2..]; + return $"{name} (GeneralPurpose tier, e.g. Standard_D2{prefix}_{suffix})"; + } + + if (name.StartsWith("standardE", StringComparison.OrdinalIgnoreCase)) + { + var skuParts = name[9..].Split("Family")[0]; + var prefix = skuParts[..^2].ToLowerInvariant(); + var suffix = skuParts[^2..]; + return $"{name} (MemoryOptimized tier, e.g. Standard_E2{prefix}_{suffix})"; + } + + if (string.Equals(name, CoresMagicString, StringComparison.OrdinalIgnoreCase)) + { + return $"{name} (remaining quota: {remainingQuota})"; + } + + return name; + } + + private static List CreateEmptyQuotaInfo() => + [ + new UsageInfo(Name: "No SKU available", Limit: 0, Used: 0) + ]; + protected async Task GetQuotaByUrlAsync(string requestUrl, CancellationToken cancellationToken = default) { try diff --git a/tools/Azure.Mcp.Tools.Quota/src/Services/Util/Usage/SQLUsageChecker .cs b/tools/Azure.Mcp.Tools.Quota/src/Services/Util/Usage/SQLUsageChecker .cs new file mode 100644 index 0000000000..f7a71f257c --- /dev/null +++ b/tools/Azure.Mcp.Tools.Quota/src/Services/Util/Usage/SQLUsageChecker .cs @@ -0,0 +1,174 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using System.Net.Http; +using System.Net.Http.Headers; +using Azure.Core; +using Microsoft.Extensions.Logging; + +namespace Azure.Mcp.Tools.Quota.Services.Util.Usage; + +public class SQLUsageChecker(TokenCredential credential, string subscriptionId, ILogger logger, IHttpClientFactory httpClientFactory) : AzureUsageChecker(credential, subscriptionId, logger) +{ + private const string ServerQuotaMagicString = "ServerQuota"; + + private static readonly string[] SkuNameList = + [ + "ServerQuota", + "RegionalVCoreQuotaForSQLDBAndDW", + "SubscriptionFreeDatabaseCount", + "SubnetQuota" + ]; + + private readonly IHttpClientFactory _httpClientFactory = httpClientFactory ?? throw new ArgumentNullException(nameof(httpClientFactory)); + + public override async Task> GetUsageForLocationAsync(string location, CancellationToken cancellationToken) + { + try + { + var apiVersion = "2015-05-01-preview"; + var requestUrl = $"{managementEndpoint}/subscriptions/{SubscriptionId}/providers/Microsoft.Sql/locations/{location}/usages?api-version={apiVersion}"; + using var rawResponse = await GetQuotaByUrlAsync(requestUrl, cancellationToken); + + if (rawResponse?.RootElement.TryGetProperty("value", out var valueElement) != true) + { + return CreateEmptyQuotaInfo(); + } + + // Check if ServerQuota is available + foreach (var item in valueElement.EnumerateArray()) + { + if (item.TryGetProperty("name", out var nameElement) && + nameElement.GetStringSafe() == ServerQuotaMagicString) + { + var limit = 0; + var used = 0; + + if (item.TryGetProperty("properties", out var propsElement)) + { + if (propsElement.TryGetProperty("limit", out var limitElement)) + { + limit = limitElement.GetInt32(); + } + + if (propsElement.TryGetProperty("currentValue", out var usedElement)) + { + used = usedElement.GetInt32(); + } + } + + if (limit - used <= 0) + { + Logger.LogWarning("No ServerQuota available for SQL in location: {Location}", location); + return CreateEmptyQuotaInfo(); + } + + break; + } + } + + var result = new List(); + foreach (var item in valueElement.EnumerateArray()) + { + var name = string.Empty; + + if (item.TryGetProperty("name", out var nameElement)) + { + name = nameElement.GetStringSafe(); + } + + // Filter by specific SKU names + if (!SkuNameList.Contains(name)) + { + continue; + } + + var limit = 0; + var used = 0; + var unit = string.Empty; + + if (item.TryGetProperty("properties", out var propsElement)) + { + if (propsElement.TryGetProperty("limit", out var limitElement)) + { + limit = limitElement.GetInt32(); + } + + if (propsElement.TryGetProperty("currentValue", out var usedElement)) + { + used = usedElement.GetInt32(); + } + + if (propsElement.TryGetProperty("unit", out var unitElement)) + { + unit = unitElement.GetStringSafe(); + } + } + + // Format name with SKU details + var displayName = GetSkuDetail(name, limit - used); + result.Add(new UsageInfo(displayName, limit, used, unit)); + } + + return result; + } + catch (Exception error) + { + Logger.LogError(error, "Error fetching SQL quotas"); + throw new InvalidOperationException($"Failed to fetch SQL quotas. {error.Message}", error); + } + } + + private static string GetSkuDetail(string name, int remainingQuota) + { + if (string.Equals(name, "serverquota", StringComparison.OrdinalIgnoreCase)) + { + return $"{name} (must be checked for all models, remaining quota: {remainingQuota})"; + } + + if (string.Equals(name, "regionalvcorequotaforsqldbanddw", StringComparison.OrdinalIgnoreCase)) + { + return $"{name} (must be checked if choose vCore model, remaining quota: {remainingQuota})"; + } + + if (string.Equals(name, "subscriptionfreedatabasecount", StringComparison.OrdinalIgnoreCase)) + { + return $"{name} (must be checked if choose free tier, remaining quota: {remainingQuota})"; + } + + return $"{name} (remaining quota: {remainingQuota})"; + } + + private static List CreateEmptyQuotaInfo() => + [ + new UsageInfo(Name: "No SKU available", Limit: 0, Used: 0) + ]; + + protected async Task GetQuotaByUrlAsync(string requestUrl, CancellationToken cancellationToken = default) + { + try + { + var token = await Credential.GetTokenAsync(new TokenRequestContext([$"{managementEndpoint}/.default"]), cancellationToken); + + using var request = new HttpRequestMessage(HttpMethod.Get, requestUrl); + request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token.Token); + request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); + + var httpClient = _httpClientFactory.CreateClient(nameof(SQLUsageChecker)); + var response = await httpClient.SendAsync(request, cancellationToken); + + if (!response.IsSuccessStatusCode) + { + throw new HttpRequestException($"HTTP error! status: {response.StatusCode}"); + } + + var content = await response.Content.ReadAsStringAsync(cancellationToken); + return JsonDocument.Parse(content); + } + catch (Exception error) + { + Logger.LogWarning("Error fetching quotas directly: {Error}", error.Message); + return null; + } + } +} diff --git a/tools/Azure.Mcp.Tools.Quota/tests/Azure.Mcp.Tools.Quota.LiveTests/QuotaCommandTests.cs b/tools/Azure.Mcp.Tools.Quota/tests/Azure.Mcp.Tools.Quota.LiveTests/QuotaCommandTests.cs index ba60488905..9849c92e8e 100644 --- a/tools/Azure.Mcp.Tools.Quota/tests/Azure.Mcp.Tools.Quota.LiveTests/QuotaCommandTests.cs +++ b/tools/Azure.Mcp.Tools.Quota/tests/Azure.Mcp.Tools.Quota.LiveTests/QuotaCommandTests.cs @@ -38,7 +38,7 @@ public sealed class QuotaCommandTests(ITestOutputHelper output, TestProxyFixture public async Task Should_check_azure_quota() { // act - var resourceTypes = "Microsoft.CognitiveServices, Microsoft.Compute, Microsoft.Storage, Microsoft.App, Microsoft.Network, Microsoft.MachineLearningServices, Microsoft.DBforPostgreSQL, Microsoft.HDInsight, Microsoft.Search, Microsoft.ContainerInstance"; + var resourceTypes = "Microsoft.CognitiveServices, Microsoft.Compute, Microsoft.Storage, Microsoft.App, Microsoft.Network, Microsoft.MachineLearningServices, Microsoft.DBforPostgreSQL, Microsoft.HDInsight, Microsoft.Search, Microsoft.ContainerInstance, Microsoft.Sql"; JsonElement? result = await CallToolAsync( "quota_usage_check", new() { @@ -79,6 +79,9 @@ public async Task Should_check_azure_quota() var containerInstanceQuotas = quotas.AssertProperty("Microsoft.ContainerInstance"); Assert.Equal(JsonValueKind.Array, containerInstanceQuotas.ValueKind); Assert.NotEmpty(containerInstanceQuotas.EnumerateArray()); + var sqlQuotas = quotas.AssertProperty("Microsoft.Sql"); + Assert.Equal(JsonValueKind.Array, sqlQuotas.ValueKind); + Assert.NotEmpty(sqlQuotas.EnumerateArray()); }