From 8765e240b55c3e6b5b09cbbea7fcbae4c76179b8 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Mon, 7 Oct 2024 12:39:05 +0200 Subject: [PATCH 1/4] [msbuild] Add support for including alternate app icons in the compiled asset catalog. --- docs/build-apps/build-items.md | 21 + docs/build-apps/build-properties.md | 40 ++ .../MSBStrings.resx | 34 + msbuild/Xamarin.MacDev.Tasks/Tasks/ACTool.cs | 103 ++- msbuild/Xamarin.Shared/Xamarin.Shared.targets | 3 + tests/dotnet/AppWithXCAssets/AppDelegate.cs | 82 ++- .../Content.imageset/Contents.json | 2 +- .../Content.imageset/Contents.json | 2 +- .../Content.imageset/Contents.json | 2 +- .../Content.imageset/Contents.json | 2 +- .../Content.imageset/Icon400x240 1.png | Bin 22054 -> 0 bytes .../Content.imageset/Contents.json | 2 +- .../Content.imageset/Icon400x240 1.png | Bin 22054 -> 0 bytes .../Content.imageset/Contents.json | 2 +- .../Content.imageset/Icon400x240 1.png | Bin 22054 -> 0 bytes .../Content.imageset/Contents.json | 2 +- .../Content.imageset/Icon400x240 1.png | Bin 22054 -> 0 bytes .../Content.imageset/Contents.json | 2 +- .../Content.imageset/Icon400x240 1.png | Bin 22054 -> 0 bytes .../Content.imageset/Contents.json | 2 +- .../Content.imageset/Icon400x240 1.png | Bin 22054 -> 0 bytes tests/dotnet/AppWithXCAssets/shared.csproj | 11 + tests/dotnet/AppWithXCAssets/shared.mk | 1 + .../Content.imageset/Contents.json | 0 .../Content.imageset/Icon-green-400x240.png | Bin .../Back.imagestacklayer/Contents.json | 0 .../Contents.json | 0 .../Content.imageset/Contents.json | 0 .../Content.imageset/Icon-green-400x240.png | Bin .../Front.imagestacklayer/Contents.json | 0 .../Content.imageset/Contents.json | 0 .../Content.imageset/Icon-green-400x240.png | Bin .../Middle.imagestacklayer/Contents.json | 0 .../Content.imageset/Contents.json | 2 +- .../Content.imageset/Icon1280x768.png} | Bin .../Back.imagestacklayer/Contents.json | 0 .../Contents.json | 0 .../Content.imageset/Contents.json | 2 +- .../Content.imageset/Icon1280x768.png} | Bin .../Front.imagestacklayer/Contents.json | 0 .../Content.imageset/Contents.json | 2 +- .../Content.imageset/Icon1280x768.png} | Bin .../Middle.imagestacklayer/Contents.json | 0 .../Content.imageset/Contents.json | 18 + .../Content.imageset/Icon400x240.png} | Bin .../Back.imagestacklayer/Contents.json | 0 .../AppIcon.imagestack}/Contents.json | 0 .../Content.imageset/Contents.json | 18 + .../Content.imageset/Icon400x240.png} | Bin .../Front.imagestacklayer/Contents.json | 0 .../Content.imageset/Contents.json | 18 + .../Content.imageset/Icon400x240.png} | Bin .../Middle.imagestacklayer/Contents.json | 0 .../Contents.json | 4 +- .../Content.imageset/Contents.json | 0 .../Content.imageset/Icon-blue-1280x768.png | Bin .../Back.imagestacklayer/Contents.json | 0 .../Contents.json | 0 .../Content.imageset/Contents.json | 0 .../Content.imageset/Icon-blue-1280x768.png | Bin .../Front.imagestacklayer/Contents.json | 0 .../Content.imageset/Contents.json | 0 .../Content.imageset/Icon-blue-1280x768.png | Bin .../Middle.imagestacklayer/Contents.json | 0 .../Content.imageset/Contents.json | 0 .../Content.imageset/Icon-blue-400x240.png | Bin .../Back.imagestacklayer/Contents.json | 6 + .../AppIcons.imagestack/Contents.json | 17 + .../Content.imageset/Contents.json | 0 .../Content.imageset/Icon-blue-400x240.png | Bin .../Front.imagestacklayer/Contents.json | 6 + .../Content.imageset/Contents.json | 0 .../Content.imageset/Icon-blue-400x240.png | Bin .../Middle.imagestacklayer/Contents.json | 6 + .../Contents.json | 0 .../TopShelfImage.imageset/Contents.json | 0 .../Icon-blue-1920x720.png | Bin .../Icon-blue-3840x1440.png | Bin .../TopShelfImageWide.imageset/Contents.json | 0 .../Icon-blue-2320x720.png | Bin .../Icon-blue-4640x1440.png | Bin tests/dotnet/UnitTests/AppIconTest.cs | 642 ++++++++++++++++++ tests/dotnet/UnitTests/AssetsTest.cs | 49 +- .../TaskTests/ACToolTaskTest.cs | 447 ++++++++++++ .../TestHelpers/Logger.cs | 29 + .../TestHelpers/TestBase.cs | 5 +- .../Xamarin.MacDev.Tasks.Tests.csproj | 3 + 87 files changed, 1540 insertions(+), 47 deletions(-) delete mode 100644 tests/dotnet/AppWithXCAssets/iOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Back.imagestacklayer/Content.imageset/Icon400x240 1.png delete mode 100644 tests/dotnet/AppWithXCAssets/iOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Front.imagestacklayer/Content.imageset/Icon400x240 1.png delete mode 100644 tests/dotnet/AppWithXCAssets/iOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Middle.imagestacklayer/Content.imageset/Icon400x240 1.png delete mode 100644 tests/dotnet/AppWithXCAssets/macOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Back.imagestacklayer/Content.imageset/Icon400x240 1.png delete mode 100644 tests/dotnet/AppWithXCAssets/macOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Front.imagestacklayer/Content.imageset/Icon400x240 1.png delete mode 100644 tests/dotnet/AppWithXCAssets/macOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Middle.imagestacklayer/Content.imageset/Icon400x240 1.png rename tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/{AlternateBrandAssets.brandassets => }/AlternateAppIcons.imagestack/Back.imagestacklayer/Content.imageset/Contents.json (100%) rename tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/{AlternateBrandAssets.brandassets => }/AlternateAppIcons.imagestack/Back.imagestacklayer/Content.imageset/Icon-green-400x240.png (100%) rename tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/{AlternateBrandAssets.brandassets/AlternateAppIcons-AppStore.imagestack => AlternateAppIcons.imagestack}/Back.imagestacklayer/Contents.json (100%) rename tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/{AlternateBrandAssets.brandassets/AlternateAppIcons-AppStore.imagestack => AlternateAppIcons.imagestack}/Contents.json (100%) rename tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/{AlternateBrandAssets.brandassets => }/AlternateAppIcons.imagestack/Front.imagestacklayer/Content.imageset/Contents.json (100%) rename tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/{AlternateBrandAssets.brandassets => }/AlternateAppIcons.imagestack/Front.imagestacklayer/Content.imageset/Icon-green-400x240.png (100%) rename tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/{AlternateBrandAssets.brandassets/AlternateAppIcons-AppStore.imagestack => AlternateAppIcons.imagestack}/Front.imagestacklayer/Contents.json (100%) rename tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/{AlternateBrandAssets.brandassets => }/AlternateAppIcons.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json (100%) rename tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/{AlternateBrandAssets.brandassets => }/AlternateAppIcons.imagestack/Middle.imagestacklayer/Content.imageset/Icon-green-400x240.png (100%) rename tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/{AlternateBrandAssets.brandassets/AlternateAppIcons-AppStore.imagestack => AlternateAppIcons.imagestack}/Middle.imagestacklayer/Contents.json (100%) rename tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/{AlternateAppIcons-AppStore.imagestack => AppIcon-AppStore.imagestack}/Back.imagestacklayer/Content.imageset/Contents.json (71%) rename tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/{AlternateAppIcons-AppStore.imagestack/Back.imagestacklayer/Content.imageset/Icon-green-1280x768.png => AppIcon-AppStore.imagestack/Back.imagestacklayer/Content.imageset/Icon1280x768.png} (100%) rename tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/{AlternateAppIcons.imagestack => AppIcon-AppStore.imagestack}/Back.imagestacklayer/Contents.json (100%) rename tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/{AlternateAppIcons.imagestack => AppIcon-AppStore.imagestack}/Contents.json (100%) rename tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/{AlternateAppIcons-AppStore.imagestack => AppIcon-AppStore.imagestack}/Front.imagestacklayer/Content.imageset/Contents.json (71%) rename tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/{AlternateAppIcons-AppStore.imagestack/Front.imagestacklayer/Content.imageset/Icon-green-1280x768.png => AppIcon-AppStore.imagestack/Front.imagestacklayer/Content.imageset/Icon1280x768.png} (100%) rename tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/{AlternateAppIcons.imagestack => AppIcon-AppStore.imagestack}/Front.imagestacklayer/Contents.json (100%) rename tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/{AlternateAppIcons-AppStore.imagestack => AppIcon-AppStore.imagestack}/Middle.imagestacklayer/Content.imageset/Contents.json (71%) rename tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/{AlternateAppIcons-AppStore.imagestack/Middle.imagestacklayer/Content.imageset/Icon-green-1280x768.png => AppIcon-AppStore.imagestack/Middle.imagestacklayer/Content.imageset/Icon1280x768.png} (100%) rename tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/{AlternateAppIcons.imagestack => AppIcon-AppStore.imagestack}/Middle.imagestacklayer/Contents.json (100%) create mode 100644 tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Back.imagestacklayer/Content.imageset/Contents.json rename tests/dotnet/AppWithXCAssets/{MacCatalyst/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Back.imagestacklayer/Content.imageset/Icon400x240 1.png => tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Back.imagestacklayer/Content.imageset/Icon400x240.png} (100%) rename tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/{BrandAssets.brandassets/AppIcons-AppStore.imagestack => AlternateBrandAssets.brandassets/AppIcon.imagestack}/Back.imagestacklayer/Contents.json (100%) rename tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/{BrandAssets.brandassets/AppIcons-AppStore.imagestack => AlternateBrandAssets.brandassets/AppIcon.imagestack}/Contents.json (100%) create mode 100644 tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Front.imagestacklayer/Content.imageset/Contents.json rename tests/dotnet/AppWithXCAssets/{MacCatalyst/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Front.imagestacklayer/Content.imageset/Icon400x240 1.png => tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Front.imagestacklayer/Content.imageset/Icon400x240.png} (100%) rename tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/{BrandAssets.brandassets/AppIcons-AppStore.imagestack => AlternateBrandAssets.brandassets/AppIcon.imagestack}/Front.imagestacklayer/Contents.json (100%) create mode 100644 tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json rename tests/dotnet/AppWithXCAssets/{MacCatalyst/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Middle.imagestacklayer/Content.imageset/Icon400x240 1.png => tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Middle.imagestacklayer/Content.imageset/Icon400x240.png} (100%) rename tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/{BrandAssets.brandassets/AppIcons-AppStore.imagestack => AlternateBrandAssets.brandassets/AppIcon.imagestack}/Middle.imagestacklayer/Contents.json (100%) rename tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/{BrandAssets.brandassets => AppIcons.brandassets}/AppIcons-AppStore.imagestack/Back.imagestacklayer/Content.imageset/Contents.json (100%) rename tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/{BrandAssets.brandassets => AppIcons.brandassets}/AppIcons-AppStore.imagestack/Back.imagestacklayer/Content.imageset/Icon-blue-1280x768.png (100%) rename tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/{BrandAssets.brandassets/AppIcons.imagestack => AppIcons.brandassets/AppIcons-AppStore.imagestack}/Back.imagestacklayer/Contents.json (100%) rename tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/{BrandAssets.brandassets/AppIcons.imagestack => AppIcons.brandassets/AppIcons-AppStore.imagestack}/Contents.json (100%) rename tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/{BrandAssets.brandassets => AppIcons.brandassets}/AppIcons-AppStore.imagestack/Front.imagestacklayer/Content.imageset/Contents.json (100%) rename tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/{BrandAssets.brandassets => AppIcons.brandassets}/AppIcons-AppStore.imagestack/Front.imagestacklayer/Content.imageset/Icon-blue-1280x768.png (100%) rename tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/{BrandAssets.brandassets/AppIcons.imagestack => AppIcons.brandassets/AppIcons-AppStore.imagestack}/Front.imagestacklayer/Contents.json (100%) rename tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/{BrandAssets.brandassets => AppIcons.brandassets}/AppIcons-AppStore.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json (100%) rename tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/{BrandAssets.brandassets => AppIcons.brandassets}/AppIcons-AppStore.imagestack/Middle.imagestacklayer/Content.imageset/Icon-blue-1280x768.png (100%) rename tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/{BrandAssets.brandassets/AppIcons.imagestack => AppIcons.brandassets/AppIcons-AppStore.imagestack}/Middle.imagestacklayer/Contents.json (100%) rename tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/{BrandAssets.brandassets => AppIcons.brandassets}/AppIcons.imagestack/Back.imagestacklayer/Content.imageset/Contents.json (100%) rename tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/{BrandAssets.brandassets => AppIcons.brandassets}/AppIcons.imagestack/Back.imagestacklayer/Content.imageset/Icon-blue-400x240.png (100%) create mode 100644 tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/AppIcons.imagestack/Back.imagestacklayer/Contents.json create mode 100644 tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/AppIcons.imagestack/Contents.json rename tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/{BrandAssets.brandassets => AppIcons.brandassets}/AppIcons.imagestack/Front.imagestacklayer/Content.imageset/Contents.json (100%) rename tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/{BrandAssets.brandassets => AppIcons.brandassets}/AppIcons.imagestack/Front.imagestacklayer/Content.imageset/Icon-blue-400x240.png (100%) create mode 100644 tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/AppIcons.imagestack/Front.imagestacklayer/Contents.json rename tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/{BrandAssets.brandassets => AppIcons.brandassets}/AppIcons.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json (100%) rename tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/{BrandAssets.brandassets => AppIcons.brandassets}/AppIcons.imagestack/Middle.imagestacklayer/Content.imageset/Icon-blue-400x240.png (100%) create mode 100644 tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/AppIcons.imagestack/Middle.imagestacklayer/Contents.json rename tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/{BrandAssets.brandassets => AppIcons.brandassets}/Contents.json (100%) rename tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/{BrandAssets.brandassets => AppIcons.brandassets}/TopShelfImage.imageset/Contents.json (100%) rename tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/{BrandAssets.brandassets => AppIcons.brandassets}/TopShelfImage.imageset/Icon-blue-1920x720.png (100%) rename tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/{BrandAssets.brandassets => AppIcons.brandassets}/TopShelfImage.imageset/Icon-blue-3840x1440.png (100%) rename tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/{BrandAssets.brandassets => AppIcons.brandassets}/TopShelfImageWide.imageset/Contents.json (100%) rename tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/{BrandAssets.brandassets => AppIcons.brandassets}/TopShelfImageWide.imageset/Icon-blue-2320x720.png (100%) rename tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/{BrandAssets.brandassets => AppIcons.brandassets}/TopShelfImageWide.imageset/Icon-blue-4640x1440.png (100%) create mode 100644 tests/dotnet/UnitTests/AppIconTest.cs create mode 100644 tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/ACToolTaskTest.cs diff --git a/docs/build-apps/build-items.md b/docs/build-apps/build-items.md index e8f6b01fb402..ca29996cd0a2 100644 --- a/docs/build-apps/build-items.md +++ b/docs/build-apps/build-items.md @@ -9,6 +9,27 @@ ms.date: 09/19/2024 Build items control how .NET for iOS, Mac Catalyst, macOS, and tvOS application or library projects are built. +## AlternateAppIcon + +The `AlternateAppIcon` item group can be used to specify alternate app icons. + +The `Include` metadata must point to the filename of an `.appiconset` (for +iOS, macOS and Mac Catalyst) or `.imagestack` (for tvOS) image resource +inside an asset catalog. + +Example: + +```xml + + + + +``` + +See also: +* The [AppIcon](build-properties.md#AppIcon) property. +* The [IncludeAllAppIcons](build-properties.md#IncludeAllAppIcons) property. + ## PartialAppManifest `PartialAppManifest` can be used to add additional partial app manifests that diff --git a/docs/build-apps/build-properties.md b/docs/build-apps/build-properties.md index 9c3ae3030c6d..2f0a9f8358f4 100644 --- a/docs/build-apps/build-properties.md +++ b/docs/build-apps/build-properties.md @@ -11,12 +11,52 @@ MSBuild properties control the behavior of the They're specified within the project file, for example **MyApp.csproj**, within an MSBuild PropertyGroup. +## AppIcon + +The `AppIcon` item group can be used to specify an app icon for the app. + +The value of the property must point to the filename of an `.appiconset` (for +iOS, macOS and Mac Catalyst) or `.brandassets` (for tvOS) image resource +inside an asset catalog. + +Example: + +```xml + + + MyAppIcon + +``` + +See also: + +* The [AlternateAppIcon](build-items.md#AlternateAppIcon) item group. +* The [IncludeAllAppIcons](#IncludeAllAppIcons) property. + ## DittoPath The full path to the `ditto` executable. The default behavior is to use `/usr/bin/ditto`. +## IncludeAllAppIcons + +Set the `IncludeAllAppIcons` property to true to automatically include all app +icons from all asset catalogs in the app. + +Example: + +```xml + + true + +``` + +See also: + +* The [AlternateAppIcon](build-items.md#AlternateAppIcon) item group. +* The [AppIcon](#AppIcon) property. + ## MaciOSPrepareForBuildDependsOn A semi-colon delimited property that can be used to extend the build process. diff --git a/msbuild/Xamarin.Localization.MSBuild/MSBStrings.resx b/msbuild/Xamarin.Localization.MSBuild/MSBStrings.resx index ab219c061e30..c9f13aba3277 100644 --- a/msbuild/Xamarin.Localization.MSBuild/MSBStrings.resx +++ b/msbuild/Xamarin.Localization.MSBuild/MSBStrings.resx @@ -1576,6 +1576,40 @@ SupportedOSPlatformVersion: don't translate (it's the name of an MSBuild property) + + Can't find the AlternateAppIcon '{0}' among the image resources. There are {1} app icons in the image resources: {2}. + + * AlternateAppIcon: don't translate (it's the name of an MSBuild property) + * {1}: count of image resources + * {2}: comma separated list of resources. + + + + + The image resource '{0}' is specified as both 'AppIcon' and 'AlternateAppIcon'. + + * AppIcon: don't translate (it's the name of an MSBuild property) + * AlternateAppIcon: don't translate (it's the name of an MSBuild property) + + + + + Can't specify both 'XSAppIconAssets' in the Info.plist and 'AppIcon' in the project file. Please select one or the other. + + * XSAppIconAssets: don't translate (it's the name of an MSBuild property) + * AppIcon: don't translate (it's the name of an MSBuild property) + + + + + Can't find the AppIcon '{0}' among the image resources. There are {1} app icons in the image resources: {2}. + + * AppIcon: don't translate (it's the name of an MSBuild property) + * {1}: count of image resources + * {2}: comma separated list of resources. + + + The source '{0}' does not exist. {0}: path to a file or a directory diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/ACTool.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/ACTool.cs index 959bade4fed7..b28989bb725b 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/ACTool.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/ACTool.cs @@ -13,13 +13,18 @@ namespace Xamarin.MacDev.Tasks { public class ACTool : XcodeCompilerToolTask, ICancelableTask { - ITaskItem? partialAppManifest; string? outputSpecs; + string? partialAppManifestPath; #region Inputs public string AccentColor { get; set; } = string.Empty; + public ITaskItem [] AlternateAppIcons { get; set; } = Array.Empty (); + + // The name of an app icon + public string AppIcon { get; set; } = string.Empty; + public string DeviceModel { get; set; } = string.Empty; public string DeviceOSVersion { get; set; } = string.Empty; @@ -29,6 +34,8 @@ public class ACTool : XcodeCompilerToolTask, ICancelableTask { [Required] public ITaskItem [] ImageAssets { get; set; } = Array.Empty (); + public bool IncludeAllAppIcons { get; set; } + public bool IsWatchApp { get; set; } [Required] @@ -46,6 +53,11 @@ public class ACTool : XcodeCompilerToolTask, ICancelableTask { #endregion + // All the icons among the 'ImageAssets'. + HashSet appIconsInAssets = new (); // iOS, macOS and Mac Catalyst + HashSet brandAssetsInAssets = new (); // tvOS + HashSet imageStacksInAssets = new (); // tvOS + protected override string DefaultBinDir { get { return DeveloperRootBinDir; } } @@ -64,6 +76,11 @@ protected override void AppendCommandLineArguments (IDictionary { var assetDirs = new HashSet (items.Select (x => BundleResource.GetVirtualProjectPath (ProjectDir, x, !string.IsNullOrEmpty (SessionId)))); + if (!string.IsNullOrEmpty (XSAppIconAssets) && !string.IsNullOrEmpty (AppIcon)) { + Log.LogError (MSBStrings.E7129 /* Can't specify both 'XSAppIconAssets' in the Info.plist and 'AppIcon' in the project file. Please select one or the other. */); + return; + } + if (!string.IsNullOrEmpty (XSAppIconAssets)) { int index = XSAppIconAssets.IndexOf (".xcassets" + Path.DirectorySeparatorChar, StringComparison.Ordinal); string? assetDir = null; @@ -75,13 +92,6 @@ protected override void AppendCommandLineArguments (IDictionary if (assetDirs is not null && assetDir is not null && assetDirs.Contains (assetDir)) { var assetName = Path.GetFileNameWithoutExtension (rpath); - if (PartialAppManifest is null && partialAppManifest is not null) { - args.Add ("--output-partial-info-plist"); - args.AddQuoted (partialAppManifest.GetMetadata ("FullPath")); - - PartialAppManifest = partialAppManifest; - } - args.Add ("--app-icon"); args.AddQuoted (assetName); @@ -104,14 +114,6 @@ protected override void AppendCommandLineArguments (IDictionary if (assetDirs is not null && assetDir is not null && assetDirs.Contains (assetDir)) { var assetName = Path.GetFileNameWithoutExtension (rpath); - - if (PartialAppManifest is null && partialAppManifest is not null) { - args.Add ("--output-partial-info-plist"); - args.AddQuoted (partialAppManifest.GetMetadata ("FullPath")); - - PartialAppManifest = partialAppManifest; - } - args.Add ("--launch-image"); args.AddQuoted (assetName); } @@ -147,12 +149,57 @@ protected override void AppendCommandLineArguments (IDictionary foreach (var targetDevice in GetTargetDevices ()) args.Add ("--target-device", targetDevice); - args.Add ("--minimum-deployment-target", MinimumOSVersion); + if (!string.IsNullOrEmpty (MinimumOSVersion)) + args.Add ("--minimum-deployment-target", MinimumOSVersion); var platform = PlatformUtils.GetTargetPlatform (SdkPlatform, IsWatchApp); if (platform is not null) args.Add ("--platform", platform); + + if (!string.IsNullOrEmpty (AppIcon)) { + if (Platform == ApplePlatform.TVOS) { + if (!brandAssetsInAssets.Contains (AppIcon)) { + Log.LogError (MSBStrings.E7130 /* Can't find the AppIcon '{0}' among the image resources. There are {1} app icons in the image resources: {2} */, AppIcon, brandAssetsInAssets.Count, string.Join (", ", brandAssetsInAssets.OrderBy (v => v))); + return; + } + } else { + if (!appIconsInAssets.Contains (AppIcon)) { + Log.LogError (MSBStrings.E7130 /* Can't find the AppIcon '{0}' among the image resources. There are {1} app icons in the image resources: {2} */, AppIcon, appIconsInAssets.Count, string.Join (", ", appIconsInAssets.OrderBy (v => v))); + return; + } + } + args.Add ("--app-icon"); + args.AddQuoted (AppIcon); + } + + foreach (var alternate in AlternateAppIcons) { + var alternateAppIcon = alternate.ItemSpec!; + if (Platform == ApplePlatform.TVOS) { + if (!imageStacksInAssets.Contains (alternateAppIcon)) { + Log.LogError (MSBStrings.E7127 /* Can't find the AlternateAppIcon '{0}' among the image resources. There are {1} app icons in the image resources: {2}. */, alternateAppIcon, imageStacksInAssets.Count, string.Join (", ", imageStacksInAssets.OrderBy (v => v))); + return; + } + } else { + if (!appIconsInAssets.Contains (alternateAppIcon)) { + Log.LogError (MSBStrings.E7127 /* Can't find the AlternateAppIcon '{0}' among the image resources. There are {1} app icons in the image resources: {2}. */, alternateAppIcon, appIconsInAssets.Count, string.Join (", ", appIconsInAssets.OrderBy (v => v))); + return; + } + } + if (string.Equals (alternateAppIcon, AppIcon, StringComparison.OrdinalIgnoreCase)) { + Log.LogError (MSBStrings.E7128 /* The image resource '{0}' is specified as both 'AppIcon' and 'AlternateAppIcon'. */, AppIcon); + return; + } + // This doesn't seem to be necessary/applicable for tvOS (it also triggers a warning from actool) + args.Add ("--alternate-app-icon"); + args.AddQuoted (alternateAppIcon); + } + + if (IncludeAllAppIcons) + args.Add ("--include-all-app-icons"); + + args.Add ("--output-partial-info-plist"); + args.AddQuoted (Path.GetFullPath (partialAppManifestPath)); } IEnumerable GetCompiledBundleResources (PDictionary output, string intermediateBundleDir) @@ -309,6 +356,17 @@ public override bool Execute () var catalog = Path.GetDirectoryName (vpath); path = Path.GetDirectoryName (path); + if (Platform == ApplePlatform.TVOS) { + if (path.EndsWith (".imagestack", StringComparison.OrdinalIgnoreCase)) { + imageStacksInAssets.Add (Path.GetFileNameWithoutExtension (path)); + } else if (path.EndsWith (".brandassets", StringComparison.OrdinalIgnoreCase)) { + brandAssetsInAssets.Add (Path.GetFileNameWithoutExtension (path)); + } + } else { + if (path.EndsWith (".appiconset", StringComparison.OrdinalIgnoreCase)) + appIconsInAssets.Add (Path.GetFileNameWithoutExtension (path)); + } + // keep walking up the directory structure until we get to the .xcassets directory while (!string.IsNullOrEmpty (catalog) && Path.GetExtension (catalog) != ".xcassets") { catalog = Path.GetDirectoryName (catalog); @@ -391,7 +449,8 @@ public override bool Execute () return !Log.HasLoggedErrors; } - partialAppManifest = new TaskItem (Path.Combine (intermediate, "partial-info.plist")); + partialAppManifestPath = Path.Combine (intermediate, "partial-info.plist"); + PartialAppManifest = new TaskItem (partialAppManifestPath); if (specs.Count > 0) { outputSpecs = Path.Combine (intermediate, "output-specifications.plist"); @@ -400,12 +459,14 @@ public override bool Execute () Directory.CreateDirectory (intermediateBundleDir); - // Note: Compile() will set the PartialAppManifest property if it is used... if ((Compile (catalogs.ToArray (), intermediateBundleDir, manifest)) != 0) return false; - if (PartialAppManifest is not null && !File.Exists (PartialAppManifest.GetMetadata ("FullPath"))) - Log.LogError (MSBStrings.E0093, PartialAppManifest.GetMetadata ("FullPath")); + if (Log.HasLoggedErrors) + return false; + + if (!File.Exists (Path.GetFullPath (partialAppManifestPath))) + Log.LogError (MSBStrings.E0093, Path.GetFullPath (partialAppManifestPath)); try { var manifestOutput = PDictionary.FromFile (manifest.ItemSpec)!; diff --git a/msbuild/Xamarin.Shared/Xamarin.Shared.targets b/msbuild/Xamarin.Shared/Xamarin.Shared.targets index b49381d49a4c..957b0314b859 100644 --- a/msbuild/Xamarin.Shared/Xamarin.Shared.targets +++ b/msbuild/Xamarin.Shared/Xamarin.Shared.targets @@ -910,12 +910,15 @@ Copyright (C) 2018 Microsoft. All rights reserved. ToolExe="$(ACToolExe)" ToolPath="$(ACToolPath)" AccentColor="$(AccentColor)" + AlternateAppIcons="@(AlternateAppIcon)" + AppIcon="$(AppIcon)" BundleIdentifier="$(_BundleIdentifier)" CLKComplicationGroup="$(_CLKComplicationGroup)" DeviceModel="$(TargetDeviceModel)" DeviceOSVersion="$(TargetDeviceOSVersion)" EnableOnDemandResources="$(EnableOnDemandResources)" ImageAssets="@(ImageAsset)" + IncludeAllAppIcons="$(IncludeAllAppIcons)" MinimumOSVersion="$(_MinimumOSVersion)" NSExtensionPointIdentifier="$(_NSExtensionPointIdentifier)" OptimizePNGs="$(OptimizePNGs)" diff --git a/tests/dotnet/AppWithXCAssets/AppDelegate.cs b/tests/dotnet/AppWithXCAssets/AppDelegate.cs index db627351190b..1bdcd57a3274 100644 --- a/tests/dotnet/AppWithXCAssets/AppDelegate.cs +++ b/tests/dotnet/AppWithXCAssets/AppDelegate.cs @@ -1,17 +1,97 @@ using System; using System.Runtime.InteropServices; +using System.Threading.Tasks; +using CoreGraphics; using Foundation; -namespace MySimpleApp { +#if !__MACOS__ +using UIKit; +#endif + +#nullable enable + +namespace AppWithXCAssets { +#if !(__MACCATALYST__ || __MACOS__) + public class AppDelegate : UIApplicationDelegate { + UIWindow? window; + UIButton? button; + UIColor blue = UIColor.FromRGB (31, 174, 206); + UIColor green = UIColor.FromRGB (119, 187, 65); + + public override bool FinishedLaunching (UIApplication app, NSDictionary options) + { + window = new UIWindow (UIScreen.MainScreen.Bounds); + + var dvc = new UIViewController (); + var bounds = window.Bounds; + button = new UIButton (window.Bounds); + button.SetTitleColor (blue, UIControlState.Normal); + button.SetTitle ("Switch icon!", UIControlState.Normal); + dvc.Add (button); + + window.RootViewController = dvc; + window.MakeKeyAndVisible (); + + ScheduleIconSwitching (); + + return true; + } + + void ScheduleIconSwitching () + { + NSTimer.CreateScheduledTimer (TimeSpan.FromSeconds (1), async (v) => { + Console.WriteLine ($"Starting icon switching!"); + await SwitchIcon (); + }); + } + + async Task SwitchIcon () + { + await Task.Delay (1000); // wait a bit, otherwise it doesn't work + + var supportsAlternateIcons = UIApplication.SharedApplication.SupportsAlternateIcons; + if (!supportsAlternateIcons) + Console.WriteLine ("Alternate icons aren't currently supported, but trying anyway!"); + + string? name; + UIColor color; + if (!string.IsNullOrEmpty (UIApplication.SharedApplication.AlternateIconName)) { + Console.WriteLine ($"Switching back to blue icon..."); + name = null; // switch back + color = blue; + } else { + Console.WriteLine ($"Switching to alternate green icon..."); + name = "AlternateAppIcons"; // switch + color = green; + } + + UIApplication.SharedApplication.SetAlternateIconName (name, (err) => { + if (err is null) { + Console.WriteLine($"Switched to {(name is null ? "original icon" : $"alternate icon {name}")}"); + button!.SetTitleColor (color, UIControlState.Normal); + ScheduleIconSwitching (); + } else { + Console.WriteLine ($"Failed to switch icon : {err}"); + } + }); + } + } +#endif + public class Program { static int Main (string [] args) { +#if __MACCATALYST__ || __MACOS__ GC.KeepAlive (typeof (NSObject)); // prevent linking away the platform assembly Console.WriteLine (Environment.GetEnvironmentVariable ("MAGIC_WORD")); return args.Length; +#else + UIApplication.Main (args, null, typeof (AppDelegate)); + return 0; +#endif } } } diff --git a/tests/dotnet/AppWithXCAssets/MacCatalyst/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Back.imagestacklayer/Content.imageset/Contents.json b/tests/dotnet/AppWithXCAssets/MacCatalyst/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Back.imagestacklayer/Content.imageset/Contents.json index 60cce20c2b25..6bd21396edd3 100644 --- a/tests/dotnet/AppWithXCAssets/MacCatalyst/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Back.imagestacklayer/Content.imageset/Contents.json +++ b/tests/dotnet/AppWithXCAssets/MacCatalyst/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Back.imagestacklayer/Content.imageset/Contents.json @@ -6,7 +6,7 @@ "scale" : "1x" }, { - "filename" : "Icon400x240 1.png", + "filename" : "Icon400x240.png", "idiom" : "tv", "scale" : "2x" } diff --git a/tests/dotnet/AppWithXCAssets/MacCatalyst/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Front.imagestacklayer/Content.imageset/Contents.json b/tests/dotnet/AppWithXCAssets/MacCatalyst/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Front.imagestacklayer/Content.imageset/Contents.json index 60cce20c2b25..6bd21396edd3 100644 --- a/tests/dotnet/AppWithXCAssets/MacCatalyst/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Front.imagestacklayer/Content.imageset/Contents.json +++ b/tests/dotnet/AppWithXCAssets/MacCatalyst/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Front.imagestacklayer/Content.imageset/Contents.json @@ -6,7 +6,7 @@ "scale" : "1x" }, { - "filename" : "Icon400x240 1.png", + "filename" : "Icon400x240.png", "idiom" : "tv", "scale" : "2x" } diff --git a/tests/dotnet/AppWithXCAssets/MacCatalyst/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json b/tests/dotnet/AppWithXCAssets/MacCatalyst/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json index 60cce20c2b25..6bd21396edd3 100644 --- a/tests/dotnet/AppWithXCAssets/MacCatalyst/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json +++ b/tests/dotnet/AppWithXCAssets/MacCatalyst/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json @@ -6,7 +6,7 @@ "scale" : "1x" }, { - "filename" : "Icon400x240 1.png", + "filename" : "Icon400x240.png", "idiom" : "tv", "scale" : "2x" } diff --git a/tests/dotnet/AppWithXCAssets/iOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Back.imagestacklayer/Content.imageset/Contents.json b/tests/dotnet/AppWithXCAssets/iOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Back.imagestacklayer/Content.imageset/Contents.json index 60cce20c2b25..6bd21396edd3 100644 --- a/tests/dotnet/AppWithXCAssets/iOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Back.imagestacklayer/Content.imageset/Contents.json +++ b/tests/dotnet/AppWithXCAssets/iOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Back.imagestacklayer/Content.imageset/Contents.json @@ -6,7 +6,7 @@ "scale" : "1x" }, { - "filename" : "Icon400x240 1.png", + "filename" : "Icon400x240.png", "idiom" : "tv", "scale" : "2x" } diff --git a/tests/dotnet/AppWithXCAssets/iOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Back.imagestacklayer/Content.imageset/Icon400x240 1.png b/tests/dotnet/AppWithXCAssets/iOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Back.imagestacklayer/Content.imageset/Icon400x240 1.png deleted file mode 100644 index f558229e8eacec411769b485348785d11f9cb85a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22054 zcmeFZb8s);wZSp|GHUfPi2n#Dx`sfPmw^;Tr(>H>AM@()gVLGZT;z00OFy zh5j)3@tr3y5?7P~0`epU0`d<60($#K`JVs*xzGavo#_Jsai#$Qq1$J*D{y}k+)dOa zOl4$%D8FF<5Ew8L5a>4q{CxreV*&l6?HdB(1;+j#uxO|S5ZHguzKJj}#EMJLflOW8!Q;;BI4W>%{5KL-a2W&Tsf1G#wGazgV2D zc!<2E{5!`(WbW*2&q+t;=H^E0#zbr9 zXhz4t!NEaC&q&9}Nb}7>qPu-CI6{M*u=@m(Zb%@!p@f9AH4>Kb}r65 zL`44>`X9%?%js-k`adn%I{n9OecvG6KNLC!T6((wm6(aU#s5a^AIiVQ{&ipfHpl&s zGENOe6DK=smw$@I%f`t4FAM)CHe3b|1K(IXKm-GWN%<(!uxIMUn2hn_20Sw zWk}o_KF14He@FM-wD^G}gawq{fiHC+ zvQR{p{1VyvX*nPSP(Ud`Ldyc6plI?GS-#n}RL~lm{r2 z%#u@}NH9mJKT^&#ZD*8)cj0@4g<&1$B(b>3Xb#Jl#` z9=L69^z9y=5kJif9lrx$dB_d%W($$DH@t|zhzlZwGdy%UIe1#uRoK{zj=|Yz^pf47 zCWZDRI*#FbyNY!QCrBZ9IE+J(rh>ceKI=Rkaxl0D8{M(Zs^QhcQ&Uj*@uCm#RIBhpGOG74z6D0zRuh!qD4OnQ<5gzm)WjBPS zAukm%)oG$2c#>2heeuhX&b<8eEy|ZaVcUqJcK-5a2wWbtQlcrF%Ddbo3LQ~CPs8Xa z5vf|M09rV@wxCmewhopEM2_HgzJmmuc&CwZ`kHIq4uj# zzRC%B85PWp%@|AnL2c_^{%OnqO(s?2%*vCB?ANAJ@Dq{+E#(#Wb$EJ;tZ zAV`j5Sx9y{nsW zt6@8~#@E+iknnegcWm5*vIMedlFA6|A?d}Hn$*Kpo6zi>hrgne%j7E+p0qKmhWY+3 z1qZeA?u?|CI5Gw|qRI>8lgMK;0|__LX=tIU~Pnv#hy%03Pe>G+I2M|fmk zAtM3oDfuGOo;5d4)gssadf$jvi=p=3&%4Bk7a>yJUBP&F!fQIc0eRteJwK8dwN`_S z6lD@!nLm2nA^Bm~Z6!UH?~s0ei(ZYpGvn@=M=V7n;_8`>_j#?J_Eq2&4daE(M=KNy zEk<&D6rp%H4$ofG8}WZ8F+F2=4c8{qA5M1GlyvcDLBK^88ozxBDqKtzk~Vu@M;d;L zk4;}7u*=$B1TT#(gFEMj8TS{|zH{mvpII&fxn!>!tfeMA9fpueO}{22ez`h-ZFXVv zSCg0OoEY|1*`u!4jqXgFlPrE&%I`+Cv1>%KIm}`PwQ4nB{Qi>(=C&2Rhpn0xP9j(sEvti)7^tqBri69Pz}K5s{;c{ zUT)v8%U~>(x^?kBQ7=QE>P?pP%H2AUlk5CyU!&%vy^`Pgzf97f=b5&9(8(pM-3af+ zH$^fv%NIQ4mj%%%@@?ViiqrFblrzV9oID)Jobhgs$~jjTJYmv_!S{Fn%mlN^&aIsbFuqUe6?|)q-7uHGuP~fI_2yf@;(BRWB7utx-c)4)z$) zA$^Be9}HB5L}+D9-E2i{1UfeOie$c8<4v|}oS#wXoS+J6bRurM7L$ zSS?u20@np#l20-a-;*Py^EREF81ap_%CZq5s*MP%Lk4k^BB zLR5V}0UZ_=LsQM`r(;T6i+IGJ(M3pE9)VQ-`1sqMppVvniMBkGf2t|N#o#~Hj!3z815!g%^DN-JG^54OHJW%-02G=}Jp@n!&i&37+RrwYx6Q>U= zJEyRJx%aO3MB{Gn>43y=qFX^`C3}SrR~#BKQfljQp9ixD_K$NR1W_Ocix zWpm%%nQVDhwpQ?;cb{KLe-m{LiBCsgb0|4?G)&ld=YdBMNXc z`)=7+$g3j$5&)=WJYsmd=e3&*bG>a$-kV=Fk07FC(ZleZKb;RB;2N?`H7e4g^$K;l zQ#@BI)RZBUR)9I&e|EQ(23%$aYhH8Sax>QrxMQu_*k{`pi1l=&N@npbLLUPim1KJP zh+aBb9*;}?FzT@psm3{bYn_e_1iPZz7PyXDD~d$ysjVsyL`YqaMl*-3{P9Mag?7}3 zwcpD7Rm>WlVJi8j%<8Xa&58ubi12Gc+k4>gJ-|Vxz^_o>`n=X+`JX>)qFsOAG(c> z2vhS1==5wna6GM>DthCY=(A$Xi6{7~OtH)T?4bw$`g0+Vy99iy4nw+hT=ZbtuG9u3Yj}!9Tt7 z1&tQ}b>wea(nYE^Z@H(gSDYZSPcTT_vI1u ziqicBk349Z)_MrfND_gzFuHt~-4=l|&0De+1__Jas{YESdQiwEOL?#>x>JDp(3+Ba z80p6YnRFwyrhNa0=A_2M%g!1en4wB*E241a&R4Tto<*i@zY&prlwDh4G7DOd16i1= z1S@+F)KzQDXzvp;Mz&{dxVgi_=b>#wzfV|%js~-V`-jT4c25vt*p@z-m1jP@T0&EZ zgsSa#Lqn7X5P?b1gCSM1_Y(@nfe8`xMG)g8=!3<3d=rJ)g#iir01|bFAfX@v$PoSj zRI&dn6q2EomX37eqcf|QzE+j~5&Z7pZtGfdScy2K00LXpO61u1X^Ka5S#UKC%z-8_ z6LeT#QJGXs#WBBf+2d3um^74Z@&ILdkt2r&4SGNMHL`C!g4#xMq_vaRt24BV_%(dq zo>Ae@yZYQE@ku=J^Kdq~1M1lXreCf>ehj-lx$dAo)QxM?UBv3cUP7v3DnaM!QN*d~ zg(((_8^Quenz`Ps^4s%S?7n7Bt33dDzXEeaX}wXHFhmp-xti+*d~$V=t9s9ANF*dG zlP6?uvPp+=r1Y)Z$;7P%9rp|A(bBEr8lV6Z%@G=UC?wAGxa-O0CM6he2yr(Y-y%DPGrUoiH#lHenpy^!~4 zqy%PSpq4VZp*%S-{nfepFvZkeV45ENcW{P}-4yKAd~&4msTaFUVADfnQ*x0PPQ`27 z3-UUb4JbEM422iz&IbQ|+zs_$w#eiQy^;GO|9$tD6U9Kuo7D0ca`kqavj!8}R4EID zF1)5kQvxYYhP^=78)bJ<=-*hJqbSeoj~^EUDeQWKbHq1jv)0Ka=$!*ul=B-FDMT5e?BFg1@b**%MS z{bMPF%Q?`6-j_h=c)zfko3=s}e7|}>7*0IBy-Jq5;U6NMd@Q)TjN(=5t4}=0i)Bh7#&|>+C!H32Fd-Kkz9YGLQ`>kI!B@ zptI2l?dqiX>icnQw5@xvh3$>X4qsS8!HWZlqS8t+e$-*Z!|q28R3#^_cN&VV>i=t? zlKqCl8}gKoY`f_OpKk}7SD!y~`bX4CZ>r7Qn}MVH*S?EK<{5-)usiun*u?dSfNoK` zmeKEWyJ(l605{yic3FOw2fKLgFL$K7{HqPZp2no^k4sNa{jFEtT`%h!<)Gz1n7Q#- z2qyv=bTKPR)0bkP2^EjwQ(%N=%lTA~Ht*z&v$cmSbut;p_}w*TJ^0b4`UR45h@$+* zuMr@*WYlI4RTY?@7#uQx>3F0xblMp<-<6h0mv=ZE3sxpqA65{ybp@{juTieKS5o)g zvv!AmS6w~s_^)y%g*Y+I{xzE(O!shcnmOj61lujp*}PY@OvuN}Uz{n>l=coIg||7^ zgQs~x7S(ygU9Hm_SvS=2co=znE!Y}WdsKSD@4wGq|GfEO!c|}vfxr@A-*k26 zhTbNv^RZ07gU!UlP}J@AW3g*apVAHY_MIhH&HWLEioKXMwAms_Dm8mBhUMHTZhNpo zPha73;kn$!Rn|qE*|tCuf%e8pXsZZ>{Jy^{2aB_1i;Nq-&1lMjrQ+3-!4gE%(BfrS z!^aAw;!4(HGkQvudw!8rwJS^)*gD1ev;M1KKf~<-DtgLh0kVI{*JV&}?OHp!V+WV6 zR$ycEI?|KDqr?{$M|W-FQb@F*o+Xm>?~8cX%P}5XR*c1km$E7ybe;`dgS`&5>-qxWihkb z#dCN+knOlWZ1HE()Ol2%+KNxsH8uuffLc(vBd(^$d{8|zB#d2RW5Y>J10F1n#BmG5 zPeAJCkAe-5-0o<5ZYLr=Qs-znSYNs$kthy<)(~2^pMRZXS&KEM!aRb7M(Y4ZaT3Hw zp-3vv><)y0<$%!I=c(X4=EF1Ha&e>yDm_^xQPh(fB*-Rd2jVbIes~!4DSkGzH%^Z- zR4egLo*B}fW1-BAxJIlu8R?L&Pv}tOuFwyD)_J@y1;e{xAucJu+f!n8(p4`LBr`Y# zsea0Ec(ooGs;93+tN|#Ub^JY*sj`g>hLIH=&g7cw`V3i%dC>9hzR*4eiZHc;@1dod zo0~djv5(?*LTP+`*-j8~Pz_j#hI)#TWN`;hSC3HKKFSbF2!N#28fZoe1{tFuZ3GZ7 zgmSx?2qNfXh_HYm6qnwG%SlHdVHahHCIkzo*yv+I4geb=FJTBGUH;0xV?h-R~AA*UAbVktwJO=j4H7u+Hpse138St^D-_nXkfAB?ybHx4TEVoTL-lP%?5WH5>%UcA3! z?e!;Kf}a)B?@`B^;Y%5p4LYlZ8}>uc%Wi*~fzD+ys!LzsRS zOHE;k>YgRBsTvR4@1hi+n`V>+8-cC#VscbSWCvj9{C50fdnxst?IWkSEF9ZkN*!oE z5KdK^X`gjyufKYeDEvSmyjKkTe9CTAp!0-(+P-xG&c#xjWP}jS@X5L2>-cZ-oQzoVe!(7u+uiZRF|(IF^EfJ*pYW!Z^UsFW zgpXt>dC&o-Kl_o_#di@d>?u({MT^u3WKy2F%m?>eU(Z*&ii@9p2B5~U>Y$cg-^{ji z%UlXe7@nh6>l8!3k_|8qCJ$@pYx>ibuV?}I$((vO24}_W*hc*~Gv3j)YfV|a8}^{y z6Q+VxN40%Rqa*=hk)r~kSxl!aS?T&29Zdb4Sml9mydZ~n z3ckNPO&~-kL=RvazHX)|)X=&b1gygJi`6b48LeY;c+TOP@m{2IoOQokzm+$dZgc6c z6}qEx%ri3K2-N-^6OWz42;}%Ydco6o+-xDWJi-WI6t)9|freSwy;`?Uj1W}ChzROv zC+u>RV+LUw4SZfc^sPne^Tea743|ks>k_lquO>T7#73TV-@SkAB^;m1kAjFNh2YLl z?0^0q3x3f5A{vvCgXg?j#yUY&KexEVh;R({qs`eK1M@H-qPnEW4GiRMUGTm!J-`); zqb|JTq`(}EcA|blL7R!>%jQ?Tckt)M8c3DDd5YV#E<_yR7BO?>gvAdcZM(|xgI%@Y zLxG@H2+*tIaP)$kQz`Y9+RSKz=Jej(g<~7BGK2G%1!xuTU1{GLM24eUx#Er6SwC!phgN!Ymb*xSGU=VA*ux%tb;yf856OZoC>SozE% z6j@jA37-OZo8(7e>+EBz{x47Bi{gy6LavaQAkmGRNGkN1eNZU|IfH0f{qO?VU!Sa# z!ZvfAq5OFCqNKQqUZ^?_Yq^57b5v4f^W6n@eHd?)h|I1; z!s1ZiZ7{H9I%^0IxwDztXA&@`C`%`u3=tz+eR9(kS3st{wA4N*)U#qUg`l>uZQ^=g zoVh929&k~>i610wE1oYwM{aXNWblIFLWxngWt#m=f0!ci3ks)DVRKf7L6vFbPSVV+ zMz!A_yiL>PY1vR!(kM0q=mN9mN9N32wq)PlQmN`i2XMvoEl?$|>Z1dv1{z{*uR5aE zj7=8S{E*ij!KP^PF@wC85}@FDe$Rj;g8Mu^{W1uDpjoFexZ66ESfP0oH2mcyo}*>M zg{?j5R^QWL6t&s4iu&M3SmxK1zc`tub+`htSdomn zhF|%p?CIXSFF>W>Mau+pOBLvgTnp&LOH^Zx-BLnhyG`1$tR^vt!*cX(e8PS^>>bxf zVO5gD5#9YUNbP0UeqMFU68z{?%5t)Ej$9==mA6%GS9ss6sb^WYi%q1^NQKi_hdwK zHsCWxFAS1>p$_$`KhJ>!q%wZgDX50a2i#@C0@E2cDAfALp{%F90l3K;xWCCB8{e+V zN5YuM!ykXcF$pIy8ZUAGL3+hG#;}mtf$dGHt1-R&zVHol1u3Q^J!BZL`!ThdB!zb& z=JJ~vv-6U<>Gy3x4UbJ??~k_InLQgS{YqE1#$Q#pP`MmJJ~@^JRynn%EKz@F z=*!yK%ErQaia|rYz29cUo}>!l3q;(0V*JGjR{NW8RYaJLS461uPJDS_3Ii)XzyOd_ z)?n&K-eI*Mo*ftKb~j}xRw(I0?)2`g*hSk>Q|XQo`J^ed=BPyN2WE;v&WOp2lxx%d z);^B>iu2B2Ctf7oU-`M}tav|uT9EjK#Jp`Bsm~5R3+Uxxk9@9I54KBJ)e5c{g1k;` zqDy}vX%(?9?f?OW#Ty&EyX&=2WHbLkiO&>>IhP!bPkhau#-L^TSc?5l61plbRA!(K zKHIA=>QGP}lWCH#UB&VTl>>yku|bo|DB9HUApEC0REQY@te>h69tBl#D4L1TWBJI8 zpcIFTuMLJIYMb=KUR^nb(rJ z%beD66|{s?>In-}sW-(40Tz2Fwu8&o^~3AiID@5}n0-;A3XKWzUqdzhRUA(~;pFCc z%bLZXCYZvY{?BI98;vpD+YT%oJlvzGqJ$T28(OSX78k{q=H*}6^x`Zfwi!(x5I)WI zOieP_h3x7#5NvZx#F^y_>F}TuWLR*Ob{%UmxlXBC`m!XApLf{kp8J&O*NLj66r ziH!*eJ@+04Y$ckSOujS+j-^T=ESVW*ti?u|t|e14?QsK^z=35I4!IUZ=6Uqu5lFff zxL6>f_n8g@0K!v_s$h>^mai(Np_= zLB%_=E9F)Cw<4eA%PZ7t+lqm`>eHk`t^3V^L>Qw;7W*cT!;>vr5+_nuSvN#g^H-X= zB|E&1%}aNt&gH=ZJ67RMBHz($_xzsu^j42%j3yS#bt8_Y;MsP$SuygI^l>2t4H}mT z*Tv#2H{QZHiX`V^ZqZ;gy*LeHggU3@*KySwG?wC6n*PBOdg%r z{G5@}2GZ{)`uZ254Ah!!0GmA90*ADTjAXkv%3X?S0^AR)Zypct`NyNDuD?DhU_`Q) z;J^2`-Vw0aMnJ$BN|_Uj%qwqZqGY7ZZMG7XfgejM(ktdA6+dTXWG(|w*D&Q3_$!Aj zca%F70Sw)<$EM(Wl0AJ7Zg7Bx3hc8XpVG@lZm zj-6s97ERex{aomzmF{oB+mfoS#t=tS(t<$`;^;R*U}+vo5_r!#Kdp9Zri_dl*5Jgh0=5rdzH=F5pf-PyF*GPUJX0O~b0mKb z$z6xx2^gy9B@hUf0R-;*fQ=vb1c$_P1 zE%Y9VT1DCc%~=B7wdCG;vtw2Gbp`q}f#-BDJ5EeaF zl~zeYtI~(T$=pwM!a+L8=o;PzK67N`NKxh?{4N_>Apr~7mBo#gn%R|p{y0)9BQn{s zxhvwqkdz^PeaeHx#%TccrRp%g}d~ghdFQjPh5hheqS=Z+cYS0gNKZ9>gGn;oXzIx zRzq$Sbw1eNwOnc0nLTjY6ll`3lerU5-1I=F#{+H|!@(&0pxy?jn9i*a~x8;LaMQp93zbvqbT$U+D{+kuLX(%n))sGiKdK7@dl;1GgCN z9Gd8eZpXaZABC~LbdX^vv<1?Ina17i8X+>{j!r6;9n-KCGA|IF9b%=tQ5Vftl9I1y z`w~2qV+a+TX_1rLV&_5vujf>r4>Ek~eX(pfJ`g9~ zq;6y$j)Xe_TH$b(9$Ug0O%8;2P*HM!P{WJ{i%bznA6b~D@={`qX4O5|^r>m(nlRa= zYUI;`p4B?J`$dAM{-h0BN`@*W&^j-tKZmL-z)!Az@Kld^Nm#Vb8pmXS2pmInv|PLL zN=CNS@Y_2wNhnr$u#7tFS3#36YeEJH>t$=s11)e(c$(X-a(m(nmC0)#wdNa8*{940 zLNk#MaFSp6Zdgtg8LAO`I;fW!dBf9eHsy4GUYgQFq;f3z5E@sFiuiGUx}2>Zu}kk7 zX8Y+xuv~CZNKGc}=ib-+8U@8!8T`e8VVMGDGaoXKn)Ys2K{X1lLCJNmC~v1@Gj)JpW^Wql+ed289NoKH9x`NC_b>aX z#}0P_bO&5~b$2$C^t*CKsI@eEsN+6Q!SzNbhKciXMv1uCRVnfDD(m+0WxE51YoS8O zDp(^{W9T)W!=Cv{VzW?YbpzP-DPoAz?8U$tkCk}A5AlfzST>Wn4y(}F>(}>scFd}7 z0idXX^OyYP-Z9?Sp3>31Er890K@q~&Z8bJhRdONdCgb}@T!;)>LvlN-g-B}l2P&2y zhviPsY~AXgskzgKsj|m0ZL*aIO_nL@5_Dh7;6^Tgi$^uOP$^cIZ5iy0#!i+?UMy`9 zJlnU~m|SI;yN?95@{L!}w0-eL2S{R{KZtIG-1HeIIj_q>54hK29K|kbSS}Zp>KFUL zgKq=yIr|qBndK7>?ubdKAiro$WA>oXc^-6(BpcwsoJgi}&|L-1T40LIQV;su*D#eu z@XB)PeN&lX?#_P4o`|0=>&F!KlG_`FvxH^o{TMST^m#aOdk#wLN}oDgNqlSW$h|mn z_EsW>U9CR-b?3qS0}99nky*ZAf}a+~>?-ZpAIlTaEz9lQDvi0+_wdIJQ#q)Za)_E- zz8L91N0I(d(&Dz_*6i~vKqEQReQ?=)lxkrrBG;ln;kYR;ucxpbwrD?7M~pRCLYbAq zerhCygkBnuAY_z>z2j2^*%|keASwWjSP1Cs;em$nUiPL!LGA46Dp3kkKFJi3st)N znMhnpW;YlS-tg@m_4iaGd||eUy}y?gQkQu^Lkxm~On~z#zK=s?dWhIrWHrZy;#}l` zY8x@$z|oV zzlDa)J>3>l^DGUST=XdiA^E3Lyu?b!MKF(2K2Syym`SXVk0eDJuX?$d{l?)Xbpnd_ zL{YCf?qw~rZPcm~0*8)8U3b|=_$P5-_b2q*#6G)`D6bA7jtTMyuU?Q+1k%7*q1U-C zrQ8wPs+#C@d;Sz%{=~MhPxakcT=vyD4qx4lB43_35t{dXhm?D4(sbcfK-c-HfoeUuk!2XEKRF}=^ucwRgIp*7csI5>gbJ@Hq$1OoC5P%s`-8T zuvC_ddWu+e@bOu)>X*M1lhSB>JlSZyoRSx5$^CJWG@n+(e(2X*iowY05u&~U?9SbB zlA%;91cA}X6c&bo=$lmsQ?PhG`fLC6SuuqOj)pwnPeY`m)Ecb|0$P`pm&vov>Z8A- zEW8PaYI|s9G(jTQ7DJW`3JyYtZl@_GQM0l1KGrMuVl3-tJ$7b9AOysddYRjLOSy`x z>r9&}{YAlF-d)U~VR_oS`sOufu?A;YE@MH6h08Br&+ zY#)27A`{q${)5271b2C0uwj61Xua?4Fh{;r%$H&AaCd=)e$3iC^MXi|fb;POGfcMN zZKzejuFktcY)XqEKDX4GurU(6@-m#|@`+{pMG_&TWZ&D6q&xU75mVw#0a9klHC1kO z++YI91`c$c?`^+4*%4^pGF>Y$-D zWM^0ksoiot#I(m}XC{R5<%Q;B#@sqf`{9_Pjzg1_2t!yl0!Q}m__vJ%mQFL2&=os| zW%_V_h5A@$sf8P%UF1vgrZ!)X8axg|lLF_=zJ|-!@Ug%qi~> zL<;jBs|fzpP_>domY|(5XA$TY?7?6=5)aCL-pS{Ax&(WY-K7NWJH3`RucaeqB+Jg{ zeo%q2Jb57^V>3x``f#&4G=(6|+DCR)EqgaZpMkE0h+}UX zhzi_{N?d4c3O7ta-##m>SlZ~Zw?$ZrspGRoO+AGRtN`*{1v|YIXduM-9mr>-KH)I^ z(WA(uMU|ZvC^c>C!u_x~oaqqsC|iWBPGoT|-ub(SZETH?iNp$T;YQQ|PL%5uQ@9+A zwDWtLxKv8^1F#=KR42Y8IT55n~j+AhVPz+>%ET8>6f>;QpQ#wt|K z>PH7>ftFEqQDY9I)>(6)pgSu8BjXD;U)kSJ@iw+G?*K--1ZUShTiWF!E=mE$<(a&!#+}Yr6 zzA(dH7kJ9>5_^4uJFK4iKt)Pn(Uwbgx$|_PB?_3GIb!#Qq!z~5;%rln%9A1>Y@T>A zYc!^uU58p@d)d4uMi8D2m1)GSPLMu#Q96_od=k$Pi;a3_bH90N$+1(3vMGOSKA9iJ zE;PIz5DZ|#;!AA4tQ6h>CW|9ErmWyhu zr22}t$>umnaF;Ct@lxD4KYJrTID5^rlhn%|d% z1k<0~bv_X~YIzC{+U|~dZ4pOyOb1^{sl9&M%v)I|Vj4q8cF;|p$oS3ZXWk2aGqNR^ zHmD{AKp56l;?D7Ie`;)7=yn)SGJp#qDaHt*`dHXuL!nYygyCkCfh#q8h(y?9jegs(3Lc5ZuLE~$LZbgZ3nJ2KD-MCg0EcB8fzQjg&+8%g!uE3 zGbt&NK-#bw)e{zC?t*4|0LnR|wwci2yJwt*3FPES|2@$cO>p>av|7D&&uy&C#Qvrk z)~$Y>>eocV&K?gP8fVv|&kf8f`k@TZXg(svPs|{yT1lh=_^C~PuJI>-i-ZA&Y|++} zzn*!6^s^3=S0&Kx@KL&~5($oDjDY#jXjz7}0(i07;^-lhh#^~YUx&n?W&`xZV>4GL z$fk+zR9e1Zp5gK2Ihg(fGg1TOOS&mNf183$M8$%O(j!RAvZanJ+26X_a;z-Q>W=o( zk06}&uU5`Vb_Q_KITWQsbCkNzsj>L_@aO0Eth3+C@M0koJ$dL6Omp_?8UKlw{m(@V zba=YONS*=fUbNL}=DbDW_J^cQecpaM#qRB@eh6H0X3pV!Z__KS?LuG&8;f&TR3uxL$JDAN}J$Rm{eB{7MYyd~t}Yw)!n zWn`E^0uRDUbBs73L~^iVisf-R06^eLcuA27`}Ynb%>QRG2QQ!l@ye7W002k;zcoS} zqN=rhiZ&Rq06zl#cU|%St7ZrYzRC3h{9xk$Kk>g+g6hDcI39{tt;Z;fd`*dp!SPrjHByiZ{Rk>;XS~bsaz}8r zu9qK+MYgRGMIb)|OGx?+G`YLYGHx3*+MeC1-5cXqlO*7z&{&+9i?bS^7HB&_n?`Nr zXd1K>6Qe}kYj-1!1-wM^%7V&02;BnsQ9(%IX$6E3ZbW;dV+OQ;GT%u_S`6hRH@YvU zHa4AjND4tDTJgot(csSPmI~+v1t#0SwumL7<%0ZTfpJwTG&d(G3sRp(c+guFhp` z`}Cq2T`||y=X(thlaS$-S(e%fRz&^ngNi8+k5pHV9ixVFm0*dSkc- zIZNY>lH9C1A_oOy92XCEMd*y-=3-FF;D~%m_K_K3_KmSU@xeA(uVy5Mgv-e{3Ik$b z_V7`YMaB7;62`B|7IAWoDSEO9EbBKCQs?*-wx{QGTomy~*O)M7;vx_?m5(i{onh&+ z9W3CUAn9D1JoEiIJuJcx7Up1~RcmTZmyflOc2cQ_K8v0SVK~fy!Gu61nkGB=tZ7~S z+yn*y!2+Qcr;Z?4ReGbzUVPJeTenb)`!Ok&xoF97xV-Z1w+yU4$!i|aF&&;icb(qGNBvY86EG#5Z)6*lMf^#yM4YK( zTXtR?j;EPDF6qzWmT-xPVI%iDhY6YBaCc>Qixx1$2eL%hB}?Xqbj;?;_QlBE!w48$ z8xVjE`QIwEywr6}N*2A?=86_m6{N5iluJrhY8_Av1FI|2P7jg59)$fT{V&tv)y=(5 zrLnv|+?eaeR{?>)>I~}$t*kr?vH=$1KoVe-C+gsA7Y~#AJ9_Zeh2d1Sh1BgOFHAsCDdohk3EO zYgnA`c0JrhtnY{zLz=94CMY4|{JyPZ)x1OT0b9wI{JAO}T{hR13#XPc16%4XSlY}H z?;dB=PauX;Hd`v#=!5`_WD``F)!oeGem(2$X|bxKeD)E9wF)6*UsoZi&OCM_bw^0h z%e7&%vZ;HtCR&`M-G10e;p`nr8$qzU`dfQ6(jO2n)o(?|}f}9#tDpX9@fB2^j z<1(4VBD!crRLsAHcug8p`D{(lcD~+OtCp?I$kwVVmjBWcNgyHW0UbEOSa}{yEPh_1 zmewnx8I@OB2B)xoSRsj?2@d%QP?q{E*!A26-d;=p{p|o9U3Uc~;=Wc)y`0W)tXb@Z zB+16O*OJD&u8Rzkt>@dwF=jZb?k_1ywZs9=pwHV-$OXpAaBI;8{IjxBauAX;g!9B- zr0iolww_i);}7?J>t!Nquivph{A!7SC7O*}jd}{i3MM7wv&B8S1@5kNL!W&GPGMK7 zDcr&{UG2@wDcr23(ZvtdNYstA-B7ApcVe2&FANT8j+Ms^7>^_p@$AQZn$rI4iXU6i zI#-O8RocQlnO)M^SkJ1W$C9)W%NrFR7!{Ur_O-2arXQgWR<1rdgt z?RK2LYQ2$;TU+S(B>R4CzS=F%8YNjRL0-AR)OU#X#wR-_rIvdR3Ox zlq5>R@zTbi&mg2!iwZ5?EoCaN$2C(xC)#^}LBcrNaPmL4?7Y2zFwj^S;>A4Fp_;qRP?Z!LBK-#G_nZTCtn)X)%v9V zt4p7wS@IV#5Pl09rJVdZx0cs#fdkp=b5rAu1=jo?PRI33y(*obL(S#FpZ8Uq(vyGy ziAFe*rwPik?Tqha>5Co9WL7p~2fcLkjMjPiB! zxsHbH&vlqL>v{6CGzUCoub~qn4;q47PDz)bY$-0Ok^&=dblk!t|GFcvKjIk)A>qi# z3vPKenhrbQS+wj}XOy~3lG4&2%c;xG*7hsrfdmG8TDg7GOTm)P4l5`4P3k>}z(`hu z=LeyU$9~>hb)4E zY24PlrL5+)N3L3!8VZrji64ZJQXO8Y6IGID$j&g^5Ziy_7LT5N z_hmoq-PJFwI09_N>tyxgFvax68FB`H39n0a2Y>ouJ$xNg&UT5-{_27MP(9Cz%tB?h zI8|!gKM`6$c{f%TKzh;Y+Nua3hCb*2BF=myYVVqMTA=K3PzD?Mj=(vYeC*mW@c^vF z{>Uz$opv#R``yRAD$y~%H1kMC7m!*jGNODcJE6Mcqmg-u|uCgM_GwAvI$2X(ygO#!4 zOAJ%hCtLas&aSeY0c^;2thRAprnFnGw2@bJ*#{=0BUUEVwGi*Z!~+5?jmzk!@BLST z7oGF~His8k8PF3)uP-)gE7!aYk6!+MM$3RTJT|2ZJ-(g$s^Y#BB7s6t!;%LsB}K8s zcy2!EP^`StP!=P8w&@*R%sFVb8(Cc>ls1R6)%16OZ{$?FhmFbYMY*F>kHMF!r^g|S zisitQI^7OjE1{saOSR!J`HJAs%(z{Fm28HrnJc%98E{z!-!<(-Y54eceniAH!wZHy z%gas|og)JXH9gKslsZUL{pOCi4>1AAAR8@Wu;q8Rb3s8ymn+_b z--he@g5Eorq@uEsEmBhuUgi(^#t?gOd8AEQqaH)tG93bC4w7}*v`~$FqY6y3-V~#& z+sbZiz*ZMd8_C_31FpafA%!mC?qt}HDZ8@zebpf`#e3<$oWOSH z#jjc^GaWrog|epu25;x0$2ccZ?yBwS~Y zx_Z37e7Qd4)Dv%Y;hISk`^3y&9H9dyQ#cagQsurkoMQ(-u4FAU3_=O|*1|Qw?9JK1 zV}F8tho1`=nU|E&-aM~UeM#{h{!L#a?-ad_SkI=Fs!J`USpes)b!1Y2bQK~({pIa=|gJL78 z;+!p|-m)7*)mc_Y6#jO!DFMeXm}M>8JQRKQxBX<1->R{74qT%6D9hGGDL+%Z!#iK5)xgS#Z9$Omkq(Fh_b-jsR5xLY~TSnuN+yX~6$ArV~9PZIXKHWhmaJq1Hu>Vj}%)X17Li=CR_Kt0yB%2X% z=?g)W7V;*2s8a#eM8SYjw<1Yr%3{=a1D8ZC)L$ci97WK9ZGWSl*hAWKz0EaN$IhMc zU?YIf_G!fvceWDOD@){?boiCvyMB}vnKLx3N#;JZ6|QCZ`SZSCqFP!|k-|SQrk@X9lm0*2Iqz>aytt1WRZ%q} zjlHQ7P0=W76SXO|)u^`AY^g1+Sz23-qJ$E$XGqPjt=edf5Co|hUwhQ7)#l0f`753u zo}ceI_uPBWz2|d2@Avz4YuALkdt?65*_A#|&<)6^`uu(^GvU6&NrH`2YnjS^7GUay z^=UFCXVZrs_T#IH5~f-1SU*gX$e@&T03O9t$%HhYN3W!P209a^+hyX!{%K?{9qD8? z@!h(msx5P?J#j9}nXEGaYe;h}Uv_aF`MOh+xx4WWIb1i!1f5wTGWd^v4T?PQe!KZd zdlle>HoooUkx;P!NOb+(6O-IkmOa_bLCvuaf;lR9rS2^fC1@8 zGair1vh1kI?lt|qLGMFj=3s6hBl9{gh*LfCM_8w0kH1043q$h(Rg8UIiOSz!^4RaV zNmp8HLYIG$@gZq4%N<^}#NHrcHeRuz>;Y#%%SMz*R!g!#zCy1zu3wl^P+j=}rM#>w zS%Ing^$g+e9dnF0un65xWcOjR#@G$M^T+-(!U1%uhTy7?zZPO+fHyODp|Oax$z43S ztmlu)(+2hEm=Rx_fxqWf>Lmk+TQ-WXAV1USvn|(C$erTzcabR`7cyHWtw_9|LxDsR zU4+0%O)%ft%2ep#=}OT=)NfG3j4|;Y?+GGwGnvLB!6ev6Ni>)fNpjej?8F#w-^t(#p?T=1c61xTzOS4sYl z^IzGG_GCVP08xFVc`X};IfU1_-u|+@S8oO6M>MQ1O}Gh>Y3hcmj#(<`-#)FjD*j-1 zNk3B(mHcwLk`hC39xWzuEoLgI&*sBz)873g@P%;-u=e3H*ZPkgn4bBcil@P3jG|uuqRimS+F%sCy($8 zh<#BLl58#15oO;~6F>fg^P#9dP4pBR-e9`thwXp~=4a9~EeZJVPFJq4R6H3vCfVg%_t z-1=$do91L2#B4WLwSdL)=^mW5YT1zR&$NXcG|#1R4WoaVkkc6E348B5oJ8&RV1X+` z$Z7J4%#3x22G+OUf0(XGBsaN!O&_-UXi_EDxf(| zfzEX^VkB{YbA)89n(@f_Y8e$U=GXfC}=$bs95epw>*Ib-ROp~CQ30ARHMhje)#8SL(blwJJO`;NleY}cP;*?!SydcgDpx)2`MIpq^+6n zactkh{D|964=yxWz1Yh2hy=tkOwf_9V<)~MhONDoDNEZdBNX89SwnA|R}tJ(q%zq9 zx<*R{(#rcs4`)?BzVaZ3KyDT45EUk0@L@sZ;n_HWZXK1Ol~L>sC@Ne4A!1y3L>IV_ zdmuZWl-DI^G{6|W?*UM-T=&9`SQ#kx3H~I znuu^HepNFF$OqwNXZ^%e|6&gzFLQ$6W(|Q>qJWe(&5GzZ0oL*zH|@aSj^`>x zRxaN|Kf3R%3>@yxpTX0v((2xHO7|DyNVH89RZ4I#Jm6|;7^K@Em9hev8!3RtMg!Sg$kqq^`ZEhtK z-)ouR@qYC0@u+mgh8)#P8yf1jl^Wz8Cqkv&^h~E%^GT%mzrPlu8Rly<0CZ2-W^C z>@n`5nvZE-w%GleMk0?JnAY$}ueGB>nNOU@3L(#7kp%Rov0en*>WAmFOr)oIE1rHHGYAr{TBh8e!I6*H_R?tguPtAS&W!)HYoDevk$3a%6YI z=)3)m;0m2caoInaW8yh)xd2=~14I(vnHE%zog}X?E#)O1Kkk7!VoUWUx{{LB=8H{D zQqWgy82DLrpWhye?z7Jtw%ODuk!f~HK|LGnKKIk2vyf>j_AAR}wU}_cPC>&Ss@;!J z^Wop{jI#NO1H_85!RyBX>(e(ClIGwt`|^MwSB2g@FP~|(=Yz_` z=3k-5*IyMRo6}6V<>6v3vVEz-w1HCkgiIPv=lhlfHDoFHy2Ve@w2m*9H8XHF9%F{X ziNV0_toYMGRl{e2>Tjz#rFCbHHbJHU2W#_+#w5#(3O^IMhcBBIe8|XOij!jcB#L|i`=SbLesEtY$ zc49}glVHx35IXkx(_>oYu-ArtrCoQA7jRo&Sir``b^h{AlO68fUyO$zV`#f}tBz~s z<*^@kZFA%?M_=rD^G+~PS{GCCA=bIieY6pVr4I@})OFjfu*mW*@MLTW))hG{&Qpc& zSG)x2A_@JFMasfP#CS9*Vj#+Tb#roIVn}w2X6H&Md5BeopjK#)NBXP)oK>7E(Mc0HMG9)TkNsU}s;PxddZ>hz>q1+flnf3=x_t}?aNP9c>L z1EqPuDDzo(@ublu{o)4_Z(e#tm(ZmzZ-eVbarBB7LrwlJ$^8iZj`m!3jtt3Y&1=BX zt2a|Djmsu^g7H6I3r3y44*>F;_p5RmP+u_v&U_dS62Gp*y^eJq!Iws#SL8mC58B$V z2vWTdbm4I2(BBVdClgZzBuKHtyDqNB&v+RrkAA@T;J#~1?)dwkIrzn>^|2qYX8RPi zo|>AO)jKkYYARdvP-0hQgK-?wU)L7rluuK&yp+kqm_(N#ZQYx*=-q~$GNM9O=xRUi z>L{xD!L8M*{84ZA^*udz{61s(r!DYJ?M9;XIWd7kS4k_94UqzrxBuL>U6QPs1E{o` z1~3n&?aov`3Cz3pDJeD*!2V>c(b}hp=bLGW53*&E^`+Ht@y&-CEtKI@-&Cy{?`19a z$YNZqNl9`;ge#kXpWXV3#e7+YeV~P`Ap*>$a+pc zw-hS7z7-A63ekPM#7)@ySC<_iKpXhQrH5zF4N|1`@9aX|hSy1zGLMg`BLdVcR)oq; zlA{_jVgz0@w}B>5``I)TiHZPt(9K0O*SjcUD!|8=#cL6nmo2T-#AG1hmWW47(RJ(a7r%r z*1whTrLAc$yc*YfYu0ELk0x>UsZs0B@MK|uuU6xdB=2o#R%<;?oUUs1T1D$BfTRdTOM01m#jh_AP z7KCc7^4)&&x*NoiVE`6){?qnRo%jkGXj0doE?M>2uxdpNf0sLPqi9N(G*A#nS{i7o zS!UdrKYQ4+DpcFVoa^@{1!evufkqDE+E<-D!}CjWoch2!Qq*V9WCIQISVwB$4bwYu zvQpL$uEEH%Q6`wRj))kUMk(Z$gvv2{4Qk#fZ`2N2fbv4HykQPg01ay0-`X>)&HQhJ zIK`+L8fvY8p2o@t56RoVUb_wnhN2xF2IDY6y-BfC#ttX`kchPhX#i%S&L-z0gTME$ zUD^mbx$utqRNotla`YqX7re}`!DQ?sy}o%r*CYAwl!_p4^?!@6Vdsi#OM{9kal{tH zo3jFi?`B*W8N@tUvYFd)@xn!^a`Z*LhC)xapj-*3;ME3 zEg2w8OT^RcjppdVoc2MQ11+5_%k7(vH^-hj zYp$>SJN`I|{-t*d2G#c&i1VDmcin7XoMI-Tt>JguqnGw>>YArZb2?*DUIP5VPBUuH z|HaeNzA!#@YW0;+cHT zJj>9ntZe^!#e<|TbyPfnw%Fyo<4y%LUCm7eu*1`>AlLsls&EJ_$2;h0h<(#yXTL;^ zD|FlbXIOHop%tPdsd0t=tF%C2xfuJ~9REM~f9VjSD2!F)d%si8q8$GF3Dw}9sZOo- Hqv-zuPLnqK diff --git a/tests/dotnet/AppWithXCAssets/iOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Front.imagestacklayer/Content.imageset/Contents.json b/tests/dotnet/AppWithXCAssets/iOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Front.imagestacklayer/Content.imageset/Contents.json index 60cce20c2b25..6bd21396edd3 100644 --- a/tests/dotnet/AppWithXCAssets/iOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Front.imagestacklayer/Content.imageset/Contents.json +++ b/tests/dotnet/AppWithXCAssets/iOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Front.imagestacklayer/Content.imageset/Contents.json @@ -6,7 +6,7 @@ "scale" : "1x" }, { - "filename" : "Icon400x240 1.png", + "filename" : "Icon400x240.png", "idiom" : "tv", "scale" : "2x" } diff --git a/tests/dotnet/AppWithXCAssets/iOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Front.imagestacklayer/Content.imageset/Icon400x240 1.png b/tests/dotnet/AppWithXCAssets/iOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Front.imagestacklayer/Content.imageset/Icon400x240 1.png deleted file mode 100644 index f558229e8eacec411769b485348785d11f9cb85a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22054 zcmeFZb8s);wZSp|GHUfPi2n#Dx`sfPmw^;Tr(>H>AM@()gVLGZT;z00OFy zh5j)3@tr3y5?7P~0`epU0`d<60($#K`JVs*xzGavo#_Jsai#$Qq1$J*D{y}k+)dOa zOl4$%D8FF<5Ew8L5a>4q{CxreV*&l6?HdB(1;+j#uxO|S5ZHguzKJj}#EMJLflOW8!Q;;BI4W>%{5KL-a2W&Tsf1G#wGazgV2D zc!<2E{5!`(WbW*2&q+t;=H^E0#zbr9 zXhz4t!NEaC&q&9}Nb}7>qPu-CI6{M*u=@m(Zb%@!p@f9AH4>Kb}r65 zL`44>`X9%?%js-k`adn%I{n9OecvG6KNLC!T6((wm6(aU#s5a^AIiVQ{&ipfHpl&s zGENOe6DK=smw$@I%f`t4FAM)CHe3b|1K(IXKm-GWN%<(!uxIMUn2hn_20Sw zWk}o_KF14He@FM-wD^G}gawq{fiHC+ zvQR{p{1VyvX*nPSP(Ud`Ldyc6plI?GS-#n}RL~lm{r2 z%#u@}NH9mJKT^&#ZD*8)cj0@4g<&1$B(b>3Xb#Jl#` z9=L69^z9y=5kJif9lrx$dB_d%W($$DH@t|zhzlZwGdy%UIe1#uRoK{zj=|Yz^pf47 zCWZDRI*#FbyNY!QCrBZ9IE+J(rh>ceKI=Rkaxl0D8{M(Zs^QhcQ&Uj*@uCm#RIBhpGOG74z6D0zRuh!qD4OnQ<5gzm)WjBPS zAukm%)oG$2c#>2heeuhX&b<8eEy|ZaVcUqJcK-5a2wWbtQlcrF%Ddbo3LQ~CPs8Xa z5vf|M09rV@wxCmewhopEM2_HgzJmmuc&CwZ`kHIq4uj# zzRC%B85PWp%@|AnL2c_^{%OnqO(s?2%*vCB?ANAJ@Dq{+E#(#Wb$EJ;tZ zAV`j5Sx9y{nsW zt6@8~#@E+iknnegcWm5*vIMedlFA6|A?d}Hn$*Kpo6zi>hrgne%j7E+p0qKmhWY+3 z1qZeA?u?|CI5Gw|qRI>8lgMK;0|__LX=tIU~Pnv#hy%03Pe>G+I2M|fmk zAtM3oDfuGOo;5d4)gssadf$jvi=p=3&%4Bk7a>yJUBP&F!fQIc0eRteJwK8dwN`_S z6lD@!nLm2nA^Bm~Z6!UH?~s0ei(ZYpGvn@=M=V7n;_8`>_j#?J_Eq2&4daE(M=KNy zEk<&D6rp%H4$ofG8}WZ8F+F2=4c8{qA5M1GlyvcDLBK^88ozxBDqKtzk~Vu@M;d;L zk4;}7u*=$B1TT#(gFEMj8TS{|zH{mvpII&fxn!>!tfeMA9fpueO}{22ez`h-ZFXVv zSCg0OoEY|1*`u!4jqXgFlPrE&%I`+Cv1>%KIm}`PwQ4nB{Qi>(=C&2Rhpn0xP9j(sEvti)7^tqBri69Pz}K5s{;c{ zUT)v8%U~>(x^?kBQ7=QE>P?pP%H2AUlk5CyU!&%vy^`Pgzf97f=b5&9(8(pM-3af+ zH$^fv%NIQ4mj%%%@@?ViiqrFblrzV9oID)Jobhgs$~jjTJYmv_!S{Fn%mlN^&aIsbFuqUe6?|)q-7uHGuP~fI_2yf@;(BRWB7utx-c)4)z$) zA$^Be9}HB5L}+D9-E2i{1UfeOie$c8<4v|}oS#wXoS+J6bRurM7L$ zSS?u20@np#l20-a-;*Py^EREF81ap_%CZq5s*MP%Lk4k^BB zLR5V}0UZ_=LsQM`r(;T6i+IGJ(M3pE9)VQ-`1sqMppVvniMBkGf2t|N#o#~Hj!3z815!g%^DN-JG^54OHJW%-02G=}Jp@n!&i&37+RrwYx6Q>U= zJEyRJx%aO3MB{Gn>43y=qFX^`C3}SrR~#BKQfljQp9ixD_K$NR1W_Ocix zWpm%%nQVDhwpQ?;cb{KLe-m{LiBCsgb0|4?G)&ld=YdBMNXc z`)=7+$g3j$5&)=WJYsmd=e3&*bG>a$-kV=Fk07FC(ZleZKb;RB;2N?`H7e4g^$K;l zQ#@BI)RZBUR)9I&e|EQ(23%$aYhH8Sax>QrxMQu_*k{`pi1l=&N@npbLLUPim1KJP zh+aBb9*;}?FzT@psm3{bYn_e_1iPZz7PyXDD~d$ysjVsyL`YqaMl*-3{P9Mag?7}3 zwcpD7Rm>WlVJi8j%<8Xa&58ubi12Gc+k4>gJ-|Vxz^_o>`n=X+`JX>)qFsOAG(c> z2vhS1==5wna6GM>DthCY=(A$Xi6{7~OtH)T?4bw$`g0+Vy99iy4nw+hT=ZbtuG9u3Yj}!9Tt7 z1&tQ}b>wea(nYE^Z@H(gSDYZSPcTT_vI1u ziqicBk349Z)_MrfND_gzFuHt~-4=l|&0De+1__Jas{YESdQiwEOL?#>x>JDp(3+Ba z80p6YnRFwyrhNa0=A_2M%g!1en4wB*E241a&R4Tto<*i@zY&prlwDh4G7DOd16i1= z1S@+F)KzQDXzvp;Mz&{dxVgi_=b>#wzfV|%js~-V`-jT4c25vt*p@z-m1jP@T0&EZ zgsSa#Lqn7X5P?b1gCSM1_Y(@nfe8`xMG)g8=!3<3d=rJ)g#iir01|bFAfX@v$PoSj zRI&dn6q2EomX37eqcf|QzE+j~5&Z7pZtGfdScy2K00LXpO61u1X^Ka5S#UKC%z-8_ z6LeT#QJGXs#WBBf+2d3um^74Z@&ILdkt2r&4SGNMHL`C!g4#xMq_vaRt24BV_%(dq zo>Ae@yZYQE@ku=J^Kdq~1M1lXreCf>ehj-lx$dAo)QxM?UBv3cUP7v3DnaM!QN*d~ zg(((_8^Quenz`Ps^4s%S?7n7Bt33dDzXEeaX}wXHFhmp-xti+*d~$V=t9s9ANF*dG zlP6?uvPp+=r1Y)Z$;7P%9rp|A(bBEr8lV6Z%@G=UC?wAGxa-O0CM6he2yr(Y-y%DPGrUoiH#lHenpy^!~4 zqy%PSpq4VZp*%S-{nfepFvZkeV45ENcW{P}-4yKAd~&4msTaFUVADfnQ*x0PPQ`27 z3-UUb4JbEM422iz&IbQ|+zs_$w#eiQy^;GO|9$tD6U9Kuo7D0ca`kqavj!8}R4EID zF1)5kQvxYYhP^=78)bJ<=-*hJqbSeoj~^EUDeQWKbHq1jv)0Ka=$!*ul=B-FDMT5e?BFg1@b**%MS z{bMPF%Q?`6-j_h=c)zfko3=s}e7|}>7*0IBy-Jq5;U6NMd@Q)TjN(=5t4}=0i)Bh7#&|>+C!H32Fd-Kkz9YGLQ`>kI!B@ zptI2l?dqiX>icnQw5@xvh3$>X4qsS8!HWZlqS8t+e$-*Z!|q28R3#^_cN&VV>i=t? zlKqCl8}gKoY`f_OpKk}7SD!y~`bX4CZ>r7Qn}MVH*S?EK<{5-)usiun*u?dSfNoK` zmeKEWyJ(l605{yic3FOw2fKLgFL$K7{HqPZp2no^k4sNa{jFEtT`%h!<)Gz1n7Q#- z2qyv=bTKPR)0bkP2^EjwQ(%N=%lTA~Ht*z&v$cmSbut;p_}w*TJ^0b4`UR45h@$+* zuMr@*WYlI4RTY?@7#uQx>3F0xblMp<-<6h0mv=ZE3sxpqA65{ybp@{juTieKS5o)g zvv!AmS6w~s_^)y%g*Y+I{xzE(O!shcnmOj61lujp*}PY@OvuN}Uz{n>l=coIg||7^ zgQs~x7S(ygU9Hm_SvS=2co=znE!Y}WdsKSD@4wGq|GfEO!c|}vfxr@A-*k26 zhTbNv^RZ07gU!UlP}J@AW3g*apVAHY_MIhH&HWLEioKXMwAms_Dm8mBhUMHTZhNpo zPha73;kn$!Rn|qE*|tCuf%e8pXsZZ>{Jy^{2aB_1i;Nq-&1lMjrQ+3-!4gE%(BfrS z!^aAw;!4(HGkQvudw!8rwJS^)*gD1ev;M1KKf~<-DtgLh0kVI{*JV&}?OHp!V+WV6 zR$ycEI?|KDqr?{$M|W-FQb@F*o+Xm>?~8cX%P}5XR*c1km$E7ybe;`dgS`&5>-qxWihkb z#dCN+knOlWZ1HE()Ol2%+KNxsH8uuffLc(vBd(^$d{8|zB#d2RW5Y>J10F1n#BmG5 zPeAJCkAe-5-0o<5ZYLr=Qs-znSYNs$kthy<)(~2^pMRZXS&KEM!aRb7M(Y4ZaT3Hw zp-3vv><)y0<$%!I=c(X4=EF1Ha&e>yDm_^xQPh(fB*-Rd2jVbIes~!4DSkGzH%^Z- zR4egLo*B}fW1-BAxJIlu8R?L&Pv}tOuFwyD)_J@y1;e{xAucJu+f!n8(p4`LBr`Y# zsea0Ec(ooGs;93+tN|#Ub^JY*sj`g>hLIH=&g7cw`V3i%dC>9hzR*4eiZHc;@1dod zo0~djv5(?*LTP+`*-j8~Pz_j#hI)#TWN`;hSC3HKKFSbF2!N#28fZoe1{tFuZ3GZ7 zgmSx?2qNfXh_HYm6qnwG%SlHdVHahHCIkzo*yv+I4geb=FJTBGUH;0xV?h-R~AA*UAbVktwJO=j4H7u+Hpse138St^D-_nXkfAB?ybHx4TEVoTL-lP%?5WH5>%UcA3! z?e!;Kf}a)B?@`B^;Y%5p4LYlZ8}>uc%Wi*~fzD+ys!LzsRS zOHE;k>YgRBsTvR4@1hi+n`V>+8-cC#VscbSWCvj9{C50fdnxst?IWkSEF9ZkN*!oE z5KdK^X`gjyufKYeDEvSmyjKkTe9CTAp!0-(+P-xG&c#xjWP}jS@X5L2>-cZ-oQzoVe!(7u+uiZRF|(IF^EfJ*pYW!Z^UsFW zgpXt>dC&o-Kl_o_#di@d>?u({MT^u3WKy2F%m?>eU(Z*&ii@9p2B5~U>Y$cg-^{ji z%UlXe7@nh6>l8!3k_|8qCJ$@pYx>ibuV?}I$((vO24}_W*hc*~Gv3j)YfV|a8}^{y z6Q+VxN40%Rqa*=hk)r~kSxl!aS?T&29Zdb4Sml9mydZ~n z3ckNPO&~-kL=RvazHX)|)X=&b1gygJi`6b48LeY;c+TOP@m{2IoOQokzm+$dZgc6c z6}qEx%ri3K2-N-^6OWz42;}%Ydco6o+-xDWJi-WI6t)9|freSwy;`?Uj1W}ChzROv zC+u>RV+LUw4SZfc^sPne^Tea743|ks>k_lquO>T7#73TV-@SkAB^;m1kAjFNh2YLl z?0^0q3x3f5A{vvCgXg?j#yUY&KexEVh;R({qs`eK1M@H-qPnEW4GiRMUGTm!J-`); zqb|JTq`(}EcA|blL7R!>%jQ?Tckt)M8c3DDd5YV#E<_yR7BO?>gvAdcZM(|xgI%@Y zLxG@H2+*tIaP)$kQz`Y9+RSKz=Jej(g<~7BGK2G%1!xuTU1{GLM24eUx#Er6SwC!phgN!Ymb*xSGU=VA*ux%tb;yf856OZoC>SozE% z6j@jA37-OZo8(7e>+EBz{x47Bi{gy6LavaQAkmGRNGkN1eNZU|IfH0f{qO?VU!Sa# z!ZvfAq5OFCqNKQqUZ^?_Yq^57b5v4f^W6n@eHd?)h|I1; z!s1ZiZ7{H9I%^0IxwDztXA&@`C`%`u3=tz+eR9(kS3st{wA4N*)U#qUg`l>uZQ^=g zoVh929&k~>i610wE1oYwM{aXNWblIFLWxngWt#m=f0!ci3ks)DVRKf7L6vFbPSVV+ zMz!A_yiL>PY1vR!(kM0q=mN9mN9N32wq)PlQmN`i2XMvoEl?$|>Z1dv1{z{*uR5aE zj7=8S{E*ij!KP^PF@wC85}@FDe$Rj;g8Mu^{W1uDpjoFexZ66ESfP0oH2mcyo}*>M zg{?j5R^QWL6t&s4iu&M3SmxK1zc`tub+`htSdomn zhF|%p?CIXSFF>W>Mau+pOBLvgTnp&LOH^Zx-BLnhyG`1$tR^vt!*cX(e8PS^>>bxf zVO5gD5#9YUNbP0UeqMFU68z{?%5t)Ej$9==mA6%GS9ss6sb^WYi%q1^NQKi_hdwK zHsCWxFAS1>p$_$`KhJ>!q%wZgDX50a2i#@C0@E2cDAfALp{%F90l3K;xWCCB8{e+V zN5YuM!ykXcF$pIy8ZUAGL3+hG#;}mtf$dGHt1-R&zVHol1u3Q^J!BZL`!ThdB!zb& z=JJ~vv-6U<>Gy3x4UbJ??~k_InLQgS{YqE1#$Q#pP`MmJJ~@^JRynn%EKz@F z=*!yK%ErQaia|rYz29cUo}>!l3q;(0V*JGjR{NW8RYaJLS461uPJDS_3Ii)XzyOd_ z)?n&K-eI*Mo*ftKb~j}xRw(I0?)2`g*hSk>Q|XQo`J^ed=BPyN2WE;v&WOp2lxx%d z);^B>iu2B2Ctf7oU-`M}tav|uT9EjK#Jp`Bsm~5R3+Uxxk9@9I54KBJ)e5c{g1k;` zqDy}vX%(?9?f?OW#Ty&EyX&=2WHbLkiO&>>IhP!bPkhau#-L^TSc?5l61plbRA!(K zKHIA=>QGP}lWCH#UB&VTl>>yku|bo|DB9HUApEC0REQY@te>h69tBl#D4L1TWBJI8 zpcIFTuMLJIYMb=KUR^nb(rJ z%beD66|{s?>In-}sW-(40Tz2Fwu8&o^~3AiID@5}n0-;A3XKWzUqdzhRUA(~;pFCc z%bLZXCYZvY{?BI98;vpD+YT%oJlvzGqJ$T28(OSX78k{q=H*}6^x`Zfwi!(x5I)WI zOieP_h3x7#5NvZx#F^y_>F}TuWLR*Ob{%UmxlXBC`m!XApLf{kp8J&O*NLj66r ziH!*eJ@+04Y$ckSOujS+j-^T=ESVW*ti?u|t|e14?QsK^z=35I4!IUZ=6Uqu5lFff zxL6>f_n8g@0K!v_s$h>^mai(Np_= zLB%_=E9F)Cw<4eA%PZ7t+lqm`>eHk`t^3V^L>Qw;7W*cT!;>vr5+_nuSvN#g^H-X= zB|E&1%}aNt&gH=ZJ67RMBHz($_xzsu^j42%j3yS#bt8_Y;MsP$SuygI^l>2t4H}mT z*Tv#2H{QZHiX`V^ZqZ;gy*LeHggU3@*KySwG?wC6n*PBOdg%r z{G5@}2GZ{)`uZ254Ah!!0GmA90*ADTjAXkv%3X?S0^AR)Zypct`NyNDuD?DhU_`Q) z;J^2`-Vw0aMnJ$BN|_Uj%qwqZqGY7ZZMG7XfgejM(ktdA6+dTXWG(|w*D&Q3_$!Aj zca%F70Sw)<$EM(Wl0AJ7Zg7Bx3hc8XpVG@lZm zj-6s97ERex{aomzmF{oB+mfoS#t=tS(t<$`;^;R*U}+vo5_r!#Kdp9Zri_dl*5Jgh0=5rdzH=F5pf-PyF*GPUJX0O~b0mKb z$z6xx2^gy9B@hUf0R-;*fQ=vb1c$_P1 zE%Y9VT1DCc%~=B7wdCG;vtw2Gbp`q}f#-BDJ5EeaF zl~zeYtI~(T$=pwM!a+L8=o;PzK67N`NKxh?{4N_>Apr~7mBo#gn%R|p{y0)9BQn{s zxhvwqkdz^PeaeHx#%TccrRp%g}d~ghdFQjPh5hheqS=Z+cYS0gNKZ9>gGn;oXzIx zRzq$Sbw1eNwOnc0nLTjY6ll`3lerU5-1I=F#{+H|!@(&0pxy?jn9i*a~x8;LaMQp93zbvqbT$U+D{+kuLX(%n))sGiKdK7@dl;1GgCN z9Gd8eZpXaZABC~LbdX^vv<1?Ina17i8X+>{j!r6;9n-KCGA|IF9b%=tQ5Vftl9I1y z`w~2qV+a+TX_1rLV&_5vujf>r4>Ek~eX(pfJ`g9~ zq;6y$j)Xe_TH$b(9$Ug0O%8;2P*HM!P{WJ{i%bznA6b~D@={`qX4O5|^r>m(nlRa= zYUI;`p4B?J`$dAM{-h0BN`@*W&^j-tKZmL-z)!Az@Kld^Nm#Vb8pmXS2pmInv|PLL zN=CNS@Y_2wNhnr$u#7tFS3#36YeEJH>t$=s11)e(c$(X-a(m(nmC0)#wdNa8*{940 zLNk#MaFSp6Zdgtg8LAO`I;fW!dBf9eHsy4GUYgQFq;f3z5E@sFiuiGUx}2>Zu}kk7 zX8Y+xuv~CZNKGc}=ib-+8U@8!8T`e8VVMGDGaoXKn)Ys2K{X1lLCJNmC~v1@Gj)JpW^Wql+ed289NoKH9x`NC_b>aX z#}0P_bO&5~b$2$C^t*CKsI@eEsN+6Q!SzNbhKciXMv1uCRVnfDD(m+0WxE51YoS8O zDp(^{W9T)W!=Cv{VzW?YbpzP-DPoAz?8U$tkCk}A5AlfzST>Wn4y(}F>(}>scFd}7 z0idXX^OyYP-Z9?Sp3>31Er890K@q~&Z8bJhRdONdCgb}@T!;)>LvlN-g-B}l2P&2y zhviPsY~AXgskzgKsj|m0ZL*aIO_nL@5_Dh7;6^Tgi$^uOP$^cIZ5iy0#!i+?UMy`9 zJlnU~m|SI;yN?95@{L!}w0-eL2S{R{KZtIG-1HeIIj_q>54hK29K|kbSS}Zp>KFUL zgKq=yIr|qBndK7>?ubdKAiro$WA>oXc^-6(BpcwsoJgi}&|L-1T40LIQV;su*D#eu z@XB)PeN&lX?#_P4o`|0=>&F!KlG_`FvxH^o{TMST^m#aOdk#wLN}oDgNqlSW$h|mn z_EsW>U9CR-b?3qS0}99nky*ZAf}a+~>?-ZpAIlTaEz9lQDvi0+_wdIJQ#q)Za)_E- zz8L91N0I(d(&Dz_*6i~vKqEQReQ?=)lxkrrBG;ln;kYR;ucxpbwrD?7M~pRCLYbAq zerhCygkBnuAY_z>z2j2^*%|keASwWjSP1Cs;em$nUiPL!LGA46Dp3kkKFJi3st)N znMhnpW;YlS-tg@m_4iaGd||eUy}y?gQkQu^Lkxm~On~z#zK=s?dWhIrWHrZy;#}l` zY8x@$z|oV zzlDa)J>3>l^DGUST=XdiA^E3Lyu?b!MKF(2K2Syym`SXVk0eDJuX?$d{l?)Xbpnd_ zL{YCf?qw~rZPcm~0*8)8U3b|=_$P5-_b2q*#6G)`D6bA7jtTMyuU?Q+1k%7*q1U-C zrQ8wPs+#C@d;Sz%{=~MhPxakcT=vyD4qx4lB43_35t{dXhm?D4(sbcfK-c-HfoeUuk!2XEKRF}=^ucwRgIp*7csI5>gbJ@Hq$1OoC5P%s`-8T zuvC_ddWu+e@bOu)>X*M1lhSB>JlSZyoRSx5$^CJWG@n+(e(2X*iowY05u&~U?9SbB zlA%;91cA}X6c&bo=$lmsQ?PhG`fLC6SuuqOj)pwnPeY`m)Ecb|0$P`pm&vov>Z8A- zEW8PaYI|s9G(jTQ7DJW`3JyYtZl@_GQM0l1KGrMuVl3-tJ$7b9AOysddYRjLOSy`x z>r9&}{YAlF-d)U~VR_oS`sOufu?A;YE@MH6h08Br&+ zY#)27A`{q${)5271b2C0uwj61Xua?4Fh{;r%$H&AaCd=)e$3iC^MXi|fb;POGfcMN zZKzejuFktcY)XqEKDX4GurU(6@-m#|@`+{pMG_&TWZ&D6q&xU75mVw#0a9klHC1kO z++YI91`c$c?`^+4*%4^pGF>Y$-D zWM^0ksoiot#I(m}XC{R5<%Q;B#@sqf`{9_Pjzg1_2t!yl0!Q}m__vJ%mQFL2&=os| zW%_V_h5A@$sf8P%UF1vgrZ!)X8axg|lLF_=zJ|-!@Ug%qi~> zL<;jBs|fzpP_>domY|(5XA$TY?7?6=5)aCL-pS{Ax&(WY-K7NWJH3`RucaeqB+Jg{ zeo%q2Jb57^V>3x``f#&4G=(6|+DCR)EqgaZpMkE0h+}UX zhzi_{N?d4c3O7ta-##m>SlZ~Zw?$ZrspGRoO+AGRtN`*{1v|YIXduM-9mr>-KH)I^ z(WA(uMU|ZvC^c>C!u_x~oaqqsC|iWBPGoT|-ub(SZETH?iNp$T;YQQ|PL%5uQ@9+A zwDWtLxKv8^1F#=KR42Y8IT55n~j+AhVPz+>%ET8>6f>;QpQ#wt|K z>PH7>ftFEqQDY9I)>(6)pgSu8BjXD;U)kSJ@iw+G?*K--1ZUShTiWF!E=mE$<(a&!#+}Yr6 zzA(dH7kJ9>5_^4uJFK4iKt)Pn(Uwbgx$|_PB?_3GIb!#Qq!z~5;%rln%9A1>Y@T>A zYc!^uU58p@d)d4uMi8D2m1)GSPLMu#Q96_od=k$Pi;a3_bH90N$+1(3vMGOSKA9iJ zE;PIz5DZ|#;!AA4tQ6h>CW|9ErmWyhu zr22}t$>umnaF;Ct@lxD4KYJrTID5^rlhn%|d% z1k<0~bv_X~YIzC{+U|~dZ4pOyOb1^{sl9&M%v)I|Vj4q8cF;|p$oS3ZXWk2aGqNR^ zHmD{AKp56l;?D7Ie`;)7=yn)SGJp#qDaHt*`dHXuL!nYygyCkCfh#q8h(y?9jegs(3Lc5ZuLE~$LZbgZ3nJ2KD-MCg0EcB8fzQjg&+8%g!uE3 zGbt&NK-#bw)e{zC?t*4|0LnR|wwci2yJwt*3FPES|2@$cO>p>av|7D&&uy&C#Qvrk z)~$Y>>eocV&K?gP8fVv|&kf8f`k@TZXg(svPs|{yT1lh=_^C~PuJI>-i-ZA&Y|++} zzn*!6^s^3=S0&Kx@KL&~5($oDjDY#jXjz7}0(i07;^-lhh#^~YUx&n?W&`xZV>4GL z$fk+zR9e1Zp5gK2Ihg(fGg1TOOS&mNf183$M8$%O(j!RAvZanJ+26X_a;z-Q>W=o( zk06}&uU5`Vb_Q_KITWQsbCkNzsj>L_@aO0Eth3+C@M0koJ$dL6Omp_?8UKlw{m(@V zba=YONS*=fUbNL}=DbDW_J^cQecpaM#qRB@eh6H0X3pV!Z__KS?LuG&8;f&TR3uxL$JDAN}J$Rm{eB{7MYyd~t}Yw)!n zWn`E^0uRDUbBs73L~^iVisf-R06^eLcuA27`}Ynb%>QRG2QQ!l@ye7W002k;zcoS} zqN=rhiZ&Rq06zl#cU|%St7ZrYzRC3h{9xk$Kk>g+g6hDcI39{tt;Z;fd`*dp!SPrjHByiZ{Rk>;XS~bsaz}8r zu9qK+MYgRGMIb)|OGx?+G`YLYGHx3*+MeC1-5cXqlO*7z&{&+9i?bS^7HB&_n?`Nr zXd1K>6Qe}kYj-1!1-wM^%7V&02;BnsQ9(%IX$6E3ZbW;dV+OQ;GT%u_S`6hRH@YvU zHa4AjND4tDTJgot(csSPmI~+v1t#0SwumL7<%0ZTfpJwTG&d(G3sRp(c+guFhp` z`}Cq2T`||y=X(thlaS$-S(e%fRz&^ngNi8+k5pHV9ixVFm0*dSkc- zIZNY>lH9C1A_oOy92XCEMd*y-=3-FF;D~%m_K_K3_KmSU@xeA(uVy5Mgv-e{3Ik$b z_V7`YMaB7;62`B|7IAWoDSEO9EbBKCQs?*-wx{QGTomy~*O)M7;vx_?m5(i{onh&+ z9W3CUAn9D1JoEiIJuJcx7Up1~RcmTZmyflOc2cQ_K8v0SVK~fy!Gu61nkGB=tZ7~S z+yn*y!2+Qcr;Z?4ReGbzUVPJeTenb)`!Ok&xoF97xV-Z1w+yU4$!i|aF&&;icb(qGNBvY86EG#5Z)6*lMf^#yM4YK( zTXtR?j;EPDF6qzWmT-xPVI%iDhY6YBaCc>Qixx1$2eL%hB}?Xqbj;?;_QlBE!w48$ z8xVjE`QIwEywr6}N*2A?=86_m6{N5iluJrhY8_Av1FI|2P7jg59)$fT{V&tv)y=(5 zrLnv|+?eaeR{?>)>I~}$t*kr?vH=$1KoVe-C+gsA7Y~#AJ9_Zeh2d1Sh1BgOFHAsCDdohk3EO zYgnA`c0JrhtnY{zLz=94CMY4|{JyPZ)x1OT0b9wI{JAO}T{hR13#XPc16%4XSlY}H z?;dB=PauX;Hd`v#=!5`_WD``F)!oeGem(2$X|bxKeD)E9wF)6*UsoZi&OCM_bw^0h z%e7&%vZ;HtCR&`M-G10e;p`nr8$qzU`dfQ6(jO2n)o(?|}f}9#tDpX9@fB2^j z<1(4VBD!crRLsAHcug8p`D{(lcD~+OtCp?I$kwVVmjBWcNgyHW0UbEOSa}{yEPh_1 zmewnx8I@OB2B)xoSRsj?2@d%QP?q{E*!A26-d;=p{p|o9U3Uc~;=Wc)y`0W)tXb@Z zB+16O*OJD&u8Rzkt>@dwF=jZb?k_1ywZs9=pwHV-$OXpAaBI;8{IjxBauAX;g!9B- zr0iolww_i);}7?J>t!Nquivph{A!7SC7O*}jd}{i3MM7wv&B8S1@5kNL!W&GPGMK7 zDcr&{UG2@wDcr23(ZvtdNYstA-B7ApcVe2&FANT8j+Ms^7>^_p@$AQZn$rI4iXU6i zI#-O8RocQlnO)M^SkJ1W$C9)W%NrFR7!{Ur_O-2arXQgWR<1rdgt z?RK2LYQ2$;TU+S(B>R4CzS=F%8YNjRL0-AR)OU#X#wR-_rIvdR3Ox zlq5>R@zTbi&mg2!iwZ5?EoCaN$2C(xC)#^}LBcrNaPmL4?7Y2zFwj^S;>A4Fp_;qRP?Z!LBK-#G_nZTCtn)X)%v9V zt4p7wS@IV#5Pl09rJVdZx0cs#fdkp=b5rAu1=jo?PRI33y(*obL(S#FpZ8Uq(vyGy ziAFe*rwPik?Tqha>5Co9WL7p~2fcLkjMjPiB! zxsHbH&vlqL>v{6CGzUCoub~qn4;q47PDz)bY$-0Ok^&=dblk!t|GFcvKjIk)A>qi# z3vPKenhrbQS+wj}XOy~3lG4&2%c;xG*7hsrfdmG8TDg7GOTm)P4l5`4P3k>}z(`hu z=LeyU$9~>hb)4E zY24PlrL5+)N3L3!8VZrji64ZJQXO8Y6IGID$j&g^5Ziy_7LT5N z_hmoq-PJFwI09_N>tyxgFvax68FB`H39n0a2Y>ouJ$xNg&UT5-{_27MP(9Cz%tB?h zI8|!gKM`6$c{f%TKzh;Y+Nua3hCb*2BF=myYVVqMTA=K3PzD?Mj=(vYeC*mW@c^vF z{>Uz$opv#R``yRAD$y~%H1kMC7m!*jGNODcJE6Mcqmg-u|uCgM_GwAvI$2X(ygO#!4 zOAJ%hCtLas&aSeY0c^;2thRAprnFnGw2@bJ*#{=0BUUEVwGi*Z!~+5?jmzk!@BLST z7oGF~His8k8PF3)uP-)gE7!aYk6!+MM$3RTJT|2ZJ-(g$s^Y#BB7s6t!;%LsB}K8s zcy2!EP^`StP!=P8w&@*R%sFVb8(Cc>ls1R6)%16OZ{$?FhmFbYMY*F>kHMF!r^g|S zisitQI^7OjE1{saOSR!J`HJAs%(z{Fm28HrnJc%98E{z!-!<(-Y54eceniAH!wZHy z%gas|og)JXH9gKslsZUL{pOCi4>1AAAR8@Wu;q8Rb3s8ymn+_b z--he@g5Eorq@uEsEmBhuUgi(^#t?gOd8AEQqaH)tG93bC4w7}*v`~$FqY6y3-V~#& z+sbZiz*ZMd8_C_31FpafA%!mC?qt}HDZ8@zebpf`#e3<$oWOSH z#jjc^GaWrog|epu25;x0$2ccZ?yBwS~Y zx_Z37e7Qd4)Dv%Y;hISk`^3y&9H9dyQ#cagQsurkoMQ(-u4FAU3_=O|*1|Qw?9JK1 zV}F8tho1`=nU|E&-aM~UeM#{h{!L#a?-ad_SkI=Fs!J`USpes)b!1Y2bQK~({pIa=|gJL78 z;+!p|-m)7*)mc_Y6#jO!DFMeXm}M>8JQRKQxBX<1->R{74qT%6D9hGGDL+%Z!#iK5)xgS#Z9$Omkq(Fh_b-jsR5xLY~TSnuN+yX~6$ArV~9PZIXKHWhmaJq1Hu>Vj}%)X17Li=CR_Kt0yB%2X% z=?g)W7V;*2s8a#eM8SYjw<1Yr%3{=a1D8ZC)L$ci97WK9ZGWSl*hAWKz0EaN$IhMc zU?YIf_G!fvceWDOD@){?boiCvyMB}vnKLx3N#;JZ6|QCZ`SZSCqFP!|k-|SQrk@X9lm0*2Iqz>aytt1WRZ%q} zjlHQ7P0=W76SXO|)u^`AY^g1+Sz23-qJ$E$XGqPjt=edf5Co|hUwhQ7)#l0f`753u zo}ceI_uPBWz2|d2@Avz4YuALkdt?65*_A#|&<)6^`uu(^GvU6&NrH`2YnjS^7GUay z^=UFCXVZrs_T#IH5~f-1SU*gX$e@&T03O9t$%HhYN3W!P209a^+hyX!{%K?{9qD8? z@!h(msx5P?J#j9}nXEGaYe;h}Uv_aF`MOh+xx4WWIb1i!1f5wTGWd^v4T?PQe!KZd zdlle>HoooUkx;P!NOb+(6O-IkmOa_bLCvuaf;lR9rS2^fC1@8 zGair1vh1kI?lt|qLGMFj=3s6hBl9{gh*LfCM_8w0kH1043q$h(Rg8UIiOSz!^4RaV zNmp8HLYIG$@gZq4%N<^}#NHrcHeRuz>;Y#%%SMz*R!g!#zCy1zu3wl^P+j=}rM#>w zS%Ing^$g+e9dnF0un65xWcOjR#@G$M^T+-(!U1%uhTy7?zZPO+fHyODp|Oax$z43S ztmlu)(+2hEm=Rx_fxqWf>Lmk+TQ-WXAV1USvn|(C$erTzcabR`7cyHWtw_9|LxDsR zU4+0%O)%ft%2ep#=}OT=)NfG3j4|;Y?+GGwGnvLB!6ev6Ni>)fNpjej?8F#w-^t(#p?T=1c61xTzOS4sYl z^IzGG_GCVP08xFVc`X};IfU1_-u|+@S8oO6M>MQ1O}Gh>Y3hcmj#(<`-#)FjD*j-1 zNk3B(mHcwLk`hC39xWzuEoLgI&*sBz)873g@P%;-u=e3H*ZPkgn4bBcil@P3jG|uuqRimS+F%sCy($8 zh<#BLl58#15oO;~6F>fg^P#9dP4pBR-e9`thwXp~=4a9~EeZJVPFJq4R6H3vCfVg%_t z-1=$do91L2#B4WLwSdL)=^mW5YT1zR&$NXcG|#1R4WoaVkkc6E348B5oJ8&RV1X+` z$Z7J4%#3x22G+OUf0(XGBsaN!O&_-UXi_EDxf(| zfzEX^VkB{YbA)89n(@f_Y8e$U=GXfC}=$bs95epw>*Ib-ROp~CQ30ARHMhje)#8SL(blwJJO`;NleY}cP;*?!SydcgDpx)2`MIpq^+6n zactkh{D|964=yxWz1Yh2hy=tkOwf_9V<)~MhONDoDNEZdBNX89SwnA|R}tJ(q%zq9 zx<*R{(#rcs4`)?BzVaZ3KyDT45EUk0@L@sZ;n_HWZXK1Ol~L>sC@Ne4A!1y3L>IV_ zdmuZWl-DI^G{6|W?*UM-T=&9`SQ#kx3H~I znuu^HepNFF$OqwNXZ^%e|6&gzFLQ$6W(|Q>qJWe(&5GzZ0oL*zH|@aSj^`>x zRxaN|Kf3R%3>@yxpTX0v((2xHO7|DyNVH89RZ4I#Jm6|;7^K@Em9hev8!3RtMg!Sg$kqq^`ZEhtK z-)ouR@qYC0@u+mgh8)#P8yf1jl^Wz8Cqkv&^h~E%^GT%mzrPlu8Rly<0CZ2-W^C z>@n`5nvZE-w%GleMk0?JnAY$}ueGB>nNOU@3L(#7kp%Rov0en*>WAmFOr)oIE1rHHGYAr{TBh8e!I6*H_R?tguPtAS&W!)HYoDevk$3a%6YI z=)3)m;0m2caoInaW8yh)xd2=~14I(vnHE%zog}X?E#)O1Kkk7!VoUWUx{{LB=8H{D zQqWgy82DLrpWhye?z7Jtw%ODuk!f~HK|LGnKKIk2vyf>j_AAR}wU}_cPC>&Ss@;!J z^Wop{jI#NO1H_85!RyBX>(e(ClIGwt`|^MwSB2g@FP~|(=Yz_` z=3k-5*IyMRo6}6V<>6v3vVEz-w1HCkgiIPv=lhlfHDoFHy2Ve@w2m*9H8XHF9%F{X ziNV0_toYMGRl{e2>Tjz#rFCbHHbJHU2W#_+#w5#(3O^IMhcBBIe8|XOij!jcB#L|i`=SbLesEtY$ zc49}glVHx35IXkx(_>oYu-ArtrCoQA7jRo&Sir``b^h{AlO68fUyO$zV`#f}tBz~s z<*^@kZFA%?M_=rD^G+~PS{GCCA=bIieY6pVr4I@})OFjfu*mW*@MLTW))hG{&Qpc& zSG)x2A_@JFMasfP#CS9*Vj#+Tb#roIVn}w2X6H&Md5BeopjK#)NBXP)oK>7E(Mc0HMG9)TkNsU}s;PxddZ>hz>q1+flnf3=x_t}?aNP9c>L z1EqPuDDzo(@ublu{o)4_Z(e#tm(ZmzZ-eVbarBB7LrwlJ$^8iZj`m!3jtt3Y&1=BX zt2a|Djmsu^g7H6I3r3y44*>F;_p5RmP+u_v&U_dS62Gp*y^eJq!Iws#SL8mC58B$V z2vWTdbm4I2(BBVdClgZzBuKHtyDqNB&v+RrkAA@T;J#~1?)dwkIrzn>^|2qYX8RPi zo|>AO)jKkYYARdvP-0hQgK-?wU)L7rluuK&yp+kqm_(N#ZQYx*=-q~$GNM9O=xRUi z>L{xD!L8M*{84ZA^*udz{61s(r!DYJ?M9;XIWd7kS4k_94UqzrxBuL>U6QPs1E{o` z1~3n&?aov`3Cz3pDJeD*!2V>c(b}hp=bLGW53*&E^`+Ht@y&-CEtKI@-&Cy{?`19a z$YNZqNl9`;ge#kXpWXV3#e7+YeV~P`Ap*>$a+pc zw-hS7z7-A63ekPM#7)@ySC<_iKpXhQrH5zF4N|1`@9aX|hSy1zGLMg`BLdVcR)oq; zlA{_jVgz0@w}B>5``I)TiHZPt(9K0O*SjcUD!|8=#cL6nmo2T-#AG1hmWW47(RJ(a7r%r z*1whTrLAc$yc*YfYu0ELk0x>UsZs0B@MK|uuU6xdB=2o#R%<;?oUUs1T1D$BfTRdTOM01m#jh_AP z7KCc7^4)&&x*NoiVE`6){?qnRo%jkGXj0doE?M>2uxdpNf0sLPqi9N(G*A#nS{i7o zS!UdrKYQ4+DpcFVoa^@{1!evufkqDE+E<-D!}CjWoch2!Qq*V9WCIQISVwB$4bwYu zvQpL$uEEH%Q6`wRj))kUMk(Z$gvv2{4Qk#fZ`2N2fbv4HykQPg01ay0-`X>)&HQhJ zIK`+L8fvY8p2o@t56RoVUb_wnhN2xF2IDY6y-BfC#ttX`kchPhX#i%S&L-z0gTME$ zUD^mbx$utqRNotla`YqX7re}`!DQ?sy}o%r*CYAwl!_p4^?!@6Vdsi#OM{9kal{tH zo3jFi?`B*W8N@tUvYFd)@xn!^a`Z*LhC)xapj-*3;ME3 zEg2w8OT^RcjppdVoc2MQ11+5_%k7(vH^-hj zYp$>SJN`I|{-t*d2G#c&i1VDmcin7XoMI-Tt>JguqnGw>>YArZb2?*DUIP5VPBUuH z|HaeNzA!#@YW0;+cHT zJj>9ntZe^!#e<|TbyPfnw%Fyo<4y%LUCm7eu*1`>AlLsls&EJ_$2;h0h<(#yXTL;^ zD|FlbXIOHop%tPdsd0t=tF%C2xfuJ~9REM~f9VjSD2!F)d%si8q8$GF3Dw}9sZOo- Hqv-zuPLnqK diff --git a/tests/dotnet/AppWithXCAssets/iOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json b/tests/dotnet/AppWithXCAssets/iOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json index 60cce20c2b25..6bd21396edd3 100644 --- a/tests/dotnet/AppWithXCAssets/iOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json +++ b/tests/dotnet/AppWithXCAssets/iOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json @@ -6,7 +6,7 @@ "scale" : "1x" }, { - "filename" : "Icon400x240 1.png", + "filename" : "Icon400x240.png", "idiom" : "tv", "scale" : "2x" } diff --git a/tests/dotnet/AppWithXCAssets/iOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Middle.imagestacklayer/Content.imageset/Icon400x240 1.png b/tests/dotnet/AppWithXCAssets/iOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Middle.imagestacklayer/Content.imageset/Icon400x240 1.png deleted file mode 100644 index f558229e8eacec411769b485348785d11f9cb85a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22054 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 Hqv-zuPLnqK diff --git a/tests/dotnet/AppWithXCAssets/macOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Back.imagestacklayer/Content.imageset/Contents.json b/tests/dotnet/AppWithXCAssets/macOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Back.imagestacklayer/Content.imageset/Contents.json index 60cce20c2b25..6bd21396edd3 100644 --- a/tests/dotnet/AppWithXCAssets/macOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Back.imagestacklayer/Content.imageset/Contents.json +++ b/tests/dotnet/AppWithXCAssets/macOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Back.imagestacklayer/Content.imageset/Contents.json @@ -6,7 +6,7 @@ "scale" : "1x" }, { - "filename" : "Icon400x240 1.png", + "filename" : "Icon400x240.png", "idiom" : "tv", "scale" : "2x" } diff --git a/tests/dotnet/AppWithXCAssets/macOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Back.imagestacklayer/Content.imageset/Icon400x240 1.png b/tests/dotnet/AppWithXCAssets/macOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Back.imagestacklayer/Content.imageset/Icon400x240 1.png deleted file mode 100644 index f558229e8eacec411769b485348785d11f9cb85a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22054 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 Hqv-zuPLnqK diff --git a/tests/dotnet/AppWithXCAssets/macOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Front.imagestacklayer/Content.imageset/Contents.json b/tests/dotnet/AppWithXCAssets/macOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Front.imagestacklayer/Content.imageset/Contents.json index 60cce20c2b25..6bd21396edd3 100644 --- a/tests/dotnet/AppWithXCAssets/macOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Front.imagestacklayer/Content.imageset/Contents.json +++ b/tests/dotnet/AppWithXCAssets/macOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Front.imagestacklayer/Content.imageset/Contents.json @@ -6,7 +6,7 @@ "scale" : "1x" }, { - "filename" : "Icon400x240 1.png", + "filename" : "Icon400x240.png", "idiom" : "tv", "scale" : "2x" } diff --git a/tests/dotnet/AppWithXCAssets/macOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Front.imagestacklayer/Content.imageset/Icon400x240 1.png b/tests/dotnet/AppWithXCAssets/macOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Front.imagestacklayer/Content.imageset/Icon400x240 1.png deleted file mode 100644 index f558229e8eacec411769b485348785d11f9cb85a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22054 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 Hqv-zuPLnqK diff --git a/tests/dotnet/AppWithXCAssets/macOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json b/tests/dotnet/AppWithXCAssets/macOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json index 60cce20c2b25..6bd21396edd3 100644 --- a/tests/dotnet/AppWithXCAssets/macOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json +++ b/tests/dotnet/AppWithXCAssets/macOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json @@ -6,7 +6,7 @@ "scale" : "1x" }, { - "filename" : "Icon400x240 1.png", + "filename" : "Icon400x240.png", "idiom" : "tv", "scale" : "2x" } diff --git a/tests/dotnet/AppWithXCAssets/macOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Middle.imagestacklayer/Content.imageset/Icon400x240 1.png b/tests/dotnet/AppWithXCAssets/macOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Middle.imagestacklayer/Content.imageset/Icon400x240 1.png deleted file mode 100644 index f558229e8eacec411769b485348785d11f9cb85a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22054 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 Hqv-zuPLnqK diff --git a/tests/dotnet/AppWithXCAssets/shared.csproj b/tests/dotnet/AppWithXCAssets/shared.csproj index 02bb2b27bf31..f61a8ba700db 100644 --- a/tests/dotnet/AppWithXCAssets/shared.csproj +++ b/tests/dotnet/AppWithXCAssets/shared.csproj @@ -5,10 +5,16 @@ AppWithXCAssets com.xamarin.appwithxcassets + + true + + AppIcons + + @@ -27,6 +33,11 @@ + + + + + diff --git a/tests/dotnet/AppWithXCAssets/shared.mk b/tests/dotnet/AppWithXCAssets/shared.mk index f555cad4e805..521c88650b37 100644 --- a/tests/dotnet/AppWithXCAssets/shared.mk +++ b/tests/dotnet/AppWithXCAssets/shared.mk @@ -1,2 +1,3 @@ TOP=../../../.. +TESTNAME=AppWithXCAssets include $(TOP)/tests/common/shared-dotnet.mk diff --git a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AlternateAppIcons.imagestack/Back.imagestacklayer/Content.imageset/Contents.json b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateAppIcons.imagestack/Back.imagestacklayer/Content.imageset/Contents.json similarity index 100% rename from tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AlternateAppIcons.imagestack/Back.imagestacklayer/Content.imageset/Contents.json rename to tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateAppIcons.imagestack/Back.imagestacklayer/Content.imageset/Contents.json diff --git a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AlternateAppIcons.imagestack/Back.imagestacklayer/Content.imageset/Icon-green-400x240.png b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateAppIcons.imagestack/Back.imagestacklayer/Content.imageset/Icon-green-400x240.png similarity index 100% rename from tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AlternateAppIcons.imagestack/Back.imagestacklayer/Content.imageset/Icon-green-400x240.png rename to tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateAppIcons.imagestack/Back.imagestacklayer/Content.imageset/Icon-green-400x240.png diff --git a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AlternateAppIcons-AppStore.imagestack/Back.imagestacklayer/Contents.json b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateAppIcons.imagestack/Back.imagestacklayer/Contents.json similarity index 100% rename from tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AlternateAppIcons-AppStore.imagestack/Back.imagestacklayer/Contents.json rename to tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateAppIcons.imagestack/Back.imagestacklayer/Contents.json diff --git a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AlternateAppIcons-AppStore.imagestack/Contents.json b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateAppIcons.imagestack/Contents.json similarity index 100% rename from tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AlternateAppIcons-AppStore.imagestack/Contents.json rename to tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateAppIcons.imagestack/Contents.json diff --git a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AlternateAppIcons.imagestack/Front.imagestacklayer/Content.imageset/Contents.json b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateAppIcons.imagestack/Front.imagestacklayer/Content.imageset/Contents.json similarity index 100% rename from tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AlternateAppIcons.imagestack/Front.imagestacklayer/Content.imageset/Contents.json rename to tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateAppIcons.imagestack/Front.imagestacklayer/Content.imageset/Contents.json diff --git a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AlternateAppIcons.imagestack/Front.imagestacklayer/Content.imageset/Icon-green-400x240.png b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateAppIcons.imagestack/Front.imagestacklayer/Content.imageset/Icon-green-400x240.png similarity index 100% rename from tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AlternateAppIcons.imagestack/Front.imagestacklayer/Content.imageset/Icon-green-400x240.png rename to tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateAppIcons.imagestack/Front.imagestacklayer/Content.imageset/Icon-green-400x240.png diff --git a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AlternateAppIcons-AppStore.imagestack/Front.imagestacklayer/Contents.json b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateAppIcons.imagestack/Front.imagestacklayer/Contents.json similarity index 100% rename from tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AlternateAppIcons-AppStore.imagestack/Front.imagestacklayer/Contents.json rename to tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateAppIcons.imagestack/Front.imagestacklayer/Contents.json diff --git a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AlternateAppIcons.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateAppIcons.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json similarity index 100% rename from tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AlternateAppIcons.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json rename to tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateAppIcons.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json diff --git a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AlternateAppIcons.imagestack/Middle.imagestacklayer/Content.imageset/Icon-green-400x240.png b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateAppIcons.imagestack/Middle.imagestacklayer/Content.imageset/Icon-green-400x240.png similarity index 100% rename from tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AlternateAppIcons.imagestack/Middle.imagestacklayer/Content.imageset/Icon-green-400x240.png rename to tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateAppIcons.imagestack/Middle.imagestacklayer/Content.imageset/Icon-green-400x240.png diff --git a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AlternateAppIcons-AppStore.imagestack/Middle.imagestacklayer/Contents.json b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateAppIcons.imagestack/Middle.imagestacklayer/Contents.json similarity index 100% rename from tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AlternateAppIcons-AppStore.imagestack/Middle.imagestacklayer/Contents.json rename to tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateAppIcons.imagestack/Middle.imagestacklayer/Contents.json diff --git a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AlternateAppIcons-AppStore.imagestack/Back.imagestacklayer/Content.imageset/Contents.json b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon-AppStore.imagestack/Back.imagestacklayer/Content.imageset/Contents.json similarity index 71% rename from tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AlternateAppIcons-AppStore.imagestack/Back.imagestacklayer/Content.imageset/Contents.json rename to tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon-AppStore.imagestack/Back.imagestacklayer/Content.imageset/Contents.json index d23b1e0950ae..08ef43149272 100644 --- a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AlternateAppIcons-AppStore.imagestack/Back.imagestacklayer/Content.imageset/Contents.json +++ b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon-AppStore.imagestack/Back.imagestacklayer/Content.imageset/Contents.json @@ -1,7 +1,7 @@ { "images" : [ { - "filename" : "Icon-green-1280x768.png", + "filename" : "Icon1280x768.png", "idiom" : "tv" } ], diff --git a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AlternateAppIcons-AppStore.imagestack/Back.imagestacklayer/Content.imageset/Icon-green-1280x768.png b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon-AppStore.imagestack/Back.imagestacklayer/Content.imageset/Icon1280x768.png similarity index 100% rename from tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AlternateAppIcons-AppStore.imagestack/Back.imagestacklayer/Content.imageset/Icon-green-1280x768.png rename to tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon-AppStore.imagestack/Back.imagestacklayer/Content.imageset/Icon1280x768.png diff --git a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AlternateAppIcons.imagestack/Back.imagestacklayer/Contents.json b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon-AppStore.imagestack/Back.imagestacklayer/Contents.json similarity index 100% rename from tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AlternateAppIcons.imagestack/Back.imagestacklayer/Contents.json rename to tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon-AppStore.imagestack/Back.imagestacklayer/Contents.json diff --git a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AlternateAppIcons.imagestack/Contents.json b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon-AppStore.imagestack/Contents.json similarity index 100% rename from tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AlternateAppIcons.imagestack/Contents.json rename to tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon-AppStore.imagestack/Contents.json diff --git a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AlternateAppIcons-AppStore.imagestack/Front.imagestacklayer/Content.imageset/Contents.json b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon-AppStore.imagestack/Front.imagestacklayer/Content.imageset/Contents.json similarity index 71% rename from tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AlternateAppIcons-AppStore.imagestack/Front.imagestacklayer/Content.imageset/Contents.json rename to tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon-AppStore.imagestack/Front.imagestacklayer/Content.imageset/Contents.json index d23b1e0950ae..08ef43149272 100644 --- a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AlternateAppIcons-AppStore.imagestack/Front.imagestacklayer/Content.imageset/Contents.json +++ b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon-AppStore.imagestack/Front.imagestacklayer/Content.imageset/Contents.json @@ -1,7 +1,7 @@ { "images" : [ { - "filename" : "Icon-green-1280x768.png", + "filename" : "Icon1280x768.png", "idiom" : "tv" } ], diff --git a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AlternateAppIcons-AppStore.imagestack/Front.imagestacklayer/Content.imageset/Icon-green-1280x768.png b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon-AppStore.imagestack/Front.imagestacklayer/Content.imageset/Icon1280x768.png similarity index 100% rename from tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AlternateAppIcons-AppStore.imagestack/Front.imagestacklayer/Content.imageset/Icon-green-1280x768.png rename to tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon-AppStore.imagestack/Front.imagestacklayer/Content.imageset/Icon1280x768.png diff --git a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AlternateAppIcons.imagestack/Front.imagestacklayer/Contents.json b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon-AppStore.imagestack/Front.imagestacklayer/Contents.json similarity index 100% rename from tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AlternateAppIcons.imagestack/Front.imagestacklayer/Contents.json rename to tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon-AppStore.imagestack/Front.imagestacklayer/Contents.json diff --git a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AlternateAppIcons-AppStore.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon-AppStore.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json similarity index 71% rename from tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AlternateAppIcons-AppStore.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json rename to tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon-AppStore.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json index d23b1e0950ae..08ef43149272 100644 --- a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AlternateAppIcons-AppStore.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json +++ b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon-AppStore.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json @@ -1,7 +1,7 @@ { "images" : [ { - "filename" : "Icon-green-1280x768.png", + "filename" : "Icon1280x768.png", "idiom" : "tv" } ], diff --git a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AlternateAppIcons-AppStore.imagestack/Middle.imagestacklayer/Content.imageset/Icon-green-1280x768.png b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon-AppStore.imagestack/Middle.imagestacklayer/Content.imageset/Icon1280x768.png similarity index 100% rename from tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AlternateAppIcons-AppStore.imagestack/Middle.imagestacklayer/Content.imageset/Icon-green-1280x768.png rename to tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon-AppStore.imagestack/Middle.imagestacklayer/Content.imageset/Icon1280x768.png diff --git a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AlternateAppIcons.imagestack/Middle.imagestacklayer/Contents.json b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon-AppStore.imagestack/Middle.imagestacklayer/Contents.json similarity index 100% rename from tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AlternateAppIcons.imagestack/Middle.imagestacklayer/Contents.json rename to tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon-AppStore.imagestack/Middle.imagestacklayer/Contents.json diff --git a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Back.imagestacklayer/Content.imageset/Contents.json b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Back.imagestacklayer/Content.imageset/Contents.json new file mode 100644 index 000000000000..6bd21396edd3 --- /dev/null +++ b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Back.imagestacklayer/Content.imageset/Contents.json @@ -0,0 +1,18 @@ +{ + "images" : [ + { + "filename" : "Icon400x240.png", + "idiom" : "tv", + "scale" : "1x" + }, + { + "filename" : "Icon400x240.png", + "idiom" : "tv", + "scale" : "2x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/tests/dotnet/AppWithXCAssets/MacCatalyst/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Back.imagestacklayer/Content.imageset/Icon400x240 1.png b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Back.imagestacklayer/Content.imageset/Icon400x240.png similarity index 100% rename from tests/dotnet/AppWithXCAssets/MacCatalyst/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Back.imagestacklayer/Content.imageset/Icon400x240 1.png rename to tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Back.imagestacklayer/Content.imageset/Icon400x240.png diff --git a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/BrandAssets.brandassets/AppIcons-AppStore.imagestack/Back.imagestacklayer/Contents.json b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Back.imagestacklayer/Contents.json similarity index 100% rename from tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/BrandAssets.brandassets/AppIcons-AppStore.imagestack/Back.imagestacklayer/Contents.json rename to tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Back.imagestacklayer/Contents.json diff --git a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/BrandAssets.brandassets/AppIcons-AppStore.imagestack/Contents.json b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Contents.json similarity index 100% rename from tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/BrandAssets.brandassets/AppIcons-AppStore.imagestack/Contents.json rename to tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Contents.json diff --git a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Front.imagestacklayer/Content.imageset/Contents.json b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Front.imagestacklayer/Content.imageset/Contents.json new file mode 100644 index 000000000000..6bd21396edd3 --- /dev/null +++ b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Front.imagestacklayer/Content.imageset/Contents.json @@ -0,0 +1,18 @@ +{ + "images" : [ + { + "filename" : "Icon400x240.png", + "idiom" : "tv", + "scale" : "1x" + }, + { + "filename" : "Icon400x240.png", + "idiom" : "tv", + "scale" : "2x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/tests/dotnet/AppWithXCAssets/MacCatalyst/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Front.imagestacklayer/Content.imageset/Icon400x240 1.png b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Front.imagestacklayer/Content.imageset/Icon400x240.png similarity index 100% rename from tests/dotnet/AppWithXCAssets/MacCatalyst/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Front.imagestacklayer/Content.imageset/Icon400x240 1.png rename to tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Front.imagestacklayer/Content.imageset/Icon400x240.png diff --git a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/BrandAssets.brandassets/AppIcons-AppStore.imagestack/Front.imagestacklayer/Contents.json b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Front.imagestacklayer/Contents.json similarity index 100% rename from tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/BrandAssets.brandassets/AppIcons-AppStore.imagestack/Front.imagestacklayer/Contents.json rename to tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Front.imagestacklayer/Contents.json diff --git a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json new file mode 100644 index 000000000000..6bd21396edd3 --- /dev/null +++ b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json @@ -0,0 +1,18 @@ +{ + "images" : [ + { + "filename" : "Icon400x240.png", + "idiom" : "tv", + "scale" : "1x" + }, + { + "filename" : "Icon400x240.png", + "idiom" : "tv", + "scale" : "2x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/tests/dotnet/AppWithXCAssets/MacCatalyst/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Middle.imagestacklayer/Content.imageset/Icon400x240 1.png b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Middle.imagestacklayer/Content.imageset/Icon400x240.png similarity index 100% rename from tests/dotnet/AppWithXCAssets/MacCatalyst/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Middle.imagestacklayer/Content.imageset/Icon400x240 1.png rename to tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Middle.imagestacklayer/Content.imageset/Icon400x240.png diff --git a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/BrandAssets.brandassets/AppIcons-AppStore.imagestack/Middle.imagestacklayer/Contents.json b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Middle.imagestacklayer/Contents.json similarity index 100% rename from tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/BrandAssets.brandassets/AppIcons-AppStore.imagestack/Middle.imagestacklayer/Contents.json rename to tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/AppIcon.imagestack/Middle.imagestacklayer/Contents.json diff --git a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/Contents.json b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/Contents.json index fdec44822147..9b55b2086ce6 100644 --- a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/Contents.json +++ b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AlternateBrandAssets.brandassets/Contents.json @@ -1,13 +1,13 @@ { "assets" : [ { - "filename" : "AlternateAppIcons-AppStore.imagestack", + "filename" : "AppIcon-AppStore.imagestack", "idiom" : "tv", "role" : "primary-app-icon", "size" : "1280x768" }, { - "filename" : "AlternateAppIcons.imagestack", + "filename" : "AppIcon.imagestack", "idiom" : "tv", "role" : "primary-app-icon", "size" : "400x240" diff --git a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/BrandAssets.brandassets/AppIcons-AppStore.imagestack/Back.imagestacklayer/Content.imageset/Contents.json b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/AppIcons-AppStore.imagestack/Back.imagestacklayer/Content.imageset/Contents.json similarity index 100% rename from tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/BrandAssets.brandassets/AppIcons-AppStore.imagestack/Back.imagestacklayer/Content.imageset/Contents.json rename to tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/AppIcons-AppStore.imagestack/Back.imagestacklayer/Content.imageset/Contents.json diff --git a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/BrandAssets.brandassets/AppIcons-AppStore.imagestack/Back.imagestacklayer/Content.imageset/Icon-blue-1280x768.png b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/AppIcons-AppStore.imagestack/Back.imagestacklayer/Content.imageset/Icon-blue-1280x768.png similarity index 100% rename from tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/BrandAssets.brandassets/AppIcons-AppStore.imagestack/Back.imagestacklayer/Content.imageset/Icon-blue-1280x768.png rename to tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/AppIcons-AppStore.imagestack/Back.imagestacklayer/Content.imageset/Icon-blue-1280x768.png diff --git a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/BrandAssets.brandassets/AppIcons.imagestack/Back.imagestacklayer/Contents.json b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/AppIcons-AppStore.imagestack/Back.imagestacklayer/Contents.json similarity index 100% rename from tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/BrandAssets.brandassets/AppIcons.imagestack/Back.imagestacklayer/Contents.json rename to tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/AppIcons-AppStore.imagestack/Back.imagestacklayer/Contents.json diff --git a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/BrandAssets.brandassets/AppIcons.imagestack/Contents.json b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/AppIcons-AppStore.imagestack/Contents.json similarity index 100% rename from tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/BrandAssets.brandassets/AppIcons.imagestack/Contents.json rename to tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/AppIcons-AppStore.imagestack/Contents.json diff --git a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/BrandAssets.brandassets/AppIcons-AppStore.imagestack/Front.imagestacklayer/Content.imageset/Contents.json b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/AppIcons-AppStore.imagestack/Front.imagestacklayer/Content.imageset/Contents.json similarity index 100% rename from tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/BrandAssets.brandassets/AppIcons-AppStore.imagestack/Front.imagestacklayer/Content.imageset/Contents.json rename to tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/AppIcons-AppStore.imagestack/Front.imagestacklayer/Content.imageset/Contents.json diff --git a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/BrandAssets.brandassets/AppIcons-AppStore.imagestack/Front.imagestacklayer/Content.imageset/Icon-blue-1280x768.png b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/AppIcons-AppStore.imagestack/Front.imagestacklayer/Content.imageset/Icon-blue-1280x768.png similarity index 100% rename from tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/BrandAssets.brandassets/AppIcons-AppStore.imagestack/Front.imagestacklayer/Content.imageset/Icon-blue-1280x768.png rename to tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/AppIcons-AppStore.imagestack/Front.imagestacklayer/Content.imageset/Icon-blue-1280x768.png diff --git a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/BrandAssets.brandassets/AppIcons.imagestack/Front.imagestacklayer/Contents.json b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/AppIcons-AppStore.imagestack/Front.imagestacklayer/Contents.json similarity index 100% rename from tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/BrandAssets.brandassets/AppIcons.imagestack/Front.imagestacklayer/Contents.json rename to tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/AppIcons-AppStore.imagestack/Front.imagestacklayer/Contents.json diff --git a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/BrandAssets.brandassets/AppIcons-AppStore.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/AppIcons-AppStore.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json similarity index 100% rename from tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/BrandAssets.brandassets/AppIcons-AppStore.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json rename to tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/AppIcons-AppStore.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json diff --git a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/BrandAssets.brandassets/AppIcons-AppStore.imagestack/Middle.imagestacklayer/Content.imageset/Icon-blue-1280x768.png b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/AppIcons-AppStore.imagestack/Middle.imagestacklayer/Content.imageset/Icon-blue-1280x768.png similarity index 100% rename from tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/BrandAssets.brandassets/AppIcons-AppStore.imagestack/Middle.imagestacklayer/Content.imageset/Icon-blue-1280x768.png rename to tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/AppIcons-AppStore.imagestack/Middle.imagestacklayer/Content.imageset/Icon-blue-1280x768.png diff --git a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/BrandAssets.brandassets/AppIcons.imagestack/Middle.imagestacklayer/Contents.json b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/AppIcons-AppStore.imagestack/Middle.imagestacklayer/Contents.json similarity index 100% rename from tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/BrandAssets.brandassets/AppIcons.imagestack/Middle.imagestacklayer/Contents.json rename to tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/AppIcons-AppStore.imagestack/Middle.imagestacklayer/Contents.json diff --git a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/BrandAssets.brandassets/AppIcons.imagestack/Back.imagestacklayer/Content.imageset/Contents.json b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/AppIcons.imagestack/Back.imagestacklayer/Content.imageset/Contents.json similarity index 100% rename from tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/BrandAssets.brandassets/AppIcons.imagestack/Back.imagestacklayer/Content.imageset/Contents.json rename to tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/AppIcons.imagestack/Back.imagestacklayer/Content.imageset/Contents.json diff --git a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/BrandAssets.brandassets/AppIcons.imagestack/Back.imagestacklayer/Content.imageset/Icon-blue-400x240.png b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/AppIcons.imagestack/Back.imagestacklayer/Content.imageset/Icon-blue-400x240.png similarity index 100% rename from tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/BrandAssets.brandassets/AppIcons.imagestack/Back.imagestacklayer/Content.imageset/Icon-blue-400x240.png rename to tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/AppIcons.imagestack/Back.imagestacklayer/Content.imageset/Icon-blue-400x240.png diff --git a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/AppIcons.imagestack/Back.imagestacklayer/Contents.json b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/AppIcons.imagestack/Back.imagestacklayer/Contents.json new file mode 100644 index 000000000000..73c00596a7fc --- /dev/null +++ b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/AppIcons.imagestack/Back.imagestacklayer/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/AppIcons.imagestack/Contents.json b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/AppIcons.imagestack/Contents.json new file mode 100644 index 000000000000..de59d885ae8d --- /dev/null +++ b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/AppIcons.imagestack/Contents.json @@ -0,0 +1,17 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "layers" : [ + { + "filename" : "Front.imagestacklayer" + }, + { + "filename" : "Middle.imagestacklayer" + }, + { + "filename" : "Back.imagestacklayer" + } + ] +} diff --git a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/BrandAssets.brandassets/AppIcons.imagestack/Front.imagestacklayer/Content.imageset/Contents.json b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/AppIcons.imagestack/Front.imagestacklayer/Content.imageset/Contents.json similarity index 100% rename from tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/BrandAssets.brandassets/AppIcons.imagestack/Front.imagestacklayer/Content.imageset/Contents.json rename to tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/AppIcons.imagestack/Front.imagestacklayer/Content.imageset/Contents.json diff --git a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/BrandAssets.brandassets/AppIcons.imagestack/Front.imagestacklayer/Content.imageset/Icon-blue-400x240.png b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/AppIcons.imagestack/Front.imagestacklayer/Content.imageset/Icon-blue-400x240.png similarity index 100% rename from tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/BrandAssets.brandassets/AppIcons.imagestack/Front.imagestacklayer/Content.imageset/Icon-blue-400x240.png rename to tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/AppIcons.imagestack/Front.imagestacklayer/Content.imageset/Icon-blue-400x240.png diff --git a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/AppIcons.imagestack/Front.imagestacklayer/Contents.json b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/AppIcons.imagestack/Front.imagestacklayer/Contents.json new file mode 100644 index 000000000000..73c00596a7fc --- /dev/null +++ b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/AppIcons.imagestack/Front.imagestacklayer/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/BrandAssets.brandassets/AppIcons.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/AppIcons.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json similarity index 100% rename from tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/BrandAssets.brandassets/AppIcons.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json rename to tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/AppIcons.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json diff --git a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/BrandAssets.brandassets/AppIcons.imagestack/Middle.imagestacklayer/Content.imageset/Icon-blue-400x240.png b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/AppIcons.imagestack/Middle.imagestacklayer/Content.imageset/Icon-blue-400x240.png similarity index 100% rename from tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/BrandAssets.brandassets/AppIcons.imagestack/Middle.imagestacklayer/Content.imageset/Icon-blue-400x240.png rename to tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/AppIcons.imagestack/Middle.imagestacklayer/Content.imageset/Icon-blue-400x240.png diff --git a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/AppIcons.imagestack/Middle.imagestacklayer/Contents.json b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/AppIcons.imagestack/Middle.imagestacklayer/Contents.json new file mode 100644 index 000000000000..73c00596a7fc --- /dev/null +++ b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/AppIcons.imagestack/Middle.imagestacklayer/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/BrandAssets.brandassets/Contents.json b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/Contents.json similarity index 100% rename from tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/BrandAssets.brandassets/Contents.json rename to tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/Contents.json diff --git a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/BrandAssets.brandassets/TopShelfImage.imageset/Contents.json b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/TopShelfImage.imageset/Contents.json similarity index 100% rename from tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/BrandAssets.brandassets/TopShelfImage.imageset/Contents.json rename to tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/TopShelfImage.imageset/Contents.json diff --git a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/BrandAssets.brandassets/TopShelfImage.imageset/Icon-blue-1920x720.png b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/TopShelfImage.imageset/Icon-blue-1920x720.png similarity index 100% rename from tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/BrandAssets.brandassets/TopShelfImage.imageset/Icon-blue-1920x720.png rename to tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/TopShelfImage.imageset/Icon-blue-1920x720.png diff --git a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/BrandAssets.brandassets/TopShelfImage.imageset/Icon-blue-3840x1440.png b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/TopShelfImage.imageset/Icon-blue-3840x1440.png similarity index 100% rename from tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/BrandAssets.brandassets/TopShelfImage.imageset/Icon-blue-3840x1440.png rename to tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/TopShelfImage.imageset/Icon-blue-3840x1440.png diff --git a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/BrandAssets.brandassets/TopShelfImageWide.imageset/Contents.json b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/TopShelfImageWide.imageset/Contents.json similarity index 100% rename from tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/BrandAssets.brandassets/TopShelfImageWide.imageset/Contents.json rename to tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/TopShelfImageWide.imageset/Contents.json diff --git a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/BrandAssets.brandassets/TopShelfImageWide.imageset/Icon-blue-2320x720.png b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/TopShelfImageWide.imageset/Icon-blue-2320x720.png similarity index 100% rename from tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/BrandAssets.brandassets/TopShelfImageWide.imageset/Icon-blue-2320x720.png rename to tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/TopShelfImageWide.imageset/Icon-blue-2320x720.png diff --git a/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/BrandAssets.brandassets/TopShelfImageWide.imageset/Icon-blue-4640x1440.png b/tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/TopShelfImageWide.imageset/Icon-blue-4640x1440.png similarity index 100% rename from tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/BrandAssets.brandassets/TopShelfImageWide.imageset/Icon-blue-4640x1440.png rename to tests/dotnet/AppWithXCAssets/tvOS/Resources/Images.xcassets/AppIcons.brandassets/TopShelfImageWide.imageset/Icon-blue-4640x1440.png diff --git a/tests/dotnet/UnitTests/AppIconTest.cs b/tests/dotnet/UnitTests/AppIconTest.cs new file mode 100644 index 000000000000..8b592b136075 --- /dev/null +++ b/tests/dotnet/UnitTests/AppIconTest.cs @@ -0,0 +1,642 @@ +#define EXHAUSTIVE_TESTS + +using System.Diagnostics.CodeAnalysis; +using System.Text.Json; + +#nullable enable + +namespace Xamarin.Tests { + public class AppIconTest : TestBaseClass { + [TestCase (ApplePlatform.iOS, "iossimulator-x64")] +#if EXHAUSTIVE_TESTS + [TestCase (ApplePlatform.iOS, "ios-arm64")] +#endif + [TestCase (ApplePlatform.TVOS, "tvossimulator-x64")] + [TestCase (ApplePlatform.MacCatalyst, "maccatalyst-x64")] +#if EXHAUSTIVE_TESTS + [TestCase (ApplePlatform.MacCatalyst, "maccatalyst-arm64;maccatalyst-x64")] +#endif + [TestCase (ApplePlatform.MacOSX, "osx-x64")] +#if EXHAUSTIVE_TESTS + [TestCase (ApplePlatform.MacOSX, "osx-arm64;osx-x64")] +#endif + public void DefaultValues (ApplePlatform platform, string runtimeIdentifiers) + { + var expectedAssets = new HashSet (); + switch (platform) { + case ApplePlatform.iOS: + expectedAssets.Add ("Image:Icon16.png"); + expectedAssets.Add ("Image:Icon32.png"); + expectedAssets.Add ("Image:Icon64.png"); + break; + case ApplePlatform.TVOS: + expectedAssets.Add ("Image:Icon-green-400x240.png"); + expectedAssets.Add ("Image:Icon16.png"); + expectedAssets.Add ("Image:Icon32.png"); + expectedAssets.Add ("Image:ZZZZFlattenedImage-1.1.0-gamut0"); + expectedAssets.Add ("Image:ZZZZFlattenedImage-2.1.0-gamut0"); + expectedAssets.Add ("Image:ZZZZRadiosityImage-1.0.0"); + expectedAssets.Add ("Image:ZZZZRadiosityImage-2.0.0"); + expectedAssets.Add ("ImageStack:AlternateAppIcons"); + break; + case ApplePlatform.MacOSX: + expectedAssets.Add ("Image:Icon16.png"); + expectedAssets.Add ("Image:Icon32.png"); + break; + case ApplePlatform.MacCatalyst: + expectedAssets.Add ("Image:Icon16.png"); + expectedAssets.Add ("Image:Icon32.png"); + break; + default: + throw new ArgumentOutOfRangeException ($"Unknown platform: {platform}"); + } + + TestXCAssetsImpl (platform, runtimeIdentifiers, extraAssets: expectedAssets.ToArray ()); + } + + [TestCase (ApplePlatform.iOS, "iossimulator-x64")] +#if EXHAUSTIVE_TESTS + [TestCase (ApplePlatform.iOS, "ios-arm64")] + [TestCase (ApplePlatform.TVOS, "tvos-arm64")] +#endif + [TestCase (ApplePlatform.TVOS, "tvossimulator-x64")] + [TestCase (ApplePlatform.MacCatalyst, "maccatalyst-x64")] +#if EXHAUSTIVE_TESTS + [TestCase (ApplePlatform.MacCatalyst, "maccatalyst-arm64;maccatalyst-x64")] +#endif + [TestCase (ApplePlatform.MacOSX, "osx-x64")] +#if EXHAUSTIVE_TESTS + [TestCase (ApplePlatform.MacOSX, "osx-arm64;osx-x64")] +#endif + public void IncludeAllIcons (ApplePlatform platform, string runtimeIdentifiers) + { + var expectedAssets = new HashSet (); + switch (platform) { + case ApplePlatform.iOS: + expectedAssets.Add ("Icon Image:Icon1024.png"); + expectedAssets.Add ("Image:Icon16.png"); + expectedAssets.Add ("Image:Icon32.png"); + expectedAssets.Add ("Image:Icon64.png"); + expectedAssets.Add ("MultiSized Image:AlternateAppIcons"); + expectedAssets.Add ("MultiSized Image:AppIcons"); + break; + case ApplePlatform.TVOS: + expectedAssets.Add ("Image:Icon-green-400x240.png"); + expectedAssets.Add ("Image:Icon16.png"); + expectedAssets.Add ("Image:Icon32.png"); + expectedAssets.Add ("Image:ZZZZFlattenedImage-1.1.0-gamut0"); + expectedAssets.Add ("Image:ZZZZFlattenedImage-2.1.0-gamut0"); + expectedAssets.Add ("Image:ZZZZRadiosityImage-1.0.0"); + expectedAssets.Add ("Image:ZZZZRadiosityImage-2.0.0"); + expectedAssets.Add ("ImageStack:AlternateAppIcons"); + break; + case ApplePlatform.MacOSX: + expectedAssets.Add ("Icon Image:Icon1024.png"); + expectedAssets.Add ("Icon Image:Icon128.png"); + expectedAssets.Add ("Icon Image:Icon16.png"); + expectedAssets.Add ("Icon Image:Icon256.png"); + expectedAssets.Add ("Icon Image:Icon32.png"); + expectedAssets.Add ("Icon Image:Icon512.png"); + expectedAssets.Add ("Icon Image:Icon64.png"); + expectedAssets.Add ("Image:Icon16.png"); + expectedAssets.Add ("Image:Icon32.png"); + expectedAssets.Add ("MultiSized Image:AlternateAppIcons"); + expectedAssets.Add ("MultiSized Image:AppIcons"); + expectedAssets.Add ("PackedImage:ZZZZPackedAsset-1.1.0-gamut0"); + expectedAssets.Add ("PackedImage:ZZZZPackedAsset-2.1.0-gamut0"); + break; + case ApplePlatform.MacCatalyst: + expectedAssets.Add ("Image:Icon16.png"); + expectedAssets.Add ("Image:Icon32.png"); + break; + default: + throw new ArgumentOutOfRangeException ($"Unknown platform: {platform}"); + } + + TestXCAssetsImpl ( + platform, + runtimeIdentifiers, + new Dictionary () { { "IncludeAllAppIcons", "true" } }, + extraAssets: expectedAssets.ToArray ()); + } + + [TestCase (ApplePlatform.iOS, "iossimulator-x64")] +#if EXHAUSTIVE_TESTS + [TestCase (ApplePlatform.iOS, "ios-arm64")] + [TestCase (ApplePlatform.TVOS, "tvos-arm64")] +#endif + [TestCase (ApplePlatform.TVOS, "tvossimulator-x64")] + [TestCase (ApplePlatform.MacCatalyst, "maccatalyst-x64")] +#if EXHAUSTIVE_TESTS + [TestCase (ApplePlatform.MacCatalyst, "maccatalyst-arm64;maccatalyst-x64")] +#endif + [TestCase (ApplePlatform.MacOSX, "osx-x64")] +#if EXHAUSTIVE_TESTS + [TestCase (ApplePlatform.MacOSX, "osx-arm64;osx-x64")] +#endif + public void XSAppIconAssets (ApplePlatform platform, string runtimeIdentifiers) + { + var expectedAssets = new HashSet (); + switch (platform) { + case ApplePlatform.iOS: + expectedAssets.Add ("Icon Image:Icon1024.png"); + expectedAssets.Add ("Image:Icon16.png"); + expectedAssets.Add ("Image:Icon32.png"); + expectedAssets.Add ("Image:Icon64.png"); + expectedAssets.Add ("MultiSized Image:AlternateAppIcons"); + break; + case ApplePlatform.TVOS: + expectedAssets.Add ("Image:Icon-green-400x240.png"); + expectedAssets.Add ("Image:Icon16.png"); + expectedAssets.Add ("Image:Icon32.png"); + expectedAssets.Add ("Image:ZZZZFlattenedImage-1.1.0-gamut0"); + expectedAssets.Add ("Image:ZZZZFlattenedImage-2.1.0-gamut0"); + expectedAssets.Add ("Image:ZZZZRadiosityImage-1.0.0"); + expectedAssets.Add ("Image:ZZZZRadiosityImage-2.0.0"); + expectedAssets.Add ("ImageStack:AlternateAppIcons"); + break; + case ApplePlatform.MacOSX: + expectedAssets.Add ("Icon Image:Icon1024.png"); + expectedAssets.Add ("Icon Image:Icon128.png"); + expectedAssets.Add ("Icon Image:Icon16.png"); + expectedAssets.Add ("Icon Image:Icon256.png"); + expectedAssets.Add ("Icon Image:Icon32.png"); + expectedAssets.Add ("Icon Image:Icon512.png"); + expectedAssets.Add ("Icon Image:Icon64.png"); + expectedAssets.Add ("Image:Icon16.png"); + expectedAssets.Add ("Image:Icon32.png"); + expectedAssets.Add ("MultiSized Image:AlternateAppIcons"); + expectedAssets.Add ("PackedImage:ZZZZPackedAsset-1.1.0-gamut0"); + expectedAssets.Add ("PackedImage:ZZZZPackedAsset-2.1.0-gamut0"); + break; + case ApplePlatform.MacCatalyst: + expectedAssets.Add ("Icon Image:Icon1024.png"); + expectedAssets.Add ("Icon Image:Icon128.png"); + expectedAssets.Add ("Icon Image:Icon16.png"); + expectedAssets.Add ("Icon Image:Icon256.png"); + expectedAssets.Add ("Icon Image:Icon32.png"); + expectedAssets.Add ("Icon Image:Icon512.png"); + expectedAssets.Add ("Icon Image:Icon64.png"); + expectedAssets.Add ("Image:Icon16.png"); + expectedAssets.Add ("Image:Icon32.png"); + expectedAssets.Add ("MultiSized Image:AlternateAppIcons"); + expectedAssets.Add ("PackedImage:ZZZZPackedAsset-1.1.0-gamut0"); + expectedAssets.Add ("PackedImage:ZZZZPackedAsset-2.1.0-gamut0"); + break; + default: + throw new ArgumentOutOfRangeException ($"Unknown platform: {platform}"); + } + + TestXCAssetsImpl ( + platform, + runtimeIdentifiers, + new Dictionary () { + { "_XSAppIconAssets", "Resources/Images.xcassets/AlternateAppIcons.appiconset" } + }, + expectedAssets.ToArray ()); + } + + [TestCase (ApplePlatform.iOS, "iossimulator-x64")] +#if EXHAUSTIVE_TESTS + [TestCase (ApplePlatform.TVOS, "tvos-arm64")] + [TestCase (ApplePlatform.TVOS, "tvossimulator-x64")] +#endif + // launch images don't exist on Mac Catalyst or macOS. + public void XSLaunchImageAssets (ApplePlatform platform, string runtimeIdentifiers) + { + var expectedAssets = new HashSet (); + switch (platform) { + case ApplePlatform.iOS: + expectedAssets.Add ("Image:Icon16.png"); + expectedAssets.Add ("Image:Icon32.png"); + expectedAssets.Add ("Image:Icon64.png"); + break; + case ApplePlatform.TVOS: + expectedAssets.Add ("Image:Icon-green-400x240.png"); + expectedAssets.Add ("Image:Icon16.png"); + expectedAssets.Add ("Image:Icon1920x1080.png"); + expectedAssets.Add ("Image:Icon32.png"); + expectedAssets.Add ("Image:Icon3840x2160.png"); + expectedAssets.Add ("Image:ZZZZFlattenedImage-1.1.0-gamut0"); + expectedAssets.Add ("Image:ZZZZFlattenedImage-2.1.0-gamut0"); + expectedAssets.Add ("Image:ZZZZRadiosityImage-1.0.0"); + expectedAssets.Add ("Image:ZZZZRadiosityImage-2.0.0"); + expectedAssets.Add ("ImageStack:AlternateAppIcons"); + break; + default: + throw new ArgumentOutOfRangeException ($"Unknown platform: {platform}"); + } + + TestXCAssetsImpl ( + platform, + runtimeIdentifiers, + new Dictionary () { + { "_XSLaunchImageAssets", $"Resources/Images.xcassets/{platform.AsString ()}LaunchImage.launchimage" } + }, + expectedAssets.ToArray ()); + } + + [TestCase (ApplePlatform.iOS, "iossimulator-x64")] +#if EXHAUSTIVE_TESTS + [TestCase (ApplePlatform.iOS, "ios-arm64")] + [TestCase (ApplePlatform.TVOS, "tvos-arm64")] +#endif + [TestCase (ApplePlatform.TVOS, "tvossimulator-x64")] + [TestCase (ApplePlatform.MacCatalyst, "maccatalyst-x64")] +#if EXHAUSTIVE_TESTS + [TestCase (ApplePlatform.MacCatalyst, "maccatalyst-arm64;maccatalyst-x64")] +#endif + [TestCase (ApplePlatform.MacOSX, "osx-x64")] +#if EXHAUSTIVE_TESTS + [TestCase (ApplePlatform.MacOSX, "osx-arm64;osx-x64")] +#endif + public void AlternateAppIcon (ApplePlatform platform, string runtimeIdentifiers) + { + var expectedAssets = new HashSet (); + switch (platform) { + case ApplePlatform.iOS: + expectedAssets.Add ("Icon Image:Icon1024.png"); + expectedAssets.Add ("Image:Icon16.png"); + expectedAssets.Add ("Image:Icon32.png"); + expectedAssets.Add ("Image:Icon64.png"); + expectedAssets.Add ("MultiSized Image:AppIcons"); + break; + case ApplePlatform.TVOS: + expectedAssets.Add ("Image:Icon-green-400x240.png"); + expectedAssets.Add ("Image:Icon16.png"); + expectedAssets.Add ("Image:Icon32.png"); + expectedAssets.Add ("Image:ZZZZFlattenedImage-1.1.0-gamut0"); + expectedAssets.Add ("Image:ZZZZFlattenedImage-2.1.0-gamut0"); + expectedAssets.Add ("Image:ZZZZRadiosityImage-1.0.0"); + expectedAssets.Add ("Image:ZZZZRadiosityImage-2.0.0"); + expectedAssets.Add ("ImageStack:AlternateAppIcons"); + break; + case ApplePlatform.MacOSX: + expectedAssets.Add ("Icon Image:Icon1024.png"); + expectedAssets.Add ("Icon Image:Icon128.png"); + expectedAssets.Add ("Icon Image:Icon16.png"); + expectedAssets.Add ("Icon Image:Icon256.png"); + expectedAssets.Add ("Icon Image:Icon32.png"); + expectedAssets.Add ("Icon Image:Icon512.png"); + expectedAssets.Add ("Icon Image:Icon64.png"); + expectedAssets.Add ("Image:Icon16.png"); + expectedAssets.Add ("Image:Icon32.png"); + expectedAssets.Add ("MultiSized Image:AppIcons"); + expectedAssets.Add ("PackedImage:ZZZZPackedAsset-1.1.0-gamut0"); + expectedAssets.Add ("PackedImage:ZZZZPackedAsset-2.1.0-gamut0"); + break; + case ApplePlatform.MacCatalyst: + expectedAssets.Add ("Image:Icon16.png"); + expectedAssets.Add ("Image:Icon32.png"); + break; + default: + throw new ArgumentOutOfRangeException ($"Unknown platform: {platform}"); + } + + TestXCAssetsImpl ( + platform, + runtimeIdentifiers, + new Dictionary () { + { "AddTheseAlternateAppIcons", "AppIcons" } + }, + expectedAssets.ToArray ()); + } + + [TestCase (ApplePlatform.iOS, "iossimulator-x64")] +#if EXHAUSTIVE_TESTS + [TestCase (ApplePlatform.iOS, "ios-arm64")] + [TestCase (ApplePlatform.TVOS, "tvos-arm64")] +#endif + [TestCase (ApplePlatform.TVOS, "tvossimulator-x64")] + [TestCase (ApplePlatform.MacCatalyst, "maccatalyst-x64")] +#if EXHAUSTIVE_TESTS + [TestCase (ApplePlatform.MacCatalyst, "maccatalyst-arm64;maccatalyst-x64")] +#endif + [TestCase (ApplePlatform.MacOSX, "osx-x64")] +#if EXHAUSTIVE_TESTS + [TestCase (ApplePlatform.MacOSX, "osx-arm64;osx-x64")] +#endif + public void AlternateAppIcons (ApplePlatform platform, string runtimeIdentifiers) + { + var expectedAssets = new HashSet (); + switch (platform) { + case ApplePlatform.iOS: + expectedAssets.Add ("Icon Image:Icon1024.png"); + expectedAssets.Add ("Image:Icon16.png"); + expectedAssets.Add ("Image:Icon32.png"); + expectedAssets.Add ("Image:Icon64.png"); + expectedAssets.Add ("MultiSized Image:AlternateAppIcons"); + expectedAssets.Add ("MultiSized Image:AppIcons"); + break; + case ApplePlatform.TVOS: + expectedAssets.Add ("Image:Icon-green-400x240.png"); + expectedAssets.Add ("Image:Icon16.png"); + expectedAssets.Add ("Image:Icon32.png"); + expectedAssets.Add ("Image:ZZZZFlattenedImage-1.1.0-gamut0"); + expectedAssets.Add ("Image:ZZZZFlattenedImage-2.1.0-gamut0"); + expectedAssets.Add ("Image:ZZZZRadiosityImage-1.0.0"); + expectedAssets.Add ("Image:ZZZZRadiosityImage-2.0.0"); + expectedAssets.Add ("ImageStack:AlternateAppIcons"); + break; + case ApplePlatform.MacOSX: + expectedAssets.Add ("Icon Image:Icon1024.png"); + expectedAssets.Add ("Icon Image:Icon128.png"); + expectedAssets.Add ("Icon Image:Icon16.png"); + expectedAssets.Add ("Icon Image:Icon256.png"); + expectedAssets.Add ("Icon Image:Icon32.png"); + expectedAssets.Add ("Icon Image:Icon512.png"); + expectedAssets.Add ("Icon Image:Icon64.png"); + expectedAssets.Add ("Image:Icon16.png"); + expectedAssets.Add ("Image:Icon32.png"); + expectedAssets.Add ("MultiSized Image:AlternateAppIcons"); + expectedAssets.Add ("MultiSized Image:AppIcons"); + expectedAssets.Add ("PackedImage:ZZZZPackedAsset-1.1.0-gamut0"); + expectedAssets.Add ("PackedImage:ZZZZPackedAsset-2.1.0-gamut0"); + break; + case ApplePlatform.MacCatalyst: + expectedAssets.Add ("Image:Icon16.png"); + expectedAssets.Add ("Image:Icon32.png"); + break; + default: + throw new ArgumentOutOfRangeException ($"Unknown platform: {platform}"); + } + + TestXCAssetsImpl ( + platform, + runtimeIdentifiers, + new Dictionary () { + { "AddTheseAlternateAppIcons", "AppIcons;AlternateAppIcons" } + }, + expectedAssets.ToArray ()); + } + + [TestCase (ApplePlatform.iOS, "iossimulator-x64")] +#if EXHAUSTIVE_TESTS + [TestCase (ApplePlatform.iOS, "ios-arm64")] + [TestCase (ApplePlatform.TVOS, "tvos-arm64")] +#endif + [TestCase (ApplePlatform.TVOS, "tvossimulator-x64")] + [TestCase (ApplePlatform.MacCatalyst, "maccatalyst-x64")] +#if EXHAUSTIVE_TESTS + [TestCase (ApplePlatform.MacCatalyst, "maccatalyst-arm64;maccatalyst-x64")] +#endif + [TestCase (ApplePlatform.MacOSX, "osx-x64")] +#if EXHAUSTIVE_TESTS + [TestCase (ApplePlatform.MacOSX, "osx-arm64;osx-x64")] +#endif + public void AlternateAppIcon_Failure (ApplePlatform platform, string runtimeIdentifiers) + { + TestXCAssetsImpl ( + platform, + runtimeIdentifiers, + new Dictionary () { + { "AddTheseAlternateAppIcons", "InexistentAppIcon" } + }, + expectedErrorMessages: new string [] { + platform == ApplePlatform.TVOS + ? "Can't find the AlternateAppIcon 'InexistentAppIcon' among the image resources. There are 5 app icons in the image resources: AlternateAppIcons, AppIcon, AppIcon-AppStore, AppIcons, AppIcons-AppStore." + : "Can't find the AlternateAppIcon 'InexistentAppIcon' among the image resources. There are 2 app icons in the image resources: AlternateAppIcons, AppIcons." + }); + } + + [TestCase (ApplePlatform.iOS, "iossimulator-x64")] +#if EXHAUSTIVE_TESTS + [TestCase (ApplePlatform.iOS, "ios-arm64")] + [TestCase (ApplePlatform.TVOS, "tvos-arm64")] +#endif + [TestCase (ApplePlatform.TVOS, "tvossimulator-x64")] + [TestCase (ApplePlatform.MacCatalyst, "maccatalyst-x64")] +#if EXHAUSTIVE_TESTS + [TestCase (ApplePlatform.MacCatalyst, "maccatalyst-arm64;maccatalyst-x64")] +#endif + [TestCase (ApplePlatform.MacOSX, "osx-x64")] +#if EXHAUSTIVE_TESTS + [TestCase (ApplePlatform.MacOSX, "osx-arm64;osx-x64")] +#endif + public void AppIcon_1 (ApplePlatform platform, string runtimeIdentifiers) + { + var expectedAssets = new HashSet (); + switch (platform) { + case ApplePlatform.iOS: + expectedAssets.Add ("Icon Image:Icon1024.png"); + expectedAssets.Add ("Image:Icon16.png"); + expectedAssets.Add ("Image:Icon32.png"); + expectedAssets.Add ("Image:Icon64.png"); + expectedAssets.Add ("MultiSized Image:AppIcons"); + break; + case ApplePlatform.TVOS: + expectedAssets.Add ("Image:Icon-blue-1280x768.png"); + expectedAssets.Add ("Image:Icon-blue-1920x720.png"); + expectedAssets.Add ("Image:Icon-blue-2320x720.png"); + expectedAssets.Add ("Image:Icon-blue-3840x1440.png"); + expectedAssets.Add ("Image:Icon-blue-400x240.png"); + expectedAssets.Add ("Image:Icon-blue-4640x1440.png"); + expectedAssets.Add ("Image:Icon-green-400x240.png"); + expectedAssets.Add ("Image:Icon16.png"); + expectedAssets.Add ("Image:Icon32.png"); + expectedAssets.Add ("Image:ZZZZFlattenedImage-1.1.0-gamut0"); + expectedAssets.Add ("Image:ZZZZFlattenedImage-2.1.0-gamut0"); + expectedAssets.Add ("Image:ZZZZRadiosityImage-1.0.0"); + expectedAssets.Add ("Image:ZZZZRadiosityImage-2.0.0"); + expectedAssets.Add ("ImageStack:AlternateAppIcons"); + expectedAssets.Add ("ImageStack:AppIcons"); + break; + case ApplePlatform.MacOSX: + expectedAssets.Add ("Icon Image:Icon1024.png"); + expectedAssets.Add ("Icon Image:Icon128.png"); + expectedAssets.Add ("Icon Image:Icon16.png"); + expectedAssets.Add ("Icon Image:Icon256.png"); + expectedAssets.Add ("Icon Image:Icon32.png"); + expectedAssets.Add ("Icon Image:Icon512.png"); + expectedAssets.Add ("Icon Image:Icon64.png"); + expectedAssets.Add ("Image:Icon16.png"); + expectedAssets.Add ("Image:Icon32.png"); + expectedAssets.Add ("MultiSized Image:AppIcons"); + expectedAssets.Add ("PackedImage:ZZZZPackedAsset-1.1.0-gamut0"); + expectedAssets.Add ("PackedImage:ZZZZPackedAsset-2.1.0-gamut0"); + break; + case ApplePlatform.MacCatalyst: + expectedAssets.Add ("Icon Image:Icon1024.png"); + expectedAssets.Add ("Icon Image:Icon128.png"); + expectedAssets.Add ("Icon Image:Icon16.png"); + expectedAssets.Add ("Icon Image:Icon256.png"); + expectedAssets.Add ("Icon Image:Icon32.png"); + expectedAssets.Add ("Icon Image:Icon512.png"); + expectedAssets.Add ("Icon Image:Icon64.png"); + expectedAssets.Add ("Image:Icon16.png"); + expectedAssets.Add ("Image:Icon32.png"); + expectedAssets.Add ("MultiSized Image:AppIcons"); + expectedAssets.Add ("PackedImage:ZZZZPackedAsset-1.1.0-gamut0"); + expectedAssets.Add ("PackedImage:ZZZZPackedAsset-2.1.0-gamut0"); + break; + default: + throw new ArgumentOutOfRangeException ($"Unknown platform: {platform}"); + } + TestXCAssetsImpl ( + platform, + runtimeIdentifiers, + new Dictionary () { + { "AppIcon", "AppIcons" } + }, + expectedAssets.ToArray ()); + } + + [TestCase (ApplePlatform.iOS, "iossimulator-x64")] +#if EXHAUSTIVE_TESTS + [TestCase (ApplePlatform.iOS, "ios-arm64")] +#endif + // Choosing a different primary app icon on tvOS at build time doesn't seem to be possible + [TestCase (ApplePlatform.TVOS, "tvos-arm64")] + [TestCase (ApplePlatform.TVOS, "tvossimulator-x64")] + [TestCase (ApplePlatform.MacCatalyst, "maccatalyst-x64")] +#if EXHAUSTIVE_TESTS + [TestCase (ApplePlatform.MacCatalyst, "maccatalyst-arm64;maccatalyst-x64")] +#endif + [TestCase (ApplePlatform.MacOSX, "osx-x64")] +#if EXHAUSTIVE_TESTS + [TestCase (ApplePlatform.MacOSX, "osx-arm64;osx-x64")] +#endif + public void AppIcon_2 (ApplePlatform platform, string runtimeIdentifiers) + { + var expectedAssets = new HashSet (); + switch (platform) { + case ApplePlatform.iOS: + expectedAssets.Add ("Icon Image:Icon1024.png"); + expectedAssets.Add ("Image:Icon16.png"); + expectedAssets.Add ("Image:Icon32.png"); + expectedAssets.Add ("Image:Icon64.png"); + expectedAssets.Add ("MultiSized Image:AlternateAppIcons"); + break; + case ApplePlatform.TVOS: + expectedAssets.Add ("Image:Icon-green-1920x720.png"); + expectedAssets.Add ("Image:Icon-green-2320x720.png"); + expectedAssets.Add ("Image:Icon-green-3840x1440.png"); + expectedAssets.Add ("Image:Icon-green-400x240.png"); + expectedAssets.Add ("Image:Icon-green-4640x1440.png"); + expectedAssets.Add ("Image:Icon1280x768.png"); + expectedAssets.Add ("Image:Icon16.png"); + expectedAssets.Add ("Image:Icon32.png"); + expectedAssets.Add ("Image:Icon400x240.png"); + expectedAssets.Add ("Image:ZZZZFlattenedImage-1.1.0-gamut0"); + expectedAssets.Add ("Image:ZZZZFlattenedImage-2.1.0-gamut0"); + expectedAssets.Add ("Image:ZZZZRadiosityImage-1.0.0"); + expectedAssets.Add ("Image:ZZZZRadiosityImage-2.0.0"); + expectedAssets.Add ("ImageStack:AlternateAppIcons"); + expectedAssets.Add ("ImageStack:AppIcon"); + break; + case ApplePlatform.MacOSX: + expectedAssets.Add ("Icon Image:Icon1024.png"); + expectedAssets.Add ("Icon Image:Icon128.png"); + expectedAssets.Add ("Icon Image:Icon16.png"); + expectedAssets.Add ("Icon Image:Icon256.png"); + expectedAssets.Add ("Icon Image:Icon32.png"); + expectedAssets.Add ("Icon Image:Icon512.png"); + expectedAssets.Add ("Icon Image:Icon64.png"); + expectedAssets.Add ("Image:Icon16.png"); + expectedAssets.Add ("Image:Icon32.png"); + expectedAssets.Add ("MultiSized Image:AlternateAppIcons"); + expectedAssets.Add ("PackedImage:ZZZZPackedAsset-1.1.0-gamut0"); + expectedAssets.Add ("PackedImage:ZZZZPackedAsset-2.1.0-gamut0"); + break; + case ApplePlatform.MacCatalyst: + expectedAssets.Add ("Icon Image:Icon1024.png"); + expectedAssets.Add ("Icon Image:Icon128.png"); + expectedAssets.Add ("Icon Image:Icon16.png"); + expectedAssets.Add ("Icon Image:Icon256.png"); + expectedAssets.Add ("Icon Image:Icon32.png"); + expectedAssets.Add ("Icon Image:Icon512.png"); + expectedAssets.Add ("Icon Image:Icon64.png"); + expectedAssets.Add ("Image:Icon16.png"); + expectedAssets.Add ("Image:Icon32.png"); + expectedAssets.Add ("MultiSized Image:AlternateAppIcons"); + expectedAssets.Add ("PackedImage:ZZZZPackedAsset-1.1.0-gamut0"); + expectedAssets.Add ("PackedImage:ZZZZPackedAsset-2.1.0-gamut0"); + break; + default: + throw new ArgumentOutOfRangeException ($"Unknown platform: {platform}"); + } + TestXCAssetsImpl ( + platform, + runtimeIdentifiers, + new Dictionary () { + { "AppIcon", platform == ApplePlatform.TVOS ? "AlternateBrandAssets" : "AlternateAppIcons" } + }, + expectedAssets.ToArray ()); + } + + [TestCase (ApplePlatform.iOS, "iossimulator-x64")] +#if EXHAUSTIVE_TESTS + [TestCase (ApplePlatform.iOS, "ios-arm64")] + [TestCase (ApplePlatform.TVOS, "tvos-arm64")] +#endif + [TestCase (ApplePlatform.TVOS, "tvossimulator-x64")] + [TestCase (ApplePlatform.MacCatalyst, "maccatalyst-x64")] +#if EXHAUSTIVE_TESTS + [TestCase (ApplePlatform.MacCatalyst, "maccatalyst-arm64;maccatalyst-x64")] +#endif + [TestCase (ApplePlatform.MacOSX, "osx-x64")] +#if EXHAUSTIVE_TESTS + [TestCase (ApplePlatform.MacOSX, "osx-arm64;osx-x64")] +#endif + public void AppIcon_Failure (ApplePlatform platform, string runtimeIdentifiers) + { + TestXCAssetsImpl ( + platform, + runtimeIdentifiers, + new Dictionary () { + { "AppIcon", "InexistentAppIcon" } + }, + expectedErrorMessages: new string [] { + platform == ApplePlatform.TVOS + ? "Can't find the AppIcon 'InexistentAppIcon' among the image resources. There are 2 app icons in the image resources: AlternateBrandAssets, AppIcons." + : "Can't find the AppIcon 'InexistentAppIcon' among the image resources. There are 2 app icons in the image resources: AlternateAppIcons, AppIcons." + }); + } + + void TestXCAssetsImpl (ApplePlatform platform, string runtimeIdentifiers, Dictionary? extraProperties = null, IEnumerable? extraAssets = null, string []? expectedErrorMessages = null) + { + var projectPath = string.Empty; + var appPath = string.Empty; + + Configuration.AssertRuntimeIdentifiersAvailable (platform, runtimeIdentifiers); + var project = "AppWithXCAssets"; + Configuration.IgnoreIfIgnoredPlatform (platform); + projectPath = GetProjectPath (project, runtimeIdentifiers: runtimeIdentifiers, platform: platform, out appPath); + + Clean (projectPath); + + var properties = GetDefaultProperties (runtimeIdentifiers, extraProperties); + properties ["IsRunningUnitTests"] = "true"; + if (expectedErrorMessages is not null) { + var rv = DotNet.AssertBuildFailure (projectPath, properties); + var errors = BinLog.GetBuildLogErrors (rv.BinLogPath).ToArray (); + AssertErrorMessages (errors, expectedErrorMessages); + return; // nothing else to test here + } + + DotNet.AssertBuild (projectPath, properties); + + var resourcesDirectory = GetResourcesDirectory (platform, appPath); + var assetsCar = Path.Combine (resourcesDirectory, "Assets.car"); + Assert.That (assetsCar, Does.Exist, "Assets.car"); + + try { + var doc = AssetsTest.ProcessAssets (assetsCar, AssetsTest.GetFullSdkVersion (platform, runtimeIdentifiers)); + Assert.IsNotNull (doc, "There was an issue processing the asset binary."); + + var foundAssets = AssetsTest.FindAssets (platform, doc); + + var expectedAssets = new HashSet (); + if (extraAssets is not null) { + foreach (var asset in extraAssets) + expectedAssets.Add (asset); + } + + CollectionAssert.AreEquivalent (expectedAssets, foundAssets, "Incorrect assets"); + } catch { + Console.WriteLine ($"Assets.car: {assetsCar}"); + throw; + } + } + } +} diff --git a/tests/dotnet/UnitTests/AssetsTest.cs b/tests/dotnet/UnitTests/AssetsTest.cs index 618cb1945ad9..6ecf003f6995 100644 --- a/tests/dotnet/UnitTests/AssetsTest.cs +++ b/tests/dotnet/UnitTests/AssetsTest.cs @@ -260,35 +260,66 @@ static bool TryGetTarget (JsonElement item, JsonElement assetType, XCAssetTarget "Image:samplepng2.png", "Image:spritejpeg.jpeg", "Image:xamlogo.svg", + "Image:Icon16.png", + "Image:Icon32.png", "PackedImage:ZZZZExplicitlyPackedAsset-1.0.0-gamut0", "Texture Rendition:TextureTest", }; static HashSet ExpectedAssetsMacCatalyst => new HashSet (ExpectedAssetsAllPlatforms) { - "Image:Icon16.png", - "Image:Icon32.png", + "Icon Image:Icon1024.png", + "Icon Image:Icon128.png", + "Icon Image:Icon16.png", + "Icon Image:Icon256.png", + "Icon Image:Icon32.png", + "Icon Image:Icon512.png", + "Icon Image:Icon64.png", + "MultiSized Image:AppIcons", + "PackedImage:ZZZZPackedAsset-1.1.0-gamut0", + "PackedImage:ZZZZPackedAsset-2.1.0-gamut0", }; static readonly HashSet ExpectedAssetsiOS = new HashSet (ExpectedAssetsAllPlatforms) { + "Icon Image:Icon1024.png", + "Image:Icon64.png", + "MultiSized Image:AlternateAppIcons", + "MultiSized Image:AppIcons", "Vector:samplepdf.pdf", "Vector:xamlogo.svg", - "Image:Icon16.png", - "Image:Icon32.png", - "Image:Icon64.png", }; static readonly HashSet ExpectedAssetstvOS = new HashSet (ExpectedAssetsAllPlatforms) { + "Image:Icon-blue-1280x768.png", + "Image:Icon-blue-1920x720.png", + "Image:Icon-blue-2320x720.png", + "Image:Icon-blue-3840x1440.png", + "Image:Icon-blue-400x240.png", + "Image:Icon-blue-4640x1440.png", + "Image:Icon-green-400x240.png", + "Image:ZZZZFlattenedImage-1.1.0-gamut0", + "Image:ZZZZFlattenedImage-2.1.0-gamut0", + "Image:ZZZZRadiosityImage-1.0.0", + "Image:ZZZZRadiosityImage-2.0.0", + "ImageStack:AlternateAppIcons", + "ImageStack:AppIcons", "Vector:samplepdf.pdf", "Vector:xamlogo.svg", - "Image:Icon16.png", - "Image:Icon32.png", }; static readonly HashSet ExpectedAssetsmacOS = new HashSet (ExpectedAssetsAllPlatforms) { + "Icon Image:Icon1024.png", + "Icon Image:Icon128.png", + "Icon Image:Icon16.png", + "Icon Image:Icon256.png", + "Icon Image:Icon32.png", + "Icon Image:Icon512.png", + "Icon Image:Icon64.png", + "MultiSized Image:AlternateAppIcons", + "MultiSized Image:AppIcons", + "PackedImage:ZZZZPackedAsset-1.1.0-gamut0", + "PackedImage:ZZZZPackedAsset-2.1.0-gamut0", "Vector:samplepdf.pdf", "Vector:xamlogo.svg", - "Image:Icon16.png", - "Image:Icon32.png", }; class XCAssetTarget { diff --git a/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/ACToolTaskTest.cs b/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/ACToolTaskTest.cs new file mode 100644 index 000000000000..9cffde4e5d9c --- /dev/null +++ b/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/ACToolTaskTest.cs @@ -0,0 +1,447 @@ +using System; +using System.IO; +using System.Linq; +using System.Collections.Generic; + +using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; + +using NUnit.Framework; + +using Xamarin.MacDev; +using Xamarin.MacDev.Tasks; +using Xamarin.Tests; +using Xamarin.Utils; + +namespace Xamarin.MacDev.Tasks { + [TestFixture] + public class ACToolTaskTests : TestBase { + ACTool CreateACToolTask (ApplePlatform platform, string projectDir, out string intermediateOutputPath, params string [] imageAssets) + { + Configuration.IgnoreIfIgnoredPlatform (platform); + + intermediateOutputPath = Cache.CreateTemporaryDirectory (); + + var sdk = Sdks.GetAppleSdk (platform); + var version = AppleSdkVersion.UseDefault.ToString (); + var root = sdk.GetSdkPath (version, false); + var usr = Path.Combine (sdk.DeveloperRoot, "usr"); + var bin = Path.Combine (usr, "bin"); + string sdkPlatform; + var uiDeviceFamily = ""; + + switch (platform) { + case ApplePlatform.TVOS: + sdkPlatform = "AppleTVOS"; + uiDeviceFamily = "TV"; + break; + case ApplePlatform.iOS: + sdkPlatform = "iPhoneOS"; + uiDeviceFamily = "IPhone, IPad"; + break; + case ApplePlatform.MacOSX: + sdkPlatform = "MacOSX"; + break; + case ApplePlatform.MacCatalyst: + sdkPlatform = "MacCatalyst"; + break; + default: + throw new NotImplementedException (platform.ToString ()); + } + + var task = CreateTask (); + task.ImageAssets = imageAssets + .Select (v => { + var spl = v.Split ('|'); + var rv = new TaskItem (spl [0]); + rv.SetMetadata ("Link", spl [1]); + return rv; + }) + .Cast () + .ToArray (); + task.IntermediateOutputPath = intermediateOutputPath; + task.MinimumOSVersion = Xamarin.SdkVersions.GetMinVersion (platform).ToString (); + task.OutputPath = Path.Combine (intermediateOutputPath, "OutputPath"); + task.ProjectDir = projectDir; + task.SdkDevPath = Configuration.xcode_root; + task.SdkPlatform = sdkPlatform; + task.SdkVersion = version.ToString (); + task.SdkUsrPath = usr; + task.SdkBinPath = bin; + task.TargetFrameworkMoniker = TargetFramework.GetTargetFramework (platform, true).ToString (); + task.UIDeviceFamily = uiDeviceFamily; + return task; + } + + ACTool CreateACToolTaskWithResources (ApplePlatform platform) + { + var projectDir = Path.Combine (Configuration.SourceRoot, "tests", "dotnet", "AppWithXCAssets", platform.AsString ()); + var files = Directory.GetFiles (Path.Combine (projectDir, "Resources", "Images.xcassets"), "*", SearchOption.AllDirectories); + var imageAssets = files.Select (v => v + "|" + v.Substring (projectDir.Length + 1)).ToArray (); + return CreateACToolTask ( + platform, + projectDir, + out var _, + imageAssets + ); + } + + [Test] + [TestCase (ApplePlatform.iOS)] + [TestCase (ApplePlatform.TVOS)] + [TestCase (ApplePlatform.MacCatalyst)] + [TestCase (ApplePlatform.MacOSX)] + public void DefaultAppIcons (ApplePlatform platform) + { + var actool = CreateACToolTaskWithResources (platform); + ExecuteTask (actool); + + Assert.IsNotNull (actool.PartialAppManifest, "PartialAppManifest"); + var appIconsManifest = PDictionary.FromFile (actool.PartialAppManifest.ItemSpec!)!; + Assert.AreEqual (0, appIconsManifest.Count, $"Partial plist contents: {actool.PartialAppManifest.ItemSpec}"); + } + + [Test] + [TestCase (ApplePlatform.iOS)] + [TestCase (ApplePlatform.TVOS)] + [TestCase (ApplePlatform.MacCatalyst)] + [TestCase (ApplePlatform.MacOSX)] + public void AllAppIcons (ApplePlatform platform) + { + var actool = CreateACToolTaskWithResources (platform); + actool.IncludeAllAppIcons = true; + + ExecuteTask (actool); + + Assert.IsNotNull (actool.PartialAppManifest, "PartialAppManifest"); + + var appIconsManifest = PDictionary.FromFile (actool.PartialAppManifest.ItemSpec!)!; + Assert.AreEqual (0, appIconsManifest.Count, $"Partial plist contents: {actool.PartialAppManifest.ItemSpec}"); + } + + [Test] + [TestCase (ApplePlatform.iOS)] + [TestCase (ApplePlatform.TVOS)] + [TestCase (ApplePlatform.MacCatalyst)] + [TestCase (ApplePlatform.MacOSX)] + public void AllAppIconsWithAppIcon (ApplePlatform platform) + { + var actool = CreateACToolTaskWithResources (platform); + actool.IncludeAllAppIcons = true; + if (platform == ApplePlatform.TVOS) { + actool.AppIcon = "AlternateBrandAssets"; + } else { + actool.AppIcon = "AlternateAppIcons"; + } + + ExecuteTask (actool); + + Assert.IsNotNull (actool.PartialAppManifest, "PartialAppManifest"); + + var appIconsManifest = PDictionary.FromFile (actool.PartialAppManifest?.ItemSpec)!; + Assert.AreEqual (2, appIconsManifest.Count, $"Partial plist contents: {actool.PartialAppManifest.ItemSpec}"); + if (platform == ApplePlatform.MacOSX || platform == ApplePlatform.MacCatalyst) { + Assert.AreEqual ("AlternateAppIcons", appIconsManifest.Get ("CFBundleIconFile")?.Value, "CFBundleIconFile"); + Assert.AreEqual ("AlternateAppIcons", appIconsManifest.Get ("CFBundleIconName")?.Value, "CFBundleIconName"); + } else if (platform == ApplePlatform.TVOS) { + var cfBundleIcons = appIconsManifest.Get ("CFBundleIcons"); + Assert.AreEqual (1, cfBundleIcons.Count, "CFBundleIcons.Count"); + Assert.AreEqual ("AlternateAppIcons", cfBundleIcons.Get ("CFBundlePrimaryIcon")?.Value, "CFBundlePrimaryIcon"); + + var tvTopShelfImage = appIconsManifest.Get ("TVTopShelfImage"); + Assert.AreEqual (2, tvTopShelfImage.Count, "TVTopShelfImage.Count"); + Assert.AreEqual ("TopShelfImage", tvTopShelfImage.Get ("TVTopShelfPrimaryImage")?.Value, "TVTopShelfPrimaryImage"); + Assert.AreEqual ("TopShelfImageWide", tvTopShelfImage.Get ("TVTopShelfPrimaryImageWide")?.Value, "TVTopShelfPrimaryImageWide"); + } else { + { + // iPhone + var cfBundleIcons = appIconsManifest.Get ("CFBundleIcons"); + Assert.AreEqual (2, cfBundleIcons.Count, "CFBundleIcons.Count"); + + var cfBundlePrimaryIcon = cfBundleIcons.Get ("CFBundlePrimaryIcon"); + Assert.AreEqual (2, cfBundlePrimaryIcon.Count, "CFBundlePrimaryIcon.Length"); + + var cfBundleIconFiles = cfBundlePrimaryIcon.Get ("CFBundleIconFiles"); + Assert.AreEqual (1, cfBundleIconFiles.Count, "CFBundleIconFiles.Length"); + Assert.AreEqual ("AlternateAppIcons60x60", ((PString) cfBundleIconFiles [0]).Value, "CFBundleIconFiles[0].Value"); + Assert.AreEqual ("AlternateAppIcons", cfBundlePrimaryIcon.Get ("CFBundleIconName")?.Value, "CFBundleIconName"); + + var cfBundleAlternateIcons = cfBundleIcons.Get ("CFBundleAlternateIcons"); + Assert.AreEqual (1, cfBundleAlternateIcons.Count, "CFBundleAlternateIcons.Count"); + + var alternateAppIcons = cfBundleAlternateIcons.Get ("AppIcons"); + Assert.AreEqual (2, alternateAppIcons.Count, "AppIcons.Count"); + Assert.AreEqual ("AppIcons", alternateAppIcons.Get ("CFBundleIconName")?.Value, "CFBundleIconName"); + + var appIcons_cfBundleIconFiles = alternateAppIcons.Get ("CFBundleIconFiles"); + Assert.AreEqual (2, appIcons_cfBundleIconFiles.Count, "AppIcons.CFBundleIconFiles.Length"); + Assert.AreEqual ("AppIcons60x60", ((PString) appIcons_cfBundleIconFiles [0]).Value, "AppIcons.CFBundleIconFiles[0].Value"); + Assert.AreEqual ("AppIcons76x76", ((PString) appIcons_cfBundleIconFiles [1]).Value, "AppIcons.CFBundleIconFiles[1].Value"); + } + { + // iPad + var cfBundleIcons = appIconsManifest.Get ("CFBundleIcons~ipad"); + Assert.AreEqual (2, cfBundleIcons.Count, "CFBundleIcons.Count"); + + var cfBundlePrimaryIcon = cfBundleIcons.Get ("CFBundlePrimaryIcon"); + Assert.AreEqual (2, cfBundlePrimaryIcon.Count, "CFBundlePrimaryIcon.Length"); + + var cfBundleIconFiles = cfBundlePrimaryIcon.Get ("CFBundleIconFiles"); + Assert.AreEqual (2, cfBundleIconFiles.Count, "CFBundleIconFiles.Length"); + Assert.AreEqual ("AlternateAppIcons60x60", ((PString) cfBundleIconFiles [0]).Value, "CFBundleIconFiles[0].Value"); + Assert.AreEqual ("AlternateAppIcons76x76", ((PString) cfBundleIconFiles [1]).Value, "CFBundleIconFiles[1].Value"); + Assert.AreEqual ("AlternateAppIcons", cfBundlePrimaryIcon.Get ("CFBundleIconName")?.Value, "CFBundleIconName"); + + var cfBundleAlternateIcons = cfBundleIcons.Get ("CFBundleAlternateIcons"); + Assert.AreEqual (1, cfBundleAlternateIcons.Count, "CFBundleAlternateIcons.Count"); + + var appIcons = cfBundleAlternateIcons.Get ("AppIcons"); + Assert.AreEqual (2, appIcons.Count, "AppIcons.Count"); + Assert.AreEqual ("AppIcons", appIcons.Get ("CFBundleIconName")?.Value, "CFBundleIconName"); + + var appIcons_cfBundleIconFiles = appIcons.Get ("CFBundleIconFiles"); + Assert.AreEqual (2, appIcons_cfBundleIconFiles.Count, "AppIcons.CFBundleIconFiles.Length"); + Assert.AreEqual ("AppIcons60x60", ((PString) appIcons_cfBundleIconFiles [0]).Value, "AppIcons.CFBundleIconFiles[0].Value"); + Assert.AreEqual ("AppIcons76x76", ((PString) appIcons_cfBundleIconFiles [1]).Value, "AppIcons.CFBundleIconFiles[1].Value"); + } + } + } + + [Test] + [TestCase (ApplePlatform.iOS)] + [TestCase (ApplePlatform.TVOS)] + [TestCase (ApplePlatform.MacCatalyst)] + [TestCase (ApplePlatform.MacOSX)] + public void AppIcon (ApplePlatform platform) + { + var actool = CreateACToolTaskWithResources (platform); + if (platform == ApplePlatform.TVOS) { + actool.AppIcon = "BrandAssets"; + } else { + actool.AppIcon = "AppIcons"; + } + + ExecuteTask (actool); + + Assert.IsNotNull (actool.PartialAppManifest, "PartialAppManifest"); + + var appIconsManifest = PDictionary.FromFile (actool.PartialAppManifest.ItemSpec!)!; + if (platform == ApplePlatform.MacOSX || platform == ApplePlatform.MacCatalyst) { + Assert.AreEqual (2, appIconsManifest.Count, $"Partial plist contents: {actool.PartialAppManifest.ItemSpec}"); + Assert.AreEqual ("AppIcons", appIconsManifest.Get ("CFBundleIconFile")?.Value, "CFBundleIconFile"); + Assert.AreEqual ("AppIcons", appIconsManifest.Get ("CFBundleIconName")?.Value, "CFBundleIconName"); + } else if (platform == ApplePlatform.TVOS) { + Assert.AreEqual (2, appIconsManifest.Count, $"Partial plist contents: {actool.PartialAppManifest.ItemSpec}"); + + var cfBundleIcons = appIconsManifest.Get ("CFBundleIcons"); + Assert.AreEqual (1, cfBundleIcons.Count, "CFBundleIcons.Count"); + Assert.AreEqual ("AppIcons", cfBundleIcons.Get ("CFBundlePrimaryIcon")?.Value, "CFBundlePrimaryIcon"); + + var tvTopShelfImage = appIconsManifest.Get ("TVTopShelfImage"); + Assert.AreEqual (2, tvTopShelfImage.Count, "TVTopShelfImage.Count"); + Assert.AreEqual ("TopShelfImage", tvTopShelfImage.Get ("TVTopShelfPrimaryImage")?.Value, "TVTopShelfPrimaryImage"); + Assert.AreEqual ("TopShelfImageWide", tvTopShelfImage.Get ("TVTopShelfPrimaryImageWide")?.Value, "TVTopShelfPrimaryImageWide"); + } else { + { + // iPhone + var cfBundleIcons = appIconsManifest.Get ("CFBundleIcons"); + Assert.AreEqual (1, cfBundleIcons.Count, "CFBundleIcons.Count"); + + var cfBundlePrimaryIcon = cfBundleIcons.Get ("CFBundlePrimaryIcon"); + Assert.AreEqual (2, cfBundlePrimaryIcon.Count, "CFBundlePrimaryIcon.Length"); + + var cfBundleIconFiles = cfBundlePrimaryIcon.Get ("CFBundleIconFiles"); + Assert.AreEqual (1, cfBundleIconFiles.Count, "CFBundleIconFiles.Length"); + Assert.AreEqual ("AppIcons60x60", ((PString) cfBundleIconFiles [0]).Value, "CFBundleIconFiles[0].Value"); + Assert.AreEqual ("AppIcons", cfBundlePrimaryIcon.Get ("CFBundleIconName")?.Value, "CFBundleIconName"); + } + { + // iPad + var cfBundleIcons = appIconsManifest.Get ("CFBundleIcons~ipad"); + Assert.AreEqual (1, cfBundleIcons.Count, "CFBundleIcons.Count"); + + var cfBundlePrimaryIcon = cfBundleIcons.Get ("CFBundlePrimaryIcon"); + Assert.AreEqual (2, cfBundlePrimaryIcon.Count, "CFBundlePrimaryIcon.Length"); + + var cfBundleIconFiles = cfBundlePrimaryIcon.Get ("CFBundleIconFiles"); + Assert.AreEqual (2, cfBundleIconFiles.Count, "CFBundleIconFiles.Length"); + Assert.AreEqual ("AppIcons60x60", ((PString) cfBundleIconFiles [0]).Value, "CFBundleIconFiles[0].Value"); + Assert.AreEqual ("AppIcons76x76", ((PString) cfBundleIconFiles [1]).Value, "CFBundleIconFiles[1].Value"); + Assert.AreEqual ("AppIcons", cfBundlePrimaryIcon.Get ("CFBundleIconName")?.Value, "CFBundleIconName"); + } + } + } + + [Test] + [TestCase (ApplePlatform.iOS)] + [TestCase (ApplePlatform.TVOS)] + [TestCase (ApplePlatform.MacCatalyst)] + [TestCase (ApplePlatform.MacOSX)] + public void AppIconAndAlternateIcons (ApplePlatform platform) + { + var actool = CreateACToolTaskWithResources (platform); + if (platform == ApplePlatform.TVOS) { + actool.AppIcon = "BrandAssets"; + actool.AlternateAppIcons = new ITaskItem [] { new TaskItem ("AlternateBrandAssets") }; + } else { + actool.AppIcon = "AppIcons"; + actool.AlternateAppIcons = new ITaskItem [] { new TaskItem ("AlternateAppIcons") }; + } + + ExecuteTask (actool); + + Assert.IsNotNull (actool.PartialAppManifest, "PartialAppManifest"); + + var appIconsManifest = PDictionary.FromFile (actool.PartialAppManifest.ItemSpec!)!; + Assert.AreEqual (2, appIconsManifest.Count, $"Partial plist contents: {actool.PartialAppManifest.ItemSpec}"); + if (platform == ApplePlatform.MacOSX || platform == ApplePlatform.MacCatalyst) { + Assert.AreEqual ("AppIcons", appIconsManifest.Get ("CFBundleIconFile")?.Value, "CFBundleIconFile"); + Assert.AreEqual ("AppIcons", appIconsManifest.Get ("CFBundleIconName")?.Value, "CFBundleIconName"); + } else if (platform == ApplePlatform.TVOS) { + var cfBundleIcons = appIconsManifest.Get ("CFBundleIcons"); + Assert.AreEqual (1, cfBundleIcons.Count, "CFBundleIcons.Count"); + Assert.AreEqual ("AppIcons", cfBundleIcons.Get ("CFBundlePrimaryIcon")?.Value, "CFBundlePrimaryIcon"); + + var tvTopShelfImage = appIconsManifest.Get ("TVTopShelfImage"); + Assert.AreEqual (2, tvTopShelfImage.Count, "TVTopShelfImage.Count"); + Assert.AreEqual ("TopShelfImage", tvTopShelfImage.Get ("TVTopShelfPrimaryImage")?.Value, "TVTopShelfPrimaryImage"); + Assert.AreEqual ("TopShelfImageWide", tvTopShelfImage.Get ("TVTopShelfPrimaryImageWide")?.Value, "TVTopShelfPrimaryImageWide"); + } else { + { + // iPhone + var cfBundleIcons = appIconsManifest.Get ("CFBundleIcons"); + Assert.AreEqual (2, cfBundleIcons.Count, "CFBundleIcons.Count"); + + var cfBundlePrimaryIcon = cfBundleIcons.Get ("CFBundlePrimaryIcon"); + Assert.AreEqual (2, cfBundlePrimaryIcon.Count, "CFBundlePrimaryIcon.Length"); + Assert.AreEqual ("AppIcons", cfBundlePrimaryIcon.Get ("CFBundleIconName")?.Value, "CFBundleIconName"); + + var cfBundleIconFiles = cfBundlePrimaryIcon.Get ("CFBundleIconFiles"); + Assert.AreEqual (1, cfBundleIconFiles.Count, "CFBundleIconFiles.Length"); + Assert.AreEqual ("AppIcons60x60", ((PString) cfBundleIconFiles [0]).Value, "CFBundleIconFiles[0].Value"); + + var cfBundleAlternateIcons = cfBundleIcons.Get ("CFBundleAlternateIcons"); + Assert.AreEqual (1, cfBundleAlternateIcons.Count, "CFBundleAlternateIcons.Count"); + + var alternateAppIcons = cfBundleAlternateIcons.Get ("AlternateAppIcons"); + Assert.AreEqual (2, alternateAppIcons.Count, "CFBundleAlternateIcons.Count"); + Assert.AreEqual ("AlternateAppIcons", alternateAppIcons.Get ("CFBundleIconName")?.Value, "CFBundleIconName"); + + var alternateAppIcons_CFBundleIconFiles = alternateAppIcons.Get ("CFBundleIconFiles"); + Assert.AreEqual (2, alternateAppIcons_CFBundleIconFiles.Count, "AlternateAppIcons.CFBundleIconFiles.Count"); + Assert.AreEqual ("AlternateAppIcons60x60", ((PString) alternateAppIcons_CFBundleIconFiles [0]).Value, "AlternateAppIcons.CFBundleIconFiles[0]"); + Assert.AreEqual ("AlternateAppIcons76x76", ((PString) alternateAppIcons_CFBundleIconFiles [1]).Value, "AlternateAppIcons.CFBundleIconFiles[1]"); + } + { + // iPad + var cfBundleIcons = appIconsManifest.Get ("CFBundleIcons~ipad"); + Assert.AreEqual (2, cfBundleIcons.Count, "CFBundleIcons.Count"); + + var cfBundlePrimaryIcon = cfBundleIcons.Get ("CFBundlePrimaryIcon"); + Assert.AreEqual (2, cfBundlePrimaryIcon.Count, "CFBundlePrimaryIcon.Length"); + Assert.AreEqual ("AppIcons", cfBundlePrimaryIcon.Get ("CFBundleIconName")?.Value, "CFBundleIconName"); + + var cfBundleIconFiles = cfBundlePrimaryIcon.Get ("CFBundleIconFiles"); + Assert.AreEqual (2, cfBundleIconFiles.Count, "CFBundleIconFiles.Length"); + Assert.AreEqual ("AppIcons60x60", ((PString) cfBundleIconFiles [0]).Value, "CFBundleIconFiles[0].Value"); + Assert.AreEqual ("AppIcons76x76", ((PString) cfBundleIconFiles [1]).Value, "CFBundleIconFiles[1].Value"); + + var cfBundleAlternateIcons = cfBundleIcons.Get ("CFBundleAlternateIcons"); + Assert.AreEqual (1, cfBundleAlternateIcons.Count, "CFBundleAlternateIcons.Count"); + + var alternateAppIcons = cfBundleAlternateIcons.Get ("AlternateAppIcons"); + Assert.AreEqual (2, alternateAppIcons.Count, "CFBundleAlternateIcons.Count"); + Assert.AreEqual ("AlternateAppIcons", alternateAppIcons.Get ("CFBundleIconName")?.Value, "CFBundleIconName"); + + var alternateAppIcons_CFBundleIconFiles = alternateAppIcons.Get ("CFBundleIconFiles"); + Assert.AreEqual (2, alternateAppIcons_CFBundleIconFiles.Count, "AlternateAppIcons.CFBundleIconFiles.Count"); + Assert.AreEqual ("AlternateAppIcons60x60", ((PString) alternateAppIcons_CFBundleIconFiles [0]).Value, "AlternateAppIcons.CFBundleIconFiles[0]"); + Assert.AreEqual ("AlternateAppIcons76x76", ((PString) alternateAppIcons_CFBundleIconFiles [1]).Value, "AlternateAppIcons.CFBundleIconFiles[1]"); + } + } + } + + [Test] + [TestCase (ApplePlatform.iOS)] + [TestCase (ApplePlatform.TVOS)] + [TestCase (ApplePlatform.MacCatalyst)] + [TestCase (ApplePlatform.MacOSX)] + public void AlternateIcons (ApplePlatform platform) + { + var actool = CreateACToolTaskWithResources (platform); + if (platform == ApplePlatform.TVOS) { + actool.AlternateAppIcons = new ITaskItem [] { new TaskItem ("AlternateBrandAssets") }; + } else { + actool.AlternateAppIcons = new ITaskItem [] { new TaskItem ("AlternateAppIcons") }; + } + + ExecuteTask (actool); + + var appIconsManifest = PDictionary.FromFile (actool.PartialAppManifest.ItemSpec!)!; + Assert.AreEqual (0, appIconsManifest.Count, $"Partial plist contents: {actool.PartialAppManifest.ItemSpec}"); + } + + [Test] + [TestCase (ApplePlatform.iOS)] + [TestCase (ApplePlatform.TVOS)] + [TestCase (ApplePlatform.MacCatalyst)] + [TestCase (ApplePlatform.MacOSX)] + public void InexistentAppIcon (ApplePlatform platform) + { + var actool = CreateACToolTaskWithResources (platform); + actool.AppIcon = "InexistentAppIcons"; + + ExecuteTask (actool, 1); + Assert.AreEqual ("Can't find the AppIcon 'InexistentAppIcons' among the image resources.", Engine.Logger.ErrorEvents [0].Message, "Error message"); + } + + [Test] + [TestCase (ApplePlatform.iOS)] + [TestCase (ApplePlatform.TVOS)] + [TestCase (ApplePlatform.MacCatalyst)] + [TestCase (ApplePlatform.MacOSX)] + public void InexistentAlternateIcons (ApplePlatform platform) + { + var actool = CreateACToolTaskWithResources (platform); + actool.AlternateAppIcons = new ITaskItem [] { new TaskItem ("InexistentAlternateAppIcons") }; + + ExecuteTask (actool, 1); + Assert.AreEqual ("Can't find the AlternateAppIcon 'InexistentAlternateAppIcons' among the image resources.", Engine.Logger.ErrorEvents [0].Message, "Error message"); + } + + [Test] + [TestCase (ApplePlatform.iOS)] + [TestCase (ApplePlatform.TVOS)] + [TestCase (ApplePlatform.MacCatalyst)] + [TestCase (ApplePlatform.MacOSX)] + public void BothAlternateAndMainIcon (ApplePlatform platform) + { + var actool = CreateACToolTaskWithResources (platform); + if (platform == ApplePlatform.TVOS) { + actool.AlternateAppIcons = new ITaskItem [] { new TaskItem ("BrandAssets") }; + actool.AppIcon = "BrandAssets"; + } else { + actool.AlternateAppIcons = new ITaskItem [] { new TaskItem ("AppIcons") }; + actool.AppIcon = "AppIcons"; + } + + ExecuteTask (actool, 1); + Assert.AreEqual ($"The image resource '{actool.AppIcon}' is specified as both 'AppIcon' and 'AlternateAppIcon'", Engine.Logger.ErrorEvents [0].Message, "Error message"); + } + + [Test] + [TestCase (ApplePlatform.iOS)] + [TestCase (ApplePlatform.TVOS)] + [TestCase (ApplePlatform.MacCatalyst)] + [TestCase (ApplePlatform.MacOSX)] + public void XSAppIconAssetsAndAppIcon (ApplePlatform platform) + { + var actool = CreateACToolTaskWithResources (platform); + actool.AppIcon = "AppIcons"; + actool.XSAppIconAssets = "Resources/Images.xcassets/AppIcons.appiconset"; + + ExecuteTask (actool, 1); + Assert.AreEqual ("Can't specify both 'XSAppIconAssets' in the Info.plist and 'AppIcon' in the project file. Please select one or the other.", Engine.Logger.ErrorEvents [0].Message, "Error message"); + } + } +} diff --git a/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TestHelpers/Logger.cs b/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TestHelpers/Logger.cs index bb131d1b7ad4..77523db0ce61 100644 --- a/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TestHelpers/Logger.cs +++ b/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TestHelpers/Logger.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using Microsoft.Build.Framework; @@ -48,5 +49,33 @@ public void Clear () MessageEvents.Clear (); WarningsEvents.Clear (); } + + public IEnumerable AllEvents { + get { + var rv = new List (); + rv.AddRange (CustomEvents); + rv.AddRange (ErrorEvents); + rv.AddRange (MessageEvents); + rv.AddRange (WarningsEvents); + return rv; + } + } + } + + public static class BuildEventArgsExtensions { + public static string AsString (this BuildEventArgs ea) + { + if (ea is BuildErrorEventArgs eea) { + return $"{eea.Code}: error: {eea.Message}"; + } else if (ea is BuildMessageEventArgs bmea) { + return $"{bmea.Code}: {bmea.Message}"; + } else if (ea is BuildWarningEventArgs bwea) { + return $"{bwea.Code}: warning: {bwea.Message}"; + } else if (ea is CustomBuildEventArgs cbea) { + return cbea.Message; + } else { + return ea.Message; + } + } } } diff --git a/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TestHelpers/TestBase.cs b/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TestHelpers/TestBase.cs index b836f1fc62d9..c3ecbbe86ac9 100644 --- a/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TestHelpers/TestBase.cs +++ b/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TestHelpers/TestBase.cs @@ -67,8 +67,9 @@ public void ExecuteTask (Task task, int expectedErrorCount = 0) var rv = task.Execute (); if (expectedErrorCount != Engine.Logger.ErrorEvents.Count) { string messages = string.Empty; - if (Engine.Logger.ErrorEvents.Count > 0) { - messages = "\n\t" + string.Join ("\n\t", Engine.Logger.ErrorEvents.Select ((v) => v.Message).ToArray ()); + var allEvents = Engine.Logger.AllEvents.ToArray (); + if (allEvents.Any ()) { + messages = "\n\t" + string.Join ("\n\t", allEvents.Select ((v) => v.AsString ()).ToArray ()); } Assert.AreEqual (expectedErrorCount, Engine.Logger.ErrorEvents.Count, "#RunTask-ErrorCount" + messages); } diff --git a/tests/msbuild/Xamarin.MacDev.Tasks.Tests/Xamarin.MacDev.Tasks.Tests.csproj b/tests/msbuild/Xamarin.MacDev.Tasks.Tests/Xamarin.MacDev.Tasks.Tests.csproj index 9c01e50e5e25..45e86e521c05 100644 --- a/tests/msbuild/Xamarin.MacDev.Tasks.Tests/Xamarin.MacDev.Tasks.Tests.csproj +++ b/tests/msbuild/Xamarin.MacDev.Tasks.Tests/Xamarin.MacDev.Tasks.Tests.csproj @@ -67,6 +67,9 @@ external\ErrorHelper.tests.cs + + external\SdkVersions.cs + external\StringUtils.cs From e07ab1fda7913aa6a4f48f74279fdb0690248c33 Mon Sep 17 00:00:00 2001 From: GitHub Actions Autoformatter Date: Tue, 29 Oct 2024 16:45:52 +0000 Subject: [PATCH 2/4] Auto-format source code --- tests/dotnet/AppWithXCAssets/AppDelegate.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/dotnet/AppWithXCAssets/AppDelegate.cs b/tests/dotnet/AppWithXCAssets/AppDelegate.cs index 1bdcd57a3274..a6edee7af51c 100644 --- a/tests/dotnet/AppWithXCAssets/AppDelegate.cs +++ b/tests/dotnet/AppWithXCAssets/AppDelegate.cs @@ -50,7 +50,7 @@ async Task SwitchIcon () { await Task.Delay (1000); // wait a bit, otherwise it doesn't work - var supportsAlternateIcons = UIApplication.SharedApplication.SupportsAlternateIcons; + var supportsAlternateIcons = UIApplication.SharedApplication.SupportsAlternateIcons; if (!supportsAlternateIcons) Console.WriteLine ("Alternate icons aren't currently supported, but trying anyway!"); @@ -68,7 +68,7 @@ async Task SwitchIcon () UIApplication.SharedApplication.SetAlternateIconName (name, (err) => { if (err is null) { - Console.WriteLine($"Switched to {(name is null ? "original icon" : $"alternate icon {name}")}"); + Console.WriteLine ($"Switched to {(name is null ? "original icon" : $"alternate icon {name}")}"); button!.SetTitleColor (color, UIControlState.Normal); ScheduleIconSwitching (); } else { From 18b51ac311409f10a7546bdc2a6aa0bb757afc68 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Wed, 30 Oct 2024 18:51:46 +0100 Subject: [PATCH 3/4] Fix msbuild tests. --- .../Tasks/XcodeCompilerToolTask.cs | 5 + tests/common/PListAsserts.cs | 124 ++++ .../TaskTests/ACToolTaskTest.cs | 583 ++++++++++++------ .../Xamarin.MacDev.Tasks.Tests.csproj | 3 + 4 files changed, 521 insertions(+), 194 deletions(-) create mode 100644 tests/common/PListAsserts.cs diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/XcodeCompilerToolTask.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/XcodeCompilerToolTask.cs index bf7ad3bbfff3..4d7e3f67c256 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/XcodeCompilerToolTask.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/XcodeCompilerToolTask.cs @@ -232,6 +232,11 @@ protected int Compile (ITaskItem [] items, string output, ITaskItem manifest) args.AddQuoted (item.GetMetadata ("FullPath")); var arguments = args.ToList (); + + // don't bother executing the tool if we've already looged errors. + if (Log.HasLoggedErrors) + return 1; + var rv = ExecuteAsync (tool, arguments, sdkDevPath, environment: environment, mergeOutput: false).Result; var exitCode = rv.ExitCode; var messages = rv.StandardOutput!.ToString (); diff --git a/tests/common/PListAsserts.cs b/tests/common/PListAsserts.cs new file mode 100644 index 000000000000..da2f33beddfe --- /dev/null +++ b/tests/common/PListAsserts.cs @@ -0,0 +1,124 @@ +using System; +using System.IO; +using System.Linq; + +using Xamarin.MacDev; +using Xamarin.Utils; + +using NUnit.Framework; + +#nullable enable + +namespace Xamarin.Tests { + public static class PListAsserts { + // Compare two plists, and assert if there are any differences. + public static void AreStringsEqual (string expectedXml, string actualXml, string? message = null) + { + if (string.Equals (expectedXml, actualXml, StringComparison.Ordinal)) + return; + + var expected = string.IsNullOrEmpty (expectedXml) ? new PDictionary () : PDictionary.FromString (expectedXml)!; + var actual = string.IsNullOrEmpty (actualXml) ? new PDictionary () : PDictionary.FromString (actualXml)!; + if (expected is not PDictionary expectedDictionary) + throw new InvalidOperationException ($"Root element for the expected plist isn't a dictionary"); + if (actual is not PDictionary actualDictionary) + throw new InvalidOperationException ($"Root element for the actual plist isn't a dictionary"); + AssertPDictionaryEqual (expectedXml, actualXml, expectedDictionary, actualDictionary, "", message); + } + + // Compare two plists, and assert if there are any differences. + public static void AreFilesEqual (string expectedXmlPath, string actualXmlPath, string? message = null) + { + Assert.That (expectedXmlPath, Does.Exist, message); + Assert.That (actualXmlPath, Does.Exist, message); + AreStringsEqual (File.ReadAllText (expectedXmlPath), File.ReadAllText (actualXmlPath), message); + } + + static void AssertPDictionaryEqual (string expectedXml, string actualXml, PDictionary expected, PDictionary actual, string key, string? message = null) + { + var expectedKeys = expected.Select (v => v.Key ?? string.Empty).OrderBy (v => v).ToArray (); + var actualKeys = actual.Select (v => v.Key ?? string.Empty).OrderBy (v => v).ToArray (); + if (expectedKeys.Length != actualKeys.Length) { + Assert.Fail ( + $"Expected {expectedKeys.Length} entries in 'dict' for key '{key}', got {actualKeys.Length} entries: {message}\n" + + $"\tExpected keys: {string.Join (", ", expectedKeys)}\n" + + $"\tActual keys: {string.Join (", ", actualKeys)}\n" + + $"\tExpected xml:\n" + + $"\t\t{expectedXml.Replace ("\n", "\n\t\t")}\n" + + $"\tActual xml:\n" + + $"\t\t{actualXml.Replace ("\n", "\n\t\t")}" + ); + return; + } + for (var i = 0; i < expectedKeys.Length; i++) { + if (expectedKeys [i] != actualKeys [i]) { + Assert.Fail ( + $"Expected key '{expectedKeys [i]}' in 'dict' for key '{key}', got key '{actualKeys [i]}': {message}\n" + + $"\tExpected xml:\n" + + $"\t\t{expectedXml.Replace ("\n", "\n\t\t")}\n" + + $"\tActual xml:\n" + + $"\t\t{actualXml.Replace ("\n", "\n\t\t")}" + ); + return; + } + var expectedValue = expected [expectedKeys [i]]!; + var actualValue = actual [actualKeys [i]]!; + AssertPObjectEqual (expectedXml, actualXml, expectedValue, actualValue, expectedKeys [i], message); + } + } + + static void AssertPArrayEqual (string expectedXml, string actualXml, PArray expected, PArray actual, string key, string? message = null) + { + if (expected.Count != actual.Count) { + Assert.Fail ( + $"Expected {expected.Count} items in 'array' for key '{key}', got {actual.Count} items: {message}\n" + + $"\tExpected xml:\n" + + $"\t\t{expectedXml.Replace ("\n", "\n\t\t")}\n" + + $"\tActual xml:\n" + + $"\t\t{actualXml.Replace ("\n", "\n\t\t")}" + ); + return; + } + for (var i = 0; i < expected.Count; i++) { + AssertPObjectEqual (expectedXml, actualXml, expected [i], actual [i], key, message); + } + } + + static void AssertPStringEqual (string expectedXml, string actualXml, PString expected, PString actual, string key, string? message = null) + { + if (expected.Value != actual.Value) { + Assert.Fail ( + $"Expected string of value '{expected.Value}' for key '{key}', got string of value '{actual.Value}': {message}\n" + + $"\tExpected xml:\n" + + $"\t\t{expectedXml.Replace ("\n", "\n\t\t")}\n" + + $"\tActual xml:\n" + + $"\t\t{actualXml.Replace ("\n", "\n\t\t")}" + ); + } + } + + static void AssertPObjectEqual (string expectedXml, string actualXml, PObject expected, PObject actual, string key, string? message = null) + { + if (expected.GetType () != actual.GetType ()) { + Assert.Fail ( + $"Expected item of type '{expected.GetType ().Name}' for key '{key}', got item of type '{actual.GetType ()}': {message}\n"+ + $"\tExpected xml:\n" + + $"\t\t{expectedXml.Replace ("\n", "\n\t\t")}\n" + + $"\tActual xml:\n" + + $"\t\t{actualXml.Replace ("\n", "\n\t\t")}" + ); + return; + } + + if (expected is PDictionary expectedDictionary) { + AssertPDictionaryEqual (expectedXml, actualXml, expectedDictionary, (PDictionary) actual, key, message); + } else if (expected is PString expectedString) { + AssertPStringEqual (expectedXml, actualXml, expectedString, (PString) actual, key, message); + } else if (expected is PArray expectedArray) { + AssertPArrayEqual (expectedXml, actualXml, expectedArray, (PArray) actual, key, message); + } else { + throw new NotImplementedException ($"Comparing PList objects of type {expected.GetType ().Name}"); + } + } + } +} diff --git a/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/ACToolTaskTest.cs b/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/ACToolTaskTest.cs index 9cffde4e5d9c..6c3204fe530c 100644 --- a/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/ACToolTaskTest.cs +++ b/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/ACToolTaskTest.cs @@ -97,8 +97,19 @@ public void DefaultAppIcons (ApplePlatform platform) ExecuteTask (actool); Assert.IsNotNull (actool.PartialAppManifest, "PartialAppManifest"); - var appIconsManifest = PDictionary.FromFile (actool.PartialAppManifest.ItemSpec!)!; + var appIconsManifestPath = actool.PartialAppManifest.ItemSpec!; + var appIconsManifest = PDictionary.FromFile (appIconsManifestPath)!; Assert.AreEqual (0, appIconsManifest.Count, $"Partial plist contents: {actool.PartialAppManifest.ItemSpec}"); + var expectedXml = + """ + + + + + + + """; + PListAsserts.AreStringsEqual (expectedXml, File.ReadAllText (appIconsManifestPath), "Partial plist contents"); } [Test] @@ -115,8 +126,33 @@ public void AllAppIcons (ApplePlatform platform) Assert.IsNotNull (actool.PartialAppManifest, "PartialAppManifest"); - var appIconsManifest = PDictionary.FromFile (actool.PartialAppManifest.ItemSpec!)!; - Assert.AreEqual (0, appIconsManifest.Count, $"Partial plist contents: {actool.PartialAppManifest.ItemSpec}"); + var appIconsManifestPath = actool.PartialAppManifest.ItemSpec!; + string expectedXml; + if (platform == ApplePlatform.TVOS) { + expectedXml = + """ + + + + + CFBundleIcons + + CFBundleAlternateIcons + + AlternateAppIcons + + CFBundleIconName + AlternateAppIcons + + + + + + """; + } else { + expectedXml = ""; + } + PListAsserts.AreStringsEqual (expectedXml, File.ReadAllText (appIconsManifestPath), "Partial plist contents"); } [Test] @@ -138,73 +174,115 @@ public void AllAppIconsWithAppIcon (ApplePlatform platform) Assert.IsNotNull (actool.PartialAppManifest, "PartialAppManifest"); - var appIconsManifest = PDictionary.FromFile (actool.PartialAppManifest?.ItemSpec)!; - Assert.AreEqual (2, appIconsManifest.Count, $"Partial plist contents: {actool.PartialAppManifest.ItemSpec}"); + var appIconsManifestPath = actool.PartialAppManifest?.ItemSpec!; + string expectedXml; if (platform == ApplePlatform.MacOSX || platform == ApplePlatform.MacCatalyst) { - Assert.AreEqual ("AlternateAppIcons", appIconsManifest.Get ("CFBundleIconFile")?.Value, "CFBundleIconFile"); - Assert.AreEqual ("AlternateAppIcons", appIconsManifest.Get ("CFBundleIconName")?.Value, "CFBundleIconName"); + expectedXml = + """ + + + + + CFBundleIconFile + AlternateAppIcons + CFBundleIconName + AlternateAppIcons + + + """; } else if (platform == ApplePlatform.TVOS) { - var cfBundleIcons = appIconsManifest.Get ("CFBundleIcons"); - Assert.AreEqual (1, cfBundleIcons.Count, "CFBundleIcons.Count"); - Assert.AreEqual ("AlternateAppIcons", cfBundleIcons.Get ("CFBundlePrimaryIcon")?.Value, "CFBundlePrimaryIcon"); - - var tvTopShelfImage = appIconsManifest.Get ("TVTopShelfImage"); - Assert.AreEqual (2, tvTopShelfImage.Count, "TVTopShelfImage.Count"); - Assert.AreEqual ("TopShelfImage", tvTopShelfImage.Get ("TVTopShelfPrimaryImage")?.Value, "TVTopShelfPrimaryImage"); - Assert.AreEqual ("TopShelfImageWide", tvTopShelfImage.Get ("TVTopShelfPrimaryImageWide")?.Value, "TVTopShelfPrimaryImageWide"); + expectedXml = + """ + + + + + CFBundleIcons + + CFBundleAlternateIcons + + AlternateAppIcons + + CFBundleIconName + AlternateAppIcons + + + CFBundlePrimaryIcon + AppIcon + + TVTopShelfImage + + TVTopShelfPrimaryImage + TopShelfImage + TVTopShelfPrimaryImageWide + TopShelfImageWide + + + + """; } else { - { - // iPhone - var cfBundleIcons = appIconsManifest.Get ("CFBundleIcons"); - Assert.AreEqual (2, cfBundleIcons.Count, "CFBundleIcons.Count"); - - var cfBundlePrimaryIcon = cfBundleIcons.Get ("CFBundlePrimaryIcon"); - Assert.AreEqual (2, cfBundlePrimaryIcon.Count, "CFBundlePrimaryIcon.Length"); - - var cfBundleIconFiles = cfBundlePrimaryIcon.Get ("CFBundleIconFiles"); - Assert.AreEqual (1, cfBundleIconFiles.Count, "CFBundleIconFiles.Length"); - Assert.AreEqual ("AlternateAppIcons60x60", ((PString) cfBundleIconFiles [0]).Value, "CFBundleIconFiles[0].Value"); - Assert.AreEqual ("AlternateAppIcons", cfBundlePrimaryIcon.Get ("CFBundleIconName")?.Value, "CFBundleIconName"); - - var cfBundleAlternateIcons = cfBundleIcons.Get ("CFBundleAlternateIcons"); - Assert.AreEqual (1, cfBundleAlternateIcons.Count, "CFBundleAlternateIcons.Count"); - - var alternateAppIcons = cfBundleAlternateIcons.Get ("AppIcons"); - Assert.AreEqual (2, alternateAppIcons.Count, "AppIcons.Count"); - Assert.AreEqual ("AppIcons", alternateAppIcons.Get ("CFBundleIconName")?.Value, "CFBundleIconName"); - - var appIcons_cfBundleIconFiles = alternateAppIcons.Get ("CFBundleIconFiles"); - Assert.AreEqual (2, appIcons_cfBundleIconFiles.Count, "AppIcons.CFBundleIconFiles.Length"); - Assert.AreEqual ("AppIcons60x60", ((PString) appIcons_cfBundleIconFiles [0]).Value, "AppIcons.CFBundleIconFiles[0].Value"); - Assert.AreEqual ("AppIcons76x76", ((PString) appIcons_cfBundleIconFiles [1]).Value, "AppIcons.CFBundleIconFiles[1].Value"); - } - { - // iPad - var cfBundleIcons = appIconsManifest.Get ("CFBundleIcons~ipad"); - Assert.AreEqual (2, cfBundleIcons.Count, "CFBundleIcons.Count"); - - var cfBundlePrimaryIcon = cfBundleIcons.Get ("CFBundlePrimaryIcon"); - Assert.AreEqual (2, cfBundlePrimaryIcon.Count, "CFBundlePrimaryIcon.Length"); - - var cfBundleIconFiles = cfBundlePrimaryIcon.Get ("CFBundleIconFiles"); - Assert.AreEqual (2, cfBundleIconFiles.Count, "CFBundleIconFiles.Length"); - Assert.AreEqual ("AlternateAppIcons60x60", ((PString) cfBundleIconFiles [0]).Value, "CFBundleIconFiles[0].Value"); - Assert.AreEqual ("AlternateAppIcons76x76", ((PString) cfBundleIconFiles [1]).Value, "CFBundleIconFiles[1].Value"); - Assert.AreEqual ("AlternateAppIcons", cfBundlePrimaryIcon.Get ("CFBundleIconName")?.Value, "CFBundleIconName"); - - var cfBundleAlternateIcons = cfBundleIcons.Get ("CFBundleAlternateIcons"); - Assert.AreEqual (1, cfBundleAlternateIcons.Count, "CFBundleAlternateIcons.Count"); - - var appIcons = cfBundleAlternateIcons.Get ("AppIcons"); - Assert.AreEqual (2, appIcons.Count, "AppIcons.Count"); - Assert.AreEqual ("AppIcons", appIcons.Get ("CFBundleIconName")?.Value, "CFBundleIconName"); - - var appIcons_cfBundleIconFiles = appIcons.Get ("CFBundleIconFiles"); - Assert.AreEqual (2, appIcons_cfBundleIconFiles.Count, "AppIcons.CFBundleIconFiles.Length"); - Assert.AreEqual ("AppIcons60x60", ((PString) appIcons_cfBundleIconFiles [0]).Value, "AppIcons.CFBundleIconFiles[0].Value"); - Assert.AreEqual ("AppIcons76x76", ((PString) appIcons_cfBundleIconFiles [1]).Value, "AppIcons.CFBundleIconFiles[1].Value"); - } + expectedXml = + """ + + + + + CFBundleIcons + + CFBundleAlternateIcons + + AppIcons + + CFBundleIconFiles + + AppIcons60x60 + AppIcons76x76 + + CFBundleIconName + AppIcons + + + CFBundlePrimaryIcon + + CFBundleIconFiles + + AlternateAppIcons60x60 + + CFBundleIconName + AlternateAppIcons + + + CFBundleIcons~ipad + + CFBundleAlternateIcons + + AppIcons + + CFBundleIconFiles + + AppIcons60x60 + AppIcons76x76 + + CFBundleIconName + AppIcons + + + CFBundlePrimaryIcon + + CFBundleIconFiles + + AlternateAppIcons60x60 + AlternateAppIcons76x76 + + CFBundleIconName + AlternateAppIcons + + + + + """; } + PListAsserts.AreStringsEqual (expectedXml, File.ReadAllText (appIconsManifestPath), "Partial plist contents"); } [Test] @@ -215,61 +293,87 @@ public void AllAppIconsWithAppIcon (ApplePlatform platform) public void AppIcon (ApplePlatform platform) { var actool = CreateACToolTaskWithResources (platform); - if (platform == ApplePlatform.TVOS) { - actool.AppIcon = "BrandAssets"; - } else { - actool.AppIcon = "AppIcons"; - } + actool.AppIcon = "AppIcons"; ExecuteTask (actool); Assert.IsNotNull (actool.PartialAppManifest, "PartialAppManifest"); - var appIconsManifest = PDictionary.FromFile (actool.PartialAppManifest.ItemSpec!)!; + var appIconsManifestPath = actool.PartialAppManifest.ItemSpec!; + string expectedXml; if (platform == ApplePlatform.MacOSX || platform == ApplePlatform.MacCatalyst) { - Assert.AreEqual (2, appIconsManifest.Count, $"Partial plist contents: {actool.PartialAppManifest.ItemSpec}"); - Assert.AreEqual ("AppIcons", appIconsManifest.Get ("CFBundleIconFile")?.Value, "CFBundleIconFile"); - Assert.AreEqual ("AppIcons", appIconsManifest.Get ("CFBundleIconName")?.Value, "CFBundleIconName"); + expectedXml = + """ + + + + + CFBundleIconFile + AppIcons + CFBundleIconName + AppIcons + + + """; } else if (platform == ApplePlatform.TVOS) { - Assert.AreEqual (2, appIconsManifest.Count, $"Partial plist contents: {actool.PartialAppManifest.ItemSpec}"); - - var cfBundleIcons = appIconsManifest.Get ("CFBundleIcons"); - Assert.AreEqual (1, cfBundleIcons.Count, "CFBundleIcons.Count"); - Assert.AreEqual ("AppIcons", cfBundleIcons.Get ("CFBundlePrimaryIcon")?.Value, "CFBundlePrimaryIcon"); - - var tvTopShelfImage = appIconsManifest.Get ("TVTopShelfImage"); - Assert.AreEqual (2, tvTopShelfImage.Count, "TVTopShelfImage.Count"); - Assert.AreEqual ("TopShelfImage", tvTopShelfImage.Get ("TVTopShelfPrimaryImage")?.Value, "TVTopShelfPrimaryImage"); - Assert.AreEqual ("TopShelfImageWide", tvTopShelfImage.Get ("TVTopShelfPrimaryImageWide")?.Value, "TVTopShelfPrimaryImageWide"); + expectedXml = + """ + + + + + CFBundleIcons + + CFBundlePrimaryIcon + AppIcons + + TVTopShelfImage + + TVTopShelfPrimaryImage + TopShelfImage + TVTopShelfPrimaryImageWide + TopShelfImageWide + + + + """; } else { - { - // iPhone - var cfBundleIcons = appIconsManifest.Get ("CFBundleIcons"); - Assert.AreEqual (1, cfBundleIcons.Count, "CFBundleIcons.Count"); - - var cfBundlePrimaryIcon = cfBundleIcons.Get ("CFBundlePrimaryIcon"); - Assert.AreEqual (2, cfBundlePrimaryIcon.Count, "CFBundlePrimaryIcon.Length"); - - var cfBundleIconFiles = cfBundlePrimaryIcon.Get ("CFBundleIconFiles"); - Assert.AreEqual (1, cfBundleIconFiles.Count, "CFBundleIconFiles.Length"); - Assert.AreEqual ("AppIcons60x60", ((PString) cfBundleIconFiles [0]).Value, "CFBundleIconFiles[0].Value"); - Assert.AreEqual ("AppIcons", cfBundlePrimaryIcon.Get ("CFBundleIconName")?.Value, "CFBundleIconName"); - } - { - // iPad - var cfBundleIcons = appIconsManifest.Get ("CFBundleIcons~ipad"); - Assert.AreEqual (1, cfBundleIcons.Count, "CFBundleIcons.Count"); - - var cfBundlePrimaryIcon = cfBundleIcons.Get ("CFBundlePrimaryIcon"); - Assert.AreEqual (2, cfBundlePrimaryIcon.Count, "CFBundlePrimaryIcon.Length"); - - var cfBundleIconFiles = cfBundlePrimaryIcon.Get ("CFBundleIconFiles"); - Assert.AreEqual (2, cfBundleIconFiles.Count, "CFBundleIconFiles.Length"); - Assert.AreEqual ("AppIcons60x60", ((PString) cfBundleIconFiles [0]).Value, "CFBundleIconFiles[0].Value"); - Assert.AreEqual ("AppIcons76x76", ((PString) cfBundleIconFiles [1]).Value, "CFBundleIconFiles[1].Value"); - Assert.AreEqual ("AppIcons", cfBundlePrimaryIcon.Get ("CFBundleIconName")?.Value, "CFBundleIconName"); - } + expectedXml = + """ + + + + + CFBundleIcons + + CFBundlePrimaryIcon + + CFBundleIconFiles + + AppIcons60x60 + + CFBundleIconName + AppIcons + + + CFBundleIcons~ipad + + CFBundlePrimaryIcon + + CFBundleIconFiles + + AppIcons60x60 + AppIcons76x76 + + CFBundleIconName + AppIcons + + + + + """; } + PListAsserts.AreStringsEqual (expectedXml, File.ReadAllText (appIconsManifestPath), "Partial plist contents"); } [Test] @@ -281,8 +385,8 @@ public void AppIconAndAlternateIcons (ApplePlatform platform) { var actool = CreateACToolTaskWithResources (platform); if (platform == ApplePlatform.TVOS) { - actool.AppIcon = "BrandAssets"; - actool.AlternateAppIcons = new ITaskItem [] { new TaskItem ("AlternateBrandAssets") }; + actool.AppIcon = "AppIcons"; + actool.AlternateAppIcons = new ITaskItem [] { new TaskItem ("AlternateAppIcons") }; } else { actool.AppIcon = "AppIcons"; actool.AlternateAppIcons = new ITaskItem [] { new TaskItem ("AlternateAppIcons") }; @@ -292,73 +396,115 @@ public void AppIconAndAlternateIcons (ApplePlatform platform) Assert.IsNotNull (actool.PartialAppManifest, "PartialAppManifest"); - var appIconsManifest = PDictionary.FromFile (actool.PartialAppManifest.ItemSpec!)!; - Assert.AreEqual (2, appIconsManifest.Count, $"Partial plist contents: {actool.PartialAppManifest.ItemSpec}"); + var appIconsManifestPath = actool.PartialAppManifest.ItemSpec!; + string expectedXml; if (platform == ApplePlatform.MacOSX || platform == ApplePlatform.MacCatalyst) { - Assert.AreEqual ("AppIcons", appIconsManifest.Get ("CFBundleIconFile")?.Value, "CFBundleIconFile"); - Assert.AreEqual ("AppIcons", appIconsManifest.Get ("CFBundleIconName")?.Value, "CFBundleIconName"); + expectedXml = + """ + + + + + CFBundleIconFile + AppIcons + CFBundleIconName + AppIcons + + + """; } else if (platform == ApplePlatform.TVOS) { - var cfBundleIcons = appIconsManifest.Get ("CFBundleIcons"); - Assert.AreEqual (1, cfBundleIcons.Count, "CFBundleIcons.Count"); - Assert.AreEqual ("AppIcons", cfBundleIcons.Get ("CFBundlePrimaryIcon")?.Value, "CFBundlePrimaryIcon"); - - var tvTopShelfImage = appIconsManifest.Get ("TVTopShelfImage"); - Assert.AreEqual (2, tvTopShelfImage.Count, "TVTopShelfImage.Count"); - Assert.AreEqual ("TopShelfImage", tvTopShelfImage.Get ("TVTopShelfPrimaryImage")?.Value, "TVTopShelfPrimaryImage"); - Assert.AreEqual ("TopShelfImageWide", tvTopShelfImage.Get ("TVTopShelfPrimaryImageWide")?.Value, "TVTopShelfPrimaryImageWide"); + expectedXml = + """ + + + + + CFBundleIcons + + CFBundleAlternateIcons + + AlternateAppIcons + + CFBundleIconName + AlternateAppIcons + + + CFBundlePrimaryIcon + AppIcons + + TVTopShelfImage + + TVTopShelfPrimaryImage + TopShelfImage + TVTopShelfPrimaryImageWide + TopShelfImageWide + + + + """; } else { - { - // iPhone - var cfBundleIcons = appIconsManifest.Get ("CFBundleIcons"); - Assert.AreEqual (2, cfBundleIcons.Count, "CFBundleIcons.Count"); - - var cfBundlePrimaryIcon = cfBundleIcons.Get ("CFBundlePrimaryIcon"); - Assert.AreEqual (2, cfBundlePrimaryIcon.Count, "CFBundlePrimaryIcon.Length"); - Assert.AreEqual ("AppIcons", cfBundlePrimaryIcon.Get ("CFBundleIconName")?.Value, "CFBundleIconName"); - - var cfBundleIconFiles = cfBundlePrimaryIcon.Get ("CFBundleIconFiles"); - Assert.AreEqual (1, cfBundleIconFiles.Count, "CFBundleIconFiles.Length"); - Assert.AreEqual ("AppIcons60x60", ((PString) cfBundleIconFiles [0]).Value, "CFBundleIconFiles[0].Value"); - - var cfBundleAlternateIcons = cfBundleIcons.Get ("CFBundleAlternateIcons"); - Assert.AreEqual (1, cfBundleAlternateIcons.Count, "CFBundleAlternateIcons.Count"); - - var alternateAppIcons = cfBundleAlternateIcons.Get ("AlternateAppIcons"); - Assert.AreEqual (2, alternateAppIcons.Count, "CFBundleAlternateIcons.Count"); - Assert.AreEqual ("AlternateAppIcons", alternateAppIcons.Get ("CFBundleIconName")?.Value, "CFBundleIconName"); - - var alternateAppIcons_CFBundleIconFiles = alternateAppIcons.Get ("CFBundleIconFiles"); - Assert.AreEqual (2, alternateAppIcons_CFBundleIconFiles.Count, "AlternateAppIcons.CFBundleIconFiles.Count"); - Assert.AreEqual ("AlternateAppIcons60x60", ((PString) alternateAppIcons_CFBundleIconFiles [0]).Value, "AlternateAppIcons.CFBundleIconFiles[0]"); - Assert.AreEqual ("AlternateAppIcons76x76", ((PString) alternateAppIcons_CFBundleIconFiles [1]).Value, "AlternateAppIcons.CFBundleIconFiles[1]"); - } - { - // iPad - var cfBundleIcons = appIconsManifest.Get ("CFBundleIcons~ipad"); - Assert.AreEqual (2, cfBundleIcons.Count, "CFBundleIcons.Count"); - - var cfBundlePrimaryIcon = cfBundleIcons.Get ("CFBundlePrimaryIcon"); - Assert.AreEqual (2, cfBundlePrimaryIcon.Count, "CFBundlePrimaryIcon.Length"); - Assert.AreEqual ("AppIcons", cfBundlePrimaryIcon.Get ("CFBundleIconName")?.Value, "CFBundleIconName"); - - var cfBundleIconFiles = cfBundlePrimaryIcon.Get ("CFBundleIconFiles"); - Assert.AreEqual (2, cfBundleIconFiles.Count, "CFBundleIconFiles.Length"); - Assert.AreEqual ("AppIcons60x60", ((PString) cfBundleIconFiles [0]).Value, "CFBundleIconFiles[0].Value"); - Assert.AreEqual ("AppIcons76x76", ((PString) cfBundleIconFiles [1]).Value, "CFBundleIconFiles[1].Value"); - - var cfBundleAlternateIcons = cfBundleIcons.Get ("CFBundleAlternateIcons"); - Assert.AreEqual (1, cfBundleAlternateIcons.Count, "CFBundleAlternateIcons.Count"); - - var alternateAppIcons = cfBundleAlternateIcons.Get ("AlternateAppIcons"); - Assert.AreEqual (2, alternateAppIcons.Count, "CFBundleAlternateIcons.Count"); - Assert.AreEqual ("AlternateAppIcons", alternateAppIcons.Get ("CFBundleIconName")?.Value, "CFBundleIconName"); - - var alternateAppIcons_CFBundleIconFiles = alternateAppIcons.Get ("CFBundleIconFiles"); - Assert.AreEqual (2, alternateAppIcons_CFBundleIconFiles.Count, "AlternateAppIcons.CFBundleIconFiles.Count"); - Assert.AreEqual ("AlternateAppIcons60x60", ((PString) alternateAppIcons_CFBundleIconFiles [0]).Value, "AlternateAppIcons.CFBundleIconFiles[0]"); - Assert.AreEqual ("AlternateAppIcons76x76", ((PString) alternateAppIcons_CFBundleIconFiles [1]).Value, "AlternateAppIcons.CFBundleIconFiles[1]"); - } + expectedXml = + """ + + + + + CFBundleIcons + + CFBundleAlternateIcons + + AlternateAppIcons + + CFBundleIconFiles + + AlternateAppIcons60x60 + AlternateAppIcons76x76 + + CFBundleIconName + AlternateAppIcons + + + CFBundlePrimaryIcon + + CFBundleIconFiles + + AppIcons60x60 + + CFBundleIconName + AppIcons + + + CFBundleIcons~ipad + + CFBundleAlternateIcons + + AlternateAppIcons + + CFBundleIconFiles + + AlternateAppIcons60x60 + AlternateAppIcons76x76 + + CFBundleIconName + AlternateAppIcons + + + CFBundlePrimaryIcon + + CFBundleIconFiles + + AppIcons60x60 + AppIcons76x76 + + CFBundleIconName + AppIcons + + + + + """; } + PListAsserts.AreStringsEqual (expectedXml, File.ReadAllText (appIconsManifestPath), "Partial plist contents"); } [Test] @@ -369,16 +515,44 @@ public void AppIconAndAlternateIcons (ApplePlatform platform) public void AlternateIcons (ApplePlatform platform) { var actool = CreateACToolTaskWithResources (platform); - if (platform == ApplePlatform.TVOS) { - actool.AlternateAppIcons = new ITaskItem [] { new TaskItem ("AlternateBrandAssets") }; - } else { - actool.AlternateAppIcons = new ITaskItem [] { new TaskItem ("AlternateAppIcons") }; - } + actool.AlternateAppIcons = new ITaskItem [] { new TaskItem ("AlternateAppIcons") }; ExecuteTask (actool); - var appIconsManifest = PDictionary.FromFile (actool.PartialAppManifest.ItemSpec!)!; - Assert.AreEqual (0, appIconsManifest.Count, $"Partial plist contents: {actool.PartialAppManifest.ItemSpec}"); + string expectedXml; + switch (platform) { + case ApplePlatform.TVOS: + expectedXml = """ + + + + + CFBundleIcons + + CFBundleAlternateIcons + + AlternateAppIcons + + CFBundleIconName + AlternateAppIcons + + + + + +"""; + break; + case ApplePlatform.iOS: + case ApplePlatform.MacOSX: + case ApplePlatform.MacCatalyst: + expectedXml = ""; + break; + default: + throw new NotImplementedException (platform.ToString ()); + } + + var appIconsManifestPath = actool.PartialAppManifest.ItemSpec!; + PListAsserts.AreStringsEqual (expectedXml, File.ReadAllText (appIconsManifestPath), "Partial plist contents"); } [Test] @@ -392,7 +566,20 @@ public void InexistentAppIcon (ApplePlatform platform) actool.AppIcon = "InexistentAppIcons"; ExecuteTask (actool, 1); - Assert.AreEqual ("Can't find the AppIcon 'InexistentAppIcons' among the image resources.", Engine.Logger.ErrorEvents [0].Message, "Error message"); + string expectedErrorMessage; + switch (platform) { + case ApplePlatform.TVOS: + expectedErrorMessage = "Can't find the AppIcon 'InexistentAppIcons' among the image resources. There are 2 app icons in the image resources: AlternateBrandAssets, AppIcons."; + break; + case ApplePlatform.iOS: + case ApplePlatform.MacOSX: + case ApplePlatform.MacCatalyst: + expectedErrorMessage = "Can't find the AppIcon 'InexistentAppIcons' among the image resources. There are 2 app icons in the image resources: AlternateAppIcons, AppIcons."; + break; + default: + throw new NotImplementedException (platform.ToString ()); + } + Assert.AreEqual (expectedErrorMessage, Engine.Logger.ErrorEvents [0].Message, "Error message"); } [Test] @@ -406,7 +593,20 @@ public void InexistentAlternateIcons (ApplePlatform platform) actool.AlternateAppIcons = new ITaskItem [] { new TaskItem ("InexistentAlternateAppIcons") }; ExecuteTask (actool, 1); - Assert.AreEqual ("Can't find the AlternateAppIcon 'InexistentAlternateAppIcons' among the image resources.", Engine.Logger.ErrorEvents [0].Message, "Error message"); + string expectedErrorMessage; + switch (platform) { + case ApplePlatform.TVOS: + expectedErrorMessage = "Can't find the AlternateAppIcon 'InexistentAlternateAppIcons' among the image resources. There are 5 app icons in the image resources: AlternateAppIcons, AppIcon, AppIcon-AppStore, AppIcons, AppIcons-AppStore."; + break; + case ApplePlatform.iOS: + case ApplePlatform.MacOSX: + case ApplePlatform.MacCatalyst: + expectedErrorMessage = "Can't find the AlternateAppIcon 'InexistentAlternateAppIcons' among the image resources. There are 2 app icons in the image resources: AlternateAppIcons, AppIcons."; + break; + default: + throw new NotImplementedException (platform.ToString ()); + } + Assert.AreEqual (expectedErrorMessage, Engine.Logger.ErrorEvents [0].Message, "Error message"); } [Test] @@ -417,16 +617,11 @@ public void InexistentAlternateIcons (ApplePlatform platform) public void BothAlternateAndMainIcon (ApplePlatform platform) { var actool = CreateACToolTaskWithResources (platform); - if (platform == ApplePlatform.TVOS) { - actool.AlternateAppIcons = new ITaskItem [] { new TaskItem ("BrandAssets") }; - actool.AppIcon = "BrandAssets"; - } else { - actool.AlternateAppIcons = new ITaskItem [] { new TaskItem ("AppIcons") }; - actool.AppIcon = "AppIcons"; - } + actool.AlternateAppIcons = new ITaskItem [] { new TaskItem ("AppIcons") }; + actool.AppIcon = "AppIcons"; ExecuteTask (actool, 1); - Assert.AreEqual ($"The image resource '{actool.AppIcon}' is specified as both 'AppIcon' and 'AlternateAppIcon'", Engine.Logger.ErrorEvents [0].Message, "Error message"); + Assert.AreEqual ($"The image resource '{actool.AppIcon}' is specified as both 'AppIcon' and 'AlternateAppIcon'.", Engine.Logger.ErrorEvents [0].Message, "Error message"); } [Test] diff --git a/tests/msbuild/Xamarin.MacDev.Tasks.Tests/Xamarin.MacDev.Tasks.Tests.csproj b/tests/msbuild/Xamarin.MacDev.Tasks.Tests/Xamarin.MacDev.Tasks.Tests.csproj index 45e86e521c05..33be922235b1 100644 --- a/tests/msbuild/Xamarin.MacDev.Tasks.Tests/Xamarin.MacDev.Tasks.Tests.csproj +++ b/tests/msbuild/Xamarin.MacDev.Tasks.Tests/Xamarin.MacDev.Tasks.Tests.csproj @@ -67,6 +67,9 @@ external\ErrorHelper.tests.cs + + external\PListAsserts.cs + external\SdkVersions.cs From 326d8bf10ffc44ce3ba1dacea59ac5c01e23f390 Mon Sep 17 00:00:00 2001 From: GitHub Actions Autoformatter Date: Wed, 30 Oct 2024 18:01:44 +0000 Subject: [PATCH 4/4] Auto-format source code --- tests/common/PListAsserts.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/common/PListAsserts.cs b/tests/common/PListAsserts.cs index da2f33beddfe..bd80c3b4e3da 100644 --- a/tests/common/PListAsserts.cs +++ b/tests/common/PListAsserts.cs @@ -101,7 +101,7 @@ static void AssertPObjectEqual (string expectedXml, string actualXml, PObject ex { if (expected.GetType () != actual.GetType ()) { Assert.Fail ( - $"Expected item of type '{expected.GetType ().Name}' for key '{key}', got item of type '{actual.GetType ()}': {message}\n"+ + $"Expected item of type '{expected.GetType ().Name}' for key '{key}', got item of type '{actual.GetType ()}': {message}\n" + $"\tExpected xml:\n" + $"\t\t{expectedXml.Replace ("\n", "\n\t\t")}\n" + $"\tActual xml:\n" +