PSWriteOffice.psm1

function ConvertFrom-Color {
    [alias('Convert-FromColor')]
    [CmdletBinding()]
    param ([ValidateScript({ if ($($_ -in $Script:RGBColors.Keys -or $_ -match "^#([A-Fa-f0-9]{6})$" -or $_ -eq "") -eq $false) { throw "The Input value is not a valid colorname nor an valid color hex code." } else { $true } })]
        [alias('Colors')][string[]] $Color,
        [switch] $AsDecimal,
        [switch] $AsDrawingColor)
    $Colors = foreach ($C in $Color) {
        $Value = $Script:RGBColors."$C"
        if ($C -match "^#([A-Fa-f0-9]{6})$") {
            $C
            continue
        }
        if ($null -eq $Value) { continue }
        $HexValue = Convert-Color -RGB $Value
        Write-Verbose "Convert-FromColor - Color Name: $C Value: $Value HexValue: $HexValue"
        if ($AsDecimal) { [Convert]::ToInt64($HexValue, 16) } elseif ($AsDrawingColor) { [System.Drawing.Color]::FromArgb("#$($HexValue)") } else { "#$($HexValue)" }
    }
    $Colors
}
function Get-FileName {
    <#
    .SYNOPSIS
    Short description
 
    .DESCRIPTION
    Long description
 
    .PARAMETER Extension
    Parameter description
 
    .PARAMETER Temporary
    Parameter description
 
    .PARAMETER TemporaryFileOnly
    Parameter description
 
    .EXAMPLE
    Get-FileName -Temporary
    Output: 3ymsxvav.tmp
 
    .EXAMPLE
 
    Get-FileName -Temporary
    Output: C:\Users\pklys\AppData\Local\Temp\tmpD74C.tmp
 
    .EXAMPLE
 
    Get-FileName -Temporary -Extension 'xlsx'
    Output: C:\Users\pklys\AppData\Local\Temp\tmp45B6.xlsx
 
 
    .NOTES
    General notes
    #>

    [CmdletBinding()]
    param([string] $Extension = 'tmp',
        [switch] $Temporary,
        [switch] $TemporaryFileOnly)
    if ($Temporary) { return [io.path]::Combine([System.IO.Path]::GetTempPath(), "$($([System.IO.Path]::GetRandomFileName()).Split('.')[0]).$Extension") }
    if ($TemporaryFileOnly) { return "$($([System.IO.Path]::GetRandomFileName()).Split('.')[0]).$Extension" }
}
function Get-RandomStringName {
    [cmdletbinding()]
    param([int] $Size = 31,
        [switch] $ToLower,
        [switch] $ToUpper,
        [switch] $LettersOnly)
    [string] $MyValue = @(if ($LettersOnly) { ( -join ((1..$Size) | ForEach-Object { (65..90) + (97..122) | Get-Random } | ForEach-Object { [char]$_ })) } else { ( -join ((48..57) + (97..122) | Get-Random -Count $Size | ForEach-Object { [char]$_ })) })
    if ($ToLower) { return $MyValue.ToLower() }
    if ($ToUpper) { return $MyValue.ToUpper() }
    return $MyValue
}
function Remove-EmptyValue {
    [alias('Remove-EmptyValues')]
    [CmdletBinding()]
    param([alias('Splat', 'IDictionary')][Parameter(Mandatory)][System.Collections.IDictionary] $Hashtable,
        [string[]] $ExcludeParameter,
        [switch] $Recursive,
        [int] $Rerun,
        [switch] $DoNotRemoveNull,
        [switch] $DoNotRemoveEmpty,
        [switch] $DoNotRemoveEmptyArray,
        [switch] $DoNotRemoveEmptyDictionary)
    foreach ($Key in [string[]] $Hashtable.Keys) { if ($Key -notin $ExcludeParameter) { if ($Recursive) { if ($Hashtable[$Key] -is [System.Collections.IDictionary]) { if ($Hashtable[$Key].Count -eq 0) { if (-not $DoNotRemoveEmptyDictionary) { $Hashtable.Remove($Key) } } else { Remove-EmptyValue -Hashtable $Hashtable[$Key] -Recursive:$Recursive } } else { if (-not $DoNotRemoveNull -and $null -eq $Hashtable[$Key]) { $Hashtable.Remove($Key) } elseif (-not $DoNotRemoveEmpty -and $Hashtable[$Key] -is [string] -and $Hashtable[$Key] -eq '') { $Hashtable.Remove($Key) } elseif (-not $DoNotRemoveEmptyArray -and $Hashtable[$Key] -is [System.Collections.IList] -and $Hashtable[$Key].Count -eq 0) { $Hashtable.Remove($Key) } } } else { if (-not $DoNotRemoveNull -and $null -eq $Hashtable[$Key]) { $Hashtable.Remove($Key) } elseif (-not $DoNotRemoveEmpty -and $Hashtable[$Key] -is [string] -and $Hashtable[$Key] -eq '') { $Hashtable.Remove($Key) } elseif (-not $DoNotRemoveEmptyArray -and $Hashtable[$Key] -is [System.Collections.IList] -and $Hashtable[$Key].Count -eq 0) { $Hashtable.Remove($Key) } } } }
    if ($Rerun) { for ($i = 0; $i -lt $Rerun; $i++) { Remove-EmptyValue -Hashtable $Hashtable -Recursive:$Recursive } }
}
function Select-Properties {
    <#
    .SYNOPSIS
    Allows for easy selecting property names from one or multiple objects
 
    .DESCRIPTION
    Allows for easy selecting property names from one or multiple objects. This is especially useful with using AllProperties parameter where we want to make sure to get all properties from all objects.
 
    .PARAMETER Objects
    One or more objects
 
    .PARAMETER Property
    Properties to include
 
    .PARAMETER ExcludeProperty
    Properties to exclude
 
    .PARAMETER AllProperties
    All unique properties from all objects
 
    .PARAMETER PropertyNameReplacement
    Default property name when object has no properties
 
    .EXAMPLE
    $Object1 = [PSCustomobject] @{
        Name1 = '1'
        Name2 = '3'
        Name3 = '5'
    }
    $Object2 = [PSCustomobject] @{
        Name4 = '2'
        Name5 = '6'
        Name6 = '7'
    }
 
    Select-Properties -Objects $Object1, $Object2 -AllProperties
 
    #OR:
 
    $Object1, $Object2 | Select-Properties -AllProperties -ExcludeProperty Name6 -Property Name3
 
    .EXAMPLE
    $Object3 = [Ordered] @{
        Name1 = '1'
        Name2 = '3'
        Name3 = '5'
    }
    $Object4 = [Ordered] @{
        Name4 = '2'
        Name5 = '6'
        Name6 = '7'
    }
 
    Select-Properties -Objects $Object3, $Object4 -AllProperties
 
    $Object3, $Object4 | Select-Properties -AllProperties
 
    .NOTES
    General notes
    #>

    [CmdLetBinding()]
    param([Array][Parameter(Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)] $Objects,
        [string[]] $Property,
        [string[]] $ExcludeProperty,
        [switch] $AllProperties,
        [string] $PropertyNameReplacement = '*')
    Begin {
        function Select-Unique {
            [CmdLetBinding()]
            param([System.Collections.IList] $Object)
            $New = $Object.ToLower() | Select-Object -Unique
            $Selected = foreach ($_ in $New) {
                $Index = $Object.ToLower().IndexOf($_)
                if ($Index -ne -1) { $Object[$Index] }
            }
            $Selected
        }
        $ObjectsList = [System.Collections.Generic.List[Object]]::new()
    }
    Process { foreach ($Object in $Objects) { $ObjectsList.Add($Object) } }
    End {
        if ($ObjectsList.Count -eq 0) {
            Write-Warning 'Select-Properties - Unable to process. Objects count equals 0.'
            return
        }
        if ($ObjectsList[0] -is [System.Collections.IDictionary]) {
            if ($AllProperties) {
                [Array] $All = foreach ($_ in $ObjectsList) { $_.Keys }
                $FirstObjectProperties = Select-Unique -Object $All
            } else { $FirstObjectProperties = $ObjectsList[0].Keys }
            if ($Property.Count -gt 0 -and $ExcludeProperty.Count -gt 0) {
                $FirstObjectProperties = foreach ($_ in $FirstObjectProperties) {
                    if ($Property -contains $_ -and $ExcludeProperty -notcontains $_) {
                        $_
                        continue
                    }
                }
            } elseif ($Property.Count -gt 0) {
                $FirstObjectProperties = foreach ($_ in $FirstObjectProperties) {
                    if ($Property -contains $_) {
                        $_
                        continue
                    }
                }
            } elseif ($ExcludeProperty.Count -gt 0) {
                $FirstObjectProperties = foreach ($_ in $FirstObjectProperties) {
                    if ($ExcludeProperty -notcontains $_) {
                        $_
                        continue
                    }
                }
            }
        } elseif ($ObjectsList[0].GetType().Name -match 'bool|byte|char|datetime|decimal|double|ExcelHyperLink|float|int|long|sbyte|short|string|timespan|uint|ulong|URI|ushort') { $FirstObjectProperties = $PropertyNameReplacement } else {
            if ($Property.Count -gt 0 -and $ExcludeProperty.Count -gt 0) { $ObjectsList = $ObjectsList | Select-Object -Property $Property -ExcludeProperty $ExcludeProperty } elseif ($Property.Count -gt 0) { $ObjectsList = $ObjectsList | Select-Object -Property $Property } elseif ($ExcludeProperty.Count -gt 0) { $ObjectsList = $ObjectsList | Select-Object -Property '*' -ExcludeProperty $ExcludeProperty }
            if ($AllProperties) {
                [Array] $All = foreach ($_ in $ObjectsList) { $_.PSObject.Properties.Name }
                $FirstObjectProperties = Select-Unique -Object $All
            } else { $FirstObjectProperties = $ObjectsList[0].PSObject.Properties.Name }
        }
        $FirstObjectProperties
    }
}
function Convert-Color {
    <#
    .Synopsis
    This color converter gives you the hexadecimal values of your RGB colors and vice versa (RGB to HEX)
    .Description
    This color converter gives you the hexadecimal values of your RGB colors and vice versa (RGB to HEX). Use it to convert your colors and prepare your graphics and HTML web pages.
    .Parameter RBG
    Enter the Red Green Blue value comma separated. Red: 51 Green: 51 Blue: 204 for example needs to be entered as 51,51,204
    .Parameter HEX
    Enter the Hex value to be converted. Do not use the '#' symbol. (Ex: 3333CC converts to Red: 51 Green: 51 Blue: 204)
    .Example
    .\convert-color -hex FFFFFF
    Converts hex value FFFFFF to RGB
 
    .Example
    .\convert-color -RGB 123,200,255
    Converts Red = 123 Green = 200 Blue = 255 to Hex value
 
    #>

    param([Parameter(ParameterSetName = "RGB", Position = 0)]
        [ValidateScript({ $_ -match '^([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])$' })]
        $RGB,
        [Parameter(ParameterSetName = "HEX", Position = 0)]
        [ValidateScript({ $_ -match '[A-Fa-f0-9]{6}' })]
        [string]
        $HEX)
    switch ($PsCmdlet.ParameterSetName) {
        "RGB" {
            if ($null -eq $RGB[2]) { Write-Error "Value missing. Please enter all three values seperated by comma." }
            $red = [convert]::Tostring($RGB[0], 16)
            $green = [convert]::Tostring($RGB[1], 16)
            $blue = [convert]::Tostring($RGB[2], 16)
            if ($red.Length -eq 1) { $red = '0' + $red }
            if ($green.Length -eq 1) { $green = '0' + $green }
            if ($blue.Length -eq 1) { $blue = '0' + $blue }
            Write-Output $red$green$blue
        }
        "HEX" {
            $red = $HEX.Remove(2, 4)
            $Green = $HEX.Remove(4, 2)
            $Green = $Green.remove(0, 2)
            $Blue = $hex.Remove(0, 4)
            $Red = [convert]::ToInt32($red, 16)
            $Green = [convert]::ToInt32($green, 16)
            $Blue = [convert]::ToInt32($blue, 16)
            Write-Output $red, $Green, $blue
        }
    }
}
$Script:RGBColors = [ordered] @{None = $null
    AirForceBlue                     = 93, 138, 168
    Akaroa                           = 195, 176, 145
    AlbescentWhite                   = 227, 218, 201
    AliceBlue                        = 240, 248, 255
    Alizarin                         = 227, 38, 54
    Allports                         = 18, 97, 128
    Almond                           = 239, 222, 205
    AlmondFrost                      = 159, 129, 112
    Amaranth                         = 229, 43, 80
    Amazon                           = 59, 122, 87
    Amber                            = 255, 191, 0
    Amethyst                         = 153, 102, 204
    AmethystSmoke                    = 156, 138, 164
    AntiqueWhite                     = 250, 235, 215
    Apple                            = 102, 180, 71
    AppleBlossom                     = 176, 92, 82
    Apricot                          = 251, 206, 177
    Aqua                             = 0, 255, 255
    Aquamarine                       = 127, 255, 212
    Armygreen                        = 75, 83, 32
    Arsenic                          = 59, 68, 75
    Astral                           = 54, 117, 136
    Atlantis                         = 164, 198, 57
    Atomic                           = 65, 74, 76
    AtomicTangerine                  = 255, 153, 102
    Axolotl                          = 99, 119, 91
    Azure                            = 240, 255, 255
    Bahia                            = 176, 191, 26
    BakersChocolate                  = 93, 58, 26
    BaliHai                          = 124, 152, 171
    BananaMania                      = 250, 231, 181
    BattleshipGrey                   = 85, 93, 80
    BayOfMany                        = 35, 48, 103
    Beige                            = 245, 245, 220
    Bermuda                          = 136, 216, 192
    Bilbao                           = 42, 128, 0
    BilobaFlower                     = 181, 126, 220
    Bismark                          = 83, 104, 114
    Bisque                           = 255, 228, 196
    Bistre                           = 61, 43, 31
    Bittersweet                      = 254, 111, 94
    Black                            = 0, 0, 0
    BlackPearl                       = 31, 38, 42
    BlackRose                        = 85, 31, 47
    BlackRussian                     = 23, 24, 43
    BlanchedAlmond                   = 255, 235, 205
    BlizzardBlue                     = 172, 229, 238
    Blue                             = 0, 0, 255
    BlueDiamond                      = 77, 26, 127
    BlueMarguerite                   = 115, 102, 189
    BlueSmoke                        = 115, 130, 118
    BlueViolet                       = 138, 43, 226
    Blush                            = 169, 92, 104
    BokaraGrey                       = 22, 17, 13
    Bole                             = 121, 68, 59
    BondiBlue                        = 0, 147, 175
    Bordeaux                         = 88, 17, 26
    Bossanova                        = 86, 60, 92
    Boulder                          = 114, 116, 114
    Bouquet                          = 183, 132, 167
    Bourbon                          = 170, 108, 57
    Brass                            = 181, 166, 66
    BrickRed                         = 199, 44, 72
    BrightGreen                      = 102, 255, 0
    BrightRed                        = 146, 43, 62
    BrightTurquoise                  = 8, 232, 222
    BrilliantRose                    = 243, 100, 162
    BrinkPink                        = 250, 110, 121
    BritishRacingGreen               = 0, 66, 37
    Bronze                           = 205, 127, 50
    Brown                            = 165, 42, 42
    BrownPod                         = 57, 24, 2
    BuddhaGold                       = 202, 169, 6
    Buff                             = 240, 220, 130
    Burgundy                         = 128, 0, 32
    BurlyWood                        = 222, 184, 135
    BurntOrange                      = 255, 117, 56
    BurntSienna                      = 233, 116, 81
    BurntUmber                       = 138, 51, 36
    ButteredRum                      = 156, 124, 56
    CadetBlue                        = 95, 158, 160
    California                       = 224, 141, 60
    CamouflageGreen                  = 120, 134, 107
    Canary                           = 255, 255, 153
    CanCan                           = 217, 134, 149
    CannonPink                       = 145, 78, 117
    CaputMortuum                     = 89, 39, 32
    Caramel                          = 255, 213, 154
    Cararra                          = 237, 230, 214
    Cardinal                         = 179, 33, 52
    CardinGreen                      = 18, 53, 36
    CareysPink                       = 217, 152, 160
    CaribbeanGreen                   = 0, 222, 164
    Carmine                          = 175, 0, 42
    CarnationPink                    = 255, 166, 201
    CarrotOrange                     = 242, 142, 28
    Cascade                          = 141, 163, 153
    CatskillWhite                    = 226, 229, 222
    Cedar                            = 67, 48, 46
    Celadon                          = 172, 225, 175
    Celeste                          = 207, 207, 196
    Cello                            = 55, 79, 107
    Cement                           = 138, 121, 93
    Cerise                           = 222, 49, 99
    Cerulean                         = 0, 123, 167
    CeruleanBlue                     = 42, 82, 190
    Chantilly                        = 239, 187, 204
    Chardonnay                       = 255, 200, 124
    Charlotte                        = 167, 216, 222
    Charm                            = 208, 116, 139
    Chartreuse                       = 127, 255, 0
    ChartreuseYellow                 = 223, 255, 0
    ChelseaCucumber                  = 135, 169, 107
    Cherub                           = 246, 214, 222
    Chestnut                         = 185, 78, 72
    ChileanFire                      = 226, 88, 34
    Chinook                          = 150, 200, 162
    Chocolate                        = 210, 105, 30
    Christi                          = 125, 183, 0
    Christine                        = 181, 101, 30
    Cinnabar                         = 235, 76, 66
    Citron                           = 159, 169, 31
    Citrus                           = 141, 182, 0
    Claret                           = 95, 25, 51
    ClassicRose                      = 251, 204, 231
    ClayCreek                        = 145, 129, 81
    Clinker                          = 75, 54, 33
    Clover                           = 74, 93, 35
    Cobalt                           = 0, 71, 171
    CocoaBrown                       = 44, 22, 8
    Cola                             = 60, 48, 36
    ColumbiaBlue                     = 166, 231, 255
    CongoBrown                       = 103, 76, 71
    Conifer                          = 178, 236, 93
    Copper                           = 218, 138, 103
    CopperRose                       = 153, 102, 102
    Coral                            = 255, 127, 80
    CoralRed                         = 255, 64, 64
    CoralTree                        = 173, 111, 105
    Coriander                        = 188, 184, 138
    Corn                             = 251, 236, 93
    CornField                        = 250, 240, 190
    Cornflower                       = 147, 204, 234
    CornflowerBlue                   = 100, 149, 237
    Cornsilk                         = 255, 248, 220
    Cosmic                           = 132, 63, 91
    Cosmos                           = 255, 204, 203
    CostaDelSol                      = 102, 93, 30
    CottonCandy                      = 255, 188, 217
    Crail                            = 164, 90, 82
    Cranberry                        = 205, 96, 126
    Cream                            = 255, 255, 204
    CreamCan                         = 242, 198, 73
    Crimson                          = 220, 20, 60
    Crusta                           = 232, 142, 90
    Cumulus                          = 255, 255, 191
    Cupid                            = 246, 173, 198
    CuriousBlue                      = 40, 135, 200
    Cyan                             = 0, 255, 255
    Cyprus                           = 6, 78, 64
    DaisyBush                        = 85, 53, 146
    Dandelion                        = 250, 218, 94
    Danube                           = 96, 130, 182
    DarkBlue                         = 0, 0, 139
    DarkBrown                        = 101, 67, 33
    DarkCerulean                     = 8, 69, 126
    DarkChestnut                     = 152, 105, 96
    DarkCoral                        = 201, 90, 73
    DarkCyan                         = 0, 139, 139
    DarkGoldenrod                    = 184, 134, 11
    DarkGray                         = 169, 169, 169
    DarkGreen                        = 0, 100, 0
    DarkGreenCopper                  = 73, 121, 107
    DarkGrey                         = 169, 169, 169
    DarkKhaki                        = 189, 183, 107
    DarkMagenta                      = 139, 0, 139
    DarkOliveGreen                   = 85, 107, 47
    DarkOrange                       = 255, 140, 0
    DarkOrchid                       = 153, 50, 204
    DarkPastelGreen                  = 3, 192, 60
    DarkPink                         = 222, 93, 131
    DarkPurple                       = 150, 61, 127
    DarkRed                          = 139, 0, 0
    DarkSalmon                       = 233, 150, 122
    DarkSeaGreen                     = 143, 188, 143
    DarkSlateBlue                    = 72, 61, 139
    DarkSlateGray                    = 47, 79, 79
    DarkSlateGrey                    = 47, 79, 79
    DarkSpringGreen                  = 23, 114, 69
    DarkTangerine                    = 255, 170, 29
    DarkTurquoise                    = 0, 206, 209
    DarkViolet                       = 148, 0, 211
    DarkWood                         = 130, 102, 68
    DeepBlush                        = 245, 105, 145
    DeepCerise                       = 224, 33, 138
    DeepKoamaru                      = 51, 51, 102
    DeepLilac                        = 153, 85, 187
    DeepMagenta                      = 204, 0, 204
    DeepPink                         = 255, 20, 147
    DeepSea                          = 14, 124, 97
    DeepSkyBlue                      = 0, 191, 255
    DeepTeal                         = 24, 69, 59
    Denim                            = 36, 107, 206
    DesertSand                       = 237, 201, 175
    DimGray                          = 105, 105, 105
    DimGrey                          = 105, 105, 105
    DodgerBlue                       = 30, 144, 255
    Dolly                            = 242, 242, 122
    Downy                            = 95, 201, 191
    DutchWhite                       = 239, 223, 187
    EastBay                          = 76, 81, 109
    EastSide                         = 178, 132, 190
    EchoBlue                         = 169, 178, 195
    Ecru                             = 194, 178, 128
    Eggplant                         = 162, 0, 109
    EgyptianBlue                     = 16, 52, 166
    ElectricBlue                     = 125, 249, 255
    ElectricIndigo                   = 111, 0, 255
    ElectricLime                     = 208, 255, 20
    ElectricPurple                   = 191, 0, 255
    Elm                              = 47, 132, 124
    Emerald                          = 80, 200, 120
    Eminence                         = 108, 48, 130
    Endeavour                        = 46, 88, 148
    EnergyYellow                     = 245, 224, 80
    Espresso                         = 74, 44, 42
    Eucalyptus                       = 26, 162, 96
    Falcon                           = 126, 94, 96
    Fallow                           = 204, 153, 102
    FaluRed                          = 128, 24, 24
    Feldgrau                         = 77, 93, 83
    Feldspar                         = 205, 149, 117
    Fern                             = 113, 188, 120
    FernGreen                        = 79, 121, 66
    Festival                         = 236, 213, 64
    Finn                             = 97, 64, 81
    FireBrick                        = 178, 34, 34
    FireBush                         = 222, 143, 78
    FireEngineRed                    = 211, 33, 45
    Flamingo                         = 233, 92, 75
    Flax                             = 238, 220, 130
    FloralWhite                      = 255, 250, 240
    ForestGreen                      = 34, 139, 34
    Frangipani                       = 250, 214, 165
    FreeSpeechAquamarine             = 0, 168, 119
    FreeSpeechRed                    = 204, 0, 0
    FrenchLilac                      = 230, 168, 215
    FrenchRose                       = 232, 83, 149
    FriarGrey                        = 135, 134, 129
    Froly                            = 228, 113, 122
    Fuchsia                          = 255, 0, 255
    FuchsiaPink                      = 255, 119, 255
    Gainsboro                        = 220, 220, 220
    Gallery                          = 219, 215, 210
    Galliano                         = 204, 160, 29
    Gamboge                          = 204, 153, 0
    Ghost                            = 196, 195, 208
    GhostWhite                       = 248, 248, 255
    Gin                              = 216, 228, 188
    GinFizz                          = 247, 231, 206
    Givry                            = 230, 208, 171
    Glacier                          = 115, 169, 194
    Gold                             = 255, 215, 0
    GoldDrop                         = 213, 108, 43
    GoldenBrown                      = 150, 113, 23
    GoldenFizz                       = 240, 225, 48
    GoldenGlow                       = 248, 222, 126
    GoldenPoppy                      = 252, 194, 0
    Goldenrod                        = 218, 165, 32
    GoldenSand                       = 233, 214, 107
    GoldenYellow                     = 253, 238, 0
    GoldTips                         = 225, 189, 39
    GordonsGreen                     = 37, 53, 41
    Gorse                            = 255, 225, 53
    Gossamer                         = 49, 145, 119
    GrannySmithApple                 = 168, 228, 160
    Gray                             = 128, 128, 128
    GrayAsparagus                    = 70, 89, 69
    Green                            = 0, 128, 0
    GreenLeaf                        = 76, 114, 29
    GreenVogue                       = 38, 67, 72
    GreenYellow                      = 173, 255, 47
    Grey                             = 128, 128, 128
    GreyAsparagus                    = 70, 89, 69
    GuardsmanRed                     = 157, 41, 51
    GumLeaf                          = 178, 190, 181
    Gunmetal                         = 42, 52, 57
    Hacienda                         = 155, 135, 12
    HalfAndHalf                      = 232, 228, 201
    HalfBaked                        = 95, 138, 139
    HalfColonialWhite                = 246, 234, 190
    HalfPearlLusta                   = 240, 234, 214
    HanPurple                        = 63, 0, 255
    Harlequin                        = 74, 255, 0
    HarleyDavidsonOrange             = 194, 59, 34
    Heather                          = 174, 198, 207
    Heliotrope                       = 223, 115, 255
    Hemp                             = 161, 122, 116
    Highball                         = 134, 126, 54
    HippiePink                       = 171, 75, 82
    Hoki                             = 110, 127, 128
    HollywoodCerise                  = 244, 0, 161
    Honeydew                         = 240, 255, 240
    Hopbush                          = 207, 113, 175
    HorsesNeck                       = 108, 84, 30
    HotPink                          = 255, 105, 180
    HummingBird                      = 201, 255, 229
    HunterGreen                      = 53, 94, 59
    Illusion                         = 244, 152, 173
    InchWorm                         = 202, 224, 13
    IndianRed                        = 205, 92, 92
    Indigo                           = 75, 0, 130
    InternationalKleinBlue           = 0, 24, 168
    InternationalOrange              = 255, 79, 0
    IrisBlue                         = 28, 169, 201
    IrishCoffee                      = 102, 66, 40
    IronsideGrey                     = 113, 112, 110
    IslamicGreen                     = 0, 144, 0
    Ivory                            = 255, 255, 240
    Jacarta                          = 61, 50, 93
    JackoBean                        = 65, 54, 40
    JacksonsPurple                   = 46, 45, 136
    Jade                             = 0, 171, 102
    JapaneseLaurel                   = 47, 117, 50
    Jazz                             = 93, 43, 44
    JazzberryJam                     = 165, 11, 94
    JellyBean                        = 68, 121, 142
    JetStream                        = 187, 208, 201
    Jewel                            = 0, 107, 60
    Jon                              = 79, 58, 60
    JordyBlue                        = 124, 185, 232
    Jumbo                            = 132, 132, 130
    JungleGreen                      = 41, 171, 135
    KaitokeGreen                     = 30, 77, 43
    Karry                            = 255, 221, 202
    KellyGreen                       = 70, 203, 24
    Keppel                           = 93, 164, 147
    Khaki                            = 240, 230, 140
    Killarney                        = 77, 140, 87
    KingfisherDaisy                  = 85, 27, 140
    Kobi                             = 230, 143, 172
    LaPalma                          = 60, 141, 13
    LaserLemon                       = 252, 247, 94
    Laurel                           = 103, 146, 103
    Lavender                         = 230, 230, 250
    LavenderBlue                     = 204, 204, 255
    LavenderBlush                    = 255, 240, 245
    LavenderPink                     = 251, 174, 210
    LavenderRose                     = 251, 160, 227
    LawnGreen                        = 124, 252, 0
    LemonChiffon                     = 255, 250, 205
    LightBlue                        = 173, 216, 230
    LightCoral                       = 240, 128, 128
    LightCyan                        = 224, 255, 255
    LightGoldenrodYellow             = 250, 250, 210
    LightGray                        = 211, 211, 211
    LightGreen                       = 144, 238, 144
    LightGrey                        = 211, 211, 211
    LightPink                        = 255, 182, 193
    LightSalmon                      = 255, 160, 122
    LightSeaGreen                    = 32, 178, 170
    LightSkyBlue                     = 135, 206, 250
    LightSlateGray                   = 119, 136, 153
    LightSlateGrey                   = 119, 136, 153
    LightSteelBlue                   = 176, 196, 222
    LightYellow                      = 255, 255, 224
    Lilac                            = 204, 153, 204
    Lime                             = 0, 255, 0
    LimeGreen                        = 50, 205, 50
    Limerick                         = 139, 190, 27
    Linen                            = 250, 240, 230
    Lipstick                         = 159, 43, 104
    Liver                            = 83, 75, 79
    Lochinvar                        = 86, 136, 125
    Lochmara                         = 38, 97, 156
    Lola                             = 179, 158, 181
    LondonHue                        = 170, 152, 169
    Lotus                            = 124, 72, 72
    LuckyPoint                       = 29, 41, 81
    MacaroniAndCheese                = 255, 189, 136
    Madang                           = 193, 249, 162
    Madras                           = 81, 65, 0
    Magenta                          = 255, 0, 255
    MagicMint                        = 170, 240, 209
    Magnolia                         = 248, 244, 255
    Mahogany                         = 215, 59, 62
    Maire                            = 27, 24, 17
    Maize                            = 230, 190, 138
    Malachite                        = 11, 218, 81
    Malibu                           = 93, 173, 236
    Malta                            = 169, 154, 134
    Manatee                          = 140, 146, 172
    Mandalay                         = 176, 121, 57
    MandarianOrange                  = 146, 39, 36
    Mandy                            = 191, 79, 81
    Manhattan                        = 229, 170, 112
    Mantis                           = 125, 194, 66
    Manz                             = 217, 230, 80
    MardiGras                        = 48, 25, 52
    Mariner                          = 57, 86, 156
    Maroon                           = 128, 0, 0
    Matterhorn                       = 85, 85, 85
    Mauve                            = 244, 187, 255
    Mauvelous                        = 255, 145, 175
    MauveTaupe                       = 143, 89, 115
    MayaBlue                         = 119, 181, 254
    McKenzie                         = 129, 97, 60
    MediumAquamarine                 = 102, 205, 170
    MediumBlue                       = 0, 0, 205
    MediumCarmine                    = 175, 64, 53
    MediumOrchid                     = 186, 85, 211
    MediumPurple                     = 147, 112, 219
    MediumRedViolet                  = 189, 51, 164
    MediumSeaGreen                   = 60, 179, 113
    MediumSlateBlue                  = 123, 104, 238
    MediumSpringGreen                = 0, 250, 154
    MediumTurquoise                  = 72, 209, 204
    MediumVioletRed                  = 199, 21, 133
    MediumWood                       = 166, 123, 91
    Melon                            = 253, 188, 180
    Merlot                           = 112, 54, 66
    MetallicGold                     = 211, 175, 55
    Meteor                           = 184, 115, 51
    MidnightBlue                     = 25, 25, 112
    MidnightExpress                  = 0, 20, 64
    Mikado                           = 60, 52, 31
    MilanoRed                        = 168, 55, 49
    Ming                             = 54, 116, 125
    MintCream                        = 245, 255, 250
    MintGreen                        = 152, 255, 152
    Mischka                          = 168, 169, 173
    MistyRose                        = 255, 228, 225
    Moccasin                         = 255, 228, 181
    Mojo                             = 149, 69, 53
    MonaLisa                         = 255, 153, 153
    Mongoose                         = 179, 139, 109
    Montana                          = 53, 56, 57
    MoodyBlue                        = 116, 108, 192
    MoonYellow                       = 245, 199, 26
    MossGreen                        = 173, 223, 173
    MountainMeadow                   = 28, 172, 120
    MountainMist                     = 161, 157, 148
    MountbattenPink                  = 153, 122, 141
    Mulberry                         = 211, 65, 157
    Mustard                          = 255, 219, 88
    Myrtle                           = 25, 89, 5
    MySin                            = 255, 179, 71
    NavajoWhite                      = 255, 222, 173
    Navy                             = 0, 0, 128
    NavyBlue                         = 2, 71, 254
    NeonCarrot                       = 255, 153, 51
    NeonPink                         = 255, 92, 205
    Nepal                            = 145, 163, 176
    Nero                             = 20, 20, 20
    NewMidnightBlue                  = 0, 0, 156
    Niagara                          = 58, 176, 158
    NightRider                       = 59, 47, 47
    Nobel                            = 152, 152, 152
    Norway                           = 169, 186, 157
    Nugget                           = 183, 135, 39
    OceanGreen                       = 95, 167, 120
    Ochre                            = 202, 115, 9
    OldCopper                        = 111, 78, 55
    OldGold                          = 207, 181, 59
    OldLace                          = 253, 245, 230
    OldLavender                      = 121, 104, 120
    OldRose                          = 195, 33, 72
    Olive                            = 128, 128, 0
    OliveDrab                        = 107, 142, 35
    OliveGreen                       = 181, 179, 92
    Olivetone                        = 110, 110, 48
    Olivine                          = 154, 185, 115
    Onahau                           = 196, 216, 226
    Opal                             = 168, 195, 188
    Orange                           = 255, 165, 0
    OrangePeel                       = 251, 153, 2
    OrangeRed                        = 255, 69, 0
    Orchid                           = 218, 112, 214
    OuterSpace                       = 45, 56, 58
    OutrageousOrange                 = 254, 90, 29
    Oxley                            = 95, 167, 119
    PacificBlue                      = 0, 136, 220
    Padua                            = 128, 193, 151
    PalatinatePurple                 = 112, 41, 99
    PaleBrown                        = 160, 120, 90
    PaleChestnut                     = 221, 173, 175
    PaleCornflowerBlue               = 188, 212, 230
    PaleGoldenrod                    = 238, 232, 170
    PaleGreen                        = 152, 251, 152
    PaleMagenta                      = 249, 132, 239
    PalePink                         = 250, 218, 221
    PaleSlate                        = 201, 192, 187
    PaleTaupe                        = 188, 152, 126
    PaleTurquoise                    = 175, 238, 238
    PaleVioletRed                    = 219, 112, 147
    PalmLeaf                         = 53, 66, 48
    Panache                          = 233, 255, 219
    PapayaWhip                       = 255, 239, 213
    ParisDaisy                       = 255, 244, 79
    Parsley                          = 48, 96, 48
    PastelGreen                      = 119, 221, 119
    PattensBlue                      = 219, 233, 244
    Peach                            = 255, 203, 164
    PeachOrange                      = 255, 204, 153
    PeachPuff                        = 255, 218, 185
    PeachYellow                      = 250, 223, 173
    Pear                             = 209, 226, 49
    PearlLusta                       = 234, 224, 200
    Pelorous                         = 42, 143, 189
    Perano                           = 172, 172, 230
    Periwinkle                       = 197, 203, 225
    PersianBlue                      = 34, 67, 182
    PersianGreen                     = 0, 166, 147
    PersianIndigo                    = 51, 0, 102
    PersianPink                      = 247, 127, 190
    PersianRed                       = 192, 54, 44
    PersianRose                      = 233, 54, 167
    Persimmon                        = 236, 88, 0
    Peru                             = 205, 133, 63
    Pesto                            = 128, 117, 50
    PictonBlue                       = 102, 153, 204
    PigmentGreen                     = 0, 173, 67
    PigPink                          = 255, 218, 233
    PineGreen                        = 1, 121, 111
    PineTree                         = 42, 47, 35
    Pink                             = 255, 192, 203
    PinkFlare                        = 191, 175, 178
    PinkLace                         = 240, 211, 220
    PinkSwan                         = 179, 179, 179
    Plum                             = 221, 160, 221
    Pohutukawa                       = 102, 12, 33
    PoloBlue                         = 119, 158, 203
    Pompadour                        = 129, 20, 83
    Portage                          = 146, 161, 207
    PotPourri                        = 241, 221, 207
    PottersClay                      = 132, 86, 60
    PowderBlue                       = 176, 224, 230
    Prim                             = 228, 196, 207
    PrussianBlue                     = 0, 58, 108
    PsychedelicPurple                = 223, 0, 255
    Puce                             = 204, 136, 153
    Pueblo                           = 108, 46, 31
    PuertoRico                       = 67, 179, 174
    Pumpkin                          = 255, 99, 28
    Purple                           = 128, 0, 128
    PurpleMountainsMajesty           = 150, 123, 182
    PurpleTaupe                      = 93, 57, 84
    QuarterSpanishWhite              = 230, 224, 212
    Quartz                           = 220, 208, 255
    Quincy                           = 106, 84, 69
    RacingGreen                      = 26, 36, 33
    RadicalRed                       = 255, 32, 82
    Rajah                            = 251, 171, 96
    RawUmber                         = 123, 63, 0
    RazzleDazzleRose                 = 254, 78, 218
    Razzmatazz                       = 215, 10, 83
    Red                              = 255, 0, 0
    RedBerry                         = 132, 22, 23
    RedDamask                        = 203, 109, 81
    RedOxide                         = 99, 15, 15
    RedRobin                         = 128, 64, 64
    RichBlue                         = 84, 90, 167
    Riptide                          = 141, 217, 204
    RobinsEggBlue                    = 0, 204, 204
    RobRoy                           = 225, 169, 95
    RockSpray                        = 171, 56, 31
    RomanCoffee                      = 131, 105, 83
    RoseBud                          = 246, 164, 148
    RoseBudCherry                    = 135, 50, 96
    RoseTaupe                        = 144, 93, 93
    RosyBrown                        = 188, 143, 143
    Rouge                            = 176, 48, 96
    RoyalBlue                        = 65, 105, 225
    RoyalHeath                       = 168, 81, 110
    RoyalPurple                      = 102, 51, 152
    Ruby                             = 215, 24, 104
    Russet                           = 128, 70, 27
    Rust                             = 192, 64, 0
    RusticRed                        = 72, 6, 7
    Saddle                           = 99, 81, 71
    SaddleBrown                      = 139, 69, 19
    SafetyOrange                     = 255, 102, 0
    Saffron                          = 244, 196, 48
    Sage                             = 143, 151, 121
    Sail                             = 161, 202, 241
    Salem                            = 0, 133, 67
    Salmon                           = 250, 128, 114
    SandyBeach                       = 253, 213, 177
    SandyBrown                       = 244, 164, 96
    Sangria                          = 134, 1, 17
    SanguineBrown                    = 115, 54, 53
    SanMarino                        = 80, 114, 167
    SanteFe                          = 175, 110, 77
    Sapphire                         = 6, 42, 120
    Saratoga                         = 84, 90, 44
    Scampi                           = 102, 102, 153
    Scarlet                          = 255, 36, 0
    ScarletGum                       = 67, 28, 83
    SchoolBusYellow                  = 255, 216, 0
    Schooner                         = 139, 134, 128
    ScreaminGreen                    = 102, 255, 102
    Scrub                            = 59, 60, 54
    SeaBuckthorn                     = 249, 146, 69
    SeaGreen                         = 46, 139, 87
    Seagull                          = 140, 190, 214
    SealBrown                        = 61, 12, 2
    Seance                           = 96, 47, 107
    SeaPink                          = 215, 131, 127
    SeaShell                         = 255, 245, 238
    Selago                           = 250, 230, 250
    SelectiveYellow                  = 242, 180, 0
    SemiSweetChocolate               = 107, 68, 35
    Sepia                            = 150, 90, 62
    Serenade                         = 255, 233, 209
    Shadow                           = 133, 109, 77
    Shakespeare                      = 114, 160, 193
    Shalimar                         = 252, 255, 164
    Shamrock                         = 68, 215, 168
    ShamrockGreen                    = 0, 153, 102
    SherpaBlue                       = 0, 75, 73
    SherwoodGreen                    = 27, 77, 62
    Shilo                            = 222, 165, 164
    ShipCove                         = 119, 139, 165
    Shocking                         = 241, 156, 187
    ShockingPink                     = 255, 29, 206
    ShuttleGrey                      = 84, 98, 111
    Sidecar                          = 238, 224, 177
    Sienna                           = 160, 82, 45
    Silk                             = 190, 164, 147
    Silver                           = 192, 192, 192
    SilverChalice                    = 175, 177, 174
    SilverTree                       = 102, 201, 146
    SkyBlue                          = 135, 206, 235
    SlateBlue                        = 106, 90, 205
    SlateGray                        = 112, 128, 144
    SlateGrey                        = 112, 128, 144
    Smalt                            = 0, 48, 143
    SmaltBlue                        = 74, 100, 108
    Snow                             = 255, 250, 250
    SoftAmber                        = 209, 190, 168
    Solitude                         = 235, 236, 240
    Sorbus                           = 233, 105, 44
    Spectra                          = 53, 101, 77
    SpicyMix                         = 136, 101, 78
    Spray                            = 126, 212, 230
    SpringBud                        = 150, 255, 0
    SpringGreen                      = 0, 255, 127
    SpringSun                        = 236, 235, 189
    SpunPearl                        = 170, 169, 173
    Stack                            = 130, 142, 132
    SteelBlue                        = 70, 130, 180
    Stiletto                         = 137, 63, 69
    Strikemaster                     = 145, 92, 131
    StTropaz                         = 50, 82, 123
    Studio                           = 115, 79, 150
    Sulu                             = 201, 220, 135
    SummerSky                        = 33, 171, 205
    Sun                              = 237, 135, 45
    Sundance                         = 197, 179, 88
    Sunflower                        = 228, 208, 10
    Sunglow                          = 255, 204, 51
    SunsetOrange                     = 253, 82, 64
    SurfieGreen                      = 0, 116, 116
    Sushi                            = 111, 153, 64
    SuvaGrey                         = 140, 140, 140
    Swamp                            = 35, 43, 43
    SweetCorn                        = 253, 219, 109
    SweetPink                        = 243, 153, 152
    Tacao                            = 236, 177, 118
    TahitiGold                       = 235, 97, 35
    Tan                              = 210, 180, 140
    Tangaroa                         = 0, 28, 61
    Tangerine                        = 228, 132, 0
    TangerineYellow                  = 253, 204, 13
    Tapestry                         = 183, 110, 121
    Taupe                            = 72, 60, 50
    TaupeGrey                        = 139, 133, 137
    TawnyPort                        = 102, 66, 77
    TaxBreak                         = 79, 102, 106
    TeaGreen                         = 208, 240, 192
    Teak                             = 176, 141, 87
    Teal                             = 0, 128, 128
    TeaRose                          = 255, 133, 207
    Temptress                        = 60, 20, 33
    Tenne                            = 200, 101, 0
    TerraCotta                       = 226, 114, 91
    Thistle                          = 216, 191, 216
    TickleMePink                     = 245, 111, 161
    Tidal                            = 232, 244, 140
    TitanWhite                       = 214, 202, 221
    Toast                            = 165, 113, 100
    Tomato                           = 255, 99, 71
    TorchRed                         = 255, 3, 62
    ToryBlue                         = 54, 81, 148
    Tradewind                        = 110, 174, 161
    TrendyPink                       = 133, 96, 136
    TropicalRainForest               = 0, 127, 102
    TrueV                            = 139, 114, 190
    TulipTree                        = 229, 183, 59
    Tumbleweed                       = 222, 170, 136
    Turbo                            = 255, 195, 36
    TurkishRose                      = 152, 119, 123
    Turquoise                        = 64, 224, 208
    TurquoiseBlue                    = 118, 215, 234
    Tuscany                          = 175, 89, 62
    TwilightBlue                     = 253, 255, 245
    Twine                            = 186, 135, 89
    TyrianPurple                     = 102, 2, 60
    Ultramarine                      = 10, 17, 149
    UltraPink                        = 255, 111, 255
    Valencia                         = 222, 82, 70
    VanCleef                         = 84, 61, 55
    VanillaIce                       = 229, 204, 201
    VenetianRed                      = 209, 0, 28
    Venus                            = 138, 127, 128
    Vermilion                        = 251, 79, 20
    VeryLightGrey                    = 207, 207, 207
    VidaLoca                         = 94, 140, 49
    Viking                           = 71, 171, 204
    Viola                            = 180, 131, 149
    ViolentViolet                    = 50, 23, 77
    Violet                           = 238, 130, 238
    VioletRed                        = 255, 57, 136
    Viridian                         = 64, 130, 109
    VistaBlue                        = 159, 226, 191
    VividViolet                      = 127, 62, 152
    WaikawaGrey                      = 83, 104, 149
    Wasabi                           = 150, 165, 60
    Watercourse                      = 0, 106, 78
    Wedgewood                        = 67, 107, 149
    WellRead                         = 147, 61, 65
    Wewak                            = 255, 152, 153
    Wheat                            = 245, 222, 179
    Whiskey                          = 217, 154, 108
    WhiskeySour                      = 217, 144, 88
    White                            = 255, 255, 255
    WhiteSmoke                       = 245, 245, 245
    WildRice                         = 228, 217, 111
    WildSand                         = 229, 228, 226
    WildStrawberry                   = 252, 65, 154
    WildWatermelon                   = 255, 84, 112
    WildWillow                       = 172, 191, 96
    Windsor                          = 76, 40, 130
    Wisteria                         = 191, 148, 228
    Wistful                          = 162, 162, 208
    Yellow                           = 255, 255, 0
    YellowGreen                      = 154, 205, 50
    YellowOrange                     = 255, 174, 66
    YourPink                         = 244, 194, 194
}
$Script:ScriptBlockColors = { param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters)
    $Script:RGBColors.Keys | Where-Object { $_ -like "*$wordToComplete*" } }
