DesktopManager.psm1
|
# DesktopManager bootstrapper # Auto-generated by PowerForge. Do not edit. # PowerForge script preamble begin # PowerForge script preamble end $PowerForgeModuleRoot = $PSScriptRoot $PowerForgeModulePath = $PSCommandPath $UnregisterPowerForgeDesktopAssemblyResolver = $null $PowerForgeModuleImportCompleted = $false try { $LibraryFileNames = @('DesktopManager.PowerShell.dll') $LibRoot = [IO.Path]::Combine($PowerForgeModuleRoot, 'Lib') $AssemblyFolders = Get-ChildItem -LiteralPath $LibRoot -Directory -ErrorAction SilentlyContinue $Default = $false $Core = $false $Standard = $false $HasNamedCorePayload = $false foreach ($AssemblyFolder in @($AssemblyFolders.Name)) { if ($AssemblyFolder -eq 'Default') { $Default = $true } elseif ($AssemblyFolder -eq 'Core') { $Core = $true } elseif ($AssemblyFolder -eq 'Standard') { $Standard = $true } elseif ($AssemblyFolder -match '^Core-(?:net|netcoreapp)\d+\.\d+$') { $HasNamedCorePayload = $true } } $Framework = if ($Standard) { 'Standard' } elseif ($Core) { 'Core' } else { '' } $FrameworkNet = if ($Default) { 'Default' } elseif ($Standard) { 'Standard' } else { '' } if ($PSEdition -eq 'Core') { $PowerForgeRuntimeVersion = [Environment]::Version $PowerForgeCoreBaselineVersion = $null if ($Core) { $PowerForgeCoreMarkerPath = [IO.Path]::Combine($LibRoot, 'Core', 'PowerForge.TargetFramework.txt') if (Test-Path -LiteralPath $PowerForgeCoreMarkerPath -PathType Leaf) { try { $PowerForgeCoreTargetFramework = [IO.File]::ReadAllText($PowerForgeCoreMarkerPath).Trim() if ($PowerForgeCoreTargetFramework -match '^net(?:coreapp)?(\d+\.\d+)$') { $PowerForgeCoreBaselineVersion = [Version]$Matches[1] } } catch { $PowerForgeCoreBaselineVersion = $null } } } $PowerForgeSelectedRuntimeVersion = [Version]'0.0' $PowerForgeSelectedRuntimeFolder = $null if ($Core -and $null -ne $PowerForgeCoreBaselineVersion -and $PowerForgeCoreBaselineVersion -le $PowerForgeRuntimeVersion) { $PowerForgeSelectedRuntimeVersion = $PowerForgeCoreBaselineVersion $PowerForgeSelectedRuntimeFolder = 'Core' } foreach ($PowerForgeRuntimeFolder in @($AssemblyFolders.Name)) { if ($PowerForgeRuntimeFolder -notmatch '^Core-(?:net|netcoreapp)(\d+\.\d+)$') { continue } try { $PowerForgeCandidateRuntimeVersion = [Version]$Matches[1] } catch { continue } if ($PowerForgeCandidateRuntimeVersion -le $PowerForgeRuntimeVersion -and $PowerForgeCandidateRuntimeVersion -gt $PowerForgeSelectedRuntimeVersion -and (Test-Path -LiteralPath ([IO.Path]::Combine($LibRoot, $PowerForgeRuntimeFolder)))) { $PowerForgeSelectedRuntimeVersion = $PowerForgeCandidateRuntimeVersion $PowerForgeSelectedRuntimeFolder = $PowerForgeRuntimeFolder } } if (-not [string]::IsNullOrWhiteSpace($PowerForgeSelectedRuntimeFolder)) { $Framework = $PowerForgeSelectedRuntimeFolder } elseif ($Core -and (-not $Standard -or ($null -ne $PowerForgeCoreBaselineVersion -and $PowerForgeCoreBaselineVersion -le $PowerForgeRuntimeVersion))) { $Framework = 'Core' } elseif ($Standard) { $Framework = 'Standard' } } $PowerForgeHasNoCompatibleNamedCorePayload = $PSEdition -eq 'Core' -and $HasNamedCorePayload -and ($Framework -eq 'Default' -or [string]::IsNullOrWhiteSpace($Framework)) $PowerForgePreferredBinaryFolders = if ($PSEdition -eq 'Core') { @($Framework, 'Standard', 'Core', '', 'Default') } else { @($FrameworkNet, 'Default', 'Standard', '', 'Core') } $PowerForgePreferredBinaryFolders = @($PowerForgePreferredBinaryFolders | Where-Object { $null -ne $_ } | Select-Object -Unique) $ResolvePowerForgeModuleAssembly = { param([Parameter(Mandatory = $true)][string] $LibraryFileName) if ([IO.Path]::IsPathRooted($LibraryFileName)) { $AbsoluteMatch = Get-Item -LiteralPath $LibraryFileName -ErrorAction SilentlyContinue if ($null -ne $AbsoluteMatch -and -not $AbsoluteMatch.PSIsContainer) { return [pscustomobject]@{ Path = $AbsoluteMatch.FullName Folder = $AbsoluteMatch.DirectoryName Directory = $AbsoluteMatch.DirectoryName } } } elseif ($LibraryFileName.IndexOfAny([char[]]@([IO.Path]::DirectorySeparatorChar, [IO.Path]::AltDirectorySeparatorChar)) -ge 0) { $RelativeReference = $LibraryFileName.Replace([IO.Path]::AltDirectorySeparatorChar, [IO.Path]::DirectorySeparatorChar) $LibPrefix = 'Lib' + [IO.Path]::DirectorySeparatorChar if ($RelativeReference.StartsWith($LibPrefix, [StringComparison]::OrdinalIgnoreCase)) { $RelativeReference = $RelativeReference.Substring($LibPrefix.Length) } $QualifiedMatch = @(Get-ChildItem -LiteralPath $LibRoot -File -Recurse -ErrorAction SilentlyContinue | Where-Object { $RelativeCandidate = $_.FullName.Substring($LibRoot.Length).TrimStart([char[]]@([IO.Path]::DirectorySeparatorChar, [IO.Path]::AltDirectorySeparatorChar)) $RelativeCandidate -ieq $RelativeReference } | Select-Object -First 1)[0] if ($null -ne $QualifiedMatch) { return [pscustomobject]@{ Path = $QualifiedMatch.FullName Folder = [IO.Path]::GetDirectoryName($RelativeReference) Directory = [IO.Path]::GetDirectoryName($QualifiedMatch.FullName) } } } foreach ($Folder in $PowerForgePreferredBinaryFolders) { $Directory = if ([string]::IsNullOrWhiteSpace($Folder)) { $LibRoot } else { [IO.Path]::Combine($LibRoot, $Folder) } if (-not (Test-Path -LiteralPath $Directory -PathType Container)) { continue } $Match = @(Get-ChildItem -LiteralPath $Directory -File -ErrorAction SilentlyContinue | Where-Object { $_.Name -ieq $LibraryFileName } | Select-Object -First 1)[0] if ($null -ne $Match) { return [pscustomobject]@{ Path = $Match.FullName Folder = $Folder Directory = [IO.Path]::GetDirectoryName($Match.FullName) } } } $RecursiveMatches = @(Get-ChildItem -LiteralPath $LibRoot -File -Recurse -ErrorAction SilentlyContinue | Where-Object { if ($_.Name -ine $LibraryFileName) { return $false } if (-not $PowerForgeHasNoCompatibleNamedCorePayload) { return $true } $RelativeCandidate = $_.FullName.Substring($LibRoot.Length).TrimStart([char[]]@([IO.Path]::DirectorySeparatorChar, [IO.Path]::AltDirectorySeparatorChar)) $TopLevelFolder = @($RelativeCandidate -split '[\\/]')[0] $TopLevelFolder -notmatch '^Core-(?:net|netcoreapp)\d+\.\d+$' }) if ($RecursiveMatches.Count -eq 1) { $RecursiveMatch = $RecursiveMatches[0] $RelativeDirectory = $RecursiveMatch.DirectoryName.Substring($LibRoot.Length).TrimStart([char[]]@([IO.Path]::DirectorySeparatorChar, [IO.Path]::AltDirectorySeparatorChar)) return [pscustomobject]@{ Path = $RecursiveMatch.FullName Folder = $RelativeDirectory Directory = $RecursiveMatch.DirectoryName } } if ($RecursiveMatches.Count -gt 1) { throw "Configured binary module '$LibraryFileName' matched multiple nested Lib payloads. Use a path-qualified ExportAssemblies entry." } if ($PowerForgeHasNoCompatibleNamedCorePayload) { throw 'No compatible PowerShell Core assemblies found' } throw "Configured binary module '$LibraryFileName' was not found in a compatible Lib layout." } $UnregisterPowerForgeDesktopAssemblyResolver = $null $PowerForgeDesktopAssemblyRoots = @() if ($PSEdition -ne 'Core') { if ($null -ne $ResolvePowerForgeModuleAssembly -and $LibraryFileNames.Count -gt 0) { foreach ($PowerForgeDesktopLibraryFileName in $LibraryFileNames) { try { $PowerForgeDesktopResolvedModule = & $ResolvePowerForgeModuleAssembly -LibraryFileName $PowerForgeDesktopLibraryFileName } catch { Write-Verbose "Skipping Desktop resolver root for '$PowerForgeDesktopLibraryFileName'. $($_.Exception.Message)" continue } if ($PowerForgeDesktopResolvedModule.Directory -notin $PowerForgeDesktopAssemblyRoots) { $PowerForgeDesktopAssemblyRoots += $PowerForgeDesktopResolvedModule.Directory } } } elseif ($LibFolder -or $Root) { $PowerForgeDesktopAssemblyRoots += if ($LibFolder) { [IO.Path]::GetFullPath([IO.Path]::Combine($PSScriptRoot, 'Lib', $LibFolder)) } else { [IO.Path]::GetFullPath([IO.Path]::Combine($PSScriptRoot, 'Lib')) } } } if ($PSEdition -ne 'Core' -and $PowerForgeDesktopAssemblyRoots.Count -gt 0) { $PowerForgeDesktopAssemblyRootPrefixes = @($PowerForgeDesktopAssemblyRoots | ForEach-Object { $PowerForgeDesktopAssemblyRootPrefix = [IO.Path]::GetFullPath($_) if (-not $PowerForgeDesktopAssemblyRootPrefix.EndsWith([IO.Path]::DirectorySeparatorChar.ToString(), [StringComparison]::Ordinal)) { $PowerForgeDesktopAssemblyRootPrefix += [IO.Path]::DirectorySeparatorChar } $PowerForgeDesktopAssemblyRootPrefix }) if ($PowerForgeDesktopAssemblyRootPrefixes.Count -eq 0) { $PowerForgeDesktopAssemblyRoots = @() } # A CLR callback must not execute a PowerShell scriptblock: AssemblyResolve # also runs on worker threads that have no runspace. Compile this BCL-only # implementation with the host's built-in Add-Type, once per process. $PowerForgeDesktopResolverTypeLock = [string]::Intern('PowerForge.Generated.DesktopAssemblyResolverV1') [Threading.Monitor]::Enter($PowerForgeDesktopResolverTypeLock) try { if (-not ('PowerForge.Generated.DesktopAssemblyResolverV1' -as [type])) { Add-Type -TypeDefinition @' using System; using System.Collections.Generic; using System.IO; using System.Reflection; using System.Threading; namespace PowerForge.Generated { public sealed class DesktopAssemblyResolverV1 { private readonly string[] roots; private readonly object lifetime = new object(); private volatile bool bootstrapActive = true; private int registered; [ThreadStatic] private static HashSet<DesktopAssemblyResolverV1> resolving; public DesktopAssemblyResolverV1(string[] assemblyRoots) { roots = new string[assemblyRoots.Length]; for (int i = 0; i < roots.Length; i++) roots[i] = Path.GetFullPath(assemblyRoots[i]).TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar; } public bool BootstrapActive { get { return bootstrapActive; } set { bootstrapActive = value; } } public bool Registered { get { return Thread.VolatileRead(ref registered) != 0; } } public ResolveEventHandler Handler { get { return Resolve; } } public void Register() { lock (lifetime) { if (Registered) return; AppDomain.CurrentDomain.AssemblyResolve += Resolve; Interlocked.Exchange(ref registered, 1); } } public void Unregister() { lock (lifetime) { AppDomain.CurrentDomain.AssemblyResolve -= Resolve; Interlocked.Exchange(ref registered, 0); } } private bool IsModuleAssembly(Assembly assembly) { if (assembly == null || assembly.IsDynamic || String.IsNullOrWhiteSpace(assembly.Location)) return false; string path = Path.GetFullPath(assembly.Location); foreach (string root in roots) if (path.StartsWith(root, StringComparison.OrdinalIgnoreCase)) return true; return false; } private bool IsDeclaredReference(string fullName) { foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()) { if (!IsModuleAssembly(assembly)) continue; foreach (AssemblyName reference in assembly.GetReferencedAssemblies()) if (String.Equals(reference.FullName, fullName, StringComparison.OrdinalIgnoreCase)) return true; } return false; } private static bool SameIdentity(AssemblyName requested, AssemblyName candidate) { if (!String.Equals(requested.Name, candidate.Name, StringComparison.OrdinalIgnoreCase) || !String.Equals(requested.CultureName ?? "", candidate.CultureName ?? "", StringComparison.OrdinalIgnoreCase) || (requested.Version != null && candidate.Version < requested.Version)) return false; byte[] expected = requested.GetPublicKeyToken() ?? new byte[0]; byte[] actual = candidate.GetPublicKeyToken() ?? new byte[0]; if (expected.Length != actual.Length) return false; for (int i = 0; i < expected.Length; i++) if (expected[i] != actual[i]) return false; return true; } private Assembly Resolve(object sender, ResolveEventArgs args) { if (!Registered || args == null) return null; if (resolving == null) resolving = new HashSet<DesktopAssemblyResolverV1>(); if (!resolving.Add(this)) return null; try { // Null callers cannot be attributed within an AppDomain. Accept // only exact references declared by this module after bootstrap; // another null caller requesting that same identity can share it. if (args.RequestingAssembly == null || args.RequestingAssembly.IsDynamic || String.IsNullOrWhiteSpace(args.RequestingAssembly.Location)) { if (!BootstrapActive && !IsDeclaredReference(args.Name)) return null; } else if (!IsModuleAssembly(args.RequestingAssembly)) return null; AssemblyName requested = new AssemblyName(args.Name); string name = requested.Name; if (String.IsNullOrWhiteSpace(name) || name != Path.GetFileName(name) || name.IndexOfAny(Path.GetInvalidFileNameChars()) >= 0) return null; foreach (string root in roots) { string candidate = Path.GetFullPath(Path.Combine(root, name + ".dll")); if (!candidate.StartsWith(root, StringComparison.OrdinalIgnoreCase) || !File.Exists(candidate)) continue; if (SameIdentity(requested, AssemblyName.GetAssemblyName(candidate))) return Assembly.LoadFrom(candidate); } return null; } catch { return null; } finally { resolving.Remove(this); } } } } '@ -ErrorAction Stop } } finally { [Threading.Monitor]::Exit($PowerForgeDesktopResolverTypeLock) } $PowerForgeDesktopAssemblyResolverState = [PowerForge.Generated.DesktopAssemblyResolverV1]::new([string[]]$PowerForgeDesktopAssemblyRoots) $PowerForgeDesktopAssemblyResolver = $PowerForgeDesktopAssemblyResolverState.Handler $PowerForgeDesktopAssemblyResolverState.Register() $UnregisterPowerForgeDesktopAssemblyResolver = { $PowerForgeDesktopAssemblyResolverState.Unregister() }.GetNewClosure() $PowerForgePreviousOnRemove = $ExecutionContext.SessionState.Module.OnRemove $ExecutionContext.SessionState.Module.OnRemove = { try { if ($null -ne $UnregisterPowerForgeDesktopAssemblyResolver) { & $UnregisterPowerForgeDesktopAssemblyResolver } } finally { if ($null -ne $PowerForgePreviousOnRemove) { & $PowerForgePreviousOnRemove @args } } }.GetNewClosure() } if ($PSEdition -ne 'Core') { $LibrariesScript = [IO.Path]::Combine($PowerForgeModuleRoot, 'DesktopManager.Libraries.ps1') if (Test-Path -LiteralPath $LibrariesScript) { try { . $LibrariesScript } catch { if ($null -ne $UnregisterPowerForgeDesktopAssemblyResolver) { & $UnregisterPowerForgeDesktopAssemblyResolver } throw } } } $PowerForgeDesktopBinaryLoaded = $false $PowerForgeDesktopBinaryDirectories = @() try { $ImportModule = Get-Command -Name Import-Module -Module Microsoft.PowerShell.Core $PowerForgeResolvedBinaryModules = [Collections.Generic.List[object]]::new() $PowerForgeResolvedBinaryModulePaths = [Collections.Generic.HashSet[string]]::new([StringComparer]::OrdinalIgnoreCase) foreach ($Library in $LibraryFileNames) { try { $ResolvedModuleAssembly = & $ResolvePowerForgeModuleAssembly -LibraryFileName $Library $ResolvedModuleAssemblyPath = [IO.Path]::GetFullPath($ResolvedModuleAssembly.Path) if ($PowerForgeResolvedBinaryModulePaths.Add($ResolvedModuleAssemblyPath)) { $PowerForgeResolvedBinaryModules.Add([pscustomobject]@{ Library = $Library Assembly = $ResolvedModuleAssembly }) } } catch { if ($ErrorActionPreference -eq 'Stop') { if ($null -ne $UnregisterPowerForgeDesktopAssemblyResolver) { & $UnregisterPowerForgeDesktopAssemblyResolver } throw } else { Write-Warning -Message "Resolving module $Library failed. Fix errors before continuing. Error: $($_.Exception.Message)" } } } $PowerForgeCoreModuleAssemblyPaths = [string[]]@($PowerForgeResolvedBinaryModules.Assembly.Path) if ($PSEdition -eq 'Core' -and $PowerForgeResolvedBinaryModules.Count -gt 0) { $LoaderAssemblyPath = [IO.Path]::Combine($PowerForgeResolvedBinaryModules[0].Assembly.Directory, 'DesktopManager.ModuleLoadContext.dll') if (-not ('DesktopManager.ModuleLoadContext.ModuleAssemblyLoadContext' -as [type])) { Add-Type -Path $LoaderAssemblyPath -ErrorAction Stop } } for ($LibraryIndex = 0; $LibraryIndex -lt $PowerForgeResolvedBinaryModules.Count; $LibraryIndex++) { $Library = $PowerForgeResolvedBinaryModules[$LibraryIndex].Library $ResolvedModuleAssembly = $PowerForgeResolvedBinaryModules[$LibraryIndex].Assembly $ModuleAssemblyPath = $ResolvedModuleAssembly.Path $LibraryDirectory = $ResolvedModuleAssembly.Directory $LibFolder = $LibraryDirectory $LibraryName = [IO.Path]::GetFileNameWithoutExtension($ModuleAssemblyPath) $Class = "$LibraryName.Initialize" try { if ($PSEdition -eq 'Core') { $ModuleAssembly = [DesktopManager.ModuleLoadContext.ModuleAssemblyLoadContext]::LoadModuleFromGroup( $PowerForgeCoreModuleAssemblyPaths, $ModuleAssemblyPath, 'DesktopManager') $InnerModule = & $ImportModule -Assembly $ModuleAssembly -Force -PassThru -ErrorAction Stop if ($InnerModule) { # Import-Module -Assembly loads the inner binary module into its own module object. PowerShell has no # public API to copy those exported cmdlets back to the script-module wrapper, so this uses the same # private PSModuleInfo hook used by community ALC loaders. $AddExportedCmdlet = [System.Management.Automation.PSModuleInfo].GetMethod( 'AddExportedCmdlet', [System.Reflection.BindingFlags]'Instance, NonPublic' ) $PowerForgeOuterModule = $ExecutionContext.SessionState.Module $PowerForgeIsModuleWrapper = $false if ($null -ne $PowerForgeOuterModule -and -not [string]::IsNullOrWhiteSpace($PowerForgeOuterModule.Path) -and -not [string]::IsNullOrWhiteSpace($PSCommandPath)) { try { [StringComparison] $PowerForgePathComparison = & { param([string] $PowerForgeProbePath) # Case behavior belongs to the containing filesystem. Windows can opt individual # directories into case sensitivity, while macOS volumes may be case-insensitive. # Inspect existing names without requiring write access; ambiguity fails closed. try { $PowerForgeProbeDirectory = [IO.Path]::GetDirectoryName([IO.Path]::GetFullPath($PowerForgeProbePath)) $PowerForgeNames = New-Object 'System.Collections.Generic.HashSet[string]' ([StringComparer]::Ordinal) foreach ($PowerForgeEntry in [IO.Directory]::EnumerateFileSystemEntries($PowerForgeProbeDirectory)) { [void] $PowerForgeNames.Add([IO.Path]::GetFileName($PowerForgeEntry)) } foreach ($PowerForgeName in $PowerForgeNames) { foreach ($PowerForgeAlternateName in @($PowerForgeName.ToUpperInvariant(), $PowerForgeName.ToLowerInvariant())) { if ([string]::Equals($PowerForgeName, $PowerForgeAlternateName, [StringComparison]::Ordinal) -or $PowerForgeNames.Contains($PowerForgeAlternateName)) { continue } $PowerForgeAlternatePath = [IO.Path]::Combine($PowerForgeProbeDirectory, $PowerForgeAlternateName) if ([IO.File]::Exists($PowerForgeAlternatePath) -or [IO.Directory]::Exists($PowerForgeAlternatePath)) { return [StringComparison]::OrdinalIgnoreCase } return [StringComparison]::Ordinal } } } catch { # Ordinal comparison prevents an uncertain probe from exporting into a caller. } return [StringComparison]::Ordinal } $PSCommandPath $PowerForgeIsModuleWrapper = [string]::Equals( [IO.Path]::GetFullPath($PowerForgeOuterModule.Path), [IO.Path]::GetFullPath($PSCommandPath), $PowerForgePathComparison ) } catch { $PowerForgeIsModuleWrapper = $false } } if (-not $PowerForgeIsModuleWrapper) { # A Script/ScriptPacked entry point, including one dot-sourced by another module, must not mutate # that caller's export table. The imported inner module's commands remain available to this script. } elseif ($null -ne $AddExportedCmdlet) { foreach ($Cmd in $InnerModule.ExportedCmdlets.Values) { $AddExportedCmdlet.Invoke($PowerForgeOuterModule, @(, $Cmd)) | Out-Null } $AddExportedAlias = [System.Management.Automation.PSModuleInfo].GetMethod( 'AddExportedAlias', [System.Reflection.BindingFlags]'Instance, NonPublic' ) if ($null -ne $AddExportedAlias) { foreach ($Alias in $InnerModule.ExportedAliases.Values) { $AliasTarget = if ([string]::IsNullOrWhiteSpace($Alias.Definition)) { $Alias.ResolvedCommandName } else { $Alias.Definition } try { # The alias must exist in this module scope before the private export table can reference it. Set-Alias -Name $Alias.Name -Value $AliasTarget -Scope Local -Force -ErrorAction Stop $ExportedAlias = $ExecutionContext.SessionState.InvokeCommand.GetCommand($Alias.Name, [System.Management.Automation.CommandTypes]::Alias) if ($null -ne $ExportedAlias) { $AddExportedAlias.Invoke($PowerForgeOuterModule, @(, $ExportedAlias)) | Out-Null } else { Write-Warning -Message "Alias '$($Alias.Name)' from $LibraryName was created but could not be resolved for export." } } catch { Write-Warning -Message "Alias '$($Alias.Name)' from $LibraryName could not be re-exported: $($_.Exception.Message)" } } } else { Write-Warning -Message "AddExportedAlias is not available on this PowerShell version. Aliases from $LibraryName will not be re-exported to the module scope." } } else { Write-Warning -Message "AddExportedCmdlet is not available on this PowerShell version. Falling back to direct Import-Module; cmdlets from $LibraryName will load from the default context." & $ImportModule $ModuleAssemblyPath -ErrorAction Stop } } } elseif (-not ($Class -as [type])) { & $ImportModule $ModuleAssemblyPath -ErrorAction Stop } else { $Type = "$Class" -as [Type] & $ImportModule -Force -Assembly ($Type.Assembly) } if ($PSEdition -ne 'Core') { $PowerForgeDesktopBinaryLoaded = $true if ($LibraryDirectory -notin $PowerForgeDesktopBinaryDirectories) { $PowerForgeDesktopBinaryDirectories += $LibraryDirectory } } } catch { if ($ErrorActionPreference -eq 'Stop') { if ($null -ne $UnregisterPowerForgeDesktopAssemblyResolver) { & $UnregisterPowerForgeDesktopAssemblyResolver } throw } else { Write-Warning -Message "Importing module $Library failed. Fix errors before continuing. Error: $($_.Exception.Message)" } } } } catch { if ($ErrorActionPreference -eq 'Stop') { if ($null -ne $UnregisterPowerForgeDesktopAssemblyResolver) { & $UnregisterPowerForgeDesktopAssemblyResolver } throw } else { Write-Warning -Message "Importing module $Library failed. Fix errors before continuing. Error: $($_.Exception.Message)" } } if ($PSEdition -ne 'Core' -and $PowerForgeDesktopBinaryLoaded) { foreach ($PowerForgeDesktopBinaryDirectory in $PowerForgeDesktopBinaryDirectories) { } } if ($PSEdition -ne 'Core' -and $null -ne $PowerForgeDesktopAssemblyResolverState) { $PowerForgeDesktopAssemblyResolverState.BootstrapActive = $false } # PowerForge script payload begin # PowerForge script payload end # PowerForge exports begin $FunctionsToExport = @() $CmdletsToExport = @('Add-DesktopDriverPackage', 'Connect-DesktopWifiProfile', 'Disable-DesktopDevice', 'Enable-DesktopDevice', 'Exit-DesktopSession', 'Export-DesktopDriverPackage', 'Get-DesktopAirplaneMode', 'Get-DesktopAudioEndpoint', 'Get-DesktopBackgroundColor', 'Get-DesktopBrightness', 'Get-DesktopClipboardText', 'Get-DesktopControlCheck', 'Get-DesktopControlObservation', 'Get-DesktopControlState', 'Get-DesktopControlTarget', 'Get-DesktopDevice', 'Get-DesktopDeviceClass', 'Get-DesktopDeviceContainer', 'Get-DesktopDeviceDriver', 'Get-DesktopDriverPackage', 'Get-DesktopFocusedControl', 'Get-DesktopHostedSessionDiagnostic', 'Get-DesktopMonitor', 'Get-DesktopMouseState', 'Get-DesktopPersonalization', 'Get-DesktopPowerStatus', 'Get-DesktopRadio', 'Get-DesktopSession', 'Get-DesktopSlideshow', 'Get-DesktopTaskbar', 'Get-DesktopVirtualDesktop', 'Get-DesktopWallpaper', 'Get-DesktopWallpaperHistory', 'Get-DesktopWifiProfile', 'Get-DesktopWindow', 'Get-DesktopWindowControl', 'Get-DesktopWindowControlDiagnostic', 'Get-DesktopWindowGeometry', 'Get-DesktopWindowKeepAlive', 'Get-DesktopWindowProcessInfo', 'Get-DesktopWindowTarget', 'Get-DesktopWindowText', 'Get-DesktopWorkstationProfile', 'Get-LogonWallpaper', 'Invoke-DesktopControlClick', 'Invoke-DesktopDeviceScan', 'Invoke-DesktopKeyPress', 'Invoke-DesktopMouseClick', 'Invoke-DesktopMouseDrag', 'Invoke-DesktopMouseMove', 'Invoke-DesktopMouseScroll', 'Invoke-DesktopScreenshot', 'Invoke-DesktopWindowClick', 'Invoke-DesktopWindowDrag', 'Invoke-DesktopWindowScreenshot', 'Invoke-DesktopWindowScroll', 'Lock-DesktopSession', 'Move-DesktopWindowToVirtualDesktop', 'New-DesktopRootDevice', 'Register-DesktopAudioEvent', 'Register-DesktopHotkey', 'Register-DesktopMonitorEvent', 'Register-DesktopOrientationEvent', 'Register-DesktopRadioEvent', 'Register-DesktopResolutionEvent', 'Register-DesktopSessionEvent', 'Remove-DesktopDevice', 'Remove-DesktopDriverPackage', 'Remove-DesktopPersonalization', 'Remove-DesktopWorkstationProfile', 'Restart-DesktopDevice', 'Restore-DesktopDeviceDriver', 'Restore-DesktopPersonalization', 'Restore-DesktopWindowLayout', 'Restore-DesktopWorkstationProfile', 'Save-DesktopPersonalization', 'Save-DesktopWindowLayout', 'Save-DesktopWorkstationProfile', 'Send-DesktopControlKey', 'Set-DefaultAudioDevice', 'Set-DesktopAirplaneMode', 'Set-DesktopAudioEndpoint', 'Set-DesktopBackgroundColor', 'Set-DesktopBrightness', 'Set-DesktopClipboardText', 'Set-DesktopControlCheck', 'Set-DesktopControlEnabled', 'Set-DesktopControlFocus', 'Set-DesktopControlTarget', 'Set-DesktopControlText', 'Set-DesktopControlVisibility', 'Set-DesktopDeviceClassFilter', 'Set-DesktopPersonalization', 'Set-DesktopPosition', 'Set-DesktopRadio', 'Set-DesktopResolution', 'Set-DesktopRootHardwareId', 'Set-DesktopSlideshowOptions', 'Set-DesktopTaskbarAutoHide', 'Set-DesktopWallpaper', 'Set-DesktopWallpaperHistory', 'Set-DesktopWindow', 'Set-DesktopWindowPlacement', 'Set-DesktopWindowSnap', 'Set-DesktopWindowStyle', 'Set-DesktopWindowTarget', 'Set-DesktopWindowText', 'Set-DesktopWindowTransparency', 'Set-DesktopWindowVisibility', 'Set-LogonWallpaper', 'Set-TaskbarPosition', 'Start-DesktopKeepAwake', 'Start-DesktopProcess', 'Start-DesktopProcessAndWait', 'Start-DesktopSlideshow', 'Start-DesktopWindowKeepAlive', 'Step-DesktopSlideshow', 'Stop-DesktopSlideshow', 'Stop-DesktopWindowKeepAlive', 'Stop-DesktopWindowProcess', 'Suspend-DesktopSystem', 'Test-DesktopElevation', 'Test-DesktopWindow', 'Test-DesktopWindowControl', 'Unregister-DesktopHotkey', 'Update-DesktopDeviceDriver', 'Wait-DesktopControlObservation', 'Wait-DesktopFocusedControl', 'Wait-DesktopWindow', 'Wait-DesktopWindowClose', 'Wait-DesktopWindowControl', 'Wait-DesktopWindowInactive', 'Wait-DesktopWindowText') $AliasesToExport = @('Get-DesktopMonitors', 'Get-LockScreenWallpaper', 'Set-LockScreenWallpaper') Export-ModuleMember -Function $FunctionsToExport -Alias $AliasesToExport -Cmdlet $CmdletsToExport # PowerForge exports end $PowerForgeModuleImportCompleted = $true } finally { if (-not $PowerForgeModuleImportCompleted -and $null -ne $UnregisterPowerForgeDesktopAssemblyResolver) { & $UnregisterPowerForgeDesktopAssemblyResolver } } # SIG # Begin signature block # MIIt7AYJKoZIhvcNAQcCoIIt3TCCLdkCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCDHUvoBe/P5MJAV # 9r4rPxHGumk4sOFn3ydrbOKJsYg3xKCCJukwggWNMIIEdaADAgECAhAOmxiO+dAt # 5+/bUOIIQBhaMA0GCSqGSIb3DQEBDAUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQK # EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNV # BAMTG0RpZ2lDZXJ0IEFzc3VyZWQgSUQgUm9vdCBDQTAeFw0yMjA4MDEwMDAwMDBa # Fw0zMTExMDkyMzU5NTlaMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2Vy # dCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lD # ZXJ0IFRydXN0ZWQgUm9vdCBHNDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC # ggIBAL/mkHNo3rvkXUo8MCIwaTPswqclLskhPfKK2FnC4SmnPVirdprNrnsbhA3E # MB/zG6Q4FutWxpdtHauyefLKEdLkX9YFPFIPUh/GnhWlfr6fqVcWWVVyr2iTcMKy # unWZanMylNEQRBAu34LzB4TmdDttceItDBvuINXJIB1jKS3O7F5OyJP4IWGbNOsF # xl7sWxq868nPzaw0QF+xembud8hIqGZXV59UWI4MK7dPpzDZVu7Ke13jrclPXuU1 # 5zHL2pNe3I6PgNq2kZhAkHnDeMe2scS1ahg4AxCN2NQ3pC4FfYj1gj4QkXCrVYJB # MtfbBHMqbpEBfCFM1LyuGwN1XXhm2ToxRJozQL8I11pJpMLmqaBn3aQnvKFPObUR # WBf3JFxGj2T3wWmIdph2PVldQnaHiZdpekjw4KISG2aadMreSx7nDmOu5tTvkpI6 # nj3cAORFJYm2mkQZK37AlLTSYW3rM9nF30sEAMx9HJXDj/chsrIRt7t/8tWMcCxB # YKqxYxhElRp2Yn72gLD76GSmM9GJB+G9t+ZDpBi4pncB4Q+UDCEdslQpJYls5Q5S # UUd0viastkF13nqsX40/ybzTQRESW+UQUOsxxcpyFiIJ33xMdT9j7CFfxCBRa2+x # q4aLT8LWRV+dIPyhHsXAj6KxfgommfXkaS+YHS312amyHeUbAgMBAAGjggE6MIIB # NjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTs1+OC0nFdZEzfLmc/57qYrhwP # TzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzAOBgNVHQ8BAf8EBAMC # AYYweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdp # Y2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNv # bS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwRQYDVR0fBD4wPDA6oDigNoY0 # aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENB # LmNybDARBgNVHSAECjAIMAYGBFUdIAAwDQYJKoZIhvcNAQEMBQADggEBAHCgv0Nc # Vec4X6CjdBs9thbX979XB72arKGHLOyFXqkauyL4hxppVCLtpIh3bb0aFPQTSnov # Lbc47/T/gLn4offyct4kvFIDyE7QKt76LVbP+fT3rDB6mouyXtTP0UNEm0Mh65Zy # oUi0mcudT6cGAxN3J0TU53/oWajwvy8LpunyNDzs9wPHh6jSTEAZNUZqaVSwuKFW # juyk1T3osdz9HNj0d1pcVIxv76FQPfx2CWiEn2/K2yCNNWAcAgPLILCsWKAOQGPF # mCLBsln1VWvPJ6tsds5vIy30fnFqI2si/xK4VC0nftg62fC2h5b9W9FcrBjDTZ9z # twGpn1eqXijiuZQwggWQMIIDeKADAgECAhAFmxtXno4hMuI5B72nd3VcMA0GCSqG # SIb3DQEBDAUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMx # GTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IFRy # dXN0ZWQgUm9vdCBHNDAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGIx # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3 # dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9vdCBH # NDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL/mkHNo3rvkXUo8MCIw # aTPswqclLskhPfKK2FnC4SmnPVirdprNrnsbhA3EMB/zG6Q4FutWxpdtHauyefLK # EdLkX9YFPFIPUh/GnhWlfr6fqVcWWVVyr2iTcMKyunWZanMylNEQRBAu34LzB4Tm # dDttceItDBvuINXJIB1jKS3O7F5OyJP4IWGbNOsFxl7sWxq868nPzaw0QF+xembu # d8hIqGZXV59UWI4MK7dPpzDZVu7Ke13jrclPXuU15zHL2pNe3I6PgNq2kZhAkHnD # eMe2scS1ahg4AxCN2NQ3pC4FfYj1gj4QkXCrVYJBMtfbBHMqbpEBfCFM1LyuGwN1 # XXhm2ToxRJozQL8I11pJpMLmqaBn3aQnvKFPObURWBf3JFxGj2T3wWmIdph2PVld # QnaHiZdpekjw4KISG2aadMreSx7nDmOu5tTvkpI6nj3cAORFJYm2mkQZK37AlLTS # YW3rM9nF30sEAMx9HJXDj/chsrIRt7t/8tWMcCxBYKqxYxhElRp2Yn72gLD76GSm # M9GJB+G9t+ZDpBi4pncB4Q+UDCEdslQpJYls5Q5SUUd0viastkF13nqsX40/ybzT # QRESW+UQUOsxxcpyFiIJ33xMdT9j7CFfxCBRa2+xq4aLT8LWRV+dIPyhHsXAj6Kx # fgommfXkaS+YHS312amyHeUbAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYD # VR0PAQH/BAQDAgGGMB0GA1UdDgQWBBTs1+OC0nFdZEzfLmc/57qYrhwPTzANBgkq # hkiG9w0BAQwFAAOCAgEAu2HZfalsvhfEkRvDoaIAjeNkaA9Wz3eucPn9mkqZucl4 # XAwMX+TmFClWCzZJXURj4K2clhhmGyMNPXnpbWvWVPjSPMFDQK4dUPVS/JA7u5iZ # aWvHwaeoaKQn3J35J64whbn2Z006Po9ZOSJTROvIXQPK7VB6fWIhCoDIc2bRoAVg # X+iltKevqPdtNZx8WorWojiZ83iL9E3SIAveBO6Mm0eBcg3AFDLvMFkuruBx8lbk # apdvklBtlo1oepqyNhR6BvIkuQkRUNcIsbiJeoQjYUIp5aPNoiBB19GcZNnqJqGL # FNdMGbJQQXE9P01wI4YMStyB0swylIQNCAmXHE/A7msgdDDS4Dk0EIUhFQEI6FUy # 3nFJ2SgXUE3mvk3RdazQyvtBuEOlqtPDBURPLDab4vriRbgjU2wGb2dVf0a1TD9u # KFp5JtKkqGKX0h7i7UqLvBv9R0oN32dmfrJbQdA75PQ79ARj6e/CVABRoIoqyc54 # zNXqhwQYs86vSYiv85KZtrPmYQ/ShQDnUBrkG5WdGaG5nLGbsQAe79APT0JsyQq8 # 7kP6OnGlyE0mpTX9iV28hWIdMtKgK1TtmlfB2/oQzxm3i0objwG2J5VT6LaJbVu8 # aNQj6ItRolb58KaAoNYes7wPD1N1KarqE3fk3oyBIa0HEEcRrYc9B9F1vM/zZn4w # ggawMIIEmKADAgECAhAIrUCyYNKcTJ9ezam9k67ZMA0GCSqGSIb3DQEBDAUAMGIx # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3 # dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9vdCBH # NDAeFw0yMTA0MjkwMDAwMDBaFw0zNjA0MjgyMzU5NTlaMGkxCzAJBgNVBAYTAlVT # MRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjFBMD8GA1UEAxM4RGlnaUNlcnQgVHJ1 # c3RlZCBHNCBDb2RlIFNpZ25pbmcgUlNBNDA5NiBTSEEzODQgMjAyMSBDQTEwggIi # MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDVtC9C0CiteLdd1TlZG7GIQvUz # jOs9gZdwxbvEhSYwn6SOaNhc9es0JAfhS0/TeEP0F9ce2vnS1WcaUk8OoVf8iJnB # kcyBAz5NcCRks43iCH00fUyAVxJrQ5qZ8sU7H/Lvy0daE6ZMswEgJfMQ04uy+wjw # iuCdCcBlp/qYgEk1hz1RGeiQIXhFLqGfLOEYwhrMxe6TSXBCMo/7xuoc82VokaJN # TIIRSFJo3hC9FFdd6BgTZcV/sk+FLEikVoQ11vkunKoAFdE3/hoGlMJ8yOobMubK # wvSnowMOdKWvObarYBLj6Na59zHh3K3kGKDYwSNHR7OhD26jq22YBoMbt2pnLdK9 # RBqSEIGPsDsJ18ebMlrC/2pgVItJwZPt4bRc4G/rJvmM1bL5OBDm6s6R9b7T+2+T # YTRcvJNFKIM2KmYoX7BzzosmJQayg9Rc9hUZTO1i4F4z8ujo7AqnsAMrkbI2eb73 # rQgedaZlzLvjSFDzd5Ea/ttQokbIYViY9XwCFjyDKK05huzUtw1T0PhH5nUwjeww # k3YUpltLXXRhTT8SkXbev1jLchApQfDVxW0mdmgRQRNYmtwmKwH0iU1Z23jPgUo+ # QEdfyYFQc4UQIyFZYIpkVMHMIRroOBl8ZhzNeDhFMJlP/2NPTLuqDQhTQXxYPUez # +rbsjDIJAsxsPAxWEQIDAQABo4IBWTCCAVUwEgYDVR0TAQH/BAgwBgEB/wIBADAd # BgNVHQ4EFgQUaDfg67Y7+F8Rhvv+YXsIiGX0TkIwHwYDVR0jBBgwFoAU7NfjgtJx # XWRM3y5nP+e6mK4cD08wDgYDVR0PAQH/BAQDAgGGMBMGA1UdJQQMMAoGCCsGAQUF # BwMDMHcGCCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGln # aWNlcnQuY29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5j # b20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNydDBDBgNVHR8EPDA6MDigNqA0hjJo # dHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNy # bDAcBgNVHSAEFTATMAcGBWeBDAEDMAgGBmeBDAEEATANBgkqhkiG9w0BAQwFAAOC # AgEAOiNEPY0Idu6PvDqZ01bgAhql+Eg08yy25nRm95RysQDKr2wwJxMSnpBEn0v9 # nqN8JtU3vDpdSG2V1T9J9Ce7FoFFUP2cvbaF4HZ+N3HLIvdaqpDP9ZNq4+sg0dVQ # eYiaiorBtr2hSBh+3NiAGhEZGM1hmYFW9snjdufE5BtfQ/g+lP92OT2e1JnPSt0o # 618moZVYSNUa/tcnP/2Q0XaG3RywYFzzDaju4ImhvTnhOE7abrs2nfvlIVNaw8rp # avGiPttDuDPITzgUkpn13c5UbdldAhQfQDN8A+KVssIhdXNSy0bYxDQcoqVLjc1v # djcshT8azibpGL6QB7BDf5WIIIJw8MzK7/0pNVwfiThV9zeKiwmhywvpMRr/Lhlc # OXHhvpynCgbWJme3kuZOX956rEnPLqR0kq3bPKSchh/jwVYbKyP/j7XqiHtwa+ag # uv06P0WmxOgWkVKLQcBIhEuWTatEQOON8BUozu3xGFYHKi8QxAwIZDwzj64ojDzL # j4gLDb879M4ee47vtevLt/B3E+bnKD+sEq6lLyJsQfmCXBVmzGwOysWGw/YmMwwH # S6DTBwJqakAwSEs0qFEgu60bhQjiWQ1tygVQK+pKHJ6l/aCnHwZ05/LWUpD9r4VI # IflXO7ScA+2GRfS0YW6/aOImYIbqyK+p/pQd52MbOoZWeE4wgga0MIIEnKADAgEC # AhANx6xXBf8hmS5AQyIMOkmGMA0GCSqGSIb3DQEBCwUAMGIxCzAJBgNVBAYTAlVT # MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j # b20xITAfBgNVBAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9vdCBHNDAeFw0yNTA1MDcw # MDAwMDBaFw0zODAxMTQyMzU5NTlaMGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5E # aWdpQ2VydCwgSW5jLjFBMD8GA1UEAxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBUaW1l # U3RhbXBpbmcgUlNBNDA5NiBTSEEyNTYgMjAyNSBDQTEwggIiMA0GCSqGSIb3DQEB # AQUAA4ICDwAwggIKAoICAQC0eDHTCphBcr48RsAcrHXbo0ZodLRRF51NrY0NlLWZ # loMsVO1DahGPNRcybEKq+RuwOnPhof6pvF4uGjwjqNjfEvUi6wuim5bap+0lgloM # 2zX4kftn5B1IpYzTqpyFQ/4Bt0mAxAHeHYNnQxqXmRinvuNgxVBdJkf77S2uPoCj # 7GH8BLuxBG5AvftBdsOECS1UkxBvMgEdgkFiDNYiOTx4OtiFcMSkqTtF2hfQz3zQ # Sku2Ws3IfDReb6e3mmdglTcaarps0wjUjsZvkgFkriK9tUKJm/s80FiocSk1VYLZ # lDwFt+cVFBURJg6zMUjZa/zbCclF83bRVFLeGkuAhHiGPMvSGmhgaTzVyhYn4p0+ # 8y9oHRaQT/aofEnS5xLrfxnGpTXiUOeSLsJygoLPp66bkDX1ZlAeSpQl92QOMeRx # ykvq6gbylsXQskBBBnGy3tW/AMOMCZIVNSaz7BX8VtYGqLt9MmeOreGPRdtBx3yG # OP+rx3rKWDEJlIqLXvJWnY0v5ydPpOjL6s36czwzsucuoKs7Yk/ehb//Wx+5kMqI # MRvUBDx6z1ev+7psNOdgJMoiwOrUG2ZdSoQbU2rMkpLiQ6bGRinZbI4OLu9BMIFm # 1UUl9VnePs6BaaeEWvjJSjNm2qA+sdFUeEY0qVjPKOWug/G6X5uAiynM7Bu2ayBj # UwIDAQABo4IBXTCCAVkwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQU729T # SunkBnx6yuKQVvYv1Ensy04wHwYDVR0jBBgwFoAU7NfjgtJxXWRM3y5nP+e6mK4c # D08wDgYDVR0PAQH/BAQDAgGGMBMGA1UdJQQMMAoGCCsGAQUFBwMIMHcGCCsGAQUF # BwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEEG # CCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRU # cnVzdGVkUm9vdEc0LmNydDBDBgNVHR8EPDA6MDigNqA0hjJodHRwOi8vY3JsMy5k # aWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNybDAgBgNVHSAEGTAX # MAgGBmeBDAEEAjALBglghkgBhv1sBwEwDQYJKoZIhvcNAQELBQADggIBABfO+xaA # HP4HPRF2cTC9vgvItTSmf83Qh8WIGjB/T8ObXAZz8OjuhUxjaaFdleMM0lBryPTQ # M2qEJPe36zwbSI/mS83afsl3YTj+IQhQE7jU/kXjjytJgnn0hvrV6hqWGd3rLAUt # 6vJy9lMDPjTLxLgXf9r5nWMQwr8Myb9rEVKChHyfpzee5kH0F8HABBgr0UdqirZ7 # bowe9Vj2AIMD8liyrukZ2iA/wdG2th9y1IsA0QF8dTXqvcnTmpfeQh35k5zOCPmS # Nq1UH410ANVko43+Cdmu4y81hjajV/gxdEkMx1NKU4uHQcKfZxAvBAKqMVuqte69 # M9J6A47OvgRaPs+2ykgcGV00TYr2Lr3ty9qIijanrUR3anzEwlvzZiiyfTPjLbnF # RsjsYg39OlV8cipDoq7+qNNjqFzeGxcytL5TTLL4ZaoBdqbhOhZ3ZRDUphPvSRmM # Thi0vw9vODRzW6AxnJll38F0cuJG7uEBYTptMSbhdhGQDpOXgpIUsWTjd6xpR6oa # Qf/DJbg3s6KCLPAlZ66RzIg9sC+NJpud/v4+7RWsWCiKi9EOLLHfMR2ZyJ/+xhCx # 9yHbxtl5TPau1j/1MIDpMPx0LckTetiSuEtQvLsNz3Qbp7wGWqbIiOWCnb5WqxL3 # /BAPvIXKUjPSxyZsq8WhbaM2tszWkPZPubdcMIIG7TCCBNWgAwIBAgIQCE/cM09+ # RU7bww+P+ZIYNTANBgkqhkiG9w0BAQsFADBpMQswCQYDVQQGEwJVUzEXMBUGA1UE # ChMORGlnaUNlcnQsIEluYy4xQTA/BgNVBAMTOERpZ2lDZXJ0IFRydXN0ZWQgRzQg # VGltZVN0YW1waW5nIFJTQTQwOTYgU0hBMjU2IDIwMjUgQ0ExMB4XDTI2MDgwNTAw # MDAwMFoXDTM3MTEwNDIzNTk1OVowYzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRp # Z2lDZXJ0LCBJbmMuMTswOQYDVQQDEzJEaWdpQ2VydCBTSEEyNTYgUlNBNDA5NiBU # aW1lc3RhbXAgUmVzcG9uZGVyIDIwMjYgMTCCAiIwDQYJKoZIhvcNAQEBBQADggIP # ADCCAgoCggIBALZ7pvLJ/s1K+NSbTGWz/TjGMPh8CQ6RucZCLv5anHzWJjF/NWJr # FIhy24fcpKXlgRiky4WAawDfU3YP0BMxt9l3Dm5oCG5Z69AqEN1kgHg2epx+l+lZ # BcmJCcN0ASURML5uFIS80sZsDwO3BSkUxDjLJhBI+qiZP3aixAC/qEGLjsBNlLol # 9VZ7pfGEXiMlneJIC5/YKuizVzNFKZZEeoy/0B8Zm+nzKBgSWG52lCO1w+nCg6Xp # CtklTJXeIg283hw7TmmsZXR+SMbjbrEOvZ3fP2VxIgeR28Y90ZStd3F9VuA5RVyn # b/whITPAo9b75Zr4Ta6Mj3URm26QZYMn/FnbuTegcoRcFEZ9FOqM5T6MTdtr/n74 # lIT/ug0eeOzmZ6QTFg33otX+bFRsIolvykE1jive4PuESaT8zzVeFWDAMDtozNgL # ctkGD1ZjkEyZtJrLl5ya0m5doH/ScpaZCZVl6pNUOCybMc/kxC6EAmSJY24L0yYK # D1Nkddsnb/ItVKi/2nXpQNMu1PT5prW83vV8d67WowuUs0HdY4H8AMLGvdL/WHEj # 3ZnqMqAQQP9u3Ai9t+5eQ02GDwy0ODjdzi0xlp70W+ow63/0++YDEX1M0iwgUHwb # rJvfpklkZQvw3+kv3vUPItdwroczk9icflf55W1zOEKAcJVAIXpcMCU9AgMBAAGj # ggGVMIIBkTAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBQUyWOKMC7USvtulPPm40B+ # 9ezN4jAfBgNVHSMEGDAWgBTvb1NK6eQGfHrK4pBW9i/USezLTjAOBgNVHQ8BAf8E # BAMCB4AwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwgwgZUGCCsGAQUFBwEBBIGIMIGF # MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wXQYIKwYBBQUH # MAKGUWh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRH # NFRpbWVTdGFtcGluZ1JTQTQwOTZTSEEyNTYyMDI1Q0ExLmNydDBfBgNVHR8EWDBW # MFSgUqBQhk5odHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVk # RzRUaW1lU3RhbXBpbmdSU0E0MDk2U0hBMjU2MjAyNUNBMS5jcmwwIAYDVR0gBBkw # FzAIBgZngQwBBAIwCwYJYIZIAYb9bAcBMA0GCSqGSIb3DQEBCwUAA4ICAQCNxTph # Hp1SCt+ZrAmAfn0oQLFr0mLywSLaDXQIENoyKqxrFbJblzCVP/pkXmwXOdrOpWyg # LzlT12os5ipDCy35RBCg2UMeApEtrfGhz45F4Wt4WGdNdIbRWt3YTYJmpR+b7lr4 # d7Uwn+H600u4D7RnOGf8Wj4UNgAdZkfHhHv1mx9EVh71SJelcEN/oORSjXzdjfw1 # iZH9d8Nh/thn6hH23d+VsPAr6GAYyzSA02nXD1nYLI7Ijmiv+xLCiYC41DSFYL3G # hTiy0PxpawPtGRyaBVGzq+UiTfM8pD7KVyF5aQyWP4KhVGUUTnmm/RlYJoW3TiXA # /+t0YcT2oRVBm3JETjajHug2AL+v5jhtKVnd3D0rbHXEu27o+Q8p4sEWPMqKDB+q # bceb6T/6WcwTwXmQ9lOCLLYcsQeSWmvKqzpAec9etE14jOQAzLKWdE3w/TCaKtLR # aRT7LCkRYVnhA2D73FLje1O5b3HR5eHs0NzU/+xX7NbEdcofy0W3Wdwd1XOqtlpg # /JgwtKfZM5dqO94lbUveOiJBI+xZEbGRsMNbXmMREUTgu+Oca7Y73MPWcslIx2Vh # kSKSXjDbD6rgg39H5Mh7QfieAIjWagkJNt68Yfim6cjEzVSiLSeZfdkr5dtFPTW6 # jATlWJdYeeDRGCyatf8R1hSjzSvdN8yWQPT9gzCCB2MwggVLoAMCAQICEAhTOt+G # wz3QWpc3Z3ZgARUwDQYJKoZIhvcNAQELBQAwaTELMAkGA1UEBhMCVVMxFzAVBgNV # BAoTDkRpZ2lDZXJ0LCBJbmMuMUEwPwYDVQQDEzhEaWdpQ2VydCBUcnVzdGVkIEc0 # IENvZGUgU2lnbmluZyBSU0E0MDk2IFNIQTM4NCAyMDIxIENBMTAeFw0yNTEyMjYw # MDAwMDBaFw0yODEyMjcyMzU5NTlaMGsxCzAJBgNVBAYTAlBMMRIwEAYDVQQHDAlN # aWtvxYLDs3cxIzAhBgNVBAoTGkV2b3RlYyBTZXJ2aWNlcyBzcC4geiBvLm8uMSMw # IQYDVQQDExpFdm90ZWMgU2VydmljZXMgc3AuIHogby5vLjCCAiIwDQYJKoZIhvcN # AQEBBQADggIPADCCAgoCggIBANxbP/C0CFW8Z1gxi5+MxwMPmc5G8c3fIiV9S9FY # Lic5MEFf2hrQJ2PIx/Xf7bsfkuk0cSeUTnTL/sZYI9U9Hjah1EAxSvryILnhjoyZ # eedLTjOJkyWjoIs8cquJ8QAJgGYW8xhYp4e52MQGv8nHFkytFLebmrNJ88czDh4F # 5+UvvYovOkxJ68kvAXU0MMdiF3SOLii+gWQRcmRFQNghMJo4jS0jDfp7EzKN5GHY # iNbT5/xc1H16olQHZ37kIzGQlCel9+hTnPxf94eVouHo+HOQWlC55nujZAGFkID1 # h9EuRFCpPfapQVKmKSH8kxcJ1Ml11VQOE2HvFuMnOzE0DTq4qUSY7OZa5ddPXz5e # usNIwiIVEIXfKZD+UHRZkmdoSEGoCNVJHLRDTEKxnNJeaGKihE/K+DgeCYVipITP # 5MOwgG5nvOxILPs7CmxqaEGH9iT/xuJ4wiiBtLmvJiyJlHUOsVj0GtTdxMP5jjg2 # tIWVRAMkLRsfqSz31c9DbENEh7n8u6qqWAW3U2pWktY1i0PZt9vwfJnboZQnP91h # +Lee9/3YGnVyXq6J/x0TkBD9tg3CD5cTBDtA3MyDYQ4AYkYoToj6QP8fJnecOHx7 # 8UuU+f3N//gAfAu1UR3cM044N3Btm6IuyaXaRrFCro8L0nAV0WFMGz/W1FWnqTfT # SQ/XAgMBAAGjggIDMIIB/zAfBgNVHSMEGDAWgBRoN+Drtjv4XxGG+/5hewiIZfRO # QjAdBgNVHQ4EFgQUehhCwq/shewf/KCCM+q+nhvZG/wwPgYDVR0gBDcwNTAzBgZn # gQwBBAEwKTAnBggrBgEFBQcCARYbaHR0cDovL3d3dy5kaWdpY2VydC5jb20vQ1BT # MA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzCBtQYDVR0fBIGt # MIGqMFOgUaBPhk1odHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVz # dGVkRzRDb2RlU2lnbmluZ1JTQTQwOTZTSEEzODQyMDIxQ0ExLmNybDBToFGgT4ZN # aHR0cDovL2NybDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZEc0Q29kZVNp # Z25pbmdSU0E0MDk2U0hBMzg0MjAyMUNBMS5jcmwwgZQGCCsGAQUFBwEBBIGHMIGE # MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wXAYIKwYBBQUH # MAKGUGh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRH # NENvZGVTaWduaW5nUlNBNDA5NlNIQTM4NDIwMjFDQTEuY3J0MAkGA1UdEwQCMAAw # DQYJKoZIhvcNAQELBQADggIBAD/YXkCSn1GzVQkE3O/LO2XlSbJYUNUFpAN4F4JZ # qAjQN1KCIdzWBPCOA844XDWo3fZox3sO/KF0tXVF2QeD7scK5bpd2gVE0tTqsWO0 # 9wR5VvzBHWZI3vWk6JfBT8pZK3++7iqpOYtZPQFYhHCk0pKqwL8K5ajrSRNoXcKK # VK8+ITMgVuwKqRtYpCs3VjX/kEPZtVTXAOLWB875hcuaqWhHye199ZCtuV0xgp4k # v1Euk42sN4s5nuFgS0M3ZTAAujJLSFsKnbGv086tbBiOjj/ntPwbKd2jwZu1MDSK # rZjvKRvUvU2sK4xVu185n5Lfz4CU6j7XRVFAYYYDxvYfMJ9ABKiZgl5o++PPx66d # gLxDKNC30YIAnQXgExaFEp1u5OCEQNJ/VmYjwl8SRvMy4A20sb9bczlFww8tpRb6 # 2WCRdhZck7rPLsPBjQgvkreachnOQAO8hMY5R4i9t88vBVq+cxj3tg0PMgqv7MWO # mrgzBeTow7twTnSU9w1SgVoUi39M7t8pwX1E6xJQiJL+SFlBH+AJK0iByN7YZjW7 # 65xxum54/kolZb9hgWiGQABNQMBHhEGYG8LLuLdBotIFs4sL+aP7IJv5N0mierbK # N5ROlavUwY4YIVqQSj+c1BU+f+uljQkZ5YFFt1y8oiYvTHkUkLYjL8cHVLvxTzsT # Nd1ZMYIGWTCCBlUCAQEwfTBpMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNl # cnQsIEluYy4xQTA/BgNVBAMTOERpZ2lDZXJ0IFRydXN0ZWQgRzQgQ29kZSBTaWdu # aW5nIFJTQTQwOTYgU0hBMzg0IDIwMjEgQ0ExAhAIUzrfhsM90FqXN2d2YAEVMA0G # CWCGSAFlAwQCAQUAoIGEMBgGCisGAQQBgjcCAQwxCjAIoAKAAKECgAAwGQYJKoZI # hvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcC # ARUwLwYJKoZIhvcNAQkEMSIEIFwj6rhVrsgHApIb8P1kKEHORgWuAlJbvCt7umkr # cg/vMA0GCSqGSIb3DQEBAQUABIICAMwvrEuqysYINgGa+yKEWk7siYTbMTfh8QOB # REiPIJS1Gkw2ObbirP/y88VFVfYNdnRAM13eRLYDaagBWHWuC3xaS2gFk2dcJqkR # gGF7l2yVpRpi9muPTHyQ5XlFmgOjL0Lmqz28OUO85/iZ/L7mF0MYjJ2V+AYuE6Ol # e+U/yexoD/jd+JThUtzk+qGpxz/TxcJneIbKyxlQmTejx1+uryDD6ocsKnurDKWj # zoFNjiZxEaQnITPtgEbshEVtcbtnLglcuQ8bpfl17FRpt0JFSig90mH11a//uAhP # ShlDJGN6SRb6MgkhXfnqyY/mZAU/oplwAkm7HqS8k4qQYqWz/fhjJjZgCl7mv1Th # YOTaHK7+CU3huQGdEC3SaQwYBdm0QiHpfGKkj6nDkmQVelSlhbq7zTiiRWfGOfO2 # 2EoR/xZjSXpGH6n24Ns/GB9A+DofSSLWQd/wa4BYQCvGM87nCPndvaIHeGqm8K8J # WWYCECZnucCIC86bzxiyB21PpPjFQzaqR5rhRrvNZMt5GzM3tWvsw6gnzdYrKZvG # 02pmYMsRi/oQ9lgnmWdFS1ze9ZdI8erQTMz+sliFl7sU5hWCIrAIFuBUYg5mgxlt # cvjEUMZsZYZdf8k8fPg7bhgOmqkTKb1FUJcJNRN19xBwgyeEBrohbyF90vVAl9FA # kGGXRuUvoYIDJjCCAyIGCSqGSIb3DQEJBjGCAxMwggMPAgEBMH0waTELMAkGA1UE # BhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMUEwPwYDVQQDEzhEaWdpQ2Vy # dCBUcnVzdGVkIEc0IFRpbWVTdGFtcGluZyBSU0E0MDk2IFNIQTI1NiAyMDI1IENB # MQIQCE/cM09+RU7bww+P+ZIYNTANBglghkgBZQMEAgEFAKBpMBgGCSqGSIb3DQEJ # AzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTI2MTAxNjE3MjkxMFowLwYJ # KoZIhvcNAQkEMSIEIFAfiYNxBvCKeJjEC64oOwGDD7G3ccP+M8oQkhv8GYyYMA0G # CSqGSIb3DQEBAQUABIICAK9YBKSSJvWt9Yo9xkqIDKhDjzWqplZoQf+rmImErgBt # sHemx5OG2eAmDCrRr0rIGh9KmH3GrA9gmPn7C1TPNFWdG74GV63+GRH+1h+o2cSr # QT46N11sufJbK3pmvbyxDD/UWIMfxtxyH5yq9gDLzMDuHi5AaDHXu3mBH+BrBGkQ # GkPhGDT/ODxNIHvO3sgk9Nd0xSfeRFfl+PEDU7NGg33uOUX2mnDPwjkt9m+r5eYn # sVmh+NRPPRzjHPLfbt/PvUy3hIU8sQYwMLoZpdBNwS9op6OhQFv6kcY5agjKjuHb # H+kY54rMY/ZDgOMZ4EdHjWQTQ+JF4vYsR8oO3MR9WtIwbtcy4GH6CTf5qEu8bebE # /20/A0B/51yE2dJYzoUJLWUX3DC0qbcG0cV686Hx0DJQ8Pn7JDs66ANe23SypfiB # tkeRsDUFR2rsN06CgZ2vIUXJL+RJAC3J4L9nwIW2ICY0/6F3eOQ9ZO6EqZqylrmW # R73padw/8ueVuxiz7YfghhKux2bod/hVvUwPcYEpegdbIuZzOyOkDWJ7yWQFSibQ # 2pjcDxRRs7t1hC1Jh5YeeGNLPJI9Ng/gY/83tXZi62qR11NkdIUBgssJJFF8rQ1j # zlGP3M33fg2klxR4KcfiIcYoyc3gkTyOZFsEFlDmXgBLyI4x7TxmyuxHzSIWH8kt # SIG # End signature block |