spacer PowerShell Code Repository

HelpModules 2.1 by Joel Bennett 7 weeks ago (modification of post by Joel Bennett view diff)
diff | embed code: <script type="text/javascript" src="/img/spacer.gif"> download | new post

A module to let you fetch and read help for modules you don’t have! Now Get-ModuleHelp works without specifying the ModuleName, and you can easily fetch help for modules from remote servers.

  1. # HelpModules
  2. #    A Module for generating module stubs so you can Update-Help (or Save-Help)
  3. #    Includes two options for reading the help from those modules (StubFunctions or Get-ModuleHelp)
  4. # 1.0 - 2013/2/1 - Initial release Friday, Feb 1st, 2013
  5. # 2.0 - 2013/2/1 - Updated release with improved pipeline/remoting support
  6. # 2.1 - 2013/2/1 - Minor change to allow the ModuleName to be empty in Get-ModuleHelp
  7. $PSModuleHelpRoot = Convert-Path "~\Documents\WindowsPowerShellModuleHelp"
  8.  
  9. function New-HelpModule {
  10.   #.Synopsis
  11.   #   Creates a dummy module and fetches the help files for it
  12.   #.Example
  13.   #   Get-Module Hyper-V -ListAvailable | New-HelpModule
  14.   #
  15.   #   Generates a new module stub from an existing module
  16.   #.Example
  17.   #   Invoke-Command -ComputerName $Servers { Get-Module -ListAvailable | Where HelpInfoUri } | New-HelpModule
  18.   #
  19.   #   Generates local Help-only Modules for all the updatable help modules which exist on the specified server
  20.   #.Example
  21.   #   New-HelpModule Hyper-V '1.0' 'af4bddd0-8583-4ff2-84b2-a33f5c8de8a7' 'go.microsoft.com/fwlink/?LinkId=206726'
  22.   #
  23.   #   Generates a new help module from the specified values (You can get the information about the module in an email, text message, phone call, etc!)
  24.   [CmdletBinding(DefaultParameterSetName="ModuleInfo")]
  25.   param(
  26.     # The name of the module you want to create a dummy for.
  27.     [Parameter(ValueFromPipelineByPropertyName=$true, Mandatory=$true, Position=0)]
  28.     [Alias("Name")]
  29.     [String]$ModuleName,
  30.  
  31.     # The version of the module you want to create a dummy for.
  32.     [Parameter(ValueFromPipelineByPropertyName=$true, Mandatory=$true, Position=1)]
  33.     [String]$Version,
  34.  
  35.     # The exact guid of the module you want to create a dummy for.
  36.     [Parameter(ValueFromPipelineByPropertyName=$true, Mandatory=$true, Position=2)]
  37.     [Guid]$Guid,
  38.  
  39.     # The HelpInfoUri of the module you want to create a dummy for.
  40.     [Parameter(ValueFromPipelineByPropertyName=$true, Mandatory=$true, Position=3)]
  41.     [String]$HelpInfoUri,
  42.  
  43.     # A list of commands to generate StubFunctions for.
  44.     #
  45.     # NOTE: stub functions will not be generated unless you also specify the -StubFunctions switch (see help on that parameter)
  46.     [Parameter(ValueFromPipelineByPropertyName=$true)]
  47.     $ExportedCommands,
  48.  
  49.     # A path to put the help modules in. Defaults to $PSModuleHelpRoot (which defaults to "~\Documents\WindowsPowerShellModuleHelp").
  50.     [String]$ModuleHelpRoot = $PSModuleHelpRoot,
  51.  
  52.     # The culture(s) you want to fetch help for (defaults to $PSUICulture)
  53.     [Alias("Culture","PSCulture")]
  54.     [CultureInfo[]]$HelpCulture = ${PSUICulture},
  55.  
  56.     # If set, generates a Blank.psm1 with stub functions in it so that you can import the dummy module and use the built-in Get-Help instead of our Get-ModuleHelp
  57.     #
  58.     # Setting this may pollute your PowerShell session with dozens or hudreds of commands which don't do anything. You probably shouldn't, for instance, add your ModuleHelpRoot path to your PSModulePath if you do this.
  59.     [Switch]$StubFunctions
  60.   )
  61.   begin {
  62.     $ModulesToUpdate = @()
  63.   }
  64.   process {
  65.     # Make the ModuleHelpRoot\ModuleName folder if it's not there
  66.     $ModuleDir = mkdir ${ModuleHelpRoot}\${ModuleName}\ -Force
  67.  
  68.     if($ExportedCommands -is [System.Collections.Generic.Dictionary[System.String,System.Management.Automation.CommandInfo]]) {
  69.       [string[]]$ExportedCommands = $ExportedCommands.Keys
  70.     }
  71.  
  72.     # Generate the stub ModuleManifest
  73.     New-ModuleManifest -Path ${ModuleHelpRoot}\${ModuleName}\${ModuleName}.psd1 `
  74.       -Guid $Guid -HelpInfoUri $HelpInfoUri -ModuleVersion $Version `
  75.       -FunctionsToExport $ExportedCommands `
  76.       -RootModule "Blank.psm1"
  77.  
  78.     $ModulesToUpdate += $ModuleName
  79.  
  80.     # Generate stub FunctionsToExport
  81.     if($StubFunctions) {
  82.       Remove-Item "${ModuleHelpRoot}\${ModuleName}\Blank.psm1" -ErrorAction SilentlyContinue
  83.       foreach($name in $ExportedCommands) {
  84.         Add-Content "${ModuleHelpRoot}\${ModuleName}\Blank.psm1" "#.ExternalHelp *.xml `nfunction $name {}`n"
  85.       }
  86.     }
  87.   }
  88.   end {
  89.     # Update the help files -- this is why we're here.
  90.     # TODO: if we're generating a lot of modules, it would be really to only do this once!
  91.     PowerShell -NoProfile -Command "&{ `$Env:PSModulePath = '$ModuleHelpRoot'; Update-Help -Module '$($ModulesToUpdate -join "','")' -UICulture '$($HelpCulture -join "','")'}"
  92.   }
  93. }
  94.  
  95. function Get-ModuleHelp {
  96.   #.Synopsis
  97.   #  Gets help from the XML help files directly without worrying about whether the commands actually exist.
  98.   [CmdletBinding(DefaultParameterSetName="MamlCommandHelpInfo")]
  99.   param(
  100.     # The command you want help for
  101.     [Alias("Name")]
  102.     [Parameter(Mandatory=$true, Position = 0, ValueFromPipelineByPropertyName = $true)]
  103.     $CommandName,
  104.     # The name of the module the command is in
  105.     # TODO: Search Get-Module -ListAvailable for modules which *say* they have the command
  106.     [Parameter(Position = 1, ValueFromPipelineByPropertyName = $true)]
  107.     $ModuleName = "*",
  108.  
  109.     # A path to search for help modules in. Defaults to $PSModuleHelpRoot (which defaults to "~\Documents\WindowsPowerShellModuleHelp").
  110.     $ModuleHelpRoot = $PSModuleHelpRoot,
  111.  
  112.     # Displays only the detailed descriptions of the specified parameters. Wildcards are permitted.
  113.     [Parameter(ParameterSetName="MamlCommandHelpInfo#parameter")]
  114.     [String]$Parameter,
  115.  
  116.     # Displays only the name, synopsis, and examples".
  117.     [Parameter(ParameterSetName="MamlCommandHelpInfo#ExamplesView")]
  118.     [Switch]$Examples,
  119.  
  120.     # Displays the entire help topic for a cmdlet, including parameter descriptions and attributes, examples, input and output object types, and additional notes.
  121.     [Parameter(ParameterSetName="MamlCommandHelpInfo#FullView")]
  122.     [Switch]$Full,
  123.  
  124.     # Adds parameter descriptions and examples to the basic help display.
  125.     [Parameter(ParameterSetName="MamlCommandHelpInfo#DetailedView")]
  126.     [Switch]$Detailed,
  127.  
  128.     # The culture you want to fetch help for (defaults to $PSUICulture)
  129.     [Alias("Culture","PSCulture")]
  130.     [CultureInfo]$HelpCulture = ${PSUICulture}
  131.   )
  132.   process {
  133.     Write-Verbose "Culture: $HelpCulture HelpSet: $($PSCmdlet.ParameterSetName)"
  134.     $matched = $false
  135.     foreach($node in Select-Xml "//*[local-name() = 'details']/*[local-name() = 'name' and text() = '$CommandName']/../.." -Path ${ModuleHelpRoot}\${ModuleName}\${PSUICulture}\*.xml | Select-Object -Expand Node) {
  136.       if($Parameter) {
  137.         foreach($param in $node.parameters.parameter) {
  138.           if($param.name -like $Parameter) {
  139.             $matched = $true
  140.             $param | FixMaml -Type $($PSCmdlet.ParameterSetName)
  141.           }
  142.         }
  143.         if(!$matched) {
  144.           throw "No parameter matches criteria $Parameter"
  145.         }
  146.       } else {
  147.         $matched = $true
  148.         $node | FixMaml -Type $($PSCmdlet.ParameterSetName)
  149.       }
  150.     }
  151.   }
  152. }
  153.  
  154. function FixMaml {
  155.   #.Synopsis
  156.   # Internal command for tweaking the XML just enough that PowerShell will format it properly
  157.   [CmdletBinding()]
  158.   param(
  159.     [Parameter(ValueFromPipeline=$true)]
  160.     $Node,
  161.  
  162.     [Parameter(Mandatory=$true)]
  163.     $Type = "MamlCommandHelpInfo"
  164.   )
  165.   process {
  166.     $node.PSTypeNames.Clear()
  167.     $node.PSTypeNames.Add($type)      
  168.     if($node.description) {
  169.       Add-Member -Input $node NoteProperty description @(
  170.         $Node.RemoveChild($node.description).para | % {
  171.           $p = New-Object PSObject -Property @{ Text = $_ };
  172.           $p.PSTypeNames.Clear();
  173.           $p.PSTypeNames.Add("MamlParaTextItem");
  174.           $p
  175.         } )
  176.     }
  177.     if($node.details) {
  178.       # Fix them, but don't output recursively
  179.       $null = $node.details | FixMaml -Type $Type
  180.     }
  181.     Write-Output $node  
  182.   }
  183. }
  184.  
  185. Export-ModuleMember -Function New-HelpModule, Get-ModuleHelp -Variable PSModuleHelpRoot
  186.  
  187. # SIG # Begin signature block
  188. # MIIfIAYJKoZIhvcNAQcCoIIfETCCHw0CAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
  189. # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
  190. # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUe4XjjCbhvPRJIycXpKAA3E/Y
  191. # waqgghpSMIID7jCCA1egAwIBAgIQfpPr+3zGTlnqS5p31Ab8OzANBgkqhkiG9w0B
  192. # AQUFADCBizELMAkGA1UEBhMCWkExFTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTEUMBIG
  193. # A1UEBxMLRHVyYmFudmlsbGUxDzANBgNVBAoTBlRoYXd0ZTEdMBsGA1UECxMUVGhh
  194. # d3RlIENlcnRpZmljYXRpb24xHzAdBgNVBAMTFlRoYXd0ZSBUaW1lc3RhbXBpbmcg
  195. # Q0EwHhcNMTIxMjIxMDAwMDAwWhcNMjAxMjMwMjM1OTU5WjBeMQswCQYDVQQGEwJV
  196. # UzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xMDAuBgNVBAMTJ1N5bWFu
  197. # dGVjIFRpbWUgU3RhbXBpbmcgU2VydmljZXMgQ0EgLSBHMjCCASIwDQYJKoZIhvcN
  198. # AQEBBQADggEPADCCAQoCggEBALGss0lUS5ccEgrYJXmRIlcqb9y4JsRDc2vCvy5Q
  199. # WvsUwnaOQwElQ7Sh4kX06Ld7w3TMIte0lAAC903tv7S3RCRrzV9FO9FEzkMScxeC
  200. # i2m0K8uZHqxyGyZNcR+xMd37UWECU6aq9UksBXhFpS+JzueZ5/6M4lc/PcaS3Er4
  201. # ezPkeQr78HWIQZz/xQNRmarXbJ+TaYdlKYOFwmAUxMjJOxTawIHwHw103pIiq8r3
  202. # +3R8J+b3Sht/p8OeLa6K6qbmqicWfWH3mHERvOJQoUvlXfrlDqcsn6plINPYlujI
  203. # fKVOSET/GeJEB5IL12iEgF1qeGRFzWBGflTBE3zFefHJwXECAwEAAaOB+jCB9zAd
  204. # BgNVHQ4EFgQUX5r1blzMzHSa1N197z/b7EyALt0wMgYIKwYBBQUHAQEEJjAkMCIG
  205. # CCsGAQUFBzABhhZodHRwOi8vb2NzcC50aGF3dGUuY29tMBIGA1UdEwEB/wQIMAYB
  206. # Af8CAQAwPwYDVR0fBDgwNjA0oDKgMIYuaHR0cDovL2NybC50aGF3dGUuY29tL1Ro
  207. # YXd0ZVRpbWVzdGFtcGluZ0NBLmNybDATBgNVHSUEDDAKBggrBgEFBQcDCDAOBgNV
  208. # HQ8BAf8EBAMCAQYwKAYDVR0RBCEwH6QdMBsxGTAXBgNVBAMTEFRpbWVTdGFtcC0y
  209. # MDQ4LTEwDQYJKoZIhvcNAQEFBQADgYEAAwmbj3nvf1kwqu9otfrjCR27T4IGXTdf
  210. # plKfFo3qHJIJRG71betYfDDo+WmNI3MLEm9Hqa45EfgqsZuwGsOO61mWAK3ODE2y
  211. # 0DGmCFwqevzieh1XTKhlGOl5QGIllm7HxzdqgyEIjkHq3dlXPx13SYcqFgZepjhq
  212. # IhKjURmDfrYwggRPMIIDuKADAgECAgQHJ1g9MA0GCSqGSIb3DQEBBQUAMHUxCzAJ
  213. # BgNVBAYTAlVTMRgwFgYDVQQKEw9HVEUgQ29ycG9yYXRpb24xJzAlBgNVBAsTHkdU
  214. # RSBDeWJlclRydXN0IFNvbHV0aW9ucywgSW5jLjEjMCEGA1UEAxMaR1RFIEN5YmVy
  215. # VHJ1c3QgR2xvYmFsIFJvb3QwHhcNMTAwMTEzMTkyMDMyWhcNMTUwOTMwMTgxOTQ3
  216. # WjBsMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQL
  217. # ExB3d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3Vy
  218. # YW5jZSBFViBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
  219. # xszlc+b71LvlLS0ypt/lgT/JzSVJtnEqw9WUNGeiChywX2mmQLHEt7KP0JikqUFZ
  220. # OtPclNY823Q4pErMTSWC90qlUxI47vNJbXGRfmO2q6Zfw6SE+E9iUb74xezbOJLj
  221. # BuUIkQzEKEFV+8taiRV+ceg1v01yCT2+OjhQW3cxG42zxyRFmqesbQAUWgS3uhPr
  222. # UQqYQUEiTmVhh4FBUKZ5XIneGUpX1S7mXRxTLH6YzRoGFqRoc9A0BBNcoXHTWnxV
  223. # 215k4TeHMFYE5RG0KYAS8Xk5iKICEXwnZreIt3jyygqoOKsKZMK/Zl2VhMGhJR6H
  224. # XRpQCyASzEG7bgtROLhLywIDAQABo4IBbzCCAWswEgYDVR0TAQH/BAgwBgEB/wIB
  225. # ATBTBgNVHSAETDBKMEgGCSsGAQQBsT4BADA7MDkGCCsGAQUFBwIBFi1odHRwOi8v
  226. # Y3liZXJ0cnVzdC5vbW5pcm9vdC5jb20vcmVwb3NpdG9yeS5jZm0wDgYDVR0PAQH/
  227. # BAQDAgEGMIGJBgNVHSMEgYEwf6F5pHcwdTELMAkGA1UEBhMCVVMxGDAWBgNVBAoT
  228. # D0dURSBDb3Jwb3JhdGlvbjEnMCUGA1UECxMeR1RFIEN5YmVyVHJ1c3QgU29sdXRp
  229. # b25zLCBJbmMuMSMwIQYDVQQDExpHVEUgQ3liZXJUcnVzdCBHbG9iYWwgUm9vdIIC
  230. # AaUwRQYDVR0fBD4wPDA6oDigNoY0aHR0cDovL3d3dy5wdWJsaWMtdHJ1c3QuY29t
  231. # L2NnaS1iaW4vQ1JMLzIwMTgvY2RwLmNybDAdBgNVHQ4EFgQUsT7DaQP4v0cB1Jgm
  232. # GggC72NkK8MwDQYJKoZIhvcNAQEFBQADgYEALnaF2TeWba+J8wZ4gjHERgcfZcmO
  233. # s8lUeObRQt91Lh5V6vf6mwTAdXvReTwF7HnEUt2mA9enUJk/BVnaxlX0hpwNZ6NJ
  234. # BJUyHceH7IWvZG7VxV8Jp0B9FrpJDaL99t9VMGzXeMa5z1gpZBZMoyCBR7FEkoQW
  235. # G29KvCHGCj3tM8owggSjMIIDi6ADAgECAhAOz/Q4yP6/NW4E2GqYGxpQMA0GCSqG
  236. # SIb3DQEBBQUAMF4xCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jw
  237. # b3JhdGlvbjEwMC4GA1UEAxMnU3ltYW50ZWMgVGltZSBTdGFtcGluZyBTZXJ2aWNl
  238. # cyBDQSAtIEcyMB4XDTEyMTAxODAwMDAwMFoXDTIwMTIyOTIzNTk1OVowYjELMAkG
  239. # A1UEBhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMTQwMgYDVQQD
  240. # EytTeW1hbnRlYyBUaW1lIFN0YW1waW5nIFNlcnZpY2VzIFNpZ25lciAtIEc0MIIB
  241. # IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAomMLOUS4uyOnREm7Dv+h8GEK
  242. # U5OwmNutLA9KxW7/hjxTVQ8VzgQ/K/2plpbZvmF5C1vJTIZ25eBDSyKV7sIrQ8Gf
  243. # 2Gi0jkBP7oU4uRHFI/JkWPAVMm9OV6GuiKQC1yoezUvh3WPVF4kyW7BemVqonShQ
  244. # DhfultthO0VRHc8SVguSR/yrrvZmPUescHLnkudfzRC5xINklBm9JYDh6NIipdC6
  245. # Anqhd5NbZcPuF3S8QYYq3AhMjJKMkS2ed0QfaNaodHfbDlsyi1aLM73ZY8hJnTrF
  246. # xeozC9Lxoxv0i77Zs1eLO94Ep3oisiSuLsdwxb5OgyYI+wu9qU+ZCOEQKHKqzQID
  247. # AQABo4IBVzCCAVMwDAYDVR0TAQH/BAIwADAWBgNVHSUBAf8EDDAKBggrBgEFBQcD
  248. # CDAOBgNVHQ8BAf8EBAMCB4AwcwYIKwYBBQUHAQEEZzBlMCoGCCsGAQUFBzABhh5o
  249. # dHRwOi8vdHMtb2NzcC53cy5zeW1hbnRlYy5jb20wNwYIKwYBBQUHMAKGK2h0dHA6
  250. # Ly90cy1haWEud3Muc3ltYW50ZWMuY29tL3Rzcy1jYS1nMi5jZXIwPAYDVR0fBDUw
  251. # MzAxoC+gLYYraHR0cDovL3RzLWNybC53cy5zeW1hbnRlYy5jb20vdHNzLWNhLWcy
  252. # LmNybDAoBgNVHREEITAfpB0wGzEZMBcGA1UEAxMQVGltZVN0YW1wLTIwNDgtMjAd
  253. # BgNVHQ4EFgQURsZpow5KFB7VTNpSYxc/Xja8DeYwHwYDVR0jBBgwFoAUX5r1blzM
  254. # zHSa1N197z/b7EyALt0wDQYJKoZIhvcNAQEFBQADggEBAHg7tJEqAEzwj2IwN3ij
  255. # hCcHbxiy3iXcoNSUA6qGTiWfmkADHN3O43nLIWgG2rYytG2/9CwmYzPkSWRtDebD
  256. # Zw73BaQ1bHyJFsbpst+y6d0gxnEPzZV03LZc3r03H0N45ni1zSgEIKOq8UvEiCmR
  257. # DoDREfzdXHZuT14ORUZBbg2w6jiasTraCXEQ/Bx5tIB7rGn0/Zy2DBYr8X9bCT2b
  258. # W+IWyhOBbQAuOA2oKY8s4bL0WqkBrxWcLC9JG9siu8P+eJRRw4axgohd8D20UaF5
  259. # Mysue7ncIAkTcetqGVvP6KUwVyyJST+5z3/Jvz4iaGNTmr1pdKzFHTx/kuDDvBzY
  260. # BHUwggafMIIFh6ADAgECAhAOaQaYwhTIerW2BLkWPNGQMA0GCSqGSIb3DQEBBQUA
  261. # MHMxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsT
  262. # EHd3dy5kaWdpY2VydC5jb20xMjAwBgNVBAMTKURpZ2lDZXJ0IEhpZ2ggQXNzdXJh
  263. # bmNlIENvZGUgU2lnbmluZyBDQS0xMB4XDTEyMDMyMDAwMDAwMFoXDTEzMDMyMjEy
  264. # MDAwMFowbTELMAkGA1UEBhMCVVMxETAPBgNVBAgTCE5ldyBZb3JrMRcwFQYDVQQH
  265. # Ew5XZXN0IEhlbnJpZXR0YTEYMBYGA1UEChMPSm9lbCBILiBCZW5uZXR0MRgwFgYD
  266. # VQQDEw9Kb2VsIEguIEJlbm5ldHQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
  267. # AoIBAQDaiAYAbz13WMx9Em/Z3dTWUKxbyiTsaSOctgOfTMLUAurXWtY3k1XBVufX
  268. # feL4pXQ7yQzm93YzvETwKdUCDJuOSu9EPYioy2nhKvBC6IaJUaw1VY7e9IsdxaxL
  269. # 8js3RQilLk+FO4UHg9w7L8wdHgXaDoksysC2SlhbFq4AVl8XC4R+bq+pahsdMO3n
  270. # Ab7Oo5PExKLVS8vl8QwOh6MaqquIjHmYoPOu9Rv8As0pnWsY9aVPs7T9QetXlW45
  271. # +CKPhdUoEB1yD0kvGTIAQgn5W9VDYmfeVU40IIdt+7khWF10yu7zVT+/lauPzRmv
  272. # CHZMfbmqVyVQqvp5dEu0/7EWbbcLAgMBAAGjggMzMIIDLzAfBgNVHSMEGDAWgBSX
  273. # SAPrFQhrubJYI8yULvHGZdJkjjAdBgNVHQ4EFgQUmJxEqr9ewFZG4rNTp5NQIEIJ
  274. # TrkwDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMDMGkGA1UdHwRi
  275. # MGAwLqAsoCqGKGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9oYS1jcy0yMDExYS5j
  276. # cmwwLqAsoCqGKGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9oYS1jcy0yMDExYS5j
  277. # cmwwggHEBgNVHSAEggG7MIIBtzCCAbMGCWCGSAGG/WwDATCCAaQwOgYIKwYBBQUH
  278. # AgEWLmh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5o
  279. # dG0wggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0
  280. # AGgAaQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1
  281. # AHQAZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABp
  282. # AGcAaQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBl
  283. # AGwAeQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBo
  284. # AGkAYwBo
gipoco.com is neither affiliated with the authors of this page nor responsible for its contents. This is a safe-cache copy of the original web site.