EntityFramework6.psm1 51 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406
  1. # Copyright (c) Microsoft Corporation. All rights reserved.
  2. $ErrorActionPreference = 'Stop'
  3. $InitialDatabase = '0'
  4. <#
  5. .SYNOPSIS
  6. Adds or updates an Entity Framework provider entry in the project config
  7. file.
  8. .DESCRIPTION
  9. Adds an entry into the 'entityFramework' section of the project config
  10. file for the specified provider invariant name and provider type. If an
  11. entry for the given invariant name already exists, then that entry is
  12. updated with the given type name, unless the given type name already
  13. matches, in which case no action is taken. The 'entityFramework'
  14. section is added if it does not exist. The config file is automatically
  15. saved if and only if a change was made.
  16. This command is typically used only by Entity Framework provider NuGet
  17. packages and is run from the 'install.ps1' script.
  18. .PARAMETER Project
  19. The Visual Studio project to update. When running in the NuGet install.ps1
  20. script the '$project' variable provided as part of that script should be
  21. used.
  22. .PARAMETER InvariantName
  23. The provider invariant name that uniquely identifies this provider. For
  24. example, the Microsoft SQL Server provider is registered with the invariant
  25. name 'System.Data.SqlClient'.
  26. .PARAMETER TypeName
  27. The assembly-qualified type name of the provider-specific type that
  28. inherits from 'System.Data.Entity.Core.Common.DbProviderServices'. For
  29. example, for the Microsoft SQL Server provider, this type is
  30. 'System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer'.
  31. #>
  32. function Add-EFProvider
  33. {
  34. [CmdletBinding(PositionalBinding = $false)]
  35. param(
  36. [parameter(Position = 0, Mandatory = $true)]
  37. $Project,
  38. [parameter(Position = 1, Mandatory = $true)]
  39. [string] $InvariantName,
  40. [parameter(Position = 2, Mandatory = $true)]
  41. [string] $TypeName)
  42. $configPath = GetConfigPath $Project
  43. if (!$configPath)
  44. {
  45. return
  46. }
  47. [xml] $configXml = Get-Content $configPath
  48. $providers = $configXml.configuration.entityFramework.providers
  49. $providers.provider |
  50. where invariantName -eq $InvariantName |
  51. %{ $providers.RemoveChild($_) | Out-Null }
  52. $provider = $providers.AppendChild($configXml.CreateElement('provider'))
  53. $provider.SetAttribute('invariantName', $InvariantName)
  54. $provider.SetAttribute('type', $TypeName)
  55. $configXml.Save($configPath)
  56. }
  57. <#
  58. .SYNOPSIS
  59. Adds or updates an Entity Framework default connection factory in the
  60. project config file.
  61. .DESCRIPTION
  62. Adds an entry into the 'entityFramework' section of the project config
  63. file for the connection factory that Entity Framework will use by default
  64. when creating new connections by convention. Any existing entry will be
  65. overridden if it does not match. The 'entityFramework' section is added if
  66. it does not exist. The config file is automatically saved if and only if
  67. a change was made.
  68. This command is typically used only by Entity Framework provider NuGet
  69. packages and is run from the 'install.ps1' script.
  70. .PARAMETER Project
  71. The Visual Studio project to update. When running in the NuGet install.ps1
  72. script the '$project' variable provided as part of that script should be
  73. used.
  74. .PARAMETER TypeName
  75. The assembly-qualified type name of the connection factory type that
  76. implements the 'System.Data.Entity.Infrastructure.IDbConnectionFactory'
  77. interface. For example, for the Microsoft SQL Server Express provider
  78. connection factory, this type is
  79. 'System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework'.
  80. .PARAMETER ConstructorArguments
  81. An optional array of strings that will be passed as arguments to the
  82. connection factory type constructor.
  83. #>
  84. function Add-EFDefaultConnectionFactory
  85. {
  86. [CmdletBinding(PositionalBinding = $false)]
  87. param(
  88. [parameter(Position = 0, Mandatory = $true)]
  89. $Project,
  90. [parameter(Position = 1, Mandatory = $true)]
  91. [string] $TypeName,
  92. [string[]] $ConstructorArguments)
  93. $configPath = GetConfigPath $Project
  94. if (!$configPath)
  95. {
  96. return
  97. }
  98. [xml] $configXml = Get-Content $configPath
  99. $entityFramework = $configXml.configuration.entityFramework
  100. $defaultConnectionFactory = $entityFramework.defaultConnectionFactory
  101. if ($defaultConnectionFactory)
  102. {
  103. $entityFramework.RemoveChild($defaultConnectionFactory) | Out-Null
  104. }
  105. $defaultConnectionFactory = $entityFramework.AppendChild($configXml.CreateElement('defaultConnectionFactory'))
  106. $defaultConnectionFactory.SetAttribute('type', $TypeName)
  107. if ($ConstructorArguments)
  108. {
  109. $parameters = $defaultConnectionFactory.AppendChild($configXml.CreateElement('parameters'))
  110. foreach ($constructorArgument in $ConstructorArguments)
  111. {
  112. $parameter = $parameters.AppendChild($configXml.CreateElement('parameter'))
  113. $parameter.SetAttribute('value', $constructorArgument)
  114. }
  115. }
  116. $configXml.Save($configPath)
  117. }
  118. <#
  119. .SYNOPSIS
  120. Enables Code First Migrations in a project.
  121. .DESCRIPTION
  122. Enables Migrations by scaffolding a migrations configuration class in the project. If the
  123. target database was created by an initializer, an initial migration will be created (unless
  124. automatic migrations are enabled via the EnableAutomaticMigrations parameter).
  125. .PARAMETER ContextTypeName
  126. Specifies the context to use. If omitted, migrations will attempt to locate a
  127. single context type in the target project.
  128. .PARAMETER EnableAutomaticMigrations
  129. Specifies whether automatic migrations will be enabled in the scaffolded migrations configuration.
  130. If omitted, automatic migrations will be disabled.
  131. .PARAMETER MigrationsDirectory
  132. Specifies the name of the directory that will contain migrations code files.
  133. If omitted, the directory will be named "Migrations".
  134. .PARAMETER ProjectName
  135. Specifies the project that the scaffolded migrations configuration class will
  136. be added to. If omitted, the default project selected in package manager
  137. console is used.
  138. .PARAMETER StartUpProjectName
  139. Specifies the configuration file to use for named connection strings. If
  140. omitted, the specified project's configuration file is used.
  141. .PARAMETER ContextProjectName
  142. Specifies the project which contains the DbContext class to use. If omitted,
  143. the context is assumed to be in the same project used for migrations.
  144. .PARAMETER ConnectionStringName
  145. Specifies the name of a connection string to use from the application's
  146. configuration file.
  147. .PARAMETER ConnectionString
  148. Specifies the connection string to use. If omitted, the context's
  149. default connection will be used.
  150. .PARAMETER ConnectionProviderName
  151. Specifies the provider invariant name of the connection string.
  152. .PARAMETER Force
  153. Specifies that the migrations configuration be overwritten when running more
  154. than once for a given project.
  155. .PARAMETER ContextAssemblyName
  156. Specifies the name of the assembly which contains the DbContext class to use. Use this
  157. parameter instead of ContextProjectName when the context is contained in a referenced
  158. assembly rather than in a project of the solution.
  159. .PARAMETER AppDomainBaseDirectory
  160. Specifies the directory to use for the app-domain that is used for running Migrations
  161. code such that the app-domain is able to find all required assemblies. This is an
  162. advanced option that should only be needed if the solution contains several projects
  163. such that the assemblies needed for the context and configuration are not all
  164. referenced from either the project containing the context or the project containing
  165. the migrations.
  166. .EXAMPLE
  167. Enable-Migrations
  168. # Scaffold a migrations configuration in a project with only one context
  169. .EXAMPLE
  170. Enable-Migrations -Auto
  171. # Scaffold a migrations configuration with automatic migrations enabled for a project
  172. # with only one context
  173. .EXAMPLE
  174. Enable-Migrations -ContextTypeName MyContext -MigrationsDirectory DirectoryName
  175. # Scaffold a migrations configuration for a project with multiple contexts
  176. # This scaffolds a migrations configuration for MyContext and will put the configuration
  177. # and subsequent configurations in a new directory called "DirectoryName"
  178. #>
  179. function Enable-Migrations
  180. {
  181. [CmdletBinding(DefaultParameterSetName = 'ConnectionStringName', PositionalBinding = $false)]
  182. param(
  183. [string] $ContextTypeName,
  184. [alias('Auto')]
  185. [switch] $EnableAutomaticMigrations,
  186. [string] $MigrationsDirectory,
  187. [string] $ProjectName,
  188. [string] $StartUpProjectName,
  189. [string] $ContextProjectName,
  190. [parameter(ParameterSetName = 'ConnectionStringName')]
  191. [string] $ConnectionStringName,
  192. [parameter(ParameterSetName = 'ConnectionStringAndProviderName', Mandatory = $true)]
  193. [string] $ConnectionString,
  194. [parameter(ParameterSetName = 'ConnectionStringAndProviderName', Mandatory = $true)]
  195. [string] $ConnectionProviderName,
  196. [switch] $Force,
  197. [string] $ContextAssemblyName,
  198. [string] $AppDomainBaseDirectory)
  199. WarnIfOtherEFs 'Enable-Migrations'
  200. $project = GetProject $ProjectName
  201. $startupProject = GetStartupProject $StartUpProjectName $project
  202. if (!$ContextAssemblyName -and $ContextProjectName)
  203. {
  204. $contextProject = Get-Project $ContextProjectName
  205. $ContextAssemblyName = GetProperty $contextProject.Properties 'AssemblyName'
  206. }
  207. $params = 'migrations', 'enable', '--json'
  208. if ($ContextTypeName)
  209. {
  210. $params += '--context', $ContextTypeName
  211. }
  212. if ($ContextAssemblyName)
  213. {
  214. $params += '--context-assembly', $ContextAssemblyName
  215. }
  216. if ($EnableAutomaticMigrations)
  217. {
  218. $params += '--auto'
  219. }
  220. if ($MigrationsDirectory)
  221. {
  222. $params += '--migrations-dir', $MigrationsDirectory
  223. }
  224. $params += GetParams $ConnectionStringName $ConnectionString $ConnectionProviderName
  225. if ($Force)
  226. {
  227. $params += '--force'
  228. }
  229. # NB: -join is here to support ConvertFrom-Json on PowerShell 3.0
  230. $result = (EF6 $project $startupProject $AppDomainBaseDirectory $params) -join "`n" | ConvertFrom-Json
  231. $project.ProjectItems.AddFromFile($result.migrationsConfiguration) | Out-Null
  232. $DTE.ItemOperations.OpenFile($result.migrationsConfiguration) | Out-Null
  233. ShowConsole
  234. if ($result.migration)
  235. {
  236. $project.ProjectItems.AddFromFile($result.migration) | Out-Null
  237. $resourcesProperties = $project.ProjectItems.AddFromFile($result.migrationResources).Properties
  238. $project.ProjectItems.AddFromFile($result.migrationDesigner) | Out-Null
  239. }
  240. }
  241. <#
  242. .SYNOPSIS
  243. Scaffolds a migration script for any pending model changes.
  244. .DESCRIPTION
  245. Scaffolds a new migration script and adds it to the project.
  246. .PARAMETER Name
  247. Specifies the name of the custom script.
  248. .PARAMETER Force
  249. Specifies that the migration user code be overwritten when re-scaffolding an
  250. existing migration.
  251. .PARAMETER ProjectName
  252. Specifies the project that contains the migration configuration type to be
  253. used. If omitted, the default project selected in package manager console
  254. is used.
  255. .PARAMETER StartUpProjectName
  256. Specifies the configuration file to use for named connection strings. If
  257. omitted, the specified project's configuration file is used.
  258. .PARAMETER ConfigurationTypeName
  259. Specifies the migrations configuration to use. If omitted, migrations will
  260. attempt to locate a single migrations configuration type in the target
  261. project.
  262. .PARAMETER ConnectionStringName
  263. Specifies the name of a connection string to use from the application's
  264. configuration file.
  265. .PARAMETER ConnectionString
  266. Specifies the connection string to use. If omitted, the context's
  267. default connection will be used.
  268. .PARAMETER ConnectionProviderName
  269. Specifies the provider invariant name of the connection string.
  270. .PARAMETER IgnoreChanges
  271. Scaffolds an empty migration ignoring any pending changes detected in the current model.
  272. This can be used to create an initial, empty migration to enable Migrations for an existing
  273. database. N.B. Doing this assumes that the target database schema is compatible with the
  274. current model.
  275. .PARAMETER AppDomainBaseDirectory
  276. Specifies the directory to use for the app-domain that is used for running Migrations
  277. code such that the app-domain is able to find all required assemblies. This is an
  278. advanced option that should only be needed if the solution contains several projects
  279. such that the assemblies needed for the context and configuration are not all
  280. referenced from either the project containing the context or the project containing
  281. the migrations.
  282. .EXAMPLE
  283. Add-Migration First
  284. # Scaffold a new migration named "First"
  285. .EXAMPLE
  286. Add-Migration First -IgnoreChanges
  287. # Scaffold an empty migration ignoring any pending changes detected in the current model.
  288. # This can be used to create an initial, empty migration to enable Migrations for an existing
  289. # database. N.B. Doing this assumes that the target database schema is compatible with the
  290. # current model.
  291. #>
  292. function Add-Migration
  293. {
  294. [CmdletBinding(DefaultParameterSetName = 'ConnectionStringName', PositionalBinding = $false)]
  295. param(
  296. [parameter(Position = 0, Mandatory = $true)]
  297. [string] $Name,
  298. [switch] $Force,
  299. [string] $ProjectName,
  300. [string] $StartUpProjectName,
  301. [string] $ConfigurationTypeName,
  302. [parameter(ParameterSetName = 'ConnectionStringName')]
  303. [string] $ConnectionStringName,
  304. [parameter(ParameterSetName = 'ConnectionStringAndProviderName', Mandatory = $true)]
  305. [string] $ConnectionString,
  306. [parameter(ParameterSetName = 'ConnectionStringAndProviderName', Mandatory = $true)]
  307. [string] $ConnectionProviderName,
  308. [switch] $IgnoreChanges,
  309. [string] $AppDomainBaseDirectory)
  310. WarnIfOtherEFs 'Add-Migration'
  311. $project = GetProject $ProjectName
  312. $startupProject = GetStartupProject $StartUpProjectName $project
  313. $params = 'migrations', 'add', $Name, '--json'
  314. if ($Force)
  315. {
  316. $params += '--force'
  317. }
  318. if ($ConfigurationTypeName)
  319. {
  320. $params += '--migrations-config', $ConfigurationTypeName
  321. }
  322. if ($IgnoreChanges)
  323. {
  324. $params += '--ignore-changes'
  325. }
  326. $params += GetParams $ConnectionStringName $ConnectionString $ConnectionProviderName
  327. # NB: -join is here to support ConvertFrom-Json on PowerShell 3.0
  328. $result = (EF6 $project $startupProject $AppDomainBaseDirectory $params) -join "`n" | ConvertFrom-Json
  329. $project.ProjectItems.AddFromFile($result.migration) | Out-Null
  330. $DTE.ItemOperations.OpenFile($result.migration) | Out-Null
  331. $resourcesProperties = $project.ProjectItems.AddFromFile($result.migrationResources).Properties
  332. $project.ProjectItems.AddFromFile($result.migrationDesigner) | Out-Null
  333. }
  334. <#
  335. .SYNOPSIS
  336. Applies any pending migrations to the database.
  337. .DESCRIPTION
  338. Updates the database to the current model by applying pending migrations.
  339. .PARAMETER SourceMigration
  340. Only valid with -Script. Specifies the name of a particular migration to use
  341. as the update's starting point. If omitted, the last applied migration in
  342. the database will be used.
  343. .PARAMETER TargetMigration
  344. Specifies the name of a particular migration to update the database to. If
  345. omitted, the current model will be used.
  346. .PARAMETER Script
  347. Generate a SQL script rather than executing the pending changes directly.
  348. .PARAMETER Force
  349. Specifies that data loss is acceptable during automatic migration of the
  350. database.
  351. .PARAMETER ProjectName
  352. Specifies the project that contains the migration configuration type to be
  353. used. If omitted, the default project selected in package manager console
  354. is used.
  355. .PARAMETER StartUpProjectName
  356. Specifies the configuration file to use for named connection strings. If
  357. omitted, the specified project's configuration file is used.
  358. .PARAMETER ConfigurationTypeName
  359. Specifies the migrations configuration to use. If omitted, migrations will
  360. attempt to locate a single migrations configuration type in the target
  361. project.
  362. .PARAMETER ConnectionStringName
  363. Specifies the name of a connection string to use from the application's
  364. configuration file.
  365. .PARAMETER ConnectionString
  366. Specifies the connection string to use. If omitted, the context's
  367. default connection will be used.
  368. .PARAMETER ConnectionProviderName
  369. Specifies the provider invariant name of the connection string.
  370. .PARAMETER AppDomainBaseDirectory
  371. Specifies the directory to use for the app-domain that is used for running Migrations
  372. code such that the app-domain is able to find all required assemblies. This is an
  373. advanced option that should only be needed if the solution contains several projects
  374. such that the assemblies needed for the context and configuration are not all
  375. referenced from either the project containing the context or the project containing
  376. the migrations.
  377. .EXAMPLE
  378. Update-Database
  379. # Update the database to the latest migration
  380. .EXAMPLE
  381. Update-Database -TargetMigration Second
  382. # Update database to a migration named "Second"
  383. # This will apply migrations if the target hasn't been applied or roll back migrations
  384. # if it has
  385. .EXAMPLE
  386. Update-Database -Script
  387. # Generate a script to update the database from its current state to the latest migration
  388. .EXAMPLE
  389. Update-Database -Script -SourceMigration Second -TargetMigration First
  390. # Generate a script to migrate the database from a specified start migration
  391. # named "Second" to a specified target migration named "First"
  392. .EXAMPLE
  393. Update-Database -Script -SourceMigration $InitialDatabase
  394. # Generate a script that can upgrade a database currently at any version to the latest version.
  395. # The generated script includes logic to check the __MigrationsHistory table and only apply changes
  396. # that haven't been previously applied.
  397. .EXAMPLE
  398. Update-Database -TargetMigration $InitialDatabase
  399. # Runs the Down method to roll-back any migrations that have been applied to the database
  400. #>
  401. function Update-Database
  402. {
  403. [CmdletBinding(DefaultParameterSetName = 'ConnectionStringName', PositionalBinding = $false)]
  404. param(
  405. [string] $SourceMigration,
  406. [string] $TargetMigration,
  407. [switch] $Script,
  408. [switch] $Force,
  409. [string] $ProjectName,
  410. [string] $StartUpProjectName,
  411. [string] $ConfigurationTypeName,
  412. [parameter(ParameterSetName = 'ConnectionStringName')]
  413. [string] $ConnectionStringName,
  414. [parameter(ParameterSetName = 'ConnectionStringAndProviderName', Mandatory = $true)]
  415. [string] $ConnectionString,
  416. [parameter(ParameterSetName = 'ConnectionStringAndProviderName', Mandatory = $true)]
  417. [string] $ConnectionProviderName,
  418. [string] $AppDomainBaseDirectory)
  419. WarnIfOtherEFs 'Update-Database'
  420. $project = GetProject $ProjectName
  421. $startupProject = GetStartupProject $StartUpProjectName $project
  422. $params = 'database', 'update'
  423. if ($SourceMigration)
  424. {
  425. $params += '--source', $SourceMigration
  426. }
  427. if ($TargetMigration)
  428. {
  429. $params += '--target', $TargetMigration
  430. }
  431. if ($Script)
  432. {
  433. $params += '--script'
  434. }
  435. if ($Force)
  436. {
  437. $params += '--force'
  438. }
  439. if ($ConfigurationTypeName)
  440. {
  441. $params += '--migrations-config', $ConfigurationTypeName
  442. }
  443. $params += GetParams $ConnectionStringName $ConnectionString $ConnectionProviderName
  444. $result = (EF6 $project $startupProject $AppDomainBaseDirectory $params) -join "`n"
  445. if ($result)
  446. {
  447. try
  448. {
  449. $window = $DTE.ItemOperations.NewFile('General\Sql File')
  450. $textDocument = $window.Document.Object('TextDocument')
  451. $editPoint = $textDocument.StartPoint.CreateEditPoint()
  452. $editPoint.Insert($result)
  453. }
  454. catch
  455. {
  456. $intermediatePath = GetIntermediatePath $project
  457. if (![IO.Path]::IsPathRooted($intermediatePath))
  458. {
  459. $projectDir = GetProperty $project.Properties 'FullPath'
  460. $intermediatePath = Join-Path $projectDir $intermediatePath -Resolve | Convert-Path
  461. }
  462. $fileName = [IO.Path]::ChangeExtension([IO.Path]::GetRandomFileName(), '.sql')
  463. $sqlFile = Join-Path $intermediatePath $fileName
  464. [IO.File]::WriteAllText($sqlFile, $result)
  465. $DTE.ItemOperations.OpenFile($sqlFile) | Out-Null
  466. }
  467. ShowConsole
  468. }
  469. }
  470. <#
  471. .SYNOPSIS
  472. Displays the migrations that have been applied to the target database.
  473. .DESCRIPTION
  474. Displays the migrations that have been applied to the target database.
  475. .PARAMETER ProjectName
  476. Specifies the project that contains the migration configuration type to be
  477. used. If omitted, the default project selected in package manager console
  478. is used.
  479. .PARAMETER StartUpProjectName
  480. Specifies the configuration file to use for named connection strings. If
  481. omitted, the specified project's configuration file is used.
  482. .PARAMETER ConfigurationTypeName
  483. Specifies the migrations configuration to use. If omitted, migrations will
  484. attempt to locate a single migrations configuration type in the target
  485. project.
  486. .PARAMETER ConnectionStringName
  487. Specifies the name of a connection string to use from the application's
  488. configuration file.
  489. .PARAMETER ConnectionString
  490. Specifies the connection string to use. If omitted, the context's
  491. default connection will be used.
  492. .PARAMETER ConnectionProviderName
  493. Specifies the provider invariant name of the connection string.
  494. .PARAMETER AppDomainBaseDirectory
  495. Specifies the directory to use for the app-domain that is used for running Migrations
  496. code such that the app-domain is able to find all required assemblies. This is an
  497. advanced option that should only be needed if the solution contains several projects
  498. such that the assemblies needed for the context and configuration are not all
  499. referenced from either the project containing the context or the project containing
  500. the migrations.
  501. #>
  502. function Get-Migrations
  503. {
  504. [CmdletBinding(DefaultParameterSetName = 'ConnectionStringName', PositionalBinding = $false)]
  505. param(
  506. [string] $ProjectName,
  507. [string] $StartUpProjectName,
  508. [string] $ConfigurationTypeName,
  509. [parameter(ParameterSetName = 'ConnectionStringName')]
  510. [string] $ConnectionStringName,
  511. [parameter(ParameterSetName = 'ConnectionStringAndProviderName', Mandatory = $true)]
  512. [string] $ConnectionString,
  513. [parameter(ParameterSetName = 'ConnectionStringAndProviderName', Mandatory = $true)]
  514. [string] $ConnectionProviderName,
  515. [string] $AppDomainBaseDirectory)
  516. WarnIfOtherEFs 'Get-Migrations'
  517. $project = GetProject $ProjectName
  518. $startupProject = GetStartupProject $StartUpProjectName $project
  519. $params = 'migrations', 'list'
  520. if ($ConfigurationTypeName)
  521. {
  522. $params += '--migrations-config', $ConfigurationTypeName
  523. }
  524. $params += GetParams $ConnectionStringName $ConnectionString $ConnectionProviderName
  525. return EF6 $project $startupProject $AppDomainBaseDirectory $params
  526. }
  527. function WarnIfOtherEFs($cmdlet)
  528. {
  529. if (Get-Module 'EntityFrameworkCore')
  530. {
  531. Write-Warning "Both Entity Framework 6 and Entity Framework Core are installed. The Entity Framework 6 tools are running. Use 'EntityFrameworkCore\$cmdlet' for Entity Framework Core."
  532. }
  533. if (Get-Module 'EntityFramework')
  534. {
  535. Write-Warning "A version of Entity Framework older than 6.3 is also installed. The newer tools are running. Use 'EntityFramework\$cmdlet' for the older version."
  536. }
  537. }
  538. function GetProject($projectName)
  539. {
  540. if (!$projectName)
  541. {
  542. return Get-Project
  543. }
  544. return Get-Project $projectName
  545. }
  546. function GetStartupProject($name, $fallbackProject)
  547. {
  548. if ($name)
  549. {
  550. return Get-Project $name
  551. }
  552. $startupProjectPaths = $DTE.Solution.SolutionBuild.StartupProjects
  553. if ($startupProjectPaths)
  554. {
  555. if ($startupProjectPaths.Length -eq 1)
  556. {
  557. $startupProjectPath = $startupProjectPaths[0]
  558. if (![IO.Path]::IsPathRooted($startupProjectPath))
  559. {
  560. $solutionPath = Split-Path (GetProperty $DTE.Solution.Properties 'Path')
  561. $startupProjectPath = Join-Path $solutionPath $startupProjectPath -Resolve | Convert-Path
  562. }
  563. $startupProject = GetSolutionProjects |
  564. ?{
  565. try
  566. {
  567. $fullName = $_.FullName
  568. }
  569. catch [NotImplementedException]
  570. {
  571. return $false
  572. }
  573. if ($fullName -and $fullName.EndsWith('\'))
  574. {
  575. $fullName = $fullName.Substring(0, $fullName.Length - 1)
  576. }
  577. return $fullName -eq $startupProjectPath
  578. }
  579. if ($startupProject)
  580. {
  581. return $startupProject
  582. }
  583. Write-Warning "Unable to resolve startup project '$startupProjectPath'."
  584. }
  585. else
  586. {
  587. Write-Warning 'Multiple startup projects set.'
  588. }
  589. }
  590. else
  591. {
  592. Write-Warning 'No startup project set.'
  593. }
  594. Write-Warning "Using project '$($fallbackProject.ProjectName)' as the startup project."
  595. return $fallbackProject
  596. }
  597. function GetSolutionProjects()
  598. {
  599. $projects = New-Object 'System.Collections.Stack'
  600. $DTE.Solution.Projects |
  601. %{ $projects.Push($_) }
  602. while ($projects.Count)
  603. {
  604. $project = $projects.Pop();
  605. <# yield return #> $project
  606. if ($project.ProjectItems)
  607. {
  608. $project.ProjectItems |
  609. ?{ $_.SubProject } |
  610. %{ $projects.Push($_.SubProject) }
  611. }
  612. }
  613. }
  614. function GetParams($connectionStringName, $connectionString, $connectionProviderName)
  615. {
  616. $params = @()
  617. if ($connectionStringName)
  618. {
  619. $params += '--connection-string-name', $connectionStringName
  620. }
  621. if ($connectionString)
  622. {
  623. $params += '--connection-string', $connectionString,
  624. '--connection-provider', $connectionProviderName
  625. }
  626. return $params
  627. }
  628. function ShowConsole
  629. {
  630. $componentModel = Get-VSComponentModel
  631. $powerConsoleWindow = $componentModel.GetService([NuGetConsole.IPowerConsoleWindow])
  632. $powerConsoleWindow.Show()
  633. }
  634. function WriteErrorLine($message)
  635. {
  636. try
  637. {
  638. # Call the internal API NuGet uses to display errors
  639. $componentModel = Get-VSComponentModel
  640. $powerConsoleWindow = $componentModel.GetService([NuGetConsole.IPowerConsoleWindow])
  641. $bindingFlags = [Reflection.BindingFlags]::Instance -bor [Reflection.BindingFlags]::NonPublic
  642. $activeHostInfo = $powerConsoleWindow.GetType().GetProperty('ActiveHostInfo', $bindingFlags).GetValue($powerConsoleWindow)
  643. $internalHost = $activeHostInfo.WpfConsole.Host
  644. $reportErrorMethod = $internalHost.GetType().GetMethod('ReportError', $bindingFlags, $null, [Exception], $null)
  645. $exception = New-Object Exception $message
  646. $reportErrorMethod.Invoke($internalHost, $exception)
  647. }
  648. catch
  649. {
  650. Write-Host $message -ForegroundColor DarkRed
  651. }
  652. }
  653. function EF6($project, $startupProject, $workingDir, $params)
  654. {
  655. $solutionBuild = $DTE.Solution.SolutionBuild
  656. $solutionBuild.BuildProject(
  657. $solutionBuild.ActiveConfiguration.Name,
  658. $project.UniqueName,
  659. <# WaitForBuildToFinish #> $true)
  660. if ($solutionBuild.LastBuildInfo)
  661. {
  662. throw "The project '$($project.ProjectName)' failed to build."
  663. }
  664. $projectDir = GetProperty $project.Properties 'FullPath'
  665. $outputPath = GetProperty $project.ConfigurationManager.ActiveConfiguration.Properties 'OutputPath'
  666. $targetDir = [IO.Path]::GetFullPath([IO.Path]::Combine($projectDir, $outputPath))
  667. $targetFrameworkMoniker = GetProperty $project.Properties 'TargetFrameworkMoniker'
  668. $frameworkName = New-Object 'System.Runtime.Versioning.FrameworkName' $targetFrameworkMoniker
  669. $targetFrameworkIdentifier = $frameworkName.Identifier
  670. $targetFrameworkVersion = $frameworkName.Version
  671. if ($targetFrameworkIdentifier -in '.NETFramework')
  672. {
  673. if ($targetFrameworkVersion -lt '4.5')
  674. {
  675. $frameworkDir = 'net40'
  676. }
  677. else
  678. {
  679. $frameworkDir = 'net45'
  680. }
  681. $platformTarget = GetPlatformTarget $project
  682. if ($platformTarget -eq 'x86')
  683. {
  684. $runtimeDir = 'win-x86'
  685. }
  686. elseif ($platformTarget -in 'AnyCPU', 'x64')
  687. {
  688. $runtimeDir = 'any'
  689. }
  690. else
  691. {
  692. throw "Project '$($project.ProjectName)' has an active platform of '$platformTarget'. Select a different " +
  693. 'platform and try again.'
  694. }
  695. $exePath = Join-Path $PSScriptRoot "$frameworkDir\$runtimeDir\ef6.exe"
  696. }
  697. elseif ($targetFrameworkIdentifier -eq '.NETCoreApp')
  698. {
  699. $exePath = (Get-Command 'dotnet').Path
  700. $targetName = GetProperty $project.Properties 'AssemblyName'
  701. $depsFile = Join-Path $targetDir ($targetName + '.deps.json')
  702. $projectAssetsFile = GetCpsProperty $project 'ProjectAssetsFile'
  703. $runtimeConfig = Join-Path $targetDir ($targetName + '.runtimeconfig.json')
  704. $runtimeFrameworkVersion = GetCpsProperty $project 'RuntimeFrameworkVersion'
  705. $efPath = Join-Path $PSScriptRoot 'netcoreapp3.0\any\ef6.dll'
  706. $dotnetParams = 'exec', '--depsfile', $depsFile
  707. if ($projectAssetsFile)
  708. {
  709. # NB: Don't use Get-Content. It doesn't handle UTF-8 without a signature
  710. # NB: Don't use ReadAllLines. ConvertFrom-Json won't work on PowerShell 3.0
  711. $projectAssets = [IO.File]::ReadAllText($projectAssetsFile) | ConvertFrom-Json
  712. $projectAssets.packageFolders.psobject.Properties.Name |
  713. %{ $dotnetParams += '--additionalprobingpath', $_.TrimEnd('\') }
  714. }
  715. if (Test-Path $runtimeConfig)
  716. {
  717. $dotnetParams += '--runtimeconfig', $runtimeConfig
  718. }
  719. elseif ($runtimeFrameworkVersion)
  720. {
  721. $dotnetParams += '--fx-version', $runtimeFrameworkVersion
  722. }
  723. $dotnetParams += $efPath
  724. $params = $dotnetParams + $params
  725. }
  726. else
  727. {
  728. throw "Project '$($startupProject.ProjectName)' targets framework '$targetFrameworkIdentifier'. The Entity Framework " +
  729. 'Package Manager Console Tools don''t support this framework.'
  730. }
  731. $targetFileName = GetProperty $project.Properties 'OutputFileName'
  732. $targetPath = Join-Path $targetDir $targetFileName
  733. $rootNamespace = GetProperty $project.Properties 'RootNamespace'
  734. $language = GetLanguage $project
  735. $params += '--verbose',
  736. '--no-color',
  737. '--prefix-output',
  738. '--assembly', $targetPath,
  739. '--project-dir', $projectDir,
  740. '--language', $language
  741. if (IsWeb $startupProject)
  742. {
  743. $startupProjectDir = GetProperty $startupProject.Properties 'FullPath'
  744. $params += '--data-dir', (Join-Path $startupProjectDir 'App_Data')
  745. }
  746. if ($rootNamespace)
  747. {
  748. $params += '--root-namespace', $rootNamespace
  749. }
  750. $configFile = GetConfigPath $startupProject
  751. if ($configFile)
  752. {
  753. $params += '--config', $configFile
  754. }
  755. if (!$workingDir)
  756. {
  757. $workingDir = $targetDir
  758. }
  759. $arguments = ToArguments $params
  760. $startInfo = New-Object 'System.Diagnostics.ProcessStartInfo' -Property @{
  761. FileName = $exePath;
  762. Arguments = $arguments;
  763. UseShellExecute = $false;
  764. CreateNoWindow = $true;
  765. RedirectStandardOutput = $true;
  766. StandardOutputEncoding = [Text.Encoding]::UTF8;
  767. RedirectStandardError = $true;
  768. WorkingDirectory = $workingDir;
  769. }
  770. Write-Verbose "$exePath $arguments"
  771. $process = [Diagnostics.Process]::Start($startInfo)
  772. while (($line = $process.StandardOutput.ReadLine()) -ne $null)
  773. {
  774. $level = $null
  775. $text = $null
  776. $parts = $line.Split(':', 2)
  777. if ($parts.Length -eq 2)
  778. {
  779. $level = $parts[0]
  780. $i = 0
  781. $count = 8 - $level.Length
  782. while ($i -lt $count -and $parts[1][$i] -eq ' ')
  783. {
  784. $i++
  785. }
  786. $text = $parts[1].Substring($i)
  787. }
  788. switch ($level)
  789. {
  790. 'error' { WriteErrorLine $text }
  791. 'warn' { Write-Warning $text }
  792. 'info' { Write-Host $text }
  793. 'data' { Write-Output $text }
  794. 'verbose' { Write-Verbose $text }
  795. default { Write-Host $line }
  796. }
  797. }
  798. $process.WaitForExit()
  799. if ($process.ExitCode)
  800. {
  801. while (($line = $process.StandardError.ReadLine()) -ne $null)
  802. {
  803. WriteErrorLine $line
  804. }
  805. exit
  806. }
  807. }
  808. function IsCpsProject($project)
  809. {
  810. $hierarchy = GetVsHierarchy $project
  811. $isCapabilityMatch = [Microsoft.VisualStudio.Shell.PackageUtilities].GetMethod(
  812. 'IsCapabilityMatch',
  813. [type[]]([Microsoft.VisualStudio.Shell.Interop.IVsHierarchy], [string]))
  814. return $isCapabilityMatch.Invoke($null, ($hierarchy, 'CPS'))
  815. }
  816. function IsWeb($project)
  817. {
  818. $hierarchy = GetVsHierarchy $project
  819. $aggregatableProject = Get-Interface $hierarchy 'Microsoft.VisualStudio.Shell.Interop.IVsAggregatableProject'
  820. if (!$aggregatableProject)
  821. {
  822. $projectTypes = $project.Kind
  823. }
  824. else
  825. {
  826. $projectTypeGuids = $null
  827. $hr = $aggregatableProject.GetAggregateProjectTypeGuids([ref] $projectTypeGuids)
  828. [Runtime.InteropServices.Marshal]::ThrowExceptionForHR($hr)
  829. $projectTypes = $projectTypeGuids.Split(';')
  830. }
  831. foreach ($projectType in $projectTypes)
  832. {
  833. if ($projectType -in '{349C5851-65DF-11DA-9384-00065B846F21}', '{E24C65DC-7377-472B-9ABA-BC803B73C61A}')
  834. {
  835. return $true
  836. }
  837. }
  838. return $false;
  839. }
  840. function GetIntermediatePath($project)
  841. {
  842. $intermediatePath = GetProperty $project.ConfigurationManager.ActiveConfiguration.Properties 'IntermediatePath'
  843. if ($intermediatePath)
  844. {
  845. return $intermediatePath
  846. }
  847. return GetMSBuildProperty $project 'IntermediateOutputPath'
  848. }
  849. function GetPlatformTarget($project)
  850. {
  851. if (IsCpsProject $project)
  852. {
  853. $platformTarget = GetCpsProperty $project 'PlatformTarget'
  854. if ($platformTarget)
  855. {
  856. return $platformTarget
  857. }
  858. return GetCpsProperty $project 'Platform'
  859. }
  860. $platformTarget = GetProperty $project.ConfigurationManager.ActiveConfiguration.Properties 'PlatformTarget'
  861. if ($platformTarget)
  862. {
  863. return $platformTarget
  864. }
  865. # NB: For classic F# projects
  866. $platformTarget = GetMSBuildProperty $project 'PlatformTarget'
  867. if ($platformTarget)
  868. {
  869. return $platformTarget
  870. }
  871. return 'AnyCPU'
  872. }
  873. function GetLanguage($project)
  874. {
  875. if (IsCpsProject $project)
  876. {
  877. return GetCpsProperty $project 'Language'
  878. }
  879. return GetMSBuildProperty $project 'Language'
  880. }
  881. function GetVsHierarchy($project)
  882. {
  883. $solution = Get-VSService 'Microsoft.VisualStudio.Shell.Interop.SVsSolution' 'Microsoft.VisualStudio.Shell.Interop.IVsSolution'
  884. $hierarchy = $null
  885. $hr = $solution.GetProjectOfUniqueName($project.UniqueName, [ref] $hierarchy)
  886. [Runtime.InteropServices.Marshal]::ThrowExceptionForHR($hr)
  887. return $hierarchy
  888. }
  889. function GetProperty($properties, $propertyName)
  890. {
  891. try
  892. {
  893. return $properties.Item($propertyName).Value
  894. }
  895. catch
  896. {
  897. return $null
  898. }
  899. }
  900. function GetCpsProperty($project, $propertyName)
  901. {
  902. $browseObjectContext = Get-Interface $project 'Microsoft.VisualStudio.ProjectSystem.Properties.IVsBrowseObjectContext'
  903. $unconfiguredProject = $browseObjectContext.UnconfiguredProject
  904. $configuredProject = $unconfiguredProject.GetSuggestedConfiguredProjectAsync().Result
  905. $properties = $configuredProject.Services.ProjectPropertiesProvider.GetCommonProperties()
  906. return $properties.GetEvaluatedPropertyValueAsync($propertyName).Result
  907. }
  908. function GetMSBuildProperty($project, $propertyName)
  909. {
  910. $msbuildProject = [Microsoft.Build.Evaluation.ProjectCollection]::GlobalProjectCollection.LoadedProjects |
  911. where FullPath -eq $project.FullName
  912. return $msbuildProject.GetProperty($propertyName).EvaluatedValue
  913. }
  914. function ToArguments($params)
  915. {
  916. $arguments = ''
  917. for ($i = 0; $i -lt $params.Length; $i++)
  918. {
  919. if ($i)
  920. {
  921. $arguments += ' '
  922. }
  923. if (!$params[$i].Contains(' '))
  924. {
  925. $arguments += $params[$i]
  926. continue
  927. }
  928. $arguments += '"'
  929. $pendingBackslashs = 0
  930. for ($j = 0; $j -lt $params[$i].Length; $j++)
  931. {
  932. switch ($params[$i][$j])
  933. {
  934. '"'
  935. {
  936. if ($pendingBackslashs)
  937. {
  938. $arguments += '\' * $pendingBackslashs * 2
  939. $pendingBackslashs = 0
  940. }
  941. $arguments += '\"'
  942. }
  943. '\'
  944. {
  945. $pendingBackslashs++
  946. }
  947. default
  948. {
  949. if ($pendingBackslashs)
  950. {
  951. if ($pendingBackslashs -eq 1)
  952. {
  953. $arguments += '\'
  954. }
  955. else
  956. {
  957. $arguments += '\' * $pendingBackslashs * 2
  958. }
  959. $pendingBackslashs = 0
  960. }
  961. $arguments += $params[$i][$j]
  962. }
  963. }
  964. }
  965. if ($pendingBackslashs)
  966. {
  967. $arguments += '\' * $pendingBackslashs * 2
  968. }
  969. $arguments += '"'
  970. }
  971. return $arguments
  972. }
  973. function GetConfigPath($project)
  974. {
  975. if (IsWeb $project)
  976. {
  977. $configFileName = 'web.config'
  978. }
  979. else
  980. {
  981. $configFileName = 'app.config'
  982. }
  983. $item = $project.ProjectItems |
  984. where Name -eq $configFileName |
  985. select -First 1
  986. return GetProperty $item.Properties 'FullPath'
  987. }
  988. Export-ModuleMember 'Add-EFDefaultConnectionFactory', 'Add-EFProvider', 'Add-Migration', 'Enable-Migrations', 'Get-Migrations', 'Update-Database' -Variable 'InitialDatabase'
  989. # SIG # Begin signature block
  990. # MIIkWAYJKoZIhvcNAQcCoIIkSTCCJEUCAQExDzANBglghkgBZQMEAgEFADB5Bgor
  991. # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
  992. # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBU8UKKdFAqCZNi
  993. # qPoRSiuscSg+YrZwC3TMOd7p8fuNZKCCDYEwggX/MIID56ADAgECAhMzAAABUZ6N
  994. # j0Bxow5BAAAAAAFRMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD
  995. # VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
  996. # b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p
  997. # bmcgUENBIDIwMTEwHhcNMTkwNTAyMjEzNzQ2WhcNMjAwNTAyMjEzNzQ2WjB0MQsw
  998. # CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u
  999. # ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy
  1000. # b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
  1001. # AQCVWsaGaUcdNB7xVcNmdfZiVBhYFGcn8KMqxgNIvOZWNH9JYQLuhHhmJ5RWISy1
  1002. # oey3zTuxqLbkHAdmbeU8NFMo49Pv71MgIS9IG/EtqwOH7upan+lIq6NOcw5fO6Os
  1003. # +12R0Q28MzGn+3y7F2mKDnopVu0sEufy453gxz16M8bAw4+QXuv7+fR9WzRJ2CpU
  1004. # 62wQKYiFQMfew6Vh5fuPoXloN3k6+Qlz7zgcT4YRmxzx7jMVpP/uvK6sZcBxQ3Wg
  1005. # B/WkyXHgxaY19IAzLq2QiPiX2YryiR5EsYBq35BP7U15DlZtpSs2wIYTkkDBxhPJ
  1006. # IDJgowZu5GyhHdqrst3OjkSRAgMBAAGjggF+MIIBejAfBgNVHSUEGDAWBgorBgEE
  1007. # AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUV4Iarkq57esagu6FUBb270Zijc8w
  1008. # UAYDVR0RBEkwR6RFMEMxKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVyYXRpb25zIFB1
  1009. # ZXJ0byBSaWNvMRYwFAYDVQQFEw0yMzAwMTIrNDU0MTM1MB8GA1UdIwQYMBaAFEhu
  1010. # ZOVQBdOCqhc3NyK1bajKdQKVMFQGA1UdHwRNMEswSaBHoEWGQ2h0dHA6Ly93d3cu
  1011. # bWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY0NvZFNpZ1BDQTIwMTFfMjAxMS0w
  1012. # Ny0wOC5jcmwwYQYIKwYBBQUHAQEEVTBTMFEGCCsGAQUFBzAChkVodHRwOi8vd3d3
  1013. # Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY0NvZFNpZ1BDQTIwMTFfMjAx
  1014. # MS0wNy0wOC5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAgEAWg+A
  1015. # rS4Anq7KrogslIQnoMHSXUPr/RqOIhJX+32ObuY3MFvdlRElbSsSJxrRy/OCCZdS
  1016. # se+f2AqQ+F/2aYwBDmUQbeMB8n0pYLZnOPifqe78RBH2fVZsvXxyfizbHubWWoUf
  1017. # NW/FJlZlLXwJmF3BoL8E2p09K3hagwz/otcKtQ1+Q4+DaOYXWleqJrJUsnHs9UiL
  1018. # crVF0leL/Q1V5bshob2OTlZq0qzSdrMDLWdhyrUOxnZ+ojZ7UdTY4VnCuogbZ9Zs
  1019. # 9syJbg7ZUS9SVgYkowRsWv5jV4lbqTD+tG4FzhOwcRQwdb6A8zp2Nnd+s7VdCuYF
  1020. # sGgI41ucD8oxVfcAMjF9YX5N2s4mltkqnUe3/htVrnxKKDAwSYliaux2L7gKw+bD
  1021. # 1kEZ/5ozLRnJ3jjDkomTrPctokY/KaZ1qub0NUnmOKH+3xUK/plWJK8BOQYuU7gK
  1022. # YH7Yy9WSKNlP7pKj6i417+3Na/frInjnBkKRCJ/eYTvBH+s5guezpfQWtU4bNo/j
  1023. # 8Qw2vpTQ9w7flhH78Rmwd319+YTmhv7TcxDbWlyteaj4RK2wk3pY1oSz2JPE5PNu
  1024. # Nmd9Gmf6oePZgy7Ii9JLLq8SnULV7b+IP0UXRY9q+GdRjM2AEX6msZvvPCIoG0aY
  1025. # HQu9wZsKEK2jqvWi8/xdeeeSI9FN6K1w4oVQM4Mwggd6MIIFYqADAgECAgphDpDS
  1026. # AAAAAAADMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMK
  1027. # V2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0
  1028. # IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0
  1029. # ZSBBdXRob3JpdHkgMjAxMTAeFw0xMTA3MDgyMDU5MDlaFw0yNjA3MDgyMTA5MDla
  1030. # MH4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS
  1031. # ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMT
  1032. # H01pY3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTEwggIiMA0GCSqGSIb3DQEB
  1033. # AQUAA4ICDwAwggIKAoICAQCr8PpyEBwurdhuqoIQTTS68rZYIZ9CGypr6VpQqrgG
  1034. # OBoESbp/wwwe3TdrxhLYC/A4wpkGsMg51QEUMULTiQ15ZId+lGAkbK+eSZzpaF7S
  1035. # 35tTsgosw6/ZqSuuegmv15ZZymAaBelmdugyUiYSL+erCFDPs0S3XdjELgN1q2jz
  1036. # y23zOlyhFvRGuuA4ZKxuZDV4pqBjDy3TQJP4494HDdVceaVJKecNvqATd76UPe/7
  1037. # 4ytaEB9NViiienLgEjq3SV7Y7e1DkYPZe7J7hhvZPrGMXeiJT4Qa8qEvWeSQOy2u
  1038. # M1jFtz7+MtOzAz2xsq+SOH7SnYAs9U5WkSE1JcM5bmR/U7qcD60ZI4TL9LoDho33
  1039. # X/DQUr+MlIe8wCF0JV8YKLbMJyg4JZg5SjbPfLGSrhwjp6lm7GEfauEoSZ1fiOIl
  1040. # XdMhSz5SxLVXPyQD8NF6Wy/VI+NwXQ9RRnez+ADhvKwCgl/bwBWzvRvUVUvnOaEP
  1041. # 6SNJvBi4RHxF5MHDcnrgcuck379GmcXvwhxX24ON7E1JMKerjt/sW5+v/N2wZuLB
  1042. # l4F77dbtS+dJKacTKKanfWeA5opieF+yL4TXV5xcv3coKPHtbcMojyyPQDdPweGF
  1043. # RInECUzF1KVDL3SV9274eCBYLBNdYJWaPk8zhNqwiBfenk70lrC8RqBsmNLg1oiM
  1044. # CwIDAQABo4IB7TCCAekwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFEhuZOVQ
  1045. # BdOCqhc3NyK1bajKdQKVMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1Ud
  1046. # DwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFHItOgIxkEO5FAVO
  1047. # 4eqnxzHRI4k0MFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly9jcmwubWljcm9zb2Z0
  1048. # LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y
  1049. # Mi5jcmwwXgYIKwYBBQUHAQEEUjBQME4GCCsGAQUFBzAChkJodHRwOi8vd3d3Lm1p
  1050. # Y3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y
  1051. # Mi5jcnQwgZ8GA1UdIASBlzCBlDCBkQYJKwYBBAGCNy4DMIGDMD8GCCsGAQUFBwIB
  1052. # FjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2RvY3MvcHJpbWFyeWNw
  1053. # cy5odG0wQAYIKwYBBQUHAgIwNB4yIB0ATABlAGcAYQBsAF8AcABvAGwAaQBjAHkA
  1054. # XwBzAHQAYQB0AGUAbQBlAG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIBAGfyhqWY
  1055. # 4FR5Gi7T2HRnIpsLlhHhY5KZQpZ90nkMkMFlXy4sPvjDctFtg/6+P+gKyju/R6mj
  1056. # 82nbY78iNaWXXWWEkH2LRlBV2AySfNIaSxzzPEKLUtCw/WvjPgcuKZvmPRul1LUd
  1057. # d5Q54ulkyUQ9eHoj8xN9ppB0g430yyYCRirCihC7pKkFDJvtaPpoLpWgKj8qa1hJ
  1058. # Yx8JaW5amJbkg/TAj/NGK978O9C9Ne9uJa7lryft0N3zDq+ZKJeYTQ49C/IIidYf
  1059. # wzIY4vDFLc5bnrRJOQrGCsLGra7lstnbFYhRRVg4MnEnGn+x9Cf43iw6IGmYslmJ
  1060. # aG5vp7d0w0AFBqYBKig+gj8TTWYLwLNN9eGPfxxvFX1Fp3blQCplo8NdUmKGwx1j
  1061. # NpeG39rz+PIWoZon4c2ll9DuXWNB41sHnIc+BncG0QaxdR8UvmFhtfDcxhsEvt9B
  1062. # xw4o7t5lL+yX9qFcltgA1qFGvVnzl6UJS0gQmYAf0AApxbGbpT9Fdx41xtKiop96
  1063. # eiL6SJUfq/tHI4D1nvi/a7dLl+LrdXga7Oo3mXkYS//WsyNodeav+vyL6wuA6mk7
  1064. # r/ww7QRMjt/fdW1jkT3RnVZOT7+AVyKheBEyIXrvQQqxP/uozKRdwaGIm1dxVk5I
  1065. # RcBCyZt2WwqASGv9eZ/BvW1taslScxMNelDNMYIWLTCCFikCAQEwgZUwfjELMAkG
  1066. # A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx
  1067. # HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEoMCYGA1UEAxMfTWljcm9z
  1068. # b2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAxMQITMwAAAVGejY9AcaMOQQAAAAABUTAN
  1069. # BglghkgBZQMEAgEFAKCBrjAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgor
  1070. # BgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQg2WtigxAj
  1071. # Szfxqqdh6zz13s7WyYGwCYznISnC+usF34IwQgYKKwYBBAGCNwIBDDE0MDKgFIAS
  1072. # AE0AaQBjAHIAbwBzAG8AZgB0oRqAGGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbTAN
  1073. # BgkqhkiG9w0BAQEFAASCAQA2S2sCreRpLI9W0DFWRPY7mNwItsQCQ+U3OmimoDrE
  1074. # Ar/bxo9hJMLm3DlzOFqO/8djKo3gvjL5pfhclUtkgPChpYWM+6aln/J7RIb3ZNjw
  1075. # 6lWic4QZRD0qYTVLit4i+I4Ew+CYjfmDJP7pwLppqWaqnF0T8qRk5TrzS0tQL/5p
  1076. # lxZzUZwGMkwwB9srwUwE+hy8tZS3H1BWbJ8mumlhi9X9cDF+nL3pOFFXVPM13zs8
  1077. # ZfvjqzlDPnOcRt2FW8kN3OloRa7bl4Lu6LEXbn8n+wbuyJKwwTCNCSU26RQesPQB
  1078. # uqTG0L7mjmZlJsF1Ga+gefD3PqbG+df7cXzSPDNR649DoYITtzCCE7MGCisGAQQB
  1079. # gjcDAwExghOjMIITnwYJKoZIhvcNAQcCoIITkDCCE4wCAQMxDzANBglghkgBZQME
  1080. # AgEFADCCAVgGCyqGSIb3DQEJEAEEoIIBRwSCAUMwggE/AgEBBgorBgEEAYRZCgMB
  1081. # MDEwDQYJYIZIAWUDBAIBBQAEINWdRiCiKsTCKKoWnNe7xytEww32lPP/4fMUMSuG
  1082. # nDHpAgZdrfQxYwgYEzIwMTkxMTE2MDQ1MjM5LjQ4OVowBwIBAYACAfSggdSkgdEw
  1083. # gc4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS
  1084. # ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsT
  1085. # IE1pY3Jvc29mdCBPcGVyYXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFs
  1086. # ZXMgVFNTIEVTTjo3RDJFLTM3ODItQjBGNzElMCMGA1UEAxMcTWljcm9zb2Z0IFRp
  1087. # bWUtU3RhbXAgU2VydmljZaCCDx8wggZxMIIEWaADAgECAgphCYEqAAAAAAACMA0G
  1088. # CSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3Rv
  1089. # bjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0
  1090. # aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3Jp
  1091. # dHkgMjAxMDAeFw0xMDA3MDEyMTM2NTVaFw0yNTA3MDEyMTQ2NTVaMHwxCzAJBgNV
  1092. # BAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4w
  1093. # HAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29m
  1094. # dCBUaW1lLVN0YW1wIFBDQSAyMDEwMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
  1095. # CgKCAQEAqR0NvHcRijog7PwTl/X6f2mUa3RUENWlCgCChfvtfGhLLF/Fw+Vhwna3
  1096. # PmYrW/AVUycEMR9BGxqVHc4JE458YTBZsTBED/FgiIRUQwzXTbg4CLNC3ZOs1nMw
  1097. # VyaCo0UN0Or1R4HNvyRgMlhgRvJYR4YyhB50YWeRX4FUsc+TTJLBxKZd0WETbijG
  1098. # GvmGgLvfYfxGwScdJGcSchohiq9LZIlQYrFd/XcfPfBXday9ikJNQFHRD5wGPmd/
  1099. # 9WbAA5ZEfu/QS/1u5ZrKsajyeioKMfDaTgaRtogINeh4HLDpmc085y9Euqf03GS9
  1100. # pAHBIAmTeM38vMDJRF1eFpwBBU8iTQIDAQABo4IB5jCCAeIwEAYJKwYBBAGCNxUB
  1101. # BAMCAQAwHQYDVR0OBBYEFNVjOlyKMZDzQ3t8RhvFM2hahW1VMBkGCSsGAQQBgjcU
  1102. # AgQMHgoAUwB1AGIAQwBBMAsGA1UdDwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB8G
  1103. # A1UdIwQYMBaAFNX2VsuP6KJcYmjRPZSQW9fOmhjEMFYGA1UdHwRPME0wS6BJoEeG
  1104. # RWh0dHA6Ly9jcmwubWljcm9zb2Z0LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jv
  1105. # b0NlckF1dF8yMDEwLTA2LTIzLmNybDBaBggrBgEFBQcBAQROMEwwSgYIKwYBBQUH
  1106. # MAKGPmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2kvY2VydHMvTWljUm9vQ2Vy
  1107. # QXV0XzIwMTAtMDYtMjMuY3J0MIGgBgNVHSABAf8EgZUwgZIwgY8GCSsGAQQBgjcu
  1108. # AzCBgTA9BggrBgEFBQcCARYxaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL1BLSS9k
  1109. # b2NzL0NQUy9kZWZhdWx0Lmh0bTBABggrBgEFBQcCAjA0HjIgHQBMAGUAZwBhAGwA
  1110. # XwBQAG8AbABpAGMAeQBfAFMAdABhAHQAZQBtAGUAbgB0AC4gHTANBgkqhkiG9w0B
  1111. # AQsFAAOCAgEAB+aIUQ3ixuCYP4FxAz2do6Ehb7Prpsz1Mb7PBeKp/vpXbRkws8LF
  1112. # Zslq3/Xn8Hi9x6ieJeP5vO1rVFcIK1GCRBL7uVOMzPRgEop2zEBAQZvcXBf/XPle
  1113. # FzWYJFZLdO9CEMivv3/Gf/I3fVo/HPKZeUqRUgCvOA8X9S95gWXZqbVr5MfO9sp6
  1114. # AG9LMEQkIjzP7QOllo9ZKby2/QThcJ8ySif9Va8v/rbljjO7Yl+a21dA6fHOmWaQ
  1115. # jP9qYn/dxUoLkSbiOewZSnFjnXshbcOco6I8+n99lmqQeKZt0uGc+R38ONiU9Mal
  1116. # CpaGpL2eGq4EQoO4tYCbIjggtSXlZOz39L9+Y1klD3ouOVd2onGqBooPiRa6YacR
  1117. # y5rYDkeagMXQzafQ732D8OE7cQnfXXSYIghh2rBQHm+98eEA3+cxB6STOvdlR3jo
  1118. # +KhIq/fecn5ha293qYHLpwmsObvsxsvYgrRyzR30uIUBHoD7G4kqVDmyW9rIDVWZ
  1119. # eodzOwjmmC3qjeAzLhIp9cAvVCch98isTtoouLGp25ayp0Kiyc8ZQU3ghvkqmqMR
  1120. # ZjDTu3QyS99je/WZii8bxyGvWbWu3EQ8l1Bx16HSxVXjad5XwdHeMMD9zOZN+w2/
  1121. # XU/pnR4ZOC+8z1gFLu8NoFA12u8JJxzVs341Hgi62jbb01+P3nSISRIwggT1MIID
  1122. # 3aADAgECAhMzAAABACD3XJNW1XfQAAAAAAEAMA0GCSqGSIb3DQEBCwUAMHwxCzAJ
  1123. # BgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25k
  1124. # MR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jv
  1125. # c29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMB4XDTE5MDkwNjIwNDEwOVoXDTIwMTIw
  1126. # NDIwNDEwOVowgc4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAw
  1127. # DgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24x
  1128. # KTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVyYXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYD
  1129. # VQQLEx1UaGFsZXMgVFNTIEVTTjo3RDJFLTM3ODItQjBGNzElMCMGA1UEAxMcTWlj
  1130. # cm9zb2Z0IFRpbWUtU3RhbXAgU2VydmljZTCCASIwDQYJKoZIhvcNAQEBBQADggEP
  1131. # ADCCAQoCggEBAMnIkckxDYWl2r86ny3RRNZPgnu8mFPweH7BDSkOhGLAQO58RqX3
  1132. # n1EH8/Z6vb3kIxVQfV9fBCv3klv1HenWK0QDRIjrgWeWA1liAVWYe+Ob1uyntMQn
  1133. # m224xp1Rev33lwbxZU+nDohaSyebrtSIfa56YgA2jYwutY+fs/GDSGRRJXeO5N1x
  1134. # NKe+JsVXXc0vm50L2pMlYIOnGslEDLZmxXrPl1c7GC2Dp/V+errggr5I93acDZTU
  1135. # oY0VaGRXpt2hUm824/ExFXaQILhL9DFlqgmiHvZXukoSRyTfklLVoI3vX+I6ZMcT
  1136. # ciD9K8Rdx6wbB51VgASO5cDnEhqb3E+eKdECAwEAAaOCARswggEXMB0GA1UdDgQW
  1137. # BBRoV5MnLIc6idXGditSix4avdXG1zAfBgNVHSMEGDAWgBTVYzpcijGQ80N7fEYb
  1138. # xTNoWoVtVTBWBgNVHR8ETzBNMEugSaBHhkVodHRwOi8vY3JsLm1pY3Jvc29mdC5j
  1139. # b20vcGtpL2NybC9wcm9kdWN0cy9NaWNUaW1TdGFQQ0FfMjAxMC0wNy0wMS5jcmww
  1140. # WgYIKwYBBQUHAQEETjBMMEoGCCsGAQUFBzAChj5odHRwOi8vd3d3Lm1pY3Jvc29m
  1141. # dC5jb20vcGtpL2NlcnRzL01pY1RpbVN0YVBDQV8yMDEwLTA3LTAxLmNydDAMBgNV
  1142. # HRMBAf8EAjAAMBMGA1UdJQQMMAoGCCsGAQUFBwMIMA0GCSqGSIb3DQEBCwUAA4IB
  1143. # AQCifptCMXyHpJghB7zNYXmFzlzpxLlmtFAkiBOdn99EnxrCJda/EZuTt9gJROel
  1144. # 99Iy3IUpX3y/5AIZTQHPqEISnCs9Y327HWMwkZtWNnp/PPv7V6eZhYgE5gsNwxKW
  1145. # eH8A5oI2m8Xa3wSDCOPHCEF9IvEHaeisGY3tlU9ZlQLnj9aeJS2JqusHfsyyUYQ6
  1146. # eX5ZQiONaTmYCwiC8oeF2QNhCKiEhb28vqpMj6HCDfL4u55u5cRME/d3YvRUgp4m
  1147. # 02gu7Jk97u9nig5+eGH56pk7J9pkNBlXGWMATawGLUyl1N+V0yY8muWHBoAS55Lo
  1148. # Z7Rzh4aBJoi2YH5snmzSWGskoYIDrTCCApUCAQEwgf6hgdSkgdEwgc4xCzAJBgNV
  1149. # BAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4w
  1150. # HAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1pY3Jvc29m
  1151. # dCBPcGVyYXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVT
  1152. # Tjo3RDJFLTM3ODItQjBGNzElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAg
  1153. # U2VydmljZaIlCgEBMAkGBSsOAwIaBQADFQA4Bx/wN9XcVHYBftuNY7yzHqGMxaCB
  1154. # 3jCB26SB2DCB1TELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAO
  1155. # BgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEp
  1156. # MCcGA1UECxMgTWljcm9zb2Z0IE9wZXJhdGlvbnMgUHVlcnRvIFJpY28xJzAlBgNV
  1157. # BAsTHm5DaXBoZXIgTlRTIEVTTjo0REU5LTBDNUUtM0UwOTErMCkGA1UEAxMiTWlj
  1158. # cm9zb2Z0IFRpbWUgU291cmNlIE1hc3RlciBDbG9jazANBgkqhkiG9w0BAQUFAAIF
  1159. # AOF5q+IwIhgPMjAxOTExMTUyMjU3MzhaGA8yMDE5MTExNjIyNTczOFowdDA6Bgor
  1160. # BgEEAYRZCgQBMSwwKjAKAgUA4Xmr4gIBADAHAgEAAgIhQDAHAgEAAgIbDTAKAgUA
  1161. # 4Xr9YgIBADA2BgorBgEEAYRZCgQCMSgwJjAMBgorBgEEAYRZCgMBoAowCAIBAAID
  1162. # FuNgoQowCAIBAAIDB6EgMA0GCSqGSIb3DQEBBQUAA4IBAQBrXPxPFldZ3BGA7waF
  1163. # bdOirq8oCBtE81jJO2BENnEFaxjUsbxIvoYB8odfcRNw3RjGH607OK2rY5NyJSs7
  1164. # mx49lP0OSIQaUtm0JuIwBOD45+zpnBEHTjBce/ciO8K6olJ6Hs/iFowkrWoEgnas
  1165. # EfDafVrHqZDKn1l17MF3XkA/Wg8a15rFphDe0H90qcWjfQOK/G4lqFpGydhAqE22
  1166. # aOEkwHunN/sTYeFo0PK19RUQVu/Hm4mA+1zCElRa/gnWaCiT9NgTiS0JugfI16dn
  1167. # E18OSTAIUsOQk4SYH1O5BHLutWbtZvPv8mLcv9xwOpBqkhfYNZkyRE3FGFhyiWbg
  1168. # 3QU1MYIC9TCCAvECAQEwgZMwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hp
  1169. # bmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jw
  1170. # b3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTAC
  1171. # EzMAAAEAIPdck1bVd9AAAAAAAQAwDQYJYIZIAWUDBAIBBQCgggEyMBoGCSqGSIb3
  1172. # DQEJAzENBgsqhkiG9w0BCRABBDAvBgkqhkiG9w0BCQQxIgQgV6mhqFSGtTlYwL+6
  1173. # PsDgVLgoVSnoI8//MHa8YbducJAwgeIGCyqGSIb3DQEJEAIMMYHSMIHPMIHMMIGx
  1174. # BBQ4Bx/wN9XcVHYBftuNY7yzHqGMxTCBmDCBgKR+MHwxCzAJBgNVBAYTAlVTMRMw
  1175. # EQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVN
  1176. # aWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0
  1177. # YW1wIFBDQSAyMDEwAhMzAAABACD3XJNW1XfQAAAAAAEAMBYEFIE7+LoOlImaaqB1
  1178. # i3tr5UrinFzPMA0GCSqGSIb3DQEBCwUABIIBADYOPGsSJ/BDYgITjyla3fi9ynH3
  1179. # oKVMHzzBT71kHErwNzS+D3soFP8ySkM21R78sbWG6VBVcsyQudlKj6PqwbREElpF
  1180. # xQti5m5XmEUzOaG4/MSnu3H1whoUBZWYvD1NQ+nATbqAGPtc0OqkJ+ULQtTs3lEr
  1181. # oCzeEKmHUbzc40JGs00A/nZtJbAj3qUxm7XUy4GepFAB5lEqOsvCRQdTyauTkqip
  1182. # S+nKvpjIv4N4SqViBeFseUKcHuQy4D6N5NKQK+nM5Jvlp2irax81/eCM7+/tCb6N
  1183. # aZa64XKo7HGgzKTD3PGd9w5RGGXLGtjYxKar0mLUlp+WVR9QUTnnP2crlH0=
  1184. # SIG # End signature block