@microsoft/windows-admin-center-sdk
Version:
Microsoft - Windows Admin Center Shell
611 lines (608 loc) • 33.1 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.EslintUpgrader = exports.EslintUpgraderMessages = exports.UpgradeType = void 0;
const tslib_1 = require("tslib");
const fs_extra_1 = tslib_1.__importStar(require("fs-extra"));
const common_1 = require("../common");
const child_process_1 = require("child_process");
/**
* Represents the type of upgrade that needs to be performed.
*/
var UpgradeType;
(function (UpgradeType) {
UpgradeType["WithBaseConfig"] = "WithBaseConfig";
UpgradeType["WithoutBaseConfig"] = "WithoutBaseConfig";
UpgradeType["NoOperation"] = "NoOperation";
})(UpgradeType = exports.UpgradeType || (exports.UpgradeType = {}));
/**
* Represents the messages that are displayed during the upgrade process.
*/
var EslintUpgraderMessages;
(function (EslintUpgraderMessages) {
EslintUpgraderMessages["StartingUpgrade"] = "Starting upgrade eslinting process...";
EslintUpgraderMessages["CheckingFilePaths"] = "Checking file paths...";
EslintUpgraderMessages["UpdateTypeWithBaseConfig"] = "UpdateType: WithBaseConfig";
EslintUpgraderMessages["UpdateTypeWithoutBaseConfig"] = "UpdateType: WithoutBaseConfig";
EslintUpgraderMessages["UpdateTypeWithoutBoth"] = "UpdateType: NoOperation";
EslintUpgraderMessages["ExitWithoutBaseConfig"] = "Exiting upgrade eslinting process...";
EslintUpgraderMessages["RCANoTsConfigFile"] = "Please manually create a tsconfig.json file in the root of your project.";
EslintUpgraderMessages["GettingTsConfigFile"] = "Getting tsconfig.json file...";
EslintUpgraderMessages["UpdateTsConfigContent"] = "Updating tsconfig.json content...";
EslintUpgraderMessages["RevertTsConfigContent"] = "Reverting tsconfig.json content...";
EslintUpgraderMessages["RenameTsBaseConfig"] = "Renaming tsconfig.base.json to tsconfig.base.json_backup...";
EslintUpgraderMessages["RevertTsBaseConfig"] = "Renaming tsconfig.base.json_backup to tsconfig.base.json...";
EslintUpgraderMessages["UpdateEslintConfig"] = "Updating .eslintrc.json content...";
EslintUpgraderMessages["UpdatePolyfills"] = "Updating polyfills.ts content...";
EslintUpgraderMessages["UpdateKarmaFile"] = "Updating karma.conf.js content...";
EslintUpgraderMessages["FinalizeInfoLintFix"] = "There are eslint violations that needs fix... After fixing the violations, please run the following commands:\n\n npx eslint . --fix \n\n gulp lintApp \n\n gulp build \n\n ";
EslintUpgraderMessages["Completed"] = "Upgrade completed!";
})(EslintUpgraderMessages = exports.EslintUpgraderMessages || (exports.EslintUpgraderMessages = {}));
/**
* This is the main class of the EslintUpgrader tool.
* It is responsible for upgrading the Tslint to Eslint.
*/
class EslintUpgrader {
tsconfigBaseFilePath;
tsconfigFilePath;
angularFilePath;
debug = false;
libUpgrade = false;
tsconfigBaseFileName = 'tsconfig.base.json';
tsconfigFileName = 'tsconfig.json';
tsconfigBaseFileNameBackUp = 'tsconfig.base.json_backup';
angularFileName = 'angular.json';
eslintConfigFileName = '.eslintrc.json';
eslintConfigFileContent = {
"extends": "./node_modules/@microsoft/windows-admin-center-sdk/tools/code-formatter/.eslintrc.base.json"
};
polifillsFilePath = './src/polyfills.ts';
karmaConfigFilePath = './src/karma.conf.js';
eslintDisable = 'eslint-disable';
targetGulpLintFilePath = '.\\gulpfile.ts\\common\\lint.ts';
targetGulpLintIndexFilePath = './gulpfile.ts/index.ts';
targetGulpLintUiTestAutomationFilePath = '.\\gulpfile.ts\\common\\ui-test-automation.ts';
/**
* The main upgrade process
* @param debug - Indicates if the debug mode is enabled.
* @returns Promise<void> - Returns a promise that resolves when the upgrade process is completed.
*/
async upgrade(debug = false) {
this.debug = !!debug;
this.logger(EslintUpgraderMessages.StartingUpgrade);
this.logger(EslintUpgraderMessages.CheckingFilePaths);
const upgradeType = this.checkFileExists();
this.checkLibUpgrade();
switch (upgradeType) {
case UpgradeType.WithBaseConfig:
this.logger(EslintUpgraderMessages.UpdateTypeWithBaseConfig);
this.updateTsConfigContent();
this.renameTsBaseConfig();
await this.addEslintSchematics();
await this.esLintSchematicsRunModuleApp();
if (this.libUpgrade) {
await this.esLintSchematicsRunModuleLib();
}
await this.uninstallDependencies();
await this.installDependencies();
await this.replaceEslintConfig();
this.updateTsConfigContent(true);
this.renameTsBaseConfig(true);
await this.replaceGulpLintFile();
this.cleanUpPolyfills();
this.cleanUpKarmaConfigFile();
await this.fixEslintErrors();
await this.gulpBuild();
break;
case UpgradeType.WithoutBaseConfig:
this.logger(EslintUpgraderMessages.UpdateTypeWithoutBaseConfig);
await this.addEslintSchematics();
await this.esLintSchematicsRunModuleApp();
if (this.libUpgrade) {
await this.esLintSchematicsRunModuleLib();
}
await this.uninstallDependencies();
await this.installDependencies();
await this.replaceEslintConfig();
await this.replaceGulpLintFile();
this.cleanUpPolyfills();
this.cleanUpKarmaConfigFile();
await this.fixEslintErrors();
await this.gulpBuild();
break;
case UpgradeType.NoOperation:
this.logger(EslintUpgraderMessages.UpdateTypeWithoutBoth);
this.logger(EslintUpgraderMessages.ExitWithoutBaseConfig);
this.logger(EslintUpgraderMessages.RCANoTsConfigFile);
break;
default:
break;
}
this.logger(EslintUpgraderMessages.Completed);
}
constructor() {
common_1.Common.rootPath = process.cwd();
this.updateBasicPaths();
}
updateBasicPaths() {
this.tsconfigBaseFilePath = common_1.Common.rootPath + '\\' + this.tsconfigBaseFileName;
this.tsconfigFilePath = common_1.Common.rootPath + '\\' + this.tsconfigFileName;
this.angularFilePath = common_1.Common.rootPath + '\\' + this.angularFileName;
}
checkLibUpgrade() {
const angularFilePathExists = (0, fs_extra_1.pathExists)(this.angularFilePath);
if (!angularFilePathExists) {
return;
}
const angularFileContent = common_1.Common.readFileData(this.angularFilePath);
this.libUpgrade = !!angularFileContent.includes('module-lib');
}
checkFileExists() {
const tsconfigBaseFilePathExists = (0, fs_extra_1.pathExists)(this.tsconfigBaseFilePath);
const tsconfigFilePathExists = (0, fs_extra_1.pathExists)(this.tsconfigFilePath);
if (tsconfigBaseFilePathExists && tsconfigFilePathExists) {
return UpgradeType.WithBaseConfig;
}
else if (tsconfigFilePathExists) {
return UpgradeType.WithoutBaseConfig;
}
else {
return UpgradeType.NoOperation;
}
}
updateTsConfigContent(revert = false) {
revert ? this.logger(EslintUpgraderMessages.RevertTsConfigContent) : this.logger(EslintUpgraderMessages.UpdateTsConfigContent);
revert ?
this.updateFile(this.tsconfigFilePath, `// "extends": "./${this.tsconfigBaseFileName}"`, `"extends": "./${this.tsconfigBaseFileName}"`) :
this.updateFile(this.tsconfigFilePath, `"extends": "./${this.tsconfigBaseFileName}"`, `// "extends": "./${this.tsconfigBaseFileName}"`);
}
updateFile(filePath, prev, target) {
this.logger('Updating file...' + filePath + ',' + prev + ',' + target + '...');
let fileData = common_1.Common.readFileData(filePath);
fileData = fileData.replace(prev, target);
fs_extra_1.default.writeFileSync(filePath, fileData);
}
renameTsBaseConfig(revert = false) {
revert ? this.logger(EslintUpgraderMessages.RenameTsBaseConfig) : this.logger(EslintUpgraderMessages.RevertTsBaseConfig);
const cmd = revert ? `git mv ./${this.tsconfigBaseFileNameBackUp} ./${this.tsconfigBaseFileName}` : `git mv ./${this.tsconfigBaseFileName} ./${this.tsconfigBaseFileNameBackUp}`;
this.runCommand(cmd);
}
async addEslintSchematics() {
const cmd = 'ng add @angular-eslint/schematics --skip-confirmation';
this.logger(cmd);
await this.runCommand(cmd);
}
async esLintSchematicsRunModuleApp() {
const cmd = 'ng g @angular-eslint/schematics:convert-tslint-to-eslint module-app';
this.logger(cmd);
await this.runCommand(cmd);
}
async esLintSchematicsRunModuleLib() {
const cmd = 'ng g @angular-eslint/schematics:convert-tslint-to-eslint module-lib';
this.logger(cmd);
await this.runCommand(cmd);
}
/**
* It updates to the eslintrc.json file on the root of the project.
*/
async replaceEslintConfig() {
const formattedNewContent = JSON.stringify(this.eslintConfigFileContent, null, 2)
.replace('}', '}\n');
this.logger(EslintUpgraderMessages.UpdateEslintConfig);
if (fs_extra_1.default.existsSync(`./${this.eslintConfigFileName}`)) {
this.logger('Updating eslint file');
common_1.Common.writeFileData(`./${this.eslintConfigFileName}`, formattedNewContent);
}
else {
this.logger('Creating new eslint file');
common_1.Common.writeFile(`./${this.eslintConfigFileName}`, formattedNewContent);
}
// race condition for the eslintrc file not being released by the writeFile function.
await this.sleep(1000);
}
async uninstallDependencies() {
const cmd = 'npm uninstall codelyzer gulp-tslint rxjs-tslint rxjs-tslint-rules tslint tslint-consistent-codestyle tslint-eslint-rules tslint-microsoft-contrib';
this.logger(cmd);
await this.runCommand(cmd);
const removeForRollBackCmd = 'npm uninstall gulp-eslint eslint eslint-plugin-angular eslint-plugin-import eslint-plugin-jsdoc eslint-plugin-jsonc eslint-plugin-prefer-arrow ' +
'@typescript-eslint/eslint-plugin @typescript-eslint/parser @angular-eslint/builder @angular-eslint/eslint-plugin @angular-eslint/eslint-plugin-template @angular-eslint/schematics ' +
'@angular-eslint/template-parser';
this.logger(removeForRollBackCmd);
await this.runCommand(removeForRollBackCmd);
}
async installDependencies() {
const cmd = 'npm install gulp-eslint@6.0.0 eslint@7.6.0 eslint-plugin-angular@4.1.0 eslint-plugin-import@2.21.0 eslint-plugin-jsdoc@36.1.1 eslint-plugin-jsonc@2.8.0 eslint-plugin-prefer-arrow@1.2.3 ' +
'@typescript-eslint/eslint-plugin@4.16.1 @typescript-eslint/parser@4.16.1 @angular-eslint/builder@4.3.1 @angular-eslint/eslint-plugin@4.3.1 @angular-eslint/eslint-plugin-template@4.3.1 ' +
'@angular-eslint/schematics@4.3.1 @angular-eslint/template-parser@4.3.1 --save-dev';
this.logger(cmd);
await this.runCommand(cmd);
}
async fixEslintErrors() {
const rootFileLinterFix = 'npx eslint . --fix';
this.logger(rootFileLinterFix);
await this.runCommand(rootFileLinterFix, true, EslintUpgraderMessages.FinalizeInfoLintFix);
const projectLinterFix = 'npx ng lint --fix';
this.logger(projectLinterFix);
await this.runCommand(projectLinterFix, true, EslintUpgraderMessages.FinalizeInfoLintFix);
}
async replaceGulpLintFile() {
const cmd = `del ${this.targetGulpLintFilePath}`;
this.logger(cmd);
await this.runCommand(cmd);
if ((0, fs_extra_1.pathExists)(this.targetGulpLintIndexFilePath)) {
this.updateFile(this.targetGulpLintIndexFilePath, `import { LintModule } from './common/lint'`, `import { LintModule } from '../node_modules/@microsoft/windows-admin-center-sdk/tools/code-formatter/lint'`);
}
if ((0, fs_extra_1.pathExists)(this.targetGulpLintUiTestAutomationFilePath)) {
this.updateFile(this.targetGulpLintUiTestAutomationFilePath, `import { LintModule } from './lint'`, `import { LintModule } from '../../node_modules/@microsoft/windows-admin-center-sdk/tools/code-formatter/lint'`);
// The new UI automation framework will remove this line.
// This is for the repositories that has not yet onboraded to the new frawework.
this.updateFile(this.targetGulpLintUiTestAutomationFilePath, `export const uiTestAutomation = series(LintModule.lintUiTestAutomation, buildUiTestAutomation);`, `export const uiTestAutomation = series(LintModule.lintUiTestAutomation_legacy, buildUiTestAutomation);`);
}
}
async gulpBuild() {
const cmd = 'gulp build';
this.logger(cmd);
await this.runCommand(cmd);
}
cleanUpPolyfills() {
this.logger(EslintUpgraderMessages.UpdatePolyfills);
const fileDataInLines = common_1.Common.readFileData(this.polifillsFilePath).split('\n');
const newLines = fileDataInLines.filter(line => !line.includes(this.eslintDisable));
common_1.Common.writeFileData(this.polifillsFilePath, newLines.join('\n'));
}
cleanUpKarmaConfigFile() {
this.logger(EslintUpgraderMessages.UpdateKarmaFile);
this.updateFile(this.karmaConfigFilePath, `module.exports = (config) => {`, `module.exports = function (config) {`);
}
runCommand(cmd, forceDebug = false, finalizeInfo = undefined) {
console.log(`Running ${cmd}`);
return new Promise((resolve) => {
const child = (0, child_process_1.exec)(cmd, (error, stdout, stderr) => {
if (error) {
console.error(` exec error: ${error}`);
return;
}
stdout.split('\n').filter(line => line.trimEnd()).forEach(line => console.log(line));
stderr.split('\n').filter(line => line.trimEnd()).forEach(line => console.error(line));
resolve();
});
if (this.debug || forceDebug) {
child.stdout.on('data', (data) => {
data.split('\n').filter(line => line.trimEnd()).forEach(line => console.log(` ${line}`));
});
}
child.stderr.on('data', (data) => {
data.split('\n').filter(line => line.trimEnd()).forEach(line => console.error(` ${line}`));
});
child.on('close', (code) => {
console.log(`exitCode: ${code}`);
if (code !== 0 && finalizeInfo) {
this.logger(finalizeInfo);
this.logger(EslintUpgraderMessages.Completed);
}
});
});
}
logger(value, prefix = 'Main thread') {
console.log(`${prefix} - ${value}`);
}
sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
}
exports.EslintUpgrader = EslintUpgrader;
//# sourceMappingURL=main.js.map
// SIG // Begin signature block
// SIG // MIIoOgYJKoZIhvcNAQcCoIIoKzCCKCcCAQExDzANBglg
// SIG // hkgBZQMEAgEFADB3BgorBgEEAYI3AgEEoGkwZzAyBgor
// SIG // BgEEAYI3AgEeMCQCAQEEEBDgyQbOONQRoqMAEEvTUJAC
// SIG // AQACAQACAQACAQACAQAwMTANBglghkgBZQMEAgEFAAQg
// SIG // a5MrkxutZpQYjp2mUq977IJbUWgGjFId5S8LgIl8bNGg
// SIG // gg2FMIIGAzCCA+ugAwIBAgITMwAABAO91ZVdDzsYrQAA
// SIG // AAAEAzANBgkqhkiG9w0BAQsFADB+MQswCQYDVQQGEwJV
// SIG // UzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH
// SIG // UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBv
// SIG // cmF0aW9uMSgwJgYDVQQDEx9NaWNyb3NvZnQgQ29kZSBT
// SIG // aWduaW5nIFBDQSAyMDExMB4XDTI0MDkxMjIwMTExM1oX
// SIG // DTI1MDkxMTIwMTExM1owdDELMAkGA1UEBhMCVVMxEzAR
// SIG // BgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1v
// SIG // bmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv
// SIG // bjEeMBwGA1UEAxMVTWljcm9zb2Z0IENvcnBvcmF0aW9u
// SIG // MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
// SIG // n3RnXcCDp20WFMoNNzt4s9fV12T5roRJlv+bshDfvJoM
// SIG // ZfhyRnixgUfGAbrRlS1St/EcXFXD2MhRkF3CnMYIoeMO
// SIG // MuMyYtxr2sC2B5bDRMUMM/r9I4GP2nowUthCWKFIS1RP
// SIG // lM0YoVfKKMaH7bJii29sW+waBUulAKN2c+Gn5znaiOxR
// SIG // qIu4OL8f9DCHYpME5+Teek3SL95sH5GQhZq7CqTdM0fB
// SIG // w/FmLLx98SpBu7v8XapoTz6jJpyNozhcP/59mi/Fu4tT
// SIG // 2rI2vD50Vx/0GlR9DNZ2py/iyPU7DG/3p1n1zluuRp3u
// SIG // XKjDfVKH7xDbXcMBJid22a3CPbuC2QJLowIDAQABo4IB
// SIG // gjCCAX4wHwYDVR0lBBgwFgYKKwYBBAGCN0wIAQYIKwYB
// SIG // BQUHAwMwHQYDVR0OBBYEFOpuKgJKc+OuNYitoqxfHlrE
// SIG // gXAZMFQGA1UdEQRNMEukSTBHMS0wKwYDVQQLEyRNaWNy
// SIG // b3NvZnQgSXJlbGFuZCBPcGVyYXRpb25zIExpbWl0ZWQx
// SIG // FjAUBgNVBAUTDTIzMDAxMis1MDI5MjYwHwYDVR0jBBgw
// SIG // FoAUSG5k5VAF04KqFzc3IrVtqMp1ApUwVAYDVR0fBE0w
// SIG // SzBJoEegRYZDaHR0cDovL3d3dy5taWNyb3NvZnQuY29t
// SIG // L3BraW9wcy9jcmwvTWljQ29kU2lnUENBMjAxMV8yMDEx
// SIG // LTA3LTA4LmNybDBhBggrBgEFBQcBAQRVMFMwUQYIKwYB
// SIG // BQUHMAKGRWh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9w
// SIG // a2lvcHMvY2VydHMvTWljQ29kU2lnUENBMjAxMV8yMDEx
// SIG // LTA3LTA4LmNydDAMBgNVHRMBAf8EAjAAMA0GCSqGSIb3
// SIG // DQEBCwUAA4ICAQBRaP+hOC1+dSKhbqCr1LIvNEMrRiOQ
// SIG // EkPc7D6QWtM+/IbrYiXesNeeCZHCMf3+6xASuDYQ+AyB
// SIG // TX0YlXSOxGnBLOzgEukBxezbfnhUTTk7YB2/TxMUcuBC
// SIG // P45zMM0CVTaJE8btloB6/3wbFrOhvQHCILx41jTd6kUq
// SIG // 4bIBHah3NG0Q1H/FCCwHRGTjAbyiwq5n/pCTxLz5XYCu
// SIG // 4RTvy/ZJnFXuuwZynowyju90muegCToTOwpHgE6yRcTv
// SIG // Ri16LKCr68Ab8p8QINfFvqWoEwJCXn853rlkpp4k7qzw
// SIG // lBNiZ71uw2pbzjQzrRtNbCFQAfmoTtsHFD2tmZvQIg1Q
// SIG // VkzM/V1KCjHL54ItqKm7Ay4WyvqWK0VIEaTbdMtbMWbF
// SIG // zq2hkRfJTNnFr7RJFeVC/k0DNaab+bpwx5FvCUvkJ3z2
// SIG // wfHWVUckZjEOGmP7cecefrF+rHpif/xW4nJUjMUiPsyD
// SIG // btY2Hq3VMLgovj+qe0pkJgpYQzPukPm7RNhbabFNFvq+
// SIG // kXWBX/z/pyuo9qLZfTb697Vi7vll5s/DBjPtfMpyfpWG
// SIG // 0phVnAI+0mM4gH09LCMJUERZMgu9bbCGVIQR7cT5YhlL
// SIG // t+tpSDtC6XtAzq4PJbKZxFjpB5wk+SRJ1gm87olbfEV9
// SIG // SFdO7iL3jWbjgVi1Qs1iYxBmvh4WhLWr48uouzCCB3ow
// SIG // ggVioAMCAQICCmEOkNIAAAAAAAMwDQYJKoZIhvcNAQEL
// SIG // BQAwgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNo
// SIG // aW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQK
// SIG // ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xMjAwBgNVBAMT
// SIG // KU1pY3Jvc29mdCBSb290IENlcnRpZmljYXRlIEF1dGhv
// SIG // cml0eSAyMDExMB4XDTExMDcwODIwNTkwOVoXDTI2MDcw
// SIG // ODIxMDkwOVowfjELMAkGA1UEBhMCVVMxEzARBgNVBAgT
// SIG // Cldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAc
// SIG // BgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEoMCYG
// SIG // A1UEAxMfTWljcm9zb2Z0IENvZGUgU2lnbmluZyBQQ0Eg
// SIG // MjAxMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC
// SIG // ggIBAKvw+nIQHC6t2G6qghBNNLrytlghn0IbKmvpWlCq
// SIG // uAY4GgRJun/DDB7dN2vGEtgL8DjCmQawyDnVARQxQtOJ
// SIG // DXlkh36UYCRsr55JnOloXtLfm1OyCizDr9mpK656Ca/X
// SIG // llnKYBoF6WZ26DJSJhIv56sIUM+zRLdd2MQuA3WraPPL
// SIG // bfM6XKEW9Ea64DhkrG5kNXimoGMPLdNAk/jj3gcN1Vx5
// SIG // pUkp5w2+oBN3vpQ97/vjK1oQH01WKKJ6cuASOrdJXtjt
// SIG // 7UORg9l7snuGG9k+sYxd6IlPhBryoS9Z5JA7La4zWMW3
// SIG // Pv4y07MDPbGyr5I4ftKdgCz1TlaRITUlwzluZH9TupwP
// SIG // rRkjhMv0ugOGjfdf8NBSv4yUh7zAIXQlXxgotswnKDgl
// SIG // mDlKNs98sZKuHCOnqWbsYR9q4ShJnV+I4iVd0yFLPlLE
// SIG // tVc/JAPw0XpbL9Uj43BdD1FGd7P4AOG8rAKCX9vAFbO9
// SIG // G9RVS+c5oQ/pI0m8GLhEfEXkwcNyeuBy5yTfv0aZxe/C
// SIG // HFfbg43sTUkwp6uO3+xbn6/83bBm4sGXgXvt1u1L50kp
// SIG // pxMopqd9Z4DmimJ4X7IvhNdXnFy/dygo8e1twyiPLI9A
// SIG // N0/B4YVEicQJTMXUpUMvdJX3bvh4IFgsE11glZo+TzOE
// SIG // 2rCIF96eTvSWsLxGoGyY0uDWiIwLAgMBAAGjggHtMIIB
// SIG // 6TAQBgkrBgEEAYI3FQEEAwIBADAdBgNVHQ4EFgQUSG5k
// SIG // 5VAF04KqFzc3IrVtqMp1ApUwGQYJKwYBBAGCNxQCBAwe
// SIG // CgBTAHUAYgBDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB
// SIG // /wQFMAMBAf8wHwYDVR0jBBgwFoAUci06AjGQQ7kUBU7h
// SIG // 6qfHMdEjiTQwWgYDVR0fBFMwUTBPoE2gS4ZJaHR0cDov
// SIG // L2NybC5taWNyb3NvZnQuY29tL3BraS9jcmwvcHJvZHVj
// SIG // dHMvTWljUm9vQ2VyQXV0MjAxMV8yMDExXzAzXzIyLmNy
// SIG // bDBeBggrBgEFBQcBAQRSMFAwTgYIKwYBBQUHMAKGQmh0
// SIG // dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2kvY2VydHMv
// SIG // TWljUm9vQ2VyQXV0MjAxMV8yMDExXzAzXzIyLmNydDCB
// SIG // nwYDVR0gBIGXMIGUMIGRBgkrBgEEAYI3LgMwgYMwPwYI
// SIG // KwYBBQUHAgEWM2h0dHA6Ly93d3cubWljcm9zb2Z0LmNv
// SIG // bS9wa2lvcHMvZG9jcy9wcmltYXJ5Y3BzLmh0bTBABggr
// SIG // BgEFBQcCAjA0HjIgHQBMAGUAZwBhAGwAXwBwAG8AbABp
// SIG // AGMAeQBfAHMAdABhAHQAZQBtAGUAbgB0AC4gHTANBgkq
// SIG // hkiG9w0BAQsFAAOCAgEAZ/KGpZjgVHkaLtPYdGcimwuW
// SIG // EeFjkplCln3SeQyQwWVfLiw++MNy0W2D/r4/6ArKO79H
// SIG // qaPzadtjvyI1pZddZYSQfYtGUFXYDJJ80hpLHPM8QotS
// SIG // 0LD9a+M+By4pm+Y9G6XUtR13lDni6WTJRD14eiPzE32m
// SIG // kHSDjfTLJgJGKsKKELukqQUMm+1o+mgulaAqPyprWElj
// SIG // HwlpblqYluSD9MCP80Yr3vw70L01724lruWvJ+3Q3fMO
// SIG // r5kol5hNDj0L8giJ1h/DMhji8MUtzluetEk5CsYKwsat
// SIG // ruWy2dsViFFFWDgycScaf7H0J/jeLDogaZiyWYlobm+n
// SIG // t3TDQAUGpgEqKD6CPxNNZgvAs0314Y9/HG8VfUWnduVA
// SIG // KmWjw11SYobDHWM2l4bf2vP48hahmifhzaWX0O5dY0Hj
// SIG // Wwechz4GdwbRBrF1HxS+YWG18NzGGwS+30HHDiju3mUv
// SIG // 7Jf2oVyW2ADWoUa9WfOXpQlLSBCZgB/QACnFsZulP0V3
// SIG // HjXG0qKin3p6IvpIlR+r+0cjgPWe+L9rt0uX4ut1eBrs
// SIG // 6jeZeRhL/9azI2h15q/6/IvrC4DqaTuv/DDtBEyO3991
// SIG // bWORPdGdVk5Pv4BXIqF4ETIheu9BCrE/+6jMpF3BoYib
// SIG // V3FWTkhFwELJm3ZbCoBIa/15n8G9bW1qyVJzEw16UM0x
// SIG // ghoNMIIaCQIBATCBlTB+MQswCQYDVQQGEwJVUzETMBEG
// SIG // A1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u
// SIG // ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9u
// SIG // MSgwJgYDVQQDEx9NaWNyb3NvZnQgQ29kZSBTaWduaW5n
// SIG // IFBDQSAyMDExAhMzAAAEA73VlV0POxitAAAAAAQDMA0G
// SIG // CWCGSAFlAwQCAQUAoIGuMBkGCSqGSIb3DQEJAzEMBgor
// SIG // BgEEAYI3AgEEMBwGCisGAQQBgjcCAQsxDjAMBgorBgEE
// SIG // AYI3AgEVMC8GCSqGSIb3DQEJBDEiBCA9Vy+4sYg1wzuY
// SIG // FDpdrdfJSvwb9kSRDk6Jzurm/xIF7jBCBgorBgEEAYI3
// SIG // AgEMMTQwMqAUgBIATQBpAGMAcgBvAHMAbwBmAHShGoAY
// SIG // aHR0cDovL3d3dy5taWNyb3NvZnQuY29tMA0GCSqGSIb3
// SIG // DQEBAQUABIIBADOslwwzKIFsUqDAZy4cDyenDId/hcUe
// SIG // hluSUDzComt2dXh3yFk8+1keqeFB9K/fGFiN4x+4sa7m
// SIG // aW0Fdk1QGQuHHSo5MZk7KeL354py+Lpex+YajN6FZs/D
// SIG // a79btUQPXMcKQ/FNBWdcBDRrNWpvR4dv7/bz8O++FZbO
// SIG // Om440Gdjv/M3YW7FkjkHz79aisUNXFGVAoC6P9AKVc/N
// SIG // FV7IpPDhwJ6to8YvwPnPTiUVPviTOZsLAPCis6WMOplq
// SIG // VC6LbLajn2isXMTTrsFL2CzzdrC/NNnPsvoDSIZG3Kl2
// SIG // VXWqRI89c8Y4Alrx/BJ4+ExV6TlALzPrkaJ1wiLwjWCY
// SIG // buehgheXMIIXkwYKKwYBBAGCNwMDATGCF4Mwghd/Bgkq
// SIG // hkiG9w0BBwKgghdwMIIXbAIBAzEPMA0GCWCGSAFlAwQC
// SIG // AQUAMIIBUgYLKoZIhvcNAQkQAQSgggFBBIIBPTCCATkC
// SIG // AQEGCisGAQQBhFkKAwEwMTANBglghkgBZQMEAgEFAAQg
// SIG // psgwh0qqidrSo4YcB1B0sRd9Y4dsf49TSnXNxylkjOgC
// SIG // Bmet/FZ02RgTMjAyNTAyMjAxNTI4NDEuODk5WjAEgAIB
// SIG // 9KCB0aSBzjCByzELMAkGA1UEBhMCVVMxEzARBgNVBAgT
// SIG // Cldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAc
// SIG // BgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjElMCMG
// SIG // A1UECxMcTWljcm9zb2Z0IEFtZXJpY2EgT3BlcmF0aW9u
// SIG // czEnMCUGA1UECxMeblNoaWVsZCBUU1MgRVNOOjg2MDMt
// SIG // MDVFMC1EOTQ3MSUwIwYDVQQDExxNaWNyb3NvZnQgVGlt
// SIG // ZS1TdGFtcCBTZXJ2aWNloIIR7TCCByAwggUIoAMCAQIC
// SIG // EzMAAAHxs0X1J+jAFtYAAQAAAfEwDQYJKoZIhvcNAQEL
// SIG // BQAwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hp
// SIG // bmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoT
// SIG // FU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMd
// SIG // TWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTAwHhcN
// SIG // MjMxMjA2MTg0NTU1WhcNMjUwMzA1MTg0NTU1WjCByzEL
// SIG // MAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x
// SIG // EDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jv
// SIG // c29mdCBDb3Jwb3JhdGlvbjElMCMGA1UECxMcTWljcm9z
// SIG // b2Z0IEFtZXJpY2EgT3BlcmF0aW9uczEnMCUGA1UECxMe
// SIG // blNoaWVsZCBUU1MgRVNOOjg2MDMtMDVFMC1EOTQ3MSUw
// SIG // IwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2
// SIG // aWNlMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKC
// SIG // AgEAsbpQmbbSH/F/e61vfyfkOFYPT4roAdcmtfw0ccS1
// SIG // tocMuEILVN4+X1e+WSmul000IVuQpZBpeoKdZ3eVQbMe
// SIG // CW/qFOD7DANn6HvID/W0DT1cSBzCbuk2HK659/R3XXrd
// SIG // sZHalIc88kl2jxahTJNlYnxH4/h0eiYXjbNiy85vBQyZ
// SIG // vqQXXTwy2oP0fgDyFh8n7avYrcDNFj+WdHX0MiOFpVXl
// SIG // Evr6LbD21pvkSrB+BUDYc29Lfw+IrrXHwit/yyvsS5ku
// SIG // nZgIewDCrhFJfItpHVgQ0XHPiVmttUgnn8eUj4SRBYGI
// SIG // XRjwKKdxtZfE993Kq2y7XBSasMOE0ImIgpHcrAnJyBdG
// SIG // akjQB3HyPUgL94H5MsakDSSd7E7IORj0RfeZqoG30G5B
// SIG // Z1Ne4mG0SDyasIEi4cgfN92Q4Js8WypiZnQ2m280tMho
// SIG // Z4B2uvoMFWjlKnB3/cOpMMTKPjqht0GSHMHecBxArOaw
// SIG // CWejyMhTOwHdoUVBR0U4t+dyO1eMRIGBrmW+qhcej3+O
// SIG // IuwI126bVKJQ3Fc2BHYC0ElorhWo0ul4N5OwsvE4jORz
// SIG // 1CvS2SJ5aE8blC0sSZie5041Izo+ccEZgu8dkv5sapfJ
// SIG // 7x0gjdThA9v8BAjqLejBHvWy9586CsDvEzZREraubHHd
// SIG // uRgNIDEDvqjV1f8UwzgUyfMwXBkCAwEAAaOCAUkwggFF
// SIG // MB0GA1UdDgQWBBS8tsXufbAhNEo8nKhORK2+GK0tYDAf
// SIG // BgNVHSMEGDAWgBSfpxVdAF5iXYP05dJlpxtTNRnpcjBf
// SIG // BgNVHR8EWDBWMFSgUqBQhk5odHRwOi8vd3d3Lm1pY3Jv
// SIG // c29mdC5jb20vcGtpb3BzL2NybC9NaWNyb3NvZnQlMjBU
// SIG // aW1lLVN0YW1wJTIwUENBJTIwMjAxMCgxKS5jcmwwbAYI
// SIG // KwYBBQUHAQEEYDBeMFwGCCsGAQUFBzAChlBodHRwOi8v
// SIG // d3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01p
// SIG // Y3Jvc29mdCUyMFRpbWUtU3RhbXAlMjBQQ0ElMjAyMDEw
// SIG // KDEpLmNydDAMBgNVHRMBAf8EAjAAMBYGA1UdJQEB/wQM
// SIG // MAoGCCsGAQUFBwMIMA4GA1UdDwEB/wQEAwIHgDANBgkq
// SIG // hkiG9w0BAQsFAAOCAgEA4UhI0gRUgmycpd1P0JhTFtni
// SIG // zwZJ55bHyA/+4EzLwDRJ4atPCPRx226osKgxB0rwEbyr
// SIG // S+49M5yAmAWzK1Upr4A8VPIwBqjMoi6DPNO/PEqN/k+i
// SIG // GVf/1GUSagZeKDN2wiEIBRqNFU3kOkc2C/rdcwlF5pqT
// SIG // 5jOMXEnFRQE14+U8ewcuEoVlAu1YZu6YnA4lOYoBo7or
// SIG // 0YcT726X5W4f27IhObceXLjiRCUhvrlnKgcke0wuHBr7
// SIG // mrx0o5NYkV0/0I2jhHiaDp33rGznbyayXW5vpXmC0SOu
// SIG // zd3HfAf7LlNtbUXYMDp05NoTrmSrP5C8Gl+jbAG1MvaS
// SIG // rA5k8qFpxpsk1gT4k29q6eaIKPGPITFNWELO6x0eYaop
// SIG // RKvPIxfvR/CnHG/9YrJiUxpwZ0TL+vFHdpeSxYTmeJ0b
// SIG // ZeJR64vjdS/BAYO2hPBLz3vAmvYM/LIdheAjk2HdTx3H
// SIG // tboC771ltfmjkqXfDZ8BIneM4A+/WUMYrCasjuJTFjMw
// SIG // IBHhYVJuNBbIbc17nQLF+S6AopeKy2x38GLRjqcPQ1V9
// SIG // 41wFfdLRvYkW3Ko7bd74VvU/i93wGZTHq2ln4e3lJj5b
// SIG // TFPJREDjHpaP9XoZCBju2GTh8VKniqZhfUGlvC1009Pd
// SIG // AB2eJOoPrXaWRXwjKLchvhOF6jemVrShAUIhN8S9uwQw
// SIG // ggdxMIIFWaADAgECAhMzAAAAFcXna54Cm0mZAAAAAAAV
// SIG // MA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzET
// SIG // MBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVk
// SIG // bW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0
// SIG // aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0
// SIG // aWZpY2F0ZSBBdXRob3JpdHkgMjAxMDAeFw0yMTA5MzAx
// SIG // ODIyMjVaFw0zMDA5MzAxODMyMjVaMHwxCzAJBgNVBAYT
// SIG // AlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQH
// SIG // EwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29y
// SIG // cG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1l
// SIG // LVN0YW1wIFBDQSAyMDEwMIICIjANBgkqhkiG9w0BAQEF
// SIG // AAOCAg8AMIICCgKCAgEA5OGmTOe0ciELeaLL1yR5vQ7V
// SIG // gtP97pwHB9KpbE51yMo1V/YBf2xK4OK9uT4XYDP/XE/H
// SIG // ZveVU3Fa4n5KWv64NmeFRiMMtY0Tz3cywBAY6GB9alKD
// SIG // RLemjkZrBxTzxXb1hlDcwUTIcVxRMTegCjhuje3XD9gm
// SIG // U3w5YQJ6xKr9cmmvHaus9ja+NSZk2pg7uhp7M62AW36M
// SIG // EBydUv626GIl3GoPz130/o5Tz9bshVZN7928jaTjkY+y
// SIG // OSxRnOlwaQ3KNi1wjjHINSi947SHJMPgyY9+tVSP3PoF
// SIG // VZhtaDuaRr3tpK56KTesy+uDRedGbsoy1cCGMFxPLOJi
// SIG // ss254o2I5JasAUq7vnGpF1tnYN74kpEeHT39IM9zfUGa
// SIG // RnXNxF803RKJ1v2lIH1+/NmeRd+2ci/bfV+Autuqfjbs
// SIG // Nkz2K26oElHovwUDo9Fzpk03dJQcNIIP8BDyt0cY7afo
// SIG // mXw/TNuvXsLz1dhzPUNOwTM5TI4CvEJoLhDqhFFG4tG9
// SIG // ahhaYQFzymeiXtcodgLiMxhy16cg8ML6EgrXY28MyTZk
// SIG // i1ugpoMhXV8wdJGUlNi5UPkLiWHzNgY1GIRH29wb0f2y
// SIG // 1BzFa/ZcUlFdEtsluq9QBXpsxREdcu+N+VLEhReTwDwV
// SIG // 2xo3xwgVGD94q0W29R6HXtqPnhZyacaue7e3PmriLq0C
// SIG // AwEAAaOCAd0wggHZMBIGCSsGAQQBgjcVAQQFAgMBAAEw
// SIG // IwYJKwYBBAGCNxUCBBYEFCqnUv5kxJq+gpE8RjUpzxD/
// SIG // LwTuMB0GA1UdDgQWBBSfpxVdAF5iXYP05dJlpxtTNRnp
// SIG // cjBcBgNVHSAEVTBTMFEGDCsGAQQBgjdMg30BATBBMD8G
// SIG // CCsGAQUFBwIBFjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5j
// SIG // b20vcGtpb3BzL0RvY3MvUmVwb3NpdG9yeS5odG0wEwYD
// SIG // VR0lBAwwCgYIKwYBBQUHAwgwGQYJKwYBBAGCNxQCBAwe
// SIG // CgBTAHUAYgBDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB
// SIG // /wQFMAMBAf8wHwYDVR0jBBgwFoAU1fZWy4/oolxiaNE9
// SIG // lJBb186aGMQwVgYDVR0fBE8wTTBLoEmgR4ZFaHR0cDov
// SIG // L2NybC5taWNyb3NvZnQuY29tL3BraS9jcmwvcHJvZHVj
// SIG // dHMvTWljUm9vQ2VyQXV0XzIwMTAtMDYtMjMuY3JsMFoG
// SIG // CCsGAQUFBwEBBE4wTDBKBggrBgEFBQcwAoY+aHR0cDov
// SIG // L3d3dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9NaWNS
// SIG // b29DZXJBdXRfMjAxMC0wNi0yMy5jcnQwDQYJKoZIhvcN
// SIG // AQELBQADggIBAJ1VffwqreEsH2cBMSRb4Z5yS/ypb+pc
// SIG // FLY+TkdkeLEGk5c9MTO1OdfCcTY/2mRsfNB1OW27DzHk
// SIG // wo/7bNGhlBgi7ulmZzpTTd2YurYeeNg2LpypglYAA7AF
// SIG // vonoaeC6Ce5732pvvinLbtg/SHUB2RjebYIM9W0jVOR4
// SIG // U3UkV7ndn/OOPcbzaN9l9qRWqveVtihVJ9AkvUCgvxm2
// SIG // EhIRXT0n4ECWOKz3+SmJw7wXsFSFQrP8DJ6LGYnn8Atq
// SIG // gcKBGUIZUnWKNsIdw2FzLixre24/LAl4FOmRsqlb30mj
// SIG // dAy87JGA0j3mSj5mO0+7hvoyGtmW9I/2kQH2zsZ0/fZM
// SIG // cm8Qq3UwxTSwethQ/gpY3UA8x1RtnWN0SCyxTkctwRQE
// SIG // cb9k+SS+c23Kjgm9swFXSVRk2XPXfx5bRAGOWhmRaw2f
// SIG // pCjcZxkoJLo4S5pu+yFUa2pFEUep8beuyOiJXk+d0tBM
// SIG // drVXVAmxaQFEfnyhYWxz/gq77EFmPWn9y8FBSX5+k77L
// SIG // +DvktxW/tM4+pTFRhLy/AsGConsXHRWJjXD+57XQKBqJ
// SIG // C4822rpM+Zv/Cuk0+CQ1ZyvgDbjmjJnW4SLq8CdCPSWU
// SIG // 5nR0W2rRnj7tfqAxM328y+l7vzhwRNGQ8cirOoo6CGJ/
// SIG // 2XBjU02N7oJtpQUQwXEGahC0HVUzWLOhcGbyoYIDUDCC
// SIG // AjgCAQEwgfmhgdGkgc4wgcsxCzAJBgNVBAYTAlVTMRMw
// SIG // EQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt
// SIG // b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRp
// SIG // b24xJTAjBgNVBAsTHE1pY3Jvc29mdCBBbWVyaWNhIE9w
// SIG // ZXJhdGlvbnMxJzAlBgNVBAsTHm5TaGllbGQgVFNTIEVT
// SIG // Tjo4NjAzLTA1RTAtRDk0NzElMCMGA1UEAxMcTWljcm9z
// SIG // b2Z0IFRpbWUtU3RhbXAgU2VydmljZaIjCgEBMAcGBSsO
// SIG // AwIaAxUA+5+wZOILDNrW1P4vjNwbUZy49PeggYMwgYCk
// SIG // fjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGlu
// SIG // Z3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMV
// SIG // TWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1N
// SIG // aWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDANBgkq
// SIG // hkiG9w0BAQsFAAIFAOthtMYwIhgPMjAyNTAyMjAxNDAz
// SIG // NTBaGA8yMDI1MDIyMTE0MDM1MFowdzA9BgorBgEEAYRZ
// SIG // CgQBMS8wLTAKAgUA62G0xgIBADAKAgEAAgIBwgIB/zAH
// SIG // AgEAAgIVgTAKAgUA62MGRgIBADA2BgorBgEEAYRZCgQC
// SIG // MSgwJjAMBgorBgEEAYRZCgMCoAowCAIBAAIDB6EgoQow
// SIG // CAIBAAIDAYagMA0GCSqGSIb3DQEBCwUAA4IBAQB0lqLF
// SIG // fCbSL1rIpBZprvSyZxBd/QZb1i4V1FGU+ad5EA/c5X8d
// SIG // AEzb3so5yjgdBIFFuzKK9c1JsCgyDmu3Du1br8WotXMb
// SIG // fUIf6BVLC0kvsbStrkAIZqCJzwNvLtBRa1PEr01G2+61
// SIG // EyDVb7wqAzqw0Og390+d6G4tlDeXpgGAWakBG8NfbkcC
// SIG // ilnTdzGqDMw3K9SmwTr/cGGV+7olU32Oc4Zt/KAj+ADw
// SIG // /9JDlK53Eg7oK1L/emZO8qMAMlTZOu8r76LaCRuPo5ls
// SIG // uZ561LEIvb5yl+q6kCZ70/nI/n0uc5yz+6vYg/x8JzKq
// SIG // 5H582KJJvotaicgQQQRkXWJDtVSYMYIEDTCCBAkCAQEw
// SIG // gZMwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hp
// SIG // bmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoT
// SIG // FU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMd
// SIG // TWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTACEzMA
// SIG // AAHxs0X1J+jAFtYAAQAAAfEwDQYJYIZIAWUDBAIBBQCg
// SIG // ggFKMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAv
// SIG // BgkqhkiG9w0BCQQxIgQgWdfu3YM8eXGk+C/KCMZTzIwT
// SIG // Zde1Y0FDw7uZukRGsfswgfoGCyqGSIb3DQEJEAIvMYHq
// SIG // MIHnMIHkMIG9BCDVd/0+YUu4o8GqOOukaLAe8MBIm7dG
// SIG // tT+RKiMBI/YReDCBmDCBgKR+MHwxCzAJBgNVBAYTAlVT
// SIG // MRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS
// SIG // ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9y
// SIG // YXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0
// SIG // YW1wIFBDQSAyMDEwAhMzAAAB8bNF9SfowBbWAAEAAAHx
// SIG // MCIEIAWV35O3VnKT12Zf9JyDFVsRBJGHihyG5iYIDGn+
// SIG // Ob76MA0GCSqGSIb3DQEBCwUABIICAIzJOERWo/o7T0Dq
// SIG // Yevjzkor2XRUzpz3kj1QoTe/kmhWJfSC+8OF/IItW7Yo
// SIG // DGaZxngL5D0O+1Hb/aE0fvKk2BwagYBXzTi1Gv1F12rU
// SIG // 8PiKStspCRAZmsy3s0RX9iA2cYT0VahPMJWeVbrV8sAK
// SIG // DOZp7w+iW49n8gmQR9sC837fEqNPaN+ZP1Y4bkWoT/77
// SIG // 1xPvICpm0D1frtrhpz/Dj6q5MNhOXIV6oqHhlnsLWqln
// SIG // dFfcw7JQXKFg/Z3juO66S2qa6RyHYcetuOfguGYKQehI
// SIG // FN6AecNvGQhbfq10YOE4+uMEuxalto4G1J+GYRny3SXt
// SIG // osBVwBSkTE6otsrQo3wrtCHgXGpRWRW9rl5o+VeHmlBm
// SIG // eurrDxFVc1F9ZEpDz3GkYELDWTn4fxi2fhGaV3ckAdMM
// SIG // MCfAcUVDJBBnAK4RQuBZe7WbEe5X9SLgDUoGbFb0dPio
// SIG // rkVJF5KBJkoeXqAMQC+RZnwwVG+yM7Nsp7AB0kVf+81j
// SIG // 3ulHsnOm/lUjkA0j7FUj5N/sBC74uOJp66l1j+hj1Rkz
// SIG // SDwxjlM04VExmaJoutFoUf+p3TojL9pujFBRg40AwFj5
// SIG // +w9G67kkCSrYUUtIrHajDpPAWhKTWQEUiYfO/4RdYsky
// SIG // uLNWFE9znL57pDIFXyhA2CVFkU5TFnA2ObO8SvmbP1u7
// SIG // o1LX4BOR
// SIG // End signature block