function Close-OfficeWord {
    [cmdletBinding()]
    param([alias('WordDocument')] $Document)
    try { $Document.Close() } catch { if ($_.Exception.InnerException.Message -eq "Memory stream is not expandable.") {} else { if ($PSBoundParameters.ErrorAction -eq 'Stop') { throw } else { Write-Warning "Close-OfficeWord - Couldn't close document properly. Error: $($_.Exception.Message)" } } }
}
function ConvertFrom-HTMLtoWord {
    <#
    .SYNOPSIS
    Converts HTML input to Microsoft Word Document
 
    .DESCRIPTION
    Converts HTML input to Microsoft Word Document
 
    .PARAMETER OutputFile
    Path to the file to save converted HTML
 
    .PARAMETER FileHTML
    Input HTML loaded straight from file
 
    .PARAMETER SourceHTML
    Input HTML loaded from string
 
    .PARAMETER Show
    Once conversion ends show the resulting document
 
    .EXAMPLE
    $Objects = @(
        [PSCustomObject] @{ Test = 1; Test2 = 'Test'; Test3 = 'Ok' }
        [PSCustomObject] @{ Test = 1; Test2 = 'Test'; Test3 = 'Ok' }
    )
 
    New-HTML {
        New-HTMLText -Text 'This is a test', ' another test' -FontSize 30pt
        New-HTMLTable -DataTable $Objects -Simplify
    } -Online -FilePath $PSScriptRoot\Documents\Test.html
 
    ConvertFrom-HTMLToWord -OutputFile $PSScriptRoot\Documents\TestHTML.docx -FileHTML $PSScriptRoot\Documents\Test.html -Show
 
    .EXAMPLE
    $Objects = @(
    [PSCustomObject] @{ Test = 1; Test2 = 'Test'; Test3 = 'Ok' }
    [PSCustomObject] @{ Test = 1; Test2 = 'Test'; Test3 = 'Ok' }
    )
 
    $Test = New-HTML {
        New-HTMLText -Text 'This is a test', ' another test' -FontSize 30pt
        New-HTMLTable -DataTable $Objects -simplify
    } -Online
 
    ConvertFrom-HTMLToWord -OutputFile $PSScriptRoot\Documents\TestHTML.docx -HTML $Test -Show
 
    .NOTES
    General notes
    #>

    [cmdletBinding(DefaultParameterSetName = 'HTML')]
    param([Parameter(Mandatory, ParameterSetName = 'HTMLFile')]
        [Parameter(Mandatory, ParameterSetName = 'HTML')]
        [string] $OutputFile,
        [Parameter(Mandatory, ParameterSetName = 'HTMLFile')][alias('InputFile')][string] $FileHTML,
        [Parameter(Mandatory, ParameterSetName = 'HTML')][alias('HTML')][string] $SourceHTML,
        [Parameter(Mandatory, ParameterSetName = 'HTMLFile')]
        [Parameter(Mandatory, ParameterSetName = 'HTML')]
        [switch] $Show)
    $Document = New-OfficeWord -FilePath $OutputFile
    if ($FileHTML) { $HTML = Get-Content -LiteralPath $FileHTML -Raw } elseif ($SourceHTML) { $HTML = $SourceHTML }
    try {
        $Converter = [HtmlToOpenXml.HtmlConverter]::new($Document._document.MainDocumentPart)
        $Converter.ParseHtml($HTML)
    } catch { Write-Warning -Message "ConvertFrom-HTMLtoWord - Couldn't convert HTML to Word. Error: $($_.Exception.Message)" }
    Save-OfficeWord -Document $Document -Show:$Show.IsPresent
}
function Export-OfficeExcel {
    [cmdletBinding()]
    param([string] $FilePath,
        [alias('Name')][string] $WorksheetName = 'Sheet1',
        [alias("TargetData")][Parameter(ValueFromPipeline = $true)][Array] $DataTable,
        [int] $Row = 1,
        [int] $Column = 1,
        [switch] $Show,
        [switch] $AllProperties,
        [ClosedXML.Excel.XLTransposeOptions] $Transpose,
        [switch] $ShowRowStripes,
        [switch] $ShowColumnStripes,
        [switch] $DisableAutoFilter,
        [switch] $HideHeaderRow,
        [switch] $ShowTotalsRow,
        [switch] $EmphasizeFirstColumn,
        [switch] $EmphasizeLastColumn,
        [string] $Theme)
    Begin { $Data = [System.Collections.Generic.List[Object]]::new() }
    Process { foreach ($_ in $DataTable) { $Data.Add($_) } }
    End {
        New-OfficeExcel -FilePath $FilePath { New-OfficeExcelWorkSheet -Name $WorksheetName { $SplatOfficeExcelTable = @{DataTable = $Data
                    Row                                                                                                            = $Row
                    Column                                                                                                         = $Column
                    AllProperties                                                                                                  = $AllProperties.IsPresent
                    DisableAutoFilter                                                                                              = $DisableAutoFilter.IsPresent
                    EmphasizeFirstColumn                                                                                           = $EmphasizeFirstColumn.IsPresent
                    EmphasizeLastColumn                                                                                            = $EmphasizeLastColumn.IsPresent
                    ShowColumnStripes                                                                                              = $ShowColumnStripes.IsPresent
                    ShowRowStripes                                                                                                 = $ShowRowStripes.IsPresent
                    ShowTotalsRow                                                                                                  = $ShowTotalsRow.IsPresent
                    HideHeaderRow                                                                                                  = $HideHeaderRow.IsPresent
                    Transpose                                                                                                      = $Transpose
                    Theme                                                                                                          = $Theme
                }
                Remove-EmptyValue -Hashtable $SplatOfficeExcelTable
                New-OfficeExcelTable @SplatOfficeExcelTable } -Option Replace } -Show:$Show.IsPresent -Save
    }
}
Register-ArgumentCompleter -CommandName Export-OfficeExcel -ParameterName Theme -ScriptBlock $Script:ScriptBlockThemes
function Get-OfficeExcel {
    [cmdletBinding()]
    param([Parameter(Mandatory)][string] $FilePath,
        [switch] $Template,
        [nullable[bool]] $RecalculateAllFormulas,
        [ClosedXML.Excel.XLEventTracking] $EventTracking)
    if ($FilePath -and (Test-Path -LiteralPath $FilePath)) {
        if ($RecalculateAllFormulas -or $EventTracking) {
            $LoadOptions = [ClosedXML.Excel.LoadOptions]::new()
            if ($null -ne $RecalculateAllFormulas) { $LoadOptions.RecalculateAllFormulas = $RecalculateAllFormulas }
            if ($EventTracking) { $LoadOptions.EventTracking = $EventTracking }
            $WorkBook = [ClosedXML.Excel.XLWorkbook]::new($FilePath, $LoadOptions)
        } else {
            if ($FilePath) {
                try { $WorkBook = [ClosedXML.Excel.XLWorkbook]::new($FilePath) } catch {
                    if ($PSBoundParameters.ErrorAction -eq 'Stop') { throw } else {
                        Write-Warning -Message "Get-OfficeExcel - Failed to open $FilePath. Eror: $($_.Exception.Message)"
                        return
                    }
                }
            } else { $WorkBook = [ClosedXML.Excel.XLWorkbook]::new() }
        }
        $WorkBook | Add-Member -MemberType NoteProperty -Name 'FilePath' -Value $FilePath -Force
        $WorkBook
    }
}
function Get-OfficeExcelValue {
    [cmdletBinding()]
    param([ClosedXML.Excel.IXLWorksheet] $Worksheet,
        [int] $Row,
        [int] $Column)
    if ($Script:OfficeTrackerExcel) { $Worksheet = $Script:OfficeTrackerExcel['WorkSheet'] } elseif (-not $Worksheet) { return }
    $Worksheet.Cell($Row, $Column)
}
function Get-OfficeExcelWorkSheet {
    [cmdletBinding(DefaultParameterSetName = 'All')]
    param([parameter(Position = 0, ParameterSetName = 'Name')]
        [parameter(Position = 0, ParameterSetName = 'Index')]
        [parameter(Position = 0, ParameterSetName = 'All')]
        [scriptblock] $ExcelContent,
        [parameter(ParameterSetName = 'Name')]
        [parameter(ParameterSetName = 'Index')]
        [parameter(ParameterSetName = 'All')]
        [alias('ExcelDocument')][ClosedXML.Excel.XLWorkbook]$Excel,
        [parameter(ParameterSetName = 'Name')][alias('Name')][string] $WorksheetName,
        [parameter(ParameterSetName = 'Index')][nullable[int]] $Index,
        [parameter(ParameterSetName = 'All')][switch] $All,
        [parameter(ParameterSetName = 'Name')]
        [parameter(ParameterSetName = 'Index')]
        [parameter(ParameterSetName = 'All')]
        [switch] $NameOnly)
    $Worksheet = $null
    if ($Script:OfficeTrackerExcel -and -not $Excel) { $Excel = $Script:OfficeTrackerExcel['WorkBook'] }
    try { if ($WorksheetName) { $Worksheet = $Excel.Worksheets.Worksheet($WorksheetName) } elseif ($null -ne $Index) { $Worksheet = $Excel.Worksheets.Worksheet($Index) } else { $Worksheet = $Excel.Worksheets } } catch { if ($PSBoundParameters.ErrorAction -eq 'Stop') { throw } else { Write-Warning -Message "Get-OfficeExcelWorkSheet - Error: $($_.Exception.Message)" } }
    if ($Worksheet) {
        if ($ExcelContent) {
            $Script:OfficeTrackerExcel['WorkSheet'] = $Worksheet
            $ExecutedContent = & $ExcelContent
            $ExecutedContent
            $Script:OfficeTrackerExcel['WorkSheet'] = $null
        } else { if ($NameOnly) { $Worksheet.Name } else { $Worksheet } }
    } else { if ($Index) { Write-Warning -Message "Get-OfficeExcelWorkSheet - WorkSheet with index $Index doesnt exits. Skipping." } elseif ($WorksheetName) { Write-Warning -Message "Get-OfficeExcelWorkSheet - WorkSheet with name $WorksheetName doesnt exits. Skipping." } else { Write-Warning -Message "Get-OfficeExcelWorkSheet - Mmm?" } }
}
function Get-OfficeExcelWorkSheetData {
    [cmdletBinding()]
    param([ClosedXML.Excel.IXLWorksheet] $WorkSheet)
    $HeaderNames = [System.Collections.Generic.List[string]]::new()
    foreach ($Cell in $WorkSheet.RangeUsed().Row(1).Cells()) {
        if ($Cell.InnerText -ne "") { $Name = $Cell.InnerText } else { $Name = "NoName$($Cell.Address)" }
        if ($HeaderNames.Contains($Name)) { $Name = $Name + $($Cell.Address) }
        $HeaderNames.Add($Name)
    }
    $LastRowUsed = $WorkSheet.RangeUsed().RowCount()
    foreach ($Row in $WorkSheet.RangeUsed().Rows(2, $LastRowUsed)) {
        $RowData = [ordered] @{}
        for ($i = 0; $i -lt $HeaderNames.Count; $i++) { $RowData[$HeaderNames[$i]] = $Row.Cells($i + 1).CachedValue }
        [PSCustomObject] $RowData
    }
}
function Get-OfficeWord {
    [cmdletBinding()]
    param([Parameter(Mandatory)][string] $FilePath,
        [switch] $ReadOnly,
        [switch] $AutoSave)
    if ($FilePath -and (Test-Path -LiteralPath $FilePath)) { try { [OfficeIMO.Word.WordDocument]::Load($FilePath, $ReadOnly.IsPresent, $AutoSave.IsPresent) } catch { if ($PSBoundParameters.ErrorAction -eq 'Stop') { throw } else { Write-Warning "Get-OfficeWord - File $FilePath couldn't be open. Error: $($_.Exception.Message)" } } } else { if ($PSBoundParameters.ErrorAction -eq 'Stop') { throw "File $FilePath doesn't exists. Try again." } else { Write-Warning "Get-OfficeWord - File $FilePath doesn't exists. Try again." } }
}
function Import-OfficeExcel {
    <#
    .SYNOPSIS
    Provides a way to converting an Excel file into PowerShell objects.
 
    .DESCRIPTION
    Provides a way to converting an Excel file into PowerShell objects.
    If Worksheet is not specified, all worksheets will be imported and returned as a hashtable of worksheet names and worksheet objects.
    If Worksheet is specified, only the specified worksheet will be imported and returned as an array of PSCustomObjects
 
    .PARAMETER FilePath
    The path to the Excel file to import.
 
    .PARAMETER WorkSheetName
    The name of the worksheet to import. If not specified, all worksheets will be imported.
 
    .EXAMPLE
    $FilePath = "$PSScriptRoot\Documents\Test5.xlsx"
 
    $ImportedData1 = Import-OfficeExcel -FilePath $FilePath
    $ImportedData1 | Format-Table
 
    .EXAMPLE
    $FilePath = "$PSScriptRoot\Documents\Excel.xlsx"
 
    $ImportedData2 = Import-OfficeExcel -FilePath $FilePath -WorkSheetName 'Contact3'
    $ImportedData2 | Format-Table
 
    .NOTES
    General notes
    #>

    [CmdletBinding()]
    param([Alias('LiteralPath')][Parameter(Mandatory)][string] $FilePath,
        [string[]] $WorkSheetName)
    $ExcelWorkbook = Get-OfficeExcel -FilePath $FilePath
    if ($ExcelWorkbook) {
        $WorkSheetContent = [ordered] @{}
        foreach ($WorkSheet in $ExcelWorkbook.Worksheets) {
            if ($WorkSheetName) { if ($WorkSheet.Worksheet -notin $WorkSheetName) { continue } }
            $WorkSheetContent[$WorkSheet.Name] = Get-OfficeExcelWorkSheetData -WorkSheet $WorkSheet
        }
        if ($WorkSheetName.Count -eq 1) { $WorkSheetContent[$WorkSheetName] } elseif ($WorkSheetName.Count -eq 0 -and $WorkSheetContent.Count -eq 1) { $WorkSheetContent[0] } else { $WorkSheetContent }
        $ExcelWorkbook.Dispose()
    }
}
function New-OfficeExcel {
    [cmdletBinding()]
    param([scriptblock] $ExcelContent,
        [Parameter(Mandatory)][string] $FilePath,
        [switch] $Template,
        [nullable[bool]] $RecalculateAllFormulas,
        [ClosedXML.Excel.XLEventTracking] $EventTracking,
        [switch] $Show,
        [switch] $Save,
        [validateSet('Reuse', 'Overwrite', 'Stop')][string] $WhenExists = 'Reuse')
    if ($ExcelContent) { $Script:OfficeTrackerExcel = [ordered] @{} }
    if (Test-Path -LiteralPath $FilePath) {
        if ($WhenExists -eq 'Stop') {
            Write-Warning -Message "New-OfficeExcel - File $FilePath already exists. Terminating."
            $Script:OfficeTrackerExcel = $null
            return
        } elseif ($WhenExists -eq 'Overwrite') {
            $WorkBook = [ClosedXML.Excel.XLWorkbook]::new()
            $WorkBook | Add-Member -MemberType NoteProperty -Name 'OpenType' -Value 'New' -Force
        } elseif ($WhenExists -eq 'ReUse') {
            Write-Warning -Message "New-OfficeExcel - File $FilePath already exists. Loading up."
            try { $WorkBook = [ClosedXML.Excel.XLWorkbook]::new($FilePath) } catch {
                $Script:OfficeTrackerExcel = $null
                if ($PSBoundParameters.ErrorAction -eq 'Stop') { throw } else {
                    Write-Warning -Message "New-OfficeExcel - File $FilePath returned error: $($_.Exception.Message)"
                    return
                }
            }
            $WorkBook | Add-Member -MemberType NoteProperty -Name 'OpenType' -Value 'Existing' -Force
        }
    } else {
        $WorkBook = [ClosedXML.Excel.XLWorkbook]::new()
        $WorkBook | Add-Member -MemberType NoteProperty -Name 'OpenType' -Value 'New' -Force
    }
    $WorkBook | Add-Member -MemberType NoteProperty -Name 'FilePath' -Value $FilePath -Force
    if ($ExcelContent) {
        $Script:OfficeTrackerExcel['WorkBook'] = $WorkBook
        $Script:OfficeTrackerExcel['OpenType'] = 'Existing'
        $ExecutedContent = & $ExcelContent
        $ExecutedContent
    }
    if ($ExcelContent) {
        if ($Save) { Save-OfficeExcel -Show:$Show.IsPresent-FilePath $FilePath -Excel $WorkBook }
        $Script:OfficeTrackerExcel = $null
    } else { $WorkBook }
}
function New-OfficeExcelTable {
    [cmdletBinding()]
    param([Array] $DataTable,
        [Object] $Worksheet,
        [alias('Row')][int] $StartRow = 1,
        [alias('Column')][int] $StartCell = 1,
        [switch] $ReturnObject,
        [ClosedXML.Excel.XLTransposeOptions] $Transpose,
        [switch] $AllProperties,
        [switch] $SkipHeader,
        [switch] $ShowRowStripes,
        [switch] $ShowColumnStripes,
        [switch] $DisableAutoFilter,
        [switch] $HideHeaderRow,
        [switch] $ShowTotalsRow,
        [switch] $EmphasizeFirstColumn,
        [switch] $EmphasizeLastColumn,
        [string] $Theme)
    if ($Script:OfficeTrackerExcel -and -not $Worksheet) { $WorkSheet = $Script:OfficeTrackerExcel['WorkSheet'] }
    $Cell = $StartCell - 1
    if ($DataTable[0] -is [System.Collections.IDictionary]) { $Properties = 'Name', 'Value' } else { $Properties = Select-Properties -Objects $DataTable -AllProperties:$AllProperties -Property $IncludeProperty -ExcludeProperty $ExcludeProperty }
    if (-not $SkipHeader) {
        foreach ($Property in $Properties) {
            $Cell++
            New-OfficeExcelValue -Row $StartRow -Value $Property -Column $Cell -Worksheet $Worksheet
        }
    }
    if ($DataTable[0] -is [System.Collections.IDictionary]) {
        foreach ($Data in $DataTable) {
            foreach ($Key in $Data.Keys) {
                $Row++
                New-OfficeExcelValue -Row ($Row + $StartRow) -Value $Key -Column ($StartCell) -Worksheet $Worksheet
                New-OfficeExcelValue -Row ($Row + $StartRow) -Value $Data[$Key] -Column ($StartCell + 1) -Worksheet $Worksheet
            }
        }
        $LastCell = $Worksheet.Row($StartRow + $Row).Cell($Cell)
    } elseif ($Properties -eq '*') {
        foreach ($Data in $DataTable) {
            $Row++
            New-OfficeExcelValue -Row ($Row + $StartRow) -Value $Data -Column ($StartCell) -Worksheet $Worksheet
        }
        $LastCell = $Worksheet.Row($StartRow + $Row).Cell($StartCell)
    } else {
        for ($Row = 1; $Row -le $DataTable.Count; $Row++) {
            $Cell = $StartCell - 1
            foreach ($Property in $Properties) {
                $Cell++
                New-OfficeExcelValue -Row ($Row + $StartRow) -Value $DataTable[$Row - 1].$Property -Column $Cell -Worksheet $Worksheet
            }
        }
        $LastCell = $Worksheet.Row($StartRow - 1 + $Row).Cell($Cell)
    }
    $FirstCell = $Worksheet.Row($StartRow).Cell($StartCell)
    $Range = $Worksheet.Range($FirstCell.Address, $LastCell.Address)
    $TableOutput = $Range.CreateTable()
    $SplatOptions = @{Table  = $TableOutput
        Transpose            = $Transpose
        ShowRowStripes       = $ShowRowStripes.IsPresent
        ShowColumnStripes    = $ShowColumnStripes.IsPresent
        DisableAutoFilter    = $DisableAutoFilter.IsPresent
        HideHeaderRow        = $HideHeaderRow.IsPresent
        ShowTotalsRow        = $ShowTotalsRow.IsPresent
        EmphasizeFirstColumn = $EmphasizeFirstColumn.IsPresent
        EmphasizeLastColumn  = $EmphasizeLastColumn.IsPresent
        Theme                = $Theme
    }
    Remove-EmptyValue -Hashtable $SplatOptions
    New-OfficeExcelTableOptions @SplatOptions
}
function New-OfficeExcelTableOptions {
    [cmdletBinding()]
    param($Table,
        [ClosedXML.Excel.XLTransposeOptions] $Transpose,
        [switch] $ShowRowStripes,
        [switch] $ShowColumnStripes,
        [switch] $DisableAutoFilter,
        [switch] $HideHeaderRow,
        [switch] $ShowTotalsRow,
        [switch] $EmphasizeFirstColumn,
        [switch] $EmphasizeLastColumn,
        [string] $Theme)
    if ($Table) {
        if ($null -ne $Transpose) { $Table.Transpose($Transpose) }
        if ($AutoFilter) { $Table.InitializeAutoFilter() }
        if ($ShowColumnStripes) { $Table.ShowColumnStripes = $true }
        if ($ShowRowStripes) { $Table.ShowRowStripes = $true }
        if ($DisableAutoFilter) { $Table.ShowAutoFilter = $false }
        if ($ShowTotalsRow) { $Table.ShowsTotalRow = $true }
        if ($null -ne $Theme) { $Table.Theme = $Theme }
        if ($EmphasizeFirstColumn) { $Table.EmphasizeFirstColumn = $true }
        if ($EmphasizeLastColumn) { $Table.EmphasizeLastColumn = $true }
        if ($HideHeaderRow) { $Table.ShowHeaderRow = $false }
        if ($ReturnObject) { $Table }
    }
}
function New-OfficeExcelValue {
    [cmdletBinding()]
    param($Worksheet,
        [Object] $Value,
        [int] $Row,
        [int] $Column,
        [string] $DateFormat,
        [string] $NumberFormat,
        [int] $FormatID)
    $KnownTypes = 'bool|byte|char|datetime|decimal|double|float|int|long|sbyte|short|string|timespan|uint|ulong|URI|ushort'
    if ($Script:OfficeTrackerExcel) { $Worksheet = $Script:OfficeTrackerExcel['WorkSheet'] } elseif (-not $Worksheet) { return }
    try { if ($null -eq $Value) { $Worksheet.Cell($Row, $Column).Value = '' } elseif ($Value.GetType().Name -match $KnownTypes) { $Worksheet.Cell($Row, $Column).Value = $Value } else { $Worksheet.Cell($Row, $Column).Value = [string] $Value } } catch { if ($PSBoundParameters.ErrorAction -eq 'Stop') { throw } else { Write-Warning "New-OfficeExcelValue - Error: $($_.Exception.Message)" } }
}
function New-OfficeExcelWorkSheet {
    [cmdletBinding()]
    param([parameter(Position = 0)][scriptblock] $ExcelContent,
        [alias('ExcelDocument')][ClosedXML.Excel.XLWorkbook]$Excel,
        [parameter(Mandatory)][alias('Name')][string] $WorksheetName,
        [ValidateSet("Replace", "Skip", "Rename")][string] $Option = 'Skip',
        [switch] $Suppress,
        [string] $TabColor)
    $Worksheet = $null
    if ($null -ne $Excel) {} elseif ($Script:OfficeTrackerExcel -and -not $Excel) { $Excel = $Script:OfficeTrackerExcel['WorkBook'] } else { return }
    if ($Excel.Worksheets.Contains($WorksheetName)) {
        if ($Option -eq 'Skip') {
            Write-Warning -Message "New-OfficeExcelWorkSheet - WorkSheet with name $WorksheetName already exists. Skipping..."
            return
        } elseif ($Option -eq 'Replace') {
            Write-Warning -Message "New-OfficeExcelWorkSheet - WorkSheet with name $WorksheetName already exists. Replacing..."
            $Excel.Worksheets.Worksheet($WorksheetName).Delete()
            $Worksheet = $Excel.Worksheets.Add($WorksheetName)
        } elseif ($Option -eq 'Rename') {
            $NewName = "Sheet" + (Get-RandomStringName -Size 6)
            Write-Warning -Message "New-OfficeExcelWorkSheet - WorkSheet with name $WorksheetName already exists. Renaming to $NewName..."
            $WorkSheetName = $NewName
            $Worksheet = $Excel.Worksheets.Add($WorksheetName)
        }
    } else { $Worksheet = $Excel.Worksheets.Add($WorksheetName) }
    if ($Worksheet) {
        if ($TabColor) { Set-OfficeExcelWorkSheetStyle -TabColor $TabColor -Worksheet $Worksheet }
        if ($ExcelContent) {
            $Script:OfficeTrackerExcel['WorkSheet'] = $Worksheet
            $ExecutedContent = & $ExcelContent
            $ExecutedContent
            $Script:OfficeTrackerExcel['WorkSheet'] = $null
        } else { if (-not $Suppress) { if ($NameOnly) { $Worksheet.Name } else { $Worksheet } } }
    }
}
Register-ArgumentCompleter -CommandName New-OfficeExcelWorkSheet -ParameterName TabColor -ScriptBlock $Script:ScriptBlockColors
function New-OfficeWord {
    [cmdletBinding()]
    param([string] $FilePath,
        [switch] $AutoSave,
        [int] $Retry = 2)
    $Saved = $false
    $Count = 0
    while ($Count -le $Retry -and $Saved -eq $false) {
        $Count++
        try {
            $WordDocument = [OfficeImo.Word.WordDocument]::Create($FilePath, $AutoSave.IsPresent)
            $Saved = $true
        } catch { if ($PSBoundParameters.ErrorAction -eq 'Stop') { throw } else { Write-Warning "New-OfficeWord - Couldn't create new Word Document at $FilePath. Error: $($_.Exception.Message)" } }
        if (-not $Saved) {
            if ($Retry -ge $Count) {
                $FilePath = [System.IO.Path]::Combine([System.IO.Path]::GetTempPath(), "$($([System.IO.Path]::GetRandomFileName()).Split('.')[0]).docx")
                Write-Warning -Message "New-OfficeWord - Couldn't save using provided file name, retrying with $FilePath"
            } else {
                Write-Warning -Message "New-OfficeWord - Couldn't save using provided file name. Run out of retries ($Count / $Retry)."
                return
            }
        }
    }
    $WordDocument
}
function New-OfficeWordList {
    [cmdletBinding()]
    param([ScriptBlock] $Content,
        [OfficeImo.Word.WordDocument] $Document,
        [OfficeIMO.Word.WordListStyle] $Style = [OfficeIMO.Word.WordListStyle]::Bulleted,
        [switch] $Suppress)
    $List = $Document.AddList($Style)
    if ($Content) {
        $ListItems = & $Content
        foreach ($Item in $ListItems) {
            $Item.List = $List
            $Item.Suppress = $true
            New-OfficeWordListItem @Item
        }
    }
    if (-not $Suppress) { $List }
}
function New-OfficeWordListItem {
    [cmdletBinding()]
    param([OfficeIMO.Word.WordList] $List,
        [int] $Level,
        [string[]]$Text,
        [nullable[bool][]] $Bold,
        [nullable[bool][]] $Italic,
        [nullable[DocumentFormat.OpenXml.Wordprocessing.UnderlineValues][]] $Underline,
        [string[]] $Color,
        [nullable[DocumentFormat.OpenXml.Wordprocessing.JustificationValues]] $Alignment,
        [switch] $Suppress)
    if ($List) {
        $ListItem = $List.AddItem($Text, $Level)
        if (-not $Suppress) { $ListItem }
    } else {
        [ordered] @{List = $null
            Level        = $Level
            Text         = $Text
            Bold         = $Bold
            Italic       = $Italic
            Underline    = $Underline
            Color        = $Color
            Alignment    = $Alignment
            Suppress     = $Suppress
        }
    }
}
function New-OfficeWordTable {
    [cmdletBinding()]
    param([OfficeIMO.Word.WordDocument] $Document,
        [Array] $DataTable,
        [OfficeIMO.Word.WordTableStyle] $Style = [OfficeIMO.Word.WordTableStyle]::TableGrid,
        [string] $TableLayout,
        [switch] $SkipHeader,
        [switch] $Suppress)
    if (-not $Document) {
        Write-Warning -Message "New-OfficeWordTable - Document is not specified. Please provide valid document."
        return
    }
    if ($DataTable[0] -is [System.Collections.IDictionary]) { $Properties = 'Name', 'Value' } else { $Properties = Select-Properties -Objects $DataTable -AllProperties:$AllProperties -Property $IncludeProperty -ExcludeProperty $ExcludeProperty }
    $CountRows = 0
    $CountColumns = 0
    $RowsCount = $DataTable.Count
    $ColumnsCount = $Properties.Count
    if (-not $SkipHeader) {
        $Table = $Document.AddTable($RowsCount + 1, $ColumnsCount, $Style)
        foreach ($Property in $Properties) {
            $Table.Rows[0].Cells[$CountColumns].Paragraphs[0].Text = $Property
            $CountColumns += 1
        }
        $CountRows += 1
    } else { $Table = $Document.AddTable($RowsCount, $ColumnsCount, $Style) }
    foreach ($Row in $DataTable) {
        $CountColumns = 0
        foreach ($P in $Properties) {
            $Table.Rows[$CountRows].Cells[$CountColumns].Paragraphs[0].Text = $Row.$P
            $CountColumns += 1
        }
        $CountRows += 1
    }
    if (-not $Suppress) { $Table }
}
function New-OfficeWordText {
    [cmdletBinding()]
    param([OfficeIMO.Word.WordDocument] $Document,
        [OfficeIMO.Word.WordParagraph] $Paragraph,
        [string[]]$Text,
        [nullable[bool][]] $Bold,
        [nullable[bool][]] $Italic,
        [nullable[DocumentFormat.OpenXml.Wordprocessing.UnderlineValues][]] $Underline,
        [string[]] $Color,
        [DocumentFormat.OpenXml.Wordprocessing.JustificationValues] $Alignment,
        [switch] $ReturnObject)
    if (-not $Paragraph) { $Paragraph = $Document.AddParagraph() }
    for ($T = 0; $T -lt $Text.Count; $T++) {
        $Paragraph = $Paragraph.AddText($Text[$T])
        if ($Bold -and $Bold.Count -ge $T -and $Bold[$T]) { $Paragraph.Bold = $Bold[$T] }
        if ($Italic -and $Italic.Count -ge $T -and $Italic[$T]) { $Paragraph.Italic = $Italic[$T] }
        if ($Underline -and $Underline.Count -ge $T -and $Underline[$T]) { $Paragraph.Underline = $Underline[$T] }
        if ($Color -and $Color.Count -ge $T -and $Color[$T]) {
            $ColorToSet = (ConvertFrom-Color -Color $Color[$T])
            if ($ColorToSet) { $Paragraph.Color = $ColorToSet }
        }
        if ($Alignment) { $Paragraph.ParagraphAlignment = $Alignment }
    }
    if ($ReturnObject) { $Paragraph }
}
Register-ArgumentCompleter -CommandName New-OfficeWordText -ParameterName Color -ScriptBlock $Script:ScriptBlockColors
function Remove-OfficeWordFooter {
    [cmdletBinding()]
    param([parameter(Mandatory)][OfficeIMO.Word.WordDocument] $Document)
    try { [OfficeIMO.Word.WordFooter]::RemoveFooters($Document) } catch { if ($PSBoundParameters.ErrorAction -eq 'Stop') { throw } else { Write-Warning -Message "Remove-OfficeWordFooter - Couldn't remove footer. Error: $($_.Exception.Message)" } }
}
function Remove-OfficeWordHeader {
    [cmdletBinding()]
    param([parameter(Mandatory)][OfficeIMO.Word.WordDocument] $Document)
    try { if ($Document) { [OfficeIMO.Word.WordHeader]::RemoveHeaders($Document) } else { if ($PSBoundParameters.ErrorAction -eq 'Stop') { throw "Couldn't remove footer. Document not provided." } else { Write-Warning -Message "Remove-OfficeWordHeader - Couldn't remove footer. Document not provided." } } } catch { if ($PSBoundParameters.ErrorAction -eq 'Stop') { throw } else { Write-Warning -Message "Remove-OfficeWordHeader - Couldn't remove footer. Error: $($_.Exception.Message)" } }
}
function Save-OfficeExcel {
    [cmdletBinding()]
    param([ClosedXML.Excel.XLWorkbook] $Excel,
        [string] $FilePath,
        [switch] $Show,
        [int] $RetryCount = 1,
        [Parameter(DontShow)] $CurrentRetryCount)
    if ($Excel) {
        if (-not $FilePath) { $FilePath = $Excel.FilePath }
        if ($Excel.Worksheets.Count -gt 0) {
            try {
                if (-not $FilePath) { if ($Excel.OpenType -eq 'Existing') { $Excel.Save() } else { if ($Excel.OpenType -eq 'New') { $Excel.SaveAs($Excel.FilePath) } } } else { $Excel.SaveAs($FilePath) }
                $CurrentRetryCount = 0
            } catch {
                if ($RetryCount -eq $CurrentRetryCount) {
                    Write-Warning "Save-ExcelDocument - Couldnt save Excel to $FilePath. Retry count limit reached. Terminating.."
                    return
                }
                $CurrentRetryCount++
                $ErrorMessage = $_.Exception.Message
                if ($ErrorMessage -like "*The process cannot access the file*because it is being used by another process.*" -or
                    $ErrorMessage -like "*Error saving file*") {
                    $FilePath = Get-FileName -Temporary -Extension 'xlsx'
                    Write-Warning "Save-OfficeExcel - Couldn't save file as it was in use or otherwise. Trying different name $FilePath"
                    Save-OfficeExcel -Excel $Excel -Show:$Show -FilePath $FilePath -RetryCount $RetryCount -CurrentRetryCount $CurrentRetryCount
                    return
                } else { Write-Warning "Save-OfficeExcel - Error: $ErrorMessage" }
            }
            if ($Show) { try { Invoke-Item -Path $FilePath } catch { Write-Warning "Save-OfficeExcel - Couldn't open file $FilePath as requested." } }
        } else { Write-Warning -Message "Save-OfficeExcel - Can't save $FilePath because there are no worksheets." }
    } else { Write-Warning -Message "Save-OfficeExcel - Excel Workbook not provided. Skipping." }
}
function Save-OfficeWord {
    [cmdletBinding()]
    param([alias('WordDocument')][OfficeIMO.Word.WordDocument] $Document,
        [switch] $Show,
        [string] $FilePath,
        [int] $Retry = 2)
    if (-not $Document) {
        Write-Warning "Save-OfficeWord - Couldn't save Word Document. Document is null."
        return
    }
    if (-not $Document.FilePath -and -not $FilePath) {
        if ($PSBoundParameters.ErrorAction -eq 'Stop') { throw } else {
            Write-Warning "Save-OfficeWord - Couldn't save Word Document. No file path provided."
            return
        }
    }
    if ($FilePath) { try { $null = $Document.Save($FilePath, $Show.IsPresent) } catch { if ($PSBoundParameters.ErrorAction -eq 'Stop') { throw } else { Write-Warning "Save-OfficeWord - Couldn't save $FilePath. Error: $($_.Exception.Message)" } } finally {} } else { if (-not $Document.AutoSave) { try { $Document.Save($Show.IsPresent) } catch { if ($PSBoundParameters.ErrorAction -eq 'Stop') { throw } else { Write-Warning "Save-OfficeWord - Couldn't save $($Document.FilePath) Error: $($_.Exception.Message)" } } finally {} } }
    $Document.Dispose()
}
function Set-OfficeExcelCellStyle {
    [cmdletBinding()]
    param($Worksheet,
        [int] $Row,
        [int] $Column,
        [string] $Format,
        [int] $FormatID,
        [nullable[bool]] $Bold,
        [ClosedXML.Excel.XLFontCharSet] $FontCharSet,
        [alias('Color')][string] $FontColor,
        [string] $BackGroundColor,
        [ClosedXML.Excel.XLFillPatternValues] $PatternType,
        [ClosedXML.Excel.XLFontFamilyNumberingValues] $FontFamilyNumbering,
        [string] $FontName,
        [double] $FontSize,
        [nullable[bool]] $Italic ,
        [nullable[bool]] $Shadow,
        [nullable[bool]] $Strikethrough ,
        [ClosedXML.Excel.XLFontUnderlineValues] $Underline,
        [ClosedXML.Excel.XLFontVerticalTextAlignmentValues] $VerticalAlignment)
    if ($Script:OfficeTrackerExcel) { $Worksheet = $Script:OfficeTrackerExcel['WorkSheet'] } elseif (-not $Worksheet) { return }
    if ($Format) { $Worksheet.Cell($Row, $Column).Style.NumberFormat.Format = $Format } elseif ($FormatID) { $Worksheet.Cell($Row, $Column).Style.NumberFormat.NumberFormatID = $FormatID }
    if ($FontColor) {
        $ColorConverted = [ClosedXML.Excel.XLColor]::FromHtml((ConvertFrom-Color -Color $FontColor))
        $Worksheet.Cell($Row, $Column).Style.Font.FontColor = $ColorConverted
    }
    if ($null -ne $Bold) { $Worksheet.Cell($Row, $Column).Style.Font.Bold = $Bold }
    if ($null -ne $Italic) { $Worksheet.Cell($Row, $Column).Style.Font.Italic = $Italic }
    if ($null -ne $Strikethrough) { $Worksheet.Cell($Row, $Column).Style.Font.Strikethrough = $Strikethrough }
    if ($null -ne $Shadow) { $Worksheet.Cell($Row, $Column).Style.Font.Shadow = $Shadow }
    if ($FontSize) { $Worksheet.Cell($Row, $Column).Style.Font.FontSize = $FontSize }
    if ($null -ne $Underline) { $Worksheet.Cell($Row, $Column).Style.Font.Underline = $Underline }
    if ($null -ne $VerticalAlignment) { $Worksheet.Cell($Row, $Column).Style.Font.VerticalAlignment = $VerticalAlignment }
    if ($null -ne $FontFamilyNumbering) { $Worksheet.Cell($Row, $Column).Style.Font.FontFamilyNumbering = $FontFamilyNumbering }
    if ($null -ne $FontCharSet) { $Worksheet.Cell($Row, $Column).Style.Font.FontCharSet = $FontCharSet }
    if ($BackGroundColor) {
        $ColorConverted = [ClosedXML.Excel.XLColor]::FromHtml((ConvertFrom-Color -Color $BackGroundColor))
        $Worksheet.Cell($Row, $Column).Style.Fill.BackgroundColor = $ColorConverted
    }
    if ($PatternType) { $Worksheet.Cell($Row, $Column).Style.Fill.PatternType = $PatternType }
}
Register-ArgumentCompleter -CommandName Set-OfficeExcelValueStyle -ParameterName FontColor -ScriptBlock $Script:ScriptBlockColors
Register-ArgumentCompleter -CommandName Set-OfficeExcelValueStyle -ParameterName BackGroundColor -ScriptBlock $Script:ScriptBlockColors
function Set-OfficeExcelWorkSheetStyle {
    [cmdletBinding(DefaultParameterSetName = 'Name')]
    param([parameter(ParameterSetName = 'Name')]
        [parameter(ParameterSetName = 'Index')]
        [parameter(ParameterSetName = 'Native')]
        [alias('ExcelDocument')][ClosedXML.Excel.XLWorkbook]$Excel,
        [parameter(ParameterSetName = 'Name')]
        [parameter(ParameterSetName = 'Index')]
        [parameter(ParameterSetName = 'Native')]
        [string] $TabColor,
        [parameter(ParameterSetName = 'Native')] $Worksheet,
        [parameter(ParameterSetName = 'Name')][alias('Name')][string] $WorksheetName,
        [parameter(ParameterSetName = 'Index')][nullable[int]] $Index)
    if ($Script:OfficeTrackerExcel -and -not $Excel) { $Excel = $Script:OfficeTrackerExcel['WorkBook'] }
    if ($Worksheet) {} else { try { if ($WorksheetName) { $Worksheet = $Excel.Worksheets.Worksheet($WorksheetName) } elseif ($null -ne $Index) { $Worksheet = $Excel.Worksheets.Worksheet($Index) } } catch { if ($PSBoundParameters.ErrorAction -eq 'Stop') { throw } else { Write-Warning -Message "Set-OfficeExcelWorkSheet - Error: $($_.Exception.Message)" } } }
    if ($Worksheet) {
        if ($TabColor) {
            $ColorConverted = [ClosedXML.Excel.XLColor]::FromHtml((ConvertFrom-Color -Color $TabColor))
            $null = $Worksheet.SetTabColor($ColorConverted)
        }
    }
}
Register-ArgumentCompleter -CommandName Set-OfficeExcelWorkSheetStyle -ParameterName TabColor -ScriptBlock $Script:ScriptBlockColors
if ($PSVersionTable.PSEdition -eq 'Desktop' -and (Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full").Release -lt 461808) { Write-Warning "This module requires .NET Framework 4.7.2 or later."; return }
Export-ModuleMember -Function @('Close-OfficeWord', 'ConvertFrom-HTMLtoWord', 'Export-OfficeExcel', 'Get-OfficeExcel', 'Get-OfficeExcelValue', 'Get-OfficeExcelWorkSheet', 'Get-OfficeExcelWorkSheetData', 'Get-OfficeWord', 'Import-OfficeExcel', 'New-OfficeExcel', 'New-OfficeExcelTable', 'New-OfficeExcelTableOptions', 'New-OfficeExcelValue', 'New-OfficeExcelWorkSheet', 'New-OfficeWord', 'New-OfficeWordList', 'New-OfficeWordListItem', 'New-OfficeWordTable', 'New-OfficeWordText', 'Remove-OfficeWordFooter', 'Remove-OfficeWordHeader', 'Save-OfficeExcel', 'Save-OfficeWord', 'Set-OfficeExcelCellStyle', 'Set-OfficeExcelWorkSheetStyle') -Alias @()
# SIG # Begin signature block
# MIInRAYJKoZIhvcNAQcCoIInNTCCJzECAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCCw1dsZLn+YljF2
# gHzh6fUPk51tuJpXQZpNy4nnz8vjEqCCIT0wggO3MIICn6ADAgECAhAM5+DlF9hG
# /o/lYPwb8DA5MA0GCSqGSIb3DQEBBQUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQK
# EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNV
# BAMTG0RpZ2lDZXJ0IEFzc3VyZWQgSUQgUm9vdCBDQTAeFw0wNjExMTAwMDAwMDBa
# Fw0zMTExMTAwMDAwMDBaMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2Vy
# dCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lD
# ZXJ0IEFzc3VyZWQgSUQgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
# AQoCggEBAK0OFc7kQ4BcsYfzt2D5cRKlrtwmlIiq9M71IDkoWGAM+IDaqRWVMmE8
# tbEohIqK3J8KDIMXeo+QrIrneVNcMYQq9g+YMjZ2zN7dPKii72r7IfJSYd+fINcf
# 4rHZ/hhk0hJbX/lYGDW8R82hNvlrf9SwOD7BG8OMM9nYLxj+KA+zp4PWw25EwGE1
# lhb+WZyLdm3X8aJLDSv/C3LanmDQjpA1xnhVhyChz+VtCshJfDGYM2wi6YfQMlqi
# uhOCEe05F52ZOnKh5vqk2dUXMXWuhX0irj8BRob2KHnIsdrkVxfEfhwOsLSSplaz
# vbKX7aqn8LfFqD+VFtD/oZbrCF8Yd08CAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGG
# MA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFEXroq/0ksuCMS1Ri6enIZ3zbcgP
# MB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA0GCSqGSIb3DQEBBQUA
# A4IBAQCiDrzf4u3w43JzemSUv/dyZtgy5EJ1Yq6H6/LV2d5Ws5/MzhQouQ2XYFwS
# TFjk0z2DSUVYlzVpGqhH6lbGeasS2GeBhN9/CTyU5rgmLCC9PbMoifdf/yLil4Qf
# 6WXvh+DfwWdJs13rsgkq6ybteL59PyvztyY1bV+JAbZJW58BBZurPSXBzLZ/wvFv
# hsb6ZGjrgS2U60K3+owe3WLxvlBnt2y98/Efaww2BxZ/N3ypW2168RJGYIPXJwS+
# S86XvsNnKmgR34DnDDNmvxMNFG7zfx9jEB76jRslbWyPpbdhAbHSoyahEHGdreLD
# +cOZUbcrBwjOLuZQsqf6CkUvovDyMIIFMDCCBBigAwIBAgIQBAkYG1/Vu2Z1U0O1
# b5VQCDANBgkqhkiG9w0BAQsFADBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGln
# aUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtE
# aWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwHhcNMTMxMDIyMTIwMDAwWhcNMjgx
# MDIyMTIwMDAwWjByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5j
# MRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBT
# SEEyIEFzc3VyZWQgSUQgQ29kZSBTaWduaW5nIENBMIIBIjANBgkqhkiG9w0BAQEF
# AAOCAQ8AMIIBCgKCAQEA+NOzHH8OEa9ndwfTCzFJGc/Q+0WZsTrbRPV/5aid2zLX
# cep2nQUut4/6kkPApfmJ1DcZ17aq8JyGpdglrA55KDp+6dFn08b7KSfH03sjlOSR
# I5aQd4L5oYQjZhJUM1B0sSgmuyRpwsJS8hRniolF1C2ho+mILCCVrhxKhwjfDPXi
# TWAYvqrEsq5wMWYzcT6scKKrzn/pfMuSoeU7MRzP6vIK5Fe7SrXpdOYr/mzLfnQ5
# Ng2Q7+S1TqSp6moKq4TzrGdOtcT3jNEgJSPrCGQ+UpbB8g8S9MWOD8Gi6CxR93O8
# vYWxYoNzQYIH5DiLanMg0A9kczyen6Yzqf0Z3yWT0QIDAQABo4IBzTCCAckwEgYD
# VR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwEwYDVR0lBAwwCgYIKwYB
# BQUHAwMweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5k
# aWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0
# LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgwOqA4
# oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJv
# b3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2Vy
# dEFzc3VyZWRJRFJvb3RDQS5jcmwwTwYDVR0gBEgwRjA4BgpghkgBhv1sAAIEMCow
# KAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwCgYIYIZI
# AYb9bAMwHQYDVR0OBBYEFFrEuXsqCqOl6nEDwGD5LfZldQ5YMB8GA1UdIwQYMBaA
# FEXroq/0ksuCMS1Ri6enIZ3zbcgPMA0GCSqGSIb3DQEBCwUAA4IBAQA+7A1aJLPz
# ItEVyCx8JSl2qB1dHC06GsTvMGHXfgtg/cM9D8Svi/3vKt8gVTew4fbRknUPUbRu
# pY5a4l4kgU4QpO4/cY5jDhNLrddfRHnzNhQGivecRk5c/5CxGwcOkRX7uq+1UcKN
# JK4kxscnKqEpKBo6cSgCPC6Ro8AlEeKcFEehemhor5unXCBc2XGxDI+7qPjFEmif
# z0DLQESlE/DmZAwlCEIysjaKJAL+L3J+HNdJRZboWR3p+nRka7LrZkPas7CM1ekN
# 3fYBIM6ZMWM9CBoYs4GbT8aTEAb8B4H6i9r5gkn3Ym6hU/oSlBiFLpKR6mhsRDKy
# ZqHnGKSaZFHvMIIFPTCCBCWgAwIBAgIQBNXcH0jqydhSALrNmpsqpzANBgkqhkiG
# 9w0BAQsFADByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkw
# FwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEy
# IEFzc3VyZWQgSUQgQ29kZSBTaWduaW5nIENBMB4XDTIwMDYyNjAwMDAwMFoXDTIz
# MDcwNzEyMDAwMFowejELMAkGA1UEBhMCUEwxEjAQBgNVBAgMCcWabMSFc2tpZTER
# MA8GA1UEBxMIS2F0b3dpY2UxITAfBgNVBAoMGFByemVteXPFgmF3IEvFgnlzIEVW
# T1RFQzEhMB8GA1UEAwwYUHJ6ZW15c8WCYXcgS8WCeXMgRVZPVEVDMIIBIjANBgkq
# hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv7KB3iyBrhkLUbbFe9qxhKKPBYqDBqln
# r3AtpZplkiVjpi9dMZCchSeT5ODsShPuZCIxJp5I86uf8ibo3vi2S9F9AlfFjVye
# 3dTz/9TmCuGH8JQt13ozf9niHecwKrstDVhVprgxi5v0XxY51c7zgMA2g1Ub+3ti
# i0vi/OpmKXdL2keNqJ2neQ5cYly/GsI8CREUEq9SZijbdA8VrRF3SoDdsWGf3tZZ
# zO6nWn3TLYKQ5/bw5U445u/V80QSoykszHRivTj+H4s8ABiforhi0i76beA6Ea41
# zcH4zJuAp48B4UhjgRDNuq8IzLWK4dlvqrqCBHKqsnrF6BmBrv+BXQIDAQABo4IB
# xTCCAcEwHwYDVR0jBBgwFoAUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHQYDVR0OBBYE
# FBixNSfoHFAgJk4JkDQLFLRNlJRmMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAK
# BggrBgEFBQcDAzB3BgNVHR8EcDBuMDWgM6Axhi9odHRwOi8vY3JsMy5kaWdpY2Vy
# dC5jb20vc2hhMi1hc3N1cmVkLWNzLWcxLmNybDA1oDOgMYYvaHR0cDovL2NybDQu
# ZGlnaWNlcnQuY29tL3NoYTItYXNzdXJlZC1jcy1nMS5jcmwwTAYDVR0gBEUwQzA3
# BglghkgBhv1sAwEwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQu
# Y29tL0NQUzAIBgZngQwBBAEwgYQGCCsGAQUFBwEBBHgwdjAkBggrBgEFBQcwAYYY
# aHR0cDovL29jc3AuZGlnaWNlcnQuY29tME4GCCsGAQUFBzAChkJodHRwOi8vY2Fj
# ZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRTSEEyQXNzdXJlZElEQ29kZVNpZ25p
# bmdDQS5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAQEAmr1sz4ls
# LARi4wG1eg0B8fVJFowtect7SnJUrp6XRnUG0/GI1wXiLIeow1UPiI6uDMsRXPHU
# F/+xjJw8SfIbwava2eXu7UoZKNh6dfgshcJmo0QNAJ5PIyy02/3fXjbUREHINrTC
# vPVbPmV6kx4Kpd7KJrCo7ED18H/XTqWJHXa8va3MYLrbJetXpaEPpb6zk+l8Rj9y
# G4jBVRhenUBUUj3CLaWDSBpOA/+sx8/XB9W9opYfYGb+1TmbCkhUg7TB3gD6o6ES
# Jre+fcnZnPVAPESmstwsT17caZ0bn7zETKlNHbc1q+Em9kyBjaQRcEQoQQNpezQu
# g9ufqExx6lHYDjCCBY0wggR1oAMCAQICEA6bGI750C3n79tQ4ghAGFowDQYJKoZI
# hvcNAQEMBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
# MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNz
# dXJlZCBJRCBSb290IENBMB4XDTIyMDgwMTAwMDAwMFoXDTMxMTEwOTIzNTk1OVow
# YjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQ
# d3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgVHJ1c3RlZCBSb290
# IEc0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAv+aQc2jeu+RdSjww
# IjBpM+zCpyUuySE98orYWcLhKac9WKt2ms2uexuEDcQwH/MbpDgW61bGl20dq7J5
# 8soR0uRf1gU8Ug9SH8aeFaV+vp+pVxZZVXKvaJNwwrK6dZlqczKU0RBEEC7fgvMH
# hOZ0O21x4i0MG+4g1ckgHWMpLc7sXk7Ik/ghYZs06wXGXuxbGrzryc/NrDRAX7F6
# Zu53yEioZldXn1RYjgwrt0+nMNlW7sp7XeOtyU9e5TXnMcvak17cjo+A2raRmECQ
# ecN4x7axxLVqGDgDEI3Y1DekLgV9iPWCPhCRcKtVgkEy19sEcypukQF8IUzUvK4b
# A3VdeGbZOjFEmjNAvwjXWkmkwuapoGfdpCe8oU85tRFYF/ckXEaPZPfBaYh2mHY9
# WV1CdoeJl2l6SPDgohIbZpp0yt5LHucOY67m1O+SkjqePdwA5EUlibaaRBkrfsCU
# tNJhbesz2cXfSwQAzH0clcOP9yGyshG3u3/y1YxwLEFgqrFjGESVGnZifvaAsPvo
# ZKYz0YkH4b235kOkGLimdwHhD5QMIR2yVCkliWzlDlJRR3S+Jqy2QXXeeqxfjT/J
# vNNBERJb5RBQ6zHFynIWIgnffEx1P2PsIV/EIFFrb7GrhotPwtZFX50g/KEexcCP
# orF+CiaZ9eRpL5gdLfXZqbId5RsCAwEAAaOCATowggE2MA8GA1UdEwEB/wQFMAMB
# Af8wHQYDVR0OBBYEFOzX44LScV1kTN8uZz/nupiuHA9PMB8GA1UdIwQYMBaAFEXr
# oq/0ksuCMS1Ri6enIZ3zbcgPMA4GA1UdDwEB/wQEAwIBhjB5BggrBgEFBQcBAQRt
# MGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBDBggrBgEF
# BQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJl
# ZElEUm9vdENBLmNydDBFBgNVHR8EPjA8MDqgOKA2hjRodHRwOi8vY3JsMy5kaWdp
# Y2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURSb290Q0EuY3JsMBEGA1UdIAQKMAgw
# BgYEVR0gADANBgkqhkiG9w0BAQwFAAOCAQEAcKC/Q1xV5zhfoKN0Gz22Ftf3v1cH
# vZqsoYcs7IVeqRq7IviHGmlUIu2kiHdtvRoU9BNKei8ttzjv9P+Aufih9/Jy3iS8
# UgPITtAq3votVs/59PesMHqai7Je1M/RQ0SbQyHrlnKhSLSZy51PpwYDE3cnRNTn
# f+hZqPC/Lwum6fI0POz3A8eHqNJMQBk1RmppVLC4oVaO7KTVPeix3P0c2PR3WlxU
# jG/voVA9/HYJaISfb8rbII01YBwCA8sgsKxYoA5AY8WYIsGyWfVVa88nq2x2zm8j
# LfR+cWojayL/ErhULSd+2DrZ8LaHlv1b0VysGMNNn3O3AamfV6peKOK5lDCCBq4w
# ggSWoAMCAQICEAc2N7ckVHzYR6z9KGYqXlswDQYJKoZIhvcNAQELBQAwYjELMAkG
# A1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRp
# Z2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgVHJ1c3RlZCBSb290IEc0MB4X
# DTIyMDMyMzAwMDAwMFoXDTM3MDMyMjIzNTk1OVowYzELMAkGA1UEBhMCVVMxFzAV
# BgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMTswOQYDVQQDEzJEaWdpQ2VydCBUcnVzdGVk
# IEc0IFJTQTQwOTYgU0hBMjU2IFRpbWVTdGFtcGluZyBDQTCCAiIwDQYJKoZIhvcN
# AQEBBQADggIPADCCAgoCggIBAMaGNQZJs8E9cklRVcclA8TykTepl1Gh1tKD0Z5M
# om2gsMyD+Vr2EaFEFUJfpIjzaPp985yJC3+dH54PMx9QEwsmc5Zt+FeoAn39Q7SE
# 2hHxc7Gz7iuAhIoiGN/r2j3EF3+rGSs+QtxnjupRPfDWVtTnKC3r07G1decfBmWN
# lCnT2exp39mQh0YAe9tEQYncfGpXevA3eZ9drMvohGS0UvJ2R/dhgxndX7RUCyFo
# bjchu0CsX7LeSn3O9TkSZ+8OpWNs5KbFHc02DVzV5huowWR0QKfAcsW6Th+xtVhN
# ef7Xj3OTrCw54qVI1vCwMROpVymWJy71h6aPTnYVVSZwmCZ/oBpHIEPjQ2OAe3Vu
# JyWQmDo4EbP29p7mO1vsgd4iFNmCKseSv6De4z6ic/rnH1pslPJSlRErWHRAKKtz
# Q87fSqEcazjFKfPKqpZzQmiftkaznTqj1QPgv/CiPMpC3BhIfxQ0z9JMq++bPf4O
# uGQq+nUoJEHtQr8FnGZJUlD0UfM2SU2LINIsVzV5K6jzRWC8I41Y99xh3pP+OcD5
# sjClTNfpmEpYPtMDiP6zj9NeS3YSUZPJjAw7W4oiqMEmCPkUEBIDfV8ju2TjY+Cm
# 4T72wnSyPx4JduyrXUZ14mCjWAkBKAAOhFTuzuldyF4wEr1GnrXTdrnSDmuZDNIz
# tM2xAgMBAAGjggFdMIIBWTASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBS6
# FtltTYUvcyl2mi91jGogj57IbzAfBgNVHSMEGDAWgBTs1+OC0nFdZEzfLmc/57qY
# rhwPTzAOBgNVHQ8BAf8EBAMCAYYwEwYDVR0lBAwwCgYIKwYBBQUHAwgwdwYIKwYB
# BQUHAQEEazBpMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20w
# QQYIKwYBBQUHMAKGNWh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2Vy
# dFRydXN0ZWRSb290RzQuY3J0MEMGA1UdHwQ8MDowOKA2oDSGMmh0dHA6Ly9jcmwz
# LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRSb290RzQuY3JsMCAGA1UdIAQZ
# MBcwCAYGZ4EMAQQCMAsGCWCGSAGG/WwHATANBgkqhkiG9w0BAQsFAAOCAgEAfVmO
# wJO2b5ipRCIBfmbW2CFC4bAYLhBNE88wU86/GPvHUF3iSyn7cIoNqilp/GnBzx0H
# 6T5gyNgL5Vxb122H+oQgJTQxZ822EpZvxFBMYh0MCIKoFr2pVs8Vc40BIiXOlWk/
# R3f7cnQU1/+rT4osequFzUNf7WC2qk+RZp4snuCKrOX9jLxkJodskr2dfNBwCnzv
# qLx1T7pa96kQsl3p/yhUifDVinF2ZdrM8HKjI/rAJ4JErpknG6skHibBt94q6/ae
# sXmZgaNWhqsKRcnfxI2g55j7+6adcq/Ex8HBanHZxhOACcS2n82HhyS7T6NJuXdm
# kfFynOlLAlKnN36TU6w7HQhJD5TNOXrd/yVjmScsPT9rp/Fmw0HNT7ZAmyEhQNC3
# EyTN3B14OuSereU0cZLXJmvkOHOrpgFPvT87eK1MrfvElXvtCl8zOYdBeHo46Zzh
# 3SP9HSjTx/no8Zhf+yvYfvJGnXUsHicsJttvFXseGYs2uJPU5vIXmVnKcPA3v5gA
# 3yAWTyf7YGcWoWa63VXAOimGsJigK+2VQbc61RWYMbRiCQ8KvYHZE/6/pNHzV9m8
# BPqC3jLfBInwAM1dwvnQI38AC+R2AibZ8GV2QqYphwlHK+Z/GqSFD/yYlvZVVCsf
# gPrA8g4r5db7qS9EFUrnEw4d2zc4GqEr9u3WfPwwggbGMIIErqADAgECAhAKekqI
# nsmZQpAGYzhNhpedMA0GCSqGSIb3DQEBCwUAMGMxCzAJBgNVBAYTAlVTMRcwFQYD
# VQQKEw5EaWdpQ2VydCwgSW5jLjE7MDkGA1UEAxMyRGlnaUNlcnQgVHJ1c3RlZCBH
# NCBSU0E0MDk2IFNIQTI1NiBUaW1lU3RhbXBpbmcgQ0EwHhcNMjIwMzI5MDAwMDAw
# WhcNMzMwMzE0MjM1OTU5WjBMMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNl
# cnQsIEluYy4xJDAiBgNVBAMTG0RpZ2lDZXJ0IFRpbWVzdGFtcCAyMDIyIC0gMjCC
# AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALkqliOmXLxf1knwFYIY9DPu
# zFxs4+AlLtIx5DxArvurxON4XX5cNur1JY1Do4HrOGP5PIhp3jzSMFENMQe6Rm7p
# o0tI6IlBfw2y1vmE8Zg+C78KhBJxbKFiJgHTzsNs/aw7ftwqHKm9MMYW2Nq867Lx
# g9GfzQnFuUFqRUIjQVr4YNNlLD5+Xr2Wp/D8sfT0KM9CeR87x5MHaGjlRDRSXw9Q
# 3tRZLER0wDJHGVvimC6P0Mo//8ZnzzyTlU6E6XYYmJkRFMUrDKAz200kheiClOEv
# A+5/hQLJhuHVGBS3BEXz4Di9or16cZjsFef9LuzSmwCKrB2NO4Bo/tBZmCbO4O2u
# fyguwp7gC0vICNEyu4P6IzzZ/9KMu/dDI9/nw1oFYn5wLOUrsj1j6siugSBrQ4nI
# fl+wGt0ZvZ90QQqvuY4J03ShL7BUdsGQT5TshmH/2xEvkgMwzjC3iw9dRLNDHSNQ
# zZHXL537/M2xwafEDsTvQD4ZOgLUMalpoEn5deGb6GjkagyP6+SxIXuGZ1h+fx/o
# K+QUshbWgaHK2jCQa+5vdcCwNiayCDv/vb5/bBMY38ZtpHlJrYt/YYcFaPfUcONC
# leieu5tLsuK2QT3nr6caKMmtYbCgQRgZTu1Hm2GV7T4LYVrqPnqYklHNP8lE54CL
# KUJy93my3YTqJ+7+fXprAgMBAAGjggGLMIIBhzAOBgNVHQ8BAf8EBAMCB4AwDAYD
# VR0TAQH/BAIwADAWBgNVHSUBAf8EDDAKBggrBgEFBQcDCDAgBgNVHSAEGTAXMAgG
# BmeBDAEEAjALBglghkgBhv1sBwEwHwYDVR0jBBgwFoAUuhbZbU2FL3MpdpovdYxq
# II+eyG8wHQYDVR0OBBYEFI1kt4kh/lZYRIRhp+pvHDaP3a8NMFoGA1UdHwRTMFEw
# T6BNoEuGSWh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRH
# NFJTQTQwOTZTSEEyNTZUaW1lU3RhbXBpbmdDQS5jcmwwgZAGCCsGAQUFBwEBBIGD
# MIGAMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wWAYIKwYB
# BQUHMAKGTGh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0
# ZWRHNFJTQTQwOTZTSEEyNTZUaW1lU3RhbXBpbmdDQS5jcnQwDQYJKoZIhvcNAQEL
# BQADggIBAA0tI3Sm0fX46kuZPwHk9gzkrxad2bOMl4IpnENvAS2rOLVwEb+EGYs/
# XeWGT76TOt4qOVo5TtiEWaW8G5iq6Gzv0UhpGThbz4k5HXBw2U7fIyJs1d/2Wcuh
# wupMdsqh3KErlribVakaa33R9QIJT4LWpXOIxJiA3+5JlbezzMWn7g7h7x44ip/v
# EckxSli23zh8y/pc9+RTv24KfH7X3pjVKWWJD6KcwGX0ASJlx+pedKZbNZJQfPQX
# podkTz5GiRZjIGvL8nvQNeNKcEiptucdYL0EIhUlcAZyqUQ7aUcR0+7px6A+TxC5
# MDbk86ppCaiLfmSiZZQR+24y8fW7OK3NwJMR1TJ4Sks3KkzzXNy2hcC7cDBVeNaY
# /lRtf3GpSBp43UZ3Lht6wDOK+EoojBKoc88t+dMj8p4Z4A2UKKDr2xpRoJWCjihr
# pM6ddt6pc6pIallDrl/q+A8GQp3fBmiW/iqgdFtjZt5rLLh4qk1wbfAs8QcVfjW0
# 5rUMopml1xVrNQ6F1uAszOAMJLh8UgsemXzvyMjFjFhpr6s94c/MfRWuFL+Kcd/K
# l7HYR+ocheBFThIcFClYzG/Tf8u+wQ5KbyCcrtlzMlkI5y2SoRoR/jKYpl0rl+CL
# 05zMbbUNrkdjOEcXW28T2moQbh9Jt0RbtAgKh1pZBHYRoad3AhMcMYIFXTCCBVkC
# AQEwgYYwcjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcG
# A1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBB
# c3N1cmVkIElEIENvZGUgU2lnbmluZyBDQQIQBNXcH0jqydhSALrNmpsqpzANBglg
# hkgBZQMEAgEFAKCBhDAYBgorBgEEAYI3AgEMMQowCKACgAChAoAAMBkGCSqGSIb3
# DQEJAzEMBgorBgEEAYI3AgEEMBwGCisGAQQBgjcCAQsxDjAMBgorBgEEAYI3AgEV
# MC8GCSqGSIb3DQEJBDEiBCCHg53chAnGCwlCM3JQBYVQtiCjYYkfuHBFXbGu+omk
# fjANBgkqhkiG9w0BAQEFAASCAQBCm+N0UNcx4+gaV8dc9ntJyVYE5UUJ0yUm5Gf0
# N3ofaav2AKcJz2erwQzS/7vz76rQDZM4PXtfwzFzlEGIBLrvOPyT30AmQn+9PVWf
# JGlYYba+DDJrpJyNnipsYBsgL6qD6hO3rg0WOR9+yH8yJ5yEOSAu+EpWsbbPp4HH
# i5Pt3K274WhP+KqRBAGVVheQr+SkT/iDzFTlchJdunGSK68MmACX0nmroyXj7UZr
# ZlnGPbw/PEUmLVECpzyqyHo2CQyAuPA6H+EPWxRFi7tveEzrhsOK89L8yMdf1fr2
# hg8YqMnAufQj2G4OLMrGtzdFwOfy6BBeZojDmByi1XRJhtHooYIDIDCCAxwGCSqG
# SIb3DQEJBjGCAw0wggMJAgEBMHcwYzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRp
# Z2lDZXJ0LCBJbmMuMTswOQYDVQQDEzJEaWdpQ2VydCBUcnVzdGVkIEc0IFJTQTQw
# OTYgU0hBMjU2IFRpbWVTdGFtcGluZyBDQQIQCnpKiJ7JmUKQBmM4TYaXnTANBglg
# hkgBZQMEAgEFAKBpMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcN
# AQkFMQ8XDTIyMDgxNDA3MzQzN1owLwYJKoZIhvcNAQkEMSIEIBlz3jb2DcRHnUIt
# BboP2VeNpdb0vJivaE2cfD0/xWHjMA0GCSqGSIb3DQEBAQUABIICADEcV4MeTtLi
# FWiQQ1zCtfqoGJQ8jgmDjwp1dClrBApLuRP4X1UwAwc92EdVVCYiLJoRmhx29D/x
# fSWaJfoGOI4+wEminJG9xYDyJDCog33E61dgPC82f0nJLgFsK0IFNJbt8lJC0Pue
# nco9u+32htrAVmVPUEKYuC1IJJFGohgexx9lfobS8WiqfJW1z05M0uCt0ochENTL
# wHR5HRKz3SsJr+yG6Wv6s6NhXVk2m5nOSL2EGkbKhCmMT1bDRaJJHSvodODHWWXG
# xSG4FSgz7ZCMlju0PxAwEmHf5R7fWrFVGYgvkAODyUZAqIhY7p2dq/uqLeJikK40
# OpC0vEmRpvnMxxHRu1ZaIFr6MLglgU5OpVs2kaTTIbiEjVnhQaKdByjrgNwLK4Ji
# KyqKNLg5Q920M4b2hEROW4lvv4KoScSBBNmR7vZUg99l1LipwHA7ojyDuu4Rtu3+
# TIRCymaBD/RVyeeyoWEcpUqxQTx0ALDCAlI/GgEBN5nN5wDTnoEfnEheRYIfkhex
# AknU8KpwJbNRf1oIxLIk2XdkrgRcm/Q9xJ2ba0Oa8ao+9oCAY94JGMsV9v1MD5Nk
# kOi/HsZtORmjrTx4fefzJ5XD91Ug16zZoyYubO3r5QOqTaYjvoRYts4K6BciTxfX
# TpaBDJD5A9gavaa+odk2UTPhYjQZyjos
# SIG # End signature block