diff options
author | Pranav K <prkrishn@hotmail.com> | 2020-06-24 04:19:55 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-06-24 04:19:55 +0300 |
commit | f6a6e4bd07bd4bf51c6965382156ebce22540fb7 (patch) | |
tree | a85ffe7caa2f2daafe52614fd020252a442d9af8 /src/Components | |
parent | da03fe4c4872c10a63497a68b0e9bd85c1b947af (diff) |
Replat blazor on net5 (#23078)
* Replat blazor on net5
* Make all e2e tests pass
* Fixup
* Update js files
* Fixups
* Fixup
* Fixup
* Skip globalization tests
* Undo workarounds
* PR feedback
* Update dependencies from https://github.com/dotnet/runtime build 20200622.6
System.ComponentModel.Annotations , System.Diagnostics.DiagnosticSource , System.Diagnostics.EventLog , Microsoft.Extensions.Logging.Configuration , Microsoft.Extensions.Logging.Console , Microsoft.Extensions.Logging.Debug , Microsoft.Extensions.Logging.EventLog , Microsoft.Extensions.Logging.EventSource , Microsoft.Extensions.Logging.TraceSource , Microsoft.Extensions.Options , Microsoft.Extensions.Options.ConfigurationExtensions , Microsoft.Extensions.Options.DataAnnotations , Microsoft.Extensions.Primitives , Microsoft.Extensions.Logging.Abstractions , Microsoft.Extensions.Logging , Microsoft.Extensions.Internal.Transport , Microsoft.Extensions.Http , Microsoft.Extensions.Caching.Abstractions , Microsoft.Extensions.Caching.Memory , Microsoft.Extensions.Configuration , Microsoft.Extensions.Configuration.Abstractions , Microsoft.Extensions.Configuration.Binder , Microsoft.Extensions.Configuration.CommandLine , Microsoft.Extensions.Configuration.EnvironmentVariables , Microsoft.Extensions.Configuration.FileExtensions , Microsoft.Extensions.Configuration.Ini , Microsoft.Extensions.Configuration.Json , Microsoft.Extensions.Configuration.UserSecrets , Microsoft.Extensions.DependencyInjection , Microsoft.Extensions.DependencyInjection.Abstractions , Microsoft.Extensions.DependencyModel , Microsoft.Extensions.FileProviders.Abstractions , Microsoft.Extensions.FileProviders.Composite , Microsoft.Extensions.FileProviders.Physical , Microsoft.Extensions.FileSystemGlobbing , Microsoft.Extensions.HostFactoryResolver.Sources , Microsoft.Extensions.Hosting , Microsoft.Extensions.Hosting.Abstractions , Microsoft.Extensions.Configuration.Xml , Microsoft.NETCore.App.Runtime.win-x64 , Microsoft.NETCore.Platforms , Microsoft.Win32.Registry , Microsoft.Win32.SystemEvents , Microsoft.NETCore.App.Internal , Microsoft.NETCore.App.Ref , System.Drawing.Common , System.ServiceProcess.ServiceController , System.Text.Encodings.Web , System.Text.Json , System.Threading.Channels , System.Windows.Extensions , System.Security.Principal.Windows , System.Security.Permissions , System.Security.Cryptography.Xml , System.IO.Pipelines , System.Net.Http.Json , System.Net.Http.WinHttpHandler , System.Net.WebSockets.WebSocketProtocol , System.Reflection.Metadata , System.Runtime.CompilerServices.Unsafe , System.Security.Cryptography.Cng , System.Security.Cryptography.Pkcs
From Version 5.0.0-preview.7.20321.2 -> To Version 5.0.0-preview.7.20322.6
* Update js file
* Fix version
* Fixup
Co-authored-by: dotnet-maestro[bot] <dotnet-maestro[bot]@users.noreply.github.com>
Diffstat (limited to 'src/Components')
107 files changed, 119 insertions, 7970 deletions
diff --git a/src/Components/Components.sln b/src/Components/Components.sln index 156f3870d8..722c3a4ea1 100644 --- a/src/Components/Components.sln +++ b/src/Components/Components.sln @@ -15,24 +15,19 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Compon EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Components.WebAssembly.Tests", "WebAssembly\WebAssembly\test\Microsoft.AspNetCore.Components.WebAssembly.Tests.csproj", "{958AD6D2-174B-4B5B-BEFC-FA64B5159334}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Components.WebAssembly.Build", "WebAssembly\Build\src\Microsoft.AspNetCore.Components.WebAssembly.Build.csproj", "{E8AD67A4-77D3-4B85-AE19-4711388B62B1}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Components.WebAssembly.Build.Tests", "WebAssembly\Build\test\Microsoft.AspNetCore.Components.WebAssembly.Build.Tests.csproj", "{E38FDBB0-08C1-444E-A449-69C8A59D721B}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Components.WebAssembly.DevServer", "WebAssembly\DevServer\src\Microsoft.AspNetCore.Components.WebAssembly.DevServer.csproj", "{A6C8050D-7C18-4585-ADCF-833AC1765847}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Components.WebAssembly.Server", "WebAssembly\Server\src\Microsoft.AspNetCore.Components.WebAssembly.Server.csproj", "{A4859630-F9F7-4F5C-9FF3-6C013D7C58FA}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "testassets", "testassets", "{A7ABAC29-F73F-456D-AE54-46842CFC2E10}" + ProjectSection(SolutionItems) = preProject + WebAssembly\testassets\Wasm.Authentication.Server\Wasm.Authentication.Server.csproj = WebAssembly\testassets\Wasm.Authentication.Server\Wasm.Authentication.Server.csproj + EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HostedInAspNet.Client", "WebAssembly\testassets\HostedInAspNet.Client\HostedInAspNet.Client.csproj", "{FD37F740-A654-4117-BFB6-9112CE4C1D3B}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HostedInAspNet.Server", "WebAssembly\testassets\HostedInAspNet.Server\HostedInAspNet.Server.csproj", "{C1E2C117-BE47-4E29-94B3-753262D97A5C}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MonoSanity", "WebAssembly\testassets\MonoSanity\MonoSanity.csproj", "{F16C1A7C-A2BD-4EB1-8BC8-23B1375F3B9E}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MonoSanityClient", "WebAssembly\testassets\MonoSanityClient\MonoSanityClient.csproj", "{1C4BF2D3-44A8-4A71-B031-15B983663CB0}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StandaloneApp", "WebAssembly\testassets\StandaloneApp\StandaloneApp.csproj", "{C0FFB29E-4696-4875-9039-E5FA1AC5A42A}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Web", "Web", "{A27FF193-195B-4474-8E6C-840B2E339373}" @@ -244,16 +239,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wasm.Performance.TestApp", EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WebAssembly", "WebAssembly", "{346EC9B8-BF36-4A5E-A1A3-77879931713A}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{1FA95650-E56E-470A-82A3-BC6572E4D6CD}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Components.WebAssembly.Server.Tests", "WebAssembly\Server\test\Microsoft.AspNetCore.Components.WebAssembly.Server.Tests.csproj", "{3D0ED658-9DAC-4066-A587-795321FA1C98}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Server", "Server", "{42E3C95D-A41E-4E14-96FD-AAE8F340FD7E}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Authentication.WebAssembly.Msal", "WebAssembly\Authentication.Msal\src\Microsoft.Authentication.WebAssembly.Msal.csproj", "{4B4E4247-7BBF-444E-9737-407D34821D70}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Components.WebAssembly.Build.BrotliCompression", "WebAssembly\Compression\src\Microsoft.AspNetCore.Components.WebAssembly.Build.BrotliCompression.csproj", "{1A4C96E8-3FAF-48FB-9F3C-068FAAAB3FEE}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Components.WebAssembly.DebugProxy", "WebAssembly\DebugProxy\src\Microsoft.AspNetCore.Components.WebAssembly.DebugProxy.csproj", "{B118AE2F-8D1D-413F-BC5D-060DF7CB707D}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DevServer", "DevServer", "{C6B58D53-04E2-4D65-B445-B510A3CB7569}" @@ -268,6 +259,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Authentication", "Authentic EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Components.WebAssembly.HttpHandler", "WebAssembly\WebAssemblyHttpHandler\src\Microsoft.AspNetCore.Components.WebAssembly.HttpHandler.csproj", "{031AD67E-DDDE-4A20-874A-8D0A791C6F4C}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wasm.Authentication.Client", "WebAssembly\testassets\Wasm.Authentication.Client\Wasm.Authentication.Client.csproj", "{5F12F7B9-70BE-48F6-922A-3A1E87EE6BF0}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wasm.Authentication.Shared", "WebAssembly\testassets\Wasm.Authentication.Shared\Wasm.Authentication.Shared.csproj", "{630D5388-7A2F-42DD-9154-1F62A18CBB69}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.JSInterop", "..\JSInterop\Microsoft.JSInterop\src\Microsoft.JSInterop.csproj", "{A062ACCE-AB0D-4569-9548-4BC0D9A9174B}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -326,30 +323,6 @@ Global {958AD6D2-174B-4B5B-BEFC-FA64B5159334}.Release|x64.Build.0 = Release|Any CPU {958AD6D2-174B-4B5B-BEFC-FA64B5159334}.Release|x86.ActiveCfg = Release|Any CPU {958AD6D2-174B-4B5B-BEFC-FA64B5159334}.Release|x86.Build.0 = Release|Any CPU - {E8AD67A4-77D3-4B85-AE19-4711388B62B1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E8AD67A4-77D3-4B85-AE19-4711388B62B1}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E8AD67A4-77D3-4B85-AE19-4711388B62B1}.Debug|x64.ActiveCfg = Debug|Any CPU - {E8AD67A4-77D3-4B85-AE19-4711388B62B1}.Debug|x64.Build.0 = Debug|Any CPU - {E8AD67A4-77D3-4B85-AE19-4711388B62B1}.Debug|x86.ActiveCfg = Debug|Any CPU - {E8AD67A4-77D3-4B85-AE19-4711388B62B1}.Debug|x86.Build.0 = Debug|Any CPU - {E8AD67A4-77D3-4B85-AE19-4711388B62B1}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E8AD67A4-77D3-4B85-AE19-4711388B62B1}.Release|Any CPU.Build.0 = Release|Any CPU - {E8AD67A4-77D3-4B85-AE19-4711388B62B1}.Release|x64.ActiveCfg = Release|Any CPU - {E8AD67A4-77D3-4B85-AE19-4711388B62B1}.Release|x64.Build.0 = Release|Any CPU - {E8AD67A4-77D3-4B85-AE19-4711388B62B1}.Release|x86.ActiveCfg = Release|Any CPU - {E8AD67A4-77D3-4B85-AE19-4711388B62B1}.Release|x86.Build.0 = Release|Any CPU - {E38FDBB0-08C1-444E-A449-69C8A59D721B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E38FDBB0-08C1-444E-A449-69C8A59D721B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E38FDBB0-08C1-444E-A449-69C8A59D721B}.Debug|x64.ActiveCfg = Debug|Any CPU - {E38FDBB0-08C1-444E-A449-69C8A59D721B}.Debug|x64.Build.0 = Debug|Any CPU - {E38FDBB0-08C1-444E-A449-69C8A59D721B}.Debug|x86.ActiveCfg = Debug|Any CPU - {E38FDBB0-08C1-444E-A449-69C8A59D721B}.Debug|x86.Build.0 = Debug|Any CPU - {E38FDBB0-08C1-444E-A449-69C8A59D721B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E38FDBB0-08C1-444E-A449-69C8A59D721B}.Release|Any CPU.Build.0 = Release|Any CPU - {E38FDBB0-08C1-444E-A449-69C8A59D721B}.Release|x64.ActiveCfg = Release|Any CPU - {E38FDBB0-08C1-444E-A449-69C8A59D721B}.Release|x64.Build.0 = Release|Any CPU - {E38FDBB0-08C1-444E-A449-69C8A59D721B}.Release|x86.ActiveCfg = Release|Any CPU - {E38FDBB0-08C1-444E-A449-69C8A59D721B}.Release|x86.Build.0 = Release|Any CPU {A6C8050D-7C18-4585-ADCF-833AC1765847}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {A6C8050D-7C18-4585-ADCF-833AC1765847}.Debug|Any CPU.Build.0 = Debug|Any CPU {A6C8050D-7C18-4585-ADCF-833AC1765847}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -398,30 +371,6 @@ Global {C1E2C117-BE47-4E29-94B3-753262D97A5C}.Release|x64.Build.0 = Release|Any CPU {C1E2C117-BE47-4E29-94B3-753262D97A5C}.Release|x86.ActiveCfg = Release|Any CPU {C1E2C117-BE47-4E29-94B3-753262D97A5C}.Release|x86.Build.0 = Release|Any CPU - {F16C1A7C-A2BD-4EB1-8BC8-23B1375F3B9E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F16C1A7C-A2BD-4EB1-8BC8-23B1375F3B9E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F16C1A7C-A2BD-4EB1-8BC8-23B1375F3B9E}.Debug|x64.ActiveCfg = Debug|Any CPU - {F16C1A7C-A2BD-4EB1-8BC8-23B1375F3B9E}.Debug|x64.Build.0 = Debug|Any CPU - {F16C1A7C-A2BD-4EB1-8BC8-23B1375F3B9E}.Debug|x86.ActiveCfg = Debug|Any CPU - {F16C1A7C-A2BD-4EB1-8BC8-23B1375F3B9E}.Debug|x86.Build.0 = Debug|Any CPU - {F16C1A7C-A2BD-4EB1-8BC8-23B1375F3B9E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F16C1A7C-A2BD-4EB1-8BC8-23B1375F3B9E}.Release|Any CPU.Build.0 = Release|Any CPU - {F16C1A7C-A2BD-4EB1-8BC8-23B1375F3B9E}.Release|x64.ActiveCfg = Release|Any CPU - {F16C1A7C-A2BD-4EB1-8BC8-23B1375F3B9E}.Release|x64.Build.0 = Release|Any CPU - {F16C1A7C-A2BD-4EB1-8BC8-23B1375F3B9E}.Release|x86.ActiveCfg = Release|Any CPU - {F16C1A7C-A2BD-4EB1-8BC8-23B1375F3B9E}.Release|x86.Build.0 = Release|Any CPU - {1C4BF2D3-44A8-4A71-B031-15B983663CB0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1C4BF2D3-44A8-4A71-B031-15B983663CB0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1C4BF2D3-44A8-4A71-B031-15B983663CB0}.Debug|x64.ActiveCfg = Debug|Any CPU - {1C4BF2D3-44A8-4A71-B031-15B983663CB0}.Debug|x64.Build.0 = Debug|Any CPU - {1C4BF2D3-44A8-4A71-B031-15B983663CB0}.Debug|x86.ActiveCfg = Debug|Any CPU - {1C4BF2D3-44A8-4A71-B031-15B983663CB0}.Debug|x86.Build.0 = Debug|Any CPU - {1C4BF2D3-44A8-4A71-B031-15B983663CB0}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1C4BF2D3-44A8-4A71-B031-15B983663CB0}.Release|Any CPU.Build.0 = Release|Any CPU - {1C4BF2D3-44A8-4A71-B031-15B983663CB0}.Release|x64.ActiveCfg = Release|Any CPU - {1C4BF2D3-44A8-4A71-B031-15B983663CB0}.Release|x64.Build.0 = Release|Any CPU - {1C4BF2D3-44A8-4A71-B031-15B983663CB0}.Release|x86.ActiveCfg = Release|Any CPU - {1C4BF2D3-44A8-4A71-B031-15B983663CB0}.Release|x86.Build.0 = Release|Any CPU {C0FFB29E-4696-4875-9039-E5FA1AC5A42A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {C0FFB29E-4696-4875-9039-E5FA1AC5A42A}.Debug|Any CPU.Build.0 = Debug|Any CPU {C0FFB29E-4696-4875-9039-E5FA1AC5A42A}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -1526,18 +1475,6 @@ Global {4B4E4247-7BBF-444E-9737-407D34821D70}.Release|x64.Build.0 = Release|Any CPU {4B4E4247-7BBF-444E-9737-407D34821D70}.Release|x86.ActiveCfg = Release|Any CPU {4B4E4247-7BBF-444E-9737-407D34821D70}.Release|x86.Build.0 = Release|Any CPU - {1A4C96E8-3FAF-48FB-9F3C-068FAAAB3FEE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1A4C96E8-3FAF-48FB-9F3C-068FAAAB3FEE}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1A4C96E8-3FAF-48FB-9F3C-068FAAAB3FEE}.Debug|x64.ActiveCfg = Debug|Any CPU - {1A4C96E8-3FAF-48FB-9F3C-068FAAAB3FEE}.Debug|x64.Build.0 = Debug|Any CPU - {1A4C96E8-3FAF-48FB-9F3C-068FAAAB3FEE}.Debug|x86.ActiveCfg = Debug|Any CPU - {1A4C96E8-3FAF-48FB-9F3C-068FAAAB3FEE}.Debug|x86.Build.0 = Debug|Any CPU - {1A4C96E8-3FAF-48FB-9F3C-068FAAAB3FEE}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1A4C96E8-3FAF-48FB-9F3C-068FAAAB3FEE}.Release|Any CPU.Build.0 = Release|Any CPU - {1A4C96E8-3FAF-48FB-9F3C-068FAAAB3FEE}.Release|x64.ActiveCfg = Release|Any CPU - {1A4C96E8-3FAF-48FB-9F3C-068FAAAB3FEE}.Release|x64.Build.0 = Release|Any CPU - {1A4C96E8-3FAF-48FB-9F3C-068FAAAB3FEE}.Release|x86.ActiveCfg = Release|Any CPU - {1A4C96E8-3FAF-48FB-9F3C-068FAAAB3FEE}.Release|x86.Build.0 = Release|Any CPU {B118AE2F-8D1D-413F-BC5D-060DF7CB707D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B118AE2F-8D1D-413F-BC5D-060DF7CB707D}.Debug|Any CPU.Build.0 = Debug|Any CPU {B118AE2F-8D1D-413F-BC5D-060DF7CB707D}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -1598,6 +1535,42 @@ Global {031AD67E-DDDE-4A20-874A-8D0A791C6F4C}.Release|x64.Build.0 = Release|Any CPU {031AD67E-DDDE-4A20-874A-8D0A791C6F4C}.Release|x86.ActiveCfg = Release|Any CPU {031AD67E-DDDE-4A20-874A-8D0A791C6F4C}.Release|x86.Build.0 = Release|Any CPU + {5F12F7B9-70BE-48F6-922A-3A1E87EE6BF0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5F12F7B9-70BE-48F6-922A-3A1E87EE6BF0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5F12F7B9-70BE-48F6-922A-3A1E87EE6BF0}.Debug|x64.ActiveCfg = Debug|Any CPU + {5F12F7B9-70BE-48F6-922A-3A1E87EE6BF0}.Debug|x64.Build.0 = Debug|Any CPU + {5F12F7B9-70BE-48F6-922A-3A1E87EE6BF0}.Debug|x86.ActiveCfg = Debug|Any CPU + {5F12F7B9-70BE-48F6-922A-3A1E87EE6BF0}.Debug|x86.Build.0 = Debug|Any CPU + {5F12F7B9-70BE-48F6-922A-3A1E87EE6BF0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5F12F7B9-70BE-48F6-922A-3A1E87EE6BF0}.Release|Any CPU.Build.0 = Release|Any CPU + {5F12F7B9-70BE-48F6-922A-3A1E87EE6BF0}.Release|x64.ActiveCfg = Release|Any CPU + {5F12F7B9-70BE-48F6-922A-3A1E87EE6BF0}.Release|x64.Build.0 = Release|Any CPU + {5F12F7B9-70BE-48F6-922A-3A1E87EE6BF0}.Release|x86.ActiveCfg = Release|Any CPU + {5F12F7B9-70BE-48F6-922A-3A1E87EE6BF0}.Release|x86.Build.0 = Release|Any CPU + {630D5388-7A2F-42DD-9154-1F62A18CBB69}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {630D5388-7A2F-42DD-9154-1F62A18CBB69}.Debug|Any CPU.Build.0 = Debug|Any CPU + {630D5388-7A2F-42DD-9154-1F62A18CBB69}.Debug|x64.ActiveCfg = Debug|Any CPU + {630D5388-7A2F-42DD-9154-1F62A18CBB69}.Debug|x64.Build.0 = Debug|Any CPU + {630D5388-7A2F-42DD-9154-1F62A18CBB69}.Debug|x86.ActiveCfg = Debug|Any CPU + {630D5388-7A2F-42DD-9154-1F62A18CBB69}.Debug|x86.Build.0 = Debug|Any CPU + {630D5388-7A2F-42DD-9154-1F62A18CBB69}.Release|Any CPU.ActiveCfg = Release|Any CPU + {630D5388-7A2F-42DD-9154-1F62A18CBB69}.Release|Any CPU.Build.0 = Release|Any CPU + {630D5388-7A2F-42DD-9154-1F62A18CBB69}.Release|x64.ActiveCfg = Release|Any CPU + {630D5388-7A2F-42DD-9154-1F62A18CBB69}.Release|x64.Build.0 = Release|Any CPU + {630D5388-7A2F-42DD-9154-1F62A18CBB69}.Release|x86.ActiveCfg = Release|Any CPU + {630D5388-7A2F-42DD-9154-1F62A18CBB69}.Release|x86.Build.0 = Release|Any CPU + {A062ACCE-AB0D-4569-9548-4BC0D9A9174B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A062ACCE-AB0D-4569-9548-4BC0D9A9174B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A062ACCE-AB0D-4569-9548-4BC0D9A9174B}.Debug|x64.ActiveCfg = Debug|Any CPU + {A062ACCE-AB0D-4569-9548-4BC0D9A9174B}.Debug|x64.Build.0 = Debug|Any CPU + {A062ACCE-AB0D-4569-9548-4BC0D9A9174B}.Debug|x86.ActiveCfg = Debug|Any CPU + {A062ACCE-AB0D-4569-9548-4BC0D9A9174B}.Debug|x86.Build.0 = Debug|Any CPU + {A062ACCE-AB0D-4569-9548-4BC0D9A9174B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A062ACCE-AB0D-4569-9548-4BC0D9A9174B}.Release|Any CPU.Build.0 = Release|Any CPU + {A062ACCE-AB0D-4569-9548-4BC0D9A9174B}.Release|x64.ActiveCfg = Release|Any CPU + {A062ACCE-AB0D-4569-9548-4BC0D9A9174B}.Release|x64.Build.0 = Release|Any CPU + {A062ACCE-AB0D-4569-9548-4BC0D9A9174B}.Release|x86.ActiveCfg = Release|Any CPU + {A062ACCE-AB0D-4569-9548-4BC0D9A9174B}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1607,15 +1580,11 @@ Global {F000C49D-3857-42A4-918D-DA4C08691FE2} = {E059A46B-56E3-41E2-83F4-B5D180056F3B} {641922CD-E6F5-41E7-A085-EE07C2A7328D} = {346EC9B8-BF36-4A5E-A1A3-77879931713A} {958AD6D2-174B-4B5B-BEFC-FA64B5159334} = {346EC9B8-BF36-4A5E-A1A3-77879931713A} - {E8AD67A4-77D3-4B85-AE19-4711388B62B1} = {1FA95650-E56E-470A-82A3-BC6572E4D6CD} - {E38FDBB0-08C1-444E-A449-69C8A59D721B} = {1FA95650-E56E-470A-82A3-BC6572E4D6CD} {A6C8050D-7C18-4585-ADCF-833AC1765847} = {C6B58D53-04E2-4D65-B445-B510A3CB7569} {A4859630-F9F7-4F5C-9FF3-6C013D7C58FA} = {42E3C95D-A41E-4E14-96FD-AAE8F340FD7E} {A7ABAC29-F73F-456D-AE54-46842CFC2E10} = {7260DED9-22A9-4E9D-92F4-5E8A4404DEAF} {FD37F740-A654-4117-BFB6-9112CE4C1D3B} = {A7ABAC29-F73F-456D-AE54-46842CFC2E10} {C1E2C117-BE47-4E29-94B3-753262D97A5C} = {A7ABAC29-F73F-456D-AE54-46842CFC2E10} - {F16C1A7C-A2BD-4EB1-8BC8-23B1375F3B9E} = {A7ABAC29-F73F-456D-AE54-46842CFC2E10} - {1C4BF2D3-44A8-4A71-B031-15B983663CB0} = {A7ABAC29-F73F-456D-AE54-46842CFC2E10} {C0FFB29E-4696-4875-9039-E5FA1AC5A42A} = {A7ABAC29-F73F-456D-AE54-46842CFC2E10} {3B1A56F8-B3E0-4F33-A717-50BDD4FBE12E} = {A27FF193-195B-4474-8E6C-840B2E339373} {35A8AE1D-ED82-485E-A8E6-A357B3CB31B3} = {3D9B9B2C-E379-41BD-83D4-2E099FBDA107} @@ -1709,11 +1678,9 @@ Global {CA9948CA-B3FA-4C2E-A726-5E47BAD19457} = {F65EFF0F-ACF3-46BD-9A8F-CDA94AF1885A} {97EA0A7D-FE5E-47D1-ADDC-4BFD702F55AB} = {F65EFF0F-ACF3-46BD-9A8F-CDA94AF1885A} {346EC9B8-BF36-4A5E-A1A3-77879931713A} = {7260DED9-22A9-4E9D-92F4-5E8A4404DEAF} - {1FA95650-E56E-470A-82A3-BC6572E4D6CD} = {7260DED9-22A9-4E9D-92F4-5E8A4404DEAF} {3D0ED658-9DAC-4066-A587-795321FA1C98} = {42E3C95D-A41E-4E14-96FD-AAE8F340FD7E} {42E3C95D-A41E-4E14-96FD-AAE8F340FD7E} = {7260DED9-22A9-4E9D-92F4-5E8A4404DEAF} {4B4E4247-7BBF-444E-9737-407D34821D70} = {81250121-9B43-40B1-BF11-CE4458F2676C} - {1A4C96E8-3FAF-48FB-9F3C-068FAAAB3FEE} = {1FA95650-E56E-470A-82A3-BC6572E4D6CD} {B118AE2F-8D1D-413F-BC5D-060DF7CB707D} = {C6B58D53-04E2-4D65-B445-B510A3CB7569} {C6B58D53-04E2-4D65-B445-B510A3CB7569} = {7260DED9-22A9-4E9D-92F4-5E8A4404DEAF} {8FDD9F2E-B940-4A5F-83FD-5486D0853D76} = {7260DED9-22A9-4E9D-92F4-5E8A4404DEAF} @@ -1721,6 +1688,9 @@ Global {6B0D6C08-FC30-4822-9464-4D24FF4CDC17} = {81250121-9B43-40B1-BF11-CE4458F2676C} {81250121-9B43-40B1-BF11-CE4458F2676C} = {7260DED9-22A9-4E9D-92F4-5E8A4404DEAF} {031AD67E-DDDE-4A20-874A-8D0A791C6F4C} = {7260DED9-22A9-4E9D-92F4-5E8A4404DEAF} + {5F12F7B9-70BE-48F6-922A-3A1E87EE6BF0} = {A7ABAC29-F73F-456D-AE54-46842CFC2E10} + {630D5388-7A2F-42DD-9154-1F62A18CBB69} = {A7ABAC29-F73F-456D-AE54-46842CFC2E10} + {A062ACCE-AB0D-4569-9548-4BC0D9A9174B} = {2FC10057-7A0A-4E34-8302-879925BC0102} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {CC3C47E1-AD1A-4619-9CD3-E08A0148E5CE} diff --git a/src/Components/ComponentsNoDeps.slnf b/src/Components/ComponentsNoDeps.slnf index 2a45ec68c9..0484ef907c 100644 --- a/src/Components/ComponentsNoDeps.slnf +++ b/src/Components/ComponentsNoDeps.slnf @@ -17,9 +17,6 @@ "Server\\src\\Microsoft.AspNetCore.Components.Server.csproj", "Server\\test\\Microsoft.AspNetCore.Components.Server.Tests.csproj", "WebAssembly\\Authentication.Msal\\src\\Microsoft.Authentication.WebAssembly.Msal.csproj", - "WebAssembly\\Build\\src\\Microsoft.AspNetCore.Components.WebAssembly.Build.csproj", - "WebAssembly\\Build\\test\\Microsoft.AspNetCore.Components.WebAssembly.Build.Tests.csproj", - "WebAssembly\\Compression\\src\\Microsoft.AspNetCore.Components.WebAssembly.Build.BrotliCompression.csproj", "WebAssembly\\DebugProxy\\src\\Microsoft.AspNetCore.Components.WebAssembly.DebugProxy.csproj", "WebAssembly\\DevServer\\src\\Microsoft.AspNetCore.Components.WebAssembly.DevServer.csproj", "WebAssembly\\JSInterop\\src\\Microsoft.JSInterop.WebAssembly.csproj", @@ -32,8 +29,6 @@ "WebAssembly\\WebAssembly\\test\\Microsoft.AspNetCore.Components.WebAssembly.Tests.csproj", "WebAssembly\\testassets\\HostedInAspNet.Client\\HostedInAspNet.Client.csproj", "WebAssembly\\testassets\\HostedInAspNet.Server\\HostedInAspNet.Server.csproj", - "WebAssembly\\testassets\\MonoSanityClient\\MonoSanityClient.csproj", - "WebAssembly\\testassets\\MonoSanity\\MonoSanity.csproj", "WebAssembly\\testassets\\StandaloneApp\\StandaloneApp.csproj", "Web\\src\\Microsoft.AspNetCore.Components.Web.csproj", "Web\\test\\Microsoft.AspNetCore.Components.Web.Tests.csproj", diff --git a/src/Components/Directory.Build.targets b/src/Components/Directory.Build.targets index 9a5acfd3e6..1ecdb38eaf 100644 --- a/src/Components/Directory.Build.targets +++ b/src/Components/Directory.Build.targets @@ -1,9 +1,18 @@ <Project> + <PropertyGroup Condition="'$(UseBlazorWebAssembly)' == 'true'"> + <BlazorWebAssemblyJSPath>$(RepoRoot)src\Components\Web.JS\dist\$(Configuration)\blazor.webassembly.js</BlazorWebAssemblyJSPath> + <BlazorWebAssemblyJSMapPath>$(BlazorWebAssemblyJSPath).map</BlazorWebAssemblyJSMapPath> + + <_BlazorDevServerPath>$(RepoRoot)src/Components/WebAssembly/DevServer/src/bin/$(Configuration)/$(DefaultNetCoreTargetFramework)/blazor-devserver.dll</_BlazorDevServerPath> + <RunCommand>dotnet</RunCommand> + <RunArguments>exec "$(_BlazorDevServerPath)" serve --applicationpath "$(TargetPath)" $(AdditionalRunArguments)</RunArguments> + </PropertyGroup> + <ItemGroup> <!-- Add a project dependency without reference output assemblies to enforce build order --> <!-- Applying workaround for https://github.com/microsoft/msbuild/issues/2661 and https://github.com/dotnet/sdk/issues/952 --> <ProjectReference - Condition="'$(ReferenceBlazorBuildLocally)' == 'true' and '$(BuildNodeJS)' != 'false' and '$(BuildingInsideVisualStudio)' != 'true'" + Condition="'$(UseBlazorWebAssembly)' == 'true' and '$(BuildNodeJS)' != 'false' and '$(BuildingInsideVisualStudio)' != 'true'" Include="$(RepoRoot)src\Components\Web.JS\Microsoft.AspNetCore.Components.Web.JS.npmproj" ReferenceOutputAssemblies="false" SkipGetTargetFrameworkProperties="true" @@ -11,8 +20,6 @@ Private="false" /> </ItemGroup> - <Import Project="WebAssembly\Build\src\ReferenceFromSource.props" Condition="'$(ReferenceBlazorBuildLocally)' == 'true'" /> - <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory)..\, Directory.Build.targets))\Directory.Build.targets" /> <ItemGroup Condition="'$(FixupWebAssemblyHttpHandlerReference)' == 'true'"> diff --git a/src/Components/Web.JS/dist/Release/blazor.webassembly.js b/src/Components/Web.JS/dist/Release/blazor.webassembly.js index a04cf089d7..59c0e5f467 100644 --- a/src/Components/Web.JS/dist/Release/blazor.webassembly.js +++ b/src/Components/Web.JS/dist/Release/blazor.webassembly.js @@ -1 +1 @@ -!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=43)}([,,,function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e){window.DotNet=e;var t=[],n={},r={},o=1,a=null;function i(e){t.push(e)}function u(e,t,n,r){var o=c();if(o.invokeDotNetFromJS){var a=JSON.stringify(r,m),i=o.invokeDotNetFromJS(e,t,n,a);return i?f(i):null}throw new Error("The current dispatcher does not support synchronous calls from JS to .NET. Use invokeMethodAsync instead.")}function s(e,t,r,a){if(e&&r)throw new Error("For instance method calls, assemblyName should be null. Received '"+e+"'.");var i=o++,u=new Promise((function(e,t){n[i]={resolve:e,reject:t}}));try{var s=JSON.stringify(a,m);c().beginInvokeDotNetFromJS(i,e,t,r,s)}catch(e){l(i,!1,e)}return u}function c(){if(null!==a)return a;throw new Error("No .NET call dispatcher has been set.")}function l(e,t,r){if(!n.hasOwnProperty(e))throw new Error("There is no pending async call with ID "+e+".");var o=n[e];delete n[e],t?o.resolve(r):o.reject(r)}function f(e){return e?JSON.parse(e,(function(e,n){return t.reduce((function(t,n){return n(e,t)}),n)})):null}function d(e){return e instanceof Error?e.message+"\n"+e.stack:e?e.toString():"null"}function p(e){if(r.hasOwnProperty(e))return r[e];var t,n=window,o="window";if(e.split(".").forEach((function(e){if(!(e in n))throw new Error("Could not find '"+e+"' in '"+o+"'.");t=n,n=n[e],o+="."+e})),n instanceof Function)return n=n.bind(t),r[e]=n,n;throw new Error("The value '"+o+"' is not a function.")}e.attachDispatcher=function(e){a=e},e.attachReviver=i,e.invokeMethod=function(e,t){for(var n=[],r=2;r<arguments.length;r++)n[r-2]=arguments[r];return u(e,t,null,n)},e.invokeMethodAsync=function(e,t){for(var n=[],r=2;r<arguments.length;r++)n[r-2]=arguments[r];return s(e,t,null,n)},e.jsCallDispatcher={findJSFunction:p,invokeJSFromDotNet:function(e,t){var n=p(e).apply(null,f(t));return null==n?null:JSON.stringify(n,m)},beginInvokeJSFromDotNet:function(e,t,n){var r=new Promise((function(e){e(p(t).apply(null,f(n)))}));e&&r.then((function(t){return c().endInvokeJSFromDotNet(e,!0,JSON.stringify([e,!0,t],m))}),(function(t){return c().endInvokeJSFromDotNet(e,!1,JSON.stringify([e,!1,d(t)]))}))},endInvokeDotNetFromJS:function(e,t,n){var r=t?n:new Error(n);l(parseInt(e),t,r)}};var h=function(){function e(e){this._id=e}return e.prototype.invokeMethod=function(e){for(var t=[],n=1;n<arguments.length;n++)t[n-1]=arguments[n];return u(null,e,this._id,t)},e.prototype.invokeMethodAsync=function(e){for(var t=[],n=1;n<arguments.length;n++)t[n-1]=arguments[n];return s(null,e,this._id,t)},e.prototype.dispose=function(){s(null,"__Dispose",this._id,null).catch((function(e){return console.error(e)}))},e.prototype.serializeAsArg=function(){return{__dotNetObject:this._id}},e}();function m(e,t){return t instanceof h?t.serializeAsArg():t}i((function(e,t){return t&&"object"==typeof t&&t.hasOwnProperty("__dotNetObject")?new h(t.__dotNetObject):t}))}(t.DotNet||(t.DotNet={}))},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),n(23),n(17);var r=n(24),o=n(12),a={},i=!1;function u(e,t,n){var o=a[e];o||(o=a[e]=new r.BrowserRenderer(e)),o.attachRootComponentToLogicalElement(n,t)}t.attachRootComponentToLogicalElement=u,t.attachRootComponentToElement=function(e,t,n){var r=document.querySelector(e);if(!r)throw new Error("Could not find any element matching selector '"+e+"'.");u(n||0,o.toLogicalElement(r,!0),t)},t.renderBatch=function(e,t){var n=a[e];if(!n)throw new Error("There is no browser renderer with ID "+e+".");for(var r=t.arrayRangeReader,o=t.updatedComponents(),u=r.values(o),s=r.count(o),c=t.referenceFrames(),l=r.values(c),f=t.diffReader,d=0;d<s;d++){var p=t.updatedComponentsEntry(u,d),h=f.componentId(p),m=f.edits(p);n.updateComponent(t,h,m,l)}var v=t.disposedComponentIds(),y=r.values(v),b=r.count(v);for(d=0;d<b;d++){h=t.disposedComponentIdsEntry(y,d);n.disposeComponent(h)}var g=t.disposedEventHandlerIds(),w=r.values(g),E=r.count(g);for(d=0;d<E;d++){var _=t.disposedEventHandlerIdsEntry(w,d);n.disposeEventHandler(_)}i&&(i=!1,window.scrollTo&&window.scrollTo(0,0))},t.resetScrollAfterNextBatch=function(){i=!0}},,,function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))((function(o,a){function i(e){try{s(r.next(e))}catch(e){a(e)}}function u(e){try{s(r.throw(e))}catch(e){a(e)}}function s(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(i,u)}s((r=r.apply(e,t||[])).next())}))},o=this&&this.__generator||function(e,t){var n,r,o,a,i={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return a={next:u(0),throw:u(1),return:u(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function u(a){return function(u){return function(a){if(n)throw new TypeError("Generator is already executing.");for(;i;)try{if(n=1,r&&(o=2&a[0]?r.return:a[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,a[1])).done)return o;switch(r=0,o&&(a=[2&a[0],o.value]),a[0]){case 0:case 1:o=a;break;case 4:return i.label++,{value:a[1],done:!1};case 5:i.label++,r=a[1],a=[0];continue;case 7:a=i.ops.pop(),i.trys.pop();continue;default:if(!(o=i.trys,(o=o.length>0&&o[o.length-1])||6!==a[0]&&2!==a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]<o[3])){i.label=a[1];break}if(6===a[0]&&i.label<o[1]){i.label=o[1],o=a;break}if(o&&i.label<o[2]){i.label=o[2],i.ops.push(a);break}o[2]&&i.ops.pop(),i.trys.pop();continue}a=t.call(e,i)}catch(e){a=[6,e],r=0}finally{n=o=0}if(5&a[0])throw a[1];return{value:a[0]?a[1]:void 0,done:!0}}([a,u])}}};Object.defineProperty(t,"__esModule",{value:!0}),n(3);var a,i=n(4),u=!1,s=!1,c=null;function l(e,t,n){void 0===n&&(n=!1);var r=p(e);if(!t&&h(r))f(r,!1,n);else if(t&&location.href===e){var o=e+"?";history.replaceState(null,"",o),location.replace(e)}else n?history.replaceState(null,"",r):location.href=e}function f(e,t,n){void 0===n&&(n=!1),i.resetScrollAfterNextBatch(),n?history.replaceState(null,"",e):history.pushState(null,"",e),d(t)}function d(e){return r(this,void 0,void 0,(function(){return o(this,(function(t){switch(t.label){case 0:return c?[4,c(location.href,e)]:[3,2];case 1:t.sent(),t.label=2;case 2:return[2]}}))}))}function p(e){return(a=a||document.createElement("a")).href=e,a.href}function h(e){var t,n=(t=document.baseURI).substr(0,t.lastIndexOf("/")+1);return e.startsWith(n)}t.internalFunctions={listenForNavigationEvents:function(e){if(c=e,s)return;s=!0,window.addEventListener("popstate",(function(){return d(!1)}))},enableNavigationInterception:function(){u=!0},navigateTo:l,getBaseURI:function(){return document.baseURI},getLocationHref:function(){return location.href}},t.attachToEventDelegator=function(e){e.notifyAfterClick((function(e){if(u&&0===e.button&&!function(e){return e.ctrlKey||e.shiftKey||e.altKey||e.metaKey}(e)&&!e.defaultPrevented){var t=function e(t,n){return t?t.tagName===n?t:e(t.parentElement,n):null}(e.target,"A");if(t&&t.hasAttribute("href")){var n=t.getAttribute("target");if(!(!n||"_self"===n))return;var r=p(t.getAttribute("href"));h(r)&&(e.preventDefault(),f(r,!0))}}}))},t.navigateTo=l,t.toAbsoluteUri=p},,,,,function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=p("_blazorLogicalChildren"),o=p("_blazorLogicalParent"),a=p("_blazorLogicalEnd");function i(e,t){if(e.childNodes.length>0&&!t)throw new Error("New logical elements must start empty, or allowExistingContents must be true");return r in e||(e[r]=[]),e}function u(e,t,n){var a=e;if(e instanceof Comment&&(c(a)&&c(a).length>0))throw new Error("Not implemented: inserting non-empty logical container");if(s(a))throw new Error("Not implemented: moving existing logical children");var i=c(t);if(n<i.length){var u=i[n];u.parentNode.insertBefore(e,u),i.splice(n,0,a)}else d(e,t),i.push(a);a[o]=t,r in a||(a[r]=[])}function s(e){return e[o]||null}function c(e){return e[r]}function l(e){if(e instanceof Element)return e;if(e instanceof Comment)return e.parentNode;throw new Error("Not a valid logical element")}function f(e){var t=c(s(e));return t[Array.prototype.indexOf.call(t,e)+1]||null}function d(e,t){if(t instanceof Element)t.appendChild(e);else{if(!(t instanceof Comment))throw new Error("Cannot append node because the parent is not a valid logical element. Parent: "+t);var n=f(t);n?n.parentNode.insertBefore(e,n):d(e,s(t))}}function p(e){return"function"==typeof Symbol?Symbol():e}t.toLogicalRootCommentElement=function(e,t){if(!e.parentNode)throw new Error("Comment not connected to the DOM "+e.textContent);var n=e.parentNode,r=i(n,!0),u=c(r);return Array.from(n.childNodes).forEach((function(e){return u.push(e)})),e[o]=r,t&&(e[a]=t,i(t)),i(e)},t.toLogicalElement=i,t.createAndInsertLogicalContainer=function(e,t){var n=document.createComment("!");return u(n,e,t),n},t.insertLogicalChild=u,t.removeLogicalChild=function e(t,n){var r=c(t).splice(n,1)[0];if(r instanceof Comment)for(var o=c(r);o.length>0;)e(r,0);var a=r;a.parentNode.removeChild(a)},t.getLogicalParent=s,t.getLogicalSiblingEnd=function(e){return e[a]||null},t.getLogicalChild=function(e,t){return c(e)[t]},t.isSvgElement=function(e){return"http://www.w3.org/2000/svg"===l(e).namespaceURI},t.getLogicalChildrenArray=c,t.permuteLogicalChildren=function(e,t){var n=c(e);t.forEach((function(e){e.moveRangeStart=n[e.fromSiblingIndex],e.moveRangeEnd=function e(t){if(t instanceof Element)return t;var n=f(t);if(n)return n.previousSibling;var r=s(t);return r instanceof Element?r.lastChild:e(r)}(e.moveRangeStart)})),t.forEach((function(t){var r=t.moveToBeforeMarker=document.createComment("marker"),o=n[t.toSiblingIndex+1];o?o.parentNode.insertBefore(r,o):d(r,e)})),t.forEach((function(e){for(var t=e.moveToBeforeMarker,n=t.parentNode,r=e.moveRangeStart,o=e.moveRangeEnd,a=r;a;){var i=a.nextSibling;if(n.insertBefore(a,t),a===o)break;a=i}n.removeChild(t)})),t.forEach((function(e){n[e.toSiblingIndex]=e.moveRangeStart}))},t.getClosestDomElement=l},,,,,function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.setPlatform=function(e){return t.platform=e,t.platform}},function(e,t,n){"use strict";var r;Object.defineProperty(t,"__esModule",{value:!0}),t.dispatchEvent=function(e,t){if(!r)throw new Error("eventDispatcher not initialized. Call 'setEventDispatcher' to configure it.");return r(e,t)},t.setEventDispatcher=function(e){r=e}},,,,function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(7),o=n(4);window.Blazor={navigateTo:r.navigateTo,_internal:{attachRootComponentToElement:o.attachRootComponentToElement,navigationManager:r.internalFunctions}}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0})},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(25),o=n(26),a=n(12),i=n(29),u=n(18),s=n(7),c=document.createElement("template"),l=document.createElementNS("http://www.w3.org/2000/svg","g"),f={submit:!0},d={},p=function(){function e(e){var t=this;this.childComponentLocations={},this.browserRendererId=e,this.eventDelegator=new o.EventDelegator((function(e,n,r,o){!function(e,t,n,r,o){f[e.type]&&e.preventDefault();var a={browserRendererId:t,eventHandlerId:n,eventArgsType:r.type,eventFieldInfo:o};u.dispatchEvent(a,r.data)}(e,t.browserRendererId,n,r,o)})),s.attachToEventDelegator(this.eventDelegator)}return e.prototype.attachRootComponentToLogicalElement=function(e,t){this.attachComponentToElement(e,t),d[e]=t},e.prototype.updateComponent=function(e,t,n,r){var o=this.childComponentLocations[t];if(!o)throw new Error("No element is currently associated with component "+t);var i=d[t];if(i){var u=a.getLogicalSiblingEnd(i);delete d[t],u?function(e,t){var n=a.getLogicalParent(e);if(!n)throw new Error("Can't clear between nodes. The start node does not have a logical parent.");for(var r=a.getLogicalChildrenArray(n),o=r.indexOf(e)+1,i=r.indexOf(t),u=o;u<=i;u++)a.removeLogicalChild(n,o);e.textContent="!"}(i,u):function(e){var t;for(;t=e.firstChild;)e.removeChild(t)}(i)}var s=a.getClosestDomElement(o).ownerDocument,c=s&&s.activeElement;this.applyEdits(e,t,o,0,n,r),c instanceof HTMLElement&&s&&s.activeElement!==c&&c.focus()},e.prototype.disposeComponent=function(e){delete this.childComponentLocations[e]},e.prototype.disposeEventHandler=function(e){this.eventDelegator.removeListener(e)},e.prototype.attachComponentToElement=function(e,t){this.childComponentLocations[e]=t},e.prototype.applyEdits=function(e,t,n,o,i,u){for(var s,c=0,l=o,f=e.arrayBuilderSegmentReader,d=e.editReader,p=e.frameReader,h=f.values(i),m=f.offset(i),v=m+f.count(i),y=m;y<v;y++){var b=e.diffReader.editsEntry(h,y),g=d.editType(b);switch(g){case r.EditType.prependFrame:var w=d.newTreeIndex(b),E=e.referenceFramesEntry(u,w),_=d.siblingIndex(b);this.insertFrame(e,t,n,l+_,u,E,w);break;case r.EditType.removeFrame:_=d.siblingIndex(b);a.removeLogicalChild(n,l+_);break;case r.EditType.setAttribute:w=d.newTreeIndex(b),E=e.referenceFramesEntry(u,w),_=d.siblingIndex(b);if(!((C=a.getLogicalChild(n,l+_))instanceof Element))throw new Error("Cannot set attribute on non-element child");this.applyAttribute(e,t,C,E);break;case r.EditType.removeAttribute:var C;_=d.siblingIndex(b);if(!((C=a.getLogicalChild(n,l+_))instanceof HTMLElement))throw new Error("Cannot remove attribute from non-element child");var I=d.removedAttributeName(b);this.tryApplySpecialProperty(e,C,I,null)||C.removeAttribute(I);break;case r.EditType.updateText:w=d.newTreeIndex(b),E=e.referenceFramesEntry(u,w),_=d.siblingIndex(b);var S=a.getLogicalChild(n,l+_);if(!(S instanceof Text))throw new Error("Cannot set text content on non-text child");S.textContent=p.textContent(E);break;case r.EditType.updateMarkup:w=d.newTreeIndex(b),E=e.referenceFramesEntry(u,w),_=d.siblingIndex(b);a.removeLogicalChild(n,l+_),this.insertMarkup(e,n,l+_,E);break;case r.EditType.stepIn:_=d.siblingIndex(b);n=a.getLogicalChild(n,l+_),c++,l=0;break;case r.EditType.stepOut:n=a.getLogicalParent(n),l=0===--c?o:0;break;case r.EditType.permutationListEntry:(s=s||[]).push({fromSiblingIndex:l+d.siblingIndex(b),toSiblingIndex:l+d.moveToSiblingIndex(b)});break;case r.EditType.permutationListEnd:a.permuteLogicalChildren(n,s),s=void 0;break;default:throw new Error("Unknown edit type: "+g)}}},e.prototype.insertFrame=function(e,t,n,o,a,u,s){var c=e.frameReader,l=c.frameType(u);switch(l){case r.FrameType.element:return this.insertElement(e,t,n,o,a,u,s),1;case r.FrameType.text:return this.insertText(e,n,o,u),1;case r.FrameType.attribute:throw new Error("Attribute frames should only be present as leading children of element frames.");case r.FrameType.component:return this.insertComponent(e,n,o,u),1;case r.FrameType.region:return this.insertFrameRange(e,t,n,o,a,s+1,s+c.subtreeLength(u));case r.FrameType.elementReferenceCapture:if(n instanceof Element)return i.applyCaptureIdToElement(n,c.elementReferenceCaptureId(u)),0;throw new Error("Reference capture frames can only be children of element frames.");case r.FrameType.markup:return this.insertMarkup(e,n,o,u),1;default:throw new Error("Unknown frame type: "+l)}},e.prototype.insertElement=function(e,t,n,o,i,u,s){var c=e.frameReader,l=c.elementName(u),f="svg"===l||a.isSvgElement(n)?document.createElementNS("http://www.w3.org/2000/svg",l):document.createElement(l),d=a.toLogicalElement(f);a.insertLogicalChild(f,n,o);for(var p=s+c.subtreeLength(u),h=s+1;h<p;h++){var m=e.referenceFramesEntry(i,h);if(c.frameType(m)!==r.FrameType.attribute){this.insertFrameRange(e,t,d,0,i,h,p);break}this.applyAttribute(e,t,f,m)}f instanceof HTMLSelectElement&&"_blazorSelectValue"in f&&v(f,f._blazorSelectValue)},e.prototype.insertComponent=function(e,t,n,r){var o=a.createAndInsertLogicalContainer(t,n),i=e.frameReader.componentId(r);this.attachComponentToElement(i,o)},e.prototype.insertText=function(e,t,n,r){var o=e.frameReader.textContent(r),i=document.createTextNode(o);a.insertLogicalChild(i,t,n)},e.prototype.insertMarkup=function(e,t,n,r){for(var o,i=a.createAndInsertLogicalContainer(t,n),u=e.frameReader.markupContent(r),s=(o=u,a.isSvgElement(t)?(l.innerHTML=o||" ",l):(c.innerHTML=o||" ",c.content)),f=0;s.firstChild;)a.insertLogicalChild(s.firstChild,i,f++)},e.prototype.applyAttribute=function(e,t,n,r){var o=e.frameReader,a=o.attributeName(r),i=o.attributeEventHandlerId(r);if(i){var u=m(a);this.eventDelegator.setListener(n,u,i,t)}else this.tryApplySpecialProperty(e,n,a,r)||n.setAttribute(a,o.attributeValue(r))},e.prototype.tryApplySpecialProperty=function(e,t,n,r){switch(n){case"value":return this.tryApplyValueProperty(e,t,r);case"checked":return this.tryApplyCheckedProperty(e,t,r);default:return!!n.startsWith("__internal_")&&(this.applyInternalAttribute(e,t,n.substring("__internal_".length),r),!0)}},e.prototype.applyInternalAttribute=function(e,t,n,r){var o=r?e.frameReader.attributeValue(r):null;if(n.startsWith("stopPropagation_")){var a=m(n.substring("stopPropagation_".length));this.eventDelegator.setStopPropagation(t,a,null!==o)}else{if(!n.startsWith("preventDefault_"))throw new Error("Unsupported internal attribute '"+n+"'");a=m(n.substring("preventDefault_".length));this.eventDelegator.setPreventDefault(t,a,null!==o)}},e.prototype.tryApplyValueProperty=function(e,t,n){var r=e.frameReader;if("INPUT"===t.tagName&&"time"===t.getAttribute("type")&&!t.getAttribute("step")){var o=n?r.attributeValue(n):null;if(o)return t.value=o.substring(0,5),!0}switch(t.tagName){case"INPUT":case"SELECT":case"TEXTAREA":var a=n?r.attributeValue(n):null;return t instanceof HTMLSelectElement?(v(t,a),t._blazorSelectValue=a):t.value=a,!0;case"OPTION":(a=n?r.attributeValue(n):null)||""===a?t.setAttribute("value",a):t.removeAttribute("value");var i=this.findClosestAncestorSelectElement(t);return i&&"_blazorSelectValue"in i&&i._blazorSelectValue===a&&(this.tryApplyValueProperty(e,i,n),delete i._blazorSelectValue),!0;default:return!1}},e.prototype.tryApplyCheckedProperty=function(e,t,n){if("INPUT"===t.tagName){var r=n?e.frameReader.attributeValue(n):null;return t.checked=null!==r,!0}return!1},e.prototype.findClosestAncestorSelectElement=function(e){for(;e;){if(e instanceof HTMLSelectElement)return e;e=e.parentElement}return null},e.prototype.insertFrameRange=function(e,t,n,r,o,a,i){for(var u=r,s=a;s<i;s++){var c=e.referenceFramesEntry(o,s);r+=this.insertFrame(e,t,n,r,o,c,s),s+=h(e,c)}return r-u},e}();function h(e,t){var n=e.frameReader;switch(n.frameType(t)){case r.FrameType.component:case r.FrameType.element:case r.FrameType.region:return n.subtreeLength(t)-1;default:return 0}}function m(e){if(e.startsWith("on"))return e.substring(2);throw new Error("Attribute should be an event name, but doesn't start with 'on'. Value: '"+e+"'")}function v(e,t){e.value=t||""}t.BrowserRenderer=p},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e){e[e.prependFrame=1]="prependFrame",e[e.removeFrame=2]="removeFrame",e[e.setAttribute=3]="setAttribute",e[e.removeAttribute=4]="removeAttribute",e[e.updateText=5]="updateText",e[e.stepIn=6]="stepIn",e[e.stepOut=7]="stepOut",e[e.updateMarkup=8]="updateMarkup",e[e.permutationListEntry=9]="permutationListEntry",e[e.permutationListEnd=10]="permutationListEnd"}(t.EditType||(t.EditType={})),function(e){e[e.element=1]="element",e[e.text=2]="text",e[e.attribute=3]="attribute",e[e.component=4]="component",e[e.region=5]="region",e[e.elementReferenceCapture=6]="elementReferenceCapture",e[e.markup=8]="markup"}(t.FrameType||(t.FrameType={}))},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(27),o=n(28),a=l(["abort","blur","change","error","focus","load","loadend","loadstart","mouseenter","mouseleave","progress","reset","scroll","submit","unload","DOMNodeInsertedIntoDocument","DOMNodeRemovedFromDocument"]),i=l(["click","dblclick","mousedown","mousemove","mouseup"]),u=function(){function e(t){this.onEvent=t,this.afterClickCallbacks=[];var n=++e.nextEventDelegatorId;this.eventsCollectionKey="_blazorEvents_"+n,this.eventInfoStore=new s(this.onGlobalEvent.bind(this))}return e.prototype.setListener=function(e,t,n,r){var o=this.getEventHandlerInfosForElement(e,!0),a=o.getHandler(t);if(a)this.eventInfoStore.update(a.eventHandlerId,n);else{var i={element:e,eventName:t,eventHandlerId:n,renderingComponentId:r};this.eventInfoStore.add(i),o.setHandler(t,i)}},e.prototype.removeListener=function(e){var t=this.eventInfoStore.remove(e);if(t){var n=t.element,r=this.getEventHandlerInfosForElement(n,!1);r&&r.removeHandler(t.eventName)}},e.prototype.notifyAfterClick=function(e){this.afterClickCallbacks.push(e),this.eventInfoStore.addGlobalListener("click")},e.prototype.setStopPropagation=function(e,t,n){this.getEventHandlerInfosForElement(e,!0).stopPropagation(t,n)},e.prototype.setPreventDefault=function(e,t,n){this.getEventHandlerInfosForElement(e,!0).preventDefault(t,n)},e.prototype.onGlobalEvent=function(e){if(e.target instanceof Element){for(var t,n,u=e.target,s=null,c=a.hasOwnProperty(e.type),l=!1;u;){var f=this.getEventHandlerInfosForElement(u,!1);if(f){var d=f.getHandler(e.type);if(d&&(t=u,n=e.type,!((t instanceof HTMLButtonElement||t instanceof HTMLInputElement||t instanceof HTMLTextAreaElement||t instanceof HTMLSelectElement)&&i.hasOwnProperty(n)&&t.disabled))){s||(s=r.EventForDotNet.fromDOMEvent(e));var p=o.EventFieldInfo.fromEvent(d.renderingComponentId,e);this.onEvent(e,d.eventHandlerId,s,p)}f.stopPropagation(e.type)&&(l=!0),f.preventDefault(e.type)&&e.preventDefault()}u=c||l?null:u.parentElement}"click"===e.type&&this.afterClickCallbacks.forEach((function(t){return t(e)}))}},e.prototype.getEventHandlerInfosForElement=function(e,t){return e.hasOwnProperty(this.eventsCollectionKey)?e[this.eventsCollectionKey]:t?e[this.eventsCollectionKey]=new c:null},e.nextEventDelegatorId=0,e}();t.EventDelegator=u;var s=function(){function e(e){this.globalListener=e,this.infosByEventHandlerId={},this.countByEventName={}}return e.prototype.add=function(e){if(this.infosByEventHandlerId[e.eventHandlerId])throw new Error("Event "+e.eventHandlerId+" is already tracked");this.infosByEventHandlerId[e.eventHandlerId]=e,this.addGlobalListener(e.eventName)},e.prototype.addGlobalListener=function(e){if(this.countByEventName.hasOwnProperty(e))this.countByEventName[e]++;else{this.countByEventName[e]=1;var t=a.hasOwnProperty(e);document.addEventListener(e,this.globalListener,t)}},e.prototype.update=function(e,t){if(this.infosByEventHandlerId.hasOwnProperty(t))throw new Error("Event "+t+" is already tracked");var n=this.infosByEventHandlerId[e];delete this.infosByEventHandlerId[e],n.eventHandlerId=t,this.infosByEventHandlerId[t]=n},e.prototype.remove=function(e){var t=this.infosByEventHandlerId[e];if(t){delete this.infosByEventHandlerId[e];var n=t.eventName;0==--this.countByEventName[n]&&(delete this.countByEventName[n],document.removeEventListener(n,this.globalListener))}return t},e}(),c=function(){function e(){this.handlers={},this.preventDefaultFlags=null,this.stopPropagationFlags=null}return e.prototype.getHandler=function(e){return this.handlers.hasOwnProperty(e)?this.handlers[e]:null},e.prototype.setHandler=function(e,t){this.handlers[e]=t},e.prototype.removeHandler=function(e){delete this.handlers[e]},e.prototype.preventDefault=function(e,t){return void 0!==t&&(this.preventDefaultFlags=this.preventDefaultFlags||{},this.preventDefaultFlags[e]=t),!!this.preventDefaultFlags&&this.preventDefaultFlags[e]},e.prototype.stopPropagation=function(e,t){return void 0!==t&&(this.stopPropagationFlags=this.stopPropagationFlags||{},this.stopPropagationFlags[e]=t),!!this.stopPropagationFlags&&this.stopPropagationFlags[e]},e}();function l(e){var t={};return e.forEach((function(e){t[e]=!0})),t}},function(e,t,n){"use strict";var r=this&&this.__assign||function(){return(r=Object.assign||function(e){for(var t,n=1,r=arguments.length;n<r;n++)for(var o in t=arguments[n])Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o]);return e}).apply(this,arguments)};Object.defineProperty(t,"__esModule",{value:!0});var o=function(){function e(e,t){this.type=e,this.data=t}return e.fromDOMEvent=function(t){var n=t.target;switch(t.type){case"input":case"change":if(function(e){return-1!==i.indexOf(e.getAttribute("type"))}(n)){var o=function(e){var t=e.value,n=e.type;switch(n){case"date":case"datetime-local":case"month":return t;case"time":return 5===t.length?t+":00":t;case"week":return t}throw new Error("Invalid element type '"+n+"'.")}(n);return new e("change",{type:t.type,value:o})}var u=function(e){return!!e&&"INPUT"===e.tagName&&"checkbox"===e.getAttribute("type")}(n)?!!n.checked:n.value;return new e("change",{type:t.type,value:u});case"copy":case"cut":case"paste":return new e("clipboard",{type:t.type});case"drag":case"dragend":case"dragenter":case"dragleave":case"dragover":case"dragstart":case"drop":return new e("drag",function(e){return r(r({},a(e)),{dataTransfer:e.dataTransfer})}(t));case"focus":case"blur":case"focusin":case"focusout":return new e("focus",{type:t.type});case"keydown":case"keyup":case"keypress":return new e("keyboard",function(e){return{type:e.type,key:e.key,code:e.code,location:e.location,repeat:e.repeat,ctrlKey:e.ctrlKey,shiftKey:e.shiftKey,altKey:e.altKey,metaKey:e.metaKey}}(t));case"contextmenu":case"click":case"mouseover":case"mouseout":case"mousemove":case"mousedown":case"mouseup":case"dblclick":return new e("mouse",a(t));case"error":return new e("error",function(e){return{type:e.type,message:e.message,filename:e.filename,lineno:e.lineno,colno:e.colno}}(t));case"loadstart":case"timeout":case"abort":case"load":case"loadend":case"progress":return new e("progress",function(e){return{type:e.type,lengthComputable:e.lengthComputable,loaded:e.loaded,total:e.total}}(t));case"touchcancel":case"touchend":case"touchmove":case"touchenter":case"touchleave":case"touchstart":return new e("touch",function(e){function t(e){for(var t=[],n=0;n<e.length;n++){var r=e[n];t.push({identifier:r.identifier,clientX:r.clientX,clientY:r.clientY,screenX:r.screenX,screenY:r.screenY,pageX:r.pageX,pageY:r.pageY})}return t}return{type:e.type,detail:e.detail,touches:t(e.touches),targetTouches:t(e.targetTouches),changedTouches:t(e.changedTouches),ctrlKey:e.ctrlKey,shiftKey:e.shiftKey,altKey:e.altKey,metaKey:e.metaKey}}(t));case"gotpointercapture":case"lostpointercapture":case"pointercancel":case"pointerdown":case"pointerenter":case"pointerleave":case"pointermove":case"pointerout":case"pointerover":case"pointerup":return new e("pointer",function(e){return r(r({},a(e)),{pointerId:e.pointerId,width:e.width,height:e.height,pressure:e.pressure,tiltX:e.tiltX,tiltY:e.tiltY,pointerType:e.pointerType,isPrimary:e.isPrimary})}(t));case"wheel":case"mousewheel":return new e("wheel",function(e){return r(r({},a(e)),{deltaX:e.deltaX,deltaY:e.deltaY,deltaZ:e.deltaZ,deltaMode:e.deltaMode})}(t));default:return new e("unknown",{type:t.type})}},e}();function a(e){return{type:e.type,detail:e.detail,screenX:e.screenX,screenY:e.screenY,clientX:e.clientX,clientY:e.clientY,offsetX:e.offsetX,offsetY:e.offsetY,button:e.button,buttons:e.buttons,ctrlKey:e.ctrlKey,shiftKey:e.shiftKey,altKey:e.altKey,metaKey:e.metaKey}}t.EventForDotNet=o;var i=["date","datetime-local","month","time","week"]},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e,t){this.componentId=e,this.fieldValue=t}return e.fromEvent=function(t,n){var r=n.target;if(r instanceof Element){var o=function(e){if(e instanceof HTMLInputElement)return e.type&&"checkbox"===e.type.toLowerCase()?{value:e.checked}:{value:e.value};if(e instanceof HTMLSelectElement||e instanceof HTMLTextAreaElement)return{value:e.value};return null}(r);if(o)return new e(t,o.value)}return null},e}();t.EventFieldInfo=r},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(3);function o(e){return"_bl_"+e}t.applyCaptureIdToElement=function(e,t){e.setAttribute(o(t),"")};r.DotNet.attachReviver((function(e,t){return t&&"object"==typeof t&&t.hasOwnProperty("__internalId")&&"string"==typeof t.__internalId?(n=t.__internalId,r="["+o(n)+"]",document.querySelector(r)):t;var n,r}))},function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))((function(o,a){function i(e){try{s(r.next(e))}catch(e){a(e)}}function u(e){try{s(r.throw(e))}catch(e){a(e)}}function s(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(i,u)}s((r=r.apply(e,t||[])).next())}))},o=this&&this.__generator||function(e,t){var n,r,o,a,i={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return a={next:u(0),throw:u(1),return:u(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function u(a){return function(u){return function(a){if(n)throw new TypeError("Generator is already executing.");for(;i;)try{if(n=1,r&&(o=2&a[0]?r.return:a[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,a[1])).done)return o;switch(r=0,o&&(a=[2&a[0],o.value]),a[0]){case 0:case 1:o=a;break;case 4:return i.label++,{value:a[1],done:!1};case 5:i.label++,r=a[1],a=[0];continue;case 7:a=i.ops.pop(),i.trys.pop();continue;default:if(!(o=i.trys,(o=o.length>0&&o[o.length-1])||6!==a[0]&&2!==a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]<o[3])){i.label=a[1];break}if(6===a[0]&&i.label<o[1]){i.label=o[1],o=a;break}if(o&&i.label<o[2]){i.label=o[2],i.ops.push(a);break}o[2]&&i.ops.pop(),i.trys.pop();continue}a=t.call(e,i)}catch(e){a=[6,e],r=0}finally{n=o=0}if(5&a[0])throw a[1];return{value:a[0]?a[1]:void 0,done:!0}}([a,u])}}};Object.defineProperty(t,"__esModule",{value:!0});var a=!1;t.showErrorNotification=function(){return r(this,void 0,void 0,(function(){var e;return o(this,(function(t){return(e=document.querySelector("#blazor-error-ui"))&&(e.style.display="block"),a||(a=!0,document.querySelectorAll("#blazor-error-ui .reload").forEach((function(e){e.onclick=function(e){location.reload(),e.preventDefault()}})),document.querySelectorAll("#blazor-error-ui .dismiss").forEach((function(e){e.onclick=function(e){var t=document.querySelector("#blazor-error-ui");t&&(t.style.display="none"),e.preventDefault()}}))),[2]}))}))}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=Math.pow(2,32),o=Math.pow(2,21)-1;function a(e,t){return e[t]+(e[t+1]<<8)+(e[t+2]<<16)+(e[t+3]<<24>>>0)}t.readInt32LE=function(e,t){return e[t]|e[t+1]<<8|e[t+2]<<16|e[t+3]<<24},t.readUint32LE=a,t.readUint64LE=function(e,t){var n=a(e,t+4);if(n>o)throw new Error("Cannot read uint64 with high order part "+n+", because the result would exceed Number.MAX_SAFE_INTEGER.");return n*r+a(e,t)},t.readLEB128=function(e,t){for(var n=0,r=0,o=0;o<4;o++){var a=e[t+o];if(n|=(127&a)<<r,a<128)break;r+=7}return n},t.numLEB128Bytes=function(e){return e<128?1:e<16384?2:e<2097152?3:4}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r="function"==typeof TextDecoder?new TextDecoder("utf-8"):null;t.decodeUtf8=r?r.decode.bind(r):function(e){var t=0,n=e.length,r=[],o=[];for(;t<n;){var a=e[t++];if(0===a)break;if(0==(128&a))r.push(a);else if(192==(224&a)){var i=63&e[t++];r.push((31&a)<<6|i)}else if(224==(240&a)){i=63&e[t++];var u=63&e[t++];r.push((31&a)<<12|i<<6|u)}else if(240==(248&a)){i=63&e[t++],u=63&e[t++];var s=63&e[t++],c=(7&a)<<18|i<<12|u<<6|s;c>65535&&(c-=65536,r.push(c>>>10&1023|55296),c=56320|1023&c),r.push(c)}r.length>1024&&(o.push(String.fromCharCode.apply(null,r)),r.length=0)}return o.push(String.fromCharCode.apply(null,r)),o.join("")}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.shouldAutoStart=function(){return!(!document||!document.currentScript||"false"===document.currentScript.getAttribute("autostart"))}},,,,,,,,,,function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))((function(o,a){function i(e){try{s(r.next(e))}catch(e){a(e)}}function u(e){try{s(r.throw(e))}catch(e){a(e)}}function s(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(i,u)}s((r=r.apply(e,t||[])).next())}))},o=this&&this.__generator||function(e,t){var n,r,o,a,i={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return a={next:u(0),throw:u(1),return:u(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function u(a){return function(u){return function(a){if(n)throw new TypeError("Generator is already executing.");for(;i;)try{if(n=1,r&&(o=2&a[0]?r.return:a[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,a[1])).done)return o;switch(r=0,o&&(a=[2&a[0],o.value]),a[0]){case 0:case 1:o=a;break;case 4:return i.label++,{value:a[1],done:!1};case 5:i.label++,r=a[1],a=[0];continue;case 7:a=i.ops.pop(),i.trys.pop();continue;default:if(!(o=i.trys,(o=o.length>0&&o[o.length-1])||6!==a[0]&&2!==a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]<o[3])){i.label=a[1];break}if(6===a[0]&&i.label<o[1]){i.label=o[1],o=a;break}if(o&&i.label<o[2]){i.label=o[2],i.ops.push(a);break}o[2]&&i.ops.pop(),i.trys.pop();continue}a=t.call(e,i)}catch(e){a=[6,e],r=0}finally{n=o=0}if(5&a[0])throw a[1];return{value:a[0]?a[1]:void 0,done:!0}}([a,u])}}},a=this&&this.__read||function(e,t){var n="function"==typeof Symbol&&e[Symbol.iterator];if(!n)return e;var r,o,a=n.call(e),i=[];try{for(;(void 0===t||t-- >0)&&!(r=a.next()).done;)i.push(r.value)}catch(e){o={error:e}}finally{try{r&&!r.done&&(n=a.return)&&n.call(a)}finally{if(o)throw o.error}}return i};Object.defineProperty(t,"__esModule",{value:!0});var i=n(3);n(22);var u=n(17),s=n(44),c=n(4),l=n(47),f=n(33),d=n(18),p=n(48),h=n(49),m=n(50),v=!1;function y(e){return r(this,void 0,void 0,(function(){var t,n,f,y,b,g,w,E=this;return o(this,(function(_){switch(_.label){case 0:if(v)throw new Error("Blazor has already started.");return v=!0,d.setEventDispatcher((function(e,t){return i.DotNet.invokeMethodAsync("Microsoft.AspNetCore.Components.WebAssembly","DispatchEvent",e,JSON.stringify(t))})),t=u.setPlatform(s.monoPlatform),window.Blazor.platform=t,window.Blazor._internal.renderBatch=function(e,t){c.renderBatch(e,new l.SharedMemoryRenderBatch(t))},n=window.Blazor._internal.navigationManager.getBaseURI,f=window.Blazor._internal.navigationManager.getLocationHref,window.Blazor._internal.navigationManager.getUnmarshalledBaseURI=function(){return BINDING.js_string_to_mono_string(n())},window.Blazor._internal.navigationManager.getUnmarshalledLocationHref=function(){return BINDING.js_string_to_mono_string(f())},window.Blazor._internal.navigationManager.listenForNavigationEvents((function(e,t){return r(E,void 0,void 0,(function(){return o(this,(function(n){switch(n.label){case 0:return[4,i.DotNet.invokeMethodAsync("Microsoft.AspNetCore.Components.WebAssembly","NotifyLocationChanged",e,t)];case 1:return n.sent(),[2]}}))}))})),[4,m.BootConfigResult.initAsync()];case 1:return y=_.sent(),[4,Promise.all([p.WebAssemblyResourceLoader.initAsync(y.bootConfig,e||{}),h.WebAssemblyConfigLoader.initAsync(y)])];case 2:b=a.apply(void 0,[_.sent(),1]),g=b[0],_.label=3;case 3:return _.trys.push([3,5,,6]),[4,t.start(g)];case 4:return _.sent(),[3,6];case 5:throw w=_.sent(),new Error("Failed to start platform. Reason: "+w);case 6:return t.callEntryPoint(g.bootConfig.entryAssembly),[2]}}))}))}window.Blazor.start=y,f.shouldAutoStart()&&y().catch((function(e){"undefined"!=typeof Module&&Module.printErr?Module.printErr(e):console.error(e)}))},function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))((function(o,a){function i(e){try{s(r.next(e))}catch(e){a(e)}}function u(e){try{s(r.throw(e))}catch(e){a(e)}}function s(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(i,u)}s((r=r.apply(e,t||[])).next())}))},o=this&&this.__generator||function(e,t){var n,r,o,a,i={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return a={next:u(0),throw:u(1),return:u(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function u(a){return function(u){return function(a){if(n)throw new TypeError("Generator is already executing.");for(;i;)try{if(n=1,r&&(o=2&a[0]?r.return:a[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,a[1])).done)return o;switch(r=0,o&&(a=[2&a[0],o.value]),a[0]){case 0:case 1:o=a;break;case 4:return i.label++,{value:a[1],done:!1};case 5:i.label++,r=a[1],a=[0];continue;case 7:a=i.ops.pop(),i.trys.pop();continue;default:if(!(o=i.trys,(o=o.length>0&&o[o.length-1])||6!==a[0]&&2!==a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]<o[3])){i.label=a[1];break}if(6===a[0]&&i.label<o[1]){i.label=o[1],o=a;break}if(o&&i.label<o[2]){i.label=o[2],i.ops.push(a);break}o[2]&&i.ops.pop(),i.trys.pop();continue}a=t.call(e,i)}catch(e){a=[6,e],r=0}finally{n=o=0}if(5&a[0])throw a[1];return{value:a[0]?a[1]:void 0,done:!0}}([a,u])}}};Object.defineProperty(t,"__esModule",{value:!0});var a,i=n(3),u=n(45),s=n(30),c=n(46),l=Math.pow(2,32),f=Math.pow(2,21)-1;function d(e){return Module.HEAP32[e>>2]}t.monoPlatform={start:function(e){return new Promise((function(t,n){var l,f;u.attachDebuggerHotkey(e),window.Browser={init:function(){}},l=function(){window.Module=function(e,t,n){var l=this,f=e.bootConfig.resources,d=window.Module||{},h=["DEBUGGING ENABLED"];d.print=function(e){return h.indexOf(e)<0&&console.log(e)},d.printErr=function(e){console.error(e),s.showErrorNotification()},d.preRun=d.preRun||[],d.postRun=d.postRun||[],d.preloadPlugins=[];var y,b=e.loadResources(f.assembly,(function(e){return"_framework/_bin/"+e}),"assembly"),g=e.loadResources(f.pdb||{},(function(e){return"_framework/_bin/"+e}),"pdb"),w=e.loadResource("dotnet.wasm","_framework/wasm/dotnet.wasm",e.bootConfig.resources.runtime["dotnet.wasm"],"dotnetwasm");return e.bootConfig.resources.runtime.hasOwnProperty("dotnet.timezones.dat")&&(y=e.loadResource("dotnet.timezones.dat","_framework/wasm/dotnet.timezones.dat",e.bootConfig.resources.runtime["dotnet.timezones.dat"],"timezonedata")),d.instantiateWasm=function(e,t){return r(l,void 0,void 0,(function(){var n,r;return o(this,(function(o){switch(o.label){case 0:return o.trys.push([0,3,,4]),[4,w];case 1:return[4,v(o.sent(),e)];case 2:return n=o.sent(),[3,4];case 3:throw r=o.sent(),d.printErr(r),r;case 4:return t(n),[2]}}))})),[]},d.preRun.push((function(){a=cwrap("mono_wasm_add_assembly",null,["string","number","number"]),cwrap("mono_wasm_string_get_utf8","number",["number"]),MONO.loaded_files=[],y&&function(e){r(this,void 0,void 0,(function(){var t,n;return o(this,(function(r){switch(r.label){case 0:return t="blazor:timezonedata",addRunDependency(t),[4,e.response];case 1:return[4,r.sent().arrayBuffer()];case 2:return n=r.sent(),c.loadTimezoneData(n),removeRunDependency(t),[2]}}))}))}(y),b.forEach((function(e){return E(e,function(e,t){var n=e.lastIndexOf(".");if(n<0)throw new Error("No extension to replace in '"+e+"'");return e.substr(0,n)+t}(e.name,".dll"))})),g.forEach((function(e){return E(e,e.name)})),window.Blazor._internal.dotNetCriticalError=function(e){d.printErr(BINDING.conv_string(e)||"(null)")},window.Blazor._internal.getSatelliteAssemblies=function(t){var n=BINDING.mono_array_to_js_array(t),a=e.bootConfig.resources.satelliteResources;if(a){var i=Promise.all(n.filter((function(e){return a.hasOwnProperty(e)})).map((function(t){return e.loadResources(a[t],(function(e){return"_framework/_bin/"+e}),"assembly")})).reduce((function(e,t){return e.concat(t)}),new Array).map((function(e){return r(l,void 0,void 0,(function(){return o(this,(function(t){switch(t.label){case 0:return[4,e.response];case 1:return[2,t.sent().arrayBuffer()]}}))}))})));return BINDING.js_to_mono_obj(i.then((function(e){return e.length&&(window.Blazor._internal.readSatelliteAssemblies=function(){for(var t=BINDING.mono_obj_array_new(e.length),n=0;n<e.length;n++)BINDING.mono_obj_array_set(t,n,BINDING.js_typed_array_to_array(new Uint8Array(e[n])));return t}),e.length})))}return BINDING.js_to_mono_obj(Promise.resolve(0))}})),d.postRun.push((function(){var n,r,o;e.bootConfig.debugBuild&&e.bootConfig.cacheBootResources&&e.logToConsole(),e.purgeUnusedCacheEntriesAsync(),MONO.mono_wasm_setenv("MONO_URI_DOTNETRELATIVEORABSOLUTE","true"),cwrap("mono_wasm_load_runtime",null,["string","number"])("appBinDir",u.hasDebuggingEnabled()?-1:0),MONO.mono_wasm_runtime_ready(),n=m("Microsoft.AspNetCore.Components.WebAssembly","Microsoft.AspNetCore.Components.WebAssembly.Services.DefaultWebAssemblyJSRuntime","InvokeDotNet"),r=m("Microsoft.AspNetCore.Components.WebAssembly","Microsoft.AspNetCore.Components.WebAssembly.Services.DefaultWebAssemblyJSRuntime","BeginInvokeDotNet"),o=m("Microsoft.AspNetCore.Components.WebAssembly","Microsoft.AspNetCore.Components.WebAssembly.Services.DefaultWebAssemblyJSRuntime","EndInvokeJS"),i.DotNet.attachDispatcher({beginInvokeDotNetFromJS:function(e,t,n,o,a){if(!o&&!t)throw new Error("Either assemblyName or dotNetObjectId must have a non null value.");var i=o?o.toString():t;r(e?e.toString():null,i,n,a)},endInvokeJSFromDotNet:function(e,t,n){o(n)},invokeDotNetFromJS:function(e,t,r,o){return n(e||null,t,r?r.toString():null,o)}}),t()})),d;function E(e,t){return r(this,void 0,void 0,(function(){var r,i,u,s,c;return o(this,(function(o){switch(o.label){case 0:r="blazor:"+e.name,addRunDependency(r),o.label=1;case 1:return o.trys.push([1,3,,4]),[4,e.response.then((function(e){return e.arrayBuffer()}))];case 2:return i=o.sent(),u=new Uint8Array(i),s=Module._malloc(u.length),new Uint8Array(Module.HEAPU8.buffer,s,u.length).set(u),a(t,s,u.length),MONO.loaded_files.push((l=e.url,p.href=l,p.href)),[3,4];case 3:return c=o.sent(),n(c),[2];case 4:return removeRunDependency(r),[2]}var l}))}))}}(e,t,n),function(e){if("undefined"==typeof WebAssembly||!WebAssembly.validate)throw new Error("This browser does not support WebAssembly.");var t=Object.keys(e.bootConfig.resources.runtime).filter((function(e){return e.startsWith("dotnet.")&&e.endsWith(".js")}))[0],n=e.bootConfig.resources.runtime[t],r=document.createElement("script");if(r.src="_framework/wasm/"+t,r.defer=!0,e.bootConfig.cacheBootResources&&(r.integrity=n,r.crossOrigin="anonymous"),e.startOptions.loadBootResource){var o=e.startOptions.loadBootResource("dotnetjs",t,r.src,n);if("string"==typeof o)r.src=o;else if(o)throw new Error("For a dotnetjs resource, custom loaders must supply a URI string.")}document.body.appendChild(r)}(e)},f=document.createElement("script"),window.__wasmmodulecallback__=l,f.type="text/javascript",f.text="var Module; window.__wasmmodulecallback__(); delete window.__wasmmodulecallback__;",document.body.appendChild(f)}))},callEntryPoint:function(e){m("Microsoft.AspNetCore.Components.WebAssembly","Microsoft.AspNetCore.Components.WebAssembly.Hosting.EntrypointInvoker","InvokeEntrypoint")(e,null)},toUint8Array:function(e){var t=h(e),n=d(t);return new Uint8Array(Module.HEAPU8.buffer,t+4,n)},getArrayLength:function(e){return d(h(e))},getArrayEntryPtr:function(e,t,n){return h(e)+4+t*n},getObjectFieldsBaseAddress:function(e){return e+8},readInt16Field:function(e,t){return n=e+(t||0),Module.HEAP16[n>>1];var n},readInt32Field:function(e,t){return d(e+(t||0))},readUint64Field:function(e,t){return function(e){var t=e>>2,n=Module.HEAPU32[t+1];if(n>f)throw new Error("Cannot read uint64 with high order part "+n+", because the result would exceed Number.MAX_SAFE_INTEGER.");return n*l+Module.HEAPU32[t]}(e+(t||0))},readFloatField:function(e,t){return n=e+(t||0),Module.HEAPF32[n>>2];var n},readObjectField:function(e,t){return d(e+(t||0))},readStringField:function(e,t,n){var r=d(e+(t||0));if(0===r)return null;if(n){var o=BINDING.unbox_mono_obj(r);return"boolean"==typeof o?o?"":null:o}return BINDING.conv_string(r)},readStructField:function(e,t){return e+(t||0)}};var p=document.createElement("a");function h(e){return e+12}function m(e,t,n){var r="["+e+"] "+t+":"+n;return BINDING.bind_static_method(r)}function v(e,t){return r(this,void 0,void 0,(function(){var n,r;return o(this,(function(o){switch(o.label){case 0:if("function"!=typeof WebAssembly.instantiateStreaming)return[3,4];o.label=1;case 1:return o.trys.push([1,3,,4]),[4,WebAssembly.instantiateStreaming(e.response,t)];case 2:return[2,o.sent().instance];case 3:return n=o.sent(),console.info("Streaming compilation failed. Falling back to ArrayBuffer instantiation. ",n),[3,4];case 4:return[4,e.response.then((function(e){return e.arrayBuffer()}))];case 5:return r=o.sent(),[4,WebAssembly.instantiate(r,t)];case 6:return[2,o.sent().instance]}}))}))}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=window.chrome&&navigator.userAgent.indexOf("Edge")<0,o=!1;function a(){return o&&r}t.hasDebuggingEnabled=a,t.attachDebuggerHotkey=function(e){o=!!e.bootConfig.resources.pdb;var t=navigator.platform.match(/^Mac/i)?"Cmd":"Alt";a()&&console.info("Debugging hotkey: Shift+"+t+"+D (when application has focus)"),document.addEventListener("keydown",(function(e){var t;e.shiftKey&&(e.metaKey||e.altKey)&&"KeyD"===e.code&&(o?r?((t=document.createElement("a")).href="_framework/debug?url="+encodeURIComponent(location.href),t.target="_blank",t.rel="noopener noreferrer",t.click()):console.error("Currently, only Microsoft Edge (80+), or Google Chrome, are supported for debugging."):console.error("Cannot start debugging, because the application was not compiled with debugging enabled."))}))}},function(e,t,n){"use strict";var r=this&&this.__values||function(e){var t="function"==typeof Symbol&&Symbol.iterator,n=t&&e[t],r=0;if(n)return n.call(e);if(e&&"number"==typeof e.length)return{next:function(){return e&&r>=e.length&&(e=void 0),{value:e&&e[r++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")},o=this&&this.__read||function(e,t){var n="function"==typeof Symbol&&e[Symbol.iterator];if(!n)return e;var r,o,a=n.call(e),i=[];try{for(;(void 0===t||t-- >0)&&!(r=a.next()).done;)i.push(r.value)}catch(e){o={error:e}}finally{try{r&&!r.done&&(n=a.return)&&n.call(a)}finally{if(o)throw o.error}}return i};Object.defineProperty(t,"__esModule",{value:!0});var a=n(31),i=n(32);t.loadTimezoneData=function(e){var t,n,u=new Uint8Array(e),s=a.readInt32LE(u,0);u=u.slice(4);var c=i.decodeUtf8(u.slice(0,s)),l=JSON.parse(c);u=u.slice(s),Module.FS_createPath("/","zoneinfo",!0,!0),new Set(l.map((function(e){return e[0].split("/")[0]}))).forEach((function(e){return Module.FS_createPath("/zoneinfo",e,!0,!0)}));try{for(var f=r(l),d=f.next();!d.done;d=f.next()){var p=o(d.value,2),h=p[0],m=p[1],v=u.slice(0,m);Module.FS_createDataFile("/zoneinfo/"+h,null,v,!0,!0,!0),u=u.slice(m)}}catch(e){t={error:e}}finally{try{d&&!d.done&&(n=f.return)&&n.call(f)}finally{if(t)throw t.error}}}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(17),o=function(){function e(e){this.batchAddress=e,this.arrayRangeReader=a,this.arrayBuilderSegmentReader=i,this.diffReader=u,this.editReader=s,this.frameReader=c}return e.prototype.updatedComponents=function(){return r.platform.readStructField(this.batchAddress,0)},e.prototype.referenceFrames=function(){return r.platform.readStructField(this.batchAddress,a.structLength)},e.prototype.disposedComponentIds=function(){return r.platform.readStructField(this.batchAddress,2*a.structLength)},e.prototype.disposedEventHandlerIds=function(){return r.platform.readStructField(this.batchAddress,3*a.structLength)},e.prototype.updatedComponentsEntry=function(e,t){return l(e,t,u.structLength)},e.prototype.referenceFramesEntry=function(e,t){return l(e,t,c.structLength)},e.prototype.disposedComponentIdsEntry=function(e,t){var n=l(e,t,4);return r.platform.readInt32Field(n)},e.prototype.disposedEventHandlerIdsEntry=function(e,t){var n=l(e,t,8);return r.platform.readUint64Field(n)},e}();t.SharedMemoryRenderBatch=o;var a={structLength:8,values:function(e){return r.platform.readObjectField(e,0)},count:function(e){return r.platform.readInt32Field(e,4)}},i={structLength:12,values:function(e){var t=r.platform.readObjectField(e,0),n=r.platform.getObjectFieldsBaseAddress(t);return r.platform.readObjectField(n,0)},offset:function(e){return r.platform.readInt32Field(e,4)},count:function(e){return r.platform.readInt32Field(e,8)}},u={structLength:4+i.structLength,componentId:function(e){return r.platform.readInt32Field(e,0)},edits:function(e){return r.platform.readStructField(e,4)},editsEntry:function(e,t){return l(e,t,s.structLength)}},s={structLength:20,editType:function(e){return r.platform.readInt32Field(e,0)},siblingIndex:function(e){return r.platform.readInt32Field(e,4)},newTreeIndex:function(e){return r.platform.readInt32Field(e,8)},moveToSiblingIndex:function(e){return r.platform.readInt32Field(e,8)},removedAttributeName:function(e){return r.platform.readStringField(e,16)}},c={structLength:36,frameType:function(e){return r.platform.readInt16Field(e,4)},subtreeLength:function(e){return r.platform.readInt32Field(e,8)},elementReferenceCaptureId:function(e){return r.platform.readStringField(e,16)},componentId:function(e){return r.platform.readInt32Field(e,12)},elementName:function(e){return r.platform.readStringField(e,16)},textContent:function(e){return r.platform.readStringField(e,16)},markupContent:function(e){return r.platform.readStringField(e,16)},attributeName:function(e){return r.platform.readStringField(e,16)},attributeValue:function(e){return r.platform.readStringField(e,24,!0)},attributeEventHandlerId:function(e){return r.platform.readUint64Field(e,8)}};function l(e,t,n){return r.platform.getArrayEntryPtr(e,t,n)}},function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))((function(o,a){function i(e){try{s(r.next(e))}catch(e){a(e)}}function u(e){try{s(r.throw(e))}catch(e){a(e)}}function s(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(i,u)}s((r=r.apply(e,t||[])).next())}))},o=this&&this.__generator||function(e,t){var n,r,o,a,i={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return a={next:u(0),throw:u(1),return:u(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function u(a){return function(u){return function(a){if(n)throw new TypeError("Generator is already executing.");for(;i;)try{if(n=1,r&&(o=2&a[0]?r.return:a[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,a[1])).done)return o;switch(r=0,o&&(a=[2&a[0],o.value]),a[0]){case 0:case 1:o=a;break;case 4:return i.label++,{value:a[1],done:!1};case 5:i.label++,r=a[1],a=[0];continue;case 7:a=i.ops.pop(),i.trys.pop();continue;default:if(!(o=i.trys,(o=o.length>0&&o[o.length-1])||6!==a[0]&&2!==a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]<o[3])){i.label=a[1];break}if(6===a[0]&&i.label<o[1]){i.label=o[1],o=a;break}if(o&&i.label<o[2]){i.label=o[2],i.ops.push(a);break}o[2]&&i.ops.pop(),i.trys.pop();continue}a=t.call(e,i)}catch(e){a=[6,e],r=0}finally{n=o=0}if(5&a[0])throw a[1];return{value:a[0]?a[1]:void 0,done:!0}}([a,u])}}};Object.defineProperty(t,"__esModule",{value:!0});var a=n(7),i=function(){function e(e,t,n){this.bootConfig=e,this.cacheIfUsed=t,this.startOptions=n,this.usedCacheKeys={},this.networkLoads={},this.cacheLoads={}}return e.initAsync=function(t,n){return r(this,void 0,void 0,(function(){var r;return o(this,(function(o){switch(o.label){case 0:return[4,u(t)];case 1:return r=o.sent(),[2,new e(t,r,n)]}}))}))},e.prototype.loadResources=function(e,t,n){var r=this;return Object.keys(e).map((function(o){return r.loadResource(o,t(o),e[o],n)}))},e.prototype.loadResource=function(e,t,n,r){return{name:e,url:t,response:this.cacheIfUsed?this.loadResourceWithCaching(this.cacheIfUsed,e,t,n,r):this.loadResourceWithoutCaching(e,t,n,r)}},e.prototype.logToConsole=function(){var e=Object.values(this.cacheLoads),t=Object.values(this.networkLoads),n=s(e),r=s(t),o=n+r;if(0!==o){var a=this.bootConfig.linkerEnabled?"%c":"\n%cThis application was built with linking (tree shaking) disabled. Published applications will be significantly smaller.";console.groupCollapsed("%cblazor%c Loaded "+c(o)+" resources"+a,"background: purple; color: white; padding: 1px 3px; border-radius: 3px;","font-weight: bold;","font-weight: normal;"),e.length&&(console.groupCollapsed("Loaded "+c(n)+" resources from cache"),console.table(this.cacheLoads),console.groupEnd()),t.length&&(console.groupCollapsed("Loaded "+c(r)+" resources from network"),console.table(this.networkLoads),console.groupEnd()),console.groupEnd()}},e.prototype.purgeUnusedCacheEntriesAsync=function(){return r(this,void 0,void 0,(function(){var e,t,n,a=this;return o(this,(function(i){switch(i.label){case 0:return(e=this.cacheIfUsed)?[4,e.keys()]:[3,3];case 1:return t=i.sent(),n=t.map((function(t){return r(a,void 0,void 0,(function(){return o(this,(function(n){switch(n.label){case 0:return t.url in this.usedCacheKeys?[3,2]:[4,e.delete(t)];case 1:n.sent(),n.label=2;case 2:return[2]}}))}))})),[4,Promise.all(n)];case 2:i.sent(),i.label=3;case 3:return[2]}}))}))},e.prototype.loadResourceWithCaching=function(e,t,n,i,u){return r(this,void 0,void 0,(function(){var r,s,c,l;return o(this,(function(o){switch(o.label){case 0:if(!i||0===i.length)throw new Error("Content hash is required");r=a.toAbsoluteUri(n+"."+i),this.usedCacheKeys[r]=!0,o.label=1;case 1:return o.trys.push([1,3,,4]),[4,e.match(r)];case 2:return s=o.sent(),[3,4];case 3:return o.sent(),[3,4];case 4:return s?(c=parseInt(s.headers.get("content-length")||"0"),this.cacheLoads[t]={responseBytes:c},[2,s]):[3,5];case 5:return[4,this.loadResourceWithoutCaching(t,n,i,u)];case 6:return l=o.sent(),this.addToCacheAsync(e,t,r,l),[2,l]}}))}))},e.prototype.loadResourceWithoutCaching=function(e,t,n,r){if(this.startOptions.loadBootResource){var o=this.startOptions.loadBootResource(r,e,t,n);if(o instanceof Promise)return o;"string"==typeof o&&(t=o)}return fetch(t,{cache:"no-cache",integrity:this.bootConfig.cacheBootResources?n:void 0})},e.prototype.addToCacheAsync=function(e,t,n,a){return r(this,void 0,void 0,(function(){var r,i,u,s;return o(this,(function(o){switch(o.label){case 0:return[4,a.clone().arrayBuffer()];case 1:r=o.sent(),i=function(e){if("undefined"!=typeof performance)return performance.getEntriesByName(e)[0]}(a.url),u=i&&i.encodedBodySize||void 0,this.networkLoads[t]={responseBytes:u},s=new Response(r,{headers:{"content-type":a.headers.get("content-type")||"","content-length":(u||a.headers.get("content-length")||"").toString()}}),o.label=2;case 2:return o.trys.push([2,4,,5]),[4,e.put(n,s)];case 3:return o.sent(),[3,5];case 4:return o.sent(),[3,5];case 5:return[2]}}))}))},e}();function u(e){return r(this,void 0,void 0,(function(){var t,n;return o(this,(function(r){switch(r.label){case 0:if(!e.cacheBootResources||"undefined"==typeof caches)return[2,null];t=document.baseURI.substring(document.location.origin.length),n="blazor-resources-"+t,r.label=1;case 1:return r.trys.push([1,3,,4]),[4,caches.open(n)];case 2:return[2,r.sent()||null];case 3:return r.sent(),[2,null];case 4:return[2]}}))}))}function s(e){return e.reduce((function(e,t){return e+(t.responseBytes||0)}),0)}function c(e){return(e/1048576).toFixed(2)+" MB"}t.WebAssemblyResourceLoader=i},function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))((function(o,a){function i(e){try{s(r.next(e))}catch(e){a(e)}}function u(e){try{s(r.throw(e))}catch(e){a(e)}}function s(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(i,u)}s((r=r.apply(e,t||[])).next())}))},o=this&&this.__generator||function(e,t){var n,r,o,a,i={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return a={next:u(0),throw:u(1),return:u(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function u(a){return function(u){return function(a){if(n)throw new TypeError("Generator is already executing.");for(;i;)try{if(n=1,r&&(o=2&a[0]?r.return:a[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,a[1])).done)return o;switch(r=0,o&&(a=[2&a[0],o.value]),a[0]){case 0:case 1:o=a;break;case 4:return i.label++,{value:a[1],done:!1};case 5:i.label++,r=a[1],a=[0];continue;case 7:a=i.ops.pop(),i.trys.pop();continue;default:if(!(o=i.trys,(o=o.length>0&&o[o.length-1])||6!==a[0]&&2!==a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]<o[3])){i.label=a[1];break}if(6===a[0]&&i.label<o[1]){i.label=o[1],o=a;break}if(o&&i.label<o[2]){i.label=o[2],i.ops.push(a);break}o[2]&&i.ops.pop(),i.trys.pop();continue}a=t.call(e,i)}catch(e){a=[6,e],r=0}finally{n=o=0}if(5&a[0])throw a[1];return{value:a[0]?a[1]:void 0,done:!0}}([a,u])}}};Object.defineProperty(t,"__esModule",{value:!0});var a=function(){function e(){}return e.initAsync=function(e){return r(this,void 0,void 0,(function(){function t(e){return r(this,void 0,void 0,(function(){var t,n;return o(this,(function(r){switch(r.label){case 0:return[4,fetch(e,{method:"GET",credentials:"include",cache:"no-cache"})];case 1:return t=r.sent(),n=Uint8Array.bind,[4,t.arrayBuffer()];case 2:return[2,new(n.apply(Uint8Array,[void 0,r.sent()]))]}}))}))}var n,a=this;return o(this,(function(i){switch(i.label){case 0:return window.Blazor._internal.getApplicationEnvironment=function(){return BINDING.js_string_to_mono_string(e.applicationEnvironment)},[4,Promise.all((e.bootConfig.config||[]).filter((function(t){return"appsettings.json"===t||t==="appsettings."+e.applicationEnvironment+".json"})).map((function(e){return r(a,void 0,void 0,(function(){var n;return o(this,(function(r){switch(r.label){case 0:return n={name:e},[4,t(e)];case 1:return[2,(n.content=r.sent(),n)]}}))}))})))];case 1:return n=i.sent(),window.Blazor._internal.getConfig=function(e){var t=BINDING.conv_string(e),r=n.find((function(e){return e.name===t}));return r?BINDING.js_typed_array_to_array(r.content):void 0},[2]}}))}))},e}();t.WebAssemblyConfigLoader=a},function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))((function(o,a){function i(e){try{s(r.next(e))}catch(e){a(e)}}function u(e){try{s(r.throw(e))}catch(e){a(e)}}function s(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(i,u)}s((r=r.apply(e,t||[])).next())}))},o=this&&this.__generator||function(e,t){var n,r,o,a,i={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return a={next:u(0),throw:u(1),return:u(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function u(a){return function(u){return function(a){if(n)throw new TypeError("Generator is already executing.");for(;i;)try{if(n=1,r&&(o=2&a[0]?r.return:a[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,a[1])).done)return o;switch(r=0,o&&(a=[2&a[0],o.value]),a[0]){case 0:case 1:o=a;break;case 4:return i.label++,{value:a[1],done:!1};case 5:i.label++,r=a[1],a=[0];continue;case 7:a=i.ops.pop(),i.trys.pop();continue;default:if(!(o=i.trys,(o=o.length>0&&o[o.length-1])||6!==a[0]&&2!==a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]<o[3])){i.label=a[1];break}if(6===a[0]&&i.label<o[1]){i.label=o[1],o=a;break}if(o&&i.label<o[2]){i.label=o[2],i.ops.push(a);break}o[2]&&i.ops.pop(),i.trys.pop();continue}a=t.call(e,i)}catch(e){a=[6,e],r=0}finally{n=o=0}if(5&a[0])throw a[1];return{value:a[0]?a[1]:void 0,done:!0}}([a,u])}}};Object.defineProperty(t,"__esModule",{value:!0});var a=function(){function e(e,t){this.bootConfig=e,this.applicationEnvironment=t}return e.initAsync=function(){return r(this,void 0,void 0,(function(){var t,n;return o(this,(function(r){switch(r.label){case 0:return[4,fetch("_framework/blazor.boot.json",{method:"GET",credentials:"include",cache:"no-cache"})];case 1:return t=r.sent(),n=t.headers.get("Blazor-Environment")||"Production",[4,t.json()];case 2:return[2,new e(r.sent(),n)]}}))}))},e}();t.BootConfigResult=a}]);
\ No newline at end of file +!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=43)}([,,,function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e){window.DotNet=e;var t=[],n={},r={},o=1,a=null;function i(e){t.push(e)}function u(e,t,n,r){var o=c();if(o.invokeDotNetFromJS){var a=JSON.stringify(r,m),i=o.invokeDotNetFromJS(e,t,n,a);return i?f(i):null}throw new Error("The current dispatcher does not support synchronous calls from JS to .NET. Use invokeMethodAsync instead.")}function s(e,t,r,a){if(e&&r)throw new Error("For instance method calls, assemblyName should be null. Received '"+e+"'.");var i=o++,u=new Promise((function(e,t){n[i]={resolve:e,reject:t}}));try{var s=JSON.stringify(a,m);c().beginInvokeDotNetFromJS(i,e,t,r,s)}catch(e){l(i,!1,e)}return u}function c(){if(null!==a)return a;throw new Error("No .NET call dispatcher has been set.")}function l(e,t,r){if(!n.hasOwnProperty(e))throw new Error("There is no pending async call with ID "+e+".");var o=n[e];delete n[e],t?o.resolve(r):o.reject(r)}function f(e){return e?JSON.parse(e,(function(e,n){return t.reduce((function(t,n){return n(e,t)}),n)})):null}function d(e){return e instanceof Error?e.message+"\n"+e.stack:e?e.toString():"null"}function p(e){if(r.hasOwnProperty(e))return r[e];var t,n=window,o="window";if(e.split(".").forEach((function(e){if(!(e in n))throw new Error("Could not find '"+e+"' in '"+o+"'.");t=n,n=n[e],o+="."+e})),n instanceof Function)return n=n.bind(t),r[e]=n,n;throw new Error("The value '"+o+"' is not a function.")}e.attachDispatcher=function(e){a=e},e.attachReviver=i,e.invokeMethod=function(e,t){for(var n=[],r=2;r<arguments.length;r++)n[r-2]=arguments[r];return u(e,t,null,n)},e.invokeMethodAsync=function(e,t){for(var n=[],r=2;r<arguments.length;r++)n[r-2]=arguments[r];return s(e,t,null,n)},e.jsCallDispatcher={findJSFunction:p,invokeJSFromDotNet:function(e,t){var n=p(e).apply(null,f(t));return null==n?null:JSON.stringify(n,m)},beginInvokeJSFromDotNet:function(e,t,n){var r=new Promise((function(e){e(p(t).apply(null,f(n)))}));e&&r.then((function(t){return c().endInvokeJSFromDotNet(e,!0,JSON.stringify([e,!0,t],m))}),(function(t){return c().endInvokeJSFromDotNet(e,!1,JSON.stringify([e,!1,d(t)]))}))},endInvokeDotNetFromJS:function(e,t,n){var r=t?n:new Error(n);l(parseInt(e),t,r)}};var h=function(){function e(e){this._id=e}return e.prototype.invokeMethod=function(e){for(var t=[],n=1;n<arguments.length;n++)t[n-1]=arguments[n];return u(null,e,this._id,t)},e.prototype.invokeMethodAsync=function(e){for(var t=[],n=1;n<arguments.length;n++)t[n-1]=arguments[n];return s(null,e,this._id,t)},e.prototype.dispose=function(){s(null,"__Dispose",this._id,null).catch((function(e){return console.error(e)}))},e.prototype.serializeAsArg=function(){return{__dotNetObject:this._id}},e}();function m(e,t){return t instanceof h?t.serializeAsArg():t}i((function(e,t){return t&&"object"==typeof t&&t.hasOwnProperty("__dotNetObject")?new h(t.__dotNetObject):t}))}(t.DotNet||(t.DotNet={}))},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),n(23),n(17);var r=n(24),o=n(12),a={},i=!1;function u(e,t,n){var o=a[e];o||(o=a[e]=new r.BrowserRenderer(e)),o.attachRootComponentToLogicalElement(n,t)}t.attachRootComponentToLogicalElement=u,t.attachRootComponentToElement=function(e,t,n){var r=document.querySelector(e);if(!r)throw new Error("Could not find any element matching selector '"+e+"'.");u(n||0,o.toLogicalElement(r,!0),t)},t.renderBatch=function(e,t){var n=a[e];if(!n)throw new Error("There is no browser renderer with ID "+e+".");for(var r=t.arrayRangeReader,o=t.updatedComponents(),u=r.values(o),s=r.count(o),c=t.referenceFrames(),l=r.values(c),f=t.diffReader,d=0;d<s;d++){var p=t.updatedComponentsEntry(u,d),h=f.componentId(p),m=f.edits(p);n.updateComponent(t,h,m,l)}var v=t.disposedComponentIds(),y=r.values(v),b=r.count(v);for(d=0;d<b;d++){h=t.disposedComponentIdsEntry(y,d);n.disposeComponent(h)}var g=t.disposedEventHandlerIds(),w=r.values(g),E=r.count(g);for(d=0;d<E;d++){var _=t.disposedEventHandlerIdsEntry(w,d);n.disposeEventHandler(_)}i&&(i=!1,window.scrollTo&&window.scrollTo(0,0))},t.resetScrollAfterNextBatch=function(){i=!0}},,,function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))((function(o,a){function i(e){try{s(r.next(e))}catch(e){a(e)}}function u(e){try{s(r.throw(e))}catch(e){a(e)}}function s(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(i,u)}s((r=r.apply(e,t||[])).next())}))},o=this&&this.__generator||function(e,t){var n,r,o,a,i={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return a={next:u(0),throw:u(1),return:u(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function u(a){return function(u){return function(a){if(n)throw new TypeError("Generator is already executing.");for(;i;)try{if(n=1,r&&(o=2&a[0]?r.return:a[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,a[1])).done)return o;switch(r=0,o&&(a=[2&a[0],o.value]),a[0]){case 0:case 1:o=a;break;case 4:return i.label++,{value:a[1],done:!1};case 5:i.label++,r=a[1],a=[0];continue;case 7:a=i.ops.pop(),i.trys.pop();continue;default:if(!(o=i.trys,(o=o.length>0&&o[o.length-1])||6!==a[0]&&2!==a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]<o[3])){i.label=a[1];break}if(6===a[0]&&i.label<o[1]){i.label=o[1],o=a;break}if(o&&i.label<o[2]){i.label=o[2],i.ops.push(a);break}o[2]&&i.ops.pop(),i.trys.pop();continue}a=t.call(e,i)}catch(e){a=[6,e],r=0}finally{n=o=0}if(5&a[0])throw a[1];return{value:a[0]?a[1]:void 0,done:!0}}([a,u])}}};Object.defineProperty(t,"__esModule",{value:!0}),n(3);var a,i=n(4),u=!1,s=!1,c=null;function l(e,t,n){void 0===n&&(n=!1);var r=p(e);if(!t&&h(r))f(r,!1,n);else if(t&&location.href===e){var o=e+"?";history.replaceState(null,"",o),location.replace(e)}else n?history.replaceState(null,"",r):location.href=e}function f(e,t,n){void 0===n&&(n=!1),i.resetScrollAfterNextBatch(),n?history.replaceState(null,"",e):history.pushState(null,"",e),d(t)}function d(e){return r(this,void 0,void 0,(function(){return o(this,(function(t){switch(t.label){case 0:return c?[4,c(location.href,e)]:[3,2];case 1:t.sent(),t.label=2;case 2:return[2]}}))}))}function p(e){return(a=a||document.createElement("a")).href=e,a.href}function h(e){var t,n=(t=document.baseURI).substr(0,t.lastIndexOf("/")+1);return e.startsWith(n)}t.internalFunctions={listenForNavigationEvents:function(e){if(c=e,s)return;s=!0,window.addEventListener("popstate",(function(){return d(!1)}))},enableNavigationInterception:function(){u=!0},navigateTo:l,getBaseURI:function(){return document.baseURI},getLocationHref:function(){return location.href}},t.attachToEventDelegator=function(e){e.notifyAfterClick((function(e){if(u&&0===e.button&&!function(e){return e.ctrlKey||e.shiftKey||e.altKey||e.metaKey}(e)&&!e.defaultPrevented){var t=function e(t,n){return t?t.tagName===n?t:e(t.parentElement,n):null}(e.target,"A");if(t&&t.hasAttribute("href")){var n=t.getAttribute("target");if(!(!n||"_self"===n))return;var r=p(t.getAttribute("href"));h(r)&&(e.preventDefault(),f(r,!0))}}}))},t.navigateTo=l,t.toAbsoluteUri=p},,,,,function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=p("_blazorLogicalChildren"),o=p("_blazorLogicalParent"),a=p("_blazorLogicalEnd");function i(e,t){if(e.childNodes.length>0&&!t)throw new Error("New logical elements must start empty, or allowExistingContents must be true");return r in e||(e[r]=[]),e}function u(e,t,n){var a=e;if(e instanceof Comment&&(c(a)&&c(a).length>0))throw new Error("Not implemented: inserting non-empty logical container");if(s(a))throw new Error("Not implemented: moving existing logical children");var i=c(t);if(n<i.length){var u=i[n];u.parentNode.insertBefore(e,u),i.splice(n,0,a)}else d(e,t),i.push(a);a[o]=t,r in a||(a[r]=[])}function s(e){return e[o]||null}function c(e){return e[r]}function l(e){if(e instanceof Element)return e;if(e instanceof Comment)return e.parentNode;throw new Error("Not a valid logical element")}function f(e){var t=c(s(e));return t[Array.prototype.indexOf.call(t,e)+1]||null}function d(e,t){if(t instanceof Element)t.appendChild(e);else{if(!(t instanceof Comment))throw new Error("Cannot append node because the parent is not a valid logical element. Parent: "+t);var n=f(t);n?n.parentNode.insertBefore(e,n):d(e,s(t))}}function p(e){return"function"==typeof Symbol?Symbol():e}t.toLogicalRootCommentElement=function(e,t){if(!e.parentNode)throw new Error("Comment not connected to the DOM "+e.textContent);var n=e.parentNode,r=i(n,!0),u=c(r);return Array.from(n.childNodes).forEach((function(e){return u.push(e)})),e[o]=r,t&&(e[a]=t,i(t)),i(e)},t.toLogicalElement=i,t.createAndInsertLogicalContainer=function(e,t){var n=document.createComment("!");return u(n,e,t),n},t.insertLogicalChild=u,t.removeLogicalChild=function e(t,n){var r=c(t).splice(n,1)[0];if(r instanceof Comment)for(var o=c(r);o.length>0;)e(r,0);var a=r;a.parentNode.removeChild(a)},t.getLogicalParent=s,t.getLogicalSiblingEnd=function(e){return e[a]||null},t.getLogicalChild=function(e,t){return c(e)[t]},t.isSvgElement=function(e){return"http://www.w3.org/2000/svg"===l(e).namespaceURI},t.getLogicalChildrenArray=c,t.permuteLogicalChildren=function(e,t){var n=c(e);t.forEach((function(e){e.moveRangeStart=n[e.fromSiblingIndex],e.moveRangeEnd=function e(t){if(t instanceof Element)return t;var n=f(t);if(n)return n.previousSibling;var r=s(t);return r instanceof Element?r.lastChild:e(r)}(e.moveRangeStart)})),t.forEach((function(t){var r=t.moveToBeforeMarker=document.createComment("marker"),o=n[t.toSiblingIndex+1];o?o.parentNode.insertBefore(r,o):d(r,e)})),t.forEach((function(e){for(var t=e.moveToBeforeMarker,n=t.parentNode,r=e.moveRangeStart,o=e.moveRangeEnd,a=r;a;){var i=a.nextSibling;if(n.insertBefore(a,t),a===o)break;a=i}n.removeChild(t)})),t.forEach((function(e){n[e.toSiblingIndex]=e.moveRangeStart}))},t.getClosestDomElement=l},,,,,function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.setPlatform=function(e){return t.platform=e,t.platform}},function(e,t,n){"use strict";var r;Object.defineProperty(t,"__esModule",{value:!0}),t.dispatchEvent=function(e,t){if(!r)throw new Error("eventDispatcher not initialized. Call 'setEventDispatcher' to configure it.");return r(e,t)},t.setEventDispatcher=function(e){r=e}},,,,function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(7),o=n(4);window.Blazor={navigateTo:r.navigateTo,_internal:{attachRootComponentToElement:o.attachRootComponentToElement,navigationManager:r.internalFunctions}}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0})},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(25),o=n(26),a=n(12),i=n(29),u=n(18),s=n(7),c=document.createElement("template"),l=document.createElementNS("http://www.w3.org/2000/svg","g"),f={submit:!0},d={},p=function(){function e(e){var t=this;this.childComponentLocations={},this.browserRendererId=e,this.eventDelegator=new o.EventDelegator((function(e,n,r,o){!function(e,t,n,r,o){f[e.type]&&e.preventDefault();var a={browserRendererId:t,eventHandlerId:n,eventArgsType:r.type,eventFieldInfo:o};u.dispatchEvent(a,r.data)}(e,t.browserRendererId,n,r,o)})),s.attachToEventDelegator(this.eventDelegator)}return e.prototype.attachRootComponentToLogicalElement=function(e,t){this.attachComponentToElement(e,t),d[e]=t},e.prototype.updateComponent=function(e,t,n,r){var o=this.childComponentLocations[t];if(!o)throw new Error("No element is currently associated with component "+t);var i=d[t];if(i){var u=a.getLogicalSiblingEnd(i);delete d[t],u?function(e,t){var n=a.getLogicalParent(e);if(!n)throw new Error("Can't clear between nodes. The start node does not have a logical parent.");for(var r=a.getLogicalChildrenArray(n),o=r.indexOf(e)+1,i=r.indexOf(t),u=o;u<=i;u++)a.removeLogicalChild(n,o);e.textContent="!"}(i,u):function(e){var t;for(;t=e.firstChild;)e.removeChild(t)}(i)}var s=a.getClosestDomElement(o).ownerDocument,c=s&&s.activeElement;this.applyEdits(e,t,o,0,n,r),c instanceof HTMLElement&&s&&s.activeElement!==c&&c.focus()},e.prototype.disposeComponent=function(e){delete this.childComponentLocations[e]},e.prototype.disposeEventHandler=function(e){this.eventDelegator.removeListener(e)},e.prototype.attachComponentToElement=function(e,t){this.childComponentLocations[e]=t},e.prototype.applyEdits=function(e,t,n,o,i,u){for(var s,c=0,l=o,f=e.arrayBuilderSegmentReader,d=e.editReader,p=e.frameReader,h=f.values(i),m=f.offset(i),v=m+f.count(i),y=m;y<v;y++){var b=e.diffReader.editsEntry(h,y),g=d.editType(b);switch(g){case r.EditType.prependFrame:var w=d.newTreeIndex(b),E=e.referenceFramesEntry(u,w),_=d.siblingIndex(b);this.insertFrame(e,t,n,l+_,u,E,w);break;case r.EditType.removeFrame:_=d.siblingIndex(b);a.removeLogicalChild(n,l+_);break;case r.EditType.setAttribute:w=d.newTreeIndex(b),E=e.referenceFramesEntry(u,w),_=d.siblingIndex(b);if(!((C=a.getLogicalChild(n,l+_))instanceof Element))throw new Error("Cannot set attribute on non-element child");this.applyAttribute(e,t,C,E);break;case r.EditType.removeAttribute:var C;_=d.siblingIndex(b);if(!((C=a.getLogicalChild(n,l+_))instanceof HTMLElement))throw new Error("Cannot remove attribute from non-element child");var I=d.removedAttributeName(b);this.tryApplySpecialProperty(e,C,I,null)||C.removeAttribute(I);break;case r.EditType.updateText:w=d.newTreeIndex(b),E=e.referenceFramesEntry(u,w),_=d.siblingIndex(b);var S=a.getLogicalChild(n,l+_);if(!(S instanceof Text))throw new Error("Cannot set text content on non-text child");S.textContent=p.textContent(E);break;case r.EditType.updateMarkup:w=d.newTreeIndex(b),E=e.referenceFramesEntry(u,w),_=d.siblingIndex(b);a.removeLogicalChild(n,l+_),this.insertMarkup(e,n,l+_,E);break;case r.EditType.stepIn:_=d.siblingIndex(b);n=a.getLogicalChild(n,l+_),c++,l=0;break;case r.EditType.stepOut:n=a.getLogicalParent(n),l=0===--c?o:0;break;case r.EditType.permutationListEntry:(s=s||[]).push({fromSiblingIndex:l+d.siblingIndex(b),toSiblingIndex:l+d.moveToSiblingIndex(b)});break;case r.EditType.permutationListEnd:a.permuteLogicalChildren(n,s),s=void 0;break;default:throw new Error("Unknown edit type: "+g)}}},e.prototype.insertFrame=function(e,t,n,o,a,u,s){var c=e.frameReader,l=c.frameType(u);switch(l){case r.FrameType.element:return this.insertElement(e,t,n,o,a,u,s),1;case r.FrameType.text:return this.insertText(e,n,o,u),1;case r.FrameType.attribute:throw new Error("Attribute frames should only be present as leading children of element frames.");case r.FrameType.component:return this.insertComponent(e,n,o,u),1;case r.FrameType.region:return this.insertFrameRange(e,t,n,o,a,s+1,s+c.subtreeLength(u));case r.FrameType.elementReferenceCapture:if(n instanceof Element)return i.applyCaptureIdToElement(n,c.elementReferenceCaptureId(u)),0;throw new Error("Reference capture frames can only be children of element frames.");case r.FrameType.markup:return this.insertMarkup(e,n,o,u),1;default:throw new Error("Unknown frame type: "+l)}},e.prototype.insertElement=function(e,t,n,o,i,u,s){var c=e.frameReader,l=c.elementName(u),f="svg"===l||a.isSvgElement(n)?document.createElementNS("http://www.w3.org/2000/svg",l):document.createElement(l),d=a.toLogicalElement(f);a.insertLogicalChild(f,n,o);for(var p=s+c.subtreeLength(u),h=s+1;h<p;h++){var m=e.referenceFramesEntry(i,h);if(c.frameType(m)!==r.FrameType.attribute){this.insertFrameRange(e,t,d,0,i,h,p);break}this.applyAttribute(e,t,f,m)}f instanceof HTMLSelectElement&&"_blazorSelectValue"in f&&v(f,f._blazorSelectValue)},e.prototype.insertComponent=function(e,t,n,r){var o=a.createAndInsertLogicalContainer(t,n),i=e.frameReader.componentId(r);this.attachComponentToElement(i,o)},e.prototype.insertText=function(e,t,n,r){var o=e.frameReader.textContent(r),i=document.createTextNode(o);a.insertLogicalChild(i,t,n)},e.prototype.insertMarkup=function(e,t,n,r){for(var o,i=a.createAndInsertLogicalContainer(t,n),u=e.frameReader.markupContent(r),s=(o=u,a.isSvgElement(t)?(l.innerHTML=o||" ",l):(c.innerHTML=o||" ",c.content)),f=0;s.firstChild;)a.insertLogicalChild(s.firstChild,i,f++)},e.prototype.applyAttribute=function(e,t,n,r){var o=e.frameReader,a=o.attributeName(r),i=o.attributeEventHandlerId(r);if(i){var u=m(a);this.eventDelegator.setListener(n,u,i,t)}else this.tryApplySpecialProperty(e,n,a,r)||n.setAttribute(a,o.attributeValue(r))},e.prototype.tryApplySpecialProperty=function(e,t,n,r){switch(n){case"value":return this.tryApplyValueProperty(e,t,r);case"checked":return this.tryApplyCheckedProperty(e,t,r);default:return!!n.startsWith("__internal_")&&(this.applyInternalAttribute(e,t,n.substring("__internal_".length),r),!0)}},e.prototype.applyInternalAttribute=function(e,t,n,r){var o=r?e.frameReader.attributeValue(r):null;if(n.startsWith("stopPropagation_")){var a=m(n.substring("stopPropagation_".length));this.eventDelegator.setStopPropagation(t,a,null!==o)}else{if(!n.startsWith("preventDefault_"))throw new Error("Unsupported internal attribute '"+n+"'");a=m(n.substring("preventDefault_".length));this.eventDelegator.setPreventDefault(t,a,null!==o)}},e.prototype.tryApplyValueProperty=function(e,t,n){var r=e.frameReader;if("INPUT"===t.tagName&&"time"===t.getAttribute("type")&&!t.getAttribute("step")){var o=n?r.attributeValue(n):null;if(o)return t.value=o.substring(0,5),!0}switch(t.tagName){case"INPUT":case"SELECT":case"TEXTAREA":var a=n?r.attributeValue(n):null;return t instanceof HTMLSelectElement?(v(t,a),t._blazorSelectValue=a):t.value=a,!0;case"OPTION":(a=n?r.attributeValue(n):null)||""===a?t.setAttribute("value",a):t.removeAttribute("value");var i=this.findClosestAncestorSelectElement(t);return i&&"_blazorSelectValue"in i&&i._blazorSelectValue===a&&(this.tryApplyValueProperty(e,i,n),delete i._blazorSelectValue),!0;default:return!1}},e.prototype.tryApplyCheckedProperty=function(e,t,n){if("INPUT"===t.tagName){var r=n?e.frameReader.attributeValue(n):null;return t.checked=null!==r,!0}return!1},e.prototype.findClosestAncestorSelectElement=function(e){for(;e;){if(e instanceof HTMLSelectElement)return e;e=e.parentElement}return null},e.prototype.insertFrameRange=function(e,t,n,r,o,a,i){for(var u=r,s=a;s<i;s++){var c=e.referenceFramesEntry(o,s);r+=this.insertFrame(e,t,n,r,o,c,s),s+=h(e,c)}return r-u},e}();function h(e,t){var n=e.frameReader;switch(n.frameType(t)){case r.FrameType.component:case r.FrameType.element:case r.FrameType.region:return n.subtreeLength(t)-1;default:return 0}}function m(e){if(e.startsWith("on"))return e.substring(2);throw new Error("Attribute should be an event name, but doesn't start with 'on'. Value: '"+e+"'")}function v(e,t){e.value=t||""}t.BrowserRenderer=p},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e){e[e.prependFrame=1]="prependFrame",e[e.removeFrame=2]="removeFrame",e[e.setAttribute=3]="setAttribute",e[e.removeAttribute=4]="removeAttribute",e[e.updateText=5]="updateText",e[e.stepIn=6]="stepIn",e[e.stepOut=7]="stepOut",e[e.updateMarkup=8]="updateMarkup",e[e.permutationListEntry=9]="permutationListEntry",e[e.permutationListEnd=10]="permutationListEnd"}(t.EditType||(t.EditType={})),function(e){e[e.element=1]="element",e[e.text=2]="text",e[e.attribute=3]="attribute",e[e.component=4]="component",e[e.region=5]="region",e[e.elementReferenceCapture=6]="elementReferenceCapture",e[e.markup=8]="markup"}(t.FrameType||(t.FrameType={}))},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(27),o=n(28),a=l(["abort","blur","change","error","focus","load","loadend","loadstart","mouseenter","mouseleave","progress","reset","scroll","submit","unload","DOMNodeInsertedIntoDocument","DOMNodeRemovedFromDocument"]),i=l(["click","dblclick","mousedown","mousemove","mouseup"]),u=function(){function e(t){this.onEvent=t,this.afterClickCallbacks=[];var n=++e.nextEventDelegatorId;this.eventsCollectionKey="_blazorEvents_"+n,this.eventInfoStore=new s(this.onGlobalEvent.bind(this))}return e.prototype.setListener=function(e,t,n,r){var o=this.getEventHandlerInfosForElement(e,!0),a=o.getHandler(t);if(a)this.eventInfoStore.update(a.eventHandlerId,n);else{var i={element:e,eventName:t,eventHandlerId:n,renderingComponentId:r};this.eventInfoStore.add(i),o.setHandler(t,i)}},e.prototype.removeListener=function(e){var t=this.eventInfoStore.remove(e);if(t){var n=t.element,r=this.getEventHandlerInfosForElement(n,!1);r&&r.removeHandler(t.eventName)}},e.prototype.notifyAfterClick=function(e){this.afterClickCallbacks.push(e),this.eventInfoStore.addGlobalListener("click")},e.prototype.setStopPropagation=function(e,t,n){this.getEventHandlerInfosForElement(e,!0).stopPropagation(t,n)},e.prototype.setPreventDefault=function(e,t,n){this.getEventHandlerInfosForElement(e,!0).preventDefault(t,n)},e.prototype.onGlobalEvent=function(e){if(e.target instanceof Element){for(var t,n,u=e.target,s=null,c=a.hasOwnProperty(e.type),l=!1;u;){var f=this.getEventHandlerInfosForElement(u,!1);if(f){var d=f.getHandler(e.type);if(d&&(t=u,n=e.type,!((t instanceof HTMLButtonElement||t instanceof HTMLInputElement||t instanceof HTMLTextAreaElement||t instanceof HTMLSelectElement)&&i.hasOwnProperty(n)&&t.disabled))){s||(s=r.EventForDotNet.fromDOMEvent(e));var p=o.EventFieldInfo.fromEvent(d.renderingComponentId,e);this.onEvent(e,d.eventHandlerId,s,p)}f.stopPropagation(e.type)&&(l=!0),f.preventDefault(e.type)&&e.preventDefault()}u=c||l?null:u.parentElement}"click"===e.type&&this.afterClickCallbacks.forEach((function(t){return t(e)}))}},e.prototype.getEventHandlerInfosForElement=function(e,t){return e.hasOwnProperty(this.eventsCollectionKey)?e[this.eventsCollectionKey]:t?e[this.eventsCollectionKey]=new c:null},e.nextEventDelegatorId=0,e}();t.EventDelegator=u;var s=function(){function e(e){this.globalListener=e,this.infosByEventHandlerId={},this.countByEventName={}}return e.prototype.add=function(e){if(this.infosByEventHandlerId[e.eventHandlerId])throw new Error("Event "+e.eventHandlerId+" is already tracked");this.infosByEventHandlerId[e.eventHandlerId]=e,this.addGlobalListener(e.eventName)},e.prototype.addGlobalListener=function(e){if(this.countByEventName.hasOwnProperty(e))this.countByEventName[e]++;else{this.countByEventName[e]=1;var t=a.hasOwnProperty(e);document.addEventListener(e,this.globalListener,t)}},e.prototype.update=function(e,t){if(this.infosByEventHandlerId.hasOwnProperty(t))throw new Error("Event "+t+" is already tracked");var n=this.infosByEventHandlerId[e];delete this.infosByEventHandlerId[e],n.eventHandlerId=t,this.infosByEventHandlerId[t]=n},e.prototype.remove=function(e){var t=this.infosByEventHandlerId[e];if(t){delete this.infosByEventHandlerId[e];var n=t.eventName;0==--this.countByEventName[n]&&(delete this.countByEventName[n],document.removeEventListener(n,this.globalListener))}return t},e}(),c=function(){function e(){this.handlers={},this.preventDefaultFlags=null,this.stopPropagationFlags=null}return e.prototype.getHandler=function(e){return this.handlers.hasOwnProperty(e)?this.handlers[e]:null},e.prototype.setHandler=function(e,t){this.handlers[e]=t},e.prototype.removeHandler=function(e){delete this.handlers[e]},e.prototype.preventDefault=function(e,t){return void 0!==t&&(this.preventDefaultFlags=this.preventDefaultFlags||{},this.preventDefaultFlags[e]=t),!!this.preventDefaultFlags&&this.preventDefaultFlags[e]},e.prototype.stopPropagation=function(e,t){return void 0!==t&&(this.stopPropagationFlags=this.stopPropagationFlags||{},this.stopPropagationFlags[e]=t),!!this.stopPropagationFlags&&this.stopPropagationFlags[e]},e}();function l(e){var t={};return e.forEach((function(e){t[e]=!0})),t}},function(e,t,n){"use strict";var r=this&&this.__assign||function(){return(r=Object.assign||function(e){for(var t,n=1,r=arguments.length;n<r;n++)for(var o in t=arguments[n])Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o]);return e}).apply(this,arguments)};Object.defineProperty(t,"__esModule",{value:!0});var o=function(){function e(e,t){this.type=e,this.data=t}return e.fromDOMEvent=function(t){var n=t.target;switch(t.type){case"input":case"change":if(function(e){return-1!==i.indexOf(e.getAttribute("type"))}(n)){var o=function(e){var t=e.value,n=e.type;switch(n){case"date":case"datetime-local":case"month":return t;case"time":return 5===t.length?t+":00":t;case"week":return t}throw new Error("Invalid element type '"+n+"'.")}(n);return new e("change",{type:t.type,value:o})}var u=function(e){return!!e&&"INPUT"===e.tagName&&"checkbox"===e.getAttribute("type")}(n)?!!n.checked:n.value;return new e("change",{type:t.type,value:u});case"copy":case"cut":case"paste":return new e("clipboard",{type:t.type});case"drag":case"dragend":case"dragenter":case"dragleave":case"dragover":case"dragstart":case"drop":return new e("drag",function(e){return r(r({},a(e)),{dataTransfer:e.dataTransfer})}(t));case"focus":case"blur":case"focusin":case"focusout":return new e("focus",{type:t.type});case"keydown":case"keyup":case"keypress":return new e("keyboard",function(e){return{type:e.type,key:e.key,code:e.code,location:e.location,repeat:e.repeat,ctrlKey:e.ctrlKey,shiftKey:e.shiftKey,altKey:e.altKey,metaKey:e.metaKey}}(t));case"contextmenu":case"click":case"mouseover":case"mouseout":case"mousemove":case"mousedown":case"mouseup":case"dblclick":return new e("mouse",a(t));case"error":return new e("error",function(e){return{type:e.type,message:e.message,filename:e.filename,lineno:e.lineno,colno:e.colno}}(t));case"loadstart":case"timeout":case"abort":case"load":case"loadend":case"progress":return new e("progress",function(e){return{type:e.type,lengthComputable:e.lengthComputable,loaded:e.loaded,total:e.total}}(t));case"touchcancel":case"touchend":case"touchmove":case"touchenter":case"touchleave":case"touchstart":return new e("touch",function(e){function t(e){for(var t=[],n=0;n<e.length;n++){var r=e[n];t.push({identifier:r.identifier,clientX:r.clientX,clientY:r.clientY,screenX:r.screenX,screenY:r.screenY,pageX:r.pageX,pageY:r.pageY})}return t}return{type:e.type,detail:e.detail,touches:t(e.touches),targetTouches:t(e.targetTouches),changedTouches:t(e.changedTouches),ctrlKey:e.ctrlKey,shiftKey:e.shiftKey,altKey:e.altKey,metaKey:e.metaKey}}(t));case"gotpointercapture":case"lostpointercapture":case"pointercancel":case"pointerdown":case"pointerenter":case"pointerleave":case"pointermove":case"pointerout":case"pointerover":case"pointerup":return new e("pointer",function(e){return r(r({},a(e)),{pointerId:e.pointerId,width:e.width,height:e.height,pressure:e.pressure,tiltX:e.tiltX,tiltY:e.tiltY,pointerType:e.pointerType,isPrimary:e.isPrimary})}(t));case"wheel":case"mousewheel":return new e("wheel",function(e){return r(r({},a(e)),{deltaX:e.deltaX,deltaY:e.deltaY,deltaZ:e.deltaZ,deltaMode:e.deltaMode})}(t));default:return new e("unknown",{type:t.type})}},e}();function a(e){return{type:e.type,detail:e.detail,screenX:e.screenX,screenY:e.screenY,clientX:e.clientX,clientY:e.clientY,offsetX:e.offsetX,offsetY:e.offsetY,button:e.button,buttons:e.buttons,ctrlKey:e.ctrlKey,shiftKey:e.shiftKey,altKey:e.altKey,metaKey:e.metaKey}}t.EventForDotNet=o;var i=["date","datetime-local","month","time","week"]},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e,t){this.componentId=e,this.fieldValue=t}return e.fromEvent=function(t,n){var r=n.target;if(r instanceof Element){var o=function(e){if(e instanceof HTMLInputElement)return e.type&&"checkbox"===e.type.toLowerCase()?{value:e.checked}:{value:e.value};if(e instanceof HTMLSelectElement||e instanceof HTMLTextAreaElement)return{value:e.value};return null}(r);if(o)return new e(t,o.value)}return null},e}();t.EventFieldInfo=r},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(3);function o(e){return"_bl_"+e}t.applyCaptureIdToElement=function(e,t){e.setAttribute(o(t),"")};r.DotNet.attachReviver((function(e,t){return t&&"object"==typeof t&&t.hasOwnProperty("__internalId")&&"string"==typeof t.__internalId?(n=t.__internalId,r="["+o(n)+"]",document.querySelector(r)):t;var n,r}))},function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))((function(o,a){function i(e){try{s(r.next(e))}catch(e){a(e)}}function u(e){try{s(r.throw(e))}catch(e){a(e)}}function s(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(i,u)}s((r=r.apply(e,t||[])).next())}))},o=this&&this.__generator||function(e,t){var n,r,o,a,i={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return a={next:u(0),throw:u(1),return:u(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function u(a){return function(u){return function(a){if(n)throw new TypeError("Generator is already executing.");for(;i;)try{if(n=1,r&&(o=2&a[0]?r.return:a[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,a[1])).done)return o;switch(r=0,o&&(a=[2&a[0],o.value]),a[0]){case 0:case 1:o=a;break;case 4:return i.label++,{value:a[1],done:!1};case 5:i.label++,r=a[1],a=[0];continue;case 7:a=i.ops.pop(),i.trys.pop();continue;default:if(!(o=i.trys,(o=o.length>0&&o[o.length-1])||6!==a[0]&&2!==a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]<o[3])){i.label=a[1];break}if(6===a[0]&&i.label<o[1]){i.label=o[1],o=a;break}if(o&&i.label<o[2]){i.label=o[2],i.ops.push(a);break}o[2]&&i.ops.pop(),i.trys.pop();continue}a=t.call(e,i)}catch(e){a=[6,e],r=0}finally{n=o=0}if(5&a[0])throw a[1];return{value:a[0]?a[1]:void 0,done:!0}}([a,u])}}};Object.defineProperty(t,"__esModule",{value:!0});var a=!1;t.showErrorNotification=function(){return r(this,void 0,void 0,(function(){var e;return o(this,(function(t){return(e=document.querySelector("#blazor-error-ui"))&&(e.style.display="block"),a||(a=!0,document.querySelectorAll("#blazor-error-ui .reload").forEach((function(e){e.onclick=function(e){location.reload(),e.preventDefault()}})),document.querySelectorAll("#blazor-error-ui .dismiss").forEach((function(e){e.onclick=function(e){var t=document.querySelector("#blazor-error-ui");t&&(t.style.display="none"),e.preventDefault()}}))),[2]}))}))}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=Math.pow(2,32),o=Math.pow(2,21)-1;function a(e,t){return e[t]+(e[t+1]<<8)+(e[t+2]<<16)+(e[t+3]<<24>>>0)}t.readInt32LE=function(e,t){return e[t]|e[t+1]<<8|e[t+2]<<16|e[t+3]<<24},t.readUint32LE=a,t.readUint64LE=function(e,t){var n=a(e,t+4);if(n>o)throw new Error("Cannot read uint64 with high order part "+n+", because the result would exceed Number.MAX_SAFE_INTEGER.");return n*r+a(e,t)},t.readLEB128=function(e,t){for(var n=0,r=0,o=0;o<4;o++){var a=e[t+o];if(n|=(127&a)<<r,a<128)break;r+=7}return n},t.numLEB128Bytes=function(e){return e<128?1:e<16384?2:e<2097152?3:4}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r="function"==typeof TextDecoder?new TextDecoder("utf-8"):null;t.decodeUtf8=r?r.decode.bind(r):function(e){var t=0,n=e.length,r=[],o=[];for(;t<n;){var a=e[t++];if(0===a)break;if(0==(128&a))r.push(a);else if(192==(224&a)){var i=63&e[t++];r.push((31&a)<<6|i)}else if(224==(240&a)){i=63&e[t++];var u=63&e[t++];r.push((31&a)<<12|i<<6|u)}else if(240==(248&a)){i=63&e[t++],u=63&e[t++];var s=63&e[t++],c=(7&a)<<18|i<<12|u<<6|s;c>65535&&(c-=65536,r.push(c>>>10&1023|55296),c=56320|1023&c),r.push(c)}r.length>1024&&(o.push(String.fromCharCode.apply(null,r)),r.length=0)}return o.push(String.fromCharCode.apply(null,r)),o.join("")}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.shouldAutoStart=function(){return!(!document||!document.currentScript||"false"===document.currentScript.getAttribute("autostart"))}},,,,,,,,,,function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))((function(o,a){function i(e){try{s(r.next(e))}catch(e){a(e)}}function u(e){try{s(r.throw(e))}catch(e){a(e)}}function s(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(i,u)}s((r=r.apply(e,t||[])).next())}))},o=this&&this.__generator||function(e,t){var n,r,o,a,i={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return a={next:u(0),throw:u(1),return:u(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function u(a){return function(u){return function(a){if(n)throw new TypeError("Generator is already executing.");for(;i;)try{if(n=1,r&&(o=2&a[0]?r.return:a[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,a[1])).done)return o;switch(r=0,o&&(a=[2&a[0],o.value]),a[0]){case 0:case 1:o=a;break;case 4:return i.label++,{value:a[1],done:!1};case 5:i.label++,r=a[1],a=[0];continue;case 7:a=i.ops.pop(),i.trys.pop();continue;default:if(!(o=i.trys,(o=o.length>0&&o[o.length-1])||6!==a[0]&&2!==a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]<o[3])){i.label=a[1];break}if(6===a[0]&&i.label<o[1]){i.label=o[1],o=a;break}if(o&&i.label<o[2]){i.label=o[2],i.ops.push(a);break}o[2]&&i.ops.pop(),i.trys.pop();continue}a=t.call(e,i)}catch(e){a=[6,e],r=0}finally{n=o=0}if(5&a[0])throw a[1];return{value:a[0]?a[1]:void 0,done:!0}}([a,u])}}},a=this&&this.__read||function(e,t){var n="function"==typeof Symbol&&e[Symbol.iterator];if(!n)return e;var r,o,a=n.call(e),i=[];try{for(;(void 0===t||t-- >0)&&!(r=a.next()).done;)i.push(r.value)}catch(e){o={error:e}}finally{try{r&&!r.done&&(n=a.return)&&n.call(a)}finally{if(o)throw o.error}}return i};Object.defineProperty(t,"__esModule",{value:!0});var i=n(3);n(22);var u=n(17),s=n(44),c=n(4),l=n(47),f=n(33),d=n(18),p=n(48),h=n(49),m=n(50),v=!1;function y(e){return r(this,void 0,void 0,(function(){var t,n,f,y,b,g,w,E=this;return o(this,(function(_){switch(_.label){case 0:if(v)throw new Error("Blazor has already started.");return v=!0,d.setEventDispatcher((function(e,t){return i.DotNet.invokeMethodAsync("Microsoft.AspNetCore.Components.WebAssembly","DispatchEvent",e,JSON.stringify(t))})),t=u.setPlatform(s.monoPlatform),window.Blazor.platform=t,window.Blazor._internal.renderBatch=function(e,t){c.renderBatch(e,new l.SharedMemoryRenderBatch(t))},n=window.Blazor._internal.navigationManager.getBaseURI,f=window.Blazor._internal.navigationManager.getLocationHref,window.Blazor._internal.navigationManager.getUnmarshalledBaseURI=function(){return BINDING.js_string_to_mono_string(n())},window.Blazor._internal.navigationManager.getUnmarshalledLocationHref=function(){return BINDING.js_string_to_mono_string(f())},window.Blazor._internal.navigationManager.listenForNavigationEvents((function(e,t){return r(E,void 0,void 0,(function(){return o(this,(function(n){switch(n.label){case 0:return[4,i.DotNet.invokeMethodAsync("Microsoft.AspNetCore.Components.WebAssembly","NotifyLocationChanged",e,t)];case 1:return n.sent(),[2]}}))}))})),[4,m.BootConfigResult.initAsync()];case 1:return y=_.sent(),[4,Promise.all([p.WebAssemblyResourceLoader.initAsync(y.bootConfig,e||{}),h.WebAssemblyConfigLoader.initAsync(y)])];case 2:b=a.apply(void 0,[_.sent(),1]),g=b[0],_.label=3;case 3:return _.trys.push([3,5,,6]),[4,t.start(g)];case 4:return _.sent(),[3,6];case 5:throw w=_.sent(),new Error("Failed to start platform. Reason: "+w);case 6:return t.callEntryPoint(g.bootConfig.entryAssembly),[2]}}))}))}window.Blazor.start=y,f.shouldAutoStart()&&y().catch((function(e){"undefined"!=typeof Module&&Module.printErr?Module.printErr(e):console.error(e)}))},function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))((function(o,a){function i(e){try{s(r.next(e))}catch(e){a(e)}}function u(e){try{s(r.throw(e))}catch(e){a(e)}}function s(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(i,u)}s((r=r.apply(e,t||[])).next())}))},o=this&&this.__generator||function(e,t){var n,r,o,a,i={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return a={next:u(0),throw:u(1),return:u(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function u(a){return function(u){return function(a){if(n)throw new TypeError("Generator is already executing.");for(;i;)try{if(n=1,r&&(o=2&a[0]?r.return:a[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,a[1])).done)return o;switch(r=0,o&&(a=[2&a[0],o.value]),a[0]){case 0:case 1:o=a;break;case 4:return i.label++,{value:a[1],done:!1};case 5:i.label++,r=a[1],a=[0];continue;case 7:a=i.ops.pop(),i.trys.pop();continue;default:if(!(o=i.trys,(o=o.length>0&&o[o.length-1])||6!==a[0]&&2!==a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]<o[3])){i.label=a[1];break}if(6===a[0]&&i.label<o[1]){i.label=o[1],o=a;break}if(o&&i.label<o[2]){i.label=o[2],i.ops.push(a);break}o[2]&&i.ops.pop(),i.trys.pop();continue}a=t.call(e,i)}catch(e){a=[6,e],r=0}finally{n=o=0}if(5&a[0])throw a[1];return{value:a[0]?a[1]:void 0,done:!0}}([a,u])}}};Object.defineProperty(t,"__esModule",{value:!0});var a,i=n(3),u=n(45),s=n(30),c=n(46),l=Math.pow(2,32),f=Math.pow(2,21)-1;function d(e){return Module.HEAP32[e>>2]}t.monoPlatform={start:function(e){return new Promise((function(t,n){var l,f;u.attachDebuggerHotkey(e),window.Browser={init:function(){}},l=function(){window.Module=function(e,t,n){var l=this,f=e.bootConfig.resources,d=window.Module||{},h=["DEBUGGING ENABLED"];d.print=function(e){return h.indexOf(e)<0&&console.log(e)},d.printErr=function(e){console.error(e),s.showErrorNotification()},d.preRun=d.preRun||[],d.postRun=d.postRun||[],d.preloadPlugins=[];var y,b=e.loadResources(f.assembly,(function(e){return"_framework/"+e}),"assembly"),g=e.loadResources(f.pdb||{},(function(e){return"_framework/"+e}),"pdb"),w=e.loadResource("dotnet.wasm","_framework/dotnet.wasm",e.bootConfig.resources.runtime["dotnet.wasm"],"dotnetwasm");return e.bootConfig.resources.runtime.hasOwnProperty("dotnet.timezones.dat")&&(y=e.loadResource("dotnet.timezones.dat","_framework/dotnet.timezones.dat",e.bootConfig.resources.runtime["dotnet.timezones.dat"],"timezonedata")),d.instantiateWasm=function(e,t){return r(l,void 0,void 0,(function(){var n,r;return o(this,(function(o){switch(o.label){case 0:return o.trys.push([0,3,,4]),[4,w];case 1:return[4,v(o.sent(),e)];case 2:return n=o.sent(),[3,4];case 3:throw r=o.sent(),d.printErr(r),r;case 4:return t(n),[2]}}))})),[]},d.preRun.push((function(){a=cwrap("mono_wasm_add_assembly",null,["string","number","number"]),cwrap("mono_wasm_string_get_utf8","number",["number"]),MONO.loaded_files=[],y&&function(e){r(this,void 0,void 0,(function(){var t,n;return o(this,(function(r){switch(r.label){case 0:return t="blazor:timezonedata",addRunDependency(t),[4,e.response];case 1:return[4,r.sent().arrayBuffer()];case 2:return n=r.sent(),c.loadTimezoneData(n),removeRunDependency(t),[2]}}))}))}(y),b.forEach((function(e){return E(e,function(e,t){var n=e.lastIndexOf(".");if(n<0)throw new Error("No extension to replace in '"+e+"'");return e.substr(0,n)+t}(e.name,".dll"))})),g.forEach((function(e){return E(e,e.name)})),window.Blazor._internal.dotNetCriticalError=function(e){d.printErr(BINDING.conv_string(e)||"(null)")},window.Blazor._internal.getSatelliteAssemblies=function(t){var n=BINDING.mono_array_to_js_array(t),a=e.bootConfig.resources.satelliteResources;if(a){var i=Promise.all(n.filter((function(e){return a.hasOwnProperty(e)})).map((function(t){return e.loadResources(a[t],(function(e){return"_framework/"+e}),"assembly")})).reduce((function(e,t){return e.concat(t)}),new Array).map((function(e){return r(l,void 0,void 0,(function(){return o(this,(function(t){switch(t.label){case 0:return[4,e.response];case 1:return[2,t.sent().arrayBuffer()]}}))}))})));return BINDING.js_to_mono_obj(i.then((function(e){return e.length&&(window.Blazor._internal.readSatelliteAssemblies=function(){for(var t=BINDING.mono_obj_array_new(e.length),n=0;n<e.length;n++)BINDING.mono_obj_array_set(t,n,BINDING.js_typed_array_to_array(new Uint8Array(e[n])));return t}),e.length})))}return BINDING.js_to_mono_obj(Promise.resolve(0))}})),d.postRun.push((function(){var n,r,o;e.bootConfig.debugBuild&&e.bootConfig.cacheBootResources&&e.logToConsole(),e.purgeUnusedCacheEntriesAsync(),MONO.mono_wasm_setenv("MONO_URI_DOTNETRELATIVEORABSOLUTE","true"),cwrap("mono_wasm_load_runtime",null,["string","number"])("appBinDir",u.hasDebuggingEnabled()?-1:0),MONO.mono_wasm_runtime_ready(),n=m("Microsoft.AspNetCore.Components.WebAssembly","Microsoft.AspNetCore.Components.WebAssembly.Services.DefaultWebAssemblyJSRuntime","InvokeDotNet"),r=m("Microsoft.AspNetCore.Components.WebAssembly","Microsoft.AspNetCore.Components.WebAssembly.Services.DefaultWebAssemblyJSRuntime","BeginInvokeDotNet"),o=m("Microsoft.AspNetCore.Components.WebAssembly","Microsoft.AspNetCore.Components.WebAssembly.Services.DefaultWebAssemblyJSRuntime","EndInvokeJS"),i.DotNet.attachDispatcher({beginInvokeDotNetFromJS:function(e,t,n,o,a){if(!o&&!t)throw new Error("Either assemblyName or dotNetObjectId must have a non null value.");var i=o?o.toString():t;r(e?e.toString():null,i,n,a)},endInvokeJSFromDotNet:function(e,t,n){o(n)},invokeDotNetFromJS:function(e,t,r,o){return n(e||null,t,r?r.toString():null,o)}}),t()})),d;function E(e,t){return r(this,void 0,void 0,(function(){var r,i,u,s,c;return o(this,(function(o){switch(o.label){case 0:r="blazor:"+e.name,addRunDependency(r),o.label=1;case 1:return o.trys.push([1,3,,4]),[4,e.response.then((function(e){return e.arrayBuffer()}))];case 2:return i=o.sent(),u=new Uint8Array(i),s=Module._malloc(u.length),new Uint8Array(Module.HEAPU8.buffer,s,u.length).set(u),a(t,s,u.length),MONO.loaded_files.push((l=e.url,p.href=l,p.href)),[3,4];case 3:return c=o.sent(),n(c),[2];case 4:return removeRunDependency(r),[2]}var l}))}))}}(e,t,n),function(e){if("undefined"==typeof WebAssembly||!WebAssembly.validate)throw new Error("This browser does not support WebAssembly.");var t=Object.keys(e.bootConfig.resources.runtime).filter((function(e){return e.startsWith("dotnet.")&&e.endsWith(".js")}))[0],n=e.bootConfig.resources.runtime[t],r=document.createElement("script");if(r.src="_framework/"+t,r.defer=!0,e.bootConfig.cacheBootResources&&(r.integrity=n,r.crossOrigin="anonymous"),e.startOptions.loadBootResource){var o=e.startOptions.loadBootResource("dotnetjs",t,r.src,n);if("string"==typeof o)r.src=o;else if(o)throw new Error("For a dotnetjs resource, custom loaders must supply a URI string.")}document.body.appendChild(r)}(e)},f=document.createElement("script"),window.__wasmmodulecallback__=l,f.type="text/javascript",f.text="var Module; window.__wasmmodulecallback__(); delete window.__wasmmodulecallback__;",document.body.appendChild(f)}))},callEntryPoint:function(e){m("Microsoft.AspNetCore.Components.WebAssembly","Microsoft.AspNetCore.Components.WebAssembly.Hosting.EntrypointInvoker","InvokeEntrypoint")(e,null)},toUint8Array:function(e){var t=h(e),n=d(t);return new Uint8Array(Module.HEAPU8.buffer,t+4,n)},getArrayLength:function(e){return d(h(e))},getArrayEntryPtr:function(e,t,n){return h(e)+4+t*n},getObjectFieldsBaseAddress:function(e){return e+8},readInt16Field:function(e,t){return n=e+(t||0),Module.HEAP16[n>>1];var n},readInt32Field:function(e,t){return d(e+(t||0))},readUint64Field:function(e,t){return function(e){var t=e>>2,n=Module.HEAPU32[t+1];if(n>f)throw new Error("Cannot read uint64 with high order part "+n+", because the result would exceed Number.MAX_SAFE_INTEGER.");return n*l+Module.HEAPU32[t]}(e+(t||0))},readFloatField:function(e,t){return n=e+(t||0),Module.HEAPF32[n>>2];var n},readObjectField:function(e,t){return d(e+(t||0))},readStringField:function(e,t,n){var r=d(e+(t||0));if(0===r)return null;if(n){var o=BINDING.unbox_mono_obj(r);return"boolean"==typeof o?o?"":null:o}return BINDING.conv_string(r)},readStructField:function(e,t){return e+(t||0)}};var p=document.createElement("a");function h(e){return e+12}function m(e,t,n){var r="["+e+"] "+t+":"+n;return BINDING.bind_static_method(r)}function v(e,t){return r(this,void 0,void 0,(function(){var n,r;return o(this,(function(o){switch(o.label){case 0:if("function"!=typeof WebAssembly.instantiateStreaming)return[3,4];o.label=1;case 1:return o.trys.push([1,3,,4]),[4,WebAssembly.instantiateStreaming(e.response,t)];case 2:return[2,o.sent().instance];case 3:return n=o.sent(),console.info("Streaming compilation failed. Falling back to ArrayBuffer instantiation. ",n),[3,4];case 4:return[4,e.response.then((function(e){return e.arrayBuffer()}))];case 5:return r=o.sent(),[4,WebAssembly.instantiate(r,t)];case 6:return[2,o.sent().instance]}}))}))}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=window.chrome&&navigator.userAgent.indexOf("Edge")<0,o=!1;function a(){return o&&r}t.hasDebuggingEnabled=a,t.attachDebuggerHotkey=function(e){o=!!e.bootConfig.resources.pdb;var t=navigator.platform.match(/^Mac/i)?"Cmd":"Alt";a()&&console.info("Debugging hotkey: Shift+"+t+"+D (when application has focus)"),document.addEventListener("keydown",(function(e){var t;e.shiftKey&&(e.metaKey||e.altKey)&&"KeyD"===e.code&&(o?r?((t=document.createElement("a")).href="_framework/debug?url="+encodeURIComponent(location.href),t.target="_blank",t.rel="noopener noreferrer",t.click()):console.error("Currently, only Microsoft Edge (80+), or Google Chrome, are supported for debugging."):console.error("Cannot start debugging, because the application was not compiled with debugging enabled."))}))}},function(e,t,n){"use strict";var r=this&&this.__values||function(e){var t="function"==typeof Symbol&&Symbol.iterator,n=t&&e[t],r=0;if(n)return n.call(e);if(e&&"number"==typeof e.length)return{next:function(){return e&&r>=e.length&&(e=void 0),{value:e&&e[r++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")},o=this&&this.__read||function(e,t){var n="function"==typeof Symbol&&e[Symbol.iterator];if(!n)return e;var r,o,a=n.call(e),i=[];try{for(;(void 0===t||t-- >0)&&!(r=a.next()).done;)i.push(r.value)}catch(e){o={error:e}}finally{try{r&&!r.done&&(n=a.return)&&n.call(a)}finally{if(o)throw o.error}}return i};Object.defineProperty(t,"__esModule",{value:!0});var a=n(31),i=n(32);t.loadTimezoneData=function(e){var t,n,u=new Uint8Array(e),s=a.readInt32LE(u,0);u=u.slice(4);var c=i.decodeUtf8(u.slice(0,s)),l=JSON.parse(c);u=u.slice(s),Module.FS_createPath("/","zoneinfo",!0,!0),new Set(l.map((function(e){return e[0].split("/")[0]}))).forEach((function(e){return Module.FS_createPath("/zoneinfo",e,!0,!0)}));try{for(var f=r(l),d=f.next();!d.done;d=f.next()){var p=o(d.value,2),h=p[0],m=p[1],v=u.slice(0,m);Module.FS_createDataFile("/zoneinfo/"+h,null,v,!0,!0,!0),u=u.slice(m)}}catch(e){t={error:e}}finally{try{d&&!d.done&&(n=f.return)&&n.call(f)}finally{if(t)throw t.error}}}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(17),o=function(){function e(e){this.batchAddress=e,this.arrayRangeReader=a,this.arrayBuilderSegmentReader=i,this.diffReader=u,this.editReader=s,this.frameReader=c}return e.prototype.updatedComponents=function(){return r.platform.readStructField(this.batchAddress,0)},e.prototype.referenceFrames=function(){return r.platform.readStructField(this.batchAddress,a.structLength)},e.prototype.disposedComponentIds=function(){return r.platform.readStructField(this.batchAddress,2*a.structLength)},e.prototype.disposedEventHandlerIds=function(){return r.platform.readStructField(this.batchAddress,3*a.structLength)},e.prototype.updatedComponentsEntry=function(e,t){return l(e,t,u.structLength)},e.prototype.referenceFramesEntry=function(e,t){return l(e,t,c.structLength)},e.prototype.disposedComponentIdsEntry=function(e,t){var n=l(e,t,4);return r.platform.readInt32Field(n)},e.prototype.disposedEventHandlerIdsEntry=function(e,t){var n=l(e,t,8);return r.platform.readUint64Field(n)},e}();t.SharedMemoryRenderBatch=o;var a={structLength:8,values:function(e){return r.platform.readObjectField(e,0)},count:function(e){return r.platform.readInt32Field(e,4)}},i={structLength:12,values:function(e){var t=r.platform.readObjectField(e,0),n=r.platform.getObjectFieldsBaseAddress(t);return r.platform.readObjectField(n,0)},offset:function(e){return r.platform.readInt32Field(e,4)},count:function(e){return r.platform.readInt32Field(e,8)}},u={structLength:4+i.structLength,componentId:function(e){return r.platform.readInt32Field(e,0)},edits:function(e){return r.platform.readStructField(e,4)},editsEntry:function(e,t){return l(e,t,s.structLength)}},s={structLength:20,editType:function(e){return r.platform.readInt32Field(e,0)},siblingIndex:function(e){return r.platform.readInt32Field(e,4)},newTreeIndex:function(e){return r.platform.readInt32Field(e,8)},moveToSiblingIndex:function(e){return r.platform.readInt32Field(e,8)},removedAttributeName:function(e){return r.platform.readStringField(e,16)}},c={structLength:36,frameType:function(e){return r.platform.readInt16Field(e,4)},subtreeLength:function(e){return r.platform.readInt32Field(e,8)},elementReferenceCaptureId:function(e){return r.platform.readStringField(e,16)},componentId:function(e){return r.platform.readInt32Field(e,12)},elementName:function(e){return r.platform.readStringField(e,16)},textContent:function(e){return r.platform.readStringField(e,16)},markupContent:function(e){return r.platform.readStringField(e,16)},attributeName:function(e){return r.platform.readStringField(e,16)},attributeValue:function(e){return r.platform.readStringField(e,24,!0)},attributeEventHandlerId:function(e){return r.platform.readUint64Field(e,8)}};function l(e,t,n){return r.platform.getArrayEntryPtr(e,t,n)}},function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))((function(o,a){function i(e){try{s(r.next(e))}catch(e){a(e)}}function u(e){try{s(r.throw(e))}catch(e){a(e)}}function s(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(i,u)}s((r=r.apply(e,t||[])).next())}))},o=this&&this.__generator||function(e,t){var n,r,o,a,i={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return a={next:u(0),throw:u(1),return:u(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function u(a){return function(u){return function(a){if(n)throw new TypeError("Generator is already executing.");for(;i;)try{if(n=1,r&&(o=2&a[0]?r.return:a[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,a[1])).done)return o;switch(r=0,o&&(a=[2&a[0],o.value]),a[0]){case 0:case 1:o=a;break;case 4:return i.label++,{value:a[1],done:!1};case 5:i.label++,r=a[1],a=[0];continue;case 7:a=i.ops.pop(),i.trys.pop();continue;default:if(!(o=i.trys,(o=o.length>0&&o[o.length-1])||6!==a[0]&&2!==a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]<o[3])){i.label=a[1];break}if(6===a[0]&&i.label<o[1]){i.label=o[1],o=a;break}if(o&&i.label<o[2]){i.label=o[2],i.ops.push(a);break}o[2]&&i.ops.pop(),i.trys.pop();continue}a=t.call(e,i)}catch(e){a=[6,e],r=0}finally{n=o=0}if(5&a[0])throw a[1];return{value:a[0]?a[1]:void 0,done:!0}}([a,u])}}};Object.defineProperty(t,"__esModule",{value:!0});var a=n(7),i=function(){function e(e,t,n){this.bootConfig=e,this.cacheIfUsed=t,this.startOptions=n,this.usedCacheKeys={},this.networkLoads={},this.cacheLoads={}}return e.initAsync=function(t,n){return r(this,void 0,void 0,(function(){var r;return o(this,(function(o){switch(o.label){case 0:return[4,u(t)];case 1:return r=o.sent(),[2,new e(t,r,n)]}}))}))},e.prototype.loadResources=function(e,t,n){var r=this;return Object.keys(e).map((function(o){return r.loadResource(o,t(o),e[o],n)}))},e.prototype.loadResource=function(e,t,n,r){return{name:e,url:t,response:this.cacheIfUsed?this.loadResourceWithCaching(this.cacheIfUsed,e,t,n,r):this.loadResourceWithoutCaching(e,t,n,r)}},e.prototype.logToConsole=function(){var e=Object.values(this.cacheLoads),t=Object.values(this.networkLoads),n=s(e),r=s(t),o=n+r;if(0!==o){var a=this.bootConfig.linkerEnabled?"%c":"\n%cThis application was built with linking (tree shaking) disabled. Published applications will be significantly smaller.";console.groupCollapsed("%cblazor%c Loaded "+c(o)+" resources"+a,"background: purple; color: white; padding: 1px 3px; border-radius: 3px;","font-weight: bold;","font-weight: normal;"),e.length&&(console.groupCollapsed("Loaded "+c(n)+" resources from cache"),console.table(this.cacheLoads),console.groupEnd()),t.length&&(console.groupCollapsed("Loaded "+c(r)+" resources from network"),console.table(this.networkLoads),console.groupEnd()),console.groupEnd()}},e.prototype.purgeUnusedCacheEntriesAsync=function(){return r(this,void 0,void 0,(function(){var e,t,n,a=this;return o(this,(function(i){switch(i.label){case 0:return(e=this.cacheIfUsed)?[4,e.keys()]:[3,3];case 1:return t=i.sent(),n=t.map((function(t){return r(a,void 0,void 0,(function(){return o(this,(function(n){switch(n.label){case 0:return t.url in this.usedCacheKeys?[3,2]:[4,e.delete(t)];case 1:n.sent(),n.label=2;case 2:return[2]}}))}))})),[4,Promise.all(n)];case 2:i.sent(),i.label=3;case 3:return[2]}}))}))},e.prototype.loadResourceWithCaching=function(e,t,n,i,u){return r(this,void 0,void 0,(function(){var r,s,c,l;return o(this,(function(o){switch(o.label){case 0:if(!i||0===i.length)throw new Error("Content hash is required");r=a.toAbsoluteUri(n+"."+i),this.usedCacheKeys[r]=!0,o.label=1;case 1:return o.trys.push([1,3,,4]),[4,e.match(r)];case 2:return s=o.sent(),[3,4];case 3:return o.sent(),[3,4];case 4:return s?(c=parseInt(s.headers.get("content-length")||"0"),this.cacheLoads[t]={responseBytes:c},[2,s]):[3,5];case 5:return[4,this.loadResourceWithoutCaching(t,n,i,u)];case 6:return l=o.sent(),this.addToCacheAsync(e,t,r,l),[2,l]}}))}))},e.prototype.loadResourceWithoutCaching=function(e,t,n,r){if(this.startOptions.loadBootResource){var o=this.startOptions.loadBootResource(r,e,t,n);if(o instanceof Promise)return o;"string"==typeof o&&(t=o)}return fetch(t,{cache:"no-cache",integrity:this.bootConfig.cacheBootResources?n:void 0})},e.prototype.addToCacheAsync=function(e,t,n,a){return r(this,void 0,void 0,(function(){var r,i,u,s;return o(this,(function(o){switch(o.label){case 0:return[4,a.clone().arrayBuffer()];case 1:r=o.sent(),i=function(e){if("undefined"!=typeof performance)return performance.getEntriesByName(e)[0]}(a.url),u=i&&i.encodedBodySize||void 0,this.networkLoads[t]={responseBytes:u},s=new Response(r,{headers:{"content-type":a.headers.get("content-type")||"","content-length":(u||a.headers.get("content-length")||"").toString()}}),o.label=2;case 2:return o.trys.push([2,4,,5]),[4,e.put(n,s)];case 3:return o.sent(),[3,5];case 4:return o.sent(),[3,5];case 5:return[2]}}))}))},e}();function u(e){return r(this,void 0,void 0,(function(){var t,n;return o(this,(function(r){switch(r.label){case 0:if(!e.cacheBootResources||"undefined"==typeof caches)return[2,null];t=document.baseURI.substring(document.location.origin.length),n="blazor-resources-"+t,r.label=1;case 1:return r.trys.push([1,3,,4]),[4,caches.open(n)];case 2:return[2,r.sent()||null];case 3:return r.sent(),[2,null];case 4:return[2]}}))}))}function s(e){return e.reduce((function(e,t){return e+(t.responseBytes||0)}),0)}function c(e){return(e/1048576).toFixed(2)+" MB"}t.WebAssemblyResourceLoader=i},function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))((function(o,a){function i(e){try{s(r.next(e))}catch(e){a(e)}}function u(e){try{s(r.throw(e))}catch(e){a(e)}}function s(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(i,u)}s((r=r.apply(e,t||[])).next())}))},o=this&&this.__generator||function(e,t){var n,r,o,a,i={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return a={next:u(0),throw:u(1),return:u(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function u(a){return function(u){return function(a){if(n)throw new TypeError("Generator is already executing.");for(;i;)try{if(n=1,r&&(o=2&a[0]?r.return:a[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,a[1])).done)return o;switch(r=0,o&&(a=[2&a[0],o.value]),a[0]){case 0:case 1:o=a;break;case 4:return i.label++,{value:a[1],done:!1};case 5:i.label++,r=a[1],a=[0];continue;case 7:a=i.ops.pop(),i.trys.pop();continue;default:if(!(o=i.trys,(o=o.length>0&&o[o.length-1])||6!==a[0]&&2!==a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]<o[3])){i.label=a[1];break}if(6===a[0]&&i.label<o[1]){i.label=o[1],o=a;break}if(o&&i.label<o[2]){i.label=o[2],i.ops.push(a);break}o[2]&&i.ops.pop(),i.trys.pop();continue}a=t.call(e,i)}catch(e){a=[6,e],r=0}finally{n=o=0}if(5&a[0])throw a[1];return{value:a[0]?a[1]:void 0,done:!0}}([a,u])}}};Object.defineProperty(t,"__esModule",{value:!0});var a=function(){function e(){}return e.initAsync=function(e){return r(this,void 0,void 0,(function(){function t(e){return r(this,void 0,void 0,(function(){var t,n;return o(this,(function(r){switch(r.label){case 0:return[4,fetch(e,{method:"GET",credentials:"include",cache:"no-cache"})];case 1:return t=r.sent(),n=Uint8Array.bind,[4,t.arrayBuffer()];case 2:return[2,new(n.apply(Uint8Array,[void 0,r.sent()]))]}}))}))}var n,a=this;return o(this,(function(i){switch(i.label){case 0:return window.Blazor._internal.getApplicationEnvironment=function(){return BINDING.js_string_to_mono_string(e.applicationEnvironment)},[4,Promise.all((e.bootConfig.config||[]).filter((function(t){return"appsettings.json"===t||t==="appsettings."+e.applicationEnvironment+".json"})).map((function(e){return r(a,void 0,void 0,(function(){var n;return o(this,(function(r){switch(r.label){case 0:return n={name:e},[4,t(e)];case 1:return[2,(n.content=r.sent(),n)]}}))}))})))];case 1:return n=i.sent(),window.Blazor._internal.getConfig=function(e){var t=BINDING.conv_string(e),r=n.find((function(e){return e.name===t}));return r?BINDING.js_typed_array_to_array(r.content):void 0},[2]}}))}))},e}();t.WebAssemblyConfigLoader=a},function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))((function(o,a){function i(e){try{s(r.next(e))}catch(e){a(e)}}function u(e){try{s(r.throw(e))}catch(e){a(e)}}function s(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(i,u)}s((r=r.apply(e,t||[])).next())}))},o=this&&this.__generator||function(e,t){var n,r,o,a,i={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return a={next:u(0),throw:u(1),return:u(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function u(a){return function(u){return function(a){if(n)throw new TypeError("Generator is already executing.");for(;i;)try{if(n=1,r&&(o=2&a[0]?r.return:a[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,a[1])).done)return o;switch(r=0,o&&(a=[2&a[0],o.value]),a[0]){case 0:case 1:o=a;break;case 4:return i.label++,{value:a[1],done:!1};case 5:i.label++,r=a[1],a=[0];continue;case 7:a=i.ops.pop(),i.trys.pop();continue;default:if(!(o=i.trys,(o=o.length>0&&o[o.length-1])||6!==a[0]&&2!==a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]<o[3])){i.label=a[1];break}if(6===a[0]&&i.label<o[1]){i.label=o[1],o=a;break}if(o&&i.label<o[2]){i.label=o[2],i.ops.push(a);break}o[2]&&i.ops.pop(),i.trys.pop();continue}a=t.call(e,i)}catch(e){a=[6,e],r=0}finally{n=o=0}if(5&a[0])throw a[1];return{value:a[0]?a[1]:void 0,done:!0}}([a,u])}}};Object.defineProperty(t,"__esModule",{value:!0});var a=function(){function e(e,t){this.bootConfig=e,this.applicationEnvironment=t}return e.initAsync=function(){return r(this,void 0,void 0,(function(){var t,n;return o(this,(function(r){switch(r.label){case 0:return[4,fetch("_framework/blazor.boot.json",{method:"GET",credentials:"include",cache:"no-cache"})];case 1:return t=r.sent(),n=t.headers.get("Blazor-Environment")||"Production",[4,t.json()];case 2:return[2,new e(r.sent(),n)]}}))}))},e}();t.BootConfigResult=a}]);
\ No newline at end of file diff --git a/src/Components/Web.JS/src/Platform/Mono/MonoPlatform.ts b/src/Components/Web.JS/src/Platform/Mono/MonoPlatform.ts index 5836de603d..ae1e93c6bd 100644 --- a/src/Components/Web.JS/src/Platform/Mono/MonoPlatform.ts +++ b/src/Components/Web.JS/src/Platform/Mono/MonoPlatform.ts @@ -142,7 +142,7 @@ function addScriptTagsToDocument(resourceLoader: WebAssemblyResourceLoader) { .filter(n => n.startsWith('dotnet.') && n.endsWith('.js'))[0]; const dotnetJsContentHash = resourceLoader.bootConfig.resources.runtime[dotnetJsResourceName]; const scriptElem = document.createElement('script'); - scriptElem.src = `_framework/wasm/${dotnetJsResourceName}`; + scriptElem.src = `_framework/${dotnetJsResourceName}`; scriptElem.defer = true; // For consistency with WebAssemblyResourceLoader, we only enforce SRI if caching is allowed @@ -204,11 +204,11 @@ function createEmscriptenModuleInstance(resourceLoader: WebAssemblyResourceLoade // Begin loading the .dll/.pdb/.wasm files, but don't block here. Let other loading processes run in parallel. const dotnetWasmResourceName = 'dotnet.wasm'; - const assembliesBeingLoaded = resourceLoader.loadResources(resources.assembly, filename => `_framework/_bin/${filename}`, 'assembly'); - const pdbsBeingLoaded = resourceLoader.loadResources(resources.pdb || {}, filename => `_framework/_bin/${filename}`, 'pdb'); + const assembliesBeingLoaded = resourceLoader.loadResources(resources.assembly, filename => `_framework/${filename}`, 'assembly'); + const pdbsBeingLoaded = resourceLoader.loadResources(resources.pdb || {}, filename => `_framework/${filename}`, 'pdb'); const wasmBeingLoaded = resourceLoader.loadResource( /* name */ dotnetWasmResourceName, - /* url */ `_framework/wasm/${dotnetWasmResourceName}`, + /* url */ `_framework/${dotnetWasmResourceName}`, /* hash */ resourceLoader.bootConfig.resources.runtime[dotnetWasmResourceName], /* type */ 'dotnetwasm'); @@ -217,7 +217,7 @@ function createEmscriptenModuleInstance(resourceLoader: WebAssemblyResourceLoade if (resourceLoader.bootConfig.resources.runtime.hasOwnProperty(dotnetTimeZoneResourceName)) { timeZoneResource = resourceLoader.loadResource( dotnetTimeZoneResourceName, - `_framework/wasm/${dotnetTimeZoneResourceName}`, + `_framework/${dotnetTimeZoneResourceName}`, resourceLoader.bootConfig.resources.runtime[dotnetTimeZoneResourceName], 'timezonedata'); } @@ -267,7 +267,7 @@ function createEmscriptenModuleInstance(resourceLoader: WebAssemblyResourceLoade if (satelliteResources) { const resourcePromises = Promise.all(culturesToLoad .filter(culture => satelliteResources.hasOwnProperty(culture)) - .map(culture => resourceLoader.loadResources(satelliteResources[culture], fileName => `_framework/_bin/${fileName}`, 'assembly')) + .map(culture => resourceLoader.loadResources(satelliteResources[culture], fileName => `_framework/${fileName}`, 'assembly')) .reduce((previous, next) => previous.concat(next), new Array<LoadingResource>()) .map(async resource => (await resource.response).arrayBuffer())); diff --git a/src/Components/WebAssembly/Build/src/Microsoft.AspNetCore.Components.WebAssembly.Build.csproj b/src/Components/WebAssembly/Build/src/Microsoft.AspNetCore.Components.WebAssembly.Build.csproj deleted file mode 100644 index d15e4ca761..0000000000 --- a/src/Components/WebAssembly/Build/src/Microsoft.AspNetCore.Components.WebAssembly.Build.csproj +++ /dev/null @@ -1,112 +0,0 @@ -<Project Sdk="Microsoft.NET.Sdk"> - - <PropertyGroup> - <TargetFrameworks>$(DefaultNetCoreTargetFramework);net46</TargetFrameworks> - <TargetName>Microsoft.AspNetCore.Components.WebAssembly.Build.Tasks</TargetName> - <AssemblyName>Microsoft.AspNetCore.Components.WebAssembly.Build</AssemblyName> - <Description>Build mechanism for ASP.NET Core Blazor WebAssembly applications.</Description> - <IsShippingPackage>true</IsShippingPackage> - <GenerateDependencyFile>false</GenerateDependencyFile> - <GenerateDocumentationFile>true</GenerateDocumentationFile> - </PropertyGroup> - - <!-- Pack settings --> - <PropertyGroup> - <!-- Producing this package requires building with NodeJS enabled. --> - <IsPackable Condition="'$(BuildNodeJS)' == 'false'">false</IsPackable> - <NoPackageAnalysis>true</NoPackageAnalysis> - <NuspecFile>Microsoft.AspNetCore.Components.WebAssembly.Build.nuspec</NuspecFile> - </PropertyGroup> - - <ItemGroup> - <NuspecProperty Include="configuration=$(Configuration)" /> - <NuspecProperty Include="taskskDir=$(OutputPath)tools" /> - <NuspecProperty Include="MicrosoftAspNetCoreComponentsWebAssemblyRuntimePackageVersion=$(MicrosoftAspNetCoreComponentsWebAssemblyRuntimePackageVersion)" /> - <NuspecProperty Include="PackageThirdPartyNoticesFile=$(PackageThirdPartyNoticesFile)" /> - </ItemGroup> - - <ItemGroup> - <InternalsVisibleTo Include="Microsoft.AspNetCore.Components.WebAssembly.Build.Tests" /> - </ItemGroup> - - <ItemGroup> - <!-- Add a project dependency without reference output assemblies to enforce build order --> - <!-- Applying workaround for https://github.com/microsoft/msbuild/issues/2661 and https://github.com/dotnet/sdk/issues/952 --> - <ProjectReference - Include="$(RepoRoot)src\Components\Web.JS\Microsoft.AspNetCore.Components.Web.JS.npmproj" - ReferenceOutputAssemblies="false" - SkipGetTargetFrameworkProperties="true" - UndefineProperties="TargetFramework" - Private="false" - Condition="'$(BuildNodeJS)' != 'false' and '$(BuildingInsideVisualStudio)' != 'true'" /> - - <ProjectReference - Include="..\..\Compression\src\Microsoft.AspNetCore.Components.WebAssembly.Build.BrotliCompression.csproj" - ReferenceOutputAssemblies="false" - Condition="'$(TargetFramework)' == '$(DefaultNetCoreTargetFramework)'" /> - - <Reference Include="Microsoft.Build.Framework" ExcludeAssets="Runtime" /> - <Reference Include="Microsoft.Build.Utilities.Core" ExcludeAssets="Runtime" /> - <Reference Include="System.Reflection.Metadata" Condition="'$(TargetFramework)' == 'net46'" /> - </ItemGroup> - - <Target Name="CopyBuildTask" BeforeTargets="Build" Condition="'$(DotNetBuildFromSource)' != 'true' AND '$(IsInnerBuild)' != 'true'"> - <!-- - The task produced by this project is referenced within this solution. When building, Visual Studio will lock up the assembly. - Any attempts to overwrite the binary with a newer version will fail. This is particularly grating if a developer "Rebuilds" the project - after an initial build since that would always attempt to overwrite the tasks dll - - This target attempts to make this solution more usable at the cost of a more onerous inner-loop build of the Blazor.Build tasks. - We'll copy the tasks to a location other that than the build output and use that in the Blazor.Build.targets. In the most common - case where these tasks aren't being worked on, everything should work great. However, if you're attemping to modify these tasks, - you will need to manaully stop MSBuild.exe processes - --> - - <ItemGroup> - <_NetCoreFilesToCopy Include="$(OutputPath)$(DefaultNetCoreTargetFramework)\*" TargetPath="netcoreapp\" /> - <_DesktopFilesToCopy Include="$(OutputPath)net46\*" TargetPath="netfx\" /> - <_AllFilesToCopy Include="@(_NetCoreFilesToCopy);@(_DesktopFilesToCopy)" /> - </ItemGroup> - - <Error Text="No files found in $(OutputPath)$(DefaultNetCoreTargetFramework)" Condition="@(_NetCoreFilesToCopy->Count()) == 0" /> - <Error Text="No files found in $(OutputPath)net46" Condition="@(_DesktopFilesToCopy->Count()) == 0" /> - - <Copy SourceFiles="@(_AllFilesToCopy)" DestinationFiles="@(_AllFilesToCopy->'$(OutputPath)tools\%(TargetPath)%(FileName)%(Extension)')" SkipUnchangedFiles="true" Retries="1" ContinueOnError="true"> - <Output TaskParameter="CopiedFiles" ItemName="FileWrites" /> - </Copy> - </Target> - - <ItemGroup> - <_BrotliToolPathInput Include="..\..\Compression\src\Microsoft.AspNetCore.Components.WebAssembly.Build.BrotliCompression.csproj" /> - <_BrotliToolPathInput Include="..\..\Compression\src\*.cs" /> - <_BrotliToolPathInput Include="..\..\Compression\src\*.runtimeconfig.json" /> - <_BrotliToolPathOutput Include="$(MSBuildThisFileDirectory)bin\$(Configuration)\tools\compression\blazor-brotli.dll" /> - </ItemGroup> - - <Target - Name="GetBrotliTools" - BeforeTargets="Build;GenerateNuspec" - Inputs="@(_BrotliToolPathInput)" - Outputs="@(_BrotliToolPathOutput)" - Condition="'$(DotNetBuildFromSource)' != 'true'"> - <ItemGroup> - <_BrotliToolsPath Include="$(MSBuildThisFileDirectory)bin\$(Configuration)\tools\compression\" /> - </ItemGroup> - - <PropertyGroup> - <_BrotliToolsOutputPath>@(_BrotliToolsPath->'%(FullPath)')</_BrotliToolsOutputPath> - </PropertyGroup> - - <ItemGroup> - <NuspecProperty Include="brotliDir=$(_BrotliToolsOutputPath)" /> - </ItemGroup> - - <MSBuild - Projects="..\..\Compression\src\Microsoft.AspNetCore.Components.WebAssembly.Build.BrotliCompression.csproj" - Targets="Publish" - Properties="Configuration=$(Configuration);TargetFramework=$(DefaultNetCoreTargetFramework);PublishDir=$(_BrotliToolsOutputPath)"> - </MSBuild> - - </Target> - -</Project> diff --git a/src/Components/WebAssembly/Build/src/Microsoft.AspNetCore.Components.WebAssembly.Build.nuspec b/src/Components/WebAssembly/Build/src/Microsoft.AspNetCore.Components.WebAssembly.Build.nuspec deleted file mode 100644 index 9b8aa9ad3a..0000000000 --- a/src/Components/WebAssembly/Build/src/Microsoft.AspNetCore.Components.WebAssembly.Build.nuspec +++ /dev/null @@ -1,19 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd"> - <metadata> - $CommonMetadataElements$ - <dependencies> - <dependency id="Microsoft.AspNetCore.Components.WebAssembly.Runtime" version="$MicrosoftAspNetCoreComponentsWebAssemblyRuntimePackageVersion$" include="all" /> - </dependencies> - </metadata> - <files> - $CommonFileElements$ - <file src="$PackageThirdPartyNoticesFile$" target=".\THIRD-PARTY-NOTICES.txt" /> - <file src="build\**" target="build" /> - <file src="$brotliDir$blazor-brotli.dll" target="tools/compression" /> - <file src="$brotliDir$blazor-brotli.runtimeconfig.json" target="tools/compression" /> - <file src="targets\**" target="targets" /> - <file src="$taskskDir$\**" target="tools/" /> - <file src="..\..\..\Web.JS\dist\$configuration$\blazor.webassembly.js" target="tools/blazor" /> - </files> -</package> diff --git a/src/Components/WebAssembly/Build/src/ReferenceBlazorBuildFromSource.props b/src/Components/WebAssembly/Build/src/ReferenceBlazorBuildFromSource.props deleted file mode 100644 index 2083ec2891..0000000000 --- a/src/Components/WebAssembly/Build/src/ReferenceBlazorBuildFromSource.props +++ /dev/null @@ -1,27 +0,0 @@ -<Project> - <!-- - Importing this file is equivalent to having: - <PackageDependency Include="Microsoft.AspNetCore.Blazor.Build" /> - ... except it's much more convenient when working in this repo, because it consumes the - Blazor.Build targets/exe directly without needing this project to be packed into a .nupkg. - - This is only intended for use by other projects in this repo. - --> - - <PropertyGroup> - <ComponentsRoot Condition="'$(ComponentsRoot)'==''">$(MSBuildThisFileDirectory)..\..\..\</ComponentsRoot> - <BlazorBuildConfiguration Condition="'$(BlazorBuildConfiguration)'==''">$(Configuration)</BlazorBuildConfiguration> - - <_BlazorJsPath>$(ComponentsRoot)Web.JS\dist\$(BlazorBuildConfiguration)\blazor.webassembly.js</_BlazorJsPath> - <_BlazorJsMapPath>$(ComponentsRoot)Web.JS\dist\$(BlazorBuildConfiguration)\blazor.webassembly.js.map</_BlazorJsMapPath> - <_BlazorToolsDir>$(MSBuildThisFileDirectory)bin\$(BlazorBuildConfiguration)\tools\</_BlazorToolsDir> - </PropertyGroup> - - <Target Name="Check_BlazorJSFiles" BeforeTargets="Build" Condition="'$(ExcludeFromBuild)' != 'true'"> - <Error Text="blazor.webassembly.js file could not be found at $(_BlazorJsPath)" Condition="!Exists($(_BlazorJsPath))" /> - </Target> - - <Import Project="$(MSBuildThisFileDirectory)targets/All.props" /> - <Import Project="$(MSBuildThisFileDirectory)targets/All.targets" /> - -</Project> diff --git a/src/Components/WebAssembly/Build/src/ReferenceFromSource.props b/src/Components/WebAssembly/Build/src/ReferenceFromSource.props deleted file mode 100644 index decf4343ee..0000000000 --- a/src/Components/WebAssembly/Build/src/ReferenceFromSource.props +++ /dev/null @@ -1,48 +0,0 @@ -<Project> - - <Import Project="ReferenceBlazorBuildFromSource.props" /> - - <!-- - Debugging support using blazor-devserver serve. - - A few things to note here: - - We have to use dotnet exec to avoid launching another process and confusing the debugger. - - Since we're doing dotnet exec, it won't automatically rebuild the DevServer project. - - $(AdditionalRunArguments) needs to be defined before importing this file. - --> - <PropertyGroup> - <RunCommand>dotnet</RunCommand> - <_BlazorCliLocation>$(MSBuildThisFileDirectory)../../DevServer/src/bin/$(Configuration)/$(DefaultNetCoreTargetFramework)/blazor-devserver.dll</_BlazorCliLocation> - <RunArguments>exec "$(_BlazorCliLocation)" serve --applicationpath "$(MSBuildProjectDirectory)/$(OutputPath)$(TargetFileName)" $(AdditionalRunArguments)</RunArguments> - </PropertyGroup> - - <ItemGroup> - <Reference Include="Microsoft.AspNetCore.Components.WebAssembly.Runtime" /> - </ItemGroup> - - <Target Name="_BuildBlazorBuildProject" BeforeTargets="ResolveProjectReferences" Condition="'$(NoBuild)' != 'true'"> - <!-- - The Blazor.Build project cross-compiles and we need the output of all TFMs to be available in the build output. - We can't represent this in any good way using ProjectReference elements, but we can try and build it instead. - --> - <MSBuild Projects="$(MSBuildThisFileDirectory)Microsoft.AspNetCore.Components.WebAssembly.Build.csproj" /> - </Target> - - <!-- This is used as a P2P when building the repo. Normal Blazor projects will get this as a reference through the Blazor.Build package --> - <ItemGroup> - <!-- Ensures these projects are built before the consuming project, but without - adding a runtime dependency on the .dll (to be equivalent to a <PackageDependency> - given that the packed version of this project wouldn't add a .dll reference) --> - <ProjectReference Include="$(MSBuildThisFileDirectory)Microsoft.AspNetCore.Components.WebAssembly.Build.csproj"> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - <SkipGetTargetFrameworkProperties>true</SkipGetTargetFrameworkProperties> - <Properties>TargetFramework=$(DefaultNetCoreTargetFramework)</Properties> - </ProjectReference> - <ProjectReference Include="$(MSBuildThisFileDirectory)..\..\DevServer\src\Microsoft.AspNetCore.Components.WebAssembly.DevServer.csproj"> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - <!-- Optimization. Do not require framework compatibility between these projects. --> - <SkipGetTargetFrameworkProperties>true</SkipGetTargetFrameworkProperties> - <UndefineProperties>TargetFramework</UndefineProperties> - </ProjectReference> - </ItemGroup> -</Project> diff --git a/src/Components/WebAssembly/Build/src/Tasks/BlazorCreateRootDescriptorFile.cs b/src/Components/WebAssembly/Build/src/Tasks/BlazorCreateRootDescriptorFile.cs deleted file mode 100644 index 45359bdb8a..0000000000 --- a/src/Components/WebAssembly/Build/src/Tasks/BlazorCreateRootDescriptorFile.cs +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Xml; -using System.Xml.Linq; -using Microsoft.Build.Framework; -using Microsoft.Build.Utilities; - -namespace Microsoft.AspNetCore.Components.WebAssembly.Build -{ - // Based on https://github.com/mono/linker/blob/3b329b9481e300bcf4fb88a2eebf8cb5ef8b323b/src/ILLink.Tasks/CreateRootDescriptorFile.cs - public class BlazorCreateRootDescriptorFile : Task - { - [Required] - public ITaskItem[] AssemblyNames { get; set; } - - [Required] - public ITaskItem RootDescriptorFilePath { get; set; } - - public override bool Execute() - { - using var fileStream = File.Create(RootDescriptorFilePath.ItemSpec); - var assemblyNames = AssemblyNames.Select(a => a.ItemSpec); - - WriteRootDescriptor(fileStream, assemblyNames); - return true; - } - - internal static void WriteRootDescriptor(Stream stream, IEnumerable<string> assemblyNames) - { - var roots = new XElement("linker"); - foreach (var assemblyName in assemblyNames) - { - roots.Add(new XElement("assembly", - new XAttribute("fullname", assemblyName), - new XElement("type", - new XAttribute("fullname", "*"), - new XAttribute("required", "true")))); - } - - var xmlWriterSettings = new XmlWriterSettings - { - Indent = true, - OmitXmlDeclaration = true - }; - - using var writer = XmlWriter.Create(stream, xmlWriterSettings); - var xDocument = new XDocument(roots); - - xDocument.Save(writer); - } - } -} diff --git a/src/Components/WebAssembly/Build/src/Tasks/BlazorGetFileHash.cs b/src/Components/WebAssembly/Build/src/Tasks/BlazorGetFileHash.cs deleted file mode 100644 index f10f53a748..0000000000 --- a/src/Components/WebAssembly/Build/src/Tasks/BlazorGetFileHash.cs +++ /dev/null @@ -1,135 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System; -using System.Collections.Generic; -using System.IO; -using System.Security.Cryptography; -using Microsoft.Build.Framework; -using Microsoft.Build.Utilities; - -namespace Microsoft.Build.Tasks -{ - /// <summary> - /// Computes the checksum for a single file. - /// </summary> - public sealed class BlazorGetFileHash : Task - { - internal const string _defaultFileHashAlgorithm = "SHA256"; - internal const string _hashEncodingBase64 = "base64"; - - /// <summary> - /// The files to be hashed. - /// </summary> - [Required] - public ITaskItem[] Files { get; set; } - - /// <summary> - /// The algorithm. Allowed values: SHA256, SHA384, SHA512. Default = SHA256. - /// </summary> - public string Algorithm { get; set; } = _defaultFileHashAlgorithm; - - /// <summary> - /// The metadata name where the hash is stored in each item. Defaults to "FileHash". - /// </summary> - public string MetadataName { get; set; } = "FileHash"; - - /// <summary> - /// The encoding to use for generated hashs. Defaults to "hex". Allowed values = "base64". - /// </summary> - public string HashEncoding { get; set; } = _hashEncodingBase64; - - /// <summary> - /// The hash of the file. This is only set if there was one item group passed in. - /// </summary> - [Output] - public string Hash { get; set; } - - /// <summary> - /// The input files with additional metadata set to include the file hash. - /// </summary> - [Output] - public ITaskItem[] Items { get; set; } - - public override bool Execute() - { - if (!SupportsAlgorithm(Algorithm)) - { - Log.LogError("Unrecognized HashAlgorithm {0}", Algorithm); - return false; - } - - System.Threading.Tasks.Parallel.ForEach(Files, file => - { - if (!File.Exists(file.ItemSpec)) - { - Log.LogError("File not found '{0}", file.ItemSpec); - } - }); - - if (Log.HasLoggedErrors) - { - return false; - } - - System.Threading.Tasks.Parallel.ForEach(Files, file => - { - var hash = ComputeHash(Algorithm, file.ItemSpec); - file.SetMetadata("FileHashAlgorithm", Algorithm); - file.SetMetadata(MetadataName, EncodeHash(hash)); - }); - - Items = Files; - - if (Files.Length == 1) - { - Hash = Files[0].GetMetadata(MetadataName); - } - - return !Log.HasLoggedErrors; - } - - internal static string EncodeHash(byte[] hash) - { - return Convert.ToBase64String(hash); - } - - internal static bool SupportsAlgorithm(string algorithmName) - => _supportedAlgorithms.Contains(algorithmName); - - internal static byte[] ComputeHash(string algorithmName, string filePath) - { - using (var stream = File.OpenRead(filePath)) - using (var algorithm = CreateAlgorithm(algorithmName)) - { - return algorithm.ComputeHash(stream); - } - } - - private static readonly HashSet<string> _supportedAlgorithms - = new HashSet<string>(StringComparer.OrdinalIgnoreCase) - { - "SHA256", - "SHA384", - "SHA512", - }; - - private static HashAlgorithm CreateAlgorithm(string algorithmName) - { - if (string.Equals(algorithmName, "SHA256", StringComparison.OrdinalIgnoreCase)) - { - return SHA256.Create(); - } - else if (string.Equals(algorithmName, "SHA384", StringComparison.OrdinalIgnoreCase)) - { - return SHA384.Create(); - } - else if (string.Equals(algorithmName, "SHA512", StringComparison.OrdinalIgnoreCase)) - { - return SHA512.Create(); - } - - throw new ArgumentOutOfRangeException(); - } - } -}
\ No newline at end of file diff --git a/src/Components/WebAssembly/Build/src/Tasks/BlazorILLink.cs b/src/Components/WebAssembly/Build/src/Tasks/BlazorILLink.cs deleted file mode 100644 index 0244e9f0c2..0000000000 --- a/src/Components/WebAssembly/Build/src/Tasks/BlazorILLink.cs +++ /dev/null @@ -1,194 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.IO; -using System.Text; -using Microsoft.Build.Framework; -using Microsoft.Build.Utilities; - -namespace Microsoft.AspNetCore.Components.WebAssembly.Build.Tasks -{ - // Based on https://github.com/mono/linker/blob/3b329b9481e300bcf4fb88a2eebf8cb5ef8b323b/src/ILLink.Tasks/LinkTask.cs - public class BlazorILLink : ToolTask - { - private const string DotNetHostPathEnvironmentName = "DOTNET_HOST_PATH"; - - [Required] - public string ILLinkPath { get; set; } - - [Required] - public ITaskItem[] AssemblyPaths { get; set; } - - public ITaskItem[] ReferenceAssemblyPaths { get; set; } - - [Required] - public ITaskItem[] RootAssemblyNames { get; set; } - - [Required] - public ITaskItem OutputDirectory { get; set; } - - public ITaskItem[] RootDescriptorFiles { get; set; } - - public bool ClearInitLocals { get; set; } - - public string ClearInitLocalsAssemblies { get; set; } - - public string ExtraArgs { get; set; } - - public bool DumpDependencies { get; set; } - - private string _dotnetPath; - - private string DotNetPath - { - get - { - if (!string.IsNullOrEmpty(_dotnetPath)) - { - return _dotnetPath; - } - - _dotnetPath = Environment.GetEnvironmentVariable(DotNetHostPathEnvironmentName); - if (string.IsNullOrEmpty(_dotnetPath)) - { - throw new InvalidOperationException($"{DotNetHostPathEnvironmentName} is not set"); - } - - return _dotnetPath; - } - } - - protected override MessageImportance StandardErrorLoggingImportance => MessageImportance.High; - - protected override string ToolName => Path.GetFileName(DotNetPath); - - protected override string GenerateFullPathToTool() => DotNetPath; - - protected override string GenerateCommandLineCommands() - { - var args = new StringBuilder(); - args.Append(Quote(ILLinkPath)); - return args.ToString(); - } - - private static string Quote(string path) - { - return $"\"{path.TrimEnd('\\')}\""; - } - - protected override string GenerateResponseFileCommands() - { - var args = new StringBuilder(); - - if (RootDescriptorFiles != null) - { - foreach (var rootFile in RootDescriptorFiles) - { - args.Append("-x ").AppendLine(Quote(rootFile.ItemSpec)); - } - } - - foreach (var assemblyItem in RootAssemblyNames) - { - args.Append("-a ").AppendLine(Quote(assemblyItem.ItemSpec)); - } - - var assemblyNames = new HashSet<string>(StringComparer.OrdinalIgnoreCase); - foreach (var assembly in AssemblyPaths) - { - var assemblyPath = assembly.ItemSpec; - var assemblyName = Path.GetFileNameWithoutExtension(assemblyPath); - - // If there are multiple paths with the same assembly name, only use the first one. - if (!assemblyNames.Add(assemblyName)) - { - continue; - } - - args.Append("-reference ") - .AppendLine(Quote(assemblyPath)); - - var action = assembly.GetMetadata("action"); - if ((action != null) && (action.Length > 0)) - { - args.Append("-p "); - args.Append(action); - args.Append(" ").AppendLine(Quote(assemblyName)); - } - } - - if (ReferenceAssemblyPaths != null) - { - foreach (var assembly in ReferenceAssemblyPaths) - { - var assemblyPath = assembly.ItemSpec; - var assemblyName = Path.GetFileNameWithoutExtension(assemblyPath); - - // Don't process references for which we already have - // implementation assemblies. - if (assemblyNames.Contains(assemblyName)) - { - continue; - } - - args.Append("-reference ").AppendLine(Quote(assemblyPath)); - - // Treat reference assemblies as "skip". Ideally we - // would not even look at the IL, but only use them to - // resolve surface area. - args.Append("-p skip ").AppendLine(Quote(assemblyName)); - } - } - - if (OutputDirectory != null) - { - args.Append("-out ").AppendLine(Quote(OutputDirectory.ItemSpec)); - } - - if (ClearInitLocals) - { - args.AppendLine("--enable-opt clearinitlocals"); - if ((ClearInitLocalsAssemblies != null) && (ClearInitLocalsAssemblies.Length > 0)) - { - args.Append("-m ClearInitLocalsAssemblies "); - args.AppendLine(ClearInitLocalsAssemblies); - } - } - - if (ExtraArgs != null) - { - args.AppendLine(ExtraArgs); - } - - if (DumpDependencies) - { - args.AppendLine("--dump-dependencies"); - } - - return args.ToString(); - } - - protected override bool HandleTaskExecutionErrors() - { - // Show a slightly better error than the standard ToolTask message that says "dotnet" failed. - Log.LogError($"ILLink failed with exit code {ExitCode}."); - return false; - } - - protected override void LogEventsFromTextOutput(string singleLine, MessageImportance messageImportance) - { - if (!string.IsNullOrEmpty(singleLine) && singleLine.StartsWith("Unhandled exception.", StringComparison.Ordinal)) - { - // The Mono linker currently prints out an entire stack trace when the linker fails. - // We want to show something actionable in the VS Error window. - Log.LogError(singleLine); - } - else - { - base.LogEventsFromTextOutput(singleLine, messageImportance); - } - } - } -} diff --git a/src/Components/WebAssembly/Build/src/Tasks/BlazorReadSatelliteAssemblyFile.cs b/src/Components/WebAssembly/Build/src/Tasks/BlazorReadSatelliteAssemblyFile.cs deleted file mode 100644 index 18a3fc8214..0000000000 --- a/src/Components/WebAssembly/Build/src/Tasks/BlazorReadSatelliteAssemblyFile.cs +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Linq; -using System.Xml.Linq; -using Microsoft.Build.Framework; -using Microsoft.Build.Utilities; - -namespace Microsoft.AspNetCore.Components.WebAssembly.Build -{ - public class BlazorReadSatelliteAssemblyFile : Task - { - [Output] - public ITaskItem[] SatelliteAssembly { get; set; } - - [Required] - public ITaskItem ReadFile { get; set; } - - public override bool Execute() - { - var document = XDocument.Load(ReadFile.ItemSpec); - SatelliteAssembly = document.Root - .Elements() - .Select(e => - { - // <Assembly Name="..." Culture="..." DestinationSubDirectory="..." /> - - var taskItem = new TaskItem(e.Attribute("Name").Value); - taskItem.SetMetadata("Culture", e.Attribute("Culture").Value); - taskItem.SetMetadata("DestinationSubDirectory", e.Attribute("DestinationSubDirectory").Value); - - return taskItem; - }).ToArray(); - - return true; - } - } -} diff --git a/src/Components/WebAssembly/Build/src/Tasks/BlazorWriteSatelliteAssemblyFile.cs b/src/Components/WebAssembly/Build/src/Tasks/BlazorWriteSatelliteAssemblyFile.cs deleted file mode 100644 index e1e6a8150e..0000000000 --- a/src/Components/WebAssembly/Build/src/Tasks/BlazorWriteSatelliteAssemblyFile.cs +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.IO; -using System.Xml; -using System.Xml.Linq; -using Microsoft.Build.Framework; -using Microsoft.Build.Utilities; - -namespace Microsoft.AspNetCore.Components.WebAssembly.Build -{ - public class BlazorWriteSatelliteAssemblyFile : Task - { - [Required] - public ITaskItem[] SatelliteAssembly { get; set; } - - [Required] - public ITaskItem WriteFile { get; set; } - - public override bool Execute() - { - using var fileStream = File.Create(WriteFile.ItemSpec); - WriteSatelliteAssemblyFile(fileStream); - return true; - } - - internal void WriteSatelliteAssemblyFile(Stream stream) - { - var root = new XElement("SatelliteAssembly"); - - foreach (var item in SatelliteAssembly) - { - // <Assembly Name="..." Culture="..." DestinationSubDirectory="..." /> - - root.Add(new XElement("Assembly", - new XAttribute("Name", item.ItemSpec), - new XAttribute("Culture", item.GetMetadata("Culture")), - new XAttribute("DestinationSubDirectory", item.GetMetadata("DestinationSubDirectory")))); - } - - var xmlWriterSettings = new XmlWriterSettings - { - Indent = true, - OmitXmlDeclaration = true - }; - - using var writer = XmlWriter.Create(stream, xmlWriterSettings); - var xDocument = new XDocument(root); - - xDocument.Save(writer); - } - } -} diff --git a/src/Components/WebAssembly/Build/src/Tasks/BrotliCompressBlazorApplicationFiles.cs b/src/Components/WebAssembly/Build/src/Tasks/BrotliCompressBlazorApplicationFiles.cs deleted file mode 100644 index fc4a4e6ad9..0000000000 --- a/src/Components/WebAssembly/Build/src/Tasks/BrotliCompressBlazorApplicationFiles.cs +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.IO; -using System.Text; -using Microsoft.Build.Framework; -using Microsoft.Build.Utilities; - -namespace Microsoft.AspNetCore.Components.WebAssembly.Build -{ - public class BrotliCompressBlazorApplicationFiles : ToolTask - { - private const string DotNetHostPathEnvironmentName = "DOTNET_HOST_PATH"; - - [Required] - public string ManifestPath { get; set; } - - [Required] - public string BlazorBrotliPath { get; set; } - - private string _dotnetPath; - - private string DotNetPath - { - get - { - if (!string.IsNullOrEmpty(_dotnetPath)) - { - return _dotnetPath; - } - - _dotnetPath = Environment.GetEnvironmentVariable(DotNetHostPathEnvironmentName); - if (string.IsNullOrEmpty(_dotnetPath)) - { - throw new InvalidOperationException($"{DotNetHostPathEnvironmentName} is not set"); - } - - return _dotnetPath; - } - } - - protected override MessageImportance StandardErrorLoggingImportance => MessageImportance.High; - - protected override string ToolName => Path.GetFileName(DotNetPath); - - protected override string GenerateFullPathToTool() => DotNetPath; - - protected override string GenerateCommandLineCommands() => - $"\"{BlazorBrotliPath}\" \"{ManifestPath}\""; - } -} diff --git a/src/Components/WebAssembly/Build/src/Tasks/GenerateBlazorBootJson.cs b/src/Components/WebAssembly/Build/src/Tasks/GenerateBlazorBootJson.cs deleted file mode 100644 index d3f1de66a9..0000000000 --- a/src/Components/WebAssembly/Build/src/Tasks/GenerateBlazorBootJson.cs +++ /dev/null @@ -1,232 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.IO; -using System.Reflection; -using System.Runtime.Serialization; -using System.Runtime.Serialization.Json; -using System.Text; -using Microsoft.Build.Framework; -using Microsoft.Build.Utilities; -using ResourceHashesByNameDictionary = System.Collections.Generic.Dictionary<string, string>; - -namespace Microsoft.AspNetCore.Components.WebAssembly.Build -{ - public class GenerateBlazorBootJson : Task - { - [Required] - public string AssemblyPath { get; set; } - - [Required] - public ITaskItem[] Resources { get; set; } - - [Required] - public bool DebugBuild { get; set; } - - [Required] - public bool LinkerEnabled { get; set; } - - [Required] - public bool CacheBootResources { get; set; } - - public ITaskItem[] ConfigurationFiles { get; set; } - - [Required] - public string OutputPath { get; set; } - - public override bool Execute() - { - using var fileStream = File.Create(OutputPath); - var entryAssemblyName = AssemblyName.GetAssemblyName(AssemblyPath).Name; - - try - { - WriteBootJson(fileStream, entryAssemblyName); - } - catch (Exception ex) - { - Log.LogErrorFromException(ex); - } - - return !Log.HasLoggedErrors; - } - - // Internal for tests - internal void WriteBootJson(Stream output, string entryAssemblyName) - { - var result = new BootJsonData - { - entryAssembly = entryAssemblyName, - cacheBootResources = CacheBootResources, - debugBuild = DebugBuild, - linkerEnabled = LinkerEnabled, - resources = new ResourcesData(), - config = new List<string>(), - }; - - // Build a two-level dictionary of the form: - // - assembly: - // - UriPath (e.g., "System.Text.Json.dll") - // - ContentHash (e.g., "4548fa2e9cf52986") - // - runtime: - // - UriPath (e.g., "dotnet.js") - // - ContentHash (e.g., "3448f339acf512448") - if (Resources != null) - { - var resourceData = result.resources; - foreach (var resource in Resources) - { - var resourceTypeMetadata = resource.GetMetadata("BootManifestResourceType"); - ResourceHashesByNameDictionary resourceList; - switch (resourceTypeMetadata) - { - case "runtime": - resourceList = resourceData.runtime; - break; - case "assembly": - resourceList = resourceData.assembly; - break; - case "dynamicAssembly": - resourceList = resourceData.dynamicAssembly; - break; - case "pdb": - resourceData.pdb ??= new ResourceHashesByNameDictionary(); - resourceList = resourceData.pdb; - break; - case "satellite": - if (resourceData.satelliteResources is null) - { - resourceData.satelliteResources = new Dictionary<string, ResourceHashesByNameDictionary>(StringComparer.OrdinalIgnoreCase); - } - var resourceCulture = resource.GetMetadata("Culture"); - if (resourceCulture is null) - { - Log.LogWarning("Satellite resource {0} does not specify required metadata 'Culture'.", resource); - continue; - } - - if (!resourceData.satelliteResources.TryGetValue(resourceCulture, out resourceList)) - { - resourceList = new ResourceHashesByNameDictionary(); - resourceData.satelliteResources.Add(resourceCulture, resourceList); - } - break; - default: - throw new NotSupportedException($"Unsupported BootManifestResourceType metadata value: {resourceTypeMetadata}"); - } - - var resourceName = GetResourceName(resource); - if (!resourceList.ContainsKey(resourceName)) - { - resourceList.Add(resourceName, $"sha256-{resource.GetMetadata("Integrity")}"); - } - } - } - - if (ConfigurationFiles != null) - { - foreach (var configFile in ConfigurationFiles) - { - result.config.Add(Path.GetFileName(configFile.ItemSpec)); - } - } - - var serializer = new DataContractJsonSerializer(typeof(BootJsonData), new DataContractJsonSerializerSettings - { - UseSimpleDictionaryFormat = true - }); - - using var writer = JsonReaderWriterFactory.CreateJsonWriter(output, Encoding.UTF8, ownsStream: false, indent: true); - serializer.WriteObject(writer, result); - } - - private static string GetResourceName(ITaskItem item) - { - var name = item.GetMetadata("BootManifestResourceName"); - - if (string.IsNullOrEmpty(name)) - { - throw new Exception($"No BootManifestResourceName was specified for item '{item.ItemSpec}'"); - } - - return name.Replace('\\', '/'); - } - -#pragma warning disable IDE1006 // Naming Styles - /// <summary> - /// Defines the structure of a Blazor boot JSON file - /// </summary> - public class BootJsonData - { - /// <summary> - /// Gets the name of the assembly with the application entry point - /// </summary> - public string entryAssembly { get; set; } - - /// <summary> - /// Gets the set of resources needed to boot the application. This includes the transitive - /// closure of .NET assemblies (including the entrypoint assembly), the dotnet.wasm file, - /// and any PDBs to be loaded. - /// - /// Within <see cref="ResourceHashesByNameDictionary"/>, dictionary keys are resource names, - /// and values are SHA-256 hashes formatted in prefixed base-64 style (e.g., 'sha256-abcdefg...') - /// as used for subresource integrity checking. - /// </summary> - public ResourcesData resources { get; set; } = new ResourcesData(); - - /// <summary> - /// Gets a value that determines whether to enable caching of the <see cref="resources"/> - /// inside a CacheStorage instance within the browser. - /// </summary> - public bool cacheBootResources { get; set; } - - /// <summary> - /// Gets a value that determines if this is a debug build. - /// </summary> - public bool debugBuild { get; set; } - - /// <summary> - /// Gets a value that determines if the linker is enabled. - /// </summary> - public bool linkerEnabled { get; set; } - - /// <summary> - /// Config files for the application - /// </summary> - public List<string> config { get; set; } - } - - public class ResourcesData - { - /// <summary> - /// .NET Wasm runtime resources (dotnet.wasm, dotnet.js) etc. - /// </summary> - public ResourceHashesByNameDictionary runtime { get; set; } = new ResourceHashesByNameDictionary(); - - /// <summary> - /// "assembly" (.dll) resources - /// </summary> - public ResourceHashesByNameDictionary assembly { get; set; } = new ResourceHashesByNameDictionary(); - - /// <summary> - /// Assembly (.dll) resources that are loaded dynamically during runtime - /// </summary> - public ResourceHashesByNameDictionary dynamicAssembly { get; set; } = new ResourceHashesByNameDictionary(); - - /// <summary> - /// "debug" (.pdb) resources - /// </summary> - [DataMember(EmitDefaultValue = false)] - public ResourceHashesByNameDictionary pdb { get; set; } - - /// <summary> - /// localization (.satellite resx) resources - /// </summary> - [DataMember(EmitDefaultValue = false)] - public Dictionary<string, ResourceHashesByNameDictionary> satelliteResources { get; set; } - } -#pragma warning restore IDE1006 // Naming Styles - } -}
\ No newline at end of file diff --git a/src/Components/WebAssembly/Build/src/Tasks/GenerateBlazorCompressionManifest.cs b/src/Components/WebAssembly/Build/src/Tasks/GenerateBlazorCompressionManifest.cs deleted file mode 100644 index e7a7b16ee2..0000000000 --- a/src/Components/WebAssembly/Build/src/Tasks/GenerateBlazorCompressionManifest.cs +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.IO; -using System.Runtime.Serialization; -using System.Runtime.Serialization.Json; -using System.Text; -using Microsoft.Build.Framework; -using Microsoft.Build.Utilities; - -namespace Microsoft.AspNetCore.Components.WebAssembly.Build -{ - public class GenerateBlazorCompressionManifest : Task - { - [Required] - public ITaskItem[] FilesToCompress { get; set; } - - [Required] - public string ManifestPath { get; set; } - - public override bool Execute() - { - try - { - WriteCompressionManifest(); - } - catch (Exception ex) - { - Log.LogErrorFromException(ex); - } - - return !Log.HasLoggedErrors; - } - - private void WriteCompressionManifest() - { - var tempFilePath = Path.GetTempFileName(); - - var manifest = new ManifestData(); - var filesToCompress = new List<CompressedFile>(); - - foreach (var file in FilesToCompress) - { - filesToCompress.Add(new CompressedFile - { - Source = file.GetMetadata("FullPath"), - InputSource = file.GetMetadata("InputSource"), - Target = file.GetMetadata("TargetCompressionPath"), - }); - } - - manifest.FilesToCompress = filesToCompress.ToArray(); - - var serializer = new DataContractJsonSerializer(typeof(ManifestData)); - - using (var tempFile = File.OpenWrite(tempFilePath)) - { - using (var writer = JsonReaderWriterFactory.CreateJsonWriter(tempFile, Encoding.UTF8, ownsStream: false, indent: true)) - { - serializer.WriteObject(writer, manifest); - } - } - - if (!File.Exists(ManifestPath)) - { - File.Move(tempFilePath, ManifestPath); - return; - } - - var originalText = File.ReadAllText(ManifestPath); - var newManifest = File.ReadAllText(tempFilePath); - if (!string.Equals(originalText, newManifest, StringComparison.Ordinal)) - { - // OnlyWriteWhenDifferent - File.Delete(ManifestPath); - File.Move(tempFilePath, ManifestPath); - } - } - - [DataContract] - private class ManifestData - { - [DataMember] - public CompressedFile[] FilesToCompress { get; set; } - } - - [DataContract] - private class CompressedFile - { - [DataMember] - public string Source { get; set; } - - [DataMember] - public string InputSource { get; set; } - - [DataMember] - public string Target { get; set; } - } - } -} diff --git a/src/Components/WebAssembly/Build/src/Tasks/GenerateServiceWorkerAssetsManifest.cs b/src/Components/WebAssembly/Build/src/Tasks/GenerateServiceWorkerAssetsManifest.cs deleted file mode 100644 index 9a1885ad0c..0000000000 --- a/src/Components/WebAssembly/Build/src/Tasks/GenerateServiceWorkerAssetsManifest.cs +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.IO; -using System.Linq; -using System.Runtime.Serialization.Json; -using System.Text; -using Microsoft.Build.Framework; -using Microsoft.Build.Utilities; - -namespace Microsoft.AspNetCore.Blazor.Build -{ - public class GenerateServiceWorkerAssetsManifest : Task - { - [Required] - public string Version { get; set; } - - [Required] - public ITaskItem[] AssetsWithHashes { get; set; } - - [Required] - public string OutputPath { get; set; } - - public override bool Execute() - { - using var fileStream = File.Create(OutputPath); - WriteFile(fileStream); - return true; - } - - internal void WriteFile(Stream stream) - { - var data = new AssetsManifestFile - { - version = Version, - assets = AssetsWithHashes.Select(item => new AssetsManifestFileEntry - { - url = item.GetMetadata("AssetUrl"), - hash = $"sha256-{item.GetMetadata("Integrity")}", - }).ToArray() - }; - - using var streamWriter = new StreamWriter(stream, Encoding.UTF8, bufferSize: 50, leaveOpen: true); - streamWriter.Write("self.assetsManifest = "); - streamWriter.Flush(); - - using var jsonWriter = JsonReaderWriterFactory.CreateJsonWriter(stream, Encoding.UTF8, ownsStream: false, indent: true); - new DataContractJsonSerializer(typeof(AssetsManifestFile)).WriteObject(jsonWriter, data); - jsonWriter.Flush(); - - streamWriter.WriteLine(";"); - } - -#pragma warning disable IDE1006 // Naming Styles - public class AssetsManifestFile - { - /// <summary> - /// Gets or sets a version string. - /// </summary> - public string version { get; set; } - - /// <summary> - /// Gets or sets the assets. Keys are URLs; values are base-64-formatted SHA256 content hashes. - /// </summary> - public AssetsManifestFileEntry[] assets { get; set; } - } - - public class AssetsManifestFileEntry - { - /// <summary> - /// Gets or sets the asset URL. Normally this will be relative to the application's base href. - /// </summary> - public string url { get; set; } - - /// <summary> - /// Gets or sets the file content hash. This should be the base-64-formatted SHA256 value. - /// </summary> - public string hash { get; set; } - } -#pragma warning restore IDE1006 // Naming Styles - } -} diff --git a/src/Components/WebAssembly/Build/src/Tasks/GenerateTypeGranularityLinkingConfig.cs b/src/Components/WebAssembly/Build/src/Tasks/GenerateTypeGranularityLinkingConfig.cs deleted file mode 100644 index 66e673501e..0000000000 --- a/src/Components/WebAssembly/Build/src/Tasks/GenerateTypeGranularityLinkingConfig.cs +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.IO; -using System.Xml.Linq; -using Microsoft.Build.Framework; -using Microsoft.Build.Utilities; - -namespace Microsoft.AspNetCore.Components.WebAssembly.Build.Tasks -{ - public class GenerateTypeGranularityLinkingConfig : Task - { - [Required] - public ITaskItem[] Assemblies { get; set; } - - [Required] - public string OutputPath { get; set; } - - public override bool Execute() - { - var linkerElement = new XElement("linker", - new XComment(" THIS IS A GENERATED FILE - DO NOT EDIT MANUALLY ")); - - foreach (var assembly in Assemblies) - { - var assemblyElement = CreateTypeGranularityConfig(assembly); - linkerElement.Add(assemblyElement); - } - - using var fileStream = File.Open(OutputPath, FileMode.Create); - new XDocument(linkerElement).Save(fileStream); - - return true; - } - - private XElement CreateTypeGranularityConfig(ITaskItem assembly) - { - // We match all types in the assembly, and for each one, tell the linker to preserve all - // its members (preserve=all) but only if there's some reference to the type (required=false) - return new XElement("assembly", - new XAttribute("fullname", Path.GetFileNameWithoutExtension(assembly.ItemSpec)), - new XElement("type", - new XAttribute("fullname", "*"), - new XAttribute("preserve", "all"), - new XAttribute("required", "false"))); - } - } -} diff --git a/src/Components/WebAssembly/Build/src/Tasks/GzipCompressBlazorApplicationFiles.cs b/src/Components/WebAssembly/Build/src/Tasks/GzipCompressBlazorApplicationFiles.cs deleted file mode 100644 index 53d26328a3..0000000000 --- a/src/Components/WebAssembly/Build/src/Tasks/GzipCompressBlazorApplicationFiles.cs +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.IO; -using System.IO.Compression; -using System.Runtime.Serialization; -using System.Runtime.Serialization.Json; -using Microsoft.Build.Framework; -using Microsoft.Build.Utilities; - -namespace Microsoft.AspNetCore.Components.WebAssembly.Build -{ - public class GzipCompressBlazorApplicationFiles : Task - { - [Required] - public string ManifestPath { get; set; } - - public override bool Execute() - { - var serializer = new DataContractJsonSerializer(typeof(ManifestData)); - - ManifestData manifest = null; - using (var tempFile = File.OpenRead(ManifestPath)) - { - manifest = (ManifestData)serializer.ReadObject(tempFile); - } - - System.Threading.Tasks.Parallel.ForEach(manifest.FilesToCompress, (file) => - { - var inputPath = file.Source; - var inputSource = file.InputSource; - var targetCompressionPath = file.Target; - - if (!File.Exists(inputSource)) - { - Log.LogMessage($"Skipping '{inputPath}' because '{inputSource}' does not exist."); - return; - } - - if (File.Exists(targetCompressionPath) && File.GetLastWriteTimeUtc(inputSource) < File.GetLastWriteTimeUtc(targetCompressionPath)) - { - // Incrementalism. If input source doesn't exist or it exists and is not newer than the expected output, do nothing. - Log.LogMessage($"Skipping '{inputPath}' because '{targetCompressionPath}' is newer than '{inputSource}'."); - return; - } - - try - { - Directory.CreateDirectory(Path.GetDirectoryName(targetCompressionPath)); - - using var sourceStream = File.OpenRead(inputPath); - using var fileStream = new FileStream(targetCompressionPath, FileMode.Create); - using var stream = new GZipStream(fileStream, CompressionLevel.Optimal); - - sourceStream.CopyTo(stream); - } - catch (Exception e) - { - Log.LogErrorFromException(e); - throw; - } - }); - - return !Log.HasLoggedErrors; - } - - [DataContract] - private class ManifestData - { - [DataMember] - public CompressedFile[] FilesToCompress { get; set; } - } - - [DataContract] - private class CompressedFile - { - [DataMember] - public string Source { get; set; } - - [DataMember] - public string InputSource { get; set; } - - [DataMember] - public string Target { get; set; } - } - } -} - diff --git a/src/Components/WebAssembly/Build/src/Tasks/ResolveBlazorRuntimeDependencies.cs b/src/Components/WebAssembly/Build/src/Tasks/ResolveBlazorRuntimeDependencies.cs deleted file mode 100644 index 4598432a1c..0000000000 --- a/src/Components/WebAssembly/Build/src/Tasks/ResolveBlazorRuntimeDependencies.cs +++ /dev/null @@ -1,203 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Reflection.Metadata; -using System.Reflection.PortableExecutable; -using Microsoft.Build.Framework; -using Microsoft.Build.Utilities; - -namespace Microsoft.AspNetCore.Components.WebAssembly.Build -{ - public class ResolveBlazorRuntimeDependencies : Task - { - [Required] - public string EntryPoint { get; set; } - - [Required] - public ITaskItem[] ApplicationDependencies { get; set; } - - [Required] - public ITaskItem[] WebAssemblyBCLAssemblies { get; set; } - - [Output] - public ITaskItem[] Dependencies { get; set; } - - public override bool Execute() - { - var paths = ResolveRuntimeDependenciesCore(EntryPoint, ApplicationDependencies.Select(c => c.ItemSpec), WebAssemblyBCLAssemblies.Select(c => c.ItemSpec)); - Dependencies = paths.Select(p => new TaskItem(p)).ToArray(); - - return true; - } - - public static IEnumerable<string> ResolveRuntimeDependenciesCore( - string entryPoint, - IEnumerable<string> applicationDependencies, - IEnumerable<string> monoBclAssemblies) - { - var entryAssembly = new AssemblyEntry(entryPoint, GetAssemblyName(entryPoint)); - - var dependencies = CreateAssemblyLookup(applicationDependencies); - - var bcl = CreateAssemblyLookup(monoBclAssemblies); - - var assemblyResolutionContext = new AssemblyResolutionContext( - entryAssembly, - dependencies, - bcl); - - assemblyResolutionContext.ResolveAssemblies(); - - var paths = assemblyResolutionContext.Results.Select(r => r.Path); - return paths.Concat(FindPdbs(paths)); - - static Dictionary<string, AssemblyEntry> CreateAssemblyLookup(IEnumerable<string> assemblyPaths) - { - var dictionary = new Dictionary<string, AssemblyEntry>(StringComparer.Ordinal); - foreach (var path in assemblyPaths) - { - var assemblyName = AssemblyName.GetAssemblyName(path).Name; - if (dictionary.TryGetValue(assemblyName, out var previous)) - { - throw new InvalidOperationException($"Multiple assemblies found with the same assembly name '{assemblyName}':" + - Environment.NewLine + string.Join(Environment.NewLine, previous, path)); - } - dictionary[assemblyName] = new AssemblyEntry(path, assemblyName); - } - - return dictionary; - } - } - - private static string GetAssemblyName(string assemblyPath) - { - return AssemblyName.GetAssemblyName(assemblyPath).Name; - } - - private static IEnumerable<string> FindPdbs(IEnumerable<string> dllPaths) - { - return dllPaths - .Select(path => Path.ChangeExtension(path, "pdb")) - .Where(path => File.Exists(path)); - } - - public class AssemblyResolutionContext - { - public AssemblyResolutionContext( - AssemblyEntry entryAssembly, - Dictionary<string, AssemblyEntry> dependencies, - Dictionary<string, AssemblyEntry> bcl) - { - EntryAssembly = entryAssembly; - Dependencies = dependencies; - Bcl = bcl; - } - - public AssemblyEntry EntryAssembly { get; } - public Dictionary<string, AssemblyEntry> Dependencies { get; } - public Dictionary<string, AssemblyEntry> Bcl { get; } - - public IList<AssemblyEntry> Results { get; } = new List<AssemblyEntry>(); - - internal void ResolveAssemblies() - { - var visitedAssemblies = new HashSet<string>(); - var pendingAssemblies = new Stack<string>(); - pendingAssemblies.Push(EntryAssembly.Name); - ResolveAssembliesCore(); - - void ResolveAssembliesCore() - { - while (pendingAssemblies.Count > 0) - { - var current = pendingAssemblies.Pop(); - if (visitedAssemblies.Add(current)) - { - // Not all references will be resolvable within the Mono BCL. - // Skipping unresolved assemblies here is equivalent to passing "--skip-unresolved true" to the Mono linker. - if (Resolve(current) is AssemblyEntry resolved) - { - Results.Add(resolved); - var references = GetAssemblyReferences(resolved.Path); - foreach (var reference in references) - { - pendingAssemblies.Push(reference); - } - } - } - } - } - - AssemblyEntry? Resolve(string assemblyName) - { - if (EntryAssembly.Name == assemblyName) - { - return EntryAssembly; - } - - // Resolution logic. For right now, we will prefer the mono BCL version of a given - // assembly if there is a candidate assembly and an equivalent mono assembly. - if (Bcl.TryGetValue(assemblyName, out var assembly) || - Dependencies.TryGetValue(assemblyName, out assembly)) - { - return assembly; - } - - return null; - } - - static IReadOnlyList<string> GetAssemblyReferences(string assemblyPath) - { - try - { - using var peReader = new PEReader(File.OpenRead(assemblyPath)); - if (!peReader.HasMetadata) - { - return Array.Empty<string>(); // not a managed assembly - } - - var metadataReader = peReader.GetMetadataReader(); - - var references = new List<string>(); - foreach (var handle in metadataReader.AssemblyReferences) - { - var reference = metadataReader.GetAssemblyReference(handle); - var referenceName = metadataReader.GetString(reference.Name); - - references.Add(referenceName); - } - - return references; - } - catch (BadImageFormatException) - { - // not a PE file, or invalid metadata - } - - return Array.Empty<string>(); // not a managed assembly - } - } - } - - [DebuggerDisplay("{ToString(),nq}")] - public readonly struct AssemblyEntry - { - public AssemblyEntry(string path, string name) - { - Path = path; - Name = name; - } - - public string Path { get; } - public string Name { get; } - - public override string ToString() => Name; - } - } -} diff --git a/src/Components/WebAssembly/Build/src/build/netstandard1.0/Microsoft.AspNetCore.Components.WebAssembly.Build.props b/src/Components/WebAssembly/Build/src/build/netstandard1.0/Microsoft.AspNetCore.Components.WebAssembly.Build.props deleted file mode 100644 index a85c05ce87..0000000000 --- a/src/Components/WebAssembly/Build/src/build/netstandard1.0/Microsoft.AspNetCore.Components.WebAssembly.Build.props +++ /dev/null @@ -1,7 +0,0 @@ -<Project> - <Import Project="$(MSBuildThisFileDirectory)..\..\targets\All.props" /> - - <PropertyGroup> - <ReferencesComponentsWebAssemblyBuild>true</ReferencesComponentsWebAssemblyBuild> - </PropertyGroup> -</Project> diff --git a/src/Components/WebAssembly/Build/src/build/netstandard1.0/Microsoft.AspNetCore.Components.WebAssembly.Build.targets b/src/Components/WebAssembly/Build/src/build/netstandard1.0/Microsoft.AspNetCore.Components.WebAssembly.Build.targets deleted file mode 100644 index 35115b33b3..0000000000 --- a/src/Components/WebAssembly/Build/src/build/netstandard1.0/Microsoft.AspNetCore.Components.WebAssembly.Build.targets +++ /dev/null @@ -1,3 +0,0 @@ -<Project> - <Import Project="$(MSBuildThisFileDirectory)..\..\targets\All.targets" /> -</Project> diff --git a/src/Components/WebAssembly/Build/src/targets/All.props b/src/Components/WebAssembly/Build/src/targets/All.props deleted file mode 100644 index 8315d3cb40..0000000000 --- a/src/Components/WebAssembly/Build/src/targets/All.props +++ /dev/null @@ -1,16 +0,0 @@ -<Project> - <Import Project="Blazor.MonoRuntime.props" /> - - <Import Project="StaticWebAssets.props" /> - - <PropertyGroup> - - <!-- Assets for a Blazor app are exposed on the root folder by default. --> - <StaticWebAssetBasePath>/</StaticWebAssetBasePath> - - <!-- When using IISExpress with a standalone app, there's no point restarting IISExpress after build. It slows things unnecessarily and breaks in-flight HTTP requests. --> - <NoRestartServerOnBuild>true</NoRestartServerOnBuild> - - <BlazorEnableCompression Condition="'$(BlazorEnableCompression)' == ''">true</BlazorEnableCompression> - </PropertyGroup> -</Project> diff --git a/src/Components/WebAssembly/Build/src/targets/All.targets b/src/Components/WebAssembly/Build/src/targets/All.targets deleted file mode 100644 index 5966cec27f..0000000000 --- a/src/Components/WebAssembly/Build/src/targets/All.targets +++ /dev/null @@ -1,21 +0,0 @@ -<Project> - <PropertyGroup> - <_BlazorToolsDir Condition="'$(_BlazorToolsDir)' == ''">$(MSBuildThisFileDirectory)..\tools\</_BlazorToolsDir> - <_BlazorTasksTFM Condition=" '$(MSBuildRuntimeType)' == 'Core'">netcoreapp</_BlazorTasksTFM> - <_BlazorTasksTFM Condition=" '$(_BlazorTasksTFM)' == ''">netfx</_BlazorTasksTFM> - <_BlazorTasksPath>$(_BlazorToolsDir)$(_BlazorTasksTFM)\Microsoft.AspNetCore.Components.WebAssembly.Build.Tasks.dll</_BlazorTasksPath> - - <!-- The Blazor build code can only find your referenced assemblies if they are in the output directory --> - <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies> - - <!-- By default, enable debugging for debug builds. --> - <BlazorEnableDebugging Condition="'$(Configuration)' == 'Debug' AND '$(BlazorEnableDebugging)' == ''">true</BlazorEnableDebugging> - </PropertyGroup> - - <Import Project="Blazor.MonoRuntime.targets" /> - <Import Project="Publish.targets" /> - <Import Project="StaticWebAssets.targets" /> - <Import Project="ServiceWorkerAssetsManifest.targets" /> - <Import Project="Compression.targets" Condition="'$(BlazorEnableCompression)' == 'true'" /> - -</Project> diff --git a/src/Components/WebAssembly/Build/src/targets/Blazor.MonoRuntime.props b/src/Components/WebAssembly/Build/src/targets/Blazor.MonoRuntime.props deleted file mode 100644 index 453deddacd..0000000000 --- a/src/Components/WebAssembly/Build/src/targets/Blazor.MonoRuntime.props +++ /dev/null @@ -1,20 +0,0 @@ -<Project> - - <PropertyGroup> - <BlazorWebAssemblyI18NAssemblies>none</BlazorWebAssemblyI18NAssemblies> <!-- See Mono linker docs - allows comma-separated values from: none,all,cjk,mideast,other,rare,west --> - <AdditionalMonoLinkerOptions>--disable-opt unreachablebodies --verbose --strip-security true --exclude-feature com -v false -c link -u link -b true</AdditionalMonoLinkerOptions> - - <_BlazorJsPath Condition="'$(_BlazorJsPath)' == ''">$(MSBuildThisFileDirectory)..\tools\blazor\blazor.webassembly.js</_BlazorJsPath> - <_BaseBlazorRuntimeOutputPath>_framework\</_BaseBlazorRuntimeOutputPath> - <_BlazorRuntimeBinOutputPath>$(_BaseBlazorRuntimeOutputPath)_bin\</_BlazorRuntimeBinOutputPath> - <_BlazorRuntimeWasmOutputPath>$(_BaseBlazorRuntimeOutputPath)wasm\</_BlazorRuntimeWasmOutputPath> - <_BlazorBuiltInBclLinkerDescriptor>$(MSBuildThisFileDirectory)BuiltInBclLinkerDescriptor.xml</_BlazorBuiltInBclLinkerDescriptor> - <_BlazorCollationLinkerDescriptor>$(MSBuildThisFileDirectory)CollationLinkerDescriptor.xml</_BlazorCollationLinkerDescriptor> - <_BlazorBootJsonName>blazor.boot.json</_BlazorBootJsonName> - </PropertyGroup> - - <ItemGroup> - <BlazorLinkerDescriptor Include="$(_BlazorBuiltInBclLinkerDescriptor)" /> - </ItemGroup> - -</Project> diff --git a/src/Components/WebAssembly/Build/src/targets/Blazor.MonoRuntime.targets b/src/Components/WebAssembly/Build/src/targets/Blazor.MonoRuntime.targets deleted file mode 100644 index c143445685..0000000000 --- a/src/Components/WebAssembly/Build/src/targets/Blazor.MonoRuntime.targets +++ /dev/null @@ -1,489 +0,0 @@ -<Project> - <UsingTask TaskName="BlazorGetFileHash" AssemblyFile="$(_BlazorTasksPath)" /> - - <PropertyGroup> - <BlazorWebAssemblyEnableLinking Condition="'$(BlazorWebAssemblyEnableLinking)' == '' AND '$(Configuration)' != 'Debug'">true</BlazorWebAssemblyEnableLinking> - <BlazorWebAssemblyEnableLinking Condition="'$(BlazorWebAssemblyEnableLinking)' == ''">false</BlazorWebAssemblyEnableLinking> - </PropertyGroup> - - <Target - Name="_PrepareBlazorOutputs" - DependsOnTargets="_ResolveBlazorInputs;_ResolveBlazorOutputs;_GenerateBlazorBootJson;_GenerateBlazorBootJsonIntegrity"> - </Target> - - <Target Name="_ResolveBlazorInputs" DependsOnTargets="ResolveReferences;ResolveRuntimePackAssets"> - <Error Text="BlazorLinkOnBuild has been renamed to BlazorWebAssemblyEnableLinking. Please update your project files to use the new property." - Condition="'$(BlazorLinkOnBuild)' != ''" /> - - <PropertyGroup> - <!-- /obj/<<configuration>>/<<targetframework>>/blazor --> - <_BlazorIntermediateOutputPath>$(IntermediateOutputPath)blazor\</_BlazorIntermediateOutputPath> - - <!-- /obj/<<configuration>>/<<targetframework>>/blazor/linker.descriptor.xml --> - <_GeneratedBlazorLinkerDescriptor>$(_BlazorIntermediateOutputPath)linker.descriptor.xml</_GeneratedBlazorLinkerDescriptor> - - <_TypeGranularityLinkerDescriptor>$(_BlazorIntermediateOutputPath)linker.typegranularityconfig.xml</_TypeGranularityLinkerDescriptor> - - <!-- /obj/<<configuration>>/<<targetframework>>/blazor/linker/ --> - <_BlazorIntermediateLinkerOutputPath>$(_BlazorIntermediateOutputPath)linker/</_BlazorIntermediateLinkerOutputPath> - - <!-- /obj/<<configuration>>/<<targetframework>>/blazor/blazor.boot.json --> - <_BlazorBootJsonIntermediateOutputPath>$(_BlazorIntermediateOutputPath)$(_BlazorBootJsonName)</_BlazorBootJsonIntermediateOutputPath> - - <_BlazorLinkerOutputCache>$(_BlazorIntermediateOutputPath)linker.output</_BlazorLinkerOutputCache> - - <_BlazorApplicationAssembliesCacheFile>$(_BlazorIntermediateOutputPath)unlinked.output</_BlazorApplicationAssembliesCacheFile> - </PropertyGroup> - - <!-- - When running from Desktop MSBuild, DOTNET_HOST_PATH is not set. - In this case, explicitly specify the path to the dotnet host. - --> - <PropertyGroup Condition=" '$(DOTNET_HOST_PATH)' == '' "> - <_DotNetHostDirectory>$(NetCoreRoot)</_DotNetHostDirectory> - <_DotNetHostFileName>dotnet</_DotNetHostFileName> - <_DotNetHostFileName Condition=" '$(OS)' == 'Windows_NT' ">dotnet.exe</_DotNetHostFileName> - </PropertyGroup> - - <ItemGroup> - <_WebAssemblyBCLFolder Include=" - $(ComponentsWebAssemblyBaseClassLibraryPath); - $(ComponentsWebAssemblyBaseClassLibraryFacadesPath); - $(ComponentsWebAssemblyFrameworkPath)" /> - - <_WebAssemblyBCLAssembly Include="%(_WebAssemblyBCLFolder.Identity)*.dll" /> - - <_BlazorConfigFile Include="wwwroot\appsettings*.json" /> - </ItemGroup> - - <!-- - Calculate the assemblies that act as inputs to calculate assembly closure. Based on _ComputeAssembliesToPostprocessOnPublish which is used as input to SDK's linker - https://github.com/dotnet/sdk/blob/d597e7b09d7657ba4e326d6734e14fcbf8473564/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Publish.targets#L864-L873 - --> - <ItemGroup> - <!-- Assemblies from packages --> - <_BlazorManagedRuntimeAssembly Include="@(RuntimeCopyLocalItems)" /> - - <!-- Assemblies from other references --> - <_BlazorUserRuntimeAssembly Include="@(ReferencePath->WithMetadataValue('CopyLocal', 'true'))" /> - <_BlazorUserRuntimeAssembly Include="@(ReferenceDependencyPaths->WithMetadataValue('CopyLocal', 'true'))" /> - - <_BlazorManagedRuntimeAssembly Include="@(_BlazorUserRuntimeAssembly)" /> - <_BlazorManagedRuntimeAssembly Include="@(IntermediateAssembly)" /> - </ItemGroup> - - <MakeDir Directories="$(_BlazorIntermediateOutputPath)" /> - </Target> - - <UsingTask TaskName="BlazorWriteSatelliteAssemblyFile" AssemblyFile="$(_BlazorTasksPath)" /> - <UsingTask TaskName="BlazorReadSatelliteAssemblyFile" AssemblyFile="$(_BlazorTasksPath)" /> - - <Target Name="_ResolveBlazorOutputs" DependsOnTargets="_ResolveBlazorOutputsWhenLinked;_ResolveBlazorOutputsWhenNotLinked"> - <!-- - These are the items calculated as the closure of the runtime assemblies, either by calling the linker - or by calling our custom ResolveBlazorRuntimeDependencies task if the linker was disabled. Other than - satellite assemblies, this should include all assemblies needed to run the application. - --> - <ItemGroup> - <_BlazorJSFile Include="$(_BlazorJSPath)" /> - <_BlazorJSFile Include="$(_BlazorJSMapPath)" Condition="Exists('$(_BlazorJSMapPath)')" /> - - <_DotNetWasmRuntimeFile Include="$(ComponentsWebAssemblyRuntimePath)*"/> - <_DotNetWasmRuntimeFile - Remove="%(Identity)" - Condition="'$(BlazorEnableTimeZoneSupport)' == 'false' AND '%(FileName)%(Extension)' == 'dotnet.timezones.dat'" /> - - <!-- - ReferenceCopyLocalPaths includes all files that are part of the build out with CopyLocalLockFileAssemblies on. - Remove assemblies that are inputs to calculating the assembly closure. Instead use the resolved outputs, since it is the minimal set. - - ReferenceCopyLocalPaths also includes satellite assemblies from referenced projects but are inexpicably missing - any metadata that might allow them to be differentiated. We'll explicitly add those - to _BlazorOutputWithTargetPath so that satellite assemblies from packages, the current project and referenced project - are all treated the same. - --> - <_BlazorCopyLocalPaths Include="@(ReferenceCopyLocalPaths)" - Exclude="@(_BlazorManagedRuntimeAssembly);@(ReferenceSatellitePaths)" - Condition="'%(Extension)' == '.dll'" /> - - <_BlazorCopyLocalPaths Include="@(IntermediateSatelliteAssembliesWithTargetPath)"> - <DestinationSubDirectory>%(IntermediateSatelliteAssembliesWithTargetPath.Culture)\</DestinationSubDirectory> - </_BlazorCopyLocalPaths> - - <_BlazorOutputWithTargetPath Include="@(_BlazorCopyLocalPaths)"> - <!-- This group is for satellite assemblies. We set the resource name to include a path, e.g. "fr\\SomeAssembly.resources.dll" --> - <BootManifestResourceType Condition="'%(_BlazorCopyLocalPaths.Extension)' == '.pdb'">pdb</BootManifestResourceType> - <BootManifestResourceType Condition="'%(_BlazorCopyLocalPaths.Culture)' == '' AND '%(_BlazorCopyLocalPaths.Extension)' == '.dll'">assembly</BootManifestResourceType> - <BootManifestResourceType Condition="'%(_BlazorCopyLocalPaths.Culture)' != '' AND '%(_BlazorCopyLocalPaths.Extension)' == '.dll'">satellite</BootManifestResourceType> - <BootManifestResourceName>%(_BlazorCopyLocalPaths.DestinationSubDirectory)%(FileName)%(Extension)</BootManifestResourceName> - <TargetOutputPath>$(_BlazorRuntimeBinOutputPath)%(_BlazorCopyLocalPaths.DestinationSubDirectory)%(FileName)%(Extension)</TargetOutputPath> - </_BlazorOutputWithTargetPath> - - <_BlazorOutputWithTargetPath Include="@(ReferenceSatellitePaths)"> - <Culture>$([System.String]::Copy('%(ReferenceSatellitePaths.DestinationSubDirectory)').Trim('\').Trim('/'))</Culture> - <BootManifestResourceType>satellite</BootManifestResourceType> - <BootManifestResourceName>%(ReferenceSatellitePaths.DestinationSubDirectory)%(FileName)%(Extension)</BootManifestResourceName> - <TargetOutputPath>$(_BlazorRuntimeBinOutputPath)%(ReferenceSatellitePaths.DestinationSubDirectory)%(FileName)%(Extension)</TargetOutputPath> - </_BlazorOutputWithTargetPath> - - <_BlazorOutputWithTargetPath Include="@(_BlazorResolvedAssembly)"> - <BootManifestResourceType Condition="'%(Extension)' == '.dll'">assembly</BootManifestResourceType> - <BootManifestResourceType Condition="'%(Extension)' == '.pdb'">pdb</BootManifestResourceType> - <BootManifestResourceType Condition="@(BlazorWebAssemblyLazyLoad->AnyHaveMetadataValue('Identity', '%(Filename)')) != ''">dynamicAssembly</BootManifestResourceType> - <BootManifestResourceName>%(FileName)%(Extension)</BootManifestResourceName> - <TargetOutputPath>$(_BlazorRuntimeBinOutputPath)%(FileName)%(Extension)</TargetOutputPath> - </_BlazorOutputWithTargetPath> - - <_BlazorOutputWithTargetPath Include="@(_DotNetWasmRuntimeFile)"> - <TargetOutputPath>$(_BlazorRuntimeWasmOutputPath)%(FileName)%(Extension)</TargetOutputPath> - <BootManifestResourceType>runtime</BootManifestResourceType> - <BootManifestResourceName>%(FileName)%(Extension)</BootManifestResourceName> - </_BlazorOutputWithTargetPath> - - <_BlazorOutputWithTargetPath Include="@(_BlazorJSFile)"> - <TargetOutputPath>$(_BaseBlazorRuntimeOutputPath)%(FileName)%(Extension)</TargetOutputPath> - </_BlazorOutputWithTargetPath> - - <_BlazorWriteSatelliteAssembly Include="@(_BlazorOutputWithTargetPath->WithMetadataValue('BootManifestResourceType', 'satellite'))" /> - </ItemGroup> - - <!-- - When building with BuildingProject=false, satellite assemblies do not get resolved (the ones for the current project and the one for - referenced project). BuildingProject=false is typically set for referenced projects when building inside VisualStudio. - To workaround this, we'll stash metadata during a regular build, and rehydrate from it when BuildingProject=false. - --> - - <PropertyGroup> - <_BlazorSatelliteAssemblyStashFile>$(_BlazorIntermediateOutputPath)blazor.satelliteasm.props</_BlazorSatelliteAssemblyStashFile> - </PropertyGroup> - - <BlazorWriteSatelliteAssemblyFile - SatelliteAssembly="@(_BlazorWriteSatelliteAssembly)" - WriteFile="$(_BlazorSatelliteAssemblyStashFile)" - Condition="'$(BuildingProject)' == 'true' AND '@(_BlazorWriteSatelliteAssembly->Count())' != '0'" /> - - <Delete - Files="$(_BlazorSatelliteAssemblyStashFile)" - Condition="'$(BuildingProject)' == 'true' AND '@(_BlazorWriteSatelliteAssembly->Count())' == '0' and EXISTS('$(_BlazorSatelliteAssemblyStashFile)')" /> - - <BlazorReadSatelliteAssemblyFile - ReadFile="$(_BlazorSatelliteAssemblyStashFile)" - Condition="'$(BuildingProject)' != 'true' AND EXISTS('$(_BlazorSatelliteAssemblyStashFile)')"> - <Output TaskParameter="SatelliteAssembly" ItemName="_BlazorReadSatelliteAssembly" /> - </BlazorReadSatelliteAssemblyFile> - - <ItemGroup> - <FileWrites Include="$(_BlazorSatelliteAssemblyStashFile)" Condition="Exists('$(_BlazorSatelliteAssemblyStashFile)')" /> - </ItemGroup> - - <ItemGroup Condition="'@(_BlazorReadSatelliteAssembly->Count())' != '0'"> - <!-- We've imported a previously stashed file. Let's turn in to a _BlazorOutputWithTargetPath --> - <_BlazorOutputWithTargetPath Include="@(_BlazorReadSatelliteAssembly)"> - <BootManifestResourceType>satellite</BootManifestResourceType> - <BootManifestResourceName>%(_BlazorReadSatelliteAssembly.DestinationSubDirectory)%(FileName)%(Extension)</BootManifestResourceName> - <TargetOutputPath>$(_BlazorRuntimeBinOutputPath)%(_BlazorReadSatelliteAssembly.DestinationSubDirectory)%(FileName)%(Extension)</TargetOutputPath> - </_BlazorOutputWithTargetPath> - </ItemGroup> - - <!-- - We need to know at build time (not publish time) whether or not to include pdbs in the - blazor.boot.json file, so this is controlled by the BlazorEnableDebugging flag, whose - default value is determined by the build configuration. - --> - <ItemGroup Condition="'$(BlazorEnableDebugging)' != 'true'"> - <_BlazorOutputWithTargetPath Remove="@(_BlazorOutputWithTargetPath)" Condition="'%(Extension)' == '.pdb'" /> - </ItemGroup> - - <ItemGroup> - <_ExistingBlazorOutputWithTargetPath Include="@(_BlazorOutputWithTargetPath)" Condition="Exists('%(FullPath)')" /> - </ItemGroup> - - <BlazorGetFileHash Files="@(_ExistingBlazorOutputWithTargetPath)" Algorithm="SHA256" HashEncoding="base64"> - <Output TaskParameter="Items" ItemName="_BlazorOutputWithHash" /> - </BlazorGetFileHash> - - <ItemGroup> - <_BlazorOutputWithIntegrity Include="@(_BlazorOutputWithHash)"> - <Integrity>%(_BlazorOutputWithHash.FileHash)</Integrity> - <IntegrityFile>$(IntermediateOutputPath)integrity\$([System.String]::Copy('%(FileHash)').Replace('/','-').Replace('+','_')).hash</IntegrityFile> - </_BlazorOutputWithIntegrity> - - <_BlazorOutputWithTargetPath Remove="@(_BlazorOutputWithIntegrity)" /> - <_BlazorOutputWithTargetPath Include="@(_BlazorOutputWithIntegrity)" RemoveMetadata="FileHash;FileHashAlgorithm" /> - - <MakeDir Directories="$(IntermediateOutputPath)integrity" /> - </ItemGroup> - - <WriteLinesToFile Lines="%(_BlazorOutputWithIntegrity.Integrity)" File="%(_BlazorOutputWithIntegrity.IntegrityFile)" WriteOnlyWhenDifferent="true" Overwrite="true" /> - - <ItemGroup> - <FileWrites Include="%(_BlazorOutputWithIntegrity.IntegrityFile)" /> - </ItemGroup> - - </Target> - - <!-- - Linker enabled part of the pipeline: - - * If there are no descriptors defined, generate a new linker descriptor. - * Invoke the linker and write linked files to a well-known directory. - * Collect the outputs of the linker. - --> - - <Target - Name="_ResolveBlazorOutputsWhenLinked" - Condition="'$(BlazorWebAssemblyEnableLinking)' == 'true'" - DependsOnTargets="_PrepareBlazorLinkerInputs;_GenerateBlazorLinkerDescriptor;_GenerateTypeGranularLinkerDescriptor;_LinkBlazorApplication"> - - <!-- _BlazorLinkerOutputCache records files linked during the last incremental build of the target. Read the contents and assign linked files to be copied to the output. --> - <ReadLinesFromFile File="$(_BlazorLinkerOutputCache)"> - <Output TaskParameter="Lines" ItemName="_BlazorResolvedAssembly"/> - </ReadLinesFromFile> - </Target> - - <Target Name="_PrepareBlazorLinkerInputs"> - <ItemGroup> - <_BlazorRuntimeCopyLocalItems Include="@(RuntimeCopyLocalItems)" /> - - <!-- - Any assembly from a package reference that starts with System. file name is allowed to be linked. - Assemblies from Microsoft.AspNetCore and Microsoft.Extensions, are also linked but with TypeGranularity. - --> - <_BlazorRuntimeCopyLocalItems IsLinkable="true" Condition="$([System.String]::Copy('%(Filename)').StartsWith('System.'))" /> - <_BlazorRuntimeCopyLocalItems IsLinkable="true" TypeGranularity="true" Condition="$([System.String]::Copy('%(Filename)').StartsWith('Microsoft.AspNetCore.'))" /> - <_BlazorRuntimeCopyLocalItems IsLinkable="true" TypeGranularity="true" Condition="$([System.String]::Copy('%(Filename)').StartsWith('Microsoft.Extensions.'))" /> - - <_BlazorAssemblyToLink Include="@(_WebAssemblyBCLAssembly)" /> - <_BlazorAssemblyToLink Include="@(_BlazorRuntimeCopyLocalItems)" Condition="'%(_BlazorRuntimeCopyLocalItems.IsLinkable)' == 'true'" /> - - <_BlazorLinkerRoot Include="@(IntermediateAssembly)" /> - <_BlazorLinkerRoot Include="@(_BlazorUserRuntimeAssembly)" /> - <_BlazorLinkerRoot Include="@(_BlazorRuntimeCopyLocalItems)" Condition="'%(_BlazorRuntimeCopyLocalItems.IsLinkable)' != 'true'" /> - </ItemGroup> - - <!-- When specifically requested, include the linker substitutions file that strips out collation information.--> - <PropertyGroup Condition="'$(BlazorWebAssemblyPreserveCollationData)' == 'false'"> - <AdditionalMonoLinkerOptions>$(AdditionalMonoLinkerOptions) --substitutions "$(_BlazorCollationLinkerDescriptor)"</AdditionalMonoLinkerOptions> - </PropertyGroup> - </Target> - - <UsingTask TaskName="BlazorCreateRootDescriptorFile" AssemblyFile="$(_BlazorTasksPath)" /> - <Target Name="_GenerateBlazorLinkerDescriptor" - Inputs="@(IntermediateAssembly)" - Outputs="$(_GeneratedBlazorLinkerDescriptor)"> - - <!-- Generate linker descriptors if the project doesn't explicitly provide one. --> - - <BlazorCreateRootDescriptorFile - AssemblyNames="@(IntermediateAssembly->'%(Filename)')" - RootDescriptorFilePath="$(_GeneratedBlazorLinkerDescriptor)" /> - - <ItemGroup> - <FileWrites Include="$(_GeneratedBlazorLinkerDescriptor)" /> - <BlazorLinkerDescriptor Include="$(_GeneratedBlazorLinkerDescriptor)" /> - </ItemGroup> - </Target> - - <UsingTask TaskName="GenerateTypeGranularityLinkingConfig" AssemblyFile="$(_BlazorTasksPath)" /> - <Target Name="_GenerateTypeGranularLinkerDescriptor" - Inputs="@(_BlazorAssemblyToLink->WithMetadataValue('TypeGranularity', 'true'))" - Outputs="$(_TypeGranularityLinkerDescriptor)"> - - <GenerateTypeGranularityLinkingConfig - Assemblies="@(_BlazorAssemblyToLink->WithMetadataValue('TypeGranularity', 'true'))" - OutputPath="$(_TypeGranularityLinkerDescriptor)" /> - - <ItemGroup> - <BlazorLinkerDescriptor Include="$(_TypeGranularityLinkerDescriptor)" /> - <FileWrites Include="$(_TypeGranularityLinkerDescriptor)" /> - </ItemGroup> - </Target> - - <!-- - Note that the VS-specific condition below is a workaround for https://github.com/dotnet/aspnetcore/issues/19822 - For more details, see https://github.com/dotnet/aspnetcore/issues/20413 - --> - <UsingTask TaskName="BlazorILLink" AssemblyFile="$(_BlazorTasksPath)" /> - <Target - Name="_LinkBlazorApplication" - Inputs="$(ProjectAssetsFile); - @(_BlazorManagedRuntimeAssembly); - @(BlazorLinkerDescriptor); - $(MSBuildAllProjects)" - Outputs="$(_BlazorLinkerOutputCache)" - Condition="'$(BuildingInsideVisualStudio)' != 'true' OR '$(DeployOnBuild)' != 'true'"> - - <PropertyGroup> - <_BlazorLinkerAdditionalOptions>-l $(BlazorWebAssemblyI18NAssemblies) $(AdditionalMonoLinkerOptions)</_BlazorLinkerAdditionalOptions> - </PropertyGroup> - - <ItemGroup> - <_OldLinkedFile Include="$(_BlazorIntermediateLinkerOutputPath)*.dll" /> - <_OldLinkedFile Include="$(_BlazorIntermediateLinkerOutputPath)*.pdb" /> - </ItemGroup> - - <Delete Files="@(_OldLinkedFile)" /> - - <BlazorILLink - ILLinkPath="$(ComponentsWebAssemblyLinkerPath)" - AssemblyPaths="@(_BlazorAssemblyToLink)" - RootAssemblyNames="@(_BlazorLinkerRoot)" - RootDescriptorFiles="@(BlazorLinkerDescriptor)" - OutputDirectory="$(_BlazorIntermediateLinkerOutputPath)" - ExtraArgs="$(_BlazorLinkerAdditionalOptions)" - ToolExe="$(_DotNetHostFileName)" - ToolPath="$(_DotNetHostDirectory)" /> - - <ItemGroup> - <_LinkerResult Include="$(_BlazorIntermediateLinkerOutputPath)*.dll" /> - <_LinkerResult Include="$(_BlazorIntermediateLinkerOutputPath)*.pdb" /> - </ItemGroup> - - <WriteLinesToFile File="$(_BlazorLinkerOutputCache)" Lines="@(_LinkerResult)" Overwrite="true" /> - </Target> - - <UsingTask TaskName="ResolveBlazorRuntimeDependencies" AssemblyFile="$(_BlazorTasksPath)" /> - <Target - Name="_ResolveBlazorOutputsWhenNotLinked" - DependsOnTargets="_ResolveBlazorRuntimeDependencies" - Condition="'$(BlazorWebAssemblyEnableLinking)' != 'true'"> - - <ReadLinesFromFile File="$(_BlazorApplicationAssembliesCacheFile)" Condition="'@(_BlazorResolvedAssembly->Count())' == '0'"> - <Output TaskParameter="Lines" ItemName="_BlazorResolvedAssembly"/> - </ReadLinesFromFile> - - <ItemGroup> - <!-- - Workaround for https://github.com/dotnet/aspnetcore/issues/19926. Add _BlazorResolvedAssembly to FileWrites so that these files - do not get removed during an incremental build. Note that we add these files here as opposed to _ResolveBlazorRuntimeDependencies - since the task that calculates these items in _ResolveBlazorRuntimeDependencies does not execute in incremental builds. - --> - <FileWrites Include="$(_BlazorResolvedAssembly)"/> - </ItemGroup> - </Target> - - <Target - Name="_ResolveBlazorRuntimeDependencies" - Inputs="$(ProjectAssetsFile); - @(IntermediateAssembly); - @(_BlazorManagedRuntimeAssembly)" - Outputs="$(_BlazorApplicationAssembliesCacheFile)"> - - <!-- - At this point we have decided not to run the linker and instead to just copy the assemblies - from the BCL referenced by the app the nuget package into the _framework/_bin folder. - The only thing we need to do here is collect the list of items that will go into _framework/_bin. - --> - <ResolveBlazorRuntimeDependencies - EntryPoint="@(IntermediateAssembly)" - ApplicationDependencies="@(_BlazorManagedRuntimeAssembly)" - WebAssemblyBCLAssemblies="@(_WebAssemblyBCLAssembly)"> - - <Output TaskParameter="Dependencies" ItemName="_BlazorResolvedAssemblyUnlinked" /> - </ResolveBlazorRuntimeDependencies> - - <ItemGroup Condition="'$(BlazorWebAssemblyI18NAssemblies)' != 'none'"> - <!-- - Unless the user has asked for no-assemblies, copy all I18N assemblies to the build output. - We do not want to decipher the linker's format for passing in I18N options in our build targets - --> - <_BlazorResolvedAssemblyUnlinked Include="$(ComponentsWebAssemblyBaseClassLibraryPath)I18N*.dll" /> - </ItemGroup> - - <!-- - Workaround for https://github.com/dotnet/aspnetcore/issues/19926. Using the files from their initial locations - as-is causes RazorSDK to remove files from a hosted app's publish directory. This is because files being removed - are looked up by their path. We'll copy files to an intermediate location to avoid the removal code. - --> - <Copy - SourceFiles="@(_BlazorResolvedAssemblyUnlinked)" - DestinationFolder="$(_BlazorIntermediateOutputPath)unlinked"> - <Output TaskParameter="CopiedFiles" ItemName="_BlazorResolvedAssembly" /> - </Copy> - - <WriteLinesToFile File="$(_BlazorApplicationAssembliesCacheFile)" Lines="@(_BlazorResolvedAssembly)" Overwrite="true" /> - - <ItemGroup> - <FileWrites Include="$(_BlazorApplicationAssembliesCacheFile)" /> - </ItemGroup> - </Target> - - <Target Name="_GenerateBlazorBootJsonInputHash"> - <ItemGroup> - <_BlazorBootJsonHashInput Include="@(IntermediateAssembly)" /> - <_BlazorBootJsonHashInput Include="@(_BlazorOutputWithTargetPath)" /> - <_BlazorBootJsonHashInput Include="@(_BlazorConfigFile)" /> - </ItemGroup> - - <Hash ItemsToHash="@(_BlazorBootJsonHashInput)"> - <Output TaskParameter="HashResult" PropertyName="_BlazorBootJsonInputHash" /> - </Hash> - - <PropertyGroup> - <_BlazorBootJsonInputHashFile>$(_BlazorIntermediateOutputPath)boot.json.input</_BlazorBootJsonInputHashFile> - </PropertyGroup> - - <WriteLinesToFile - Lines="$(_BlazorBootJsonInputHash)" - File="$(_BlazorBootJsonInputHashFile)" - Overwrite="True" - WriteOnlyWhenDifferent="True" /> - - </Target> - - <UsingTask TaskName="GenerateBlazorBootJson" AssemblyFile="$(_BlazorTasksPath)" /> - - <Target - Name="_GenerateBlazorBootJson" - DependsOnTargets="_GenerateBlazorBootJsonInputHash" - Inputs="$(MSBuildAllProjects);@(_BlazorOutputWithTargetPath);$(_BlazorBootJsonInputHashFile)" - Outputs="$(_BlazorBootJsonIntermediateOutputPath)"> - - <PropertyGroup> - <_IsDebugBuild>false</_IsDebugBuild> - <_IsDebugBuild Condition="'$(Configuration)' == 'Debug'">true</_IsDebugBuild> - <BlazorCacheBootResources Condition="'$(BlazorCacheBootResources)' == ''">true</BlazorCacheBootResources> - </PropertyGroup> - - <ItemGroup> - <_BlazorBootResource Include="@(_BlazorOutputWithTargetPath->HasMetadata('BootManifestResourceType'))" /> - </ItemGroup> - - <GenerateBlazorBootJson - AssemblyPath="@(IntermediateAssembly)" - Resources="@(_BlazorBootResource)" - DebugBuild="$(_IsDebugBuild)" - LinkerEnabled="$(BlazorWebAssemblyEnableLinking)" - CacheBootResources="$(BlazorCacheBootResources)" - OutputPath="$(_BlazorBootJsonIntermediateOutputPath)" - ConfigurationFiles="@(_BlazorConfigFile)" /> - - </Target> - - <Target Name="_GenerateBlazorBootJsonIntegrity"> - - <GetFileHash Files="$(_BlazorBootJsonIntermediateOutputPath)" Algorithm="SHA256" HashEncoding="base64"> - <Output TaskParameter="Items" ItemName="_BlazorBootJsonWithHash" /> - </GetFileHash> - - <ItemGroup> - - <_BlazorBootJsonWithIntegrity Include="@(_BlazorBootJsonWithHash)"> - <Integrity>%(FileHash)</Integrity> - <IntegrityFile>$(IntermediateOutputPath)integrity\$([System.String]::Copy('%(FileHash)').Replace('/','-').Replace('+','_')).hash</IntegrityFile> - </_BlazorBootJsonWithIntegrity> - - <_BlazorOutputWithTargetPath Include="@(_BlazorBootJsonWithIntegrity)" RemoveMetadata="FileHash;FileHashAlgorithm"> - <TargetOutputPath>$(_BaseBlazorRuntimeOutputPath)$(_BlazorBootJsonName)</TargetOutputPath> - </_BlazorOutputWithTargetPath> - - <FileWrites Include="$(_BlazorBootJsonIntermediateOutputPath)" /> - <FileWrites Include="%(_BlazorBootJsonWithIntegrity.IntegrityFile)" /> - - </ItemGroup> - - <WriteLinesToFile Lines="%(_BlazorBootJsonWithIntegrity.Integrity)" File="%(_BlazorBootJsonWithIntegrity.IntegrityFile)" WriteOnlyWhenDifferent="true" Overwrite="true" /> - - </Target> - -</Project> diff --git a/src/Components/WebAssembly/Build/src/targets/BuiltInBclLinkerDescriptor.xml b/src/Components/WebAssembly/Build/src/targets/BuiltInBclLinkerDescriptor.xml deleted file mode 100644 index 6fb65f5a14..0000000000 --- a/src/Components/WebAssembly/Build/src/targets/BuiltInBclLinkerDescriptor.xml +++ /dev/null @@ -1,32 +0,0 @@ -<linker> - - <!-- This file specifies which parts of the BCL or Blazor packages must not be stripped - by the IL linker even if they are not referenced by user code. The file format is - described at https://github.com/mono/linker/blob/master/src/linker/README.md#syntax-of-xml-descriptor --> - - <assembly fullname="mscorlib"> - <!-- Preserve all methods on WasmRuntime, because these are called by JS-side code - to implement timers. Fixes https://github.com/dotnet/blazor/issues/239 --> - <type fullname="System.Threading.WasmRuntime" /> - </assembly> - - <assembly fullname="System"> - <!-- Without this, [Required(typeof(bool), "true", "true", ErrorMessage = "...")] fails --> - <type fullname="System.ComponentModel.BooleanConverter" /> - - <!-- TypeConverters are only used through reflection. These are two built-in TypeConverters that are useful. --> - <type fullname="System.ComponentModel.GuidConverter" /> - <type fullname="System.ComponentModel.TimeSpanConverter" /> - </assembly> - - <assembly fullname="System.Text.Json"> - <!-- S.T.J. uses Activator.CreateInstance to instantiate converters, so we need to preserve default constructors. - For safety, do this for all converter types, even though most of them are preserved anyway due to being referenced - statically. It's only JsonStringEnumConverter that currently isn't referenced statically. - The following is a workaround for https://github.com/dotnet/aspnetcore/issues/19086. - The underlying issue is reported in the runtime repo at https://github.com/dotnet/runtime/issues/34449 --> - <type fullname="System.Text.Json.Serialization.*Converter"> - <method signature="System.Void .ctor()" /> - </type> - </assembly> -</linker> diff --git a/src/Components/WebAssembly/Build/src/targets/CollationLinkerDescriptor.xml b/src/Components/WebAssembly/Build/src/targets/CollationLinkerDescriptor.xml deleted file mode 100644 index 693bdb6768..0000000000 --- a/src/Components/WebAssembly/Build/src/targets/CollationLinkerDescriptor.xml +++ /dev/null @@ -1,21 +0,0 @@ -<linker> - <!-- This file disables exclusions that remove collation data --> - - <assembly fullname="mscorlib"> - <resource name="collation.cjkCHS.bin" action="remove"/> - <resource name="collation.cjkCHT.bin" action="remove"/> - <resource name="collation.cjkJA.bin" action="remove"/> - <resource name="collation.cjkKO.bin" action="remove"/> - <resource name="collation.cjkKOlv2.bin" action="remove"/> - <resource name="collation.core.bin" action="remove"/> - <resource name="collation.tailoring.bin" action="remove"/> - - <type fullname="System.Globalization.CompareInfo"> - <method signature="System.Boolean get_IgnoreCaseNotSupported()" body="stub" value="true"/> - </type> - - <type fullname="System.Globalization.CompareInfo"> - <method signature="System.Boolean get_UseManagedCollation()" body="stub" value="false"/> - </type> - </assembly> -</linker>
\ No newline at end of file diff --git a/src/Components/WebAssembly/Build/src/targets/Compression.targets b/src/Components/WebAssembly/Build/src/targets/Compression.targets deleted file mode 100644 index 348d62481a..0000000000 --- a/src/Components/WebAssembly/Build/src/targets/Compression.targets +++ /dev/null @@ -1,108 +0,0 @@ -<Project> - <PropertyGroup> - - <_BlazorBrotliPath>$(_BlazorToolsDir)compression\blazor-brotli.dll</_BlazorBrotliPath> - <ResolveCurrentProjectStaticWebAssetsDependsOn> - $(ResolveCurrentProjectStaticWebAssetsDependsOn); - _ResolveBlazorFilesToCompress; - </ResolveCurrentProjectStaticWebAssetsDependsOn> - - </PropertyGroup> - - <Target Name="_ResolveBlazorFilesToCompress" AfterTargets="_ResolveBlazorGeneratedAssets"> - - <PropertyGroup> - <_BlazorFilesIntermediateOutputPath>$(IntermediateOutputPath)compressed\</_BlazorFilesIntermediateOutputPath> - <_GzipCompressionBlazorApplicationFilesManifestPath>$(IntermediateOutputPath)compressed\gzip.manifest.json</_GzipCompressionBlazorApplicationFilesManifestPath> - <_BrotliCompressionBlazorApplicationFilesManifestPath>$(IntermediateOutputPath)compressed\brotli.manifest.json</_BrotliCompressionBlazorApplicationFilesManifestPath> - </PropertyGroup> - - <MakeDir Directories="$(_BlazorFilesIntermediateOutputPath)" /> - <ItemGroup> - - <_CompressionCandidate Include="@(StaticWebAsset)" Condition="'%(SourceType)' == '' and $([System.String]::Copy('%(RelativePath)').Replace('\','/').StartsWith('_framework/'))" KeepDuplicates="false" /> - <_CompressionCandidateIntegrity Include="@(_BlazorOutputWithTargetPath->'%(FullPath)')" /> - <_CompressionCandidateWithIntegrity Include="%(Identity)"> - <SourceType>@(_CompressionCandidate->'%(SourceType)')</SourceType> - <SourceId>@(_CompressionCandidate->'%(SourceId)')</SourceId> - <ContentRoot>@(_CompressionCandidate->'%(ContentRoot)')</ContentRoot> - <BasePath>@(_CompressionCandidate->'%(BasePath)')</BasePath> - <RelativePath>@(_CompressionCandidate->'%(RelativePath)')</RelativePath> - <InputSource>@(_CompressionCandidateIntegrity->'%(IntegrityFile)')</InputSource> - </_CompressionCandidateWithIntegrity> - - <_GzipBlazorFileToCompress Include="@(_CompressionCandidateWithIntegrity)"> - <TargetCompressionPath>$(_BlazorFilesIntermediateOutputPath)%(RelativePath).gz</TargetCompressionPath> - <TargetOutputPath>%(RelativePath).gz</TargetOutputPath> - <RelativePath>%(RelativePath).gz</RelativePath> - </_GzipBlazorFileToCompress> - <_GzipBlazorFileToCompress Remove="@(_BlazorFileCompressExclusion)" /> - - <_BrotliBlazorFileToCompress Include="@(_CompressionCandidateWithIntegrity)"> - <TargetCompressionPath>$(_BlazorFilesIntermediateOutputPath)%(RelativePath).br</TargetCompressionPath> - <TargetOutputPath>%(RelativePath).br</TargetOutputPath> - <RelativePath>%(RelativePath).br</RelativePath> - </_BrotliBlazorFileToCompress> - <_BrotliBlazorFileToCompress Remove="@(_BlazorFileCompressExclusion)" /> - - <_BlazorFileToCompress Include="@(_GzipBlazorFileToCompress)" /> - <_BlazorFileToCompress Include="@(_BrotliBlazorFileToCompress)" /> - <_BlazorFileToCompress Remove="@(_BlazorFileCompressExclusion)" /> - - <_CompressedStaticWebAsset Include="@(_BlazorFileToCompress->'%(TargetCompressionPath)')" RemoveMetadata="TargetOutputPath;TargetCompressionPath" /> - - <StaticWebAsset Include="@(_CompressedStaticWebAsset->'%(FullPath)')" KeepMetadata="SourceType;SourceId;ContentRoot;BasePath;RelativePath" /> - <FileWrites Include="@(_CompressedStaticWebAsset)" /> - - </ItemGroup> - - </Target> - - <UsingTask TaskName="GzipCompressBlazorApplicationFiles" AssemblyFile="$(_BlazorTasksPath)" /> - <UsingTask TaskName="BrotliCompressBlazorApplicationFiles" AssemblyFile="$(_BlazorTasksPath)" /> - <UsingTask TaskName="GenerateBlazorCompressionManifest" AssemblyFile="$(_BlazorTasksPath)" /> - - <Target - Name="_GzipCompressBlazorApplicationFiles" - DependsOnTargets="ResolveStaticWebAssetsInputs" - BeforeTargets="_BlazorStaticWebAssetsCopyGeneratedFilesToOutputDirectory" - Inputs="$(_GzipCompressionBlazorApplicationFilesManifestPath)" - Outputs="@(_GzipBlazorFileToCompress->'%(TargetCompressionPath)')"> - - <GzipCompressBlazorApplicationFiles ManifestPath="$(_GzipCompressionBlazorApplicationFilesManifestPath)" /> - - </Target> - - <Target - Name="_GenerateGzipCompressionBlazorApplicationFilesManifest" - BeforeTargets="_GzipCompressBlazorApplicationFiles" - Inputs="@(_GzipBlazorFileToCompress->'%(InputSource)')" - Outputs="$(_GzipCompressionBlazorApplicationFilesManifestPath)"> - - <GenerateBlazorCompressionManifest FilesToCompress="@(_GzipBlazorFileToCompress)" ManifestPath="$(_GzipCompressionBlazorApplicationFilesManifestPath)" /> - </Target> - - <Target - Name="_BrotliCompressBlazorApplicationFiles" - BeforeTargets="GetCopyToPublishDirectoryItems;_CopyResolvedFilesToPublishPreserveNewest" - DependsOnTargets="ResolveStaticWebAssetsInputs" - Inputs="$(_BrotliCompressionBlazorApplicationFilesManifestPath)" - Outputs="@(_BrotliBlazorFileToCompress->'%(TargetCompressionPath)')"> - - <BrotliCompressBlazorApplicationFiles - BlazorBrotliPath="$(_BlazorBrotliPath)" - ManifestPath="$(_BrotliCompressionBlazorApplicationFilesManifestPath)" - ToolExe="$(_DotNetHostFileName)" - ToolPath="$(_DotNetHostDirectory)" /> - </Target> - - <Target - Name="_GenerateBrotliCompressionBlazorApplicationFilesManifest" - BeforeTargets="_GzipCompressBlazorApplicationFiles" - Inputs="@(_BrotliBlazorFileToCompress->'%(InputSource)')" - Outputs="$(_BrotliCompressionBlazorApplicationFilesManifestPath)"> - - <GenerateBlazorCompressionManifest FilesToCompress="@(_BrotliBlazorFileToCompress)" ManifestPath="$(_BrotliCompressionBlazorApplicationFilesManifestPath)" /> - </Target> - -</Project> diff --git a/src/Components/WebAssembly/Build/src/targets/Publish.targets b/src/Components/WebAssembly/Build/src/targets/Publish.targets deleted file mode 100644 index 5847bb0aca..0000000000 --- a/src/Components/WebAssembly/Build/src/targets/Publish.targets +++ /dev/null @@ -1,40 +0,0 @@ -<Project> - <PropertyGroup> - <!-- Disable unwanted parts of the default publish process --> - <CopyBuildOutputToPublishDirectory>false</CopyBuildOutputToPublishDirectory> - <CopyOutputSymbolsToPublishDirectory>false</CopyOutputSymbolsToPublishDirectory> - <PreserveCompilationContext>false</PreserveCompilationContext> - <RazorCompileOnPublish>false</RazorCompileOnPublish> - <GenerateDependencyFile>false</GenerateDependencyFile> - <IsWebConfigTransformDisabled>true</IsWebConfigTransformDisabled> - </PropertyGroup> - - <Target - Name="_BlazorCleanupPublishOutput" - AfterTargets="ComputeResolvedFilesToPublishList" - Condition="'$(BlazorPrunePublishOutput)' != 'false'"> - - <ItemGroup> - <!-- Delete stray contents from the root of the the app. --> - <ResolvedFileToPublish - Remove="%(ResolvedFileToPublish.Identity)" - Condition="'%(ResolvedFileToPublish.RelativePath)' != 'web.config' AND !$([System.String]::Copy('%(ResolvedFileToPublish.RelativePath)').Replace('\','/').StartsWith('wwwroot/'))"/> - </ItemGroup> - </Target> - - <Target - Name="_BlazorCopyStandaloneWebConfig" - AfterTargets="_BlazorCleanupPublishOutput;ComputeResolvedFilesToPublishList" - Condition="'@(ResolvedFileToPublish->AnyHaveMetadataValue('RelativePath', 'web.config'))' != 'true'"> - - <ItemGroup> - <ResolvedFileToPublish Include="$(MSBuildThisFileDirectory)Standalone.Web.config"> - <ExcludeFromSingleFile>true</ExcludeFromSingleFile> - <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory> - <RelativePath>web.config</RelativePath> - </ResolvedFileToPublish> - </ItemGroup> - - </Target> - -</Project>
\ No newline at end of file diff --git a/src/Components/WebAssembly/Build/src/targets/ServiceWorkerAssetsManifest.targets b/src/Components/WebAssembly/Build/src/targets/ServiceWorkerAssetsManifest.targets deleted file mode 100644 index c17edf60e0..0000000000 --- a/src/Components/WebAssembly/Build/src/targets/ServiceWorkerAssetsManifest.targets +++ /dev/null @@ -1,240 +0,0 @@ -<Project> - - <Target Name="_ComputeServiceWorkerAssetsManifestInputs" - Condition="'$(ServiceWorkerAssetsManifest)' != ''" - BeforeTargets="_ResolveBlazorOutputs;_ResolveBlazorFilesToCompress"> - - <PropertyGroup> - <_ServiceWorkerAssetsManifestIntermediateOutputPath>$([MSBuild]::MakeRelative($(MSBuildProjectDirectory), $(_BlazorIntermediateOutputPath)))$(ServiceWorkerAssetsManifest)</_ServiceWorkerAssetsManifestIntermediateOutputPath> - <_ServiceWorkerAssetsManifestFullPath>$([System.IO.Path]::GetFullPath('$(MSBuildProjectDirectory)/$(_ServiceWorkerAssetsManifestIntermediateOutputPath)'))</_ServiceWorkerAssetsManifestFullPath> - </PropertyGroup> - - <ItemGroup> - <_BlazorOutputWithTargetPath - Include="$(_ServiceWorkerAssetsManifestFullPath)" - TargetOutputPath="$(_ServiceWorkerAssetsManifestIntermediateOutputPath)" /> - - <_ManifestStaticWebAsset Include="$(_ServiceWorkerAssetsManifestFullPath)"> - <SourceType></SourceType> - <SourceId>$(PackageId)</SourceId> - <ContentRoot>$([MSBuild]::NormalizeDirectory('$(TargetDir)wwwroot\'))</ContentRoot> - <BasePath>$(StaticWebAssetBasePath)</BasePath> - <RelativePath>$(ServiceWorkerAssetsManifest)</RelativePath> - </_ManifestStaticWebAsset> - - <StaticWebAsset Include="@(_ManifestStaticWebAsset)" /> - <_CompressionCandidate Include="@(_ManifestStaticWebAsset)" /> - <_CompressionCandidateWithIntegrity Include="@(_ManifestStaticWebAsset)"> - <InputSource>$(_ServiceWorkerAssetsManifestFullPath)</InputSource> - </_CompressionCandidateWithIntegrity> - - </ItemGroup> - - </Target> - - <UsingTask TaskName="GenerateServiceWorkerAssetsManifest" AssemblyFile="$(_BlazorTasksPath)" /> - - <Target Name="_WriteServiceWorkerAssetsManifest" - Condition="'$(ServiceWorkerAssetsManifest)' != ''" - Inputs="@(ServiceWorkerAssetsManifestItem)" - Outputs="$(_ServiceWorkerAssetsManifestIntermediateOutputPath)" - BeforeTargets="_ComputeManifestIntegrity" - DependsOnTargets="ResolveStaticWebAssetsInputs;_GenerateServiceWorkerIntermediateFiles"> - - <GenerateServiceWorkerAssetsManifest - Version="$(ServiceWorkerAssetsManifestVersion)" - AssetsWithHashes="@(_ServiceWorkerAssetsManifestItemWithHash)" - OutputPath="$(_ServiceWorkerAssetsManifestIntermediateOutputPath)" /> - - <ItemGroup> - <FileWrites Include="$(_ServiceWorkerAssetsManifestIntermediateOutputPath)" /> - </ItemGroup> - - </Target> - - <Target Name="_ComputeManifestIntegrity" - Condition="'$(ServiceWorkerAssetsManifest)' != ''" - BeforeTargets="_BlazorStaticWebAssetsCopyGeneratedFilesToOutputDirectory;_GzipCompressBlazorApplicationFiles"> - - <GetFileHash Files="$(_ServiceWorkerAssetsManifestIntermediateOutputPath)" Algorithm="SHA256" HashEncoding="base64"> - <Output TaskParameter="Items" ItemName="_ServiceWorkerManifestWithHash" /> - </GetFileHash> - - <ItemGroup> - - <_ServiceWorkerManifestWithIntegrity Include="@(_ServiceWorkerManifestWithHash)"> - <Integrity>%(FileHash)</Integrity> - <IntegrityFile>$(IntermediateOutputPath)integrity\$([System.String]::Copy('%(FileHash)').Replace('/','-').Replace('+','_')).hash</IntegrityFile> - </_ServiceWorkerManifestWithIntegrity> - - <FileWrites Include="%(_ServiceWorkerManifestWithIntegrity.IntegrityFile)" /> - - </ItemGroup> - - <WriteLinesToFile Lines="%(_ServiceWorkerManifestWithIntegrity.Integrity)" File="%(_ServiceWorkerManifestWithIntegrity.IntegrityFile)" WriteOnlyWhenDifferent="true" Overwrite="true" /> - - <PropertyGroup> - <_ServiceWorkerManifestIntegrityFile>$(IntermediateOutputPath)integrity\$([System.String]::Copy('%(_ServiceWorkerManifestWithIntegrity.FileHash)').Replace('/','-').Replace('+','_')).hash</_ServiceWorkerManifestIntegrityFile> - </PropertyGroup> - - <ItemGroup> - <_GzipFileToPatch Include="@(_GzipBlazorFileToCompress)" Condition="'%(Identity)' == '$(_ServiceWorkerAssetsManifestFullPath)'" KeepDuplicates="false"> - <InputSource>$(_ServiceWorkerManifestIntegrityFile)</InputSource> - </_GzipFileToPatch> - - <_GzipBlazorFileToCompress Remove="@(_GzipFileToPatch)" /> - <_GzipBlazorFileToCompress Include="@(_GzipFileToPatch)" /> - - <_BrotliFileToPatch Include="@(_BrotliBlazorFileToCompress)" Condition="'%(Identity)' == '$(_ServiceWorkerAssetsManifestFullPath)'" KeepDuplicates="false"> - <InputSource>$(_ServiceWorkerManifestIntegrityFile)</InputSource> - </_BrotliFileToPatch> - - <_BrotliBlazorFileToCompress Remove="@(_BrotliFileToPatch)" /> - <_BrotliBlazorFileToCompress Include="@(_BrotliFileToPatch)" /> - </ItemGroup> - - </Target> - - <Target Name="_ComputeServiceWorkerAssetsManifestFileHashes" - Condition="'$(ServiceWorkerAssetsManifest)' != ''" - DependsOnTargets="ResolveStaticWebAssetsInputs;_BlazorComputeOtherAssetsIntegrity"> - - <ItemGroup> - <ServiceWorkerAssetsManifestItem - Include="%(StaticWebAsset.Identity)" - Condition="'%(RelativePath)' != '$(ServiceWorkerAssetsManifest)'"> - <AssetUrl>$([System.String]::Copy('$([System.String]::Copy('%(StaticWebAsset.BasePath)').TrimEnd('/'))/%(StaticWebAsset.RelativePath)').Replace('\','/').TrimStart('/'))</AssetUrl> - </ServiceWorkerAssetsManifestItem> - - <!-- Don't include compressed files in the manifest, since their existence is transparent to the client --> - <ServiceWorkerAssetsManifestItem Remove="@(_CompressedStaticWebAsset->'%(FullPath)')" /> - - <!-- Don't include the service worker files in the manifest, as the service worker doesn't need to fetch itself --> - <ServiceWorkerAssetsManifestItem Remove="%(_ServiceWorkerIntermediateFile.FullPath)" /> - - <_ServiceWorkerExclude Include="@(_StaticWebAssetIntegrity)" /> - <_ServiceWorkerItemBase Include="@(ServiceWorkerAssetsManifestItem)" /> - <_ServiceWorkerItemBase Remove="@(_ServiceWorkerExclude)" /> - <_ServiceWorkerItemHash Include="@(ServiceWorkerAssetsManifestItem)" /> - <_ServiceWorkerItemHash Remove="@(_ServiceWorkerItemBase)" /> - <_ServiceWorkerAssetsManifestItemWithHash Include="%(Identity)"> - <AssetUrl>@(_ServiceWorkerItemHash->'%(AssetUrl)')</AssetUrl> - <Integrity>@(_StaticWebAssetIntegrity->'%(Integrity)')</Integrity> - </_ServiceWorkerAssetsManifestItemWithHash> - - </ItemGroup> - </Target> - - <Target Name="_BlazorComputeOtherAssetsIntegrity" Condition="'$(ServiceWorkerAssetsManifest)' != ''"> - <ItemGroup> - <_StaticWebAssetsWithoutHash Include="@(StaticWebAsset)" Condition="'%(SourceType)' != '' or '%(ContentRoot)' == '$(_BlazorCurrentProjectWWWroot)'" /> - <_StaticWebAssetsWithoutHash Remove="@(_StaticWebAssetIntegrity)" /> - </ItemGroup> - - <GetFileHash Files="@(_StaticWebAssetsWithoutHash)" Algorithm="SHA256" HashEncoding="base64"> - <Output TaskParameter="Items" ItemName="_StaticWebAssetHash" /> - </GetFileHash> - - <ItemGroup> - <_StaticWebAssetIntegrity Include="%(_StaticWebAssetHash.Identity)"> - <Integrity>%(_StaticWebAssetHash.FileHash)</Integrity> - </_StaticWebAssetIntegrity> - </ItemGroup> - - </Target> - - - <!-- - Compute a default ServiceWorkerAssetsManifestVersion value by combining all the asset hashes. - This is useful because then clients will only have to repopulate caches if the contents have changed. - --> - <Target Name="_ComputeDefaultServiceWorkerAssetsManifestVersion" - Condition="'$(ServiceWorkerAssetsManifest)' != ''" - DependsOnTargets="_ComputeServiceWorkerAssetsManifestFileHashes"> - <PropertyGroup> - <_CombinedHashIntermediatePath>$(_BlazorIntermediateOutputPath)serviceworkerhashes.txt</_CombinedHashIntermediatePath> - </PropertyGroup> - - <!-- Neither of these should ever happen, but if we do we want to know about it. --> - <Error Text="Cannot compute service worker assets manifest version, because no service worker manifest items were defined." - Condition="'@(_ServiceWorkerAssetsManifestItemWithHash)' == ''" /> - <Error Text="While computing service worker assets manifest version, did not find any dll entries in service worker assets manifest." - Condition="'@(_ServiceWorkerAssetsManifestItemWithHash->WithMetadataValue('Extension', '.dll'))' == ''" /> - - <WriteLinesToFile - File="$(_CombinedHashIntermediatePath)" - Lines="@(_ServiceWorkerAssetsManifestItemWithHash->'%(Integrity)')" - WriteOnlyWhenDifferent="true" - Overwrite="true" /> - - <GetFileHash Files="$(_CombinedHashIntermediatePath)" Algorithm="SHA256" HashEncoding="base64"> - <Output TaskParameter="Items" ItemName="_ServiceWorkerAssetsManifestCombinedHash" /> - </GetFileHash> - - <PropertyGroup> - <ServiceWorkerAssetsManifestVersion Condition="'$(ServiceWorkerAssetsManifestVersion)' == ''">$([System.String]::Copy('%(_ServiceWorkerAssetsManifestCombinedHash.FileHash)').Substring(0, 8))</ServiceWorkerAssetsManifestVersion> - </PropertyGroup> - </Target> - - <Target Name="_OmitServiceWorkerContent" - Condition="'$(ServiceWorkerAssetsManifest)' != ''" - BeforeTargets="AssignTargetPaths;ResolveCurrentProjectStaticWebAssetsInputs"> - - <ItemGroup> - <!-- Don't emit the service worker source files to the output --> - <Content Remove="@(ServiceWorker)" /> - <Content Remove="@(ServiceWorker->'%(PublishedContent)')" /> - </ItemGroup> - </Target> - - <Target Name="_ResolveServiceWorkerOutputs" - Condition="'$(ServiceWorkerAssetsManifest)' != ''" - BeforeTargets="_ResolveBlazorOutputs" - DependsOnTargets="_ComputeServiceWorkerOutputs"> - - <ItemGroup> - <_BlazorFileCompressExclusion Include="@(_ServiceWorkerIntermediateFile->'%(FullPath)')" /> - - <_ServiceWorkerStaticWebAsset Include="@(_ServiceWorkerIntermediateFile->'%(FullPath)')"> - <SourceType></SourceType> - <SourceId>$(PackageId)</SourceId> - <ContentRoot>$([MSBuild]::NormalizeDirectory('$(TargetDir)wwwroot\'))</ContentRoot> - <BasePath>$(StaticWebAssetBasePath)</BasePath> - <RelativePath>%(TargetOutputPath)</RelativePath> - </_ServiceWorkerStaticWebAsset> - - <StaticWebAsset Include="@(_ServiceWorkerStaticWebAsset)" /> - - </ItemGroup> - </Target> - - <Target Name="_ComputeServiceWorkerOutputs" - Condition="'$(ServiceWorkerAssetsManifest)' != ''"> - - <ItemGroup> - <!-- Figure out where we're getting the content for each @(ServiceWorker) entry, depending on whether there's a PublishedContent value --> - <_ServiceWorkerIntermediateFile Include="@(ServiceWorker->'$(IntermediateOutputPath)blazor\serviceworkers\%(Identity)')"> - <ContentSourcePath Condition="'%(ServiceWorker.PublishedContent)' != ''">%(ServiceWorker.PublishedContent)</ContentSourcePath> - <ContentSourcePath Condition="'%(ServiceWorker.PublishedContent)' == ''">%(ServiceWorker.Identity)</ContentSourcePath> - <TargetOutputPath>%(ServiceWorker.Identity)</TargetOutputPath> - <TargetOutputPath Condition="$([System.String]::Copy('%(ServiceWorker.Identity)').Replace('\','/').StartsWith('wwwroot/'))">$([System.String]::Copy('%(ServiceWorker.Identity)').Substring(8))</TargetOutputPath> - </_ServiceWorkerIntermediateFile> - </ItemGroup> - </Target> - - <Target Name="_GenerateServiceWorkerIntermediateFiles" - Condition="'$(ServiceWorkerAssetsManifest)' != ''" - Inputs="@(_ServiceWorkerIntermediateFile->'%(ContentSourcePath)'); $(_CombinedHashIntermediatePath)" - Outputs="@(_ServiceWorkerIntermediateFile)" - DependsOnTargets="_ComputeDefaultServiceWorkerAssetsManifestVersion"> - <Copy SourceFiles="%(_ServiceWorkerIntermediateFile.ContentSourcePath)" DestinationFiles="%(_ServiceWorkerIntermediateFile.Identity)" /> - <WriteLinesToFile - File="%(_ServiceWorkerIntermediateFile.Identity)" - Lines="/* Manifest version: $(ServiceWorkerAssetsManifestVersion) */" - Condition="'$(ServiceWorkerAssetsManifestVersion)' != ''" /> - <ItemGroup> - <FileWrites Include="%(_ServiceWorkerIntermediateFile.Identity)" /> - </ItemGroup> - </Target> - -</Project> diff --git a/src/Components/WebAssembly/Build/src/targets/Standalone.Web.config b/src/Components/WebAssembly/Build/src/targets/Standalone.Web.config deleted file mode 100644 index 7f9995d792..0000000000 --- a/src/Components/WebAssembly/Build/src/targets/Standalone.Web.config +++ /dev/null @@ -1,40 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<configuration> - <system.webServer> - <staticContent> - <remove fileExtension=".dat" /> - <remove fileExtension=".dll" /> - <remove fileExtension=".json" /> - <remove fileExtension=".wasm" /> - <remove fileExtension=".woff" /> - <remove fileExtension=".woff2" /> - <mimeMap fileExtension=".dll" mimeType="application/octet-stream" /> - <mimeMap fileExtension=".dat" mimeType="application/octet-stream" /> - <mimeMap fileExtension=".json" mimeType="application/json" /> - <mimeMap fileExtension=".wasm" mimeType="application/wasm" /> - <mimeMap fileExtension=".woff" mimeType="application/font-woff" /> - <mimeMap fileExtension=".woff2" mimeType="application/font-woff" /> - </staticContent> - <httpCompression> - <dynamicTypes> - <add mimeType="application/octet-stream" enabled="true" /> - <add mimeType="application/wasm" enabled="true" /> - </dynamicTypes> - </httpCompression> - <rewrite> - <rules> - <rule name="Serve subdir"> - <match url=".*" /> - <action type="Rewrite" url="wwwroot\{R:0}" /> - </rule> - <rule name="SPA fallback routing" stopProcessing="true"> - <match url=".*" /> - <conditions logicalGrouping="MatchAll"> - <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" /> - </conditions> - <action type="Rewrite" url="wwwroot\" /> - </rule> - </rules> - </rewrite> - </system.webServer> -</configuration> diff --git a/src/Components/WebAssembly/Build/src/targets/StaticWebAssets.props b/src/Components/WebAssembly/Build/src/targets/StaticWebAssets.props deleted file mode 100644 index d15d07d729..0000000000 --- a/src/Components/WebAssembly/Build/src/targets/StaticWebAssets.props +++ /dev/null @@ -1,15 +0,0 @@ -<Project> - <PropertyGroup> - <ResolveStaticWebAssetsInputsDependsOn> - $(ResolveStaticWebAssetsInputsDependsOn); - _BlazorApplyLinkPreferencesToStaticWebAssets; - _ResolveBlazorGeneratedAssets; - </ResolveStaticWebAssetsInputsDependsOn> - - <GetCurrentProjectStaticWebAssetsDependsOn> - $(GetCurrentProjectStaticWebAssetsDependsOn); - _BlazorApplyLinkPreferencesToStaticWebAssets; - _ResolveBlazorGeneratedAssets; - </GetCurrentProjectStaticWebAssetsDependsOn> - </PropertyGroup> -</Project> diff --git a/src/Components/WebAssembly/Build/src/targets/StaticWebAssets.targets b/src/Components/WebAssembly/Build/src/targets/StaticWebAssets.targets deleted file mode 100644 index 9c16d9dd5a..0000000000 --- a/src/Components/WebAssembly/Build/src/targets/StaticWebAssets.targets +++ /dev/null @@ -1,165 +0,0 @@ -<Project> - - <PropertyGroup> - <_BlazorCurrentProjectWWWroot>$([MSBuild]::NormalizeDirectory('$(MSBuildProjectDirectory)\wwwroot\'))</_BlazorCurrentProjectWWWroot> - </PropertyGroup> - - <Target Name="_ResolveBlazorGeneratedAssets" DependsOnTargets="_PrepareBlazorOutputs"> - <ItemGroup> - <_BlazorOutputCandidateAsset Include="@(_BlazorOutputWithTargetPath->'%(FullPath)')"> - <SourceType></SourceType> - <SourceId>$(PackageId)</SourceId> - <ContentRoot>$([MSBuild]::NormalizeDirectory('$(TargetDir)wwwroot\'))</ContentRoot> - <BasePath>$(StaticWebAssetBasePath)</BasePath> - <RelativePath>$([System.String]::Copy('%(_BlazorOutputWithTargetPath.TargetOutputPath)').Replace('\','/'))</RelativePath> - <Integrity>%(_BlazorOutputWithTargetPath.Integrity)</Integrity> - </_BlazorOutputCandidateAsset> - - <_BlazorOutputCandidateAsset Remove="@(StaticWebAsset)" /> - - <_StaticWebAssetIntegrity Include="@(_BlazorOutputCandidateAsset)" KeepMetadata="Integrity" /> - - <StaticWebAsset Include="@(_BlazorOutputCandidateAsset)" KeepMetadata="SourceType;SourceId;ContentRoot;BasePath;RelativePath" /> - - <StaticWebAsset Remove="@(StaticWebAsset)" Condition="'$(BlazorEnableDebugging)' != 'true' and '%(SourceType)' == '' and '%(Extension)' == '.pdb'" /> - - <!-- We are depending on a "private" property for static web assets, but this is something we can clean-up in a later release. - These files are not "external" in the "traditional" sense but it is fine for now as this is an implementation detail. - We only need to do this for the standalone case, for hosted scenarios this works just fine as the assets are considered - external. --> - <_ExternalStaticWebAsset Include="@(_BlazorOutputWithTargetPath->'%(FullPath)')"> - <SourceId>$(PackageId)</SourceId> - <!-- We just do this to keep the existing implementation happy. We will update this in the next release. --> - <SourceType>Generated</SourceType> - <ContentRoot>$([MSBuild]::NormalizeDirectory('$(TargetDir)wwwroot\'))</ContentRoot> - <BasePath>$(StaticWebAssetBasePath)</BasePath> - </_ExternalStaticWebAsset> - - <!-- These items we are adding for forward-compatibility with newer SDK versions. The paths listed here will be added unconditionally - to the generated static web assets manifest. This is only needed for forward compatibility in Blazor standalone scenarios. --> - <StaticWebAssetsManifestPath Include="$([MSBuild]::NormalizeDirectory('$(TargetDir)wwwroot\'))"> - <SourceId>$(PackageId)</SourceId> - <BasePath>$(StaticWebAssetBasePath)</BasePath> - </StaticWebAssetsManifestPath> - </ItemGroup> - - </Target> - - <Target Name="_BlazorStaticWebAssetsCopyGeneratedFilesToOutputDirectory" - DependsOnTargets="ResolveStaticWebAssetsInputs;$(_BlazorCopyFilesToOutputDirectoryDependsOn)" - AfterTargets="CopyFilesToOutputDirectory" - Condition="'$(OutputType.ToLowerInvariant())'=='exe'"> - - <ItemGroup> - <_BlazorCopyLocalAssets - Include="@(StaticWebAsset)" - Condition="'%(SourceType)' == '' and '%(ContentRoot)' != '$(_BlazorCurrentProjectWWWroot)' and !$([System.String]::Copy('%(RelativePath)').EndsWith('.br'))" /> - <_BlazorCopyLocalAssets Remove="@(_BlazorCopyLocalExclusion)" /> - </ItemGroup> - - <!-- Copy the blazor output files --> - <Copy - SourceFiles="@(_BlazorCopyLocalAssets)" - DestinationFiles="@(_BlazorCopyLocalAssets->'%(ContentRoot)%(RelativePath)')" - SkipUnchangedFiles="$(SkipCopyUnchangedFiles)" - OverwriteReadOnlyFiles="$(OverwriteReadOnlyFiles)" - Retries="$(CopyRetryCount)" - RetryDelayMilliseconds="$(CopyRetryDelayMilliseconds)" - UseHardlinksIfPossible="$(CreateHardLinksForCopyFilesToOutputDirectoryIfPossible)" - UseSymboliclinksIfPossible="$(CreateSymbolicLinksForCopyFilesToOutputDirectoryIfPossible)" - Condition="'@(_BlazorCopyLocalAssets)' != '' and '$(CopyBuildOutputToOutputDirectory)' == 'true' and '$(SkipCopyBuildProduct)' != 'true'"> - </Copy> - - <ItemGroup> - <FileWrites Include="@(_BlazorCopyLocalAssets->'%(ContentRoot)%(RelativePath)')" /> - </ItemGroup> - - <ItemGroup> - <_BlazorStatisticsOutput Include="@(_BlazorCopyLocalAssets->'%(RelativePath)')" /> - </ItemGroup> - - <Message Importance="high" Text="$(TargetName) (Blazor output) -> $(TargetDir)wwwroot" /> - </Target> - - <Target Name="_StaticWebAssetsBlazorStandalonePublish" - AfterTargets="_StaticWebAssetsComputeFilesToPublish"> - - <ItemGroup> - - <_CurrentProjectStandalonePublishStaticWebAsset Include="%(StaticWebAsset.FullPath)" Condition="'%(StaticWebAsset.SourceType)' == ''"> - <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory> - <RelativePath>$([MSBuild]::MakeRelative('$(MSBuildProjectDirectory)','$([MSBuild]::NormalizePath('wwwroot\%(BasePath)\%(RelativePath)'))'))</RelativePath> - </_CurrentProjectStandalonePublishStaticWebAsset> - - <!-- Remove any existing external static web asset that might have been added as part of the - regular publish pipeline. --> - <ResolvedFileToPublish Remove="@(_CurrentProjectStandalonePublishStaticWebAsset)" /> - - <ResolvedFileToPublish Include="@(_CurrentProjectStandalonePublishStaticWebAsset)"> - <ExcludeFromSingleFile>true</ExcludeFromSingleFile> - </ResolvedFileToPublish> - - </ItemGroup> - - </Target> - - <Target Name="_BlazorApplyLinkPreferencesToStaticWebAssets"> - <ItemGroup> - <_ContentWithWwrootLinkAttribute Include="@(Content)" Condition="'%(Content.Link)' != '' and $([System.String]::Copy('%(Content.Link)').Replace('\','/').StartsWith('wwwroot/'))" /> - - <_ContentLinkedIntoWwwroot - Include="@(_ContentWithWwrootLinkAttribute)" - Condition="@(_ContentWithWwrootLinkAttribute) != '' and '%(_ContentWithWwrootLinkAttribute.CopyToPublishDirectory)' != 'false'"> - <!-- This gets rid of wwwroot\ --> - <RelativePath>$([System.String]::Copy('%(Link)').Substring(8))</RelativePath> - </_ContentLinkedIntoWwwroot> - - <_OutsideContentLinkedIntoWwwroot Include="@(_ContentLinkedIntoWwwroot->'%(FullPath)')" Condition="@(_ContentLinkedIntoWwwroot) != '' and !$([System.String]::Copy('%(Identity)').Replace('\','/').StartsWith('wwwroot/'))" /> - <_WwwrootLinkedContent Include="@(_ContentLinkedIntoWwwroot->'%(FullPath)')" Condition="@(_ContentLinkedIntoWwwroot) != '' and $([System.String]::Copy('%(Identity)').Replace('\','/').StartsWith('wwwroot/'))" KeepMetadata="RelativePath" /> - - <!-- For content items with the Link attribute on them, we update the relative path. This enables support at publish time for these assets but forgoes any - dev-time support. (If you want to have dev-time support, you need to add an appropriate file into the wwwroot folder with CopyToPublishDirectory="false") - --> - <_NonLinkedStaticWebAssets Include="@(StaticWebAsset)" Exclude="@(_WwwrootLinkedContent)" /> - <_LinkedStaticWebAssets Include="@(StaticWebAsset)" Exclude="@(_NonLinkedStaticWebAssets)" /> - - <_UpdatedStaticWebAssets Include="%(Identity)"> - <SourceType>@(_LinkedStaticWebAssets->'%(SourceType)')</SourceType> - <SourceId>@(_LinkedStaticWebAssets->'%(SourceId)')</SourceId> - <ContentRoot>@(_LinkedStaticWebAssets->'%(ContentRoot)')</ContentRoot> - <BasePath>@(_LinkedStaticWebAssets->'%(BasePath)')</BasePath> - <RelativePath>@(_WwwrootLinkedContent->'%(RelativePath)')</RelativePath> - </_UpdatedStaticWebAssets> - - <StaticWebAsset Remove="@(_UpdatedStaticWebAssets)" /> - <StaticWebAsset Include="@(_UpdatedStaticWebAssets)" /> - - <!-- This allows limited publish time support for content items that are outside the wwwroot folder but are linked into the wwwroot folder. For example: - * Imagine a set of items in <ProjectDir>/Client/publish that are linked into <ProjectDir>/wwwroot/. - * We will consider them static web assets and default their content root to `<ProjectDir>/wwwroot` and their relative path will be whatever is after wwwroot\ - * We don't guarantee that these assets can be resolved at development time. - * We do guarantee that we will copy them into the actual wwwroot folder at publish time. - * If you want this type of dev-time support, the recomendation is to add the list of assets to the item group manually indicating a suitable content root. - --> - <StaticWebAsset Include="@(_OutsideContentLinkedIntoWwwroot)" Condition="@(_OutsideContentLinkedIntoWwwroot) != ''"> - <SourceType></SourceType> - <SourceId>$(PackageId)</SourceId> - <!-- We don't try to come up with a separate content root to make the inner loop work. - You can add items with CopyToPublishDirectory=false for development time support or add the assets directly by pasing in the parameters - --> - <ContentRoot>$([MSBuild]::NormalizeDirectory('$(MSBuildProjectDirectory)\wwwroot\'))</ContentRoot> - <BasePath>$(StaticWebAssetBasePath)</BasePath> - <RelativePath>%(_OutsideContentLinkedIntoWwwroot.RelativePath)</RelativePath> - </StaticWebAsset> - - <_StaticWebAssetsPublishFalse Include="@(Content->'%(FullPath)')" Condition="'%(Content.CopyToPublishDirectory)' == 'false'" /> - <_StaticWebAssetsLinkOutsideWwwroot Include="@(Content->'%(FullPath)')" Condition="'%(Content.Link)' != '' and !$([System.String]::Copy('%(Content.Link)').Replace('\','/').StartsWith('wwwroot/'))" /> - - <!-- Remove files that wouldn't be copied to the publish folder or that would be copied outside of the wwwroot folder if they were ever considered static web assets --> - <StaticWebAsset Remove="@(_StaticWebAssetsPublishFalse)" /> - <StaticWebAsset Remove="@(_StaticWebAssetsLinkOutsideWwwroot)" /> - </ItemGroup> - - </Target> - -</Project> diff --git a/src/Components/WebAssembly/Build/test/BlazorCreateRootDescriptorFileTest.cs b/src/Components/WebAssembly/Build/test/BlazorCreateRootDescriptorFileTest.cs deleted file mode 100644 index 2ad0ecdddd..0000000000 --- a/src/Components/WebAssembly/Build/test/BlazorCreateRootDescriptorFileTest.cs +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.IO; -using System.Xml.Linq; -using Xunit; - -namespace Microsoft.AspNetCore.Components.WebAssembly.Build -{ - public class BlazorCreateRootDescriptorFileTest - { - [Fact] - public void ProducesRootDescriptor() - { - // Arrange/Act - using var stream = new MemoryStream(); - - // Act - BlazorCreateRootDescriptorFile.WriteRootDescriptor( - stream, - new[] { "MyApp.dll" }); - - // Assert - stream.Position = 0; - var document = XDocument.Load(stream); - var rootElement = document.Root; - - var assemblyElement = Assert.Single(rootElement.Elements()); - Assert.Equal("assembly", assemblyElement.Name.ToString()); - Assert.Equal("MyApp.dll", assemblyElement.Attribute("fullname").Value); - - var typeElement = Assert.Single(assemblyElement.Elements()); - Assert.Equal("type", typeElement.Name.ToString()); - Assert.Equal("*", typeElement.Attribute("fullname").Value); - Assert.Equal("true", typeElement.Attribute("required").Value); - } - } -} diff --git a/src/Components/WebAssembly/Build/test/BlazorReadSatelliteAssemblyFileTest.cs b/src/Components/WebAssembly/Build/test/BlazorReadSatelliteAssemblyFileTest.cs deleted file mode 100644 index 991d11f7da..0000000000 --- a/src/Components/WebAssembly/Build/test/BlazorReadSatelliteAssemblyFileTest.cs +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Collections.Generic; -using System.IO; -using System.Xml.Linq; -using Microsoft.Build.Framework; -using Microsoft.Build.Utilities; -using Moq; -using Xunit; - -namespace Microsoft.AspNetCore.Components.WebAssembly.Build -{ - public class BlazorReadSatelliteAssemblyFileTest - { - [Fact] - public void WritesAndReadsRoundTrip() - { - // Arrange/Act - var tempFile = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); - - var writer = new BlazorWriteSatelliteAssemblyFile - { - BuildEngine = Mock.Of<IBuildEngine>(), - WriteFile = new TaskItem(tempFile), - SatelliteAssembly = new[] - { - new TaskItem("Resources.fr.dll", new Dictionary<string, string> - { - ["Culture"] = "fr", - ["DestinationSubDirectory"] = "fr\\", - }), - new TaskItem("Resources.ja-jp.dll", new Dictionary<string, string> - { - ["Culture"] = "ja-jp", - ["DestinationSubDirectory"] = "ja-jp\\", - }), - }, - }; - - var reader = new BlazorReadSatelliteAssemblyFile - { - BuildEngine = Mock.Of<IBuildEngine>(), - ReadFile = new TaskItem(tempFile), - }; - - writer.Execute(); - - Assert.True(File.Exists(tempFile), "Write should have succeeded."); - - reader.Execute(); - - Assert.Collection( - reader.SatelliteAssembly, - assembly => - { - Assert.Equal("Resources.fr.dll", assembly.ItemSpec); - Assert.Equal("fr", assembly.GetMetadata("Culture")); - Assert.Equal("fr\\", assembly.GetMetadata("DestinationSubDirectory")); - }, - assembly => - { - Assert.Equal("Resources.ja-jp.dll", assembly.ItemSpec); - Assert.Equal("ja-jp", assembly.GetMetadata("Culture")); - Assert.Equal("ja-jp\\", assembly.GetMetadata("DestinationSubDirectory")); - }); - } - } -} diff --git a/src/Components/WebAssembly/Build/test/BuildIntegrationTests/Assert.cs b/src/Components/WebAssembly/Build/test/BuildIntegrationTests/Assert.cs deleted file mode 100644 index aaf3e508b5..0000000000 --- a/src/Components/WebAssembly/Build/test/BuildIntegrationTests/Assert.cs +++ /dev/null @@ -1,1006 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.IO.Compression; -using System.Linq; -using System.Reflection.Metadata; -using System.Reflection.PortableExecutable; -using System.Security.Cryptography; -using System.Text; -using System.Text.RegularExpressions; - -namespace Microsoft.AspNetCore.Components.WebAssembly.Build -{ - internal class Assert : Xunit.Assert - { - // Matches `{filename}: error {code}: {message} [{project}] - // See https://stackoverflow.com/questions/3441452/msbuild-and-ignorestandarderrorwarningformat/5180353#5180353 - private static readonly Regex ErrorRegex = new Regex(@"^(?'location'.+): error (?'errorcode'[A-Z0-9]+): (?'message'.+) \[(?'project'.+)\]$"); - private static readonly Regex WarningRegex = new Regex(@"^(?'location'.+): warning (?'errorcode'[A-Z0-9]+): (?'message'.+) \[(?'project'.+)\]$"); - private static readonly string[] AllowedBuildWarnings = new[] - { - "MSB3491" , // The process cannot access the file. As long as the build succeeds, we're ok. - "NETSDK1071", // "A PackageReference to 'Microsoft.NETCore.App' specified a Version ..." - }; - - public static void BuildPassed(MSBuildResult result, bool allowWarnings = false) - { - if (result == null) - { - throw new ArgumentNullException(nameof(result)); - } - - if (result.ExitCode != 0) - { - throw new BuildFailedException(result); - } - - var buildWarnings = GetBuildWarnings(result) - .Where(m => !AllowedBuildWarnings.Contains(m.match.Groups["errorcode"].Value)) - .Select(m => m.line); - - if (!allowWarnings && buildWarnings.Any()) - { - throw new BuildWarningsException(result, buildWarnings); - } - } - - public static void BuildError(MSBuildResult result, string errorCode, string location = null) - { - if (result == null) - { - throw new ArgumentNullException(nameof(result)); - } - - // We don't really need to search line by line, I'm doing this so that it's possible/easy to debug. - var lines = result.Output.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); - for (var i = 0; i < lines.Length; i++) - { - var line = lines[i]; - var match = ErrorRegex.Match(line); - if (match.Success) - { - if (match.Groups["errorcode"].Value != errorCode) - { - continue; - } - - if (location != null && match.Groups["location"].Value.Trim() != location) - { - continue; - } - - // This is a match - return; - } - } - - throw new BuildErrorMissingException(result, errorCode, location); - } - - public static void BuildWarning(MSBuildResult result, string errorCode, string location = null) - { - if (result == null) - { - throw new ArgumentNullException(nameof(result)); - } - - // We don't really need to search line by line, I'm doing this so that it's possible/easy to debug. - foreach (var (_, match) in GetBuildWarnings(result)) - { - if (match.Groups["errorcode"].Value != errorCode) - { - continue; - } - - if (location != null && match.Groups["location"].Value.Trim() != location) - { - continue; - } - - // This is a match - return; - } - - throw new BuildErrorMissingException(result, errorCode, location); - } - - private static IEnumerable<(string line, Match match)> GetBuildWarnings(MSBuildResult result) - { - var lines = result.Output.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); - for (var i = 0; i < lines.Length; i++) - { - var line = lines[i]; - var match = WarningRegex.Match(line); - if (match.Success) - { - yield return (line, match); - } - } - } - - public static void BuildFailed(MSBuildResult result) - { - if (result == null) - { - throw new ArgumentNullException(nameof(result)); - }; - - if (result.ExitCode == 0) - { - throw new BuildPassedException(result); - } - } - - public static void BuildOutputContainsLine(MSBuildResult result, string match) - { - if (result == null) - { - throw new ArgumentNullException(nameof(result)); - } - - if (match == null) - { - throw new ArgumentNullException(nameof(match)); - } - - // We don't really need to search line by line, I'm doing this so that it's possible/easy to debug. - var lines = result.Output.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); - for (var i = 0; i < lines.Length; i++) - { - var line = lines[i].Trim(); - if (line == match) - { - return; - } - } - - throw new BuildOutputMissingException(result, match); - } - - public static void BuildOutputDoesNotContainLine(MSBuildResult result, string match) - { - if (result == null) - { - throw new ArgumentNullException(nameof(result)); - } - - if (match == null) - { - throw new ArgumentNullException(nameof(match)); - } - - // We don't really need to search line by line, I'm doing this so that it's possible/easy to debug. - var lines = result.Output.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); - for (var i = 0; i < lines.Length; i++) - { - var line = lines[i].Trim(); - if (line == match) - { - throw new BuildOutputContainsLineException(result, match); - } - } - } - - public static void FileContains(MSBuildResult result, string filePath, string match) - { - if (result == null) - { - throw new ArgumentNullException(nameof(result)); - } - - filePath = Path.Combine(result.Project.DirectoryPath, filePath); - FileExists(result, filePath); - - var text = File.ReadAllText(filePath); - if (text.Contains(match)) - { - return; - } - - throw new FileContentMissingException(result, filePath, File.ReadAllText(filePath), match); - } - - public static void FileDoesNotContain(MSBuildResult result, string filePath, string match) - { - if (result == null) - { - throw new ArgumentNullException(nameof(result)); - } - - filePath = Path.Combine(result.Project.DirectoryPath, filePath); - FileExists(result, filePath); - - var text = File.ReadAllText(filePath); - if (text.Contains(match)) - { - throw new FileContentFoundException(result, filePath, File.ReadAllText(filePath), match); - } - } - - public static void FileContentEquals(MSBuildResult result, string filePath, string expected) - { - if (result == null) - { - throw new ArgumentNullException(nameof(result)); - } - - filePath = Path.Combine(result.Project.DirectoryPath, filePath); - FileExists(result, filePath); - - var actual = File.ReadAllText(filePath); - if (!actual.Equals(expected, StringComparison.Ordinal)) - { - throw new FileContentNotEqualException(result, filePath, expected, actual); - } - } - - public static void FileHashEquals(MSBuildResult result, string filePath, string expectedSha256Base64) - { - if (result == null) - { - throw new ArgumentNullException(nameof(result)); - } - - filePath = Path.Combine(result.Project.DirectoryPath, filePath); - FileExists(result, filePath); - - var actual = File.ReadAllBytes(filePath); - using var algorithm = SHA256.Create(); - var actualSha256 = algorithm.ComputeHash(actual); - var actualSha256Base64 = Convert.ToBase64String(actualSha256); - Assert.Equal(expectedSha256Base64, actualSha256Base64); - } - - public static void FileEquals(MSBuildResult result, string expected, string actual) - { - if (result == null) - { - throw new ArgumentNullException(nameof(result)); - } - - expected = Path.Combine(result.Project.DirectoryPath, expected); - actual = Path.Combine(result.Project.DirectoryPath, actual); - FileExists(result, expected); - FileExists(result, actual); - - if (!Enumerable.SequenceEqual(File.ReadAllBytes(expected), File.ReadAllBytes(actual))) - { - throw new FilesNotEqualException(result, expected, actual); - } - } - - public static void FileContainsLine(MSBuildResult result, string filePath, string match) - { - if (result == null) - { - throw new ArgumentNullException(nameof(result)); - } - - filePath = Path.Combine(result.Project.DirectoryPath, filePath); - FileExists(result, filePath); - - var lines = File.ReadAllLines(filePath); - for (var i = 0; i < lines.Length; i++) - { - var line = lines[i].Trim(); - if (line == match) - { - return; - } - } - - throw new FileContentMissingException(result, filePath, File.ReadAllText(filePath), match); - } - - public static void FileDoesNotContainLine(MSBuildResult result, string filePath, string match) - { - if (result == null) - { - throw new ArgumentNullException(nameof(result)); - } - - filePath = Path.Combine(result.Project.DirectoryPath, filePath); - FileExists(result, filePath); - - var lines = File.ReadAllLines(filePath); - for (var i = 0; i < lines.Length; i++) - { - var line = lines[i].Trim(); - if (line == match) - { - throw new FileContentFoundException(result, filePath, File.ReadAllText(filePath), match); - } - } - } - - public static string FileExists(MSBuildResult result, params string[] paths) - { - if (result == null) - { - throw new ArgumentNullException(nameof(result)); - } - - var filePath = Path.Combine(result.Project.DirectoryPath, Path.Combine(paths)); - if (!File.Exists(filePath)) - { - throw new FileMissingException(result, filePath); - } - - return filePath; - } - - public static void FileCountEquals(MSBuildResult result, int expected, string directoryPath, string searchPattern, SearchOption searchOption = SearchOption.AllDirectories) - { - if (result == null) - { - throw new ArgumentNullException(nameof(result)); - } - - if (directoryPath == null) - { - throw new ArgumentNullException(nameof(directoryPath)); - } - - if (searchPattern == null) - { - throw new ArgumentNullException(nameof(searchPattern)); - } - - directoryPath = Path.Combine(result.Project.DirectoryPath, directoryPath); - - if (Directory.Exists(directoryPath)) - { - var files = Directory.GetFiles(directoryPath, searchPattern, searchOption); - if (files.Length != expected) - { - throw new FileCountException(result, expected, directoryPath, searchPattern, files); - } - } - else if (expected > 0) - { - // directory doesn't exist, that's OK if we expected to find nothing. - throw new FileCountException(result, expected, directoryPath, searchPattern, Array.Empty<string>()); - } - } - - public static void FileDoesNotExist(MSBuildResult result, params string[] paths) - { - if (result == null) - { - throw new ArgumentNullException(nameof(result)); - } - - var filePath = Path.Combine(result.Project.DirectoryPath, Path.Combine(paths)); - if (File.Exists(filePath)) - { - throw new FileFoundException(result, filePath); - } - } - - public static void NuspecContains(MSBuildResult result, string nuspecPath, string expected) - { - if (result == null) - { - throw new ArgumentNullException(nameof(result)); - } - - if (nuspecPath == null) - { - throw new ArgumentNullException(nameof(nuspecPath)); - } - - if (expected == null) - { - throw new ArgumentNullException(nameof(expected)); - } - - nuspecPath = Path.Combine(result.Project.DirectoryPath, nuspecPath); - FileExists(result, nuspecPath); - - var content = File.ReadAllText(nuspecPath); - if (!content.Contains(expected)) - { - throw new NuspecException(result, nuspecPath, content, expected); - } - } - - public static void NuspecDoesNotContain(MSBuildResult result, string nuspecPath, string expected) - { - if (result == null) - { - throw new ArgumentNullException(nameof(result)); - } - - if (nuspecPath == null) - { - throw new ArgumentNullException(nameof(nuspecPath)); - } - - if (expected == null) - { - throw new ArgumentNullException(nameof(expected)); - } - - nuspecPath = Path.Combine(result.Project.DirectoryPath, nuspecPath); - FileExists(result, nuspecPath); - - var content = File.ReadAllText(nuspecPath); - if (content.Contains(expected)) - { - throw new NuspecFoundException(result, nuspecPath, content, expected); - } - } - - // This method extracts the nupkg to a fixed directory path. To avoid the extra work of - // cleaning up after each invocation, this method accepts multiple files. - public static void NupkgContains(MSBuildResult result, string nupkgPath, params string[] filePaths) - { - if (result == null) - { - throw new ArgumentNullException(nameof(result)); - } - - if (nupkgPath == null) - { - throw new ArgumentNullException(nameof(nupkgPath)); - } - - if (filePaths == null) - { - throw new ArgumentNullException(nameof(filePaths)); - } - - nupkgPath = Path.Combine(result.Project.DirectoryPath, nupkgPath); - FileExists(result, nupkgPath); - - var unzipped = Path.Combine(result.Project.DirectoryPath, Path.GetFileNameWithoutExtension(nupkgPath)); - ZipFile.ExtractToDirectory(nupkgPath, unzipped); - - foreach (var filePath in filePaths) - { - if (!File.Exists(Path.Combine(unzipped, filePath))) - { - throw new NupkgFileMissingException(result, nupkgPath, filePath); - } - } - } - - // This method extracts the nupkg to a fixed directory path. To avoid the extra work of - // cleaning up after each invocation, this method accepts multiple files. - public static void NupkgDoesNotContain(MSBuildResult result, string nupkgPath, params string[] filePaths) - { - if (result == null) - { - throw new ArgumentNullException(nameof(result)); - } - - if (nupkgPath == null) - { - throw new ArgumentNullException(nameof(nupkgPath)); - } - - if (filePaths == null) - { - throw new ArgumentNullException(nameof(filePaths)); - } - - nupkgPath = Path.Combine(result.Project.DirectoryPath, nupkgPath); - FileExists(result, nupkgPath); - - var unzipped = Path.Combine(result.Project.DirectoryPath, Path.GetFileNameWithoutExtension(nupkgPath)); - ZipFile.ExtractToDirectory(nupkgPath, unzipped); - - foreach (var filePath in filePaths) - { - if (File.Exists(Path.Combine(unzipped, filePath))) - { - throw new NupkgFileFoundException(result, nupkgPath, filePath); - } - } - } - - public static void AssemblyContainsType(MSBuildResult result, string assemblyPath, string fullTypeName) - { - if (result == null) - { - throw new ArgumentNullException(nameof(result)); - } - - assemblyPath = Path.Combine(result.Project.DirectoryPath, Path.Combine(assemblyPath)); - - var typeNames = GetDeclaredTypeNames(assemblyPath); - Assert.Contains(fullTypeName, typeNames); - } - - public static void AssemblyDoesNotContainType(MSBuildResult result, string assemblyPath, string fullTypeName) - { - if (result == null) - { - throw new ArgumentNullException(nameof(result)); - } - - assemblyPath = Path.Combine(result.Project.DirectoryPath, Path.Combine(assemblyPath)); - - var typeNames = GetDeclaredTypeNames(assemblyPath); - Assert.DoesNotContain(fullTypeName, typeNames); - } - - private static IEnumerable<string> GetDeclaredTypeNames(string assemblyPath) - { - using (var file = File.OpenRead(assemblyPath)) - { - using var peReader = new PEReader(file); - var metadataReader = peReader.GetMetadataReader(); - return metadataReader.TypeDefinitions.Where(t => !t.IsNil).Select(t => - { - var type = metadataReader.GetTypeDefinition(t); - return metadataReader.GetString(type.Namespace) + "." + metadataReader.GetString(type.Name); - }).ToArray(); - } - } - - public static void AssemblyContainsResource(MSBuildResult result, string assemblyPath, string resourceName) - { - if (result == null) - { - throw new ArgumentNullException(nameof(result)); - } - - assemblyPath = Path.Combine(result.Project.DirectoryPath, Path.Combine(assemblyPath)); - - var resources = GetAssemblyResourceNames(assemblyPath); - Assert.Contains(resourceName, resources); - } - - public static void AssemblyDoesNotContainResource(MSBuildResult result, string assemblyPath, string resourceName) - { - if (result == null) - { - throw new ArgumentNullException(nameof(result)); - } - - assemblyPath = Path.Combine(result.Project.DirectoryPath, Path.Combine(assemblyPath)); - - var resources = GetAssemblyResourceNames(assemblyPath); - Assert.DoesNotContain(resourceName, resources); - } - - private static IEnumerable<string> GetAssemblyResourceNames(string assemblyPath) - { - using var file = File.OpenRead(assemblyPath); - using var peReader = new PEReader(file); - var metadataReader = peReader.GetMetadataReader(); - return metadataReader.ManifestResources.Where(r => !r.IsNil).Select(r => - { - var resource = metadataReader.GetManifestResource(r); - return metadataReader.GetString(resource.Name); - }).ToArray(); - } - - public static void AssemblyHasAttribute(MSBuildResult result, string assemblyPath, string fullTypeName) - { - if (result == null) - { - throw new ArgumentNullException(nameof(result)); - } - - assemblyPath = Path.Combine(result.Project.DirectoryPath, Path.Combine(assemblyPath)); - - var typeNames = GetAssemblyAttributes(assemblyPath); - Assert.Contains(fullTypeName, typeNames); - } - - private static IEnumerable<string> GetAssemblyAttributes(string assemblyPath) - { - using (var file = File.OpenRead(assemblyPath)) - { - var peReader = new PEReader(file); - var metadataReader = peReader.GetMetadataReader(); - return metadataReader.CustomAttributes.Where(t => !t.IsNil).Select(t => - { - var attribute = metadataReader.GetCustomAttribute(t); - var constructor = metadataReader.GetMemberReference((MemberReferenceHandle)attribute.Constructor); - var type = metadataReader.GetTypeReference((TypeReferenceHandle)constructor.Parent); - - return metadataReader.GetString(type.Namespace) + "." + metadataReader.GetString(type.Name); - }).ToArray(); - } - } - - private abstract class MSBuildXunitException : Xunit.Sdk.XunitException - { - protected MSBuildXunitException(MSBuildResult result) - { - Result = result; - } - - protected abstract string Heading { get; } - - public MSBuildResult Result { get; } - - public override string Message - { - get - { - var message = new StringBuilder(); - message.AppendLine(Heading); - message.Append(Result.FileName); - message.Append(" "); - message.Append(Result.Arguments); - message.AppendLine(); - message.AppendLine(); - message.Append(Result.Output); - message.AppendLine(); - message.Append("Exit Code:"); - message.Append(Result.ExitCode); - return message.ToString(); - } - } - } - - private class BuildErrorMissingException : MSBuildXunitException - { - public BuildErrorMissingException(MSBuildResult result, string errorCode, string location) - : base(result) - { - ErrorCode = errorCode; - Location = location; - } - - public string ErrorCode { get; } - - public string Location { get; } - - protected override string Heading - { - get - { - return - $"Error code '{ErrorCode}' was not found." + Environment.NewLine + - $"Looking for '{Location ?? ".*"}: error {ErrorCode}: .*'"; - } - } - } - - private class BuildFailedException : MSBuildXunitException - { - public BuildFailedException(MSBuildResult result) - : base(result) - { - } - - protected override string Heading => "Build failed."; - } - - private class BuildWarningsException : MSBuildXunitException - { - public BuildWarningsException(MSBuildResult result, IEnumerable<string> warnings) - : base(result) - { - Warnings = warnings.ToList(); - } - - public List<string> Warnings { get; } - - protected override string Heading => "Build contains unexpected warnings: " + string.Join(Environment.NewLine, Warnings); - } - - private class BuildPassedException : MSBuildXunitException - { - public BuildPassedException(MSBuildResult result) - : base(result) - { - } - - protected override string Heading => "Build should have failed, but it passed."; - } - - private class BuildOutputMissingException : MSBuildXunitException - { - public BuildOutputMissingException(MSBuildResult result, string match) - : base(result) - { - Match = match; - } - - public string Match { get; } - - protected override string Heading => $"Build did not contain the line: '{Match}'."; - } - - private class BuildOutputContainsLineException : MSBuildXunitException - { - public BuildOutputContainsLineException(MSBuildResult result, string match) - : base(result) - { - Match = match; - } - - public string Match { get; } - - protected override string Heading => $"Build output contains the line: '{Match}'."; - } - - private class FileContentFoundException : MSBuildXunitException - { - public FileContentFoundException(MSBuildResult result, string filePath, string content, string match) - : base(result) - { - FilePath = filePath; - Content = content; - Match = match; - } - - public string Content { get; } - - public string FilePath { get; } - - public string Match { get; } - - protected override string Heading - { - get - { - var builder = new StringBuilder(); - builder.AppendFormat("File content of '{0}' should not contain line: '{1}'.", FilePath, Match); - builder.AppendLine(); - builder.AppendLine(); - builder.AppendLine(Content); - return builder.ToString(); - } - } - } - - private class FileContentMissingException : MSBuildXunitException - { - public FileContentMissingException(MSBuildResult result, string filePath, string content, string match) - : base(result) - { - FilePath = filePath; - Content = content; - Match = match; - } - - public string Content { get; } - - public string FilePath { get; } - - public string Match { get; } - - protected override string Heading - { - get - { - var builder = new StringBuilder(); - builder.AppendFormat("File content of '{0}' did not contain the line: '{1}'.", FilePath, Match); - builder.AppendLine(); - builder.AppendLine(); - builder.AppendLine(Content); - return builder.ToString(); - } - } - } - - private class FileContentNotEqualException : MSBuildXunitException - { - public FileContentNotEqualException(MSBuildResult result, string filePath, string expected, string actual) - : base(result) - { - FilePath = filePath; - Expected = expected; - Actual = actual; - } - - public string Actual { get; } - - public string FilePath { get; } - - public string Expected { get; } - - protected override string Heading - { - get - { - var builder = new StringBuilder(); - builder.AppendFormat("File content of '{0}' did not match the expected content: '{1}'.", FilePath, Expected); - builder.AppendLine(); - builder.AppendLine(); - builder.AppendLine(Actual); - return builder.ToString(); - } - } - } - - private class FilesNotEqualException : MSBuildXunitException - { - public FilesNotEqualException(MSBuildResult result, string expected, string actual) - : base(result) - { - Expected = expected; - Actual = actual; - } - - public string Actual { get; } - - public string Expected { get; } - - protected override string Heading - { - get - { - var builder = new StringBuilder(); - builder.AppendFormat("File content of '{0}' did not match the contents of '{1}'.", Expected, Actual); - builder.AppendLine(); - builder.AppendLine(); - builder.AppendLine(Actual); - return builder.ToString(); - } - } - } - - private class FileMissingException : MSBuildXunitException - { - public FileMissingException(MSBuildResult result, string filePath) - : base(result) - { - FilePath = filePath; - } - - public string FilePath { get; } - - protected override string Heading => $"File: '{FilePath}' was not found."; - } - - private class FileCountException : MSBuildXunitException - { - public FileCountException(MSBuildResult result, int expected, string directoryPath, string searchPattern, string[] files) - : base(result) - { - Expected = expected; - DirectoryPath = directoryPath; - SearchPattern = searchPattern; - Files = files; - } - - public string DirectoryPath { get; } - - public int Expected { get; } - - public string[] Files { get; } - - public string SearchPattern { get; } - - protected override string Heading - { - get - { - var heading = new StringBuilder(); - heading.AppendLine($"Expected {Expected} files matching {SearchPattern} in {DirectoryPath}, found {Files.Length}."); - - if (Files.Length > 0) - { - heading.AppendLine("Files:"); - - foreach (var file in Files) - { - heading.Append("\t"); - heading.Append(file); - } - - heading.AppendLine(); - } - - return heading.ToString(); - } - } - } - - private class FileFoundException : MSBuildXunitException - { - public FileFoundException(MSBuildResult result, string filePath) - : base(result) - { - FilePath = filePath; - } - - public string FilePath { get; } - - protected override string Heading => $"File: '{FilePath}' was found, but should not exist."; - } - - private class NuspecException : MSBuildXunitException - { - public NuspecException(MSBuildResult result, string filePath, string content, string expected) - : base(result) - { - FilePath = filePath; - Content = content; - Expected = expected; - } - - public string Content { get; } - - public string Expected { get; } - - public string FilePath { get; } - - protected override string Heading - { - get - { - return - $"nuspec: '{FilePath}' did not contain the expected content." + Environment.NewLine + - Environment.NewLine + - $"expected: {Expected}" + Environment.NewLine + - Environment.NewLine + - $"actual: {Content}"; - } - } - } - - private class NuspecFoundException : MSBuildXunitException - { - public NuspecFoundException(MSBuildResult result, string filePath, string content, string expected) - : base(result) - { - FilePath = filePath; - Content = content; - Expected = expected; - } - - public string Content { get; } - - public string Expected { get; } - - public string FilePath { get; } - - protected override string Heading - { - get - { - return - $"nuspec: '{FilePath}' should not contain the content {Expected}." + - Environment.NewLine + - $"actual content: {Content}"; - } - } - } - - private class NupkgFileMissingException : MSBuildXunitException - { - public NupkgFileMissingException(MSBuildResult result, string nupkgPath, string filePath) - : base(result) - { - NupkgPath = nupkgPath; - FilePath = filePath; - } - - public string FilePath { get; } - - public string NupkgPath { get; } - - protected override string Heading => $"File: '{FilePath}' was not found was not found in {NupkgPath}."; - } - - private class NupkgFileFoundException : MSBuildXunitException - { - public NupkgFileFoundException(MSBuildResult result, string nupkgPath, string filePath) - : base(result) - { - NupkgPath = nupkgPath; - FilePath = filePath; - } - - public string FilePath { get; } - - public string NupkgPath { get; } - - protected override string Heading => $"File: '{FilePath}' was found in {NupkgPath}."; - } - } -} diff --git a/src/Components/WebAssembly/Build/test/BuildIntegrationTests/BuildCompressionTests.cs b/src/Components/WebAssembly/Build/test/BuildIntegrationTests/BuildCompressionTests.cs deleted file mode 100644 index 397d32bd61..0000000000 --- a/src/Components/WebAssembly/Build/test/BuildIntegrationTests/BuildCompressionTests.cs +++ /dev/null @@ -1,396 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.IO; -using System.Linq; -using System.Threading.Tasks; -using Xunit; - -namespace Microsoft.AspNetCore.Components.WebAssembly.Build -{ - public class BuildCompressionTests - { - [Fact] - public async Task Build_WithLinkerAndCompression_IsIncremental() - { - // Arrange - using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" }); - var result = await MSBuildProcessManager.DotnetMSBuild(project); - - Assert.BuildPassed(result); - - var buildOutputDirectory = project.BuildOutputDirectory; - - // Act - var compressedFilesFolder = Path.Combine(project.IntermediateOutputDirectory, "compressed"); - var thumbPrint = FileThumbPrint.CreateFolderThumbprint(project, compressedFilesFolder); - - // Assert - for (var i = 0; i < 3; i++) - { - result = await MSBuildProcessManager.DotnetMSBuild(project); - Assert.BuildPassed(result); - - var newThumbPrint = FileThumbPrint.CreateFolderThumbprint(project, compressedFilesFolder); - Assert.Equal(thumbPrint.Count, newThumbPrint.Count); - for (var j = 0; j < thumbPrint.Count; j++) - { - Assert.Equal(thumbPrint[j], newThumbPrint[j]); - } - } - } - - [Fact] - public async Task Build_WithLinkerAndCompression_UpdatesFilesWhenSourcesChange() - { - // Arrange - using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" }); - var result = await MSBuildProcessManager.DotnetMSBuild(project); - - Assert.BuildPassed(result); - - var mainAppDll = Path.Combine(project.DirectoryPath, project.BuildOutputDirectory, "wwwroot", "_framework", "_bin", "standalone.dll"); - var mainAppDllThumbPrint = FileThumbPrint.Create(mainAppDll); - var mainAppCompressedDll = Path.Combine(project.DirectoryPath, project.BuildOutputDirectory, "wwwroot", "_framework", "_bin", "standalone.dll.gz"); - var mainAppCompressedDllThumbPrint = FileThumbPrint.Create(mainAppCompressedDll); - - var blazorBootJson = Path.Combine(project.DirectoryPath, project.BuildOutputDirectory, "wwwroot", "_framework", "blazor.boot.json"); - var blazorBootJsonThumbPrint = FileThumbPrint.Create(blazorBootJson); - var blazorBootJsonCompressed = Path.Combine(project.DirectoryPath, project.BuildOutputDirectory, "wwwroot", "_framework", "blazor.boot.json.gz"); - var blazorBootJsonCompressedThumbPrint = FileThumbPrint.Create(blazorBootJsonCompressed); - - // Act - var programFile = Path.Combine(project.DirectoryPath, "Program.cs"); - var programFileContents = File.ReadAllText(programFile); - File.WriteAllText(programFile, programFileContents.Replace("args", "arguments")); - result = await MSBuildProcessManager.DotnetMSBuild(project); - - // Assert - Assert.BuildPassed(result); - var newMainAppDllThumbPrint = FileThumbPrint.Create(mainAppDll); - var newMainAppCompressedDllThumbPrint = FileThumbPrint.Create(mainAppCompressedDll); - var newBlazorBootJsonThumbPrint = FileThumbPrint.Create(blazorBootJson); - var newBlazorBootJsonCompressedThumbPrint = FileThumbPrint.Create(blazorBootJsonCompressed); - - Assert.NotEqual(mainAppDllThumbPrint, newMainAppDllThumbPrint); - Assert.NotEqual(mainAppCompressedDllThumbPrint, newMainAppCompressedDllThumbPrint); - - Assert.NotEqual(blazorBootJsonThumbPrint, newBlazorBootJsonThumbPrint); - Assert.NotEqual(blazorBootJsonCompressedThumbPrint, newBlazorBootJsonCompressedThumbPrint); - } - - [Fact] - public async Task Build_WithoutLinkerAndCompression_IsIncremental() - { - // Arrange - using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" }); - var result = await MSBuildProcessManager.DotnetMSBuild(project, args: "/p:BlazorWebAssemblyEnableLinking=false"); - - Assert.BuildPassed(result); - - var buildOutputDirectory = project.BuildOutputDirectory; - - // Act - var compressedFilesFolder = Path.Combine(project.IntermediateOutputDirectory, "compressed"); - var thumbPrint = FileThumbPrint.CreateFolderThumbprint(project, compressedFilesFolder); - - // Assert - for (var i = 0; i < 3; i++) - { - result = await MSBuildProcessManager.DotnetMSBuild(project, args: "/p:BlazorWebAssemblyEnableLinking=false"); - Assert.BuildPassed(result); - - var newThumbPrint = FileThumbPrint.CreateFolderThumbprint(project, compressedFilesFolder); - Assert.Equal(thumbPrint.Count, newThumbPrint.Count); - for (var j = 0; j < thumbPrint.Count; j++) - { - Assert.Equal(thumbPrint[j], newThumbPrint[j]); - } - } - } - - [Fact] - public async Task Build_WithoutLinkerAndCompression_UpdatesFilesWhenSourcesChange() - { - // Arrange - using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" }); - var result = await MSBuildProcessManager.DotnetMSBuild(project, args: "/p:BlazorWebAssemblyEnableLinking=false"); - - // Act - var mainAppDll = Path.Combine(project.DirectoryPath, project.BuildOutputDirectory, "wwwroot", "_framework", "_bin", "standalone.dll"); - var mainAppDllThumbPrint = FileThumbPrint.Create(mainAppDll); - - var mainAppCompressedDll = Path.Combine(project.DirectoryPath, project.BuildOutputDirectory, "wwwroot", "_framework", "_bin", "standalone.dll.gz"); - var mainAppCompressedDllThumbPrint = FileThumbPrint.Create(mainAppCompressedDll); - - var programFile = Path.Combine(project.DirectoryPath, "Program.cs"); - var programFileContents = File.ReadAllText(programFile); - File.WriteAllText(programFile, programFileContents.Replace("args", "arguments")); - - // Assert - result = await MSBuildProcessManager.DotnetMSBuild(project, args: "/p:BlazorWebAssemblyEnableLinking=false"); - Assert.BuildPassed(result); - var newMainAppDllThumbPrint = FileThumbPrint.Create(mainAppDll); - var newMainAppCompressedDllThumbPrint = FileThumbPrint.Create(mainAppCompressedDll); - - Assert.NotEqual(mainAppDllThumbPrint, newMainAppDllThumbPrint); - Assert.NotEqual(mainAppCompressedDllThumbPrint, newMainAppCompressedDllThumbPrint); - } - - [Fact] - public async Task Build_CompressesAllFrameworkFiles() - { - // Arrange - using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" }); - var result = await MSBuildProcessManager.DotnetMSBuild(project); - - Assert.BuildPassed(result); - - var buildOutputDirectory = project.BuildOutputDirectory; - - var extensions = new[] { ".dll", ".js", ".pdb", ".wasm", ".map", ".json", ".dat" }; - // Act - var compressedFilesPath = Path.Combine( - project.DirectoryPath, - project.IntermediateOutputDirectory, - "compressed", - "_framework"); - var compressedFiles = Directory.EnumerateFiles( - compressedFilesPath, - "*", - SearchOption.AllDirectories) - .Where(f => Path.GetExtension(f) == ".gz") - .Select(f => Path.GetRelativePath(compressedFilesPath, f[0..^3])) - .OrderBy(f => f) - .ToArray(); - - var frameworkFilesPath = Path.Combine( - project.DirectoryPath, - project.BuildOutputDirectory, - "wwwroot", - "_framework"); - var frameworkFiles = Directory.EnumerateFiles( - frameworkFilesPath, - "*", - SearchOption.AllDirectories) - .Where(f => extensions.Contains(Path.GetExtension(f))) - .Select(f => Path.GetRelativePath(frameworkFilesPath, f)) - .OrderBy(f => f) - .ToArray(); - - Assert.Equal(frameworkFiles.Length, compressedFiles.Length); - Assert.Equal(frameworkFiles, compressedFiles); - - var brotliFiles = Directory.EnumerateFiles( - compressedFilesPath, - "*", - SearchOption.AllDirectories) - .Where(f => Path.GetExtension(f) == ".br") - .Select(f => Path.GetRelativePath(compressedFilesPath, f[0..^3])) - .OrderBy(f => f) - .ToArray(); - - // We don't compress things with brotli at build time - Assert.Empty(brotliFiles); - } - - [Fact] - public async Task Build_DisabledCompression_DoesNotCompressFiles() - { - // Arrange - using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" }); - - // Act - var result = await MSBuildProcessManager.DotnetMSBuild(project, args: "/p:BlazorEnableCompression=false"); - - //Assert - Assert.BuildPassed(result); - - var compressedFilesPath = Path.Combine( - project.DirectoryPath, - project.IntermediateOutputDirectory, - "compressed"); - - Assert.False(Directory.Exists(compressedFilesPath)); - } - - [Fact] - public async Task Publish_WithLinkerAndCompression_UpdatesFilesWhenSourcesChange() - { - // Arrange - using var project = ProjectDirectory.Create("blazorhosted", additionalProjects: new[] { "standalone", "razorclasslibrary" }); - project.TargetFramework = TestFacts.DefaultNetCoreTargetFramework; - var result = await MSBuildProcessManager.DotnetMSBuild(project, target: "publish"); - - Assert.BuildPassed(result); - - // Act - var mainAppDll = Path.Combine(project.DirectoryPath, project.PublishOutputDirectory, "wwwroot", "_framework", "_bin", "standalone.dll"); - var mainAppDllThumbPrint = FileThumbPrint.Create(mainAppDll); - var mainAppCompressedDll = Path.Combine(project.DirectoryPath, project.PublishOutputDirectory, "wwwroot", "_framework", "_bin", "standalone.dll.br"); - var mainAppCompressedDllThumbPrint = FileThumbPrint.Create(mainAppCompressedDll); - - var blazorBootJson = Path.Combine(project.DirectoryPath, project.PublishOutputDirectory, "wwwroot", "_framework", "blazor.boot.json"); - var blazorBootJsonThumbPrint = FileThumbPrint.Create(blazorBootJson); - var blazorBootJsonCompressed = Path.Combine(project.DirectoryPath, project.PublishOutputDirectory, "wwwroot", "_framework", "blazor.boot.json.br"); - var blazorBootJsonCompressedThumbPrint = FileThumbPrint.Create(blazorBootJsonCompressed); - - var programFile = Path.Combine(project.DirectoryPath, "..", "standalone", "Program.cs"); - var programFileContents = File.ReadAllText(programFile); - File.WriteAllText(programFile, programFileContents.Replace("args", "arguments")); - - // Assert - result = await MSBuildProcessManager.DotnetMSBuild(project, target: "publish"); - Assert.BuildPassed(result); - var newMainAppDllThumbPrint = FileThumbPrint.Create(mainAppDll); - var newMainAppCompressedDllThumbPrint = FileThumbPrint.Create(mainAppCompressedDll); - var newBlazorBootJsonThumbPrint = FileThumbPrint.Create(blazorBootJson); - var newBlazorBootJsonCompressedThumbPrint = FileThumbPrint.Create(blazorBootJsonCompressed); - - Assert.NotEqual(mainAppDllThumbPrint, newMainAppDllThumbPrint); - Assert.NotEqual(mainAppCompressedDllThumbPrint, newMainAppCompressedDllThumbPrint); - - Assert.NotEqual(blazorBootJsonThumbPrint, newBlazorBootJsonThumbPrint); - Assert.NotEqual(blazorBootJsonCompressedThumbPrint, newBlazorBootJsonCompressedThumbPrint); - } - - [Fact] - public async Task Publish_WithoutLinkerAndCompression_UpdatesFilesWhenSourcesChange() - { - // Arrange - using var project = ProjectDirectory.Create("blazorhosted", additionalProjects: new[] { "standalone", "razorclasslibrary" }); - project.TargetFramework = TestFacts.DefaultNetCoreTargetFramework; - var result = await MSBuildProcessManager.DotnetMSBuild(project, target: "publish", args: "/p:BlazorWebAssemblyEnableLinking=false"); - - Assert.BuildPassed(result); - - // Act - var mainAppDll = Path.Combine(project.DirectoryPath, project.PublishOutputDirectory, "wwwroot", "_framework", "_bin", "standalone.dll"); - var mainAppDllThumbPrint = FileThumbPrint.Create(mainAppDll); - - var mainAppCompressedDll = Path.Combine(project.DirectoryPath, project.PublishOutputDirectory, "wwwroot", "_framework", "_bin", "standalone.dll.br"); - var mainAppCompressedDllThumbPrint = FileThumbPrint.Create(mainAppCompressedDll); - - var programFile = Path.Combine(project.DirectoryPath, "..", "standalone", "Program.cs"); - var programFileContents = File.ReadAllText(programFile); - File.WriteAllText(programFile, programFileContents.Replace("args", "arguments")); - - // Assert - result = await MSBuildProcessManager.DotnetMSBuild(project, target: "publish", args: "/p:BlazorWebAssemblyEnableLinking=false"); - Assert.BuildPassed(result); - var newMainAppDllThumbPrint = FileThumbPrint.Create(mainAppDll); - var newMainAppCompressedDllThumbPrint = FileThumbPrint.Create(mainAppCompressedDll); - - Assert.NotEqual(mainAppDllThumbPrint, newMainAppDllThumbPrint); - Assert.NotEqual(mainAppCompressedDllThumbPrint, newMainAppCompressedDllThumbPrint); - } - - [Fact] - public async Task Publish_WithLinkerAndCompression_IsIncremental() - { - // Arrange - using var project = ProjectDirectory.Create("blazorhosted", additionalProjects: new[] { "standalone", "razorclasslibrary" }); - var result = await MSBuildProcessManager.DotnetMSBuild(project, target: "publish"); - - Assert.BuildPassed(result); - - var buildOutputDirectory = project.BuildOutputDirectory; - - // Act - var compressedFilesFolder = Path.Combine("..", "standalone", project.IntermediateOutputDirectory, "compressed"); - var thumbPrint = FileThumbPrint.CreateFolderThumbprint(project, compressedFilesFolder); - - // Assert - for (var i = 0; i < 3; i++) - { - result = await MSBuildProcessManager.DotnetMSBuild(project); - Assert.BuildPassed(result); - - var newThumbPrint = FileThumbPrint.CreateFolderThumbprint(project, compressedFilesFolder); - Assert.Equal(thumbPrint.Count, newThumbPrint.Count); - for (var j = 0; j < thumbPrint.Count; j++) - { - Assert.Equal(thumbPrint[j], newThumbPrint[j]); - } - } - } - - [Fact] - public async Task Publish_WithoutLinkerAndCompression_IsIncremental() - { - // Arrange - using var project = ProjectDirectory.Create("blazorhosted", additionalProjects: new[] { "standalone", "razorclasslibrary" }); - var result = await MSBuildProcessManager.DotnetMSBuild(project, target: "publish", args: "/p:BlazorWebAssemblyEnableLinking=false"); - - Assert.BuildPassed(result); - - var buildOutputDirectory = project.BuildOutputDirectory; - - // Act - var compressedFilesFolder = Path.Combine("..", "standalone", project.IntermediateOutputDirectory, "compressed"); - var thumbPrint = FileThumbPrint.CreateFolderThumbprint(project, compressedFilesFolder); - - // Assert - for (var i = 0; i < 3; i++) - { - result = await MSBuildProcessManager.DotnetMSBuild(project, args: "/p:BlazorWebAssemblyEnableLinking=false"); - Assert.BuildPassed(result); - - var newThumbPrint = FileThumbPrint.CreateFolderThumbprint(project, compressedFilesFolder); - Assert.Equal(thumbPrint.Count, newThumbPrint.Count); - for (var j = 0; j < thumbPrint.Count; j++) - { - Assert.Equal(thumbPrint[j], newThumbPrint[j]); - } - } - } - - [Fact] - public async Task Publish_CompressesAllFrameworkFiles() - { - // Arrange - using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" }); - var result = await MSBuildProcessManager.DotnetMSBuild(project, target: "publish"); - - Assert.BuildPassed(result); - - var buildOutputDirectory = project.BuildOutputDirectory; - - var extensions = new[] { ".dll", ".js", ".pdb", ".wasm", ".map", ".json", ".dat" }; - // Act - var compressedFilesPath = Path.Combine( - project.DirectoryPath, - "..", - "standalone", - project.IntermediateOutputDirectory, - "compressed", - "_framework"); - var compressedFiles = Directory.EnumerateFiles( - compressedFilesPath, - "*", - SearchOption.AllDirectories) - .Where(f => Path.GetExtension(f) == ".br") - .Select(f => Path.GetRelativePath(compressedFilesPath, f[0..^3])) - .OrderBy(f => f) - .ToArray(); - - var frameworkFilesPath = Path.Combine( - project.DirectoryPath, - project.BuildOutputDirectory, - "wwwroot", - "_framework"); - var frameworkFiles = Directory.EnumerateFiles( - frameworkFilesPath, - "*", - SearchOption.AllDirectories) - .Where(f => extensions.Contains(Path.GetExtension(f))) - .Select(f => Path.GetRelativePath(frameworkFilesPath, f)) - .OrderBy(f => f) - .ToArray(); - - Assert.Equal(frameworkFiles.Length, compressedFiles.Length); - Assert.Equal(frameworkFiles, compressedFiles); - } - } -} diff --git a/src/Components/WebAssembly/Build/test/BuildIntegrationTests/BuildIncrementalismTest.cs b/src/Components/WebAssembly/Build/test/BuildIntegrationTests/BuildIncrementalismTest.cs deleted file mode 100644 index 46a85cdea1..0000000000 --- a/src/Components/WebAssembly/Build/test/BuildIntegrationTests/BuildIncrementalismTest.cs +++ /dev/null @@ -1,159 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.IO; -using System.Text.Json; -using System.Threading.Tasks; -using Xunit; - -namespace Microsoft.AspNetCore.Components.WebAssembly.Build -{ - public class BuildIncrementalismTest - { - [Fact] - public async Task Build_WithLinker_IsIncremental() - { - // Arrange - using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" }); - var result = await MSBuildProcessManager.DotnetMSBuild(project); - - Assert.BuildPassed(result); - - var buildOutputDirectory = project.BuildOutputDirectory; - - // Act - var thumbPrint = FileThumbPrint.CreateFolderThumbprint(project, project.BuildOutputDirectory); - - // Assert - for (var i = 0; i < 3; i++) - { - result = await MSBuildProcessManager.DotnetMSBuild(project); - Assert.BuildPassed(result); - - var newThumbPrint = FileThumbPrint.CreateFolderThumbprint(project, project.BuildOutputDirectory); - Assert.Equal(thumbPrint.Count, newThumbPrint.Count); - for (var j = 0; j < thumbPrint.Count; j++) - { - Assert.Equal(thumbPrint[j], newThumbPrint[j]); - } - } - } - - [Fact] - public async Task Build_SatelliteAssembliesFileIsPreserved() - { - // Arrange - using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" }); - File.Move(Path.Combine(project.DirectoryPath, "Resources.ja.resx.txt"), Path.Combine(project.DirectoryPath, "Resource.ja.resx")); - var result = await MSBuildProcessManager.DotnetMSBuild(project); - - Assert.BuildPassed(result); - - var satelliteAssemblyCacheFile = Path.Combine(project.IntermediateOutputDirectory, "blazor", "blazor.satelliteasm.props"); - var satelliteAssemblyFile = Path.Combine(project.BuildOutputDirectory, "wwwroot", "_framework", "_bin", "ja", "standalone.resources.dll"); - var bootJson = Path.Combine(project.DirectoryPath, project.BuildOutputDirectory, "wwwroot", "_framework", "blazor.boot.json"); - - // Assert - for (var i = 0; i < 3; i++) - { - result = await MSBuildProcessManager.DotnetMSBuild(project); - Assert.BuildPassed(result); - - Verify(); - } - - // Assert - incremental builds with BuildingProject=false - for (var i = 0; i < 3; i++) - { - result = await MSBuildProcessManager.DotnetMSBuild(project, args: "/p:BuildingProject=false"); - Assert.BuildPassed(result); - - Verify(); - } - - void Verify() - { - Assert.FileExists(result, satelliteAssemblyCacheFile); - Assert.FileExists(result, satelliteAssemblyFile); - - var bootJsonFile = JsonSerializer.Deserialize<GenerateBlazorBootJson.BootJsonData>(File.ReadAllText(bootJson), new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); - var satelliteResources = bootJsonFile.resources.satelliteResources; - var kvp = Assert.Single(satelliteResources); - Assert.Equal("ja", kvp.Key); - Assert.Equal("ja/standalone.resources.dll", Assert.Single(kvp.Value).Key); - } - } - - [Fact] - public async Task Build_SatelliteAssembliesFileIsCreated_IfNewFileIsAdded() - { - // Arrange - using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" }); - var result = await MSBuildProcessManager.DotnetMSBuild(project); - - Assert.BuildPassed(result); - - var satelliteAssemblyCacheFile = Path.Combine(project.IntermediateOutputDirectory, "blazor", "blazor.satelliteasm.props"); - var satelliteAssemblyFile = Path.Combine(project.BuildOutputDirectory, "wwwroot", "_framework", "_bin", "ja", "standalone.resources.dll"); - var bootJson = Path.Combine(project.DirectoryPath, project.BuildOutputDirectory, "wwwroot", "_framework", "blazor.boot.json"); - - result = await MSBuildProcessManager.DotnetMSBuild(project); - Assert.BuildPassed(result); - - Assert.FileDoesNotExist(result, satelliteAssemblyCacheFile); - Assert.FileDoesNotExist(result, satelliteAssemblyFile); - var bootJsonFile = JsonSerializer.Deserialize<GenerateBlazorBootJson.BootJsonData>(File.ReadAllText(bootJson), new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); - var satelliteResources = bootJsonFile.resources.satelliteResources; - Assert.Null(satelliteResources); - - File.Move(Path.Combine(project.DirectoryPath, "Resources.ja.resx.txt"), Path.Combine(project.DirectoryPath, "Resource.ja.resx")); - result = await MSBuildProcessManager.DotnetMSBuild(project); - Assert.BuildPassed(result); - - Assert.FileExists(result, satelliteAssemblyCacheFile); - Assert.FileExists(result, satelliteAssemblyFile); - bootJsonFile = JsonSerializer.Deserialize<GenerateBlazorBootJson.BootJsonData>(File.ReadAllText(bootJson), new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); - satelliteResources = bootJsonFile.resources.satelliteResources; - var kvp = Assert.Single(satelliteResources); - Assert.Equal("ja", kvp.Key); - Assert.Equal("ja/standalone.resources.dll", Assert.Single(kvp.Value).Key); - } - - [Fact] - public async Task Build_SatelliteAssembliesFileIsDeleted_IfAllSatelliteFilesAreRemoved() - { - // Arrange - using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" }); - File.Move(Path.Combine(project.DirectoryPath, "Resources.ja.resx.txt"), Path.Combine(project.DirectoryPath, "Resource.ja.resx")); - - var result = await MSBuildProcessManager.DotnetMSBuild(project); - - Assert.BuildPassed(result); - - var satelliteAssemblyCacheFile = Path.Combine(project.IntermediateOutputDirectory, "blazor", "blazor.satelliteasm.props"); - var satelliteAssemblyFile = Path.Combine(project.BuildOutputDirectory, "wwwroot", "_framework", "_bin", "ja", "standalone.resources.dll"); - var bootJson = Path.Combine(project.DirectoryPath, project.BuildOutputDirectory, "wwwroot", "_framework", "blazor.boot.json"); - - result = await MSBuildProcessManager.DotnetMSBuild(project); - Assert.BuildPassed(result); - - Assert.FileExists(result, satelliteAssemblyCacheFile); - Assert.FileExists(result, satelliteAssemblyFile); - var bootJsonFile = JsonSerializer.Deserialize<GenerateBlazorBootJson.BootJsonData>(File.ReadAllText(bootJson), new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); - var satelliteResources = bootJsonFile.resources.satelliteResources; - var kvp = Assert.Single(satelliteResources); - Assert.Equal("ja", kvp.Key); - Assert.Equal("ja/standalone.resources.dll", Assert.Single(kvp.Value).Key); - - - File.Delete(Path.Combine(project.DirectoryPath, "Resource.ja.resx")); - result = await MSBuildProcessManager.DotnetMSBuild(project); - Assert.BuildPassed(result); - - Assert.FileDoesNotExist(result, satelliteAssemblyCacheFile); - bootJsonFile = JsonSerializer.Deserialize<GenerateBlazorBootJson.BootJsonData>(File.ReadAllText(bootJson), new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); - satelliteResources = bootJsonFile.resources.satelliteResources; - Assert.Null(satelliteResources); - } - } -} diff --git a/src/Components/WebAssembly/Build/test/BuildIntegrationTests/BuildIntegrationTest.cs b/src/Components/WebAssembly/Build/test/BuildIntegrationTests/BuildIntegrationTest.cs deleted file mode 100644 index c9184b649d..0000000000 --- a/src/Components/WebAssembly/Build/test/BuildIntegrationTests/BuildIntegrationTest.cs +++ /dev/null @@ -1,361 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.IO; -using System.Text.Json; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Testing; -using Xunit; -using static Microsoft.AspNetCore.Components.WebAssembly.Build.WebAssemblyRuntimePackage; - -namespace Microsoft.AspNetCore.Components.WebAssembly.Build -{ - public class BuildIntegrationTest - { - [Fact] - public async Task Build_WithDefaultSettings_Works() - { - // Arrange - using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" }); - project.Configuration = "Debug"; - var result = await MSBuildProcessManager.DotnetMSBuild(project); - - Assert.BuildPassed(result); - - var buildOutputDirectory = project.BuildOutputDirectory; - - Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "blazor.boot.json"); - Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "blazor.webassembly.js"); - Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "wasm", "dotnet.wasm"); - Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "wasm", DotNetJsFileName); - Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "wasm", "dotnet.timezones.dat"); - Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "standalone.dll"); - Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "RazorClassLibrary.dll"); - Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "Microsoft.Extensions.Logging.Abstractions.dll"); // Verify dependencies are part of the output. - Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "standalone.pdb"); - Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "RazorClassLibrary.pdb"); - - var staticWebAssets = Assert.FileExists(result, buildOutputDirectory, "standalone.StaticWebAssets.xml"); - Assert.FileContains(result, staticWebAssets, Path.Combine("netstandard2.1", "wwwroot")); - } - - [Fact] - public async Task Build_InRelease_Works() - { - // Arrange - using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" }); - project.Configuration = "Release"; - var result = await MSBuildProcessManager.DotnetMSBuild(project); - - Assert.BuildPassed(result); - - var buildOutputDirectory = project.BuildOutputDirectory; - - Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "blazor.boot.json"); - Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "blazor.webassembly.js"); - Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "wasm", "dotnet.wasm"); - Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "wasm", DotNetJsFileName); - Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "wasm", "dotnet.timezones.dat"); - Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "standalone.dll"); - Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "RazorClassLibrary.dll"); - Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "Microsoft.Extensions.Logging.Abstractions.dll"); // Verify dependencies are part of the output. - Assert.FileDoesNotExist(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "standalone.pdb"); - Assert.FileDoesNotExist(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "RazorClassLibrary.pdb"); - - var staticWebAssets = Assert.FileExists(result, buildOutputDirectory, "standalone.StaticWebAssets.xml"); - Assert.FileContains(result, staticWebAssets, Path.Combine("netstandard2.1", "wwwroot")); - } - - [Fact] - public async Task Build_ProducesBootJsonDataWithExpectedContent() - { - // Arrange - using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" }); - project.Configuration = "Debug"; - var result = await MSBuildProcessManager.DotnetMSBuild(project); - - Assert.BuildPassed(result); - - var buildOutputDirectory = project.BuildOutputDirectory; - - var bootJsonPath = Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "blazor.boot.json"); - var bootJsonData = ReadBootJsonData(result, bootJsonPath); - - var runtime = bootJsonData.resources.runtime.Keys; - Assert.Contains(DotNetJsFileName, runtime); - Assert.Contains("dotnet.wasm", runtime); - Assert.Contains("dotnet.timezones.dat", runtime); - - var assemblies = bootJsonData.resources.assembly.Keys; - Assert.Contains("standalone.dll", assemblies); - Assert.Contains("RazorClassLibrary.dll", assemblies); - Assert.Contains("Microsoft.Extensions.Logging.Abstractions.dll", assemblies); - - var pdb = bootJsonData.resources.pdb.Keys; - Assert.Contains("standalone.pdb", pdb); - Assert.Contains("RazorClassLibrary.pdb", pdb); - - Assert.Null(bootJsonData.resources.satelliteResources); - } - - [Fact] - public async Task Build_InRelease_ProducesBootJsonDataWithExpectedContent() - { - // Arrange - using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" }); - project.Configuration = "Release"; - var result = await MSBuildProcessManager.DotnetMSBuild(project); - - Assert.BuildPassed(result); - - var buildOutputDirectory = project.BuildOutputDirectory; - - var bootJsonPath = Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "blazor.boot.json"); - var bootJsonData = ReadBootJsonData(result, bootJsonPath); - - var runtime = bootJsonData.resources.runtime.Keys; - Assert.Contains(DotNetJsFileName, runtime); - Assert.Contains("dotnet.wasm", runtime); - Assert.Contains("dotnet.timezones.dat", runtime); - - var assemblies = bootJsonData.resources.assembly.Keys; - Assert.Contains("standalone.dll", assemblies); - Assert.Contains("RazorClassLibrary.dll", assemblies); - Assert.Contains("Microsoft.Extensions.Logging.Abstractions.dll", assemblies); - - Assert.Null(bootJsonData.resources.pdb); - Assert.Null(bootJsonData.resources.satelliteResources); - } - - [Fact] - public async Task Build_WithBlazorEnableTimeZoneSupportDisabled_DoesNotCopyTimeZoneInfo() - { - // Arrange - using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" }); - project.Configuration = "Release"; - project.AddProjectFileContent( -@" -<PropertyGroup> - <BlazorEnableTimeZoneSupport>false</BlazorEnableTimeZoneSupport> -</PropertyGroup>"); - - var result = await MSBuildProcessManager.DotnetMSBuild(project); - - Assert.BuildPassed(result); - - var buildOutputDirectory = project.BuildOutputDirectory; - - var bootJsonPath = Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "blazor.boot.json"); - var bootJsonData = ReadBootJsonData(result, bootJsonPath); - - var runtime = bootJsonData.resources.runtime.Keys; - Assert.Contains("dotnet.wasm", runtime); - Assert.DoesNotContain("dotnet.timezones.dat", runtime); - - Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "wasm", "dotnet.wasm"); - Assert.FileDoesNotExist(result, buildOutputDirectory, "wwwroot", "_framework", "wasm", "dotnet.timezones.dat"); - } - - [Fact] - public async Task Build_Hosted_Works() - { - // Arrange - using var project = ProjectDirectory.Create("blazorhosted", additionalProjects: new[] { "standalone", "razorclasslibrary", }); - project.TargetFramework = TestFacts.DefaultNetCoreTargetFramework; - var result = await MSBuildProcessManager.DotnetMSBuild(project); - - Assert.BuildPassed(result); - - var buildOutputDirectory = project.BuildOutputDirectory; - - var path = Path.GetFullPath(Path.Combine(project.SolutionPath, "standalone", "bin", project.Configuration, "netstandard2.1", "standalone.dll")); - Assert.FileDoesNotExist(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "standalone.dll"); - - var staticWebAssets = Assert.FileExists(result, buildOutputDirectory, "blazorhosted.StaticWebAssets.xml"); - Assert.FileContains(result, staticWebAssets, Path.Combine("netstandard2.1", "wwwroot")); - Assert.FileContains(result, staticWebAssets, Path.Combine("razorclasslibrary", "wwwroot")); - Assert.FileContains(result, staticWebAssets, Path.Combine("standalone", "wwwroot")); - } - - [Fact] - public async Task Build_WithLinkOnBuildDisabled_Works() - { - // Arrange - using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" }); - project.AddProjectFileContent( -@"<PropertyGroup> - <BlazorWebAssemblyEnableLinking>false</BlazorWebAssemblyEnableLinking> -</PropertyGroup>"); - - var result = await MSBuildProcessManager.DotnetMSBuild(project); - - Assert.BuildPassed(result); - - var buildOutputDirectory = project.BuildOutputDirectory; - - Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "blazor.boot.json"); - Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "blazor.webassembly.js"); - Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "wasm", "dotnet.wasm"); - Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "wasm", DotNetJsFileName); - Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "wasm", "dotnet.timezones.dat"); - - Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "standalone.dll"); - Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "Microsoft.Extensions.Logging.Abstractions.dll"); // Verify dependencies are part of the output. - } - - [Fact] - [QuarantinedTest] - public async Task Build_SatelliteAssembliesAreCopiedToBuildOutput() - { - // Arrange - using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary", "classlibrarywithsatelliteassemblies" }); - project.AddProjectFileContent( -@" -<PropertyGroup> - <DefineConstants>$(DefineConstants);REFERENCE_classlibrarywithsatelliteassemblies</DefineConstants> -</PropertyGroup> -<ItemGroup> - <ProjectReference Include=""..\classlibrarywithsatelliteassemblies\classlibrarywithsatelliteassemblies.csproj"" /> -</ItemGroup>"); - var resxfileInProject = Path.Combine(project.DirectoryPath, "Resources.ja.resx.txt"); - File.Move(resxfileInProject, Path.Combine(project.DirectoryPath, "Resource.ja.resx")); - - var result = await MSBuildProcessManager.DotnetMSBuild(project, args: "/restore"); - - Assert.BuildPassed(result); - - var buildOutputDirectory = project.BuildOutputDirectory; - - Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "standalone.dll"); - Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "classlibrarywithsatelliteassemblies.dll"); - Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "Microsoft.CodeAnalysis.CSharp.dll"); - Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "fr", "Microsoft.CodeAnalysis.CSharp.resources.dll"); // Verify satellite assemblies are present in the build output. - - var bootJsonPath = Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "blazor.boot.json"); - Assert.FileContains(result, bootJsonPath, "\"Microsoft.CodeAnalysis.CSharp.dll\""); - Assert.FileContains(result, bootJsonPath, "\"fr\\/Microsoft.CodeAnalysis.CSharp.resources.dll\""); - } - - [Fact] - public async Task Build_WithBlazorWebAssemblyEnableLinkingFalse_SatelliteAssembliesAreCopiedToBuildOutput() - { - // Arrange - using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary", "classlibrarywithsatelliteassemblies" }); - project.AddProjectFileContent( -@" -<PropertyGroup> - <BlazorWebAssemblyEnableLinking>false</BlazorWebAssemblyEnableLinking> - <DefineConstants>$(DefineConstants);REFERENCE_classlibrarywithsatelliteassemblies</DefineConstants> -</PropertyGroup> -<ItemGroup> - <ProjectReference Include=""..\classlibrarywithsatelliteassemblies\classlibrarywithsatelliteassemblies.csproj"" /> -</ItemGroup>"); - - var resxfileInProject = Path.Combine(project.DirectoryPath, "Resources.ja.resx.txt"); - File.Move(resxfileInProject, Path.Combine(project.DirectoryPath, "Resource.ja.resx")); - - var result = await MSBuildProcessManager.DotnetMSBuild(project, args: "/restore"); - - Assert.BuildPassed(result); - - var buildOutputDirectory = project.BuildOutputDirectory; - - Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "standalone.dll"); - Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "classlibrarywithsatelliteassemblies.dll"); - Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "Microsoft.CodeAnalysis.CSharp.dll"); - Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "fr", "Microsoft.CodeAnalysis.CSharp.resources.dll"); // Verify satellite assemblies are present in the build output. - - var bootJson = ReadBootJsonData(result, Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "blazor.boot.json")); - - var satelliteResources = bootJson.resources.satelliteResources; - Assert.NotNull(satelliteResources); - - Assert.Contains("es-ES", satelliteResources.Keys); - Assert.Contains("es-ES/classlibrarywithsatelliteassemblies.resources.dll", satelliteResources["es-ES"].Keys); - Assert.Contains("fr", satelliteResources.Keys); - Assert.Contains("fr/Microsoft.CodeAnalysis.CSharp.resources.dll", satelliteResources["fr"].Keys); - Assert.Contains("ja", satelliteResources.Keys); - Assert.Contains("ja/standalone.resources.dll", satelliteResources["ja"].Keys); - } - - - [Fact] - public async Task Build_WithI8NOption_CopiesI8NAssembliesWithoutLinkerEnabled() - { - // Arrange - using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" }); - project.Configuration = "Debug"; - project.AddProjectFileContent( -@" -<PropertyGroup> - <BlazorWebAssemblyI18NAssemblies>other</BlazorWebAssemblyI18NAssemblies> -</PropertyGroup>"); - - var result = await MSBuildProcessManager.DotnetMSBuild(project); - - Assert.BuildPassed(result); - - var buildOutputDirectory = project.BuildOutputDirectory; - - Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "I18N.dll"); - Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "I18N.Other.dll"); - // When running without linker, we copy all I18N assemblies. Look for one additional - Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "I18N.West.dll"); - } - - [Fact] - public async Task Build_WithI8NOption_CopiesI8NAssembliesWithLinkerEnabled() - { - // Arrange - using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" }); - project.Configuration = "Debug"; - project.AddProjectFileContent( -@" -<PropertyGroup> - <BlazorWebAssemblyEnableLinking>true</BlazorWebAssemblyEnableLinking> - <BlazorWebAssemblyI18NAssemblies>other</BlazorWebAssemblyI18NAssemblies> -</PropertyGroup>"); - - var result = await MSBuildProcessManager.DotnetMSBuild(project); - - Assert.BuildPassed(result); - - var buildOutputDirectory = project.BuildOutputDirectory; - - Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "I18N.dll"); - Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "I18N.Other.dll"); - Assert.FileDoesNotExist(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "I18N.West.dll"); - } - - [Fact] - public async Task Build_WithCustomOutputPath_Works() - { - // Arrange - using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" }); - - project.AddDirectoryBuildContent( -@"<PropertyGroup> - <BaseOutputPath>$(MSBuildThisFileDirectory)build\bin\</BaseOutputPath> - <BaseIntermediateOutputPath>$(MSBuildThisFileDirectory)build\obj\</BaseIntermediateOutputPath> -</PropertyGroup>"); - - var result = await MSBuildProcessManager.DotnetMSBuild(project, args: "/restore"); - Assert.BuildPassed(result); - - var compressedFilesPath = Path.Combine( - project.DirectoryPath, - "build", - project.IntermediateOutputDirectory, - "compressed"); - - Assert.True(Directory.Exists(compressedFilesPath)); - } - - private static GenerateBlazorBootJson.BootJsonData ReadBootJsonData(MSBuildResult result, string path) - { - return JsonSerializer.Deserialize<GenerateBlazorBootJson.BootJsonData>( - File.ReadAllText(Path.Combine(result.Project.DirectoryPath, path)), - new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); - } - } -} diff --git a/src/Components/WebAssembly/Build/test/BuildIntegrationTests/FileThumbPrint.cs b/src/Components/WebAssembly/Build/test/BuildIntegrationTests/FileThumbPrint.cs deleted file mode 100644 index c5f210be52..0000000000 --- a/src/Components/WebAssembly/Build/test/BuildIntegrationTests/FileThumbPrint.cs +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Security.Cryptography; - -namespace Microsoft.AspNetCore.Components.WebAssembly.Build -{ - internal class FileThumbPrint : IEquatable<FileThumbPrint> - { - private FileThumbPrint(string path, DateTime lastWriteTimeUtc, string hash) - { - FilePath = path; - LastWriteTimeUtc = lastWriteTimeUtc; - Hash = hash; - } - - public string FilePath { get; } - - public DateTime LastWriteTimeUtc { get; } - - public string Hash { get; } - - public override string ToString() - { - return $"{Path.GetFileName(FilePath)}, {LastWriteTimeUtc.ToString("u")}, {Hash}"; - } - - /// <summary> - /// Returns a list of thumbprints for all files (recursive) in the specified directory, sorted by file paths. - /// </summary> - public static List<FileThumbPrint> CreateFolderThumbprint(ProjectDirectory project, string directoryPath, params string[] filesToIgnore) - { - directoryPath = Path.Combine(project.DirectoryPath, directoryPath); - var files = Directory.GetFiles(directoryPath).Where(p => !filesToIgnore.Contains(p)); - var thumbprintLookup = new List<FileThumbPrint>(); - foreach (var file in files) - { - var thumbprint = Create(file); - thumbprintLookup.Add(thumbprint); - } - - thumbprintLookup.Sort(Comparer<FileThumbPrint>.Create((a, b) => StringComparer.Ordinal.Compare(a.FilePath, b.FilePath))); - return thumbprintLookup; - } - - public static FileThumbPrint Create(string path) - { - byte[] hashBytes; - using (var sha1 = SHA1.Create()) - using (var fileStream = File.OpenRead(path)) - { - hashBytes = sha1.ComputeHash(fileStream); - } - - var hash = Convert.ToBase64String(hashBytes); - var lastWriteTimeUtc = File.GetLastWriteTimeUtc(path); - return new FileThumbPrint(path, lastWriteTimeUtc, hash); - } - - public bool Equals(FileThumbPrint other) - { - return - string.Equals(FilePath, other.FilePath, StringComparison.Ordinal) && - LastWriteTimeUtc == other.LastWriteTimeUtc && - string.Equals(Hash, other.Hash, StringComparison.Ordinal); - } - - public override int GetHashCode() => LastWriteTimeUtc.GetHashCode(); - } -} diff --git a/src/Components/WebAssembly/Build/test/BuildIntegrationTests/MSBuildProcessManager.cs b/src/Components/WebAssembly/Build/test/BuildIntegrationTests/MSBuildProcessManager.cs deleted file mode 100644 index e1ee50af43..0000000000 --- a/src/Components/WebAssembly/Build/test/BuildIntegrationTests/MSBuildProcessManager.cs +++ /dev/null @@ -1,284 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Text; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.Extensions.CommandLineUtils; - -namespace Microsoft.AspNetCore.Components.WebAssembly.Build -{ - internal static class MSBuildProcessManager - { - public static Task<MSBuildResult> DotnetMSBuild( - ProjectDirectory project, - string target = "Build", - string args = null) - { - var buildArgumentList = new List<string> - { - // Disable node-reuse. We don't want msbuild processes to stick around - // once the test is completed. - "/nr:false", - - // Always generate a bin log for debugging purposes - "/bl", - }; - - buildArgumentList.Add($"/t:{target}"); - buildArgumentList.Add($"/p:Configuration={project.Configuration}"); - buildArgumentList.Add($"/p:BlazorBuildConfiguration={ProjectDirectory.TestProjectConfiguration}"); - buildArgumentList.Add(args); - - var buildArguments = string.Join(" ", buildArgumentList); - - return MSBuildProcessManager.RunProcessAsync(project, buildArguments); - } - - public static async Task<MSBuildResult> RunProcessAsync( - ProjectDirectory project, - string arguments, - TimeSpan? timeout = null) - { - var processStartInfo = new ProcessStartInfo() - { - WorkingDirectory = project.DirectoryPath, - UseShellExecute = false, - RedirectStandardError = true, - RedirectStandardOutput = true, - }; - - processStartInfo.FileName = DotNetMuxer.MuxerPathOrDefault(); - processStartInfo.Arguments = $"msbuild {arguments}"; - - // Suppresses the 'Welcome to .NET Core!' output that times out tests and causes locked file issues. - // When using dotnet we're not guarunteed to run in an environment where the dotnet.exe has had its first run experience already invoked. - processStartInfo.EnvironmentVariables["DOTNET_SKIP_FIRST_TIME_EXPERIENCE"] = "true"; - processStartInfo.EnvironmentVariables["_BlazorWebAssemblyBuildTest_BrotliCompressionLevel_NoCompression"] = "1"; - - var processResult = await RunProcessCoreAsync(processStartInfo, timeout); - - return new MSBuildResult(project, processResult.FileName, processResult.Arguments, processResult.ExitCode, processResult.Output); - } - - internal static Task<ProcessResult> RunProcessCoreAsync( - ProcessStartInfo processStartInfo, - TimeSpan? timeout = null) - { - timeout = timeout ?? TimeSpan.FromSeconds(5 * 60); - - var process = new Process() - { - StartInfo = processStartInfo, - EnableRaisingEvents = true, - }; - - var output = new StringBuilder(); - var outputLock = new object(); - - var diagnostics = new StringBuilder(); - diagnostics.AppendLine("Process execution diagnostics:"); - - process.ErrorDataReceived += Process_ErrorDataReceived; - process.OutputDataReceived += Process_OutputDataReceived; - - process.Start(); - process.BeginOutputReadLine(); - process.BeginErrorReadLine(); - - var timeoutTask = GetTimeoutForProcess(process, timeout, diagnostics); - - var waitTask = Task.Run(() => - { - // We need to use two WaitForExit calls to ensure that all of the output/events are processed. Previously - // this code used Process.Exited, which could result in us missing some output due to the ordering of - // events. - // - // See the remarks here: https://msdn.microsoft.com/en-us/library/ty0d8k56(v=vs.110).aspx - if (!process.WaitForExit(Int32.MaxValue)) - { - // unreachable - the timeoutTask will kill the process before this happens. - throw new TimeoutException(); - } - - process.WaitForExit(); - - - string outputString; - lock (outputLock) - { - // This marks the end of the diagnostic info which we collect when something goes wrong. - diagnostics.AppendLine("Process output:"); - - // Expected output - // Process execution diagnostics: - // ... - // Process output: - outputString = diagnostics.ToString(); - outputString += output.ToString(); - } - - var result = new ProcessResult(process.StartInfo.FileName, process.StartInfo.Arguments, process.ExitCode, outputString); - return result; - }); - - return Task.WhenAny<ProcessResult>(waitTask, timeoutTask).Unwrap(); - - void Process_ErrorDataReceived(object sender, DataReceivedEventArgs e) - { - lock (outputLock) - { - output.AppendLine(e.Data); - } - } - - void Process_OutputDataReceived(object sender, DataReceivedEventArgs e) - { - lock (outputLock) - { - output.AppendLine(e.Data); - } - } - - async Task<ProcessResult> GetTimeoutForProcess(Process process, TimeSpan? timeout, StringBuilder diagnostics) - { - await Task.Delay(timeout.Value); - - // Don't timeout during debug sessions - while (Debugger.IsAttached) - { - Thread.Sleep(TimeSpan.FromSeconds(1)); - } - if (!process.HasExited) - { - await CollectDumps(process, timeout, diagnostics); - - // This is a timeout. - process.Kill(); - } - - throw new TimeoutException($"command '${process.StartInfo.FileName} {process.StartInfo.Arguments}' timed out after {timeout}. Output: {output.ToString()}"); - } - - static async Task CollectDumps(Process process, TimeSpan? timeout, StringBuilder diagnostics) - { - var procDumpProcess = await CaptureDump(process, timeout, diagnostics); - var allDotNetProcesses = Process.GetProcessesByName("dotnet"); - - var allDotNetChildProcessCandidates = allDotNetProcesses - .Where(p => p.StartTime >= process.StartTime && p.Id != process.Id); - - if (!allDotNetChildProcessCandidates.Any()) - { - diagnostics.AppendLine("Couldn't find any candidate child process."); - foreach (var dotnetProcess in allDotNetProcesses) - { - diagnostics.AppendLine($"Found dotnet process with PID {dotnetProcess.Id} and start time {dotnetProcess.StartTime}."); - } - } - - foreach (var childProcess in allDotNetChildProcessCandidates) - { - diagnostics.AppendLine($"Found child process candidate '{childProcess.Id}'."); - } - - var childrenProcessDumpProcesses = await Task.WhenAll(allDotNetChildProcessCandidates.Select(d => CaptureDump(d, timeout, diagnostics))); - foreach (var childProcess in childrenProcessDumpProcesses) - { - if (childProcess != null && childProcess.HasExited) - { - diagnostics.AppendLine($"ProcDump failed to run for child dotnet process candidate '{process.Id}'."); - childProcess.Kill(); - } - } - - if (procDumpProcess != null && procDumpProcess.HasExited) - { - diagnostics.AppendLine($"ProcDump failed to run for '{process.Id}'."); - procDumpProcess.Kill(); - } - } - - static async Task<Process> CaptureDump(Process process, TimeSpan? timeout, StringBuilder diagnostics) - { - var metadataAttributes = Assembly.GetExecutingAssembly() - .GetCustomAttributes<AssemblyMetadataAttribute>(); - - var procDumpPath = metadataAttributes - .SingleOrDefault(ama => ama.Key == "ProcDumpToolPath")?.Value; - - if (string.IsNullOrEmpty(procDumpPath)) - { - diagnostics.AppendLine("ProcDumpPath not defined."); - return null; - } - var procDumpExePath = Path.Combine(procDumpPath, "procdump.exe"); - if (!File.Exists(procDumpExePath)) - { - diagnostics.AppendLine($"Can't find procdump.exe in '{procDumpPath}'."); - return null; - } - - var dumpDirectory = metadataAttributes - .SingleOrDefault(ama => ama.Key == "ArtifactsLogDir")?.Value; - - if (string.IsNullOrEmpty(dumpDirectory)) - { - diagnostics.AppendLine("ArtifactsLogDir not defined."); - return null; - } - - if (!Directory.Exists(dumpDirectory)) - { - diagnostics.AppendLine($"'{dumpDirectory}' does not exist."); - return null; - } - - var procDumpPattern = Path.Combine(dumpDirectory, "HangingProcess_PROCESSNAME_PID_YYMMDD_HHMMSS.dmp"); - var procDumpStartInfo = new ProcessStartInfo( - procDumpExePath, - $"-accepteula -ma {process.Id} {procDumpPattern}") - { - CreateNoWindow = true, - UseShellExecute = false, - RedirectStandardOutput = true, - RedirectStandardError = true - }; - - var procDumpProcess = Process.Start(procDumpStartInfo); - var tcs = new TaskCompletionSource<object>(); - - procDumpProcess.Exited += (s, a) => tcs.TrySetResult(null); - procDumpProcess.EnableRaisingEvents = true; - - await Task.WhenAny(tcs.Task, Task.Delay(timeout ?? TimeSpan.FromSeconds(30))); - return procDumpProcess; - } - } - - internal class ProcessResult - { - public ProcessResult(string fileName, string arguments, int exitCode, string output) - { - FileName = fileName; - Arguments = arguments; - ExitCode = exitCode; - Output = output; - } - - public string Arguments { get; } - - public string FileName { get; } - - public int ExitCode { get; } - - public string Output { get; } - } - } -} diff --git a/src/Components/WebAssembly/Build/test/BuildIntegrationTests/MSBuildResult.cs b/src/Components/WebAssembly/Build/test/BuildIntegrationTests/MSBuildResult.cs deleted file mode 100644 index 4ad24e269d..0000000000 --- a/src/Components/WebAssembly/Build/test/BuildIntegrationTests/MSBuildResult.cs +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -namespace Microsoft.AspNetCore.Components.WebAssembly.Build -{ - internal class MSBuildResult - { - public MSBuildResult(ProjectDirectory project, string fileName, string arguments, int exitCode, string output) - { - Project = project; - FileName = fileName; - Arguments = arguments; - ExitCode = exitCode; - Output = output; - } - - public ProjectDirectory Project { get; } - - public string Arguments { get; } - - public string FileName { get; } - - public int ExitCode { get; } - - public string Output { get; } - } - -} diff --git a/src/Components/WebAssembly/Build/test/BuildIntegrationTests/ProjectDirectory.cs b/src/Components/WebAssembly/Build/test/BuildIntegrationTests/ProjectDirectory.cs deleted file mode 100644 index 97ad1e8bd3..0000000000 --- a/src/Components/WebAssembly/Build/test/BuildIntegrationTests/ProjectDirectory.cs +++ /dev/null @@ -1,233 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Threading; - -namespace Microsoft.AspNetCore.Components.WebAssembly.Build -{ - internal class ProjectDirectory : IDisposable - { - public bool PreserveWorkingDirectory { get; set; } = false; - - // Configuration the test project is building in. - public static readonly string TestProjectConfiguration -#if DEBUG - = "Debug"; -#elif RELEASE - = "Release"; -#else -#error Configuration not supported -#endif - - private static readonly string RepoRoot = GetTestAttribute("Testing.RepoRoot"); - - public static ProjectDirectory Create(string projectName, string baseDirectory = "", string[] additionalProjects = null) - { - var destinationPath = Path.Combine(Path.GetTempPath(), "BlazorBuild", baseDirectory, Path.GetRandomFileName()); - Directory.CreateDirectory(destinationPath); - - try - { - if (Directory.EnumerateFiles(destinationPath).Any()) - { - throw new InvalidOperationException($"{destinationPath} should be empty"); - } - - if (string.IsNullOrEmpty(RepoRoot)) - { - throw new InvalidOperationException("RepoRoot was not specified."); - } - - var testAppsRoot = Path.Combine(RepoRoot, "src", "Components", "WebAssembly", "Build", "testassets"); - foreach (var project in new string[] { projectName, }.Concat(additionalProjects ?? Array.Empty<string>())) - { - var projectRoot = Path.Combine(testAppsRoot, project); - if (!Directory.Exists(projectRoot)) - { - throw new InvalidOperationException($"Could not find project at '{projectRoot}'"); - } - - var projectDestination = Path.Combine(destinationPath, project); - var projectDestinationDir = Directory.CreateDirectory(projectDestination); - CopyDirectory(new DirectoryInfo(projectRoot), projectDestinationDir); - SetupDirectoryBuildFiles(RepoRoot, testAppsRoot, projectDestination); - } - - var directoryPath = Path.Combine(destinationPath, projectName); - var projectPath = Path.Combine(directoryPath, projectName + ".csproj"); - - CopyRepositoryAssets(destinationPath); - - return new ProjectDirectory( - destinationPath, - directoryPath, - projectPath); - } - catch - { - CleanupDirectory(destinationPath); - throw; - } - - static void CopyDirectory(DirectoryInfo source, DirectoryInfo destination, bool recursive = true) - { - foreach (var file in source.EnumerateFiles()) - { - file.CopyTo(Path.Combine(destination.FullName, file.Name)); - } - - if (!recursive) - { - return; - } - - foreach (var directory in source.EnumerateDirectories()) - { - if (directory.Name == "bin") - { - // Just in case someone has opened the project in an IDE or built it. We don't want to copy - // these folders. - continue; - } - - var created = destination.CreateSubdirectory(directory.Name); - if (directory.Name == "obj") - { - // Copy NuGet restore assets (viz all the files at the root of the obj directory, but stop there.) - CopyDirectory(directory, created, recursive: false); - } - else - { - CopyDirectory(directory, created); - } - } - } - - static void SetupDirectoryBuildFiles(string repoRoot, string testAppsRoot, string projectDestination) - { - var razorSdkDirectoryRoot = TestFacts.RazorSdkDirectoryRoot; - var beforeDirectoryPropsContent = -$@"<Project> - <PropertyGroup> - <RepoRoot>{repoRoot}</RepoRoot> - <RazorSdkDirectoryRoot>{razorSdkDirectoryRoot}</RazorSdkDirectoryRoot> - </PropertyGroup> -</Project>"; - File.WriteAllText(Path.Combine(projectDestination, "Before.Directory.Build.props"), beforeDirectoryPropsContent); - - new List<string> { "Directory.Build.props", "Directory.Build.targets", } - .ForEach(file => - { - var source = Path.Combine(testAppsRoot, file); - var destination = Path.Combine(projectDestination, file); - File.Copy(source, destination); - }); - } - - static void CopyRepositoryAssets(string projectRoot) - { - const string GlobalJsonFileName = "global.json"; - var globalJsonPath = Path.Combine(RepoRoot, GlobalJsonFileName); - - var destinationFile = Path.Combine(projectRoot, GlobalJsonFileName); - File.Copy(globalJsonPath, destinationFile); - } - } - - protected ProjectDirectory(string solutionPath, string directoryPath, string projectFilePath) - { - SolutionPath = solutionPath; - DirectoryPath = directoryPath; - ProjectFilePath = projectFilePath; - } - - public string DirectoryPath { get; } - - public string ProjectFilePath { get; } - - public string SolutionPath { get; } - - public string TargetFramework { get; set; } = "netstandard2.1"; - - public string Configuration { get; set; } = TestProjectConfiguration; - - public string IntermediateOutputDirectory => Path.Combine("obj", Configuration, TargetFramework); - - public string BuildOutputDirectory => Path.Combine("bin", Configuration, TargetFramework); - - public string PublishOutputDirectory => Path.Combine(BuildOutputDirectory, "publish"); - - internal void AddProjectFileContent(string content) - { - if (content == null) - { - throw new ArgumentNullException(nameof(content)); - } - - var existing = File.ReadAllText(ProjectFilePath); - var updated = existing.Replace("<!-- Test Placeholder -->", content); - File.WriteAllText(ProjectFilePath, updated); - } - - internal void AddDirectoryBuildContent(string content) - { - if (content == null) - { - throw new ArgumentNullException(nameof(content)); - } - - var filepath = Path.Combine(DirectoryPath, "Directory.Build.props"); - - var existing = File.ReadAllText(filepath); - var updated = existing.Replace("<!-- Test Placeholder -->", content); - File.WriteAllText(filepath, updated); - } - - public void Dispose() - { - if (PreserveWorkingDirectory) - { - Console.WriteLine($"Skipping deletion of working directory {SolutionPath}"); - } - else - { - CleanupDirectory(SolutionPath); - } - } - - internal static void CleanupDirectory(string filePath) - { - var tries = 5; - var sleep = TimeSpan.FromSeconds(3); - - for (var i = 0; i < tries; i++) - { - try - { - Directory.Delete(filePath, recursive: true); - return; - } - catch when (i < tries - 1) - { - Console.WriteLine($"Failed to delete directory {filePath}, trying again."); - Thread.Sleep(sleep); - } - } - } - - private static string GetTestAttribute(string key) - { - return typeof(ProjectDirectory).Assembly - .GetCustomAttributes<AssemblyMetadataAttribute>() - .FirstOrDefault(f => f.Key == key) - ?.Value; - } - - public override string ToString() => DirectoryPath; - } -} diff --git a/src/Components/WebAssembly/Build/test/BuildIntegrationTests/ProjectDirectoryTest.cs b/src/Components/WebAssembly/Build/test/BuildIntegrationTests/ProjectDirectoryTest.cs deleted file mode 100644 index 130a14ef8d..0000000000 --- a/src/Components/WebAssembly/Build/test/BuildIntegrationTests/ProjectDirectoryTest.cs +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using Xunit; - -namespace Microsoft.AspNetCore.Components.WebAssembly.Build -{ - public class ProjectDirectoryTest - { - [Fact] - public void ProjectDirectory_IsNotSetToBePreserved() - { - // Arrange - using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" }); - - // Act & Assert - // This flag is only meant for local debugging and should not be set when checking in. - Assert.False(project.PreserveWorkingDirectory); - } - } -} diff --git a/src/Components/WebAssembly/Build/test/BuildIntegrationTests/PublishIntegrationTest.cs b/src/Components/WebAssembly/Build/test/BuildIntegrationTests/PublishIntegrationTest.cs deleted file mode 100644 index b4b34470ea..0000000000 --- a/src/Components/WebAssembly/Build/test/BuildIntegrationTests/PublishIntegrationTest.cs +++ /dev/null @@ -1,658 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text.Json; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Blazor.Build; -using Microsoft.AspNetCore.Testing; -using Xunit; -using ResourceHashesByNameDictionary = System.Collections.Generic.Dictionary<string, string>; -using static Microsoft.AspNetCore.Components.WebAssembly.Build.WebAssemblyRuntimePackage; -using System.IO.Compression; - -namespace Microsoft.AspNetCore.Components.WebAssembly.Build -{ - public class PublishIntegrationTest - { - [Fact] - public async Task Publish_WithDefaultSettings_Works() - { - // Arrange - using var project = ProjectDirectory.Create("standalone", additionalProjects: new [] { "razorclasslibrary", "LinkBaseToWebRoot" }); - project.Configuration = "Debug"; - var result = await MSBuildProcessManager.DotnetMSBuild(project, "Publish"); - - Assert.BuildPassed(result); - - var publishDirectory = project.PublishOutputDirectory; - - var blazorPublishDirectory = Path.Combine(publishDirectory, "wwwroot"); - - Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazor.boot.json"); - Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazor.webassembly.js"); - Assert.FileExists(result, blazorPublishDirectory, "_framework", "wasm", "dotnet.wasm"); - Assert.FileExists(result, blazorPublishDirectory, "_framework", "wasm", DotNetJsFileName); - Assert.FileExists(result, blazorPublishDirectory, "_framework", "_bin", "standalone.dll"); - Assert.FileExists(result, blazorPublishDirectory, "_framework", "_bin", "Microsoft.Extensions.Logging.Abstractions.dll"); // Verify dependencies are part of the output. - - // Verify referenced static web assets - Assert.FileExists(result, blazorPublishDirectory, "_content", "RazorClassLibrary", "wwwroot", "exampleJsInterop.js"); - Assert.FileExists(result, blazorPublishDirectory, "_content", "RazorClassLibrary", "styles.css"); - - // Verify static assets are in the publish directory - Assert.FileExists(result, blazorPublishDirectory, "index.html"); - - // Verify link item assets are in the publish directory - Assert.FileExists(result, blazorPublishDirectory, "js", "LinkedScript.js"); - var cssFile = Assert.FileExists(result, blazorPublishDirectory, "css", "app.css"); - Assert.FileContains(result, cssFile, ".publish"); - Assert.FileDoesNotExist(result, "dist", "Fake-License.txt"); - - // Verify web.config - Assert.FileExists(result, publishDirectory, "web.config"); - Assert.FileCountEquals(result, 1, publishDirectory, "*", SearchOption.TopDirectoryOnly); - - VerifyBootManifestHashes(result, blazorPublishDirectory); - VerifyServiceWorkerFiles(result, blazorPublishDirectory, - serviceWorkerPath: Path.Combine("serviceworkers", "my-service-worker.js"), - serviceWorkerContent: "// This is the production service worker", - assetsManifestPath: "custom-service-worker-assets.js"); - - // When publishing without linker, we expect to have collation information present in mscorlib.dll - Assert.AssemblyContainsResource(result, Path.Combine(blazorPublishDirectory, "_framework", "_bin", "mscorlib.dll"), "collation.cjkCHS.bin"); - } - - [Fact] - public async Task Publish_InRelease_Works() - { - // Arrange - using var project = ProjectDirectory.Create("standalone", additionalProjects: new [] { "razorclasslibrary", "LinkBaseToWebRoot" }); - project.Configuration = "Release"; - var result = await MSBuildProcessManager.DotnetMSBuild(project, "Publish"); - - Assert.BuildPassed(result); - - var publishDirectory = project.PublishOutputDirectory; - - var blazorPublishDirectory = Path.Combine(publishDirectory, "wwwroot"); - - Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazor.boot.json"); - Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazor.webassembly.js"); - Assert.FileExists(result, blazorPublishDirectory, "_framework", "wasm", "dotnet.wasm"); - Assert.FileExists(result, blazorPublishDirectory, "_framework", "wasm", DotNetJsFileName); - Assert.FileExists(result, blazorPublishDirectory, "_framework", "_bin", "standalone.dll"); - Assert.FileExists(result, blazorPublishDirectory, "_framework", "_bin", "Microsoft.Extensions.Logging.Abstractions.dll"); // Verify dependencies are part of the output. - - // Verify referenced static web assets - Assert.FileExists(result, blazorPublishDirectory, "_content", "RazorClassLibrary", "wwwroot", "exampleJsInterop.js"); - Assert.FileExists(result, blazorPublishDirectory, "_content", "RazorClassLibrary", "styles.css"); - - // Verify static assets are in the publish directory - Assert.FileExists(result, blazorPublishDirectory, "index.html"); - - // Verify link item assets are in the publish directory - Assert.FileExists(result, blazorPublishDirectory, "js", "LinkedScript.js"); - var cssFile = Assert.FileExists(result, blazorPublishDirectory, "css", "app.css"); - Assert.FileContains(result, cssFile, ".publish"); - Assert.FileDoesNotExist(result, "dist", "Fake-License.txt"); - - // Verify web.config - Assert.FileExists(result, publishDirectory, "web.config"); - Assert.FileCountEquals(result, 1, publishDirectory, "*", SearchOption.TopDirectoryOnly); - - // When publishing with linker, we expect to have collation information present in mscorlib.dll - Assert.AssemblyContainsResource(result, Path.Combine(blazorPublishDirectory, "_framework", "_bin", "mscorlib.dll"), "collation.cjkCHS.bin"); - } - - [Fact] - public async Task Publish_LinkerEnabledAndBlazorWebAssemblyPreserveCollationDataSet_CollationInformationIsPreserved() - { - // Arrange - using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" }); - project.Configuration = "Release"; - project.AddProjectFileContent( -@"<PropertyGroup> - <BlazorWebAssemblyPreserveCollationData>false</BlazorWebAssemblyPreserveCollationData> -</PropertyGroup>"); - var result = await MSBuildProcessManager.DotnetMSBuild(project, "Publish"); - - Assert.BuildPassed(result); - - var publishDirectory = project.PublishOutputDirectory; - - var blazorPublishDirectory = Path.Combine(publishDirectory, "wwwroot"); - - // When publishing with BlazorWebAssemblyPreserveCollationData=false, collation information should be stripped out. - Assert.AssemblyDoesNotContainResource(result, Path.Combine(blazorPublishDirectory, "_framework", "_bin", "mscorlib.dll"), "collation.cjkCHS.bin"); - } - - [Fact] - public async Task Publish_WithExistingWebConfig_Works() - { - // Arrange - using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary", "LinkBaseToWebRoot" }); - project.Configuration = "Release"; - - var webConfigContents = "test webconfig contents"; - AddFileToProject(project, "web.config", webConfigContents); - - var result = await MSBuildProcessManager.DotnetMSBuild(project, "Publish"); - - Assert.BuildPassed(result); - - var publishDirectory = project.PublishOutputDirectory; - - // Verify web.config - Assert.FileExists(result, publishDirectory, "web.config"); - Assert.FileContains(result, Path.Combine(publishDirectory, "web.config"), webConfigContents); - } - - [Fact] - public async Task Publish_WithNoBuild_Works() - { - // Arrange - using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" }); - var result = await MSBuildProcessManager.DotnetMSBuild(project, "Build"); - - Assert.BuildPassed(result); - - result = await MSBuildProcessManager.DotnetMSBuild(project, "Publish", "/p:NoBuild=true"); - - Assert.BuildPassed(result); - - var publishDirectory = project.PublishOutputDirectory; - var blazorPublishDirectory = Path.Combine(publishDirectory, "wwwroot"); - - Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazor.boot.json"); - Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazor.webassembly.js"); - Assert.FileExists(result, blazorPublishDirectory, "_framework", "wasm", "dotnet.wasm"); - Assert.FileExists(result, blazorPublishDirectory, "_framework", "wasm", DotNetJsFileName); - Assert.FileExists(result, blazorPublishDirectory, "_framework", "_bin", "standalone.dll"); - Assert.FileExists(result, blazorPublishDirectory, "_framework", "_bin", "Microsoft.Extensions.Logging.Abstractions.dll"); // Verify dependencies are part of the output. - - // Verify static assets are in the publish directory - Assert.FileExists(result, blazorPublishDirectory, "index.html"); - - // Verify static web assets from referenced projects are copied. - Assert.FileExists(result, blazorPublishDirectory, "_content", "RazorClassLibrary", "wwwroot", "exampleJsInterop.js"); - Assert.FileExists(result, blazorPublishDirectory, "_content", "RazorClassLibrary", "styles.css"); - - // Verify static assets are in the publish directory - Assert.FileExists(result, blazorPublishDirectory, "index.html"); - - // Verify web.config - Assert.FileExists(result, publishDirectory, "web.config"); - - VerifyBootManifestHashes(result, blazorPublishDirectory); - VerifyServiceWorkerFiles(result, blazorPublishDirectory, - serviceWorkerPath: Path.Combine("serviceworkers", "my-service-worker.js"), - serviceWorkerContent: "// This is the production service worker", - assetsManifestPath: "custom-service-worker-assets.js"); - - VerifyCompression(result, blazorPublishDirectory); - } - - private static void VerifyCompression(MSBuildResult result, string blazorPublishDirectory) - { - var original = Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazor.boot.json"); - var compressed = Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazor.boot.json.br"); - using var brotliStream = new BrotliStream(File.OpenRead(compressed), CompressionMode.Decompress); - using var textReader = new StreamReader(brotliStream); - var uncompressedText = textReader.ReadToEnd(); - var originalText = File.ReadAllText(original); - - Assert.Equal(originalText, uncompressedText); - } - - [Fact] - public async Task Publish_WithLinkOnBuildDisabled_Works() - { - // Arrange - using var project = ProjectDirectory.Create("standalone", additionalProjects: new [] { "razorclasslibrary" }); - project.AddProjectFileContent( -@"<PropertyGroup> - <BlazorWebAssemblyEnableLinking>false</BlazorWebAssemblyEnableLinking> -</PropertyGroup>"); - - var result = await MSBuildProcessManager.DotnetMSBuild(project, "Publish"); - - Assert.BuildPassed(result); - - var publishDirectory = project.PublishOutputDirectory; - var blazorPublishDirectory = Path.Combine(publishDirectory, "wwwroot"); - - Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazor.boot.json"); - Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazor.webassembly.js"); - Assert.FileExists(result, blazorPublishDirectory, "_framework", "wasm", "dotnet.wasm"); - Assert.FileExists(result, blazorPublishDirectory, "_framework", "wasm", DotNetJsFileName); - Assert.FileExists(result, blazorPublishDirectory, "_framework", "_bin", "standalone.dll"); - Assert.FileExists(result, blazorPublishDirectory, "_framework", "_bin", "Microsoft.Extensions.Logging.Abstractions.dll"); // Verify dependencies are part of the output. - - // Verify static assets are in the publish directory - Assert.FileExists(result, blazorPublishDirectory, "index.html"); - - // Verify referenced static web assets - Assert.FileExists(result, blazorPublishDirectory, "_content", "RazorClassLibrary", "wwwroot", "exampleJsInterop.js"); - Assert.FileExists(result, blazorPublishDirectory, "_content", "RazorClassLibrary", "styles.css"); - - // Verify web.config - Assert.FileExists(result, publishDirectory, "web.config"); - - VerifyBootManifestHashes(result, blazorPublishDirectory); - VerifyServiceWorkerFiles(result, blazorPublishDirectory, - serviceWorkerPath: Path.Combine("serviceworkers", "my-service-worker.js"), - serviceWorkerContent: "// This is the production service worker", - assetsManifestPath: "custom-service-worker-assets.js"); - } - - [Fact] - public async Task Publish_SatelliteAssemblies_AreCopiedToBuildOutput() - { - // Arrange - using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary", "classlibrarywithsatelliteassemblies" }); - project.AddProjectFileContent( -@" -<PropertyGroup> - <DefineConstants>$(DefineConstants);REFERENCE_classlibrarywithsatelliteassemblies</DefineConstants> -</PropertyGroup> -<ItemGroup> - <ProjectReference Include=""..\classlibrarywithsatelliteassemblies\classlibrarywithsatelliteassemblies.csproj"" /> -</ItemGroup>"); - - var result = await MSBuildProcessManager.DotnetMSBuild(project, "Publish", args: "/restore"); - - Assert.BuildPassed(result); - - var publishDirectory = project.PublishOutputDirectory; - var blazorPublishDirectory = Path.Combine(publishDirectory, "wwwroot"); - - Assert.FileExists(result, blazorPublishDirectory, "_framework", "_bin", "Microsoft.CodeAnalysis.CSharp.dll"); - Assert.FileExists(result, blazorPublishDirectory, "_framework", "_bin", "fr", "Microsoft.CodeAnalysis.CSharp.resources.dll"); // Verify satellite assemblies are present in the build output. - - var bootJsonPath = Path.Combine(blazorPublishDirectory, "_framework", "blazor.boot.json"); - Assert.FileContains(result, bootJsonPath, "\"Microsoft.CodeAnalysis.CSharp.dll\""); - Assert.FileContains(result, bootJsonPath, "\"fr\\/Microsoft.CodeAnalysis.CSharp.resources.dll\""); - - VerifyBootManifestHashes(result, blazorPublishDirectory); - VerifyServiceWorkerFiles(result, blazorPublishDirectory, - serviceWorkerPath: Path.Combine("serviceworkers", "my-service-worker.js"), - serviceWorkerContent: "// This is the production service worker", - assetsManifestPath: "custom-service-worker-assets.js"); - } - - [Fact] - [QuarantinedTest] - public async Task Publish_HostedApp_WithLinkOnBuildTrue_Works() - { - // Arrange - using var project = ProjectDirectory.Create("blazorhosted", additionalProjects: new[] { "standalone", "razorclasslibrary", }); - project.TargetFramework = TestFacts.DefaultNetCoreTargetFramework; - var result = await MSBuildProcessManager.DotnetMSBuild(project, "Publish"); - AddSiblingProjectFileContent(project, @" -<PropertyGroup> - <BlazorWebAssemblyEnableLinking>true</BlazorWebAssemblyEnableLinking> -</PropertyGroup>"); - - Assert.BuildPassed(result); - - var publishDirectory = project.PublishOutputDirectory; - // Make sure the main project exists - Assert.FileExists(result, publishDirectory, "blazorhosted.dll"); - Assert.FileExists(result, publishDirectory, "RazorClassLibrary.dll"); - - var blazorPublishDirectory = Path.Combine(publishDirectory, "wwwroot"); - Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazor.boot.json"); - Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazor.webassembly.js"); - Assert.FileExists(result, blazorPublishDirectory, "_framework", "wasm", "dotnet.wasm"); - Assert.FileExists(result, blazorPublishDirectory, "_framework", "wasm", DotNetJsFileName); - Assert.FileExists(result, blazorPublishDirectory, "_framework", "_bin", "standalone.dll"); - Assert.FileExists(result, blazorPublishDirectory, "_framework", "_bin", "Microsoft.Extensions.Logging.Abstractions.dll"); // Verify dependencies are part of the output. - // Verify project references appear as static web assets - Assert.FileExists(result, blazorPublishDirectory, "_framework", "_bin", "RazorClassLibrary.dll"); - // Also verify project references to the server project appear in the publish output - Assert.FileExists(result, publishDirectory, "RazorClassLibrary.dll"); - - // Verify static assets are in the publish directory - Assert.FileExists(result, blazorPublishDirectory, "index.html"); - - // Verify static web assets from referenced projects are copied. - Assert.FileExists(result, publishDirectory, "wwwroot", "_content", "RazorClassLibrary", "wwwroot", "exampleJsInterop.js"); - Assert.FileExists(result, publishDirectory, "wwwroot", "_content", "RazorClassLibrary", "styles.css"); - - // Verify web.config - Assert.FileExists(result, publishDirectory, "web.config"); - - VerifyBootManifestHashes(result, blazorPublishDirectory); - VerifyServiceWorkerFiles(result, blazorPublishDirectory, - serviceWorkerPath: Path.Combine("serviceworkers", "my-service-worker.js"), - serviceWorkerContent: "// This is the production service worker", - assetsManifestPath: "custom-service-worker-assets.js"); - } - - [Fact] - // Regression test for https://github.com/dotnet/aspnetcore/issues/18752 - public async Task Publish_HostedApp_WithLinkOnBuildFalse_Works() - { - // Arrange - using var project = ProjectDirectory.Create("blazorhosted", additionalProjects: new[] { "standalone", "razorclasslibrary", }); - project.TargetFramework = TestFacts.DefaultNetCoreTargetFramework; - - AddSiblingProjectFileContent(project, @" -<PropertyGroup> - <BlazorWebAssemblyEnableLinking>false</BlazorWebAssemblyEnableLinking> -</PropertyGroup>"); - - // VS builds projects individually and then a publish with BuildDependencies=false, but building the main project is a close enough approximation for this test. - var result = await MSBuildProcessManager.DotnetMSBuild(project, "Build"); - - Assert.BuildPassed(result); - - // Publish - result = await MSBuildProcessManager.DotnetMSBuild(project, "Publish", "/p:BuildDependencies=false"); - - var publishDirectory = project.PublishOutputDirectory; - // Make sure the main project exists - Assert.FileExists(result, publishDirectory, "blazorhosted.dll"); - - // Verification for https://github.com/dotnet/aspnetcore/issues/19926. Verify binaries for projects - // referenced by the Hosted project appear in the publish directory - Assert.FileExists(result, publishDirectory, "RazorClassLibrary.dll"); - Assert.FileExists(result, publishDirectory, "standalone.dll"); - - var blazorPublishDirectory = Path.Combine(publishDirectory, "wwwroot"); - Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazor.boot.json"); - Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazor.webassembly.js"); - Assert.FileExists(result, blazorPublishDirectory, "_framework", "wasm", "dotnet.wasm"); - Assert.FileExists(result, blazorPublishDirectory, "_framework", "wasm", DotNetJsFileName); - Assert.FileExists(result, blazorPublishDirectory, "_framework", "_bin", "standalone.dll"); - Assert.FileExists(result, blazorPublishDirectory, "_framework", "_bin", "RazorClassLibrary.dll"); - Assert.FileExists(result, blazorPublishDirectory, "_framework", "_bin", "Microsoft.Extensions.Logging.Abstractions.dll"); // Verify dependencies are part of the output. - - // Verify static assets are in the publish directory - Assert.FileExists(result, blazorPublishDirectory, "index.html"); - - // Verify static web assets from referenced projects are copied. - Assert.FileExists(result, publishDirectory, "wwwroot", "_content", "RazorClassLibrary", "wwwroot", "exampleJsInterop.js"); - Assert.FileExists(result, publishDirectory, "wwwroot", "_content", "RazorClassLibrary", "styles.css"); - - // Verify static assets are in the publish directory - Assert.FileExists(result, blazorPublishDirectory, "index.html"); - - // Verify web.config - Assert.FileExists(result, publishDirectory, "web.config"); - - VerifyBootManifestHashes(result, blazorPublishDirectory); - VerifyServiceWorkerFiles(result, blazorPublishDirectory, - serviceWorkerPath: Path.Combine("serviceworkers", "my-service-worker.js"), - serviceWorkerContent: "// This is the production service worker", - assetsManifestPath: "custom-service-worker-assets.js"); - - } - - [Fact] - public async Task Publish_HostedApp_WithNoBuild_Works() - { - // Arrange - using var project = ProjectDirectory.Create("blazorhosted", additionalProjects: new[] { "standalone", "razorclasslibrary", }); - project.TargetFramework = TestFacts.DefaultNetCoreTargetFramework; - var result = await MSBuildProcessManager.DotnetMSBuild(project, "Build"); - - Assert.BuildPassed(result); - - result = await MSBuildProcessManager.DotnetMSBuild(project, "Publish", "/p:NoBuild=true"); - - var publishDirectory = project.PublishOutputDirectory; - // Make sure the main project exists - Assert.FileExists(result, publishDirectory, "blazorhosted.dll"); - - var blazorPublishDirectory = Path.Combine(publishDirectory, "wwwroot"); - Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazor.boot.json"); - Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazor.webassembly.js"); - Assert.FileExists(result, blazorPublishDirectory, "_framework", "wasm", "dotnet.wasm"); - Assert.FileExists(result, blazorPublishDirectory, "_framework", "wasm", DotNetJsFileName); - Assert.FileExists(result, blazorPublishDirectory, "_framework", "_bin", "standalone.dll"); - Assert.FileExists(result, blazorPublishDirectory, "_framework", "_bin", "Microsoft.Extensions.Logging.Abstractions.dll"); // Verify dependencies are part of the output. - - // Verify static assets are in the publish directory - Assert.FileExists(result, blazorPublishDirectory, "index.html"); - - // Verify static web assets from referenced projects are copied. - Assert.FileExists(result, publishDirectory, "wwwroot", "_content", "RazorClassLibrary", "wwwroot", "exampleJsInterop.js"); - Assert.FileExists(result, publishDirectory, "wwwroot", "_content", "RazorClassLibrary", "styles.css"); - - // Verify web.config - Assert.FileExists(result, publishDirectory, "web.config"); - - VerifyBootManifestHashes(result, blazorPublishDirectory); - VerifyServiceWorkerFiles(result, blazorPublishDirectory, - serviceWorkerPath: Path.Combine("serviceworkers", "my-service-worker.js"), - serviceWorkerContent: "// This is the production service worker", - assetsManifestPath: "custom-service-worker-assets.js"); - } - - [Fact] - public async Task Publish_HostedApp_VisualStudio() - { - // Simulates publishing the same way VS does by setting BuildProjectReferences=false. - // Arrange - using var project = ProjectDirectory.Create("blazorhosted", additionalProjects: new[] { "standalone", "razorclasslibrary", }); - project.TargetFramework = TestFacts.DefaultNetCoreTargetFramework; - project.Configuration = "Release"; - var result = await MSBuildProcessManager.DotnetMSBuild(project, "Build", "/p:BuildInsideVisualStudio=true"); - - Assert.BuildPassed(result); - - result = await MSBuildProcessManager.DotnetMSBuild(project, "Publish", "/p:BuildProjectReferences=false /p:BuildInsideVisualStudio=true"); - - var publishDirectory = project.PublishOutputDirectory; - // Make sure the main project exists - Assert.FileExists(result, publishDirectory, "blazorhosted.dll"); - - var blazorPublishDirectory = Path.Combine(publishDirectory, "wwwroot"); - Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazor.boot.json"); - Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazor.webassembly.js"); - Assert.FileExists(result, blazorPublishDirectory, "_framework", "wasm", "dotnet.wasm"); - Assert.FileExists(result, blazorPublishDirectory, "_framework", "wasm", DotNetJsFileName); - Assert.FileExists(result, blazorPublishDirectory, "_framework", "_bin", "standalone.dll"); - Assert.FileExists(result, blazorPublishDirectory, "_framework", "_bin", "Microsoft.Extensions.Logging.Abstractions.dll"); // Verify dependencies are part of the output. - - // Verify static assets are in the publish directory - Assert.FileExists(result, blazorPublishDirectory, "index.html"); - - // Verify static web assets from referenced projects are copied. - Assert.FileExists(result, publishDirectory, "wwwroot", "_content", "RazorClassLibrary", "wwwroot", "exampleJsInterop.js"); - Assert.FileExists(result, publishDirectory, "wwwroot", "_content", "RazorClassLibrary", "styles.css"); - - // Verify web.config - Assert.FileExists(result, publishDirectory, "web.config"); - - VerifyBootManifestHashes(result, blazorPublishDirectory); - VerifyServiceWorkerFiles(result, blazorPublishDirectory, - serviceWorkerPath: Path.Combine("serviceworkers", "my-service-worker.js"), - serviceWorkerContent: "// This is the production service worker", - assetsManifestPath: "custom-service-worker-assets.js"); - } - - // Regression test to verify satellite assemblies from the blazor app are copied to the published app's wwwroot output directory as - // part of publishing in VS - [Fact] - public async Task Publish_HostedApp_VisualStudio_WithSatelliteAssemblies() - { - // Simulates publishing the same way VS does by setting BuildProjectReferences=false. - // Arrange - var project = ProjectDirectory.Create("blazorhosted", additionalProjects: new[] { "standalone", "razorclasslibrary", "classlibrarywithsatelliteassemblies" }); - project.TargetFramework = TestFacts.DefaultNetCoreTargetFramework; - project.Configuration = "Release"; - var standaloneProjectDirectory = Path.Combine(project.DirectoryPath, "..", "standalone"); - - // Setup the standalone app to have it's own satellite assemblies as well as transitively imported satellite assemblies. - var resxfileInProject = Path.Combine(standaloneProjectDirectory , "Resources.ja.resx.txt"); - File.Move(resxfileInProject, Path.Combine(standaloneProjectDirectory, "Resource.ja.resx")); - - var standaloneProjFile = Path.Combine(standaloneProjectDirectory, "standalone.csproj"); - var existing = File.ReadAllText(standaloneProjFile); - var updatedContent = @" -<PropertyGroup> - <DefineConstants>$(DefineConstants);REFERENCE_classlibrarywithsatelliteassemblies</DefineConstants> -</PropertyGroup> -<ItemGroup> - <ProjectReference Include=""..\classlibrarywithsatelliteassemblies\classlibrarywithsatelliteassemblies.csproj"" /> -</ItemGroup>"; - var updated = existing.Replace("<!-- Test Placeholder -->", updatedContent); - File.WriteAllText(standaloneProjFile, updated); - - var result = await MSBuildProcessManager.DotnetMSBuild(project, "Build", $"/restore"); - - Assert.BuildPassed(result); - - result = await MSBuildProcessManager.DotnetMSBuild(project, "Publish", "/p:BuildProjectReferences=false"); - - var publishDirectory = project.PublishOutputDirectory; - // Make sure the main project exists - Assert.FileExists(result, publishDirectory, "blazorhosted.dll"); - - var blazorPublishDirectory = Path.Combine(publishDirectory, "wwwroot"); - Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazor.boot.json"); - Assert.FileExists(result, blazorPublishDirectory, "_framework", "_bin", "ja", "standalone.resources.dll"); - Assert.FileExists(result, blazorPublishDirectory, "_framework", "_bin", "fr", "Microsoft.CodeAnalysis.resources.dll"); - - var bootJson = Path.Combine(project.DirectoryPath, blazorPublishDirectory, "_framework", "blazor.boot.json"); - var bootJsonFile = JsonSerializer.Deserialize<GenerateBlazorBootJson.BootJsonData>(File.ReadAllText(bootJson), new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); - var satelliteResources = bootJsonFile.resources.satelliteResources; - - Assert.Contains("es-ES", satelliteResources.Keys); - Assert.Contains("es-ES/classlibrarywithsatelliteassemblies.resources.dll", satelliteResources["es-ES"].Keys); - Assert.Contains("fr", satelliteResources.Keys); - Assert.Contains("fr/Microsoft.CodeAnalysis.CSharp.resources.dll", satelliteResources["fr"].Keys); - Assert.Contains("ja", satelliteResources.Keys); - Assert.Contains("ja/standalone.resources.dll", satelliteResources["ja"].Keys); - - VerifyServiceWorkerFiles(result, blazorPublishDirectory, - serviceWorkerPath: Path.Combine("serviceworkers", "my-service-worker.js"), - serviceWorkerContent: "// This is the production service worker", - assetsManifestPath: "custom-service-worker-assets.js"); - } - - private static void AddSiblingProjectFileContent(ProjectDirectory project, string content) - { - var path = Path.Combine(project.SolutionPath, "standalone", "standalone.csproj"); - var existing = File.ReadAllText(path); - var updated = existing.Replace("<!-- Test Placeholder -->", content); - File.WriteAllText(path, updated); - } - - private static void AddFileToProject(ProjectDirectory project, string filename, string content) - { - var path = Path.Combine(project.DirectoryPath, filename); - File.WriteAllText(path, content); - } - - private static void VerifyBootManifestHashes(MSBuildResult result, string blazorPublishDirectory) - { - var bootManifestResolvedPath = Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazor.boot.json"); - var bootManifestJson = File.ReadAllText(bootManifestResolvedPath); - var bootManifest = JsonSerializer.Deserialize<GenerateBlazorBootJson.BootJsonData>(bootManifestJson); - - VerifyBootManifestHashes(result, blazorPublishDirectory, bootManifest.resources.assembly, r => $"_framework/_bin/{r}"); - VerifyBootManifestHashes(result, blazorPublishDirectory, bootManifest.resources.runtime, r => $"_framework/wasm/{r}"); - - if (bootManifest.resources.pdb != null) - { - VerifyBootManifestHashes(result, blazorPublishDirectory, bootManifest.resources.pdb, r => $"_framework/_bin/{r}"); - } - - if (bootManifest.resources.satelliteResources != null) - { - foreach (var resourcesForCulture in bootManifest.resources.satelliteResources.Values) - { - VerifyBootManifestHashes(result, blazorPublishDirectory, resourcesForCulture, r => $"_framework/_bin/{r}"); - } - } - } - - private static void VerifyBootManifestHashes(MSBuildResult result, string blazorPublishDirectory, ResourceHashesByNameDictionary resources, Func<string, string> relativePathFunc) - { - foreach (var (name, hash) in resources) - { - var relativePath = Path.Combine(blazorPublishDirectory, relativePathFunc(name)); - Assert.FileHashEquals(result, relativePath, ParseWebFormattedHash(hash)); - } - } - - private static void VerifyServiceWorkerFiles(MSBuildResult result, string blazorPublishDirectory, string serviceWorkerPath, string serviceWorkerContent, string assetsManifestPath) - { - // Check the expected files are there - var serviceWorkerResolvedPath = Assert.FileExists(result, blazorPublishDirectory, serviceWorkerPath); - var assetsManifestResolvedPath = Assert.FileExists(result, blazorPublishDirectory, assetsManifestPath); - - // Check the service worker contains the expected content (which comes from the PublishedContent file) - Assert.FileContains(result, serviceWorkerResolvedPath, serviceWorkerContent); - - // Check the assets manifest version was added to the published service worker - var assetsManifest = ReadServiceWorkerAssetsManifest(assetsManifestResolvedPath); - Assert.FileContains(result, serviceWorkerResolvedPath, $"/* Manifest version: {assetsManifest.version} */"); - - // Check the assets manifest contains correct entries for all static content we're publishing - var resolvedPublishDirectory = Path.Combine(result.Project.DirectoryPath, blazorPublishDirectory); - var publishedStaticFiles = Directory.GetFiles(resolvedPublishDirectory, "*", new EnumerationOptions { RecurseSubdirectories = true }); - var assetsManifestHashesByUrl = (IReadOnlyDictionary<string, string>)assetsManifest.assets.ToDictionary(x => x.url, x => x.hash); - foreach (var publishedFilePath in publishedStaticFiles) - { - var publishedFileRelativePath = Path.GetRelativePath(resolvedPublishDirectory, publishedFilePath); - - // We don't list compressed files in the SWAM, as these are transparent to the client, - // nor do we list the service worker itself or its assets manifest, as these don't need to be fetched in the same way - if (IsCompressedFile(publishedFileRelativePath) - || string.Equals(publishedFileRelativePath, serviceWorkerPath, StringComparison.Ordinal) - || string.Equals(publishedFileRelativePath, assetsManifestPath, StringComparison.Ordinal)) - { - continue; - } - - // Verify hash - var publishedFileUrl = publishedFileRelativePath.Replace('\\', '/'); - var expectedHash = ParseWebFormattedHash(assetsManifestHashesByUrl[publishedFileUrl]); - Assert.Contains(publishedFileUrl, assetsManifestHashesByUrl); - Assert.FileHashEquals(result, publishedFilePath, expectedHash); - } - } - - private static string ParseWebFormattedHash(string webFormattedHash) - { - Assert.StartsWith("sha256-", webFormattedHash); - return webFormattedHash.Substring(7); - } - - private static bool IsCompressedFile(string path) - { - switch (Path.GetExtension(path)) - { - case ".br": - case ".gz": - return true; - default: - return false; - } - } - - private static GenerateServiceWorkerAssetsManifest.AssetsManifestFile ReadServiceWorkerAssetsManifest(string assetsManifestResolvedPath) - { - var jsContents = File.ReadAllText(assetsManifestResolvedPath); - var jsonStart = jsContents.IndexOf("{"); - var jsonLength = jsContents.LastIndexOf("}") - jsonStart + 1; - var json = jsContents.Substring(jsonStart, jsonLength); - return JsonSerializer.Deserialize<GenerateServiceWorkerAssetsManifest.AssetsManifestFile>(json); - } - - private static GenerateBlazorBootJson.BootJsonData ReadBootJsonData(MSBuildResult result, string path) - { - return JsonSerializer.Deserialize<GenerateBlazorBootJson.BootJsonData>( - File.ReadAllText(Path.Combine(result.Project.DirectoryPath, path)), - new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); - } - } -} diff --git a/src/Components/WebAssembly/Build/test/BuildIntegrationTests/PwaManifestTests.cs b/src/Components/WebAssembly/Build/test/BuildIntegrationTests/PwaManifestTests.cs deleted file mode 100644 index 464d361e70..0000000000 --- a/src/Components/WebAssembly/Build/test/BuildIntegrationTests/PwaManifestTests.cs +++ /dev/null @@ -1,118 +0,0 @@ -using System.IO; -using System.Linq; -using System.Text.Json; -using System.Text.RegularExpressions; -using System.Threading.Tasks; -using Xunit; - -namespace Microsoft.AspNetCore.Components.WebAssembly.Build -{ - public class PwaManifestTests - { - [Fact] - public async Task Build_ServiceWorkerAssetsManifest_Works() - { - // Arrange - var expectedExtensions = new[] { ".dll", ".pdb", ".js", ".wasm" }; - using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" }); - var result = await MSBuildProcessManager.DotnetMSBuild(project, args: "/p:ServiceWorkerAssetsManifest=service-worker-assets.js"); - - Assert.BuildPassed(result); - - var buildOutputDirectory = project.BuildOutputDirectory; - - Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "blazor.boot.json"); - Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "blazor.webassembly.js"); - Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "wasm", "dotnet.wasm"); - Assert.FileCountEquals(result, 1, Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "wasm"), "dotnet.*.js"); - Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "standalone.dll"); - Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "Microsoft.Extensions.Logging.Abstractions.dll"); // Verify dependencies are part of the output. - - var staticWebAssets = Assert.FileExists(result, buildOutputDirectory, "standalone.StaticWebAssets.xml"); - Assert.FileContains(result, staticWebAssets, Path.Combine("netstandard2.1", "wwwroot")); - - var serviceWorkerAssetsManifest = Assert.FileExists(result, buildOutputDirectory, "wwwroot", "service-worker-assets.js"); - // Trim prefix 'self.assetsManifest = ' and suffix ';' - var manifestContents = File.ReadAllText(serviceWorkerAssetsManifest).TrimEnd()[22..^1]; - - var manifestContentsJson = JsonDocument.Parse(manifestContents); - Assert.True(manifestContentsJson.RootElement.TryGetProperty("assets", out var assets)); - Assert.Equal(JsonValueKind.Array, assets.ValueKind); - - var entries = assets.EnumerateArray().Select(e => e.GetProperty("url").GetString()).OrderBy(e => e).ToArray(); - Assert.All(entries, e => expectedExtensions.Contains(Path.GetExtension(e))); - } - - [Fact] - public async Task Publish_UpdatesServiceWorkerVersionHash_WhenSourcesChange() - { - // Arrange - using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" }); - var result = await MSBuildProcessManager.DotnetMSBuild(project, "Publish", args: "/bl:initial.binlog /p:ServiceWorkerAssetsManifest=service-worker-assets.js"); - - Assert.BuildPassed(result); - - var publishOutputDirectory = project.PublishOutputDirectory; - - var serviceWorkerFile = Assert.FileExists(result, publishOutputDirectory, "wwwroot", "serviceworkers", "my-service-worker.js"); - var version = File.ReadAllLines(serviceWorkerFile).Last(); - var match = Regex.Match(version, "\\/\\* Manifest version: (.{8}) \\*\\/"); - Assert.True(match.Success); - Assert.Equal(2, match.Groups.Count); - Assert.NotNull(match.Groups[1].Value); - var capture = match.Groups[1].Value; - - // Act - var cssFile = Path.Combine(project.DirectoryPath, "LinkToWebRoot", "css", "app.css"); - File.WriteAllText(cssFile, ".updated { }"); - - // Assert - var updatedResult = await MSBuildProcessManager.DotnetMSBuild(project, "Publish", args: "/bl:updated.binlog /p:ServiceWorkerAssetsManifest=service-worker-assets.js"); - - Assert.BuildPassed(result); - - var updatedVersion = File.ReadAllLines(serviceWorkerFile).Last(); - var updatedMatch = Regex.Match(updatedVersion, "\\/\\* Manifest version: (.{8}) \\*\\/"); - Assert.True(updatedMatch.Success); - Assert.Equal(2, updatedMatch.Groups.Count); - Assert.NotNull(updatedMatch.Groups[1].Value); - var updatedCapture = updatedMatch.Groups[1].Value; - - Assert.NotEqual(capture, updatedCapture); - } - - [Fact] - public async Task Publish_DeterministicAcrossBuilds_WhenNoSourcesChange() - { - // Arrange - using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" }); - var result = await MSBuildProcessManager.DotnetMSBuild(project, "Publish", args: "/bl:initial.binlog /p:ServiceWorkerAssetsManifest=service-worker-assets.js"); - - Assert.BuildPassed(result); - - var publishOutputDirectory = project.PublishOutputDirectory; - - var serviceWorkerFile = Assert.FileExists(result, publishOutputDirectory, "wwwroot", "serviceworkers", "my-service-worker.js"); - var version = File.ReadAllLines(serviceWorkerFile).Last(); - var match = Regex.Match(version, "\\/\\* Manifest version: (.{8}) \\*\\/"); - Assert.True(match.Success); - Assert.Equal(2, match.Groups.Count); - Assert.NotNull(match.Groups[1].Value); - var capture = match.Groups[1].Value; - - // Act && Assert - var updatedResult = await MSBuildProcessManager.DotnetMSBuild(project, "Publish", args: "/bl:updated.binlog /p:ServiceWorkerAssetsManifest=service-worker-assets.js"); - - Assert.BuildPassed(result); - - var updatedVersion = File.ReadAllLines(serviceWorkerFile).Last(); - var updatedMatch = Regex.Match(updatedVersion, "\\/\\* Manifest version: (.{8}) \\*\\/"); - Assert.True(updatedMatch.Success); - Assert.Equal(2, updatedMatch.Groups.Count); - Assert.NotNull(updatedMatch.Groups[1].Value); - var updatedCapture = updatedMatch.Groups[1].Value; - - Assert.Equal(capture, updatedCapture); - } - } -} diff --git a/src/Components/WebAssembly/Build/test/BuildIntegrationTests/TestFacts.cs b/src/Components/WebAssembly/Build/test/BuildIntegrationTests/TestFacts.cs deleted file mode 100644 index 1da03c94c6..0000000000 --- a/src/Components/WebAssembly/Build/test/BuildIntegrationTests/TestFacts.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Linq; -using System.Reflection; - -namespace Microsoft.AspNetCore.Components.WebAssembly.Build -{ - public static class TestFacts - { - public static string DefaultNetCoreTargetFramework => - GetAttributeValue(nameof(DefaultNetCoreTargetFramework)); - - public static string RazorSdkDirectoryRoot => - GetAttributeValue(nameof(RazorSdkDirectoryRoot)); - - private static string GetAttributeValue(string name) - { - return Assembly - .GetExecutingAssembly() - .GetCustomAttributes<AssemblyMetadataAttribute>() - .FirstOrDefault(a => a.Key == $"Testing.{name}") - .Value; - } - } -} diff --git a/src/Components/WebAssembly/Build/test/BuildIntegrationTests/WebAssemblyRuntimePackage.cs b/src/Components/WebAssembly/Build/test/BuildIntegrationTests/WebAssemblyRuntimePackage.cs deleted file mode 100644 index d95ba1e41c..0000000000 --- a/src/Components/WebAssembly/Build/test/BuildIntegrationTests/WebAssemblyRuntimePackage.cs +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Linq; -using System.Reflection; - -namespace Microsoft.AspNetCore.Components.WebAssembly.Build -{ - internal static class WebAssemblyRuntimePackage - { - public static readonly string ComponentsWebAssemblyRuntimePackageVersion; - public static readonly string DotNetJsFileName; - - static WebAssemblyRuntimePackage() - { - ComponentsWebAssemblyRuntimePackageVersion = typeof(WebAssemblyRuntimePackage) - .Assembly - .GetCustomAttributes<AssemblyMetadataAttribute>() - .FirstOrDefault(f => f.Key == "Testing.MicrosoftAspNetCoreComponentsWebAssemblyRuntimePackageVersion") - ?.Value - ?? throw new InvalidOperationException("Testing.MicrosoftAspNetCoreComponentsWebAssemblyRuntimePackageVersion was not found"); - - DotNetJsFileName = $"dotnet.{ComponentsWebAssemblyRuntimePackageVersion}.js"; - } - } -} diff --git a/src/Components/WebAssembly/Build/test/GenerateBlazorBootJsonTest.cs b/src/Components/WebAssembly/Build/test/GenerateBlazorBootJsonTest.cs deleted file mode 100644 index 5b95548d57..0000000000 --- a/src/Components/WebAssembly/Build/test/GenerateBlazorBootJsonTest.cs +++ /dev/null @@ -1,202 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.IO; -using System.Linq; -using System.Runtime.Serialization.Json; -using Microsoft.Build.Framework; -using Moq; -using Xunit; -using BootJsonData = Microsoft.AspNetCore.Components.WebAssembly.Build.GenerateBlazorBootJson.BootJsonData; - -namespace Microsoft.AspNetCore.Components.WebAssembly.Build -{ - public class GenerateBlazorBootJsonTest - { - [Fact] - public void GroupsResourcesByType() - { - // Arrange - var taskInstance = new GenerateBlazorBootJson - { - AssemblyPath = "MyApp.Entrypoint.dll", - Resources = new[] - { - CreateResourceTaskItem( - "assembly", - name: "My.Assembly1.ext", // Can specify filename with no dir - fileHash: "abcdefghikjlmnopqrstuvwxyz"), - - CreateResourceTaskItem( - "assembly", - name: "dir\\My.Assembly2.ext2", // Can specify Windows-style path - fileHash: "012345678901234567890123456789"), - - CreateResourceTaskItem( - "pdb", - name: "otherdir/SomePdb.pdb", // Can specify Linux-style path - fileHash: "pdbhashpdbhashpdbhash"), - - CreateResourceTaskItem( - "pdb", - name: "My.Assembly1.pdb", - fileHash: "pdbdefghikjlmnopqrstuvwxyz"), - - CreateResourceTaskItem( - "runtime", - name: "some-runtime-file", // Can specify path with no extension - fileHash: "runtimehashruntimehash"), - - CreateResourceTaskItem( - "satellite", - name: "en-GB\\satellite-assembly1.ext", - fileHash: "hashsatelliteassembly1", - ("Culture", "en-GB")), - - CreateResourceTaskItem( - "satellite", - name: "fr/satellite-assembly2.dll", - fileHash: "hashsatelliteassembly2", - ("Culture", "fr")), - - CreateResourceTaskItem( - "satellite", - name: "en-GB\\satellite-assembly3.ext", - fileHash: "hashsatelliteassembly3", - ("Culture", "en-GB")), - } - }; - - using var stream = new MemoryStream(); - - // Act - taskInstance.WriteBootJson(stream, "MyEntrypointAssembly"); - - // Assert - var parsedContent = ParseBootData(stream); - Assert.Equal("MyEntrypointAssembly", parsedContent.entryAssembly); - - var resources = parsedContent.resources.assembly; - Assert.Equal(2, resources.Count); - Assert.Equal("sha256-abcdefghikjlmnopqrstuvwxyz", resources["My.Assembly1.ext"]); - Assert.Equal("sha256-012345678901234567890123456789", resources["dir/My.Assembly2.ext2"]); // Paths are converted to use URL-style separators - - resources = parsedContent.resources.pdb; - Assert.Equal(2, resources.Count); - Assert.Equal("sha256-pdbhashpdbhashpdbhash", resources["otherdir/SomePdb.pdb"]); - Assert.Equal("sha256-pdbdefghikjlmnopqrstuvwxyz", resources["My.Assembly1.pdb"]); - - resources = parsedContent.resources.runtime; - Assert.Single(resources); - Assert.Equal("sha256-runtimehashruntimehash", resources["some-runtime-file"]); - - var satelliteResources = parsedContent.resources.satelliteResources; - Assert.Collection( - satelliteResources.OrderBy(kvp => kvp.Key), - kvp => - { - Assert.Equal("en-GB", kvp.Key); - Assert.Collection( - kvp.Value.OrderBy(item => item.Key), - item => - { - Assert.Equal("en-GB/satellite-assembly1.ext", item.Key); - Assert.Equal("sha256-hashsatelliteassembly1", item.Value); - }, - item => - { - Assert.Equal("en-GB/satellite-assembly3.ext", item.Key); - Assert.Equal("sha256-hashsatelliteassembly3", item.Value); - }); - }, - kvp => - { - Assert.Equal("fr", kvp.Key); - Assert.Collection( - kvp.Value.OrderBy(item => item.Key), - item => - { - Assert.Equal("fr/satellite-assembly2.dll", item.Key); - Assert.Equal("sha256-hashsatelliteassembly2", item.Value); - }); - }); - } - - [Theory] - [InlineData(false)] - [InlineData(true)] - public void CanSpecifyCacheBootResources(bool flagValue) - { - // Arrange - var taskInstance = new GenerateBlazorBootJson { CacheBootResources = flagValue }; - using var stream = new MemoryStream(); - - // Act - taskInstance.WriteBootJson(stream, "MyEntrypointAssembly"); - - // Assert - var parsedContent = ParseBootData(stream); - Assert.Equal(flagValue, parsedContent.cacheBootResources); - } - - [Theory] - [InlineData(false)] - [InlineData(true)] - public void CanSpecifyDebugBuild(bool flagValue) - { - // Arrange - var taskInstance = new GenerateBlazorBootJson { DebugBuild = flagValue }; - using var stream = new MemoryStream(); - - // Act - taskInstance.WriteBootJson(stream, "MyEntrypointAssembly"); - - // Assert - var parsedContent = ParseBootData(stream); - Assert.Equal(flagValue, parsedContent.debugBuild); - } - - [Theory] - [InlineData(false)] - [InlineData(true)] - public void CanSpecifyLinkerEnabled(bool flagValue) - { - // Arrange - var taskInstance = new GenerateBlazorBootJson { LinkerEnabled = flagValue }; - using var stream = new MemoryStream(); - - // Act - taskInstance.WriteBootJson(stream, "MyEntrypointAssembly"); - - // Assert - var parsedContent = ParseBootData(stream); - Assert.Equal(flagValue, parsedContent.linkerEnabled); - } - - private static BootJsonData ParseBootData(Stream stream) - { - stream.Position = 0; - var serializer = new DataContractJsonSerializer( - typeof(BootJsonData), - new DataContractJsonSerializerSettings { UseSimpleDictionaryFormat = true }); - return (BootJsonData)serializer.ReadObject(stream); - } - - private static ITaskItem CreateResourceTaskItem(string type, string name, string fileHash, params (string key, string value)[] values) - { - var mock = new Mock<ITaskItem>(); - mock.Setup(m => m.GetMetadata("BootManifestResourceType")).Returns(type); - mock.Setup(m => m.GetMetadata("BootManifestResourceName")).Returns(name); - mock.Setup(m => m.GetMetadata("Integrity")).Returns(fileHash); - - if (values != null) - { - foreach (var (key, value) in values) - { - mock.Setup(m => m.GetMetadata(key)).Returns(value); - } - } - return mock.Object; - } - } -} diff --git a/src/Components/WebAssembly/Build/test/Microsoft.AspNetCore.Components.WebAssembly.Build.Tests.csproj b/src/Components/WebAssembly/Build/test/Microsoft.AspNetCore.Components.WebAssembly.Build.Tests.csproj deleted file mode 100644 index e7b4c82883..0000000000 --- a/src/Components/WebAssembly/Build/test/Microsoft.AspNetCore.Components.WebAssembly.Build.Tests.csproj +++ /dev/null @@ -1,75 +0,0 @@ -<Project Sdk="Microsoft.NET.Sdk"> - - <PropertyGroup> - <TargetFramework>$(DefaultNetCoreTargetFramework)</TargetFramework> - - <!-- Exclude the TestFiles directory from default wildcards --> - <DefaultItemExcludes>$(DefaultItemExcludes);TestFiles\**\*</DefaultItemExcludes> - <BuildHelixPayload>false</BuildHelixPayload> - </PropertyGroup> - - <ItemGroup> - <!-- Embed test files so they can be referenced in tests --> - <EmbeddedResource Include="TestFiles\**" /> - </ItemGroup> - - <PropertyGroup Condition="'$(GenerateBaselines)'=='true'"> - <DefineConstants>GENERATE_BASELINES;$(DefineConstants)</DefineConstants> - </PropertyGroup> - - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> - <DefineConstants>TRACE</DefineConstants> - </PropertyGroup> - - <ItemGroup> - <Reference Include="Microsoft.AspNetCore.Components.WebAssembly.Build" /> - <Reference Include="Microsoft.AspNetCore.Components.WebAssembly.Runtime" /> - <Reference Include="Microsoft.Build.Framework" /> - <Reference Include="Microsoft.Build.Utilities.Core" /> - <!-- Avoid CS1705 errors due to mix of assemblies brought in transitively. --> - <Reference Include="Microsoft.AspNetCore.Components" /> - </ItemGroup> - - <ItemGroup> - <ProjectReference Include="..\..\testassets\StandaloneApp\StandaloneApp.csproj" /> - <Compile Include="$(SharedSourceRoot)CommandLineUtils\**\*.cs" /> - </ItemGroup> - - <ItemGroup> - <AssemblyAttribute Include="System.Reflection.AssemblyMetadataAttribute"> - <_Parameter1>Testing.RepoRoot</_Parameter1> - <_Parameter2>$(RepoRoot)</_Parameter2> - </AssemblyAttribute> - - <AssemblyAttribute Include="System.Reflection.AssemblyMetadataAttribute"> - <_Parameter1>Testing.RazorSdkDirectoryRoot</_Parameter1> - <_Parameter2>$(ArtifactsBinDir)Microsoft.NET.Sdk.Razor\$(Configuration)\sdk-output\</_Parameter2> - </AssemblyAttribute> - - <AssemblyAttribute Include="System.Reflection.AssemblyMetadataAttribute"> - <_Parameter1>Testing.MicrosoftAspNetCoreComponentsWebAssemblyRuntimePackageVersion</_Parameter1> - <_Parameter2>$(MicrosoftAspNetCoreComponentsWebAssemblyRuntimePackageVersion)</_Parameter2> - </AssemblyAttribute> - - <AssemblyAttribute Include="System.Reflection.AssemblyMetadataAttribute"> - <_Parameter1>Testing.DefaultNetCoreTargetFramework</_Parameter1> - <_Parameter2>$(DefaultNetCoreTargetFramework)</_Parameter2> - </AssemblyAttribute> - </ItemGroup> - - <Target Name="RestoreTestAssets" AfterTargets="Restore;Build" Condition="'$(DotNetBuildFromSource)' != 'true'"> - <ItemGroup> - <_TestAsset Include="..\testassets\standalone\standalone.csproj" /> - <_TestAsset Include="..\testassets\blazorhosted\blazorhosted.csproj" /> - </ItemGroup> - - <MSBuild - Projects="@(_TestAsset)" - Targets="Restore" - Properties=" - RepoRoot=$(RepoRoot); - MicrosoftNetCompilersToolsetPackageVersion=$(MicrosoftNetCompilersToolsetPackageVersion); - MicrosoftNETSdkRazorPackageVersion=$(MicrosoftNETSdkRazorPackageVersion)" /> - </Target> - -</Project> diff --git a/src/Components/WebAssembly/Build/test/RuntimeDependenciesResolverTest.cs b/src/Components/WebAssembly/Build/test/RuntimeDependenciesResolverTest.cs deleted file mode 100644 index 6fba8b34d9..0000000000 --- a/src/Components/WebAssembly/Build/test/RuntimeDependenciesResolverTest.cs +++ /dev/null @@ -1,181 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Text; -using Microsoft.AspNetCore.Testing; -using Xunit; - -namespace Microsoft.AspNetCore.Components.WebAssembly.Build -{ - public class RuntimeDependenciesResolverTest - { - [Fact] - [QuarantinedTest] - public void FindsReferenceAssemblyGraph_ForStandaloneApp() - { - // Arrange - var standaloneAppAssembly = typeof(StandaloneApp.Program).Assembly; - var mainAssemblyLocation = standaloneAppAssembly.Location; - - var hintPaths = ReadContent(standaloneAppAssembly, "StandaloneApp.referenceHints.txt"); - var bclLocations = ReadContent(standaloneAppAssembly, "StandaloneApp.bclLocations.txt"); - - var expectedContents = new[] - { - /* - The current Mono WASM BCL forwards from netstandard.dll to various facade assemblies - in which small bits of implementation live, such as System.Xml.XPath.XDocument. So - if you reference netstandard, then you also reference System.Xml.XPath.XDocument.dll, - even though you're very unlikely to be calling it at runtime. That's why the following - list (for a very basic Blazor app) is longer than you'd expect. - - These redundant references could be stripped out during publishing, but it's still - unfortunate that in development mode you'd see all these unexpected assemblies get - fetched from the server. We should try to get the Mono WASM BCL reorganized so that - all the implementation goes into mscorlib.dll, with the facade assemblies existing only - in case someone (or some 3rd party assembly) references them directly, but with their - implementations 100% forwarding to mscorlib.dll. Then in development you'd fetch far - fewer assemblies from the server, and during publishing, illink would remove all the - uncalled implementation code from mscorlib.dll anyway. - */ - "Microsoft.AspNetCore.Components.dll", - "Microsoft.AspNetCore.Components.Forms.dll", - "Microsoft.AspNetCore.Components.Web.dll", - "Microsoft.AspNetCore.Components.WebAssembly.dll", - "Microsoft.Bcl.AsyncInterfaces.dll", - "Microsoft.Extensions.Configuration.Abstractions.dll", - "Microsoft.Extensions.Configuration.dll", - "Microsoft.Extensions.Configuration.FileExtensions.dll", - "Microsoft.Extensions.Configuration.Json.dll", - "Microsoft.Extensions.DependencyInjection.Abstractions.dll", - "Microsoft.Extensions.DependencyInjection.dll", - "Microsoft.Extensions.FileProviders.Abstractions.dll", - "Microsoft.Extensions.FileProviders.Physical.dll", - "Microsoft.Extensions.FileSystemGlobbing.dll", - "Microsoft.Extensions.Logging.dll", - "Microsoft.Extensions.Logging.Abstractions.dll", - "Microsoft.Extensions.Options.dll", - "Microsoft.Extensions.Primitives.dll", - "Microsoft.JSInterop.dll", - "Microsoft.JSInterop.WebAssembly.dll", - "Mono.Security.dll", - "mscorlib.dll", - "netstandard.dll", - "StandaloneApp.dll", - "System.dll", - "System.Buffers.dll", - "System.Collections.Concurrent.dll", - "System.Collections.dll", - "System.ComponentModel.Annotations.dll", - "System.ComponentModel.DataAnnotations.dll", - "System.ComponentModel.Composition.dll", - "System.Core.dll", - "System.Data.dll", - "System.Data.DataSetExtensions.dll", - "System.Diagnostics.Debug.dll", - "System.Diagnostics.DiagnosticSource.dll", - "System.Diagnostics.Tracing.dll", - "System.Drawing.Common.dll", - "System.IO.Compression.dll", - "System.IO.Compression.FileSystem.dll", - "System.Memory.dll", - "System.Net.Http.dll", - "System.Net.Http.Json.dll", - "System.Net.Http.WebAssemblyHttpHandler.dll", - "System.Numerics.dll", - "System.Numerics.Vectors.dll", - "System.Reflection.dll", - "System.Resources.ResourceManager.dll", - "System.Runtime.Extensions.dll", - "System.Runtime.InteropServices.dll", - "System.Runtime.CompilerServices.Unsafe.dll", - "System.Runtime.Serialization.dll", - "System.Runtime.dll", - "System.ServiceModel.Internals.dll", - "System.Text.Encodings.Web.dll", - "System.Text.Json.dll", - "System.Threading.dll", - "System.Threading.Tasks.Extensions.dll", - "System.Transactions.dll", - "System.Xml.dll", - "System.Xml.Linq.dll", - "WebAssembly.Bindings.dll", - "WebAssembly.Net.WebSockets.dll", - }.OrderBy(i => i, StringComparer.Ordinal) - .ToArray(); - - // Act - - var paths = ResolveBlazorRuntimeDependencies - .ResolveRuntimeDependenciesCore( - mainAssemblyLocation, - hintPaths, - bclLocations); - - var contents = paths - .Select(p => Path.GetFileName(p)) - .Where(p => Path.GetExtension(p) != ".pdb") - .OrderBy(i => i, StringComparer.Ordinal) - .ToArray(); - - var expected = new HashSet<string>(expectedContents); - var actual = new HashSet<string>(contents); - - var contentNotFound = expected.Except(actual); - var additionalContentFound = actual.Except(expected); - - // Assert - if (contentNotFound.Any() || additionalContentFound.Any()) - { - throw new ContentMisMatchException - { - ContentNotFound = contentNotFound, - AdditionalContentFound = additionalContentFound, - }; - } - - Assert.Equal(expectedContents, contents); - } - - private string[] ReadContent(Assembly standaloneAppAssembly, string fileName) - { - using var resource = standaloneAppAssembly.GetManifestResourceStream(fileName); - using var streamReader = new StreamReader(resource); - - return streamReader.ReadToEnd().Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries); - } - - private class ContentMisMatchException : Xunit.Sdk.XunitException - { - public IEnumerable<string> ContentNotFound { get; set; } - - public IEnumerable<string> AdditionalContentFound { get; set; } - - public override string Message - { - get - { - var error = new StringBuilder(); - if (ContentNotFound.Any()) - { - error.Append($"Expected content not found: ") - .AppendJoin(", ", ContentNotFound); - } - - if (AdditionalContentFound.Any()) - { - error.Append("Unexpected content found: ") - .AppendJoin(", ", AdditionalContentFound); - } - - return error.ToString(); - } - } - } - } -} diff --git a/src/Components/WebAssembly/Build/testassets/Directory.Build.props b/src/Components/WebAssembly/Build/testassets/Directory.Build.props deleted file mode 100644 index 109d34f261..0000000000 --- a/src/Components/WebAssembly/Build/testassets/Directory.Build.props +++ /dev/null @@ -1,30 +0,0 @@ -<Project> - <Import Project="Before.Directory.Build.props" Condition="Exists('Before.Directory.Build.props')" /> - - <!-- Test Placeholder --> - - <PropertyGroup> - <RepoRoot Condition="'$(RepoRoot)' ==''">$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), global.json))\</RepoRoot> - <ComponentsRoot>$(RepoRoot)src\Components\</ComponentsRoot> - <BlazorBuildRoot>$(ComponentsRoot)WebAssembly\Build\src\</BlazorBuildRoot> - <ReferenceBlazorBuildFromSourceProps>$(BlazorBuildRoot)ReferenceBlazorBuildFromSource.props</ReferenceBlazorBuildFromSourceProps> - - <!-- Workaround for https://github.com/dotnet/aspnetcore/issues/17308 --> - <DefaultNetCoreTargetFramework>netcoreapp3.1</DefaultNetCoreTargetFramework> - - <EnableSourceLink>false</EnableSourceLink> - <DeterministicSourcePaths>false</DeterministicSourcePaths> - </PropertyGroup> - - <Import Project="$(RepoRoot)eng\Versions.props" /> - - <ItemGroup> - <!-- Use the sample compiler \ SDK that the rest of our build uses--> - <PackageReference Include="Microsoft.Net.Compilers.Toolset" - Version="$(MicrosoftNetCompilersToolsetPackageVersion)" - PrivateAssets="all" - IsImplicitlyDefined="true" /> - </ItemGroup> - - <Import Project="$(RepoRoot)src\Razor\Microsoft.NET.Sdk.Razor\src\build\netstandard2.0\Microsoft.NET.Sdk.Razor.props"/> -</Project> diff --git a/src/Components/WebAssembly/Build/testassets/Directory.Build.targets b/src/Components/WebAssembly/Build/testassets/Directory.Build.targets deleted file mode 100644 index 8c119d5413..0000000000 --- a/src/Components/WebAssembly/Build/testassets/Directory.Build.targets +++ /dev/null @@ -1,2 +0,0 @@ -<Project> -</Project> diff --git a/src/Components/WebAssembly/Build/testassets/LinkBaseToWebRoot/js/LinkedScript.js b/src/Components/WebAssembly/Build/testassets/LinkBaseToWebRoot/js/LinkedScript.js deleted file mode 100644 index 5f282702bb..0000000000 --- a/src/Components/WebAssembly/Build/testassets/LinkBaseToWebRoot/js/LinkedScript.js +++ /dev/null @@ -1 +0,0 @@ -
\ No newline at end of file diff --git a/src/Components/WebAssembly/Build/testassets/blazorhosted/Program.cs b/src/Components/WebAssembly/Build/testassets/blazorhosted/Program.cs deleted file mode 100644 index a90f4db291..0000000000 --- a/src/Components/WebAssembly/Build/testassets/blazorhosted/Program.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using Microsoft.AspNetCore; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Configuration; - -namespace blazorhosted.Server -{ - public class Program - { - public static void Main(string[] args) - { - Console.WriteLine(typeof(IWebHost)); - GC.KeepAlive(typeof(RazorClassLibrary.Class1)); - } - } -} diff --git a/src/Components/WebAssembly/Build/testassets/blazorhosted/blazorhosted.csproj b/src/Components/WebAssembly/Build/testassets/blazorhosted/blazorhosted.csproj deleted file mode 100644 index bcdc9dba7d..0000000000 --- a/src/Components/WebAssembly/Build/testassets/blazorhosted/blazorhosted.csproj +++ /dev/null @@ -1,11 +0,0 @@ -<Project Sdk="Microsoft.NET.Sdk.Web"> - - <PropertyGroup> - <TargetFramework>net5.0</TargetFramework> - </PropertyGroup> - - <ItemGroup> - <ProjectReference Include="..\standalone\standalone.csproj" /> - </ItemGroup> - -</Project> diff --git a/src/Components/WebAssembly/Build/testassets/classlibrarywithsatelliteassemblies/Class1.cs b/src/Components/WebAssembly/Build/testassets/classlibrarywithsatelliteassemblies/Class1.cs deleted file mode 100644 index 944699cdb3..0000000000 --- a/src/Components/WebAssembly/Build/testassets/classlibrarywithsatelliteassemblies/Class1.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; - -namespace classlibrarywithsatelliteassemblies -{ - public class Class1 - { - public static void Test() - { - GC.KeepAlive(typeof(Microsoft.CodeAnalysis.CSharp.CSharpCompilation)); - } - } -}
\ No newline at end of file diff --git a/src/Components/WebAssembly/Build/testassets/classlibrarywithsatelliteassemblies/Resources.es-ES.resx b/src/Components/WebAssembly/Build/testassets/classlibrarywithsatelliteassemblies/Resources.es-ES.resx deleted file mode 100644 index 0ab8f0ddfb..0000000000 --- a/src/Components/WebAssembly/Build/testassets/classlibrarywithsatelliteassemblies/Resources.es-ES.resx +++ /dev/null @@ -1,123 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<root> - <!-- - Microsoft ResX Schema - - Version 2.0 - - The primary goals of this format is to allow a simple XML format - that is mostly human readable. The generation and parsing of the - various data types are done through the TypeConverter classes - associated with the data types. - - Example: - - ... ado.net/XML headers & schema ... - <resheader name="resmimetype">text/microsoft-resx</resheader> - <resheader name="version">2.0</resheader> - <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> - <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> - <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> - <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> - <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> - <value>[base64 mime encoded serialized .NET Framework object]</value> - </data> - <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> - <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> - <comment>This is a comment</comment> - </data> - - There are any number of "resheader" rows that contain simple - name/value pairs. - - Each data row contains a name, and value. The row also contains a - type or mimetype. Type corresponds to a .NET class that support - text/value conversion through the TypeConverter architecture. - Classes that don't support this are serialized and stored with the - mimetype set. - - The mimetype is used for serialized objects, and tells the - ResXResourceReader how to depersist the object. This is currently not - extensible. For a given mimetype the value must be set accordingly: - - Note - application/x-microsoft.net.object.binary.base64 is the format - that the ResXResourceWriter will generate, however the reader can - read any of the formats listed below. - - mimetype: application/x-microsoft.net.object.binary.base64 - value : The object must be serialized with - : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter - : and then encoded with base64 encoding. - - mimetype: application/x-microsoft.net.object.soap.base64 - value : The object must be serialized with - : System.Runtime.Serialization.Formatters.Soap.SoapFormatter - : and then encoded with base64 encoding. - - mimetype: application/x-microsoft.net.object.bytearray.base64 - value : The object must be serialized into a byte array - : using a System.ComponentModel.TypeConverter - : and then encoded with base64 encoding. - --> - <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> - <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> - <xsd:element name="root" msdata:IsDataSet="true"> - <xsd:complexType> - <xsd:choice maxOccurs="unbounded"> - <xsd:element name="metadata"> - <xsd:complexType> - <xsd:sequence> - <xsd:element name="value" type="xsd:string" minOccurs="0" /> - </xsd:sequence> - <xsd:attribute name="name" use="required" type="xsd:string" /> - <xsd:attribute name="type" type="xsd:string" /> - <xsd:attribute name="mimetype" type="xsd:string" /> - <xsd:attribute ref="xml:space" /> - </xsd:complexType> - </xsd:element> - <xsd:element name="assembly"> - <xsd:complexType> - <xsd:attribute name="alias" type="xsd:string" /> - <xsd:attribute name="name" type="xsd:string" /> - </xsd:complexType> - </xsd:element> - <xsd:element name="data"> - <xsd:complexType> - <xsd:sequence> - <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> - <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> - </xsd:sequence> - <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> - <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> - <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> - <xsd:attribute ref="xml:space" /> - </xsd:complexType> - </xsd:element> - <xsd:element name="resheader"> - <xsd:complexType> - <xsd:sequence> - <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> - </xsd:sequence> - <xsd:attribute name="name" type="xsd:string" use="required" /> - </xsd:complexType> - </xsd:element> - </xsd:choice> - </xsd:complexType> - </xsd:element> - </xsd:schema> - <resheader name="resmimetype"> - <value>text/microsoft-resx</value> - </resheader> - <resheader name="version"> - <value>2.0</value> - </resheader> - <resheader name="reader"> - <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> - </resheader> - <resheader name="writer"> - <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> - </resheader> - <data name="Hello" xml:space="preserve"> - <value>Hola</value> - </data> -</root>
\ No newline at end of file diff --git a/src/Components/WebAssembly/Build/testassets/classlibrarywithsatelliteassemblies/classlibrarywithsatelliteassemblies.csproj b/src/Components/WebAssembly/Build/testassets/classlibrarywithsatelliteassemblies/classlibrarywithsatelliteassemblies.csproj deleted file mode 100644 index 7081842748..0000000000 --- a/src/Components/WebAssembly/Build/testassets/classlibrarywithsatelliteassemblies/classlibrarywithsatelliteassemblies.csproj +++ /dev/null @@ -1,13 +0,0 @@ -<Project Sdk="Microsoft.NET.Sdk.Razor"> - - <PropertyGroup> - <TargetFramework>netstandard2.1</TargetFramework> - <RazorLangVersion>3.0</RazorLangVersion> - </PropertyGroup> - - <ItemGroup> - <!-- The compiler package contains quite a few satellite assemblies --> - <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.4.0" /> - </ItemGroup> - -</Project> diff --git a/src/Components/WebAssembly/Build/testassets/razorclasslibrary/Class1.cs b/src/Components/WebAssembly/Build/testassets/razorclasslibrary/Class1.cs deleted file mode 100644 index fb55605ff4..0000000000 --- a/src/Components/WebAssembly/Build/testassets/razorclasslibrary/Class1.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace RazorClassLibrary -{ - public class Class1 - { - } -} diff --git a/src/Components/WebAssembly/Build/testassets/razorclasslibrary/RazorClassLibrary.csproj b/src/Components/WebAssembly/Build/testassets/razorclasslibrary/RazorClassLibrary.csproj deleted file mode 100644 index 94e866815d..0000000000 --- a/src/Components/WebAssembly/Build/testassets/razorclasslibrary/RazorClassLibrary.csproj +++ /dev/null @@ -1,8 +0,0 @@ -<Project Sdk="Microsoft.NET.Sdk.Razor"> - - <PropertyGroup> - <TargetFramework>netstandard2.1</TargetFramework> - <RazorLangVersion>3.0</RazorLangVersion> - </PropertyGroup> - -</Project> diff --git a/src/Components/WebAssembly/Build/testassets/razorclasslibrary/wwwroot/styles.css b/src/Components/WebAssembly/Build/testassets/razorclasslibrary/wwwroot/styles.css deleted file mode 100644 index 5f282702bb..0000000000 --- a/src/Components/WebAssembly/Build/testassets/razorclasslibrary/wwwroot/styles.css +++ /dev/null @@ -1 +0,0 @@ -
\ No newline at end of file diff --git a/src/Components/WebAssembly/Build/testassets/razorclasslibrary/wwwroot/wwwroot/exampleJsInterop.js b/src/Components/WebAssembly/Build/testassets/razorclasslibrary/wwwroot/wwwroot/exampleJsInterop.js deleted file mode 100644 index e69de29bb2..0000000000 --- a/src/Components/WebAssembly/Build/testassets/razorclasslibrary/wwwroot/wwwroot/exampleJsInterop.js +++ /dev/null diff --git a/src/Components/WebAssembly/Build/testassets/standalone/App.razor b/src/Components/WebAssembly/Build/testassets/standalone/App.razor deleted file mode 100644 index eba23da9b5..0000000000 --- a/src/Components/WebAssembly/Build/testassets/standalone/App.razor +++ /dev/null @@ -1,8 +0,0 @@ -<Router AppAssembly="@typeof(Program).Assembly"> - <Found Context="routeData"> - <RouteView RouteData="@routeData"/> - </Found> - <NotFound> - <p>Sorry, there's nothing at this address.</p> - </NotFound> -</Router> diff --git a/src/Components/WebAssembly/Build/testassets/standalone/LinkToWebRoot/css/app.css b/src/Components/WebAssembly/Build/testassets/standalone/LinkToWebRoot/css/app.css deleted file mode 100644 index 6c9631b4e1..0000000000 --- a/src/Components/WebAssembly/Build/testassets/standalone/LinkToWebRoot/css/app.css +++ /dev/null @@ -1 +0,0 @@ -.publish { } diff --git a/src/Components/WebAssembly/Build/testassets/standalone/Pages/Index.razor b/src/Components/WebAssembly/Build/testassets/standalone/Pages/Index.razor deleted file mode 100644 index 16dac31925..0000000000 --- a/src/Components/WebAssembly/Build/testassets/standalone/Pages/Index.razor +++ /dev/null @@ -1,5 +0,0 @@ -@page "/" - -<h1>Hello, world!</h1> - -Welcome to your new app. diff --git a/src/Components/WebAssembly/Build/testassets/standalone/Program.cs b/src/Components/WebAssembly/Build/testassets/standalone/Program.cs deleted file mode 100644 index 7d2cb4eeea..0000000000 --- a/src/Components/WebAssembly/Build/testassets/standalone/Program.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; - -namespace standalone -{ - public class Program - { - public static void Main(string[] args) - { - GC.KeepAlive(typeof(RazorClassLibrary.Class1)); -#if REFERENCE_classlibrarywithsatelliteassemblies - GC.KeepAlive(typeof(classlibrarywithsatelliteassemblies.Class1)); -#endif - } - } -} diff --git a/src/Components/WebAssembly/Build/testassets/standalone/Resources.ja.resx.txt b/src/Components/WebAssembly/Build/testassets/standalone/Resources.ja.resx.txt deleted file mode 100644 index aabe84e3c0..0000000000 --- a/src/Components/WebAssembly/Build/testassets/standalone/Resources.ja.resx.txt +++ /dev/null @@ -1,123 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<root> - <!-- - Microsoft ResX Schema - - Version 2.0 - - The primary goals of this format is to allow a simple XML format - that is mostly human readable. The generation and parsing of the - various data types are done through the TypeConverter classes - associated with the data types. - - Example: - - ... ado.net/XML headers & schema ... - <resheader name="resmimetype">text/microsoft-resx</resheader> - <resheader name="version">2.0</resheader> - <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> - <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> - <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> - <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> - <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> - <value>[base64 mime encoded serialized .NET Framework object]</value> - </data> - <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> - <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> - <comment>This is a comment</comment> - </data> - - There are any number of "resheader" rows that contain simple - name/value pairs. - - Each data row contains a name, and value. The row also contains a - type or mimetype. Type corresponds to a .NET class that support - text/value conversion through the TypeConverter architecture. - Classes that don't support this are serialized and stored with the - mimetype set. - - The mimetype is used for serialized objects, and tells the - ResXResourceReader how to depersist the object. This is currently not - extensible. For a given mimetype the value must be set accordingly: - - Note - application/x-microsoft.net.object.binary.base64 is the format - that the ResXResourceWriter will generate, however the reader can - read any of the formats listed below. - - mimetype: application/x-microsoft.net.object.binary.base64 - value : The object must be serialized with - : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter - : and then encoded with base64 encoding. - - mimetype: application/x-microsoft.net.object.soap.base64 - value : The object must be serialized with - : System.Runtime.Serialization.Formatters.Soap.SoapFormatter - : and then encoded with base64 encoding. - - mimetype: application/x-microsoft.net.object.bytearray.base64 - value : The object must be serialized into a byte array - : using a System.ComponentModel.TypeConverter - : and then encoded with base64 encoding. - --> - <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> - <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> - <xsd:element name="root" msdata:IsDataSet="true"> - <xsd:complexType> - <xsd:choice maxOccurs="unbounded"> - <xsd:element name="metadata"> - <xsd:complexType> - <xsd:sequence> - <xsd:element name="value" type="xsd:string" minOccurs="0" /> - </xsd:sequence> - <xsd:attribute name="name" use="required" type="xsd:string" /> - <xsd:attribute name="type" type="xsd:string" /> - <xsd:attribute name="mimetype" type="xsd:string" /> - <xsd:attribute ref="xml:space" /> - </xsd:complexType> - </xsd:element> - <xsd:element name="assembly"> - <xsd:complexType> - <xsd:attribute name="alias" type="xsd:string" /> - <xsd:attribute name="name" type="xsd:string" /> - </xsd:complexType> - </xsd:element> - <xsd:element name="data"> - <xsd:complexType> - <xsd:sequence> - <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> - <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> - </xsd:sequence> - <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> - <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> - <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> - <xsd:attribute ref="xml:space" /> - </xsd:complexType> - </xsd:element> - <xsd:element name="resheader"> - <xsd:complexType> - <xsd:sequence> - <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> - </xsd:sequence> - <xsd:attribute name="name" type="xsd:string" use="required" /> - </xsd:complexType> - </xsd:element> - </xsd:choice> - </xsd:complexType> - </xsd:element> - </xsd:schema> - <resheader name="resmimetype"> - <value>text/microsoft-resx</value> - </resheader> - <resheader name="version"> - <value>2.0</value> - </resheader> - <resheader name="reader"> - <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> - </resheader> - <resheader name="writer"> - <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> - </resheader> - <data name="Hello" xml:space="preserve"> - <value>Konnichiwa</value> - </data> -</root>
\ No newline at end of file diff --git a/src/Components/WebAssembly/Build/testassets/standalone/_Imports.razor b/src/Components/WebAssembly/Build/testassets/standalone/_Imports.razor deleted file mode 100644 index 129b440e86..0000000000 --- a/src/Components/WebAssembly/Build/testassets/standalone/_Imports.razor +++ /dev/null @@ -1,2 +0,0 @@ -@using Microsoft.AspNetCore.Components.Routing -@using standalone diff --git a/src/Components/WebAssembly/Build/testassets/standalone/standalone.csproj b/src/Components/WebAssembly/Build/testassets/standalone/standalone.csproj deleted file mode 100644 index bbeafa77c2..0000000000 --- a/src/Components/WebAssembly/Build/testassets/standalone/standalone.csproj +++ /dev/null @@ -1,40 +0,0 @@ -<Project Sdk="Microsoft.NET.Sdk.Web"> - <Import Project="$(ReferenceBlazorBuildFromSourceProps)" /> - - <PropertyGroup> - <TargetFramework>netstandard2.1</TargetFramework> - <RazorLangVersion>3.0</RazorLangVersion> - <ServiceWorkerAssetsManifest>custom-service-worker-assets.js</ServiceWorkerAssetsManifest> - </PropertyGroup> - - <!-- Test Placeholder --> - - <ItemGroup> - <PackageReference Include="Microsoft.AspNetCore.Components" Version="3.1.3" /> - <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Runtime" Version="$(MicrosoftAspNetCoreComponentsWebAssemblyRuntimePackageVersion)" /> - </ItemGroup> - - <ItemGroup> - <ProjectReference Include="..\razorclasslibrary\RazorClassLibrary.csproj" /> - </ItemGroup> - - <ItemGroup> - <!-- These assets should be treated as static web assets for publish purposes --> - <Content Include="..\LinkBaseToWebRoot\**\*.js"> - <LinkBase>wwwroot\</LinkBase> - </Content> - - <!-- This asset should be ignored as a static web assets as it defines CopyToPublishDirectory="false" --> - <Content Update="wwwroot\css\app.css" CopyToPublishDirectory="false" /> - - <!-- This asset should be treated as a static web asset and copied into the right location defined by its link attribute. --> - <Content Include="LinkToWebRoot\css\app.css" Link="wwwroot\css\app.css" /> - - <!-- This asset should not be treated as a static web asset as it is being linked out of the wwwroot folder. --> - <Content Update="wwwroot\Fake-License.txt" Link="Excluded-Static-Web-Assets\Fake-License.txt" /> - - <!-- The content from my-prod-service-worker.js should be published under the name my-service-worker.js --> - <ServiceWorker Include="wwwroot\serviceworkers\my-service-worker.js" PublishedContent="wwwroot\serviceworkers\my-prod-service-worker.js" /> - </ItemGroup> - -</Project> diff --git a/src/Components/WebAssembly/Build/testassets/standalone/wwwroot/Fake-License.txt b/src/Components/WebAssembly/Build/testassets/standalone/wwwroot/Fake-License.txt deleted file mode 100644 index 5f282702bb..0000000000 --- a/src/Components/WebAssembly/Build/testassets/standalone/wwwroot/Fake-License.txt +++ /dev/null @@ -1 +0,0 @@ -
\ No newline at end of file diff --git a/src/Components/WebAssembly/Build/testassets/standalone/wwwroot/css/app.css b/src/Components/WebAssembly/Build/testassets/standalone/wwwroot/css/app.css deleted file mode 100644 index fc64a12376..0000000000 --- a/src/Components/WebAssembly/Build/testassets/standalone/wwwroot/css/app.css +++ /dev/null @@ -1 +0,0 @@ -.build { } diff --git a/src/Components/WebAssembly/Build/testassets/standalone/wwwroot/index.html b/src/Components/WebAssembly/Build/testassets/standalone/wwwroot/index.html deleted file mode 100644 index bbfa66c41a..0000000000 --- a/src/Components/WebAssembly/Build/testassets/standalone/wwwroot/index.html +++ /dev/null @@ -1,24 +0,0 @@ -<!DOCTYPE html> -<html> - -<head> - <meta charset="utf-8" /> - <meta name="viewport" content="width=device-width" /> - <title>standalone</title> - <base href="/" /> - <link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" /> - <link href="css/app.css" rel="stylesheet" /> -</head> - -<body> - <app>Loading...</app> - - <div id="blazor-error-ui"> - An unhandled error has occurred. - <a href="" class="reload">Reload</a> - <a class="dismiss">🗙</a> - </div> - <script src="_framework/blazor.webassembly.js"></script> -</body> - -</html> diff --git a/src/Components/WebAssembly/Build/testassets/standalone/wwwroot/serviceworkers/my-prod-service-worker.js b/src/Components/WebAssembly/Build/testassets/standalone/wwwroot/serviceworkers/my-prod-service-worker.js deleted file mode 100644 index a2ecc1b349..0000000000 --- a/src/Components/WebAssembly/Build/testassets/standalone/wwwroot/serviceworkers/my-prod-service-worker.js +++ /dev/null @@ -1 +0,0 @@ -// This is the production service worker diff --git a/src/Components/WebAssembly/Build/testassets/standalone/wwwroot/serviceworkers/my-service-worker.js b/src/Components/WebAssembly/Build/testassets/standalone/wwwroot/serviceworkers/my-service-worker.js deleted file mode 100644 index c42d1c8475..0000000000 --- a/src/Components/WebAssembly/Build/testassets/standalone/wwwroot/serviceworkers/my-service-worker.js +++ /dev/null @@ -1 +0,0 @@ -// This is the development service worker diff --git a/src/Components/WebAssembly/Compression/src/Microsoft.AspNetCore.Components.WebAssembly.Build.BrotliCompression.csproj b/src/Components/WebAssembly/Compression/src/Microsoft.AspNetCore.Components.WebAssembly.Build.BrotliCompression.csproj deleted file mode 100644 index 7267b5ed54..0000000000 --- a/src/Components/WebAssembly/Compression/src/Microsoft.AspNetCore.Components.WebAssembly.Build.BrotliCompression.csproj +++ /dev/null @@ -1,10 +0,0 @@ -<Project Sdk="Microsoft.NET.Sdk"> - - <PropertyGroup> - <TargetFramework>$(DefaultNetCoreTargetFramework)</TargetFramework> - <OutputType>Exe</OutputType> - <AssemblyName>blazor-brotli</AssemblyName> - <IsShippingPackage>false</IsShippingPackage> - </PropertyGroup> - -</Project> diff --git a/src/Components/WebAssembly/Compression/src/Program.cs b/src/Components/WebAssembly/Compression/src/Program.cs deleted file mode 100644 index 804129166b..0000000000 --- a/src/Components/WebAssembly/Compression/src/Program.cs +++ /dev/null @@ -1,91 +0,0 @@ -using System; -using System.IO; -using System.IO.Compression; -using System.Text.Json; -using System.Threading.Tasks; - -namespace Microsoft.AspNetCore.Components.WebAssembly.Build.BrotliCompression -{ - class Program - { - private const int _error = -1; - - static async Task<int> Main(string[] args) - { - if (args.Length != 1) - { - Console.Error.WriteLine("Invalid argument count. Usage: 'blazor-brotli <<path-to-manifest>>'"); - return _error; - } - - var manifestPath = args[0]; - if (!File.Exists(manifestPath)) - { - Console.Error.WriteLine($"Manifest '{manifestPath}' does not exist."); - return -1; - } - - using var manifestStream = File.OpenRead(manifestPath); - - var manifest = await JsonSerializer.DeserializeAsync<ManifestData>(manifestStream); - var result = 0; - Parallel.ForEach(manifest.FilesToCompress, (file) => - { - var inputPath = file.Source; - var inputSource = file.InputSource; - var targetCompressionPath = file.Target; - - if (!File.Exists(inputSource)) - { - Console.WriteLine($"Skipping '{inputPath}' because '{inputSource}' does not exist."); - return; - } - - if (File.Exists(targetCompressionPath) && File.GetLastWriteTimeUtc(inputSource) < File.GetLastWriteTimeUtc(targetCompressionPath)) - { - // Incrementalism. If input source doesn't exist or it exists and is not newer than the expected output, do nothing. - Console.WriteLine($"Skipping '{inputPath}' because '{targetCompressionPath}' is newer than '{inputSource}'."); - return; - } - - try - { - Directory.CreateDirectory(Path.GetDirectoryName(targetCompressionPath)); - - using var sourceStream = File.OpenRead(inputPath); - using var fileStream = new FileStream(targetCompressionPath, FileMode.Create); - - var compressionLevel = CompressionLevel.Optimal; - if (Environment.GetEnvironmentVariable("_BlazorWebAssemblyBuildTest_BrotliCompressionLevel_NoCompression") == "1") - { - compressionLevel = CompressionLevel.NoCompression; - } - using var stream = new BrotliStream(fileStream, compressionLevel); - - sourceStream.CopyTo(stream); - } - catch (Exception e) - { - Console.Error.WriteLine(e); - result = -1; - } - }); - - return result; - } - - private class ManifestData - { - public CompressedFile[] FilesToCompress { get; set; } - } - - private class CompressedFile - { - public string Source { get; set; } - - public string InputSource { get; set; } - - public string Target { get; set; } - } - } -} diff --git a/src/Components/WebAssembly/Compression/src/runtimeconfig.template.json b/src/Components/WebAssembly/Compression/src/runtimeconfig.template.json deleted file mode 100644 index f022b7ffce..0000000000 --- a/src/Components/WebAssembly/Compression/src/runtimeconfig.template.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "rollForwardOnNoCandidateFx": 2 -}
\ No newline at end of file diff --git a/src/Components/WebAssembly/WebAssembly/src/Microsoft.AspNetCore.Components.WebAssembly.csproj b/src/Components/WebAssembly/WebAssembly/src/Microsoft.AspNetCore.Components.WebAssembly.csproj index 0447c61b7e..2aab0dbca7 100644 --- a/src/Components/WebAssembly/WebAssembly/src/Microsoft.AspNetCore.Components.WebAssembly.csproj +++ b/src/Components/WebAssembly/WebAssembly/src/Microsoft.AspNetCore.Components.WebAssembly.csproj @@ -1,4 +1,4 @@ -<Project Sdk="Microsoft.NET.Sdk"> +<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>netstandard2.1</TargetFramework> @@ -15,6 +15,14 @@ <Reference Include="Microsoft.Extensions.Logging" /> <Reference Include="Microsoft.JSInterop.WebAssembly" /> + <ProjectReference + Include="..\..\..\Web.JS\Microsoft.AspNetCore.Components.Web.JS.npmproj" + ReferenceOutputAssemblies="false" + SkipGetTargetFrameworkProperties="true" + UndefineProperties="TargetFramework" + Private="false" + Condition="'$(BuildNodeJS)' != 'false' and '$(BuildingInsideVisualStudio)' != 'true'" /> + <!-- Tracking removing using https://github.com/dotnet/aspnetcore/issues/22283 --> <ProjectReference Include="..\..\WebAssemblyHttpHandler\src\Microsoft.AspNetCore.Components.WebAssembly.HttpHandler.csproj" @@ -35,4 +43,13 @@ <InternalsVisibleTo Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication.Tests" /> <InternalsVisibleTo Include="BasicTestApp" /> </ItemGroup> + + <PropertyGroup> + <BlazorWebAssemblyJSFile>..\..\..\Web.JS\dist\$(Configuration)\blazor.webassembly.js</BlazorWebAssemblyJSFile> + </PropertyGroup> + + <ItemGroup> + <Content Include="$(BlazorWebAssemblyJSFile)" Pack="true" PackagePath="build\netstandard2.0\" LinkBase="build\netstandard2.0\" /> + <Content Include="build\netstandard2.0\*.props" Pack="true" PackagePath="build\netstandard2.0\" /> + </ItemGroup> </Project> diff --git a/src/Components/WebAssembly/WebAssembly/src/build/netstandard2.0/Microsoft.AspNetCore.Components.WebAssembly.props b/src/Components/WebAssembly/WebAssembly/src/build/netstandard2.0/Microsoft.AspNetCore.Components.WebAssembly.props new file mode 100644 index 0000000000..41ae67bf35 --- /dev/null +++ b/src/Components/WebAssembly/WebAssembly/src/build/netstandard2.0/Microsoft.AspNetCore.Components.WebAssembly.props @@ -0,0 +1,5 @@ +<Project> + <PropertyGroup> + <BlazorWebAssemblyJSPath>$(MSBuildThisFileDirectory)blazor.webassembly.js</BlazorWebAssemblyJSPath> + </PropertyGroup> +</Project> diff --git a/src/Components/WebAssembly/testassets/HostedInAspNet.Client/HostedInAspNet.Client.csproj b/src/Components/WebAssembly/testassets/HostedInAspNet.Client/HostedInAspNet.Client.csproj index 84dae61bf7..4994c3eb7d 100644 --- a/src/Components/WebAssembly/testassets/HostedInAspNet.Client/HostedInAspNet.Client.csproj +++ b/src/Components/WebAssembly/testassets/HostedInAspNet.Client/HostedInAspNet.Client.csproj @@ -1,12 +1,10 @@ <Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> - <TargetFramework>netstandard2.1</TargetFramework> - <OutputType>Exe</OutputType> - <ReferenceBlazorBuildLocally>true</ReferenceBlazorBuildLocally> - <RazorLangVersion>3.0</RazorLangVersion> - <!-- Disable compression in this project so that we can validate that it can be disabled --> - <BlazorEnableCompression>false</BlazorEnableCompression> + <TargetFramework>$(DefaultNetCoreTargetFramework)</TargetFramework> + <RuntimeIdentifier>browser-wasm</RuntimeIdentifier> + <UseBlazorWebAssembly>true</UseBlazorWebAssembly> + <FixupWebAssemblyHttpHandlerReference>true</FixupWebAssemblyHttpHandlerReference> </PropertyGroup> diff --git a/src/Components/WebAssembly/testassets/MonoSanity/MonoSanity.csproj b/src/Components/WebAssembly/testassets/MonoSanity/MonoSanity.csproj deleted file mode 100644 index 00b73a99ed..0000000000 --- a/src/Components/WebAssembly/testassets/MonoSanity/MonoSanity.csproj +++ /dev/null @@ -1,16 +0,0 @@ -<Project Sdk="Microsoft.NET.Sdk.Web"> - - <PropertyGroup> - <TargetFramework>$(DefaultNetCoreTargetFramework)</TargetFramework> - </PropertyGroup> - - <ItemGroup> - <ProjectReference Include="..\MonoSanityClient\MonoSanityClient.csproj" /> - </ItemGroup> - - <ItemGroup> - <Reference Include="Microsoft.AspNetCore" /> - <Reference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" /> - </ItemGroup> - -</Project> diff --git a/src/Components/WebAssembly/testassets/MonoSanity/Program.cs b/src/Components/WebAssembly/testassets/MonoSanity/Program.cs deleted file mode 100644 index 6481e4d4bc..0000000000 --- a/src/Components/WebAssembly/testassets/MonoSanity/Program.cs +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Hosting; - -namespace MonoSanity -{ - public class Program - { - public static void Main(string[] args) - { - BuildWebHost(args).Run(); - } - - public static IHost BuildWebHost(string[] args) => - Host.CreateDefaultBuilder(args) - .ConfigureWebHostDefaults(webHostBuilder => - { - // We require this line because we run in Production environment - // and static web assets are only on by default during development. - webHostBuilder.UseStaticWebAssets(); - webHostBuilder.UseStartup<Startup>(); - }) - .Build(); - } -} diff --git a/src/Components/WebAssembly/testassets/MonoSanity/Startup.cs b/src/Components/WebAssembly/testassets/MonoSanity/Startup.cs deleted file mode 100644 index 3cf349e787..0000000000 --- a/src/Components/WebAssembly/testassets/MonoSanity/Startup.cs +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using Microsoft.AspNetCore.Builder; -using Microsoft.Extensions.DependencyInjection; - -namespace MonoSanity -{ - public class Startup - { - public void ConfigureServices(IServiceCollection services) - { - } - - public void Configure(IApplicationBuilder app) - { - app.UseDeveloperExceptionPage(); - app.UseFileServer(new FileServerOptions() { EnableDefaultFiles = true, }); - app.UseBlazorFrameworkFiles(); - app.UseStaticFiles(); - app.UseRouting(); - app.UseEndpoints(endpoints => - { - endpoints.MapFallbackToFile("index.html"); - }); - } - } -} diff --git a/src/Components/WebAssembly/testassets/MonoSanity/wwwroot/index.html b/src/Components/WebAssembly/testassets/MonoSanity/wwwroot/index.html deleted file mode 100644 index 8a42e8e5d1..0000000000 --- a/src/Components/WebAssembly/testassets/MonoSanity/wwwroot/index.html +++ /dev/null @@ -1,158 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <title>Mono sanity check</title> - <meta http-equiv="content-type" content="text/html; charset=utf-8" /> -</head> -<body> - <p>Simple sanity check to ensure the Mono runtime works in basic cases.</p> - - <fieldset> - <legend>Add numbers</legend> - <form id="addNumbers"> - <input id="addNumberA" value="123" /> + - <input id="addNumberB" value="456" /> = - <input id="addNumbersResult" readonly /> - <button type="submit" disabled>Go</button> - </form> - </fieldset> - - <fieldset> - <legend>Repeat string</legend> - <form id="repeatString"> - <input id="repeatStringStr" value="Hello" /> * - <input id="repeatStringCount" value="3" type="number" /> = - <input id="repeatStringResult" readonly /> - <button type="submit" disabled>Go</button> - </form> - </fieldset> - - <fieldset> - <legend>Trigger .NET exception</legend> - <form id="triggerException"> - <input id="triggerExceptionMessage" value="Your message here" /> - <button type="submit" disabled>Go</button> - <div><textarea rows="5" cols="80" readonly id="triggerExceptionMessageStackTrace"></textarea></div> - </form> - </fieldset> - - <fieldset> - <legend>Call JS from .NET</legend> - <form id="callJs"> - <input id="callJsEvalExpression" value="location.href" /> - <button type="submit" disabled>Go</button> - <div><textarea rows="5" cols="80" readonly id="callJsResult"></textarea></div> - </form> - </fieldset> - - <fieldset> - <legend>Call JS from .NET (no boxing)</legend> - <form id="callJsNoBoxing"> - <input id="callJsNoBoxingNumberA" value="28" /> / - <input id="callJsNoBoxingNumberB" value="4" /> = - <input id="callJsNoBoxingResult" readonly /> - <button type="submit" disabled>Go</button> - </form> - </fieldset> - - <fieldset> - <legend>Get runtime OS</legend> - <form id="getRuntimeInformation"> - <button type="submit" disabled>Get</button> - <input id="getRuntimeInformationResult" readonly /> - </form> - </fieldset> - - <p id="loadingIndicator">Loading...</p> - - <script src="loader.js"></script> - <script> - initMono(['MonoSanityClient.dll', 'MonoSanityClient.pdb'], function () { - var buttons = document.getElementsByTagName('button'); - for (var i = 0; i < buttons.length; i++) { - buttons[i].disabled = false; - } - el('loadingIndicator').style.display = 'none'; - window.isTestReady = true; // The Xunit code polls until this is true - }); - - el('addNumbers').onsubmit = function (evt) { - evt.preventDefault(); - var a = parseInt(el('addNumberA').value); - var b = parseInt(el('addNumberB').value); - var result = invokeMonoMethod('MonoSanityClient', 'MonoSanityClient', 'Examples', 'AddNumbers', [a, b]); - el('addNumbersResult').value = result; - }; - - el('repeatString').onsubmit = function (evt) { - evt.preventDefault(); - var str = el('repeatStringStr').value; - var count = parseInt(el('repeatStringCount').value); - var result = invokeMonoMethod('MonoSanityClient', 'MonoSanityClient', 'Examples', 'RepeatString', [str, count]); - el('repeatStringResult').value = result; - }; - - el('triggerException').onsubmit = function (evt) { - evt.preventDefault(); - var message = el('triggerExceptionMessage').value; - try { - invokeMonoMethod('MonoSanityClient', 'MonoSanityClient', 'Examples', 'TriggerException', [message]); - el('triggerExceptionMessageStackTrace').value = 'WARNING: No exception occurred'; - } catch (ex) { - el('triggerExceptionMessageStackTrace').value = ex.toString(); - } - }; - - el('callJs').onsubmit = function (evt) { - evt.preventDefault(); - var expression = el('callJsEvalExpression').value; - var result = invokeMonoMethod('MonoSanityClient', 'MonoSanityClient', 'Examples', 'EvaluateJavaScript', [expression]); - el('callJsResult').value = result; - }; - - el('callJsNoBoxing').onsubmit = function (evt) { - evt.preventDefault(); - var a = parseInt(el('callJsNoBoxingNumberA').value); - var b = parseInt(el('callJsNoBoxingNumberB').value); - var result = invokeMonoMethod('MonoSanityClient', 'MonoSanityClient', 'Examples', 'CallJsNoBoxing', [a, b]); - el('callJsNoBoxingResult').value = result; - }; - - el('getRuntimeInformation').onsubmit = function (evt) { - evt.preventDefault(); - var result = invokeMonoMethod('MonoSanityClient', 'MonoSanityClient', 'Examples', 'GetRuntimeInformation', []); - el('getRuntimeInformationResult').value = result; - }; - - function el(id) { - return document.getElementById(id); - } - - // Examples of functions we can invoke from .NET - - function getUserAgentString() { - return navigator.userAgent; - } - - function triggerJsException() { - throw new Error('This is a JavaScript exception.'); - } - - function evaluateJsExpression(dotNetStringExpression) { - var result = eval(dotnetStringToJavaScriptString(dotNetStringExpression)); - return result === null || result === undefined - ? result // Pass through null/undefined so we can verify this is handled upstream - : javaScriptStringToDotNetString(result.toString()); - } - - function divideNumbersUnmarshalled(a, b) { - // In this example, neither the arguments nor return value are boxed - // -- we expect to receive and return numbers directly - if (b === 0) { - throw new Error('Division by zero'); - } - return a / b; - } - </script> -</body> -</html> diff --git a/src/Components/WebAssembly/testassets/MonoSanity/wwwroot/loader.js b/src/Components/WebAssembly/testassets/MonoSanity/wwwroot/loader.js deleted file mode 100644 index ad004cee37..0000000000 --- a/src/Components/WebAssembly/testassets/MonoSanity/wwwroot/loader.js +++ /dev/null @@ -1,128 +0,0 @@ -(function () { - // Implement just enough of the DotNet.* API surface for unmarshalled interop calls to work - // in the cases used in this project - window.DotNet = { - jsCallDispatcher: { - findJSFunction: function (identifier) { - return window[identifier]; - } - } - }; - - window.initMono = function initMono(loadAssemblyUrls, onReadyCallback) { - window.Module = { - locateFile: function (fileName) { - return fileName === 'dotnet.wasm' ? '/_framework/wasm/dotnet.wasm' : fileName; - }, - onRuntimeInitialized: function () { - var allAssemblyUrls = loadAssemblyUrls.concat([ - 'netstandard.dll', - 'mscorlib.dll', - 'System.dll', - 'System.Core.dll', - 'System.Net.Http.dll', - 'System.Net.Http.WebAssemblyHttpHandler.dll', - 'WebAssembly.Bindings.dll' - ]); - - // For these tests we're using Mono's built-in mono_load_runtime_and_bcl util. - // In real apps we don't use this because we want to have more fine-grained - // control over how the requests are issued, what gets logged, etc., so for - // real apps Blazor's Boot.WebAssembly.ts implements its own equivalent. - MONO.mono_load_runtime_and_bcl( - /* vfx_prefix */ 'myapp', // Virtual filesystem root - arbitrary value - /* deploy_prefix */ '_framework/_bin', - /* enable_debugging */ 1, - allAssemblyUrls, - onReadyCallback - ); - } - }; - - addScriptTagsToDocument(); - }; - - window.invokeMonoMethod = function invokeMonoMethod(assemblyName, namespace, typeName, methodName, args) { - var assembly_load = Module.cwrap('mono_wasm_assembly_load', 'number', ['string']); - var find_class = Module.cwrap('mono_wasm_assembly_find_class', 'number', ['number', 'string', 'string']); - var find_method = Module.cwrap('mono_wasm_assembly_find_method', 'number', ['number', 'string', 'number']); - - var assembly = assembly_load(assemblyName); - var type = find_class(assembly, namespace, typeName); - var method = find_method(type, methodName, -1); - - var stack = Module.stackSave(); - try { - var resultPtr = callMethod(method, null, args); - return dotnetStringToJavaScriptString(resultPtr); - } - finally { - Module.stackRestore(stack); - } - }; - - window.dotnetStringToJavaScriptString = function dotnetStringToJavaScriptString(mono_obj) { - if (mono_obj === 0) - return null; - var mono_string_get_utf8 = Module.cwrap('mono_wasm_string_get_utf8', 'number', ['number']); - var raw = mono_string_get_utf8(mono_obj); - var res = Module.UTF8ToString(raw); - Module._free(raw); - return res; - }; - - window.javaScriptStringToDotNetString = function dotnetStringToJavaScriptString(javaScriptString) { - var mono_string = Module.cwrap('mono_wasm_string_from_js', 'number', ['string']); - return mono_string(javaScriptString); - }; - - function callMethod(method, target, args) { - var stack = Module.stackSave(); - var invoke_method = Module.cwrap('mono_wasm_invoke_method', 'number', ['number', 'number', 'number']); - - try { - var argsBuffer = Module.stackAlloc(args.length); - var exceptionFlagManagedInt = Module.stackAlloc(4); - for (var i = 0; i < args.length; ++i) { - var argVal = args[i]; - if (typeof argVal === 'number') { - var managedInt = Module.stackAlloc(4); - Module.setValue(managedInt, argVal, 'i32'); - Module.setValue(argsBuffer + i * 4, managedInt, 'i32'); - } else if (typeof argVal === 'string') { - var managedString = javaScriptStringToDotNetString(argVal); - Module.setValue(argsBuffer + i * 4, managedString, 'i32'); - } else { - throw new Error('Unsupported arg type: ' + typeof argVal); - } - } - Module.setValue(exceptionFlagManagedInt, 0, 'i32'); - - var res = invoke_method(method, target, argsBuffer, exceptionFlagManagedInt); - - if (Module.getValue(exceptionFlagManagedInt, 'i32') !== 0) { - throw new Error(dotnetStringToJavaScriptString(res)); - } - - return res; - } finally { - Module.stackRestore(stack); - } - } - - async function addScriptTagsToDocument() { - var browserSupportsNativeWebAssembly = typeof WebAssembly !== 'undefined' && WebAssembly.validate; - if (!browserSupportsNativeWebAssembly) { - throw new Error('This browser does not support WebAssembly.'); - } - - var bootJson = await fetch('/_framework/blazor.boot.json').then(res => res.json()); - var dotNetJsResourceName = Object.keys(bootJson.resources.runtime) - .filter(name => name.endsWith('.js')); - - var scriptElem = document.createElement('script'); - scriptElem.src = '/_framework/wasm/' + dotNetJsResourceName; - document.body.appendChild(scriptElem); - } - -})(); diff --git a/src/Components/WebAssembly/testassets/MonoSanityClient/Examples.cs b/src/Components/WebAssembly/testassets/MonoSanityClient/Examples.cs deleted file mode 100644 index 7bae673449..0000000000 --- a/src/Components/WebAssembly/testassets/MonoSanityClient/Examples.cs +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using WebAssembly.JSInterop; -using System; -using System.Runtime.InteropServices; -using System.Text; -using System.Net.Http; - -namespace MonoSanityClient -{ - public static class Examples - { - public static string AddNumbers(int a, int b) - => (a + b).ToString(); - - public static string RepeatString(string str, int count) - { - var result = new StringBuilder(); - - for (var i = 0; i < count; i++) - { - result.Append(str); - } - - return result.ToString(); - } - - public static void TriggerException(string message) - { - throw new InvalidOperationException(message); - } - - public static string EvaluateJavaScript(string expression) - { - var result = InternalCalls.InvokeJSUnmarshalled<string, string, object, object>(out var exceptionMessage, "evaluateJsExpression", expression, null, null); - if (exceptionMessage != null) - { - return $".NET got exception: {exceptionMessage}"; - } - - return $".NET received: {(result ?? "(NULL)")}"; - } - - public static string CallJsNoBoxing(int numberA, int numberB) - { - // For tests that call this method, we'll exercise the 'BlazorInvokeJS' code path - // since that doesn't box the params - var result = InternalCalls.InvokeJSUnmarshalled<int, int, object, int>(out var exceptionMessage, "divideNumbersUnmarshalled", numberA, numberB, null); - if (exceptionMessage != null) - { - return $".NET got exception: {exceptionMessage}"; - } - - return $".NET received: {result}"; - } - - public static string GetRuntimeInformation() - => $"OSDescription: '{RuntimeInformation.OSDescription}';" - + $" OSArchitecture: '{RuntimeInformation.OSArchitecture}';" - + $" IsOSPlatform(BROWSER): '{RuntimeInformation.IsOSPlatform(OSPlatform.Create("BROWSER"))}'"; - } -} diff --git a/src/Components/WebAssembly/testassets/MonoSanityClient/InternalCalls.cs b/src/Components/WebAssembly/testassets/MonoSanityClient/InternalCalls.cs deleted file mode 100644 index 0fb15337e8..0000000000 --- a/src/Components/WebAssembly/testassets/MonoSanityClient/InternalCalls.cs +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Runtime.CompilerServices; - -namespace WebAssembly.JSInterop -{ - // This file is copied from https://github.com/dotnet/jsinterop/blob/master/src/Mono.WebAssembly.Interop/InternalCalls.cs - // so that MonoSanityClient can directly use the same underlying interop APIs (because - // we're trying to observe the behavior of the Mono runtime itself, not JSInterop). - - internal class InternalCalls - { - // The exact namespace, type, and method names must match the corresponding entries - // in driver.c in the Mono distribution - - // We're passing asyncHandle by ref not because we want it to be writable, but so it gets - // passed as a pointer (4 bytes). We can pass 4-byte values, but not 8-byte ones. - [MethodImpl(MethodImplOptions.InternalCall)] - public static extern string InvokeJSMarshalled(out string exception, ref long asyncHandle, string functionIdentifier, string argsJson); - - [MethodImpl(MethodImplOptions.InternalCall)] - public static extern TRes InvokeJSUnmarshalled<T0, T1, T2, TRes>(out string exception, string functionIdentifier, T0 arg0, T1 arg1, T2 arg2); - } -} diff --git a/src/Components/WebAssembly/testassets/MonoSanityClient/MonoSanityClient.csproj b/src/Components/WebAssembly/testassets/MonoSanityClient/MonoSanityClient.csproj deleted file mode 100644 index 9df38c64eb..0000000000 --- a/src/Components/WebAssembly/testassets/MonoSanityClient/MonoSanityClient.csproj +++ /dev/null @@ -1,13 +0,0 @@ -<Project Sdk="Microsoft.NET.Sdk.Razor" TreatAsLocalProperty="BlazorWebAssemblyEnableLinking"> - - <PropertyGroup> - <TargetFramework>netstandard2.1</TargetFramework> - <BlazorWebAssemblyEnableLinking>false</BlazorWebAssemblyEnableLinking> - <OutputType>exe</OutputType> - <RazorLangVersion>3.0</RazorLangVersion> - - <ReferenceBlazorBuildLocally>true</ReferenceBlazorBuildLocally> - <!-- loader.js is hard-coded to assume it can load .pdbs regardless of Debug/Release configuration --> - <BlazorEnableDebugging>true</BlazorEnableDebugging> - </PropertyGroup> -</Project> diff --git a/src/Components/WebAssembly/testassets/MonoSanityClient/Program.cs b/src/Components/WebAssembly/testassets/MonoSanityClient/Program.cs deleted file mode 100644 index 3bba6ffba6..0000000000 --- a/src/Components/WebAssembly/testassets/MonoSanityClient/Program.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -namespace MonoSanityClient -{ - // Note: Not used at runtime. This exists only to give the server app some type to reference. - // In realistic scenarios you'd have a Program class for real. - - public class Program - { - static void Main() - { - } - } -} diff --git a/src/Components/WebAssembly/testassets/StandaloneApp/StandaloneApp.csproj b/src/Components/WebAssembly/testassets/StandaloneApp/StandaloneApp.csproj index 8959978daa..9ebf31c365 100644 --- a/src/Components/WebAssembly/testassets/StandaloneApp/StandaloneApp.csproj +++ b/src/Components/WebAssembly/testassets/StandaloneApp/StandaloneApp.csproj @@ -1,9 +1,9 @@ <Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> - <TargetFramework>netstandard2.1</TargetFramework> - <ReferenceBlazorBuildLocally>true</ReferenceBlazorBuildLocally> - <RazorLangVersion>3.0</RazorLangVersion> + <TargetFramework>net5.0</TargetFramework> + <RuntimeIdentifier>browser-wasm</RuntimeIdentifier> + <UseBlazorWebAssembly>true</UseBlazorWebAssembly> <FixupWebAssemblyHttpHandlerReference>true</FixupWebAssemblyHttpHandlerReference> </PropertyGroup> diff --git a/src/Components/WebAssembly/testassets/Wasm.Authentication.Client/Wasm.Authentication.Client.csproj b/src/Components/WebAssembly/testassets/Wasm.Authentication.Client/Wasm.Authentication.Client.csproj index 6ade900b99..16fddd3ddc 100644 --- a/src/Components/WebAssembly/testassets/Wasm.Authentication.Client/Wasm.Authentication.Client.csproj +++ b/src/Components/WebAssembly/testassets/Wasm.Authentication.Client/Wasm.Authentication.Client.csproj @@ -1,9 +1,10 @@ <Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> - <TargetFramework>netstandard2.1</TargetFramework> - <RazorLangVersion>3.0</RazorLangVersion> - <ReferenceBlazorBuildLocally>true</ReferenceBlazorBuildLocally> + <TargetFramework>$(DefaultNetCoreTargetFramework)</TargetFramework> + <RuntimeIdentifier>browser-wasm</RuntimeIdentifier> + <UseBlazorWebAssembly>true</UseBlazorWebAssembly> + <FixupWebAssemblyHttpHandlerReference>true</FixupWebAssemblyHttpHandlerReference> </PropertyGroup> diff --git a/src/Components/benchmarkapps/Wasm.Performance/TestApp/Wasm.Performance.TestApp.csproj b/src/Components/benchmarkapps/Wasm.Performance/TestApp/Wasm.Performance.TestApp.csproj index 57de501f63..54ec8b638d 100644 --- a/src/Components/benchmarkapps/Wasm.Performance/TestApp/Wasm.Performance.TestApp.csproj +++ b/src/Components/benchmarkapps/Wasm.Performance/TestApp/Wasm.Performance.TestApp.csproj @@ -1,9 +1,9 @@ <Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> - <TargetFramework>netstandard2.1</TargetFramework> - <RazorLangVersion>3.0</RazorLangVersion> - <ReferenceBlazorBuildLocally>true</ReferenceBlazorBuildLocally> + <TargetFramework>net5.0</TargetFramework> + <RuntimeIdentifier>browser-wasm</RuntimeIdentifier> + <UseBlazorWebAssembly>true</UseBlazorWebAssembly> <IsTestAssetProject>true</IsTestAssetProject> </PropertyGroup> diff --git a/src/Components/test/E2ETest/Microsoft.AspNetCore.Components.E2ETests.csproj b/src/Components/test/E2ETest/Microsoft.AspNetCore.Components.E2ETests.csproj index fb063e00c8..256ea831e1 100644 --- a/src/Components/test/E2ETest/Microsoft.AspNetCore.Components.E2ETests.csproj +++ b/src/Components/test/E2ETest/Microsoft.AspNetCore.Components.E2ETests.csproj @@ -40,8 +40,6 @@ <ProjectReference Include="..\..\benchmarkapps\Wasm.Performance\TestApp\Wasm.Performance.TestApp.csproj" /> <ProjectReference Include="..\..\WebAssembly\testassets\HostedInAspNet.Client\HostedInAspNet.Client.csproj" /> <ProjectReference Include="..\..\WebAssembly\testassets\HostedInAspNet.Server\HostedInAspNet.Server.csproj" /> - <ProjectReference Include="..\..\WebAssembly\testassets\MonoSanityClient\MonoSanityClient.csproj" /> - <ProjectReference Include="..\..\WebAssembly\testassets\MonoSanity\MonoSanity.csproj" /> <ProjectReference Include="..\..\WebAssembly\testassets\StandaloneApp\StandaloneApp.csproj" /> <ProjectReference Include="..\..\WebAssembly\DevServer\src\Microsoft.AspNetCore.Components.WebAssembly.DevServer.csproj" /> <ProjectReference Include="..\testassets\BasicTestApp\BasicTestApp.csproj" /> diff --git a/src/Components/test/E2ETest/Tests/BootResourceCachingTest.cs b/src/Components/test/E2ETest/Tests/BootResourceCachingTest.cs index f273f5e53f..1dd32e8221 100644 --- a/src/Components/test/E2ETest/Tests/BootResourceCachingTest.cs +++ b/src/Components/test/E2ETest/Tests/BootResourceCachingTest.cs @@ -48,7 +48,6 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests var initialResourcesRequested = GetAndClearRequestedPaths(); Assert.NotEmpty(initialResourcesRequested.Where(path => path.EndsWith("/blazor.boot.json"))); Assert.NotEmpty(initialResourcesRequested.Where(path => path.EndsWith("/dotnet.wasm"))); - Assert.NotEmpty(initialResourcesRequested.Where(path => path.EndsWith("/dotnet.timezones.dat"))); Assert.NotEmpty(initialResourcesRequested.Where(path => path.EndsWith(".js"))); Assert.NotEmpty(initialResourcesRequested.Where(path => path.EndsWith(".dll"))); @@ -60,7 +59,6 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests var subsequentResourcesRequested = GetAndClearRequestedPaths(); Assert.NotEmpty(initialResourcesRequested.Where(path => path.EndsWith("/blazor.boot.json"))); Assert.Empty(subsequentResourcesRequested.Where(path => path.EndsWith("/dotnet.wasm"))); - Assert.Empty(subsequentResourcesRequested.Where(path => path.EndsWith("/dotnet.timezones.dat"))); Assert.NotEmpty(subsequentResourcesRequested.Where(path => path.EndsWith(".js"))); Assert.Empty(subsequentResourcesRequested.Where(path => path.EndsWith(".dll"))); } diff --git a/src/Components/test/E2ETest/Tests/MonoSanityTest.cs b/src/Components/test/E2ETest/Tests/MonoSanityTest.cs deleted file mode 100644 index 181a1f9974..0000000000 --- a/src/Components/test/E2ETest/Tests/MonoSanityTest.cs +++ /dev/null @@ -1,157 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using Microsoft.AspNetCore.Components.E2ETest.Infrastructure; -using Microsoft.AspNetCore.Components.E2ETest.Infrastructure.ServerFixtures; -using Microsoft.AspNetCore.E2ETesting; -using OpenQA.Selenium; -using OpenQA.Selenium.Support.UI; -using System; -using System.Threading.Tasks; -using Xunit; -using Xunit.Abstractions; - -namespace Microsoft.AspNetCore.Components.E2ETest.Tests -{ - public class MonoSanityTest : ServerTestBase<AspNetSiteServerFixture> - { - public MonoSanityTest( - BrowserFixture browserFixture, - AspNetSiteServerFixture serverFixture, - ITestOutputHelper output) - : base(browserFixture, serverFixture, output) - { - serverFixture.BuildWebHostMethod = MonoSanity.Program.BuildWebHost; - } - - protected override void InitializeAsyncCore() - { - Navigate("/", noReload: true); - WaitUntilMonoRunningInBrowser(); - } - - private void WaitUntilMonoRunningInBrowser() - { - new WebDriverWait(Browser, TimeSpan.FromSeconds(30)).Until(driver => - { - return ((IJavaScriptExecutor)driver) - .ExecuteScript("return window.isTestReady;"); - }); - } - - [Fact] - public void HasTitle() - { - Assert.Equal("Mono sanity check", Browser.Title); - } - - [Fact] - public void CanAddNumbers() - { - SetValue(Browser, "addNumberA", "1001"); - SetValue(Browser, "addNumberB", "2002"); - Browser.FindElement(By.CssSelector("#addNumbers button")).Click(); - - Assert.Equal("3003", GetValue(Browser, "addNumbersResult")); - } - - [Fact] - public void CanRepeatString() - { - SetValue(Browser, "repeatStringStr", "Test"); - SetValue(Browser, "repeatStringCount", "5"); - Browser.FindElement(By.CssSelector("#repeatString button")).Click(); - - Assert.Equal("TestTestTestTestTest", GetValue(Browser, "repeatStringResult")); - } - - [Fact] - public void CanReceiveDotNetExceptionInJavaScript() - { - SetValue(Browser, "triggerExceptionMessage", "Hello from test"); - Browser.FindElement(By.CssSelector("#triggerException button")).Click(); - - Assert.Contains("Hello from test", GetValue(Browser, "triggerExceptionMessageStackTrace")); - } - - [Fact] - public void CanCallJavaScriptFromDotNet() - { - SetValue(Browser, "callJsEvalExpression", "getUserAgentString()"); - Browser.FindElement(By.CssSelector("#callJs button")).Click(); - var result = GetValue(Browser, "callJsResult"); - Assert.StartsWith(".NET received: Mozilla", result); - } - - [Fact] - public void CanReceiveJavaScriptExceptionInDotNet() - { - SetValue(Browser, "callJsEvalExpression", "triggerJsException()"); - Browser.FindElement(By.CssSelector("#callJs button")).Click(); - var result = GetValue(Browser, "callJsResult"); - Assert.StartsWith(".NET got exception: This is a JavaScript exception.", result); - - // Also verify we got a stack trace - Assert.Contains("at triggerJsException", result); - } - - [Fact] - public void CanEvaluateJsExpressionThatResultsInNull() - { - SetValue(Browser, "callJsEvalExpression", "null"); - Browser.FindElement(By.CssSelector("#callJs button")).Click(); - var result = GetValue(Browser, "callJsResult"); - Assert.Equal(".NET received: (NULL)", result); - } - - [Fact] - public void CanEvaluateJsExpressionThatResultsInUndefined() - { - SetValue(Browser, "callJsEvalExpression", "console.log('Not returning anything')"); - Browser.FindElement(By.CssSelector("#callJs button")).Click(); - var result = GetValue(Browser, "callJsResult"); - Assert.Equal(".NET received: (NULL)", result); - } - - [Fact] - public void CanCallJsFunctionsWithoutBoxing() - { - SetValue(Browser, "callJsNoBoxingNumberA", "108"); - SetValue(Browser, "callJsNoBoxingNumberB", "4"); - Browser.FindElement(By.CssSelector("#callJsNoBoxing button")).Click(); - Assert.Equal(".NET received: 27", GetValue(Browser, "callJsNoBoxingResult")); - } - - [Fact] - public void CanCallJsFunctionsWithoutBoxingAndReceiveException() - { - SetValue(Browser, "callJsNoBoxingNumberA", "1"); - SetValue(Browser, "callJsNoBoxingNumberB", "0"); - Browser.FindElement(By.CssSelector("#callJsNoBoxing button")).Click(); - - Assert.StartsWith(".NET got exception: Division by zero", GetValue(Browser, "callJsNoBoxingResult")); - } - - [Fact] - public void ReturnsExpectedRuntimeInformation() - { - Browser.FindElement(By.CssSelector("#getRuntimeInformation button")).Click(); - Assert.Equal( - "OSDescription: 'web'; OSArchitecture: 'X86'; IsOSPlatform(BROWSER): 'True'", - GetValue(Browser, "getRuntimeInformationResult")); - } - - private static string GetValue(IWebDriver webDriver, string elementId) - { - var element = webDriver.FindElement(By.Id(elementId)); - return element.GetAttribute("value"); - } - - private static void SetValue(IWebDriver webDriver, string elementId, string value) - { - var element = webDriver.FindElement(By.Id(elementId)); - element.Clear(); - element.SendKeys(value); - } - } -} diff --git a/src/Components/test/E2ETest/Tests/WebAssemblyAuthenticationTests.cs b/src/Components/test/E2ETest/Tests/WebAssemblyAuthenticationTests.cs index 8fce8f9513..998144b33c 100644 --- a/src/Components/test/E2ETest/Tests/WebAssemblyAuthenticationTests.cs +++ b/src/Components/test/E2ETest/Tests/WebAssemblyAuthenticationTests.cs @@ -66,7 +66,7 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests [Fact] public void WasmAuthentication_Loads() { - Assert.Equal("Wasm.Authentication.Client", Browser.Title); + Browser.Equal("Wasm.Authentication.Client", () => Browser.Title); } [Fact] @@ -408,8 +408,8 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests private void WaitUntilLoaded(bool skipHeader = false) { - new WebDriverWait(Browser, TimeSpan.FromSeconds(30)).Until( - driver => driver.FindElement(By.TagName("app")).Text != "Loading..."); + Browser.Exists(By.TagName("app")); + Browser.True(() => Browser.FindElement(By.TagName("app")).Text != "Loading..."); if (!skipHeader) { diff --git a/src/Components/test/E2ETest/Tests/WebAssemblyGlobalizationTest.cs b/src/Components/test/E2ETest/Tests/WebAssemblyGlobalizationTest.cs index bf5fcb6f62..a18343dd75 100644 --- a/src/Components/test/E2ETest/Tests/WebAssemblyGlobalizationTest.cs +++ b/src/Components/test/E2ETest/Tests/WebAssemblyGlobalizationTest.cs @@ -10,11 +10,13 @@ using OpenQA.Selenium; using Xunit; using Xunit.Abstractions; -namespace Microsoft.AspNetCore.Components.E2ETest.ServerExecutionTests +namespace Microsoft.AspNetCore.Components.E2ETest.Tests { // For now this is limited to server-side execution because we don't have the ability to set the // culture in client-side Blazor. - public class WebAssemblyGlobalizationTest : GlobalizationTest<ToggleExecutionModeServerFixture<Program>> + // This type is internal since localization currently does not work. + // Make it public onc https://github.com/dotnet/runtime/issues/38124 is resolved. + internal class WebAssemblyGlobalizationTest : GlobalizationTest<ToggleExecutionModeServerFixture<Program>> { public WebAssemblyGlobalizationTest( BrowserFixture browserFixture, diff --git a/src/Components/test/E2ETest/Tests/WebAssemblyLocalizationTest.cs b/src/Components/test/E2ETest/Tests/WebAssemblyLocalizationTest.cs index 81c99ccf67..184c62e33c 100644 --- a/src/Components/test/E2ETest/Tests/WebAssemblyLocalizationTest.cs +++ b/src/Components/test/E2ETest/Tests/WebAssemblyLocalizationTest.cs @@ -22,7 +22,7 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests { } - [Theory] + [Theory(Skip = "https://github.com/dotnet/runtime/issues/38124")] [InlineData("en-US", "Hello!")] [InlineData("fr-FR", "Bonjour!")] public void CanSetCultureAndReadLocalizedResources(string culture, string message) diff --git a/src/Components/test/E2ETest/Tests/WebAssemblyLoggingTest.cs b/src/Components/test/E2ETest/Tests/WebAssemblyLoggingTest.cs index 5d83568f50..c6440eecd8 100644 --- a/src/Components/test/E2ETest/Tests/WebAssemblyLoggingTest.cs +++ b/src/Components/test/E2ETest/Tests/WebAssemblyLoggingTest.cs @@ -52,7 +52,8 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests AssertLogContainsCriticalMessages( "crit: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]", "[Custom logger] Unhandled exception rendering component: Here is the outer exception", - "System.InvalidTimeZoneException: Here is the outer exception ---> System.ArithmeticException: Here is the inner exception", + "System.InvalidTimeZoneException: Here is the outer exception", + "System.ArithmeticException: Here is the inner exception", "at BasicTestApp.ErrorComponent.ThrowInner"); } diff --git a/src/Components/test/E2ETest/Tests/WebAssemblyStringComparisonTest.cs b/src/Components/test/E2ETest/Tests/WebAssemblyStringComparisonTest.cs index 9a38268403..61eb71c618 100644 --- a/src/Components/test/E2ETest/Tests/WebAssemblyStringComparisonTest.cs +++ b/src/Components/test/E2ETest/Tests/WebAssemblyStringComparisonTest.cs @@ -21,7 +21,7 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests { } - [Fact] + [Fact(Skip = "https://github.com/dotnet/runtime/issues/38126")] public void InvariantCultureWorksAsExpected() { Navigate(ServerPathBase, noReload: false); diff --git a/src/Components/test/testassets/BasicTestApp/BasicTestApp.csproj b/src/Components/test/testassets/BasicTestApp/BasicTestApp.csproj index 1cba39fcde..3923c0d5c0 100644 --- a/src/Components/test/testassets/BasicTestApp/BasicTestApp.csproj +++ b/src/Components/test/testassets/BasicTestApp/BasicTestApp.csproj @@ -1,10 +1,10 @@ <Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> - <TargetFramework>netstandard2.1</TargetFramework> - <RazorLangVersion>3.0</RazorLangVersion> + <TargetFramework>$(DefaultNetCoreTargetFramework)</TargetFramework> + <UseBlazorWebAssembly>true</UseBlazorWebAssembly> + <RuntimeIdentifier>browser-wasm</RuntimeIdentifier> - <ReferenceBlazorBuildLocally>true</ReferenceBlazorBuildLocally> <!-- Must be defined before ReferenceFromSource.props is imported --> <AdditionalRunArguments>--pathbase /subdir</AdditionalRunArguments> diff --git a/src/Components/test/testassets/BasicTestApp/Program.cs b/src/Components/test/testassets/BasicTestApp/Program.cs index 01d7c29f00..b512810bc1 100644 --- a/src/Components/test/testassets/BasicTestApp/Program.cs +++ b/src/Components/test/testassets/BasicTestApp/Program.cs @@ -42,7 +42,7 @@ namespace BasicTestApp builder.Logging.Services.AddSingleton<ILoggerProvider, PrependMessageLoggerProvider>(s => new PrependMessageLoggerProvider(builder.Configuration["Logging:PrependMessage:Message"], s.GetService<IJSRuntime>())); - + var host = builder.Build(); ConfigureCulture(host); diff --git a/src/Components/test/testassets/BasicTestApp/wwwroot/js/jsinteroptests.js b/src/Components/test/testassets/BasicTestApp/wwwroot/js/jsinteroptests.js index a1f7975a90..dbbba1e0c8 100644 --- a/src/Components/test/testassets/BasicTestApp/wwwroot/js/jsinteroptests.js +++ b/src/Components/test/testassets/BasicTestApp/wwwroot/js/jsinteroptests.js @@ -258,4 +258,4 @@ function receiveDotNetObjectByRefAsync(incomingData) { testDto: testDto }; }); -} +}
\ No newline at end of file diff --git a/src/Components/test/testassets/ComponentsApp.App/ComponentsApp.App.csproj b/src/Components/test/testassets/ComponentsApp.App/ComponentsApp.App.csproj index 470c119f13..2680ed8709 100644 --- a/src/Components/test/testassets/ComponentsApp.App/ComponentsApp.App.csproj +++ b/src/Components/test/testassets/ComponentsApp.App/ComponentsApp.App.csproj @@ -1,8 +1,7 @@ <Project Sdk="Microsoft.NET.Sdk.Razor"> <PropertyGroup> - <TargetFramework>netstandard2.0</TargetFramework> - <RazorLangVersion>3.0</RazorLangVersion> + <TargetFramework>$(DefaultNetCoreTargetFramework)</TargetFramework> </PropertyGroup> <ItemGroup> |