EntityFramework.psm1 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777
  1. # Copyright (c) Microsoft Corporation. All rights reserved.
  2. $InitialDatabase = '0'
  3. $knownExceptions = @(
  4. 'System.Data.Entity.Migrations.Infrastructure.MigrationsException',
  5. 'System.Data.Entity.Migrations.Infrastructure.AutomaticMigrationsDisabledException',
  6. 'System.Data.Entity.Migrations.Infrastructure.AutomaticDataLossException',
  7. 'System.Data.Entity.Migrations.MigrationsPendingException',
  8. 'System.Data.Entity.Migrations.ProjectTypeNotSupportedException'
  9. )
  10. <#
  11. .SYNOPSIS
  12. Enables Code First Migrations in a project.
  13. .DESCRIPTION
  14. Enables Migrations by scaffolding a migrations configuration class in the project. If the
  15. target database was created by an initializer, an initial migration will be created (unless
  16. automatic migrations are enabled via the EnableAutomaticMigrations parameter).
  17. .PARAMETER ContextTypeName
  18. Specifies the context to use. If omitted, migrations will attempt to locate a
  19. single context type in the target project.
  20. .PARAMETER EnableAutomaticMigrations
  21. Specifies whether automatic migrations will be enabled in the scaffolded migrations configuration.
  22. If ommitted, automatic migrations will be disabled.
  23. .PARAMETER ProjectName
  24. Specifies the project that the scaffolded migrations configuration class will
  25. be added to. If omitted, the default project selected in package manager
  26. console is used.
  27. .PARAMETER StartUpProjectName
  28. Specifies the configuration file to use for named connection strings. If
  29. omitted, the specified project's configuration file is used.
  30. .PARAMETER ConnectionStringName
  31. Specifies the name of a connection string to use from the application's
  32. configuration file.
  33. .PARAMETER ConnectionString
  34. Specifies the the connection string to use. If omitted, the context's
  35. default connection will be used.
  36. .PARAMETER ConnectionProviderName
  37. Specifies the provider invariant name of the connection string.
  38. .PARAMETER Force
  39. Specifies that the migrations configuration be overwritten when running more
  40. than once for a given project.
  41. #>
  42. function Enable-Migrations
  43. {
  44. [CmdletBinding(DefaultParameterSetName = 'ConnectionStringName')]
  45. param (
  46. [string] $ContextTypeName,
  47. [alias('Auto')]
  48. [switch] $EnableAutomaticMigrations,
  49. [string] $ProjectName,
  50. [string] $StartUpProjectName,
  51. [parameter(ParameterSetName = 'ConnectionStringName')]
  52. [string] $ConnectionStringName,
  53. [parameter(ParameterSetName = 'ConnectionStringAndProviderName',
  54. Mandatory = $true)]
  55. [string] $ConnectionString,
  56. [parameter(ParameterSetName = 'ConnectionStringAndProviderName',
  57. Mandatory = $true)]
  58. [string] $ConnectionProviderName,
  59. [switch] $Force
  60. )
  61. $runner = New-MigrationsRunner $ProjectName $StartUpProjectName $null $ConnectionStringName $ConnectionString $ConnectionProviderName
  62. try
  63. {
  64. Invoke-RunnerCommand $runner System.Data.Entity.Migrations.EnableMigrationsCommand @( $EnableAutomaticMigrations.IsPresent, $Force.IsPresent ) @{ 'ContextTypeName' = $ContextTypeName }
  65. $error = Get-RunnerError $runner
  66. if ($error)
  67. {
  68. if ($knownExceptions -notcontains $error.TypeName)
  69. {
  70. Write-Host $error.StackTrace
  71. }
  72. throw $error.Message
  73. }
  74. }
  75. finally
  76. {
  77. Remove-Runner $runner
  78. }
  79. }
  80. <#
  81. .SYNOPSIS
  82. Scaffolds a migration script for any pending model changes.
  83. .DESCRIPTION
  84. Scaffolds a new migration script and adds it to the project.
  85. .PARAMETER Name
  86. Specifies the name of the custom script.
  87. .PARAMETER Force
  88. Specifies that the migration user code be overwritten when re-scaffolding an
  89. existing migration.
  90. .PARAMETER ProjectName
  91. Specifies the project that contains the migration configuration type to be
  92. used. If ommitted, the default project selected in package manager console
  93. is used.
  94. .PARAMETER StartUpProjectName
  95. Specifies the configuration file to use for named connection strings. If
  96. omitted, the specified project's configuration file is used.
  97. .PARAMETER ConfigurationTypeName
  98. Specifies the migrations configuration to use. If omitted, migrations will
  99. attempt to locate a single migrations configuration type in the target
  100. project.
  101. .PARAMETER ConnectionStringName
  102. Specifies the name of a connection string to use from the application's
  103. configuration file.
  104. .PARAMETER ConnectionString
  105. Specifies the the connection string to use. If omitted, the context's
  106. default connection will be used.
  107. .PARAMETER ConnectionProviderName
  108. Specifies the provider invariant name of the connection string.
  109. .PARAMETER IgnoreChanges
  110. Scaffolds an empty migration ignoring any pending changes detected in the current model.
  111. This can be used to create an initial, empty migration to enable Migrations for an existing
  112. database. N.B. Doing this assumes that the target database schema is compatible with the
  113. current model.
  114. #>
  115. function Add-Migration
  116. {
  117. [CmdletBinding(DefaultParameterSetName = 'ConnectionStringName')]
  118. param (
  119. [parameter(Position = 0,
  120. Mandatory = $true)]
  121. [string] $Name,
  122. [switch] $Force,
  123. [string] $ProjectName,
  124. [string] $StartUpProjectName,
  125. [string] $ConfigurationTypeName,
  126. [parameter(ParameterSetName = 'ConnectionStringName')]
  127. [string] $ConnectionStringName,
  128. [parameter(ParameterSetName = 'ConnectionStringAndProviderName',
  129. Mandatory = $true)]
  130. [string] $ConnectionString,
  131. [parameter(ParameterSetName = 'ConnectionStringAndProviderName',
  132. Mandatory = $true)]
  133. [string] $ConnectionProviderName,
  134. [switch] $IgnoreChanges)
  135. $runner = New-MigrationsRunner $ProjectName $StartUpProjectName $ConfigurationTypeName $ConnectionStringName $ConnectionString $ConnectionProviderName
  136. try
  137. {
  138. Invoke-RunnerCommand $runner System.Data.Entity.Migrations.AddMigrationCommand @( $Name, $Force.IsPresent, $IgnoreChanges.IsPresent )
  139. $error = Get-RunnerError $runner
  140. if ($error)
  141. {
  142. if ($knownExceptions -notcontains $error.TypeName)
  143. {
  144. Write-Host $error.StackTrace
  145. }
  146. throw $error.Message
  147. }
  148. }
  149. finally
  150. {
  151. Remove-Runner $runner
  152. }
  153. }
  154. <#
  155. .SYNOPSIS
  156. Applies any pending migrations to the database.
  157. .DESCRIPTION
  158. Updates the database to the current model by applying pending migrations.
  159. .PARAMETER SourceMigration
  160. Only valid with -Script. Specifies the name of a particular migration to use
  161. as the update's starting point. If ommitted, the last applied migration in
  162. the database will be used.
  163. .PARAMETER TargetMigration
  164. Specifies the name of a particular migration to update the database to. If
  165. ommitted, the current model will be used.
  166. .PARAMETER Script
  167. Generate a SQL script rather than executing the pending changes directly.
  168. .PARAMETER Force
  169. Specifies that data loss is acceptable during automatic migration of the
  170. database.
  171. .PARAMETER ProjectName
  172. Specifies the project that contains the migration configuration type to be
  173. used. If ommitted, the default project selected in package manager console
  174. is used.
  175. .PARAMETER StartUpProjectName
  176. Specifies the configuration file to use for named connection strings. If
  177. omitted, the specified project's configuration file is used.
  178. .PARAMETER ConfigurationTypeName
  179. Specifies the migrations configuration to use. If omitted, migrations will
  180. attempt to locate a single migrations configuration type in the target
  181. project.
  182. .PARAMETER ConnectionStringName
  183. Specifies the name of a connection string to use from the application's
  184. configuration file.
  185. .PARAMETER ConnectionString
  186. Specifies the the connection string to use. If omitted, the context's
  187. default connection will be used.
  188. .PARAMETER ConnectionProviderName
  189. Specifies the provider invariant name of the connection string.
  190. #>
  191. function Update-Database
  192. {
  193. [CmdletBinding(DefaultParameterSetName = 'ConnectionStringName')]
  194. param (
  195. [string] $SourceMigration,
  196. [string] $TargetMigration,
  197. [switch] $Script,
  198. [switch] $Force,
  199. [string] $ProjectName,
  200. [string] $StartUpProjectName,
  201. [string] $ConfigurationTypeName,
  202. [parameter(ParameterSetName = 'ConnectionStringName')]
  203. [string] $ConnectionStringName,
  204. [parameter(ParameterSetName = 'ConnectionStringAndProviderName',
  205. Mandatory = $true)]
  206. [string] $ConnectionString,
  207. [parameter(ParameterSetName = 'ConnectionStringAndProviderName',
  208. Mandatory = $true)]
  209. [string] $ConnectionProviderName)
  210. $runner = New-MigrationsRunner $ProjectName $StartUpProjectName $ConfigurationTypeName $ConnectionStringName $ConnectionString $ConnectionProviderName
  211. try
  212. {
  213. Invoke-RunnerCommand $runner System.Data.Entity.Migrations.UpdateDatabaseCommand @( $SourceMigration, $TargetMigration, $Script.IsPresent, $Force.IsPresent, $Verbose.IsPresent )
  214. $error = Get-RunnerError $runner
  215. if ($error)
  216. {
  217. if ($knownExceptions -notcontains $error.TypeName)
  218. {
  219. Write-Host $error.StackTrace
  220. }
  221. throw $error.Message
  222. }
  223. }
  224. finally
  225. {
  226. Remove-Runner $runner
  227. }
  228. }
  229. <#
  230. .SYNOPSIS
  231. Displays the migrations that have been applied to the target database.
  232. .DESCRIPTION
  233. Displays the migrations that have been applied to the target database.
  234. .PARAMETER ProjectName
  235. Specifies the project that contains the migration configuration type to be
  236. used. If ommitted, the default project selected in package manager console
  237. is used.
  238. .PARAMETER StartUpProjectName
  239. Specifies the configuration file to use for named connection strings. If
  240. omitted, the specified project's configuration file is used.
  241. .PARAMETER ConfigurationTypeName
  242. Specifies the migrations configuration to use. If omitted, migrations will
  243. attempt to locate a single migrations configuration type in the target
  244. project.
  245. .PARAMETER ConnectionStringName
  246. Specifies the name of a connection string to use from the application's
  247. configuration file.
  248. .PARAMETER ConnectionString
  249. Specifies the the connection string to use. If omitted, the context's
  250. default connection will be used.
  251. .PARAMETER ConnectionProviderName
  252. Specifies the provider invariant name of the connection string.
  253. #>
  254. function Get-Migrations
  255. {
  256. [CmdletBinding(DefaultParameterSetName = 'ConnectionStringName')]
  257. param (
  258. [string] $ProjectName,
  259. [string] $StartUpProjectName,
  260. [string] $ConfigurationTypeName,
  261. [parameter(ParameterSetName = 'ConnectionStringName')]
  262. [string] $ConnectionStringName,
  263. [parameter(ParameterSetName = 'ConnectionStringAndProviderName',
  264. Mandatory = $true)]
  265. [string] $ConnectionString,
  266. [parameter(ParameterSetName = 'ConnectionStringAndProviderName',
  267. Mandatory = $true)]
  268. [string] $ConnectionProviderName)
  269. $runner = New-MigrationsRunner $ProjectName $StartUpProjectName $ConfigurationTypeName $ConnectionStringName $ConnectionString $ConnectionProviderName
  270. try
  271. {
  272. Invoke-RunnerCommand $runner System.Data.Entity.Migrations.GetMigrationsCommand
  273. $error = Get-RunnerError $runner
  274. if ($error)
  275. {
  276. if ($knownExceptions -notcontains $error.TypeName)
  277. {
  278. Write-Host $error.StackTrace
  279. }
  280. throw $error.Message
  281. }
  282. }
  283. finally
  284. {
  285. Remove-Runner $runner
  286. }
  287. }
  288. function New-MigrationsRunner($ProjectName, $StartUpProjectName, $ConfigurationTypeName, $ConnectionStringName, $ConnectionString, $ConnectionProviderName)
  289. {
  290. $startUpProject = Get-MigrationsStartUpProject $StartUpProjectName $ProjectName
  291. Build-Project $startUpProject
  292. $project = Get-MigrationsProject $ProjectName
  293. Build-Project $project
  294. $installPath = Get-EntityFrameworkInstallPath $project
  295. $toolsPath = Join-Path $installPath tools
  296. $info = New-Object System.AppDomainSetup -Property @{
  297. ShadowCopyFiles = 'true';
  298. ApplicationBase = $installPath;
  299. PrivateBinPath = 'tools'
  300. }
  301. $targetFrameworkVersion = (New-Object System.Runtime.Versioning.FrameworkName ($project.Properties.Item('TargetFrameworkMoniker').Value)).Version
  302. if ($targetFrameworkVersion -lt (New-Object Version @( 4, 5 )))
  303. {
  304. $info.PrivateBinPath += ';lib\net40'
  305. $dteVersion = [System.Text.RegularExpressions.Regex]::Match($DTE.Version, '^(?<version>\d{1,2}(\.\d{1,2})?)( \(.+\))?$').Groups['version'].Value
  306. if ((New-Object Version $dteVersion) -lt (New-Object Version @( 11, 0 )))
  307. {
  308. $info.ConfigurationFile = Join-Path $toolsPath 'Redirect.config'
  309. }
  310. else
  311. {
  312. $info.ConfigurationFile = Join-Path $toolsPath 'Redirect.VS11.config'
  313. }
  314. }
  315. else
  316. {
  317. $info.PrivateBinPath += ';lib\net45'
  318. $info.ConfigurationFile = [AppDomain]::CurrentDomain.SetupInformation.ConfigurationFile
  319. }
  320. $domain = [AppDomain]::CreateDomain('Migrations', $null, $info)
  321. $domain.SetData('project', $project)
  322. $domain.SetData('startUpProject', $startUpProject)
  323. $domain.SetData('configurationTypeName', $ConfigurationTypeName)
  324. $domain.SetData('connectionStringName', $ConnectionStringName)
  325. $domain.SetData('connectionString', $ConnectionString)
  326. $domain.SetData('connectionProviderName', $ConnectionProviderName)
  327. [AppDomain]::CurrentDomain.SetShadowCopyFiles()
  328. $utilityAssembly = [System.Reflection.Assembly]::LoadFrom((Join-Path $toolsPath EntityFramework.PowerShell.Utility.dll))
  329. $dispatcher = $utilityAssembly.CreateInstance(
  330. 'System.Data.Entity.Migrations.Utilities.DomainDispatcher',
  331. $false,
  332. [System.Reflection.BindingFlags]::Instance -bor [System.Reflection.BindingFlags]::Public,
  333. $null,
  334. $PSCmdlet,
  335. $null,
  336. $null)
  337. $domain.SetData('efDispatcher', $dispatcher)
  338. return @{
  339. Domain = $domain;
  340. ToolsPath = $toolsPath
  341. }
  342. }
  343. function Remove-Runner($runner)
  344. {
  345. [AppDomain]::Unload($runner.Domain)
  346. }
  347. function Invoke-RunnerCommand($runner, $command, $parameters, $anonymousArguments)
  348. {
  349. $domain = $runner.Domain
  350. if ($anonymousArguments)
  351. {
  352. $anonymousArguments.GetEnumerator() | %{
  353. $domain.SetData($_.Name, $_.Value)
  354. }
  355. }
  356. $domain.CreateInstanceFrom(
  357. (Join-Path $runner.ToolsPath EntityFramework.PowerShell.dll),
  358. $command,
  359. $false,
  360. 0,
  361. $null,
  362. $parameters,
  363. $null,
  364. $null) | Out-Null
  365. }
  366. function Get-RunnerError($runner)
  367. {
  368. $domain = $runner.Domain
  369. if (!$domain.GetData('wasError'))
  370. {
  371. return $null
  372. }
  373. return @{
  374. Message = $domain.GetData('error.Message');
  375. TypeName = $domain.GetData('error.TypeName');
  376. StackTrace = $domain.GetData('error.StackTrace')
  377. }
  378. }
  379. function Get-MigrationsProject($name, $hideMessage)
  380. {
  381. if ($name)
  382. {
  383. return Get-SingleProject $name
  384. }
  385. $project = Get-Project
  386. $projectName = $project.Name
  387. if (!$hideMessage)
  388. {
  389. Write-Verbose "Using NuGet project '$projectName'."
  390. }
  391. return $project
  392. }
  393. function Get-MigrationsStartUpProject($name, $fallbackName)
  394. {
  395. $startUpProject = $null
  396. if ($name)
  397. {
  398. $startUpProject = Get-SingleProject $name
  399. }
  400. else
  401. {
  402. $startupProjectPaths = $DTE.Solution.SolutionBuild.StartupProjects
  403. if ($startupProjectPaths)
  404. {
  405. if ($startupProjectPaths.Length -eq 1)
  406. {
  407. $startupProjectPath = $startupProjectPaths[0]
  408. if (!(Split-Path -IsAbsolute $startupProjectPath))
  409. {
  410. $solutionPath = Split-Path $DTE.Solution.Properties.Item('Path').Value
  411. $startupProjectPath = Join-Path $solutionPath $startupProjectPath -Resolve
  412. }
  413. $startupProject = Get-SolutionProjects | ?{
  414. try
  415. {
  416. $fullName = $_.FullName
  417. }
  418. catch [NotImplementedException]
  419. {
  420. return false;
  421. }
  422. if ($fullName -and $fullName.EndsWith('\'))
  423. {
  424. $fullName = $fullName.Substring(0, $fullName.Length - 1)
  425. }
  426. return $fullName -eq $startupProjectPath
  427. }
  428. }
  429. else
  430. {
  431. Write-Verbose 'More than one start-up project found.'
  432. }
  433. }
  434. else
  435. {
  436. Write-Verbose 'No start-up project found.'
  437. }
  438. }
  439. if (!($startUpProject -and (Test-StartUpProject $startUpProject)))
  440. {
  441. $startUpProject = Get-MigrationsProject $fallbackName $true
  442. $startUpProjectName = $startUpProject.Name
  443. Write-Warning "Cannot determine a valid start-up project. Using project '$startUpProjectName' instead. Your configuration file and working directory may not be set as expected. Use the -StartUpProjectName parameter to set one explicitly. Use the -Verbose switch for more information."
  444. }
  445. else
  446. {
  447. $startUpProjectName = $startUpProject.Name
  448. Write-Verbose "Using StartUp project '$startUpProjectName'."
  449. }
  450. return $startUpProject
  451. }
  452. function Get-SolutionProjects()
  453. {
  454. $projects = New-Object System.Collections.Stack
  455. $DTE.Solution.Projects | %{
  456. $projects.Push($_)
  457. }
  458. while ($projects.Count -ne 0)
  459. {
  460. $project = $projects.Pop();
  461. # NOTE: This line is similar to doing a "yield return" in C#
  462. $project
  463. if ($project.ProjectItems)
  464. {
  465. $project.ProjectItems | ?{ $_.SubProject } | %{
  466. $projects.Push($_.SubProject)
  467. }
  468. }
  469. }
  470. }
  471. function Get-SingleProject($name)
  472. {
  473. $project = Get-Project $name
  474. if ($project -is [array])
  475. {
  476. throw "More than one project '$name' was found. Specify the full name of the one to use."
  477. }
  478. return $project
  479. }
  480. function Test-StartUpProject($project)
  481. {
  482. if ($project.Kind -eq '{cc5fd16d-436d-48ad-a40c-5a424c6e3e79}')
  483. {
  484. $projectName = $project.Name
  485. Write-Verbose "Cannot use start-up project '$projectName'. The Windows Azure Project type isn't supported."
  486. return $false
  487. }
  488. return $true
  489. }
  490. function Build-Project($project)
  491. {
  492. $configuration = $DTE.Solution.SolutionBuild.ActiveConfiguration.Name
  493. $DTE.Solution.SolutionBuild.BuildProject($configuration, $project.UniqueName, $true)
  494. if ($DTE.Solution.SolutionBuild.LastBuildInfo)
  495. {
  496. $projectName = $project.Name
  497. throw "The project '$projectName' failed to build."
  498. }
  499. }
  500. function Get-EntityFrameworkInstallPath($project)
  501. {
  502. $package = Get-Package -ProjectName $project.FullName | ?{ $_.Id -eq 'EntityFramework' }
  503. if (!$package)
  504. {
  505. $projectName = $project.Name
  506. throw "The EntityFramework package is not installed on project '$projectName'."
  507. }
  508. return Get-PackageInstallPath $package
  509. }
  510. function Get-PackageInstallPath($package)
  511. {
  512. $componentModel = Get-VsComponentModel
  513. $packageInstallerServices = $componentModel.GetService([NuGet.VisualStudio.IVsPackageInstallerServices])
  514. $vsPackage = $packageInstallerServices.GetInstalledPackages() | ?{ $_.Id -eq $package.Id -and $_.Version -eq $package.Version }
  515. return $vsPackage.InstallPath
  516. }
  517. Export-ModuleMember @( 'Enable-Migrations', 'Add-Migration', 'Update-Database', 'Get-Migrations' ) -Variable InitialDatabase
  518. # SIG # Begin signature block
  519. # MIIaRgYJKoZIhvcNAQcCoIIaNzCCGjMCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
  520. # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
  521. # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUc46O5H/xCa1Zd+kKsDgAx0de
  522. # pNmgghUtMIIEoDCCA4igAwIBAgIKYRnMkwABAAAAZjANBgkqhkiG9w0BAQUFADB5
  523. # MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVk
  524. # bW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSMwIQYDVQQDExpN
  525. # aWNyb3NvZnQgQ29kZSBTaWduaW5nIFBDQTAeFw0xMTEwMTAyMDMyMjVaFw0xMzAx
  526. # MTAyMDMyMjVaMIGDMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQ
  527. # MA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9u
  528. # MQ0wCwYDVQQLEwRNT1BSMR4wHAYDVQQDExVNaWNyb3NvZnQgQ29ycG9yYXRpb24w
  529. # ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDuW759ESTjhgbgZv9ItRe9
  530. # AuS0DDLwcj59LofXTqGxp0Mv92WeMeEyMUWu18EkhCHXLrWEfvo101Mc17ZRHk/O
  531. # ZrnrtwwC/SlcraiH9soitNW/CHX1inCPY9fvih7pj0MkZFrTh32QbTusds1XNn3o
  532. # vBBWrJjwiV0uZMavJgleHmMV8T2/Fo+ZiALDMLfBC2AfD3LM1reoNRKGm6ELCuaT
  533. # W476VJzB8xlfQo0Snx0/kLcnE4MZMoId89mH1CGyPKK2B0/XJKrujfWz2fr5OU+n
  534. # 6fKvWVL03EGbLxFwY93q3qrxbSEEEFMzu7JPxeFTskFlR2439rzpmxZBkWsuWzDD
  535. # AgMBAAGjggEdMIIBGTATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUG1IO
  536. # 8xEqt8CJwxGBPdSWWLmjU24wDgYDVR0PAQH/BAQDAgeAMB8GA1UdIwQYMBaAFMsR
  537. # 6MrStBZYAck3LjMWFrlMmgofMFYGA1UdHwRPME0wS6BJoEeGRWh0dHA6Ly9jcmwu
  538. # bWljcm9zb2Z0LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY0NvZFNpZ1BDQV8wOC0z
  539. # MS0yMDEwLmNybDBaBggrBgEFBQcBAQROMEwwSgYIKwYBBQUHMAKGPmh0dHA6Ly93
  540. # d3cubWljcm9zb2Z0LmNvbS9wa2kvY2VydHMvTWljQ29kU2lnUENBXzA4LTMxLTIw
  541. # MTAuY3J0MA0GCSqGSIb3DQEBBQUAA4IBAQClWzZsrU6baRLjb4oCm2l3w2xkciiI
  542. # 2T1FbSwYe9QoLxPiWWobwgs0t4r96rmU7Acx5mr0dQTTp9peOgaeEP2pDb2cUUNv
  543. # /2eUnOHPfPAksDXMg13u2sBvNknAWgpX9nPhnvPjCEw7Pi/M0s3uTyJw9wQfAqZL
  544. # m7iPXIgONpRsMwe4qa1RoNDC3I4iEr3D34LXVqH33fClIFcQEJ3urIZ0bHGbwfDy
  545. # wnBep9ttTTdYmU15QNA0XVolrmfrG05GBrCMKR+jEI+lM58j1fi1Rn3g7mOYkEs+
  546. # BagvsBizWaSvQVOOCAUQLSrJOgZMHC6pMVFWZKyazKyXmCmKl5CH6p22MIIEujCC
  547. # A6KgAwIBAgIKYQUZlgAAAAAAGzANBgkqhkiG9w0BAQUFADB3MQswCQYDVQQGEwJV
  548. # UzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UE
  549. # ChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSEwHwYDVQQDExhNaWNyb3NvZnQgVGlt
  550. # ZS1TdGFtcCBQQ0EwHhcNMTEwNzI1MjA0MjE5WhcNMTIxMDI1MjA0MjE5WjCBszEL
  551. # MAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1v
  552. # bmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjENMAsGA1UECxMETU9Q
  553. # UjEnMCUGA1UECxMebkNpcGhlciBEU0UgRVNOOjlFNzgtODY0Qi0wMzlEMSUwIwYD
  554. # VQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNlMIIBIjANBgkqhkiG9w0B
  555. # AQEFAAOCAQ8AMIIBCgKCAQEA08s7U6KfRKN6q01WcVOKd6o3k34BPv2rAqNTqf/R
  556. # sSLFAJDndW7uGOiBDhPF2GEAvh+gdjsEDQTFBKCo/ENTBqEEBLkLkpgCYjjv1DMS
  557. # 9ys9e++tRVeFlSCf12M0nGJGjr6u4NmeOfapVf3P53fmNRPvXOi/SJNPGkMHWDiK
  558. # f4UUbOrJ0Et6gm7L0xVgCBSJlKhbPzrJPyB9bS9YGn3Kiji8w8I5aNgtWBoj7SoQ
  559. # CFogjIKl7dGXRZKFzMM3g98NmHzF07bgmVPYeAj15SMhB2KGWmppGf1w+VM0gfcl
  560. # MRmGh4vAVZr9qkw1Ff1b6ZXJq1OYKV8speElD2TF8rAndQIDAQABo4IBCTCCAQUw
  561. # HQYDVR0OBBYEFHkj56ENvlUsaBgpYoJn1vPhNjhaMB8GA1UdIwQYMBaAFCM0+NlS
  562. # RnAK7UD7dvuzK7DDNbMPMFQGA1UdHwRNMEswSaBHoEWGQ2h0dHA6Ly9jcmwubWlj
  563. # cm9zb2Z0LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY3Jvc29mdFRpbWVTdGFtcFBD
  564. # QS5jcmwwWAYIKwYBBQUHAQEETDBKMEgGCCsGAQUFBzAChjxodHRwOi8vd3d3Lm1p
  565. # Y3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY3Jvc29mdFRpbWVTdGFtcFBDQS5jcnQw
  566. # EwYDVR0lBAwwCgYIKwYBBQUHAwgwDQYJKoZIhvcNAQEFBQADggEBAEfCdoFbMd1v
  567. # 0zyZ8npsfpcTUCwFFxsQuEShtYz0Vs+9sCG0ZG1hHNju6Ov1ku5DohhEw/r67622
  568. # XH+XbUu1Q/snYXgIVHyx+a+YCrR0xKroLVDEff59TqGZ1icot67Y37GPgyKOzvN5
  569. # /GEUbb/rzISw36O7WwW36lT1Yh1sJ6ZjS/rjofq734WWZWlTsLZxmGQmZr3F8Vxi
  570. # vJH0PZxLQgANzzgFFCZa3CoFS39qmTjY3XOZos6MUCSepOv1P4p4zFSZXSVmpEEG
  571. # KK9JxLRSlOzeAoNk/k3U/0ui/CmA2+4/qzztM4jKvyJg0Fw7BLAKtJhtPKc6T5rR
  572. # ARYRYopBdqAwggW8MIIDpKADAgECAgphMyYaAAAAAAAxMA0GCSqGSIb3DQEBBQUA
  573. # MF8xEzARBgoJkiaJk/IsZAEZFgNjb20xGTAXBgoJkiaJk/IsZAEZFgltaWNyb3Nv
  574. # ZnQxLTArBgNVBAMTJE1pY3Jvc29mdCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0
  575. # eTAeFw0xMDA4MzEyMjE5MzJaFw0yMDA4MzEyMjI5MzJaMHkxCzAJBgNVBAYTAlVT
  576. # MRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQK
  577. # ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xIzAhBgNVBAMTGk1pY3Jvc29mdCBDb2Rl
  578. # IFNpZ25pbmcgUENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsnJZ
  579. # XBkwZL8dmmAgIEKZdlNsPhvWb8zL8epr/pcWEODfOnSDGrcvoDLs/97CQk4j1XIA
  580. # 2zVXConKriBJ9PBorE1LjaW9eUtxm0cH2v0l3511iM+qc0R/14Hb873yNqTJXEXc
  581. # r6094CholxqnpXJzVvEXlOT9NZRyoNZ2Xx53RYOFOBbQc1sFumdSjaWyaS/aGQv+
  582. # knQp4nYvVN0UMFn40o1i/cvJX0YxULknE+RAMM9yKRAoIsc3Tj2gMj2QzaE4BoVc
  583. # TlaCKCoFMrdL109j59ItYvFFPeesCAD2RqGe0VuMJlPoeqpK8kbPNzw4nrR3XKUX
  584. # no3LEY9WPMGsCV8D0wIDAQABo4IBXjCCAVowDwYDVR0TAQH/BAUwAwEB/zAdBgNV
  585. # HQ4EFgQUyxHoytK0FlgByTcuMxYWuUyaCh8wCwYDVR0PBAQDAgGGMBIGCSsGAQQB
  586. # gjcVAQQFAgMBAAEwIwYJKwYBBAGCNxUCBBYEFP3RMU7TJoqV4ZhgO6gxb6Y8vNgt
  587. # MBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMB8GA1UdIwQYMBaAFA6sgmBAVieX
  588. # 5SUT/CrhClOVWeSkMFAGA1UdHwRJMEcwRaBDoEGGP2h0dHA6Ly9jcmwubWljcm9z
  589. # b2Z0LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL21pY3Jvc29mdHJvb3RjZXJ0LmNybDBU
  590. # BggrBgEFBQcBAQRIMEYwRAYIKwYBBQUHMAKGOGh0dHA6Ly93d3cubWljcm9zb2Z0
  591. # LmNvbS9wa2kvY2VydHMvTWljcm9zb2Z0Um9vdENlcnQuY3J0MA0GCSqGSIb3DQEB
  592. # BQUAA4ICAQBZOT5/Jkav629AsTK1ausOL26oSffrX3XtTDst10OtC/7L6S0xoyPM
  593. # fFCYgCFdrD0vTLqiqFac43C7uLT4ebVJcvc+6kF/yuEMF2nLpZwgLfoLUMRWzS3j
  594. # StK8cOeoDaIDpVbguIpLV/KVQpzx8+/u44YfNDy4VprwUyOFKqSCHJPilAcd8uJO
  595. # +IyhyugTpZFOyBvSj3KVKnFtmxr4HPBT1mfMIv9cHc2ijL0nsnljVkSiUc356aNY
  596. # Vt2bAkVEL1/02q7UgjJu/KSVE+Traeepoiy+yCsQDmWOmdv1ovoSJgllOJTxeh9K
  597. # u9HhVujQeJYYXMk1Fl/dkx1Jji2+rTREHO4QFRoAXd01WyHOmMcJ7oUOjE9tDhNO
  598. # PXwpSJxy0fNsysHscKNXkld9lI2gG0gDWvfPo2cKdKU27S0vF8jmcjcS9G+xPGeC
  599. # +VKyjTMWZR4Oit0Q3mT0b85G1NMX6XnEBLTT+yzfH4qerAr7EydAreT54al/RrsH
  600. # YEdlYEBOsELsTu2zdnnYCjQJbRyAMR/iDlTd5aH75UcQrWSY/1AWLny/BSF64pVB
  601. # J2nDk4+VyY3YmyGuDVyc8KKuhmiDDGotu3ZrAB2WrfIWe/YWgyS5iM9qqEcxL5rc
  602. # 43E91wB+YkfRzojJuBj6DnKNwaM9rwJAav9pm5biEKgQtDdQCNbDPTCCBgcwggPv
  603. # oAMCAQICCmEWaDQAAAAAABwwDQYJKoZIhvcNAQEFBQAwXzETMBEGCgmSJomT8ixk
  604. # ARkWA2NvbTEZMBcGCgmSJomT8ixkARkWCW1pY3Jvc29mdDEtMCsGA1UEAxMkTWlj
  605. # cm9zb2Z0IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTA3MDQwMzEyNTMw
  606. # OVoXDTIxMDQwMzEzMDMwOVowdzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hp
  607. # bmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jw
  608. # b3JhdGlvbjEhMB8GA1UEAxMYTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBMIIBIjAN
  609. # BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAn6Fssd/bSJIqfGsuGeG94uPFmVEj
  610. # UK3O3RhOJA/u0afRTK10MCAR6wfVVJUVSZQbQpKumFwwJtoAa+h7veyJBw/3DgSY
  611. # 8InMH8szJIed8vRnHCz8e+eIHernTqOhwSNTyo36Rc8J0F6v0LBCBKL5pmyTZ9co
  612. # 3EZTsIbQ5ShGLieshk9VUgzkAyz7apCQMG6H81kwnfp+1pez6CGXfvjSE/MIt1Nt
  613. # UrRFkJ9IAEpHZhEnKWaol+TTBoFKovmEpxFHFAmCn4TtVXj+AZodUAiFABAwRu23
  614. # 3iNGu8QtVJ+vHnhBMXfMm987g5OhYQK1HQ2x/PebsgHOIktU//kFw8IgCwIDAQAB
  615. # o4IBqzCCAacwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUIzT42VJGcArtQPt2
  616. # +7MrsMM1sw8wCwYDVR0PBAQDAgGGMBAGCSsGAQQBgjcVAQQDAgEAMIGYBgNVHSME
  617. # gZAwgY2AFA6sgmBAVieX5SUT/CrhClOVWeSkoWOkYTBfMRMwEQYKCZImiZPyLGQB
  618. # GRYDY29tMRkwFwYKCZImiZPyLGQBGRYJbWljcm9zb2Z0MS0wKwYDVQQDEyRNaWNy
  619. # b3NvZnQgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHmCEHmtFqFKoKWtTHNY9AcT
  620. # LmUwUAYDVR0fBEkwRzBFoEOgQYY/aHR0cDovL2NybC5taWNyb3NvZnQuY29tL3Br
  621. # aS9jcmwvcHJvZHVjdHMvbWljcm9zb2Z0cm9vdGNlcnQuY3JsMFQGCCsGAQUFBwEB
  622. # BEgwRjBEBggrBgEFBQcwAoY4aHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraS9j
  623. # ZXJ0cy9NaWNyb3NvZnRSb290Q2VydC5jcnQwEwYDVR0lBAwwCgYIKwYBBQUHAwgw
  624. # DQYJKoZIhvcNAQEFBQADggIBABCXisNcA0Q23em0rXfbznlRTQGxLnRxW20ME6vO
  625. # vnuPuC7UEqKMbWK4VwLLTiATUJndekDiV7uvWJoc4R0Bhqy7ePKL0Ow7Ae7ivo8K
  626. # BciNSOLwUxXdT6uS5OeNatWAweaU8gYvhQPpkSokInD79vzkeJkuDfcH4nC8GE6d
  627. # jmsKcpW4oTmcZy3FUQ7qYlw/FpiLID/iBxoy+cwxSnYxPStyC8jqcD3/hQoT38IK
  628. # YY7w17gX606Lf8U1K16jv+u8fQtCe9RTciHuMMq7eGVcWwEXChQO0toUmPU8uWZY
  629. # sy0v5/mFhsxRVuidcJRsrDlM1PZ5v6oYemIp76KbKTQGdxpiyT0ebR+C8AvHLLvP
  630. # Q7Pl+ex9teOkqHQ1uE7FcSMSJnYLPFKMcVpGQxS8s7OwTWfIn0L/gHkhgJ4VMGbo
  631. # QhJeGsieIiHQQ+kr6bv0SMws1NgygEwmKkgkX1rqVu+m3pmdyjpvvYEndAYR7nYh
  632. # v5uCwSdUtrFqPYmhdmG0bqETpr+qR/ASb/2KMmyy/t9RyIwjyWa9nR2HEmQCPS2v
  633. # WY+45CHltbDKY7R4VAXUQS5QrJSwpXirs6CWdRrZkocTdSIvMqgIbqBbjCW/oO+E
  634. # yiHW6x5PyZruSeD3AWVviQt9yGnI5m7qp5fOMSn/DsVbXNhNG6HY+i+ePy5VFmvJ
  635. # E6P9MYIEgzCCBH8CAQEwgYcweTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hp
  636. # bmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jw
  637. # b3JhdGlvbjEjMCEGA1UEAxMaTWljcm9zb2Z0IENvZGUgU2lnbmluZyBQQ0ECCmEZ
  638. # zJMAAQAAAGYwCQYFKw4DAhoFAKCBsDAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIB
  639. # BDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQU
  640. # SDInMyiqV3LEzPhzf6mjYJvp5qAwUAYKKwYBBAGCNwIBDDFCMECgIoAgAEUAbgB0
  641. # AGkAdAB5ACAARgByAGEAbQBlAHcAbwByAGuhGoAYaHR0cDovL21zZG4uY29tL2Rh
  642. # dGEvZWYgMA0GCSqGSIb3DQEBAQUABIIBAMTy2exDNM/cRmGrhj6rawr6XoQp77kh
  643. # +WOMUmSG5U4qSlP8g3fVFH030Xsxz5d8TunxEzRUyDhYHh3mQ56x4RCVJU/fdl8Q
  644. # dhXwn4VfV84G3+mIHVRCo8+8hm/o1l1K0sHhLCaPSoZht1bcKH09gK1VxoNhBt78
  645. # BFUHLTWw0sRwrEJRW1xZPwOoh2rv1cnYi7GPKFHiYrCV3NSHRkSJZmA42UYA1iZv
  646. # 3fF9QCQNlTDY4jiC2vsa/eWt0qhups1gQXdqg8y/Zvc5cEYxF+ByataJ6fI4w5HP
  647. # 5WNzsVl1O+6VFlj1qjMzOyVlsHWCOIfFfc8iLoWWy+A4W00yEeHIMT2hggIdMIIC
  648. # GQYJKoZIhvcNAQkGMYICCjCCAgYCAQEwgYUwdzELMAkGA1UEBhMCVVMxEzARBgNV
  649. # BAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jv
  650. # c29mdCBDb3Jwb3JhdGlvbjEhMB8GA1UEAxMYTWljcm9zb2Z0IFRpbWUtU3RhbXAg
  651. # UENBAgphBRmWAAAAAAAbMAcGBSsOAwIaoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3
  652. # DQEHATAcBgkqhkiG9w0BCQUxDxcNMTIwNjI4MjA0MzM5WjAjBgkqhkiG9w0BCQQx
  653. # FgQU2luimdNA+66F/z6ooEia0K5OZC8wDQYJKoZIhvcNAQEFBQAEggEAPUTPALhi
  654. # x8qJIn6WmeZTiazQRH4/TVQHCJPDxhlaMgDUDsPwwmjrAfL/UnMz+TVi5ltSM0Hb
  655. # jGLfhTbaw/YcLUqztgxNq/vm0cFqU3n+rIGUBXFUwDoS6Ol6UTSoXkJVHyiOxHuU
  656. # Fdh33QDv9EVBbr1CQJLTs02d31Uwjg8vUt9+LDSYQWFlZH0+xsy1wStReGX4DSRz
  657. # QneatHmqk+Vej4/3iFKBlCJO1SPlXQLaFAUFsZr6yl6oTrpfatG6sA16/e8jjW4u
  658. # Kz0GzJYJ4DMVdSVGpsvVWMADsbEsjlr6yesOrN4ZDEBdv7Y3P518wK/iJ1/WdgRc
  659. # SA474q5bExc5pA==
  660. # SIG # End signature block