@flxbl-io/sfp
Version:
sfp is a CLI tool to help you manage your Salesforce projects in an artifact centric model
212 lines • 16.9 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const path = require("path");
const fs = __importStar(require("fs-extra"));
const sfp_logger_1 = __importStar(require("@flxbl-io/sfp-logger"));
const glob_1 = require("glob");
const AdmZip = require("adm-zip");
const semver = require("semver");
const tar = require("tar");
class ArtifactFetcher {
/**
* Decider for which artifact retrieval method to use
* Returns empty array if no artifacts are found
* @param artifactDirectory
* @param sfdx_package
*/
static fetchArtifacts(artifactDirectory, sfdx_package, logger) {
let result = [];
if (!fs.existsSync(artifactDirectory)) {
throw new Error(`Artifact directory ${path.resolve(artifactDirectory)} does not exist`);
}
let artifacts = this.findArtifacts(artifactDirectory, sfdx_package);
sfp_logger_1.default.log(`Artifacts: ${JSON.stringify(artifacts)}`, sfp_logger_1.LoggerLevel.TRACE, logger);
for (let artifact of artifacts) {
let artifactFilePaths;
if (path.extname(artifact) === '.zip') {
artifactFilePaths = ArtifactFetcher.fetchArtifactFilePathsFromZipFile(artifact);
}
else if (path.extname(artifact) === '.tgz') {
artifactFilePaths = ArtifactFetcher.fetchArtifactFilePathsFromTarball(artifact);
}
else {
throw new Error(`Unhandled artifact format ${artifact}, neither tar or zip file`);
}
result.push(artifactFilePaths);
}
return result;
}
/**
* Helper method for retrieving the ArtifactFilePaths of an artifact folder
* @param packageMetadataFilePath
*/
static fetchArtifactFilePathsFromFolder(packageMetadataFilePath) {
let sourceDirectory = path.join(path.dirname(packageMetadataFilePath), `source`);
let changelogFilePath = path.join(path.dirname(packageMetadataFilePath), `changelog.json`);
let artifactFilePaths = {
packageMetadataFilePath: packageMetadataFilePath,
sourceDirectoryPath: sourceDirectory,
changelogFilePath: changelogFilePath,
};
ArtifactFetcher.existsArtifactFilepaths(artifactFilePaths);
return artifactFilePaths;
}
/**
* Helper method for retrieving ArtifactFilePaths of an artifact zip
* @param artifact
*/
static fetchArtifactFilePathsFromZipFile(artifact) {
let unzippedArtifactsDirectory = `.sfpowerscripts/unzippedArtifacts/${this.makefolderid(8)}`;
fs.mkdirpSync(unzippedArtifactsDirectory);
let zip = new AdmZip(artifact);
// Overwrite existing files
zip.extractAllTo(unzippedArtifactsDirectory, true);
let artifactName = path.basename(artifact).match(/.*sfpowerscripts_artifact/)?.[0];
if (artifactName == null) {
throw new Error(`Failed to fetch artifact file paths for ${artifact}`);
}
let packageMetadataFilePath = path.join(unzippedArtifactsDirectory, artifactName, 'artifact_metadata.json');
let sourceDirectory = path.join(unzippedArtifactsDirectory, artifactName, `source`);
let changelogFilePath = path.join(unzippedArtifactsDirectory, artifactName, `changelog.json`);
let artifactFilePaths = {
packageMetadataFilePath: packageMetadataFilePath,
sourceDirectoryPath: sourceDirectory,
changelogFilePath: changelogFilePath,
};
ArtifactFetcher.existsArtifactFilepaths(artifactFilePaths);
return artifactFilePaths;
}
/**
* Helper method for retrieving ArtifactFilePaths of a tarball
* @param artifact
*/
static fetchArtifactFilePathsFromTarball(artifact) {
let unzippedArtifactsDirectory = `.sfpowerscripts/unzippedArtifacts/${this.makefolderid(8)}`;
fs.mkdirpSync(unzippedArtifactsDirectory);
tar.x({
file: artifact,
cwd: unzippedArtifactsDirectory,
sync: true,
});
let packageMetadataFilePath = path.join(unzippedArtifactsDirectory, 'package', 'artifact_metadata.json');
let sourceDirectory = path.join(unzippedArtifactsDirectory, 'package', `source`);
let changelogFilePath = path.join(unzippedArtifactsDirectory, 'package', `changelog.json`);
let artifactFilePaths = {
packageMetadataFilePath: packageMetadataFilePath,
sourceDirectoryPath: sourceDirectory,
changelogFilePath: changelogFilePath,
};
ArtifactFetcher.existsArtifactFilepaths(artifactFilePaths);
return artifactFilePaths;
}
/**
* Find zip and tarball artifacts
* Artifact format/s:
* sfpowerscripts_artifact_<version>.zip,
* [sfdx_package]_sfpowerscripts_artifact_[version].zip,
* [sfdx_package]_sfpowerscripts_artifact_[version].tgz
*/
static findArtifacts(artifactDirectory, sfdx_package) {
let pattern;
if (sfdx_package) {
pattern = `**/*${sfdx_package}_sfpowerscripts_artifact*.@(zip|tgz)`;
}
else {
pattern = `**/*sfpowerscripts_artifact*.@(zip|tgz)`;
}
let artifacts = (0, glob_1.globSync)(pattern, {
cwd: artifactDirectory,
absolute: true,
});
if (sfdx_package && artifacts.length > 1) {
sfp_logger_1.default.log(`Found more than one artifact for ${sfdx_package}`, sfp_logger_1.LoggerLevel.INFO);
let latestArtifact = ArtifactFetcher.getLatestArtifact(artifacts);
sfp_logger_1.default.log(`Using latest artifact ${latestArtifact}`, sfp_logger_1.LoggerLevel.INFO);
return [latestArtifact];
}
else
return artifacts;
}
/**
* Get the artifact with the latest semantic version
* @param artifacts
*/
static getLatestArtifact(artifacts) {
// Consider zip & tarball artifacts only
artifacts = artifacts.filter((artifact) => {
let ext = path.extname(artifact);
return ext === '.zip' || ext === '.tgz';
});
let pattern = new RegExp('(?:^.*)(?:_sfpowerscripts_artifact[_-])(?<version>.*)(?:\\.zip|\\.tgz)$');
let versions = artifacts.map((artifact) => {
let match = path.basename(artifact).match(pattern);
let version = match?.groups.version;
if (version)
return version;
else
throw new Error('Corrupted artifact detected with no version number');
});
// Pick artifact with latest semantic version
let sortedVersions = semver.sort(versions);
let latestVersion = sortedVersions.pop();
return artifacts.find((artifact) => artifact.includes(latestVersion));
}
/**
* Verify that artifact filepaths exist on the file system
* @param artifactFilePaths
*/
static existsArtifactFilepaths(artifactFilePaths) {
Object.values(artifactFilePaths).forEach((filepath) => {
if (!fs.existsSync(filepath))
throw new Error(`Artifact filepath ${filepath} does not exist`);
});
}
/**
* Decider for task outcome if the artifact cannot be found
* @param artifacts_filepaths
* @param isToSkipOnMissingArtifact
*/
static missingArtifactDecider(artifacts, isToSkipOnMissingArtifact) {
if (artifacts.length === 0 && !isToSkipOnMissingArtifact) {
throw new Error(`Artifact not found, Please check the inputs`);
}
else if (artifacts.length === 0 && isToSkipOnMissingArtifact) {
sfp_logger_1.default.log(`Skipping task as artifact is missing, and 'Skip If no artifact is found' ${isToSkipOnMissingArtifact}`);
return true;
}
}
static makefolderid(length) {
let result = '';
let characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
let charactersLength = characters.length;
for (let i = 0; i < length; i++) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
}
return result;
}
}
exports.default = ArtifactFetcher;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQXJ0aWZhY3RGZXRjaGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NvcmUvYXJ0aWZhY3RzL0FydGlmYWN0RmV0Y2hlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsNkJBQThCO0FBQzlCLDZDQUErQjtBQUMvQixtRUFBc0U7QUFDdEUsK0JBQWdDO0FBQ2hDLGtDQUFtQztBQUNuQyxpQ0FBa0M7QUFDbEMsMkJBQTRCO0FBRTVCLE1BQXFCLGVBQWU7SUFDaEM7Ozs7O09BS0c7SUFDSSxNQUFNLENBQUMsY0FBYyxDQUFDLGlCQUF5QixFQUFFLFlBQXFCLEVBQUUsTUFBZTtRQUMxRixJQUFJLE1BQU0sR0FBZSxFQUFFLENBQUM7UUFFNUIsSUFBSSxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsaUJBQWlCLENBQUMsRUFBRSxDQUFDO1lBQ3BDLE1BQU0sSUFBSSxLQUFLLENBQUMsc0JBQXNCLElBQUksQ0FBQyxPQUFPLENBQUMsaUJBQWlCLENBQUMsaUJBQWlCLENBQUMsQ0FBQztRQUM1RixDQUFDO1FBRUQsSUFBSSxTQUFTLEdBQWEsSUFBSSxDQUFDLGFBQWEsQ0FBQyxpQkFBaUIsRUFBRSxZQUFZLENBQUMsQ0FBQztRQUU5RSxvQkFBUyxDQUFDLEdBQUcsQ0FBQyxjQUFjLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLEVBQUUsRUFBRSx3QkFBVyxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsQ0FBQztRQUVwRixLQUFLLElBQUksUUFBUSxJQUFJLFNBQVMsRUFBRSxDQUFDO1lBQzdCLElBQUksaUJBQTJCLENBQUM7WUFDaEMsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxLQUFLLE1BQU0sRUFBRSxDQUFDO2dCQUNwQyxpQkFBaUIsR0FBRyxlQUFlLENBQUMsaUNBQWlDLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDcEYsQ0FBQztpQkFBTSxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLEtBQUssTUFBTSxFQUFFLENBQUM7Z0JBQzNDLGlCQUFpQixHQUFHLGVBQWUsQ0FBQyxpQ0FBaUMsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUNwRixDQUFDO2lCQUFNLENBQUM7Z0JBQ0osTUFBTSxJQUFJLEtBQUssQ0FBQyw2QkFBNkIsUUFBUSwyQkFBMkIsQ0FBQyxDQUFDO1lBQ3RGLENBQUM7WUFDRCxNQUFNLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUM7UUFDbkMsQ0FBQztRQUVELE9BQU8sTUFBTSxDQUFDO0lBQ2xCLENBQUM7SUFFRDs7O09BR0c7SUFDSyxNQUFNLENBQUMsZ0NBQWdDLENBQUMsdUJBQStCO1FBQzNFLElBQUksZUFBZSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyx1QkFBdUIsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBRWpGLElBQUksaUJBQWlCLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLHVCQUF1QixDQUFDLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQztRQUUzRixJQUFJLGlCQUFpQixHQUFhO1lBQzlCLHVCQUF1QixFQUFFLHVCQUF1QjtZQUNoRCxtQkFBbUIsRUFBRSxlQUFlO1lBQ3BDLGlCQUFpQixFQUFFLGlCQUFpQjtTQUN2QyxDQUFDO1FBRUYsZUFBZSxDQUFDLHVCQUF1QixDQUFDLGlCQUFpQixDQUFDLENBQUM7UUFFM0QsT0FBTyxpQkFBaUIsQ0FBQztJQUM3QixDQUFDO0lBRUQ7OztPQUdHO0lBQ0ssTUFBTSxDQUFDLGlDQUFpQyxDQUFDLFFBQWdCO1FBQzdELElBQUksMEJBQTBCLEdBQVcscUNBQXFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUVyRyxFQUFFLENBQUMsVUFBVSxDQUFDLDBCQUEwQixDQUFDLENBQUM7UUFDMUMsSUFBSSxHQUFHLEdBQUcsSUFBSSxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7UUFFL0IsMkJBQTJCO1FBQzNCLEdBQUcsQ0FBQyxZQUFZLENBQUMsMEJBQTBCLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFFbkQsSUFBSSxZQUFZLEdBQVcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQyxLQUFLLENBQUMsMkJBQTJCLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzNGLElBQUksWUFBWSxJQUFJLElBQUksRUFBRSxDQUFDO1lBQ3ZCLE1BQU0sSUFBSSxLQUFLLENBQUMsMkNBQTJDLFFBQVEsRUFBRSxDQUFDLENBQUM7UUFDM0UsQ0FBQztRQUVELElBQUksdUJBQXVCLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQywwQkFBMEIsRUFBRSxZQUFZLEVBQUUsd0JBQXdCLENBQUMsQ0FBQztRQUU1RyxJQUFJLGVBQWUsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLDBCQUEwQixFQUFFLFlBQVksRUFBRSxRQUFRLENBQUMsQ0FBQztRQUVwRixJQUFJLGlCQUFpQixHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsMEJBQTBCLEVBQUUsWUFBWSxFQUFFLGdCQUFnQixDQUFDLENBQUM7UUFFOUYsSUFBSSxpQkFBaUIsR0FBYTtZQUM5Qix1QkFBdUIsRUFBRSx1QkFBdUI7WUFDaEQsbUJBQW1CLEVBQUUsZUFBZTtZQUNwQyxpQkFBaUIsRUFBRSxpQkFBaUI7U0FDdkMsQ0FBQztRQUVGLGVBQWUsQ0FBQyx1QkFBdUIsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1FBRTNELE9BQU8saUJBQWlCLENBQUM7SUFDN0IsQ0FBQztJQUVEOzs7T0FHRztJQUNLLE1BQU0sQ0FBQyxpQ0FBaUMsQ0FBQyxRQUFnQjtRQUM3RCxJQUFJLDBCQUEwQixHQUFXLHFDQUFxQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDckcsRUFBRSxDQUFDLFVBQVUsQ0FBQywwQkFBMEIsQ0FBQyxDQUFDO1FBRTFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFDRixJQUFJLEVBQUUsUUFBUTtZQUNkLEdBQUcsRUFBRSwwQkFBMEI7WUFDL0IsSUFBSSxFQUFFLElBQUk7U0FDYixDQUFDLENBQUM7UUFFSCxJQUFJLHVCQUF1QixHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsMEJBQTBCLEVBQUUsU0FBUyxFQUFFLHdCQUF3QixDQUFDLENBQUM7UUFFekcsSUFBSSxlQUFlLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQywwQkFBMEIsRUFBRSxTQUFTLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFFakYsSUFBSSxpQkFBaUIsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLDBCQUEwQixFQUFFLFNBQVMsRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDO1FBRTNGLElBQUksaUJBQWlCLEdBQWE7WUFDOUIsdUJBQXVCLEVBQUUsdUJBQXVCO1lBQ2hELG1CQUFtQixFQUFFLGVBQWU7WUFDcEMsaUJBQWlCLEVBQUUsaUJBQWlCO1NBQ3ZDLENBQUM7UUFFRixlQUFlLENBQUMsdUJBQXVCLENBQUMsaUJBQWlCLENBQUMsQ0FBQztRQUUzRCxPQUFPLGlCQUFpQixDQUFDO0lBQzdCLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSSxNQUFNLENBQUMsYUFBYSxDQUFDLGlCQUF5QixFQUFFLFlBQXFCO1FBQ3hFLElBQUksT0FBZSxDQUFDO1FBQ3BCLElBQUksWUFBWSxFQUFFLENBQUM7WUFDZixPQUFPLEdBQUcsT0FBTyxZQUFZLHNDQUFzQyxDQUFDO1FBQ3hFLENBQUM7YUFBTSxDQUFDO1lBQ0osT0FBTyxHQUFHLHlDQUF5QyxDQUFDO1FBQ3hELENBQUM7UUFFRCxJQUFJLFNBQVMsR0FBYSxJQUFBLGVBQVEsRUFBQyxPQUFPLEVBQUU7WUFDeEMsR0FBRyxFQUFFLGlCQUFpQjtZQUN0QixRQUFRLEVBQUUsSUFBSTtTQUNqQixDQUFDLENBQUM7UUFFSCxJQUFJLFlBQVksSUFBSSxTQUFTLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ3ZDLG9CQUFTLENBQUMsR0FBRyxDQUFDLG9DQUFvQyxZQUFZLEVBQUUsRUFBRSx3QkFBVyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ3BGLElBQUksY0FBYyxHQUFXLGVBQWUsQ0FBQyxpQkFBaUIsQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUMxRSxvQkFBUyxDQUFDLEdBQUcsQ0FBQyx5QkFBeUIsY0FBYyxFQUFFLEVBQUUsd0JBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUMzRSxPQUFPLENBQUMsY0FBYyxDQUFDLENBQUM7UUFDNUIsQ0FBQzs7WUFBTSxPQUFPLFNBQVMsQ0FBQztJQUM1QixDQUFDO0lBRUQ7OztPQUdHO0lBQ0ssTUFBTSxDQUFDLGlCQUFpQixDQUFDLFNBQW1CO1FBQ2hELHdDQUF3QztRQUN4QyxTQUFTLEdBQUcsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDLFFBQVEsRUFBRSxFQUFFO1lBQ3RDLElBQUksR0FBRyxHQUFXLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDekMsT0FBTyxHQUFHLEtBQUssTUFBTSxJQUFJLEdBQUcsS0FBSyxNQUFNLENBQUM7UUFDNUMsQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLE9BQU8sR0FBRyxJQUFJLE1BQU0sQ0FBQyx5RUFBeUUsQ0FBQyxDQUFDO1FBQ3BHLElBQUksUUFBUSxHQUFhLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxRQUFRLEVBQUUsRUFBRTtZQUNoRCxJQUFJLEtBQUssR0FBcUIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDckUsSUFBSSxPQUFPLEdBQUcsS0FBSyxFQUFFLE1BQU0sQ0FBQyxPQUFPLENBQUM7WUFFcEMsSUFBSSxPQUFPO2dCQUFFLE9BQU8sT0FBTyxDQUFDOztnQkFDdkIsTUFBTSxJQUFJLEtBQUssQ0FBQyxvREFBb0QsQ0FBQyxDQUFDO1FBQy9FLENBQUMsQ0FBQyxDQUFDO1FBRUgsNkNBQTZDO1FBQzdDLElBQUksY0FBYyxHQUFhLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDckQsSUFBSSxhQUFhLEdBQVcsY0FBYyxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBRWpELE9BQU8sU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDO0lBQzFFLENBQUM7SUFFRDs7O09BR0c7SUFDSyxNQUFNLENBQUMsdUJBQXVCLENBQUMsaUJBQTJCO1FBQzlELE1BQU0sQ0FBQyxNQUFNLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxRQUFRLEVBQUUsRUFBRTtZQUNsRCxJQUFJLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUM7Z0JBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyxxQkFBcUIsUUFBUSxpQkFBaUIsQ0FBQyxDQUFDO1FBQ2xHLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUVEOzs7O09BSUc7SUFDSSxNQUFNLENBQUMsc0JBQXNCLENBQUMsU0FBcUIsRUFBRSx5QkFBa0M7UUFDMUYsSUFBSSxTQUFTLENBQUMsTUFBTSxLQUFLLENBQUMsSUFBSSxDQUFDLHlCQUF5QixFQUFFLENBQUM7WUFDdkQsTUFBTSxJQUFJLEtBQUssQ0FBQyw2Q0FBNkMsQ0FBQyxDQUFDO1FBQ25FLENBQUM7YUFBTSxJQUFJLFNBQVMsQ0FBQyxNQUFNLEtBQUssQ0FBQyxJQUFJLHlCQUF5QixFQUFFLENBQUM7WUFDN0Qsb0JBQVMsQ0FBQyxHQUFHLENBQ1QsNEVBQTRFLHlCQUF5QixFQUFFLENBQzFHLENBQUM7WUFDRixPQUFPLElBQUksQ0FBQztRQUNoQixDQUFDO0lBQ0wsQ0FBQztJQUVPLE1BQU0sQ0FBQyxZQUFZLENBQUMsTUFBTTtRQUM5QixJQUFJLE1BQU0sR0FBRyxFQUFFLENBQUM7UUFDaEIsSUFBSSxVQUFVLEdBQUcsZ0VBQWdFLENBQUM7UUFDbEYsSUFBSSxnQkFBZ0IsR0FBRyxVQUFVLENBQUMsTUFBTSxDQUFDO1FBQ3pDLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUM5QixNQUFNLElBQUksVUFBVSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsR0FBRyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUM7UUFDOUUsQ0FBQztRQUNELE9BQU8sTUFBTSxDQUFDO0lBQ2xCLENBQUM7Q0FDSjtBQWpORCxrQ0FpTkMifQ==