UNPKG

@microsoft/windows-admin-center-sdk

Version:

Microsoft - Windows Admin Center Shell

540 lines (537 loc) 26 kB
import { of, Subject } from 'rxjs'; import { catchError, map } from 'rxjs/operators'; import { Net } from '../data/net'; import { LogLevel } from '../diagnostics/log-level'; import { Logging } from '../diagnostics/logging'; import { SmeWebTelemetry } from '../diagnostics/sme-web-telemetry'; import { TelemetryEventStates } from '../diagnostics/sme-web-telemetry-models'; import { NotificationState } from './notification-state'; import { SocketMessageFlags, SocketSignalR } from './socket-signalr'; /** * The PowerShell script based notification class. */ export class PowerShellNotification extends SocketSignalR { static connectionUrl = '/api/notifications'; static notify = 'Notify'; static subscribe = 'Subscribe'; subjectInternal; /* tslint:disable:no-bitwise */ static hasConnectionError(item) { return (item.type & SocketMessageFlags.ConnectionError) === SocketMessageFlags.ConnectionError; } static hasError(item) { return (item.type & SocketMessageFlags.Error) === SocketMessageFlags.Error; } static hasException(item) { return (item.type & SocketMessageFlags.Exception) === SocketMessageFlags.Exception; } static hasCompleted(item) { return (item.type & SocketMessageFlags.Completed) === SocketMessageFlags.Completed; } static hasData(item) { return (item.type & SocketMessageFlags.Data) === SocketMessageFlags.Data; } static hasProgress(item) { return (item.type & SocketMessageFlags.Progress) === SocketMessageFlags.Progress; } /** * Initializes a new instance of the GatewaySocket class. */ constructor(gatewayUrl) { super(gatewayUrl, PowerShellNotification.connectionUrl); } /** * Gets the subject observable to get notifications. */ get subject() { return this.subjectInternal.asObservable(); } /** * Submit PowerShell command as a work item. * * @param nodeConnection The node connection. * @param command The PowerShell command. * @param metadata The meta data. * @param nodeRequestOptions The node request options. * @param create The callback to create new notification. * @return Observable the observable of initial powershell query result. */ submit(nodeConnection, nodeName, command, metadata, nodeRequestOptions, create) { // For a non-powershell long running task (eg: azure site recovery setup): // The 'command' parameter is null. // The metadata.id is the workitem id generated by a gateway api. if (!command && metadata.id) { const result = { id: metadata.id, completed: false, error: null, state: NotificationState.Started }; if (create) { create(result); } this.subscribeSession(metadata.id); return of({ id: metadata.id, state: NotificationState.Started, error: null }); } const data = Net.createPropertiesJSONString({ ...command, useInProcRunspace: nodeRequestOptions.useInProcRunspace, ...{ metadata: metadata } }); return nodeConnection.post(nodeName, Net.powerShellApiInvokeCommand, data, nodeRequestOptions) .pipe(catchError((error) => { SmeWebTelemetry.tracePowershellEvent(command, TelemetryEventStates.Error, { response: error.response }); const result = { id: MsftSme.newGuid(), completed: true, error: { message: Net.getErrorMessage(error) }, state: NotificationState.Error }; if (create) { create(result); } return of({ id: result.id, state: result.state, error: result.error }); }), map((response) => { const completed = response.completed === 'True'; if (response.id) { // sending back the client for the error. return response; } let error = null; if (response.errors && response.errors.length > 0) { const errorObj = MsftSme.first(response.errors); error = { message: errorObj.message }; SmeWebTelemetry.tracePowershellEvent(command, TelemetryEventStates.Error, { response: response }); } const result = { id: response.sessionId, completed: completed, error: error, state: completed ? (response.errors ? NotificationState.Error : NotificationState.Success) : NotificationState.Started }; if (result.state === NotificationState.Success) { result.error = response.results[0]; } if (create) { create(result); } if (!result.completed) { this.subscribeSession(response.sessionId); // store ID here to correlate command with the gateway notification later const powershellCommandId = response.id ? response.id : response.sessionId; SmeWebTelemetry.addPowershellId(powershellCommandId, command); } this.processPowerShellData(response); // sending back the client. const workItemResult = { id: result.id, state: result.state, error: error }; // passing in the results as object of the workItemResult if (response.results) { workItemResult.object = response.results; } return workItemResult; })); } /** * Initialize to subscribe the web socket connection. */ initialize() { if (this.subjectInternal) { this.subjectInternal.complete(); } this.subjectInternal = new Subject(); this.subscribe(PowerShellNotification.notify); return this.start(); } /** * Uninitialize to subscribe the web socket connection. */ uninitialize() { if (this.subjectInternal) { this.subjectInternal.complete(); this.subjectInternal = null; } this.unsubscribe(PowerShellNotification.notify); this.stop(); } /** * Invoke subscribe method to a session. * * @param id the session ID of work item. * @return Promise the promise object. */ subscribeSession(id) { return this.invoke(PowerShellNotification.subscribe, id); } /** * The client handler to process message. * * @param notification the message notification. */ clientHandler(notification) { this.subjectInternal.next(notification); } /** * Process the message. * * @param messages the messages. */ processMessage(message) { if (!message) { const message2 = MsftSme.getStrings().MsftSmeShell.Core.Error.NotificationEmptyMessage.message; Logging.log({ source: 'socket', level: LogLevel.Warning, message: message2 }); return; } const data = JSON.parse(message); if (data.sessionId) { // PowerShell work item. this.processPowerShellData(data); return; } if (data.id) { // Notification message. this.processMessageData(data); return; } } processPowerShellData(data) { /* tslint:disable:no-bitwise */ let type = SocketMessageFlags.None; if (data.results && data.results.length > 0) { type |= SocketMessageFlags.Data; } if (data.progress && data.progress.length > 0) { type |= SocketMessageFlags.Progress; } if (data.errors && data.errors.length > 0) { type |= SocketMessageFlags.Error; } if (data.exception) { type |= SocketMessageFlags.Exception; } if (data.completed === 'True') { type |= SocketMessageFlags.Completed; } this.clientHandler({ type: type, message: data }); } processMessageData(message) { const type = SocketMessageFlags.Data; this.clientHandler({ type, message }); } } //# sourceMappingURL=powershell-notification.js.map // SIG // Begin signature block // SIG // MIIoKAYJKoZIhvcNAQcCoIIoGTCCKBUCAQExDzANBglg // SIG // hkgBZQMEAgEFADB3BgorBgEEAYI3AgEEoGkwZzAyBgor // SIG // BgEEAYI3AgEeMCQCAQEEEBDgyQbOONQRoqMAEEvTUJAC // SIG // AQACAQACAQACAQACAQAwMTANBglghkgBZQMEAgEFAAQg // SIG // FxINvSyIENYBj9H4o75y2LCgzJKhK41oDuQgbFHnFVyg // SIG // gg12MIIF9DCCA9ygAwIBAgITMwAABARsdAb/VysncgAA // SIG // AAAEBDANBgkqhkiG9w0BAQsFADB+MQswCQYDVQQGEwJV // SIG // UzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH // SIG // UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBv // SIG // cmF0aW9uMSgwJgYDVQQDEx9NaWNyb3NvZnQgQ29kZSBT // SIG // aWduaW5nIFBDQSAyMDExMB4XDTI0MDkxMjIwMTExNFoX // SIG // DTI1MDkxMTIwMTExNFowdDELMAkGA1UEBhMCVVMxEzAR // SIG // BgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1v // SIG // bmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv // SIG // bjEeMBwGA1UEAxMVTWljcm9zb2Z0IENvcnBvcmF0aW9u // SIG // MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA // SIG // tCg32mOdDA6rBBnZSMwxwXegqiDEUFlvQH9Sxww07hY3 // SIG // w7L52tJxLg0mCZjcszQddI6W4NJYb5E9QM319kyyE0l8 // SIG // EvA/pgcxgljDP8E6XIlgVf6W40ms286Cr0azaA1f7vaJ // SIG // jjNhGsMqOSSSXTZDNnfKs5ENG0bkXeB2q5hrp0qLsm/T // SIG // WO3oFjeROZVHN2tgETswHR3WKTm6QjnXgGNj+V6rSZJO // SIG // /WkTqc8NesAo3Up/KjMwgc0e67x9llZLxRyyMWUBE9co // SIG // T2+pUZqYAUDZ84nR1djnMY3PMDYiA84Gw5JpceeED38O // SIG // 0cEIvKdX8uG8oQa047+evMfDRr94MG9EWwIDAQABo4IB // SIG // czCCAW8wHwYDVR0lBBgwFgYKKwYBBAGCN0wIAQYIKwYB // SIG // BQUHAwMwHQYDVR0OBBYEFPIboTWxEw1PmVpZS+AzTDwo // SIG // oxFOMEUGA1UdEQQ+MDykOjA4MR4wHAYDVQQLExVNaWNy // SIG // b3NvZnQgQ29ycG9yYXRpb24xFjAUBgNVBAUTDTIzMDAx // SIG // Mis1MDI5MjMwHwYDVR0jBBgwFoAUSG5k5VAF04KqFzc3 // SIG // IrVtqMp1ApUwVAYDVR0fBE0wSzBJoEegRYZDaHR0cDov // SIG // L3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jcmwvTWlj // SIG // Q29kU2lnUENBMjAxMV8yMDExLTA3LTA4LmNybDBhBggr // SIG // BgEFBQcBAQRVMFMwUQYIKwYBBQUHMAKGRWh0dHA6Ly93 // SIG // d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY2VydHMvTWlj // SIG // Q29kU2lnUENBMjAxMV8yMDExLTA3LTA4LmNydDAMBgNV // SIG // HRMBAf8EAjAAMA0GCSqGSIb3DQEBCwUAA4ICAQCI5g/S // SIG // KUFb3wdUHob6Qhnu0Hk0JCkO4925gzI8EqhS+K4umnvS // SIG // BU3acsJ+bJprUiMimA59/5x7WhJ9F9TQYy+aD9AYwMtb // SIG // KsQ/rst+QflfML+Rq8YTAyT/JdkIy7R/1IJUkyIS6srf // SIG // G1AKlX8n6YeAjjEb8MI07wobQp1F1wArgl2B1mpTqHND // SIG // lNqBjfpjySCScWjUHNbIwbDGxiFr93JoEh5AhJqzL+8m // SIG // onaXj7elfsjzIpPnl8NyH2eXjTojYC9a2c4EiX0571Ko // SIG // mhENF3RtR25A7/X7+gk6upuE8tyMy4sBkl2MUSF08U+E // SIG // 2LOVcR8trhYxV1lUi9CdgEU2CxODspdcFwxdT1+G8YNc // SIG // gzHyjx3BNSI4nOZcdSnStUpGhCXbaOIXfvtOSfQX/UwJ // SIG // oruhCugvTnub0Wna6CQiturglCOMyIy/6hu5rMFvqk9A // SIG // ltIJ0fSR5FwljW6PHHDJNbCWrZkaEgIn24M2mG1M/Ppb // SIG // /iF8uRhbgJi5zWxo2nAdyDBqWvpWxYIoee/3yIWpquVY // SIG // cYGhJp/1I1sq/nD4gBVrk1SKX7Do2xAMMO+cFETTNSJq // SIG // fTSSsntTtuBLKRB5mw5qglHKuzapDiiBuD1Zt4QwxA/1 // SIG // kKcyQ5L7uBayG78kxlVNNbyrIOFH3HYmdH0Pv1dIX/Mq // SIG // 7avQpAfIiLpOWwcbjzCCB3owggVioAMCAQICCmEOkNIA // SIG // AAAAAAMwDQYJKoZIhvcNAQELBQAwgYgxCzAJBgNVBAYT // SIG // AlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQH // SIG // EwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29y // SIG // cG9yYXRpb24xMjAwBgNVBAMTKU1pY3Jvc29mdCBSb290 // SIG // IENlcnRpZmljYXRlIEF1dGhvcml0eSAyMDExMB4XDTEx // SIG // MDcwODIwNTkwOVoXDTI2MDcwODIxMDkwOVowfjELMAkG // SIG // A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAO // SIG // BgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29m // SIG // dCBDb3Jwb3JhdGlvbjEoMCYGA1UEAxMfTWljcm9zb2Z0 // SIG // IENvZGUgU2lnbmluZyBQQ0EgMjAxMTCCAiIwDQYJKoZI // SIG // hvcNAQEBBQADggIPADCCAgoCggIBAKvw+nIQHC6t2G6q // SIG // ghBNNLrytlghn0IbKmvpWlCquAY4GgRJun/DDB7dN2vG // SIG // EtgL8DjCmQawyDnVARQxQtOJDXlkh36UYCRsr55JnOlo // SIG // XtLfm1OyCizDr9mpK656Ca/XllnKYBoF6WZ26DJSJhIv // SIG // 56sIUM+zRLdd2MQuA3WraPPLbfM6XKEW9Ea64DhkrG5k // SIG // NXimoGMPLdNAk/jj3gcN1Vx5pUkp5w2+oBN3vpQ97/vj // SIG // K1oQH01WKKJ6cuASOrdJXtjt7UORg9l7snuGG9k+sYxd // SIG // 6IlPhBryoS9Z5JA7La4zWMW3Pv4y07MDPbGyr5I4ftKd // SIG // gCz1TlaRITUlwzluZH9TupwPrRkjhMv0ugOGjfdf8NBS // SIG // v4yUh7zAIXQlXxgotswnKDglmDlKNs98sZKuHCOnqWbs // SIG // YR9q4ShJnV+I4iVd0yFLPlLEtVc/JAPw0XpbL9Uj43Bd // SIG // D1FGd7P4AOG8rAKCX9vAFbO9G9RVS+c5oQ/pI0m8GLhE // SIG // fEXkwcNyeuBy5yTfv0aZxe/CHFfbg43sTUkwp6uO3+xb // SIG // n6/83bBm4sGXgXvt1u1L50kppxMopqd9Z4DmimJ4X7Iv // SIG // hNdXnFy/dygo8e1twyiPLI9AN0/B4YVEicQJTMXUpUMv // SIG // dJX3bvh4IFgsE11glZo+TzOE2rCIF96eTvSWsLxGoGyY // SIG // 0uDWiIwLAgMBAAGjggHtMIIB6TAQBgkrBgEEAYI3FQEE // SIG // AwIBADAdBgNVHQ4EFgQUSG5k5VAF04KqFzc3IrVtqMp1 // SIG // ApUwGQYJKwYBBAGCNxQCBAweCgBTAHUAYgBDAEEwCwYD // SIG // VR0PBAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0j // SIG // BBgwFoAUci06AjGQQ7kUBU7h6qfHMdEjiTQwWgYDVR0f // SIG // BFMwUTBPoE2gS4ZJaHR0cDovL2NybC5taWNyb3NvZnQu // SIG // Y29tL3BraS9jcmwvcHJvZHVjdHMvTWljUm9vQ2VyQXV0 // SIG // MjAxMV8yMDExXzAzXzIyLmNybDBeBggrBgEFBQcBAQRS // SIG // MFAwTgYIKwYBBQUHMAKGQmh0dHA6Ly93d3cubWljcm9z // SIG // b2Z0LmNvbS9wa2kvY2VydHMvTWljUm9vQ2VyQXV0MjAx // SIG // MV8yMDExXzAzXzIyLmNydDCBnwYDVR0gBIGXMIGUMIGR // SIG // BgkrBgEEAYI3LgMwgYMwPwYIKwYBBQUHAgEWM2h0dHA6 // SIG // Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvZG9jcy9w // SIG // cmltYXJ5Y3BzLmh0bTBABggrBgEFBQcCAjA0HjIgHQBM // SIG // AGUAZwBhAGwAXwBwAG8AbABpAGMAeQBfAHMAdABhAHQA // SIG // ZQBtAGUAbgB0AC4gHTANBgkqhkiG9w0BAQsFAAOCAgEA // SIG // Z/KGpZjgVHkaLtPYdGcimwuWEeFjkplCln3SeQyQwWVf // SIG // Liw++MNy0W2D/r4/6ArKO79HqaPzadtjvyI1pZddZYSQ // SIG // fYtGUFXYDJJ80hpLHPM8QotS0LD9a+M+By4pm+Y9G6XU // SIG // tR13lDni6WTJRD14eiPzE32mkHSDjfTLJgJGKsKKELuk // SIG // qQUMm+1o+mgulaAqPyprWEljHwlpblqYluSD9MCP80Yr // SIG // 3vw70L01724lruWvJ+3Q3fMOr5kol5hNDj0L8giJ1h/D // SIG // Mhji8MUtzluetEk5CsYKwsatruWy2dsViFFFWDgycSca // SIG // f7H0J/jeLDogaZiyWYlobm+nt3TDQAUGpgEqKD6CPxNN // SIG // ZgvAs0314Y9/HG8VfUWnduVAKmWjw11SYobDHWM2l4bf // SIG // 2vP48hahmifhzaWX0O5dY0HjWwechz4GdwbRBrF1HxS+ // SIG // YWG18NzGGwS+30HHDiju3mUv7Jf2oVyW2ADWoUa9WfOX // SIG // pQlLSBCZgB/QACnFsZulP0V3HjXG0qKin3p6IvpIlR+r // SIG // +0cjgPWe+L9rt0uX4ut1eBrs6jeZeRhL/9azI2h15q/6 // SIG // /IvrC4DqaTuv/DDtBEyO3991bWORPdGdVk5Pv4BXIqF4 // SIG // ETIheu9BCrE/+6jMpF3BoYibV3FWTkhFwELJm3ZbCoBI // SIG // a/15n8G9bW1qyVJzEw16UM0xghoKMIIaBgIBATCBlTB+ // SIG // MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3Rv // SIG // bjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWlj // SIG // cm9zb2Z0IENvcnBvcmF0aW9uMSgwJgYDVQQDEx9NaWNy // SIG // b3NvZnQgQ29kZSBTaWduaW5nIFBDQSAyMDExAhMzAAAE // SIG // BGx0Bv9XKydyAAAAAAQEMA0GCWCGSAFlAwQCAQUAoIGu // SIG // MBkGCSqGSIb3DQEJAzEMBgorBgEEAYI3AgEEMBwGCisG // SIG // AQQBgjcCAQsxDjAMBgorBgEEAYI3AgEVMC8GCSqGSIb3 // SIG // DQEJBDEiBCCRI8le3zJCzgYfYXb6vPa3s/9/suQoA74c // SIG // tFBdDCBYizBCBgorBgEEAYI3AgEMMTQwMqAUgBIATQBp // SIG // AGMAcgBvAHMAbwBmAHShGoAYaHR0cDovL3d3dy5taWNy // SIG // b3NvZnQuY29tMA0GCSqGSIb3DQEBAQUABIIBAFJREcJi // SIG // El2IryQuo24ZfeGlMvMnKmie0onbyBIz6tmwkvokmZsv // SIG // 9OmkJbZjX8VZMVqirfticZ4XYKOenonOp6TluDvW4yRb // SIG // QDqQTobAyYFXOxMgCDH1JULjqtejOnGBn89HGpiMvI9X // SIG // uz8mauWSKYwLWIvNdWCw8QYwRt1pqSquk+Rsupgt0DGZ // SIG // rHne9oAiUSz057BzIiAg1UKySmGYS/j4VsyNswSmnD6t // SIG // Mg8ZNyYxlQLi53KGTqwOnI2NuKViPgHShGt7QrsqdeRj // SIG // 64o3h536nG3BnjNSfR4xyGXCoCefAdWBq+tJTG9qh7LW // SIG // uTs36BRVSjTTbkzX/+53suXGI8ahgheUMIIXkAYKKwYB // SIG // BAGCNwMDATGCF4Awghd8BgkqhkiG9w0BBwKgghdtMIIX // SIG // aQIBAzEPMA0GCWCGSAFlAwQCAQUAMIIBUgYLKoZIhvcN // SIG // AQkQAQSgggFBBIIBPTCCATkCAQEGCisGAQQBhFkKAwEw // SIG // MTANBglghkgBZQMEAgEFAAQgPbU0ffuzvMtPuv3/wfn4 // SIG // uNRMnPHdoVfD1DbuAZOt7HgCBmet86n9rBgTMjAyNTAy // SIG // MjAxNTI4MzkuMDM0WjAEgAIB9KCB0aSBzjCByzELMAkG // SIG // A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAO // SIG // BgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29m // SIG // dCBDb3Jwb3JhdGlvbjElMCMGA1UECxMcTWljcm9zb2Z0 // SIG // IEFtZXJpY2EgT3BlcmF0aW9uczEnMCUGA1UECxMeblNo // SIG // aWVsZCBUU1MgRVNOOjhEMDAtMDVFMC1EOTQ3MSUwIwYD // SIG // VQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNl // SIG // oIIR6jCCByAwggUIoAMCAQICEzMAAAHzxQpDrgPMHTEA // SIG // AQAAAfMwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UEBhMC // SIG // VVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcT // SIG // B1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jw // SIG // b3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUt // SIG // U3RhbXAgUENBIDIwMTAwHhcNMjMxMjA2MTg0NjAyWhcN // SIG // MjUwMzA1MTg0NjAyWjCByzELMAkGA1UEBhMCVVMxEzAR // SIG // BgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1v // SIG // bmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv // SIG // bjElMCMGA1UECxMcTWljcm9zb2Z0IEFtZXJpY2EgT3Bl // SIG // cmF0aW9uczEnMCUGA1UECxMeblNoaWVsZCBUU1MgRVNO // SIG // OjhEMDAtMDVFMC1EOTQ3MSUwIwYDVQQDExxNaWNyb3Nv // SIG // ZnQgVGltZS1TdGFtcCBTZXJ2aWNlMIICIjANBgkqhkiG // SIG // 9w0BAQEFAAOCAg8AMIICCgKCAgEA/p+m2uErgfYkjuVj // SIG // IW54KmAG/s9yH8zaWSFkv7IH14ZS2Jhp7FLaxl9zlXIP // SIG // vJKyXYsbjVDDu2QDqgmbF1Izs/M3J9WlA+Q9q9j4c1So // SIG // x7Yr1hoBo+MecKlntUKL97zM/Fh7CrH2nSJVo3wTJ1Sl // SIG // aJjsm0O/to3OGn849lyUEEphPY0EaAaIA8JqmWpHmJyM // SIG // dBJjrrnD6+u+E+v2Gkz4iGJRn/l1druqEBwJDBuesWD0 // SIG // IpIrUI4zVhwA3wamwRGqqaWrLcaUTXOIndktcVUMXEBl // SIG // 45wIHnlW2z2wKBC4W8Ps91XrUcLhBSUc0+oW1hIL8/Sz // SIG // GD0m4qBy/MPmYlqN8bsN0e3ybKnu6arJ48L54j+7HxNb // SIG // rX4u5NDUGTKb4jrP/9t/R+ngOiDlbRfMOuoqRO9RGK3E // SIG // jazhpU5ubqqvrMjtbnWTnijNMWO9vDXBgxap47hT2xBJ // SIG // uvnrWSn7VPY8Swks6lzlTs3agPDuV2txONY97OzJUxeE // SIG // OwWK0Jm6caoU737iJWMCNgM3jtzor3HsycAY9hUIE4lR // SIG // 2nLzEA4EgOxOb8rWpNPjCwZtAHFuCD3q/AOIDhg/aEqa // SIG // 5sgLtSesBZAa39ko5/onjauhcdLVo/CKYN7kL3LoN+40 // SIG // mnReqta1BGqDyGo2QhlZPqOcJ+q7fnMHSd/URFON2lgs // SIG // J9Avl8cCAwEAAaOCAUkwggFFMB0GA1UdDgQWBBTDZBX2 // SIG // pRFRDIwNwKaFMfag6w0KJDAfBgNVHSMEGDAWgBSfpxVd // SIG // AF5iXYP05dJlpxtTNRnpcjBfBgNVHR8EWDBWMFSgUqBQ // SIG // hk5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3Bz // SIG // L2NybC9NaWNyb3NvZnQlMjBUaW1lLVN0YW1wJTIwUENB // SIG // JTIwMjAxMCgxKS5jcmwwbAYIKwYBBQUHAQEEYDBeMFwG // SIG // CCsGAQUFBzAChlBodHRwOi8vd3d3Lm1pY3Jvc29mdC5j // SIG // b20vcGtpb3BzL2NlcnRzL01pY3Jvc29mdCUyMFRpbWUt // SIG // U3RhbXAlMjBQQ0ElMjAyMDEwKDEpLmNydDAMBgNVHRMB // SIG // Af8EAjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMA4G // SIG // A1UdDwEB/wQEAwIHgDANBgkqhkiG9w0BAQsFAAOCAgEA // SIG // 38Qcj/zR/u/b3N5YjuHO51zP1ChXAJucOtRcUcT8Ql0V // SIG // 5YjY2e7A6jT9A81EwVPbUuQ6pKkUoiFdeY+6vHunpYPP // SIG // 3A9279LFuBqPQDC+JYQOTAYN8MynYoXydBPxyKnB19dZ // SIG // sLW6U4gtrIAFIe/jmZ2/U8CRO6WxATyUFMcbgokuf69L // SIG // NkFYqQZov/DBFtniIuJifrxyOQwmgBqKE+ANef+6DY/c // SIG // 8s0QAU1CAjTa0tfSn68hDeXYeZKjhuEIHGvcOi+wi/kr // SIG // rk2YtEmfGauuYitoUPCDADlcXsAqQ+JWS+jQ7FTUsATV // SIG // zlJbMTgDtxtMDU/nAboPxw+NwexNqHVX7Oh9hGAmcVEt // SIG // a4EXhndrqkMYENsKzLk2+cpDvqnfuJ4Wn//Ujd4HraJr // SIG // UJ+SM4XwpK2k9Sp2RfEyN8ntWd6Z3q9Ap/6deR+8DcA5 // SIG // AQImftos/TVBHmC3zBpvbxKw1QQ0TIxrBPx6qmO0E0k7 // SIG // Q71O/s2cETxo4mGFBV0/lYJH3R4haSsONl7JtDHy+Wjm // SIG // t9RcgjNe/6T0yCk0YirAxd+9EsCMGQI1c4g//UIRBQbv // SIG // aaIxVCzmb87i+YkhCSHKqKVQMHWzXa6GYthzfJ3w48yW // SIG // vAjE5EHkn0LEKSq/NzoQZhNzBdrM/IKnt5aHNOQ1vCTb // SIG // 2d9vCabNyyQgC7dK0DyWJzswggdxMIIFWaADAgECAhMz // SIG // AAAAFcXna54Cm0mZAAAAAAAVMA0GCSqGSIb3DQEBCwUA // SIG // MIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGlu // SIG // Z3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMV // SIG // TWljcm9zb2Z0IENvcnBvcmF0aW9uMTIwMAYDVQQDEylN // SIG // aWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3Jp // SIG // dHkgMjAxMDAeFw0yMTA5MzAxODIyMjVaFw0zMDA5MzAx // SIG // ODMyMjVaMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpX // SIG // YXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYD // SIG // VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNV // SIG // BAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEw // SIG // MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA // SIG // 5OGmTOe0ciELeaLL1yR5vQ7VgtP97pwHB9KpbE51yMo1 // SIG // V/YBf2xK4OK9uT4XYDP/XE/HZveVU3Fa4n5KWv64NmeF // SIG // RiMMtY0Tz3cywBAY6GB9alKDRLemjkZrBxTzxXb1hlDc // SIG // wUTIcVxRMTegCjhuje3XD9gmU3w5YQJ6xKr9cmmvHaus // SIG // 9ja+NSZk2pg7uhp7M62AW36MEBydUv626GIl3GoPz130 // SIG // /o5Tz9bshVZN7928jaTjkY+yOSxRnOlwaQ3KNi1wjjHI // SIG // NSi947SHJMPgyY9+tVSP3PoFVZhtaDuaRr3tpK56KTes // SIG // y+uDRedGbsoy1cCGMFxPLOJiss254o2I5JasAUq7vnGp // SIG // F1tnYN74kpEeHT39IM9zfUGaRnXNxF803RKJ1v2lIH1+ // SIG // /NmeRd+2ci/bfV+AutuqfjbsNkz2K26oElHovwUDo9Fz // SIG // pk03dJQcNIIP8BDyt0cY7afomXw/TNuvXsLz1dhzPUNO // SIG // wTM5TI4CvEJoLhDqhFFG4tG9ahhaYQFzymeiXtcodgLi // SIG // Mxhy16cg8ML6EgrXY28MyTZki1ugpoMhXV8wdJGUlNi5 // SIG // UPkLiWHzNgY1GIRH29wb0f2y1BzFa/ZcUlFdEtsluq9Q // SIG // BXpsxREdcu+N+VLEhReTwDwV2xo3xwgVGD94q0W29R6H // SIG // XtqPnhZyacaue7e3PmriLq0CAwEAAaOCAd0wggHZMBIG // SIG // CSsGAQQBgjcVAQQFAgMBAAEwIwYJKwYBBAGCNxUCBBYE // SIG // FCqnUv5kxJq+gpE8RjUpzxD/LwTuMB0GA1UdDgQWBBSf // SIG // pxVdAF5iXYP05dJlpxtTNRnpcjBcBgNVHSAEVTBTMFEG // SIG // DCsGAQQBgjdMg30BATBBMD8GCCsGAQUFBwIBFjNodHRw // SIG // Oi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL0RvY3Mv // SIG // UmVwb3NpdG9yeS5odG0wEwYDVR0lBAwwCgYIKwYBBQUH // SIG // AwgwGQYJKwYBBAGCNxQCBAweCgBTAHUAYgBDAEEwCwYD // SIG // VR0PBAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0j // SIG // BBgwFoAU1fZWy4/oolxiaNE9lJBb186aGMQwVgYDVR0f // SIG // BE8wTTBLoEmgR4ZFaHR0cDovL2NybC5taWNyb3NvZnQu // SIG // Y29tL3BraS9jcmwvcHJvZHVjdHMvTWljUm9vQ2VyQXV0 // SIG // XzIwMTAtMDYtMjMuY3JsMFoGCCsGAQUFBwEBBE4wTDBK // SIG // BggrBgEFBQcwAoY+aHR0cDovL3d3dy5taWNyb3NvZnQu // SIG // Y29tL3BraS9jZXJ0cy9NaWNSb29DZXJBdXRfMjAxMC0w // SIG // Ni0yMy5jcnQwDQYJKoZIhvcNAQELBQADggIBAJ1Vffwq // SIG // reEsH2cBMSRb4Z5yS/ypb+pcFLY+TkdkeLEGk5c9MTO1 // SIG // OdfCcTY/2mRsfNB1OW27DzHkwo/7bNGhlBgi7ulmZzpT // SIG // Td2YurYeeNg2LpypglYAA7AFvonoaeC6Ce5732pvvinL // SIG // btg/SHUB2RjebYIM9W0jVOR4U3UkV7ndn/OOPcbzaN9l // SIG // 9qRWqveVtihVJ9AkvUCgvxm2EhIRXT0n4ECWOKz3+SmJ // SIG // w7wXsFSFQrP8DJ6LGYnn8AtqgcKBGUIZUnWKNsIdw2Fz // SIG // Lixre24/LAl4FOmRsqlb30mjdAy87JGA0j3mSj5mO0+7 // SIG // hvoyGtmW9I/2kQH2zsZ0/fZMcm8Qq3UwxTSwethQ/gpY // SIG // 3UA8x1RtnWN0SCyxTkctwRQEcb9k+SS+c23Kjgm9swFX // SIG // SVRk2XPXfx5bRAGOWhmRaw2fpCjcZxkoJLo4S5pu+yFU // SIG // a2pFEUep8beuyOiJXk+d0tBMdrVXVAmxaQFEfnyhYWxz // SIG // /gq77EFmPWn9y8FBSX5+k77L+DvktxW/tM4+pTFRhLy/ // SIG // AsGConsXHRWJjXD+57XQKBqJC4822rpM+Zv/Cuk0+CQ1 // SIG // ZyvgDbjmjJnW4SLq8CdCPSWU5nR0W2rRnj7tfqAxM328 // SIG // y+l7vzhwRNGQ8cirOoo6CGJ/2XBjU02N7oJtpQUQwXEG // SIG // ahC0HVUzWLOhcGbyoYIDTTCCAjUCAQEwgfmhgdGkgc4w // SIG // gcsxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5n // SIG // dG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVN // SIG // aWNyb3NvZnQgQ29ycG9yYXRpb24xJTAjBgNVBAsTHE1p // SIG // Y3Jvc29mdCBBbWVyaWNhIE9wZXJhdGlvbnMxJzAlBgNV // SIG // BAsTHm5TaGllbGQgVFNTIEVTTjo4RDAwLTA1RTAtRDk0 // SIG // NzElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAg // SIG // U2VydmljZaIjCgEBMAcGBSsOAwIaAxUAbvoGLNi0YWua // SIG // RTu/YNy5H8CkZyiggYMwgYCkfjB8MQswCQYDVQQGEwJV // SIG // UzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH // SIG // UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBv // SIG // cmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1T // SIG // dGFtcCBQQ0EgMjAxMDANBgkqhkiG9w0BAQsFAAIFAOth // SIG // rBkwIhgPMjAyNTAyMjAxMzI2NDlaGA8yMDI1MDIyMTEz // SIG // MjY0OVowdDA6BgorBgEEAYRZCgQBMSwwKjAKAgUA62Gs // SIG // GQIBADAHAgEAAgIBnjAHAgEAAgIUvzAKAgUA62L9mQIB // SIG // ADA2BgorBgEEAYRZCgQCMSgwJjAMBgorBgEEAYRZCgMC // SIG // oAowCAIBAAIDB6EgoQowCAIBAAIDAYagMA0GCSqGSIb3 // SIG // DQEBCwUAA4IBAQAoTQfdDvZWBMekHKV5gFhVyHjl8oV7 // SIG // 5TqpTteSLKY0Bdi2o4JeRDQ04ABchdUlZkdfu8JYMhep // SIG // fw/irZeE79ijSJnoKc4++qzsV1mnrz5i53sCcwylzLHD // SIG // gUOWov375oREEiI+4cu3eELySA7SckfMLsYC6dMfJGNj // SIG // YUXr5Dgc3zo2Xvv6Ax997nmY7242L4ZrG121sxpHYRCg // SIG // ghB3uEQFQp0zxTuKQ79tVDc+GBlEO5KzDO+NKZ/WgCfU // SIG // Dne6aE4/eOSm3Y0c/CrbhdaQ7Azl0k8twq+oNGHstcR9 // SIG // rhHusUcMYhH0gGcYAmPeCkmiSbBZTFjx/HEdN7mu+2aS // SIG // hR3XMYIEDTCCBAkCAQEwgZMwfDELMAkGA1UEBhMCVVMx // SIG // EzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1Jl // SIG // ZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3Jh // SIG // dGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3Rh // SIG // bXAgUENBIDIwMTACEzMAAAHzxQpDrgPMHTEAAQAAAfMw // SIG // DQYJYIZIAWUDBAIBBQCgggFKMBoGCSqGSIb3DQEJAzEN // SIG // BgsqhkiG9w0BCRABBDAvBgkqhkiG9w0BCQQxIgQgpgPx // SIG // vLLoHEcRANQKOxgFXjSXWoa0mRw6pX2t4Uhw+zwwgfoG // SIG // CyqGSIb3DQEJEAIvMYHqMIHnMIHkMIG9BCAYvNk0i7bh // SIG // uFZKfMAZiZP0/kQIfONbBv2gzsMYOjti6DCBmDCBgKR+ // SIG // MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5n // SIG // dG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVN // SIG // aWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1p // SIG // Y3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAAB // SIG // 88UKQ64DzB0xAAEAAAHzMCIEIG2uliVrDtmXRDIFDtPg // SIG // J/wKSOs7YDo2gSjScMwMr06RMA0GCSqGSIb3DQEBCwUA // SIG // BIICAAc4b/0GA/sCmJq9XWb9mOd7SB7Rdk8UvrxixdOw // SIG // HE6LAkgTkyoqT1ZIOjCcZq5Kxdf9FF7ts7w9v3WUOL44 // SIG // 8rpMQPpPKpR36ES3eRsS27vZGdUpq9uDO/R0xcJIDk1t // SIG // s0+NAGcGY/Zu66UaWKGlhRvQfUQGh6uZ9iPaqTJbeQD7 // SIG // w+UWxXluEFwZeTED3yDW1qH9om0kFSDuQtJvVembp1r6 // SIG // u+INMMKLrCxxJ8rabcsdKPKkxYgoJiccmGuYa8bI8O5H // SIG // VDTRwXrfdwVOZHqF+f2CRam+hlUuRPZE/0MQUlLo6W7o // SIG // yDPPYRDhaEwrYBqCdKAylsRpgz3bsRoK14JO+iXl6ZMs // SIG // Wkf/xFRiF2OP9JE5fKJjjrRoYilF+qF+Cb3zxjz0cDFY // SIG // t1BOMFcOjrsayThHamnuxLZiqZ5rfUFYTE1tQxhSDEDU // SIG // qWs+yquunP/bX2w92xjUkf7F4yLrTy2UzYOwp7uW5c9N // SIG // on+K8rr9ugqHXJDsK8DpX72bhK4kCM72CgTo/sqN6wy2 // SIG // LJXwPLqKsFMAe5O973ss5sVkkiuBowKZmdM6DNyAQuUb // SIG // eLAU1vgDG5CgSj0VVXriWX0zVj+Io4ErGEC8D8nXFGG9 // SIG // ek21fMpb+XBl+5jFrNqa53tkLWeJylZTq21tSTR3s4I2 // SIG // Ufv8d6PP+HFQnY48Td216j9yQAjh // SIG // End signature block