Export-PowerQuery.ps1
<#PSScriptInfo .VERSION 1.0.2 .GUID 8b80dbcc-b787-47b0-9e3f-96c73cb7f72b .AUTHOR Jimmy Briggs .COMPANYNAME jimbrig .COPYRIGHT Jimmy Briggs | 2023 .TAGS Excel PowerQuery M-Code Export Utility Mashup Formula Automation VersionControl Extract .LICENSEURI https://github.com/jimbrig/PSScripts/blob/main/LICENSE .PROJECTURI https://github.com/jimbrig/PSScripts/tree/main/Export-PowerQuery/ .ICONURI .EXTERNALMODULEDEPENDENCIES DataMashup .REQUIREDSCRIPTS .EXTERNALSCRIPTDEPENDENCIES .RELEASENOTES 1.0.2: Fixed Link to Project in Metadata 1.0.1: Updated to use DataMashup PowerShell Module 1.0.0: Initial Release .PRIVATEDATA #> <# .SYNOPSIS Exports Power Queries' M-Code Formulae from an Excel PowerQuery Enabled Workbook to a specified folder. .DESCRIPTION This function exports Power Queries' M-Code Formulae from an Excel PowerQuery Enabled Workbook to a specified destination source code folder. This allows for the M-Code to be version controlled and maintained in a source code repository alongside the rest of the workbook's source code (VBA, XML, SQL, DAX, etc.). The function is designed to be used in conjunction with the Import-PowerQueries function, which imports all of the Power Queries' M-Code Formulae from the specified source code folder into the Excel PowerQuery Enabled Workbook. .PARAMETER Path The path to the Excel PowerQuery Enabled Workbook. .PARAMETER ExportPath (Optional) The path to the folder where the Power Queries' M-Code Formulae will be exported to. If not specified, `<ProjectRoot>/Source/PowerQuery/*` is used as the default source code export path for the queries. .PARAMETER Extension (Optional) The file extension to use for the exported Power Queries' M-Code Formulae. If not specified, `.pq` is used as the default file extension. Typically, `.pq` is used for Power Query M-Code files, but other extensions are also common such as `.m`, `.pqm`, `.txt`, etc. .PARAMETER Force (Optional) If specified, the function will overwrite any existing files in the specified source code export path. .EXAMPLE Export-PowerQuery -Path ".\MyWorkbook.xlsx" -ExportPath ".\Source\PowerQuery" # Exports all Power Queries' M-Code Formulae from the Excel PowerQuery Enabled Workbook at the specified path # to the specified source code export path. .EXAMPLE Export-PowerQuery -Path .\Test.xlsm -ExportPath .\Source\PQ -Extension .pqm -Force # Exports all Power Queries' M-Code Formulae from the Excel PowerQuery Enabled Workbook at the specified path # to the specified source code export path, using the specified file extension, and overwriting any existing files # in the specified source code export path. .NOTES During Development of Excel based applications, an essential component of developing and maintaining the project's source code is continuous export/import and synchronization of source files with the host application for portability and most of all, version control. One area typically overlooked in this regard is the M-Code behind the Power Query components in the workbook's data model. Whether it be a Dynamic Query, User Defined Function, Query Parameter, Lookup Table, or any other Power Query component type (i.e. template, data source, properties, metadata, etc.), the M-Code behind the scenes is the foundation that all queries are built from and what drives the core behaviour of the query's component. .COMPONENT - [Dependency]: DataMashup PowerShell Module - [Related]: PSXLDevTools PowerShell Module - [Related]: Import-PowerQuery PowerShell Function .LINK https://github.com/jimbrig/PSXLDevTools/blob/main/PSXLDevTools/Public/Export-PowerQuery.ps1 .OUTPUTS System.Collections.ArrayList .INPUTS #> [CmdletBinding()] [OutputType([System.Collections.ArrayList])] Param( [Parameter(Mandatory = $true, Position = 0, HelpMessage = 'The path to the Excel PowerQuery Enabled Workbook.')] [string]$Path, [Parameter(Mandatory = $false, Position = 1, HelpMessage = 'The path to the folder where the Power Queries'' M-Code Formulae will be exported to. If not specified, `<ProjectRoot>/Source/PowerQuery/*` is used as the default source code export path for the queries.')] [string]$ExportPath = (Join-Path (Split-Path $Path -Parent)), [Parameter(Mandatory = $false, Position = 2, HelpMessage = 'The file extension to use for the exported Power Queries')] [ValidateSet('.pq', '.m', '.pqm', '.txt', '.qry')] [string]$Extension = '.pq', [Parameter(Mandatory = $false, Position = 3, HelpMessage = 'If specified, the function will overwrite any existing files in the specified source code export path.')] [switch]$Force ) Begin { # Check if DataMashup PowerShell Module is installed If (-not (Get-Module -Name DataMashup -ListAvailable)) { Write-Output 'DataMashup PowerShell Module is not installed. Please install it before running this function.' -ForegroundColor Red throw 'DataMashup PowerShell Module is not installed. Please install it before running this function.' } # Check if the specified Excel Workbook exists If (-not (Test-Path -Path $Path)) { Write-Output 'The specified Excel Workbook does not exist. Please specify a valid path to an Excel Workbook.' -ForegroundColor Red throw 'The specified Excel Workbook does not exist. Please specify a valid path to an Excel Workbook.' } # Check if the specified Excel Workbook is a PowerQuery Enabled Workbook If (-not (Test-DataMashup -Path $Path)) { Write-Output 'The specified Excel Workbook is not a PowerQuery Enabled Workbook or has Data Connections Disabled.' -ForegroundColor Red throw 'The specified Excel Workbook is not a PowerQuery Enabled Workbook or has Data Connections Disabled.' } # Check if the specified Export Path exists If (-not (Test-Path -Path $ExportPath)) { Write-Information 'The specified Export Path does not exist. Creating the path...' -ForegroundColor Yellow New-Item -Path $ExportPath -ItemType Directory -Force } # For user-provided extensions: If ($Extension -ne '.pq') { # Check the provided Extension is valid: $validExtensions = @('.pq', '.m', '.pqm', '.txt', '.qry') # Parse the provided Extension to ensure has leading period: If ($Extension -notlike '.?*') { $Extension = ".$Extension" } If (-not ($validExtensions -contains $Extension)) { Write-Output 'The provided Extension is not valid. Please specify a valid file extension from the following list:' -ForegroundColor Red Write-Output $validExtensions -ForegroundColor Magenta throw "The provided Extension is not valid. Please specify a valid file extension from the following list: $($validExtensions -join ', ')" } } } Process { Import-Module DataMashup # Export DataMashup for the PowerQueries via Export-DataMashup: try { $PQs = Export-DataMashup $Path } catch { Write-Output 'An error occurred while exporting the Power Queries from the specified Excel Workbook.' -ForegroundColor Red Write-Output $_.Exception.Message -ForegroundColor Magenta throw "An error occurred while exporting the Power Queries from the specified Excel Workbook: $_.Exception.Message" } finally { Remove-Module DataMashup } # Export PowerQuery query formulas to files: ForEach ($pq in $PQs) { $pqName = $pq.Name $pqFormula = $pq.Expression try { $pqFormula | Out-File -FilePath "$ExportPath\$pqName$Extension" -Encoding UTF8 -Force:$Force } catch { Write-Output "An error occurred while exporting $pqName to file $ExportPath\$pqName$Extension" -ForegroundColor Red Write-Output $_.Exception.Message -ForegroundColor Magenta throw "An error occurred while exporting $pqName to file $ExportPath\$pqName$Extension - $_.Exception.Message" } finally { Write-Output "Successfully exported $pqName to file $ExportPath\$pqName$Extension" -ForegroundColor Green } } } End { Write-Output 'Successfully exported all Power Queries from the specified Excel Workbook.' -ForegroundColor Green } # SIG # Begin signature block # MIIbsQYJKoZIhvcNAQcCoIIbojCCG54CAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBtKNb40+E5tAys # WYvY3FfKlfgurGYTzHvcoKH3WptoZKCCFgcwggL8MIIB5KADAgECAhBvRxLIstso # kkFFgS0muvCbMA0GCSqGSIb3DQEBCwUAMBYxFDASBgNVBAMMC0ppbUJyaWdEZXZ0 # MB4XDTIzMDMxMDIzMjY1NVoXDTI0MDMxMDIzNDY1NVowFjEUMBIGA1UEAwwLSmlt # QnJpZ0RldnQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDHDgwOjMvc # sURWKCDgflsMLhNRIA5yWwkkwCSRTb2jPZTniUkPGgdJy8XQRXoecakq9Cw5QS2x # UeCwVw+om9b4TeHdcZP237tLwJzMVf38xEfE7pE4jZHqcWd4owLtuD9oB//1nkiy # FqiVBVgsOyRy4YJmwvhtbmA5ZWW1WHkNOgnh4ZPEBdLIIwsZlQT8B5aTHZQCj2YX # NgUeroPJH0WgVajI4FDvN3usL8m3uh0UvE82nBgkJ5dkuVxHB2U3G4FN6nVb7N2y # 4urqwBG/L8R04vI/IYYSEj2wxZb1swF5BJ22opDauWFdFQ7sN4qpElNMb6teAG7M # qW6FK+eSLrJ1AgMBAAGjRjBEMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggr # BgEFBQcDAzAdBgNVHQ4EFgQUacXlY5TOFBx5jUTmblh9+x5NcSUwDQYJKoZIhvcN # AQELBQADggEBALbBLxYxORHVIHbZELfnX89QPM3+uKs0/SVWD7tiSa2HRPBDPSo1 # xFC2k/FzkzXaNXatKj1+4S/W/2tbOv7AM9a8t5luZeRZcRrfhaM+MHlN31ATBDMB # ENMFt3iA70ToY5yRdVBaBsoA0FVvdmaIK/NsfwfU0hqz891w5bgYV4JFju832e19 # yoDqTXWmQUaAxFDQhL8I08y/cWTSxicRNdfEmn9ySV+QBrd76CV4F49nWWK9gcvP # Ja2cOHxWb1EWW2yBC54aVOKidI+CzlYBYYeZZpRtkTseirvxoMt34b8iajKKqPlr # VPNjRcQxLgfT841f49girM/UA4gtKgXBexYwggWNMIIEdaADAgECAhAOmxiO+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 # twGpn1eqXijiuZQwggauMIIElqADAgECAhAHNje3JFR82Ees/ShmKl5bMA0GCSqG # SIb3DQEBCwUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMx # GTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IFRy # dXN0ZWQgUm9vdCBHNDAeFw0yMjAzMjMwMDAwMDBaFw0zNzAzMjIyMzU5NTlaMGMx # CzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjE7MDkGA1UEAxMy # RGlnaUNlcnQgVHJ1c3RlZCBHNCBSU0E0MDk2IFNIQTI1NiBUaW1lU3RhbXBpbmcg # Q0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDGhjUGSbPBPXJJUVXH # JQPE8pE3qZdRodbSg9GeTKJtoLDMg/la9hGhRBVCX6SI82j6ffOciQt/nR+eDzMf # UBMLJnOWbfhXqAJ9/UO0hNoR8XOxs+4rgISKIhjf69o9xBd/qxkrPkLcZ47qUT3w # 1lbU5ygt69OxtXXnHwZljZQp09nsad/ZkIdGAHvbREGJ3HxqV3rwN3mfXazL6IRk # tFLydkf3YYMZ3V+0VAshaG43IbtArF+y3kp9zvU5EmfvDqVjbOSmxR3NNg1c1eYb # qMFkdECnwHLFuk4fsbVYTXn+149zk6wsOeKlSNbwsDETqVcplicu9Yemj052FVUm # cJgmf6AaRyBD40NjgHt1biclkJg6OBGz9vae5jtb7IHeIhTZgirHkr+g3uM+onP6 # 5x9abJTyUpURK1h0QCirc0PO30qhHGs4xSnzyqqWc0Jon7ZGs506o9UD4L/wojzK # QtwYSH8UNM/STKvvmz3+DrhkKvp1KCRB7UK/BZxmSVJQ9FHzNklNiyDSLFc1eSuo # 80VgvCONWPfcYd6T/jnA+bIwpUzX6ZhKWD7TA4j+s4/TXkt2ElGTyYwMO1uKIqjB # Jgj5FBASA31fI7tk42PgpuE+9sJ0sj8eCXbsq11GdeJgo1gJASgADoRU7s7pXche # MBK9Rp6103a50g5rmQzSM7TNsQIDAQABo4IBXTCCAVkwEgYDVR0TAQH/BAgwBgEB # /wIBADAdBgNVHQ4EFgQUuhbZbU2FL3MpdpovdYxqII+eyG8wHwYDVR0jBBgwFoAU # 7NfjgtJxXWRM3y5nP+e6mK4cD08wDgYDVR0PAQH/BAQDAgGGMBMGA1UdJQQMMAoG # CCsGAQUFBwMIMHcGCCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29j # c3AuZGlnaWNlcnQuY29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdp # Y2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNydDBDBgNVHR8EPDA6MDig # NqA0hjJodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9v # dEc0LmNybDAgBgNVHSAEGTAXMAgGBmeBDAEEAjALBglghkgBhv1sBwEwDQYJKoZI # hvcNAQELBQADggIBAH1ZjsCTtm+YqUQiAX5m1tghQuGwGC4QTRPPMFPOvxj7x1Bd # 4ksp+3CKDaopafxpwc8dB+k+YMjYC+VcW9dth/qEICU0MWfNthKWb8RQTGIdDAiC # qBa9qVbPFXONASIlzpVpP0d3+3J0FNf/q0+KLHqrhc1DX+1gtqpPkWaeLJ7giqzl # /Yy8ZCaHbJK9nXzQcAp876i8dU+6WvepELJd6f8oVInw1YpxdmXazPByoyP6wCeC # RK6ZJxurJB4mwbfeKuv2nrF5mYGjVoarCkXJ38SNoOeY+/umnXKvxMfBwWpx2cYT # gAnEtp/Nh4cku0+jSbl3ZpHxcpzpSwJSpzd+k1OsOx0ISQ+UzTl63f8lY5knLD0/ # a6fxZsNBzU+2QJshIUDQtxMkzdwdeDrknq3lNHGS1yZr5Dhzq6YBT70/O3itTK37 # xJV77QpfMzmHQXh6OOmc4d0j/R0o08f56PGYX/sr2H7yRp11LB4nLCbbbxV7HhmL # NriT1ObyF5lZynDwN7+YAN8gFk8n+2BnFqFmut1VwDophrCYoCvtlUG3OtUVmDG0 # YgkPCr2B2RP+v6TR81fZvAT6gt4y3wSJ8ADNXcL50CN/AAvkdgIm2fBldkKmKYcJ # RyvmfxqkhQ/8mJb2VVQrH4D6wPIOK+XW+6kvRBVK5xMOHds3OBqhK/bt1nz8MIIG # wDCCBKigAwIBAgIQDE1pckuU+jwqSj0pB4A9WjANBgkqhkiG9w0BAQsFADBjMQsw # CQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xOzA5BgNVBAMTMkRp # Z2lDZXJ0IFRydXN0ZWQgRzQgUlNBNDA5NiBTSEEyNTYgVGltZVN0YW1waW5nIENB # MB4XDTIyMDkyMTAwMDAwMFoXDTMzMTEyMTIzNTk1OVowRjELMAkGA1UEBhMCVVMx # ETAPBgNVBAoTCERpZ2lDZXJ0MSQwIgYDVQQDExtEaWdpQ2VydCBUaW1lc3RhbXAg # MjAyMiAtIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDP7KUmOsap # 8mu7jcENmtuh6BSFdDMaJqzQHFUeHjZtvJJVDGH0nQl3PRWWCC9rZKT9BoMW15GS # OBwxApb7crGXOlWvM+xhiummKNuQY1y9iVPgOi2Mh0KuJqTku3h4uXoW4VbGwLpk # U7sqFudQSLuIaQyIxvG+4C99O7HKU41Agx7ny3JJKB5MgB6FVueF7fJhvKo6B332 # q27lZt3iXPUv7Y3UTZWEaOOAy2p50dIQkUYp6z4m8rSMzUy5Zsi7qlA4DeWMlF0Z # Wr/1e0BubxaompyVR4aFeT4MXmaMGgokvpyq0py2909ueMQoP6McD1AGN7oI2TWm # tR7aeFgdOej4TJEQln5N4d3CraV++C0bH+wrRhijGfY59/XBT3EuiQMRoku7mL/6 # T+R7Nu8GRORV/zbq5Xwx5/PCUsTmFntafqUlc9vAapkhLWPlWfVNL5AfJ7fSqxTl # OGaHUQhr+1NDOdBk+lbP4PQK5hRtZHi7mP2Uw3Mh8y/CLiDXgazT8QfU4b3ZXUtu # MZQpi+ZBpGWUwFjl5S4pkKa3YWT62SBsGFFguqaBDwklU/G/O+mrBw5qBzliGcnW # hX8T2Y15z2LF7OF7ucxnEweawXjtxojIsG4yeccLWYONxu71LHx7jstkifGxxLjn # U15fVdJ9GSlZA076XepFcxyEftfO4tQ6dwIDAQABo4IBizCCAYcwDgYDVR0PAQH/ # BAQDAgeAMAwGA1UdEwEB/wQCMAAwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwgwIAYD # VR0gBBkwFzAIBgZngQwBBAIwCwYJYIZIAYb9bAcBMB8GA1UdIwQYMBaAFLoW2W1N # hS9zKXaaL3WMaiCPnshvMB0GA1UdDgQWBBRiit7QYfyPMRTtlwvNPSqUFN9SnDBa # BgNVHR8EUzBRME+gTaBLhklodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNl # cnRUcnVzdGVkRzRSU0E0MDk2U0hBMjU2VGltZVN0YW1waW5nQ0EuY3JsMIGQBggr # BgEFBQcBAQSBgzCBgDAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu # Y29tMFgGCCsGAQUFBzAChkxodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln # aUNlcnRUcnVzdGVkRzRSU0E0MDk2U0hBMjU2VGltZVN0YW1waW5nQ0EuY3J0MA0G # CSqGSIb3DQEBCwUAA4ICAQBVqioa80bzeFc3MPx140/WhSPx/PmVOZsl5vdyipjD # d9Rk/BX7NsJJUSx4iGNVCUY5APxp1MqbKfujP8DJAJsTHbCYidx48s18hc1Tna9i # 4mFmoxQqRYdKmEIrUPwbtZ4IMAn65C3XCYl5+QnmiM59G7hqopvBU2AJ6KO4ndet # Hxy47JhB8PYOgPvk/9+dEKfrALpfSo8aOlK06r8JSRU1NlmaD1TSsht/fl4JrXZU # inRtytIFZyt26/+YsiaVOBmIRBTlClmia+ciPkQh0j8cwJvtfEiy2JIMkU88ZpSv # XQJT657inuTTH4YBZJwAwuladHUNPeF5iL8cAZfJGSOA1zZaX5YWsWMMxkZAO85d # NdRZPkOaGK7DycvD+5sTX2q1x+DzBcNZ3ydiK95ByVO5/zQQZ/YmMph7/lxClIGU # gp2sCovGSxVK05iQRWAzgOAj3vgDpPZFR+XOuANCR+hBNnF3rf2i6Jd0Ti7aHh2M # WsgemtXC8MYiqE+bvdgcmlHEL5r2X6cnl7qWLoVXwGDneFZ/au/ClZpLEQLIgpzJ # GgV8unG1TnqZbPTontRamMifv427GFxD9dAq6OJi7ngE273R+1sKqHB+8JeEeOMI # A11HLGOoJTiXAdI/Otrl5fbmm9x+LMz/F0xNAKLY1gEOuIvu5uByVYksJxlh9ncB # jDGCBQAwggT8AgEBMCowFjEUMBIGA1UEAwwLSmltQnJpZ0RldnQCEG9HEsiy2yiS # QUWBLSa68JswDQYJYIZIAWUDBAIBBQCggYQwGAYKKwYBBAGCNwIBDDEKMAigAoAA # oQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgorBgEEAYI3AgELMQ4w # DAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQgvkCFDQl4ctEQSHXfxjwvfC1i # lXeDJlP8O/TA8T9QeAUwDQYJKoZIhvcNAQEBBQAEggEAYdQ70ldu1QA5ZxUjSz2h # wrF3dY/oznzMJEPwtY/DO8n6zTzB+MoHHtf5LDLi8wBk2EBUrODE+cqQVa7Ubo00 # IHYyJq8nxUfzX1YDkQqAqY2UVq7XqIYr/amm0JSDdHBj4dEtcLn+1x5jdnZ9TDlE # mVzWsOJaEtWzUeOkB/0IajZzrDR/pRxi2ZjUNDtx6BVzVGxZsi9poQGyep09tqtf # M89ji0jI3jXRt6pigrLO+K47NKmeZkf60AU7UKOQWfXel4MbM9Gz5mLb3AP2DlJP # 4vSrr7vMTSZueqh1VrCVrCwGk/gMrnRaXBouUVb4sz3egrnseuHM4pa7KItkzBoG # 9aGCAyAwggMcBgkqhkiG9w0BCQYxggMNMIIDCQIBATB3MGMxCzAJBgNVBAYTAlVT # MRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjE7MDkGA1UEAxMyRGlnaUNlcnQgVHJ1 # c3RlZCBHNCBSU0E0MDk2IFNIQTI1NiBUaW1lU3RhbXBpbmcgQ0ECEAxNaXJLlPo8 # Kko9KQeAPVowDQYJYIZIAWUDBAIBBQCgaTAYBgkqhkiG9w0BCQMxCwYJKoZIhvcN # AQcBMBwGCSqGSIb3DQEJBTEPFw0yMzAzMTMwMDI2NDFaMC8GCSqGSIb3DQEJBDEi # BCC4TCGxmSqKUhoCUe4kex+15xRjdgzYFm43J0clqUfXZzANBgkqhkiG9w0BAQEF # AASCAgAVCU6d0ZC6k0fSWPyBp/1xW67MCnj1R8LDT7sOUTQl1ASd4PtZoBPr/77/ # Ms1wLBEflUMb4ako5BPEOjgZa0du557wUdKCCozsnNp9+9IgVcduh5QSfYKHQ1Tl # Izi/WhfXiL+1LvjacOxdapNXQGrEd0ifVsbXZLajD5WcOUaghINIBdH4jF0xkU8c # LHNG57cu3nkKcU946MVDxEI3PeitDbEXKC2FBf9jMekHpAI8XS/3qHHhH/37I+lL # G9O2mxQu2ZIDUqBlLhbZJPsWYnbQEeTBn+qXWht2VYxMjrnlLhCjwKWRVZ2Prq9W # uhcWbaY6lxvAyV9hRaqRuz4QTo5OH/hr682jfP1WyS9xTY79ar1zsds+yb9GnKH7 # uadm6AnzZTCCC2H5AsO4m1pumNSdVs6v6eJJycBl0/cBfn1uaG5rBQDh3nSbzc3x # ZJKuAAyci1BioB7cBUPfPyE2CI/CR6PW+VEO+SrgLw8NECtqUAC7PtteWj5Ahhen # a7Q3N5JLQ1/GmJSVEmx8id1x3A715BByf/bCwR8KzGRxabz8Z1QdJaQ9qAs24p85 # n8lus/sZ9K9l1n3ZfX29cYofLRQsFMxUyz8xIhBjapQxvq9J36BjzBJTh/bw5DKU # tBfmFcmyywqxQucq9WmkTs9C/KGWVwXG+f+VJZ5U3/qF9uEd7A== # SIG # End signature block |