diff --git a/lib/modules/datasource/nuget/__fixtures__/nlog/NLog.4.7.3.nupkg b/lib/modules/datasource/nuget/__fixtures__/nlog/NLog.4.7.3.nupkg new file mode 100644 index 000000000000000..6ec85f1ec046510 Binary files /dev/null and b/lib/modules/datasource/nuget/__fixtures__/nlog/NLog.4.7.3.nupkg differ diff --git a/lib/modules/datasource/nuget/index.spec.ts b/lib/modules/datasource/nuget/index.spec.ts index db7bbaa7b52d61d..b16a07a3df2b73a 100644 --- a/lib/modules/datasource/nuget/index.spec.ts +++ b/lib/modules/datasource/nuget/index.spec.ts @@ -1,8 +1,12 @@ +import { Readable } from 'stream'; import { mockDeep } from 'jest-mock-extended'; +import { join } from 'upath'; import { getPkgReleases } from '..'; import { Fixtures } from '../../../../test/fixtures'; import * as httpMock from '../../../../test/http-mock'; import { logger } from '../../../../test/util'; +import { GlobalConfig } from '../../../config/global'; +import type { RepoGlobalConfig } from '../../../config/types'; import * as _hostRules from '../../../util/host-rules'; import { id as versioning } from '../../versioning/nuget'; import { parseRegistryUrl } from './common'; @@ -302,6 +306,77 @@ describe('modules/datasource/nuget/index', () => { ); }); + it('can determine source URL from nupkg when PackageBaseAddress is missing', async () => { + GlobalConfig.set({ + cacheDir: join('/tmp/cache'), + }); + + const nugetIndex = ` + { + "version": "3.0.0", + "resources": [ + { + "@id": "https://some-registry/v3/metadata", + "@type": "RegistrationsBaseUrl/3.0.0-beta", + "comment": "Get package metadata." + } + ] + } + `; + const nlogRegistration = ` + { + "count": 1, + "items": [ + { + "@id": "https://some-registry/v3/metadata/nlog/4.7.3.json", + "lower": "4.7.3", + "upper": "4.7.3", + "count": 1, + "items": [ + { + "@id": "foo", + "catalogEntry": { + "id": "NLog", + "version": "4.7.3", + "packageContent": "https://some-registry/v3-flatcontainer/nlog/4.7.3/nlog.4.7.3.nupkg" + } + } + ] + } + ] + } + `; + httpMock + .scope('https://some-registry') + .get('/v3/index.json') + .twice() + .reply(200, nugetIndex) + .get('/v3/metadata/nlog/index.json') + .reply(200, nlogRegistration) + .get('/v3-flatcontainer/nlog/4.7.3/nlog.4.7.3.nupkg') + .reply(200, () => { + const readableStream = new Readable(); + readableStream.push(Fixtures.getBinary('nlog/NLog.4.7.3.nupkg')); + readableStream.push(null); + return readableStream; + }); + const res = await getPkgReleases({ + datasource, + versioning, + packageName: 'NLog', + registryUrls: ['https://some-registry/v3/index.json'], + }); + expect(logger.logger.debug).toHaveBeenCalledWith( + { + sourceUrl: 'https://github.com/NLog/NLog.git', + nupkgUrl: + 'https://some-registry/v3-flatcontainer/nlog/4.7.3/nlog.4.7.3.nupkg', + }, + 'Determined sourceUrl from nupkgUrl', + ); + expect(res?.sourceUrl).toBeDefined(); + }); + it('returns null for non 200 (v3v2)', async () => { httpMock.scope('https://api.nuget.org').get('/v3/index.json').reply(500); httpMock diff --git a/lib/modules/datasource/nuget/types.ts b/lib/modules/datasource/nuget/types.ts index 29aba2a5c6b4a5d..2d4d00cb74da4be 100644 --- a/lib/modules/datasource/nuget/types.ts +++ b/lib/modules/datasource/nuget/types.ts @@ -10,6 +10,7 @@ export interface CatalogEntry { published?: string; projectUrl?: string; listed?: boolean; + packageContent?: string; } export interface CatalogPage { diff --git a/lib/modules/datasource/nuget/v3.ts b/lib/modules/datasource/nuget/v3.ts index 6f53906b3afc6a6..12eb9ba28a2fe35 100644 --- a/lib/modules/datasource/nuget/v3.ts +++ b/lib/modules/datasource/nuget/v3.ts @@ -1,9 +1,13 @@ import is from '@sindresorhus/is'; +import extract from 'extract-zip'; import semver from 'semver'; +import upath from 'upath'; import { XmlDocument } from 'xmldoc'; import { logger } from '../../../logger'; import { ExternalHostError } from '../../../types/errors/external-host-error'; import * as packageCache from '../../../util/cache/package'; +import * as fs from '../../../util/fs'; +import { ensureCacheDir } from '../../../util/fs'; import { Http, HttpError } from '../../../util/http'; import * as p from '../../../util/promises'; import { regEx } from '../../../util/regex'; @@ -160,8 +164,15 @@ export async function getReleases( let homepage: string | null = null; let latestStable: string | null = null; + let latestNupkgUrl: string | null = null; const releases = catalogEntries.map( - ({ version, published: releaseTimestamp, projectUrl, listed }) => { + ({ + version, + published: releaseTimestamp, + projectUrl, + listed, + packageContent: nupkgUrl, + }) => { const release: Release = { version: removeBuildMeta(version) }; if (releaseTimestamp) { release.releaseTimestamp = releaseTimestamp; @@ -169,6 +180,7 @@ export async function getReleases( if (versioning.isValid(version) && versioning.isStable(version)) { latestStable = removeBuildMeta(version); homepage = projectUrl ? massageUrl(projectUrl) : homepage; + latestNupkgUrl = nupkgUrl ? massageUrl(nupkgUrl) : null; } if (listed === false) { release.isDeprecated = true; @@ -198,7 +210,6 @@ export async function getReleases( registryUrl, 'PackageBaseAddress', ); - // istanbul ignore else: this is a required v3 api if (is.nonEmptyString(packageBaseAddress)) { const nuspecUrl = `${ensureTrailingSlash( packageBaseAddress, @@ -212,6 +223,20 @@ export async function getReleases( if (sourceUrl) { dep.sourceUrl = massageUrl(sourceUrl); } + } else if (latestNupkgUrl) { + const sourceUrl = await getSourceUrlFromNupkg( + http, + pkgName, + latestStable, + latestNupkgUrl, + ); + if (sourceUrl) { + dep.sourceUrl = massageUrl(sourceUrl); + logger.debug( + { sourceUrl, nupkgUrl: latestNupkgUrl }, + `Determined sourceUrl from nupkgUrl`, + ); + } } } catch (err) { // istanbul ignore if: not easy testable with nock @@ -242,3 +267,31 @@ export async function getReleases( return dep; } + +async function getSourceUrlFromNupkg( + http: Http, + packageName: string, + packageVersion: string | null, + nupkgUrl: string, +): Promise { + const cacheDir = await ensureCacheDir(`nuget`); + const readStream = http.stream(nupkgUrl); + try { + const nupkgFile = upath.join( + cacheDir, + `${packageName}.${packageVersion}.nupkg`, + ); + const writeStream = fs.createCacheWriteStream(nupkgFile); + await fs.pipeline(readStream, writeStream); + const contentsDir = upath.join( + cacheDir, + `${packageName}.${packageVersion}`, + ); + await extract(nupkgFile, { dir: contentsDir }); + const nuspecFile = upath.join(contentsDir, `${packageName}.nuspec`); + const nuspec = new XmlDocument(await fs.readCacheFile(nuspecFile, 'utf8')); + return nuspec.valueWithPath('metadata.repository@url'); + } finally { + await fs.rmCache(cacheDir); + } +} diff --git a/renovate.sln b/renovate.sln new file mode 100644 index 000000000000000..51c2d276960f5f7 --- /dev/null +++ b/renovate.sln @@ -0,0 +1,228 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.5.002.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "lib", "lib", "{0898EFCE-DBD2-4ABA-892E-6A6CA7807AD2}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "modules", "modules", "{BFB865AC-82AC-4B51-BF78-3617748DA748}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "manager", "manager", "{40F9730D-F712-4046-B68E-F7571E422907}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "nuget", "nuget", "{E562B314-D8F1-4BD4-A541-34A6DC9082D4}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "sample", "lib\modules\manager\nuget\__fixtures__\sample.csproj", "{DB5A0A63-4F25-4CB6-ABBA-74659BEF1D83}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__fixtures__", "__fixtures__", "{7BCF43AB-6B02-46EE-B3BA-3F29003F18C8}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "one", "lib\modules\manager\nuget\__fixtures__\two-no-reference\one.csproj", "{60E24E69-A195-40EC-9A91-5C8BD6E634EA}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "two", "lib\modules\manager\nuget\__fixtures__\two-no-reference\two.csproj", "{E7ADA3DE-40C8-4950-A16B-79E772FA5CB8}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "with-pascal-case-config-file", "lib\modules\manager\nuget\__fixtures__\with-pascal-case-config-file\with-pascal-case-config-file.csproj", "{9371A47E-6A7C-4AEB-9981-0E6293E27DAB}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "with-local-feed-in-config-file", "lib\modules\manager\nuget\__fixtures__\with-local-feed-in-config-file\with-local-feed-in-config-file.csproj", "{30A239EE-3DA7-4EFE-8A64-EFA6C0652DA4}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "with-lower-case-config-file", "lib\modules\manager\nuget\__fixtures__\with-lower-case-config-file\with-lower-case-config-file.csproj", "{C8A38004-127E-4801-85E6-70CE3872C083}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "single", "lib\modules\manager\nuget\__fixtures__\single-project-file\single.csproj", "{DF664B6B-9C90-4E36-B85C-2270E8269355}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "with-malformed-config-file", "lib\modules\manager\nuget\__fixtures__\with-malformed-config-file\with-malformed-config-file.csproj", "{4F327593-4BCF-4A4D-9861-6508E8E74DE9}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "with-whitespaces", "lib\modules\manager\nuget\__fixtures__\with-whitespaces\with-whitespaces.csproj", "{80FA9DD3-1717-4C7E-AB66-DC1DBD31DBF1}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "without-package-sources", "lib\modules\manager\nuget\__fixtures__\without-package-sources\without-package-sources.csproj", "{CE342FE4-4574-4671-BE5F-E33E4454F8EF}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "with-config-file", "lib\modules\manager\nuget\__fixtures__\with-config-file\with-config-file.csproj", "{F6E21C34-8871-4626-889D-C72E2B2D8E66}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "two-one-reference-with-central-versions", "two-one-reference-with-central-versions", "{6C2D0B64-8792-41A0-BF50-7E6981D42C0E}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "one", "lib\modules\manager\nuget\__fixtures__\two-one-reference-with-central-versions\one\one.csproj", "{C10CC309-53D2-4D0E-8446-37621BF055B3}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "two", "lib\modules\manager\nuget\__fixtures__\two-one-reference-with-central-versions\two\two.csproj", "{C1D11CE3-6FAE-4218-BACF-F8461D806510}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "two-one-reference", "two-one-reference", "{F5BCEF2B-6E6C-4463-9AB7-E4BF37376C8C}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "one", "lib\modules\manager\nuget\__fixtures__\two-one-reference\one\one.csproj", "{FB239377-2F5F-4091-8F1F-ADAF64D09B90}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "two", "lib\modules\manager\nuget\__fixtures__\two-one-reference\two\two.csproj", "{CFE75707-E998-4A5B-9E82-E96C7893F803}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "three-two-linear-references", "three-two-linear-references", "{DD9C0CB9-54A5-42D7-BFBB-0B3B8812B540}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "three", "lib\modules\manager\nuget\__fixtures__\three-two-linear-references\three\three.csproj", "{7F50286D-6ABD-4C54-A3DB-D55A2ADF980C}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "one", "lib\modules\manager\nuget\__fixtures__\three-two-linear-references\one\one.csproj", "{3ECD09B9-9896-41FB-800C-1FFDA947CFE4}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "two", "lib\modules\manager\nuget\__fixtures__\three-two-linear-references\two\two.csproj", "{20C25CCD-12D1-46FC-B0AF-DFAB1966243D}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "multiple-package-files", "multiple-package-files", "{2942975F-1759-48BB-8B3E-8F800314B68E}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "one", "lib\modules\manager\nuget\__fixtures__\multiple-package-files\one\one.csproj", "{EAC7D44A-DF2A-4D98-A607-C99D69881C32}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "two", "lib\modules\manager\nuget\__fixtures__\multiple-package-files\two\two.csproj", "{6287A312-72B6-432D-BDFF-761F670EEC33}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "three-two-treelike-references", "three-two-treelike-references", "{89F6EA61-2009-4270-97C7-2BFF5B5915C0}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "three", "lib\modules\manager\nuget\__fixtures__\three-two-treelike-references\three\three.csproj", "{1598EA74-9128-4870-95CF-DFCA5F52141B}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "one", "lib\modules\manager\nuget\__fixtures__\three-two-treelike-references\one\one.csproj", "{4F1FB479-538E-4C8C-8654-F5817EF56479}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "two", "lib\modules\manager\nuget\__fixtures__\three-two-treelike-references\two\two.csproj", "{1D9C0137-B2D3-4495-B961-83EC443388C2}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "circular-reference", "circular-reference", "{F5CE873C-8AE0-40BE-9180-90404F51C8D8}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "one", "lib\modules\manager\nuget\__fixtures__\circular-reference\one\one.csproj", "{88A5201E-F5B3-486E-B45E-E28BC705F438}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "two", "lib\modules\manager\nuget\__fixtures__\circular-reference\two\two.csproj", "{D5CA1B44-A328-485B-9E3E-8402808DBA11}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {DB5A0A63-4F25-4CB6-ABBA-74659BEF1D83}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DB5A0A63-4F25-4CB6-ABBA-74659BEF1D83}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DB5A0A63-4F25-4CB6-ABBA-74659BEF1D83}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DB5A0A63-4F25-4CB6-ABBA-74659BEF1D83}.Release|Any CPU.Build.0 = Release|Any CPU + {60E24E69-A195-40EC-9A91-5C8BD6E634EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {60E24E69-A195-40EC-9A91-5C8BD6E634EA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {60E24E69-A195-40EC-9A91-5C8BD6E634EA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {60E24E69-A195-40EC-9A91-5C8BD6E634EA}.Release|Any CPU.Build.0 = Release|Any CPU + {E7ADA3DE-40C8-4950-A16B-79E772FA5CB8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E7ADA3DE-40C8-4950-A16B-79E772FA5CB8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E7ADA3DE-40C8-4950-A16B-79E772FA5CB8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E7ADA3DE-40C8-4950-A16B-79E772FA5CB8}.Release|Any CPU.Build.0 = Release|Any CPU + {9371A47E-6A7C-4AEB-9981-0E6293E27DAB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9371A47E-6A7C-4AEB-9981-0E6293E27DAB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9371A47E-6A7C-4AEB-9981-0E6293E27DAB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9371A47E-6A7C-4AEB-9981-0E6293E27DAB}.Release|Any CPU.Build.0 = Release|Any CPU + {30A239EE-3DA7-4EFE-8A64-EFA6C0652DA4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {30A239EE-3DA7-4EFE-8A64-EFA6C0652DA4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {30A239EE-3DA7-4EFE-8A64-EFA6C0652DA4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {30A239EE-3DA7-4EFE-8A64-EFA6C0652DA4}.Release|Any CPU.Build.0 = Release|Any CPU + {C8A38004-127E-4801-85E6-70CE3872C083}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C8A38004-127E-4801-85E6-70CE3872C083}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C8A38004-127E-4801-85E6-70CE3872C083}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C8A38004-127E-4801-85E6-70CE3872C083}.Release|Any CPU.Build.0 = Release|Any CPU + {DF664B6B-9C90-4E36-B85C-2270E8269355}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DF664B6B-9C90-4E36-B85C-2270E8269355}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DF664B6B-9C90-4E36-B85C-2270E8269355}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DF664B6B-9C90-4E36-B85C-2270E8269355}.Release|Any CPU.Build.0 = Release|Any CPU + {4F327593-4BCF-4A4D-9861-6508E8E74DE9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4F327593-4BCF-4A4D-9861-6508E8E74DE9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4F327593-4BCF-4A4D-9861-6508E8E74DE9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4F327593-4BCF-4A4D-9861-6508E8E74DE9}.Release|Any CPU.Build.0 = Release|Any CPU + {80FA9DD3-1717-4C7E-AB66-DC1DBD31DBF1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {80FA9DD3-1717-4C7E-AB66-DC1DBD31DBF1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {80FA9DD3-1717-4C7E-AB66-DC1DBD31DBF1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {80FA9DD3-1717-4C7E-AB66-DC1DBD31DBF1}.Release|Any CPU.Build.0 = Release|Any CPU + {CE342FE4-4574-4671-BE5F-E33E4454F8EF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CE342FE4-4574-4671-BE5F-E33E4454F8EF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CE342FE4-4574-4671-BE5F-E33E4454F8EF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CE342FE4-4574-4671-BE5F-E33E4454F8EF}.Release|Any CPU.Build.0 = Release|Any CPU + {F6E21C34-8871-4626-889D-C72E2B2D8E66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F6E21C34-8871-4626-889D-C72E2B2D8E66}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F6E21C34-8871-4626-889D-C72E2B2D8E66}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F6E21C34-8871-4626-889D-C72E2B2D8E66}.Release|Any CPU.Build.0 = Release|Any CPU + {C10CC309-53D2-4D0E-8446-37621BF055B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C10CC309-53D2-4D0E-8446-37621BF055B3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C10CC309-53D2-4D0E-8446-37621BF055B3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C10CC309-53D2-4D0E-8446-37621BF055B3}.Release|Any CPU.Build.0 = Release|Any CPU + {C1D11CE3-6FAE-4218-BACF-F8461D806510}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C1D11CE3-6FAE-4218-BACF-F8461D806510}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C1D11CE3-6FAE-4218-BACF-F8461D806510}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C1D11CE3-6FAE-4218-BACF-F8461D806510}.Release|Any CPU.Build.0 = Release|Any CPU + {FB239377-2F5F-4091-8F1F-ADAF64D09B90}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FB239377-2F5F-4091-8F1F-ADAF64D09B90}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FB239377-2F5F-4091-8F1F-ADAF64D09B90}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FB239377-2F5F-4091-8F1F-ADAF64D09B90}.Release|Any CPU.Build.0 = Release|Any CPU + {CFE75707-E998-4A5B-9E82-E96C7893F803}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CFE75707-E998-4A5B-9E82-E96C7893F803}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CFE75707-E998-4A5B-9E82-E96C7893F803}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CFE75707-E998-4A5B-9E82-E96C7893F803}.Release|Any CPU.Build.0 = Release|Any CPU + {7F50286D-6ABD-4C54-A3DB-D55A2ADF980C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7F50286D-6ABD-4C54-A3DB-D55A2ADF980C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7F50286D-6ABD-4C54-A3DB-D55A2ADF980C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7F50286D-6ABD-4C54-A3DB-D55A2ADF980C}.Release|Any CPU.Build.0 = Release|Any CPU + {3ECD09B9-9896-41FB-800C-1FFDA947CFE4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3ECD09B9-9896-41FB-800C-1FFDA947CFE4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3ECD09B9-9896-41FB-800C-1FFDA947CFE4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3ECD09B9-9896-41FB-800C-1FFDA947CFE4}.Release|Any CPU.Build.0 = Release|Any CPU + {20C25CCD-12D1-46FC-B0AF-DFAB1966243D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {20C25CCD-12D1-46FC-B0AF-DFAB1966243D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {20C25CCD-12D1-46FC-B0AF-DFAB1966243D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {20C25CCD-12D1-46FC-B0AF-DFAB1966243D}.Release|Any CPU.Build.0 = Release|Any CPU + {EAC7D44A-DF2A-4D98-A607-C99D69881C32}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EAC7D44A-DF2A-4D98-A607-C99D69881C32}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EAC7D44A-DF2A-4D98-A607-C99D69881C32}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EAC7D44A-DF2A-4D98-A607-C99D69881C32}.Release|Any CPU.Build.0 = Release|Any CPU + {6287A312-72B6-432D-BDFF-761F670EEC33}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6287A312-72B6-432D-BDFF-761F670EEC33}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6287A312-72B6-432D-BDFF-761F670EEC33}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6287A312-72B6-432D-BDFF-761F670EEC33}.Release|Any CPU.Build.0 = Release|Any CPU + {1598EA74-9128-4870-95CF-DFCA5F52141B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1598EA74-9128-4870-95CF-DFCA5F52141B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1598EA74-9128-4870-95CF-DFCA5F52141B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1598EA74-9128-4870-95CF-DFCA5F52141B}.Release|Any CPU.Build.0 = Release|Any CPU + {4F1FB479-538E-4C8C-8654-F5817EF56479}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4F1FB479-538E-4C8C-8654-F5817EF56479}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4F1FB479-538E-4C8C-8654-F5817EF56479}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4F1FB479-538E-4C8C-8654-F5817EF56479}.Release|Any CPU.Build.0 = Release|Any CPU + {1D9C0137-B2D3-4495-B961-83EC443388C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1D9C0137-B2D3-4495-B961-83EC443388C2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1D9C0137-B2D3-4495-B961-83EC443388C2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1D9C0137-B2D3-4495-B961-83EC443388C2}.Release|Any CPU.Build.0 = Release|Any CPU + {88A5201E-F5B3-486E-B45E-E28BC705F438}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {88A5201E-F5B3-486E-B45E-E28BC705F438}.Debug|Any CPU.Build.0 = Debug|Any CPU + {88A5201E-F5B3-486E-B45E-E28BC705F438}.Release|Any CPU.ActiveCfg = Release|Any CPU + {88A5201E-F5B3-486E-B45E-E28BC705F438}.Release|Any CPU.Build.0 = Release|Any CPU + {D5CA1B44-A328-485B-9E3E-8402808DBA11}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D5CA1B44-A328-485B-9E3E-8402808DBA11}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D5CA1B44-A328-485B-9E3E-8402808DBA11}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D5CA1B44-A328-485B-9E3E-8402808DBA11}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {BFB865AC-82AC-4B51-BF78-3617748DA748} = {0898EFCE-DBD2-4ABA-892E-6A6CA7807AD2} + {40F9730D-F712-4046-B68E-F7571E422907} = {BFB865AC-82AC-4B51-BF78-3617748DA748} + {E562B314-D8F1-4BD4-A541-34A6DC9082D4} = {40F9730D-F712-4046-B68E-F7571E422907} + {DB5A0A63-4F25-4CB6-ABBA-74659BEF1D83} = {E562B314-D8F1-4BD4-A541-34A6DC9082D4} + {7BCF43AB-6B02-46EE-B3BA-3F29003F18C8} = {E562B314-D8F1-4BD4-A541-34A6DC9082D4} + {60E24E69-A195-40EC-9A91-5C8BD6E634EA} = {7BCF43AB-6B02-46EE-B3BA-3F29003F18C8} + {E7ADA3DE-40C8-4950-A16B-79E772FA5CB8} = {7BCF43AB-6B02-46EE-B3BA-3F29003F18C8} + {9371A47E-6A7C-4AEB-9981-0E6293E27DAB} = {7BCF43AB-6B02-46EE-B3BA-3F29003F18C8} + {30A239EE-3DA7-4EFE-8A64-EFA6C0652DA4} = {7BCF43AB-6B02-46EE-B3BA-3F29003F18C8} + {C8A38004-127E-4801-85E6-70CE3872C083} = {7BCF43AB-6B02-46EE-B3BA-3F29003F18C8} + {DF664B6B-9C90-4E36-B85C-2270E8269355} = {7BCF43AB-6B02-46EE-B3BA-3F29003F18C8} + {4F327593-4BCF-4A4D-9861-6508E8E74DE9} = {7BCF43AB-6B02-46EE-B3BA-3F29003F18C8} + {80FA9DD3-1717-4C7E-AB66-DC1DBD31DBF1} = {7BCF43AB-6B02-46EE-B3BA-3F29003F18C8} + {CE342FE4-4574-4671-BE5F-E33E4454F8EF} = {7BCF43AB-6B02-46EE-B3BA-3F29003F18C8} + {F6E21C34-8871-4626-889D-C72E2B2D8E66} = {7BCF43AB-6B02-46EE-B3BA-3F29003F18C8} + {6C2D0B64-8792-41A0-BF50-7E6981D42C0E} = {7BCF43AB-6B02-46EE-B3BA-3F29003F18C8} + {C10CC309-53D2-4D0E-8446-37621BF055B3} = {6C2D0B64-8792-41A0-BF50-7E6981D42C0E} + {C1D11CE3-6FAE-4218-BACF-F8461D806510} = {6C2D0B64-8792-41A0-BF50-7E6981D42C0E} + {F5BCEF2B-6E6C-4463-9AB7-E4BF37376C8C} = {7BCF43AB-6B02-46EE-B3BA-3F29003F18C8} + {FB239377-2F5F-4091-8F1F-ADAF64D09B90} = {F5BCEF2B-6E6C-4463-9AB7-E4BF37376C8C} + {CFE75707-E998-4A5B-9E82-E96C7893F803} = {F5BCEF2B-6E6C-4463-9AB7-E4BF37376C8C} + {DD9C0CB9-54A5-42D7-BFBB-0B3B8812B540} = {7BCF43AB-6B02-46EE-B3BA-3F29003F18C8} + {7F50286D-6ABD-4C54-A3DB-D55A2ADF980C} = {DD9C0CB9-54A5-42D7-BFBB-0B3B8812B540} + {3ECD09B9-9896-41FB-800C-1FFDA947CFE4} = {DD9C0CB9-54A5-42D7-BFBB-0B3B8812B540} + {20C25CCD-12D1-46FC-B0AF-DFAB1966243D} = {DD9C0CB9-54A5-42D7-BFBB-0B3B8812B540} + {2942975F-1759-48BB-8B3E-8F800314B68E} = {7BCF43AB-6B02-46EE-B3BA-3F29003F18C8} + {EAC7D44A-DF2A-4D98-A607-C99D69881C32} = {2942975F-1759-48BB-8B3E-8F800314B68E} + {6287A312-72B6-432D-BDFF-761F670EEC33} = {2942975F-1759-48BB-8B3E-8F800314B68E} + {89F6EA61-2009-4270-97C7-2BFF5B5915C0} = {7BCF43AB-6B02-46EE-B3BA-3F29003F18C8} + {1598EA74-9128-4870-95CF-DFCA5F52141B} = {89F6EA61-2009-4270-97C7-2BFF5B5915C0} + {4F1FB479-538E-4C8C-8654-F5817EF56479} = {89F6EA61-2009-4270-97C7-2BFF5B5915C0} + {1D9C0137-B2D3-4495-B961-83EC443388C2} = {89F6EA61-2009-4270-97C7-2BFF5B5915C0} + {F5CE873C-8AE0-40BE-9180-90404F51C8D8} = {7BCF43AB-6B02-46EE-B3BA-3F29003F18C8} + {88A5201E-F5B3-486E-B45E-E28BC705F438} = {F5CE873C-8AE0-40BE-9180-90404F51C8D8} + {D5CA1B44-A328-485B-9E3E-8402808DBA11} = {F5CE873C-8AE0-40BE-9180-90404F51C8D8} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {7C6A9AE8-77B4-46B2-9A51-11F5807BAFE7} + EndGlobalSection +EndGlobal