OTRS-CiCS-CustomerCompanyService 1.0.0 c.a.p.e. IT GmbH http://www.cape-it.de/ GNU GENERAL PUBLIC LICENSE Version 2, June 1991 First production release. First test release. 2008-12-12 v0.1.0 New package CustomerCompanyService package. KundenFirmenService-Paket. 2.4.x <br> WELCOME<br> <br> You are about to install OTRS-CiCS-CustomerCompanyService.<br> <br> <br> REQUIRED OTRS PACKAGES <ul> <li>OTRS::CiCS 3.3.2 or OTRS::CiCS::ITSM 2.3.2 or higher</li> <br> <br> c.a.p.e. IT ...global consulting - individual solutions.<br> <br> <br> WILLKOMMEN<br> <br> Sie sind im Begriff OTRS-CiCS-CustomerCompanyService zu installieren.<br> <br> <br> BENOETIGTE OTRS-PAKETE <ul> <li>OTRS::CiCS 3.3.2 bzw. OTRS::CiCS::ITSM 2.3.2 oder hoeher</li> <br> <br> c.a.p.e. IT ...global consulting - individual solutions.<br> <br> OTRS-CiCS my $FunctionName = 'CodeInstall'; my $CodeModule = 'var::packagesetup::CustomerCompanyService'; if ( $Self->{MainObject}->Require($CodeModule) ) { my $CodeObject = $CodeModule->new( %{$Self} ); if ($CodeObject) { if ( !$CodeObject->$FunctionName(%{$Self}, %Param) ) { $Self->{LogObject}->Log( Priority => 'error', Message => "Could not call method $FunctionName() on $CodeModule.pm." ); } } else { $Self->{LogObject}->Log( Priority => 'error', Message => "Could not call method new() on $CodeModule.pm." ); } } my $FunctionName = 'CodeUpgrade'; my $CodeModule = 'var::packagesetup::CustomerCompanyService'; if ( $Self->{MainObject}->Require($CodeModule) ) { my $CodeObject = $CodeModule->new( %{$Self} ); if ($CodeObject) { if ( !$CodeObject->$FunctionName(%{$Self}, %Param) ) { $Self->{LogObject}->Log( Priority => 'error', Message => "Could not call method $FunctionName() on $CodeModule.pm." ); } } else { $Self->{LogObject}->Log( Priority => 'error', Message => "Could not call method new() on $CodeModule.pm." ); } } my $FunctionName = 'CodeUninstall'; my $CodeModule = 'var::packagesetup::CustomerCompanyService'; if ( $Self->{MainObject}->Require($CodeModule) ) { my $CodeObject = $CodeModule->new( %{$Self} ); if ($CodeObject) { if ( !$CodeObject->$FunctionName(%{$Self}, %Param) ) { $Self->{LogObject}->Log( Priority => 'error', Message => "Could not call method $FunctionName() on $CodeModule.pm." ); } } else { $Self->{LogObject}->Log( Priority => 'error', Message => "Could not call method new() on $CodeModule.pm." ); } } my $FunctionName = 'CodeReinstall'; my $CodeModule = 'var::packagesetup::CustomerCompanyService'; if ( $Self->{MainObject}->Require($CodeModule) ) { my $CodeObject = $CodeModule->new( %{$Self} ); if ($CodeObject) { if ( !$CodeObject->$FunctionName(%{$Self}, %Param) ) { $Self->{LogObject}->Log( Priority => 'error', Message => "Could not call method $FunctionName() on $CodeModule.pm." ); } } else { $Self->{LogObject}->Log( Priority => 'error', Message => "Could not call method new() on $CodeModule.pm." ); } } 2010-10-14 13:33:21 cvs.intra.cape-it.de IyAtLQojIENIQU5HRVNfQ3VzdG9tZXJDb21wYW55U2VydmljZSAtIGNoYW5nZSBsb2cgb2YgQ3VzdG9tZXJTZXJ2aWNlIG1vZHVsZQojIENvcHlyaWdodCAoQykgMjAwNi0yMDEwIGMuYS5wLmUuIElUIEdtYkgsIGh0dHA6Ly93d3cuY2FwZS1pdC5kZS8KIyAtLQojICRJZDogQ0hBTkdFU19DdXN0b21lckNvbXBhbnlTZXJ2aWNlLHYgMS4zIDIwMTAtMTAtMTQgMTE6MzI6NTAgcmJvIEV4cCAkCiMgLS0KIyBUaGlzIHNvZnR3YXJlIGNvbWVzIHdpdGggQUJTT0xVVEVMWSBOTyBXQVJSQU5UWS4gRm9yIGRldGFpbHMsIHNlZQojIHRoZSBlbmNsb3NlZCBmaWxlIENPUFlJTkcgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24gKEdQTCkuIElmIHlvdQojIGRpZCBub3QgcmVjZWl2ZSB0aGlzIGZpbGUsIHNlZSBodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvZ3BsLTIuMC50eHQuCiMgLS0KCiMtLS0tLS0tLS0tLS0tLS0tLS0tLSAxLjAuMCAtLS0tLS0tLSAoMjAxMC8xMC8xNCkgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyAqIGZpcnN0IHByb2R1Y3Rpb24gcmVsZWFzZQojICogKDIwMTAvMTAvMTQpIC0gYnVnZml4ZWQgaW5zdGFsbGF0aW9uIHByb2NlZHVyZSBhbmQgaW1wbGVtZW50ZWQgSVRTTSBjaGVjawojICogKDIwMTAvMTAvMTQpIC0gYWRkZWQgdHJhbnNsYXRpb25zCiAgCgojLS0tLS0tLS0tLS0tLS0tLS0tLS0gMC4wLjEgLS0tLS0tLS0gKDIwMTAvMTAvMTIpIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgKiBmaXJzdCB0ZXN0IHJlbGVhc2UgIAoK PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pgo8b3Ryc19jb25maWcgdmVyc2lvbj0iMS4wIiBpbml0PSJBcHBsaWNhdGlvbiI+CiAgICA8Q1ZTPiRJZDogQ3VzdG9tZXJDb21wYW55U2VydmljZS54bWwsdiAxLjEgMjAxMC0xMC0wNyAxNjoxNTo1OSByYm8gRXhwICQ8L0NWUz4KICAgIAogICAgPENvbmZpZ0l0ZW0gTmFtZT0iRnJvbnRlbmQ6Ok1vZHVsZSMjI0FkbWluQ3VzdG9tZXJDb21wYW55U2VydmljZSIgUmVxdWlyZWQ9IjAiIFZhbGlkPSIxIj4KICAgICAgICA8RGVzY3JpcHRpb24gTGFuZz0iZW4iPkZyb250ZW5kIG1vZHVsZSByZWdpc3RyYXRpb24gZm9yIHRoZSBBZG1pbkN1c3RvbWVyQ29tcGFueVNlcnZpY2Ugb2JqZWN0IGluIHRoZSBhZG1pbiBhcmVhLjwvRGVzY3JpcHRpb24+CiAgICAgICAgPERlc2NyaXB0aW9uIExhbmc9ImRlIj5Gcm9udGVuZG1vZHVsLVJlZ2lzdHJhdGlvbiBkZXMgQWRtaW5DdXN0b21lckNvbXBhbnlTZXJ2aWNlLU9iamVrdHMgaW0gQWRtaW4tQmVyZWljaC48L0Rlc2NyaXB0aW9uPgogICAgICAgIDxHcm91cD5GcmFtZXdvcms8L0dyb3VwPgogICAgICAgIDxTdWJHcm91cD5Gcm9udGVuZDo6QWRtaW46Ok1vZHVsZVJlZ2lzdHJhdGlvbjwvU3ViR3JvdXA+CiAgICAgICAgPFNldHRpbmc+CiAgICAgICAgICAgIDxGcm9udGVuZE1vZHVsZVJlZz4KICAgICAgICAgICAgICAgIDxHcm91cD5hZG1pbjwvR3JvdXA+CiAgICAgICAgICAgICAgICA8RGVzY3JpcHRpb24+QWRtaW48L0Rlc2NyaXB0aW9uPgogICAgICAgICAgICAgICAgPFRpdGxlPkN1c3RvbWVyIENvbXBhbnkgJmx0Oy0mZ3Q7IFNlcnZpY2VzPC9UaXRsZT4KICAgICAgICAgICAgICAgIDxOYXZCYXJOYW1lPkFkbWluPC9OYXZCYXJOYW1lPgogICAgICAgICAgICAgICAgPE5hdkJhck1vZHVsZT4KICAgICAgICAgICAgICAgICAgICA8TW9kdWxlPktlcm5lbDo6T3V0cHV0OjpIVE1MOjpOYXZCYXJNb2R1bGVBZG1pbjwvTW9kdWxlPgogICAgICAgICAgICAgICAgICAgIDxOYW1lPkN1c3RvbWVyIENvbXBhbnkgJmx0Oy0mZ3Q7IFNlcnZpY2VzPC9OYW1lPgogICAgICAgICAgICAgICAgICAgIDxCbG9jaz5CbG9jazE8L0Jsb2NrPgogICAgICAgICAgICAgICAgICAgIDxQcmlvPjMxNTwvUHJpbz4KICAgICAgICAgICAgICAgIDwvTmF2QmFyTW9kdWxlPgogICAgICAgICAgICA8L0Zyb250ZW5kTW9kdWxlUmVnPgogICAgICAgIDwvU2V0dGluZz4KICAgIDwvQ29uZmlnSXRlbT4KICAgIAo8L290cnNfY29uZmlnPgogICAg IyAtLQojIEtlcm5lbC9MYW5ndWFnZS9kZV9DdXN0b21lckNvbXBhbnlTZXJ2aWNlLnBtIC0gcHJvdmlkZXMgZ2VybWFuIGxhbmd1YWdlIHRyYW5zbGF0aW9uIGZvciBDdXN0b21lckNvbXBhbnlTZXJ2aWNlCiMKIyBDb3B5cmlnaHQgKEMpIDIwMDYtMjAxMCBjLmEucC5lLiBJVCBHbWJILCBodHRwOi8vd3d3LmNhcGUtaXQuZGUKIyAtLQojICRJZDogZGVfQ3VzdG9tZXJDb21wYW55U2VydmljZS5wbSx2IDEuMSAyMDEwLTEwLTE0IDExOjMxOjQ0IHJibyBFeHAgJAojIC0tCiMgVGhpcyBzb2Z0d2FyZSBjb21lcyB3aXRoIEFCU09MVVRFTFkgTk8gV0FSUkFOVFkuIEZvciBkZXRhaWxzLCBzZWUKIyB0aGUgZW5jbG9zZWQgZmlsZSBDT1BZSU5HIGZvciBsaWNlbnNlIGluZm9ybWF0aW9uIChHUEwpLiBJZiB5b3UKIyBkaWQgbm90IHJlY2VpdmUgdGhpcyBmaWxlLCBzZWUgaHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2dwbC0yLjAudHh0LgojIC0tCnBhY2thZ2UgS2VybmVsOjpMYW5ndWFnZTo6ZGVfQ3VzdG9tZXJDb21wYW55U2VydmljZTsKCnVzZSBzdHJpY3Q7Cgp1c2UgdmFycyBxdygkVkVSU0lPTik7CiRWRVJTSU9OID0gJyRSZXZpc2lvbjogMS4xICQnOwokVkVSU0lPTiA9fiBzL15cJC4qOlxXKC4qKVxXLis/JC8kMS87CgojIC0tCnN1YiBEYXRhIHsKICAgIG15ICRTZWxmICA9IHNoaWZ0OwogICAgbXkgJVBhcmFtID0gQF87CgogICAgJFNlbGYtPntUcmFuc2xhdGlvbn0tPnsnQ3VzdG9tZXIgQ29tcGFueSA8LT4gU2VydmljZXMnfSA9ICdLdW5kZW4tRmlybWEgPC0+IFNlcnZpY2VzJzsKICAgICRTZWxmLT57VHJhbnNsYXRpb259LT57J0N1c3RvbWVyIENvbXBhbnkgPC0+IFNlcnZpY2VzIE1hbmFnZW1lbnQnfSA9CiAgICAgICAgJ0t1bmRlbi1GaXJtYSA8LT4gU2VydmljZXMgVmVyd2FsdHVuZyc7CiAgICAkU2VsZi0+e1RyYW5zbGF0aW9ufS0+eydBbGxvY2F0ZSBzZXJ2aWNlcyB0byBDdXN0b21lciBDb21wYW55J30gPQogICAgICAgICdTZXJ2aWNlcyB6dW9yZG5lbiB6dXIgS3VuZGVuLUZpcm1hJzsKICAgICRTZWxmLT57VHJhbnNsYXRpb259LT57J0FsbG9jYXRlIEN1c3RvbWVyIENvbXBhbnkgdG8gU2VydmljZSd9ID0KICAgICAgICAnS3VuZGVuLUZpcm1hIHp1b3JkbmVuIHp1IFNlcnZpY2UnOwp9CgojIC0tCjE7Cg== IyAtLQojIEtlcm5lbC9Nb2R1bGVzL0FkbWluQ3VzdG9tZXJDb21wYW55U2VydmljZS5wbSAtIHRvIGFkZC91cGRhdGUvZGVsZXRlIGN1c3RvbWVycyA8LT4gc2VydmljZXMKIyBvcmlnaW5hbCBDb3B5cmlnaHQgKEMpIDIwMDEtMjAwOSBPVFJTIEFHLCBodHRwOi8vb3Rycy5vcmcvCiMKIyBFeHRlbnNpb25zIENvcHlyaWdodCAoQykgMjAwNi0yMDEwIGMuYS5wLmUuIElUIEdtYkgsIGh0dHA6Ly93d3cuY2FwZS1pdC5kZQojCiMgd3JpdHRlbi9lZGl0ZWQgYnk6CiMgICBSZW5lKGRvdClCb2VobShhdCljYXBlLWl0LmRlCiMKIyAtLQojICRJZDogQWRtaW5DdXN0b21lckNvbXBhbnlTZXJ2aWNlLnBtLHYgMS4xIDIwMTAtMTAtMDcgMTY6MTU6NTkgcmJvIEV4cCAkCiMgLS0KIyBUaGlzIHNvZnR3YXJlIGNvbWVzIHdpdGggQUJTT0xVVEVMWSBOTyBXQVJSQU5UWS4gRm9yIGRldGFpbHMsIHNlZQojIHRoZSBlbmNsb3NlZCBmaWxlIENPUFlJTkcgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24gKEFHUEwpLiBJZiB5b3UKIyBkaWQgbm90IHJlY2VpdmUgdGhpcyBmaWxlLCBzZWUgaHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwudHh0LgojIC0tCgpwYWNrYWdlIEtlcm5lbDo6TW9kdWxlczo6QWRtaW5DdXN0b21lckNvbXBhbnlTZXJ2aWNlOwoKdXNlIHN0cmljdDsKdXNlIHdhcm5pbmdzOwoKIyBjYXBlSVQKdXNlIEtlcm5lbDo6U3lzdGVtOjpDdXN0b21lckNvbXBhbnk7CgojIEVPIGNhcGVJVAp1c2UgS2VybmVsOjpTeXN0ZW06OlNlcnZpY2U7CnVzZSBLZXJuZWw6OlN5c3RlbTo6VmFsaWQ7Cgp1c2UgdmFycyBxdygkVkVSU0lPTik7CiRWRVJTSU9OID0gcXcoJFJldmlzaW9uOiAxLjEgJCkgWzFdOwoKc3ViIG5ldyB7CiAgICBteSAoICRUeXBlLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgYWxsb2NhdGUgbmV3IGhhc2ggZm9yIG9iamVjdAogICAgbXkgJFNlbGYgPSB7JVBhcmFtfTsKICAgIGJsZXNzKCAkU2VsZiwgJFR5cGUgKTsKCiAgICAjIGNoZWNrIGFsbCBuZWVkZWQgb2JqZWN0cwogICAgZm9yIChxdyhQYXJhbU9iamVjdCBEQk9iamVjdCBMYXlvdXRPYmplY3QgQ29uZmlnT2JqZWN0IExvZ09iamVjdCkpIHsKICAgICAgICBpZiAoICEkU2VsZi0+eyRffSApIHsKICAgICAgICAgICAgJFNlbGYtPntMYXlvdXRPYmplY3R9LT5GYXRhbEVycm9yKCBNZXNzYWdlID0+ICJHb3Qgbm8gJF8hIiApOwogICAgICAgIH0KICAgIH0KCiAgICAjIGNhcGVJVAogICAgJFNlbGYtPntDdXN0b21lckNvbXBhbnlPYmplY3R9ID0gS2VybmVsOjpTeXN0ZW06OkN1c3RvbWVyQ29tcGFueS0+bmV3KCVQYXJhbSk7CgogICAgIyBFTyBjYXBlSVQKICAgICRTZWxmLT57U2VydmljZU9iamVjdH0gPSBLZXJuZWw6OlN5c3RlbTo6U2VydmljZS0+bmV3KCVQYXJhbSk7CiAgICAkU2VsZi0+e1ZhbGlkT2JqZWN0fSAgID0gS2VybmVsOjpTeXN0ZW06OlZhbGlkLT5uZXcoJVBhcmFtKTsKCiAgICByZXR1cm4gJFNlbGY7Cn0KCnN1YiBSdW4gewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICAjIHNldCBzZWFyY2ggbGltaXQKICAgIG15ICRTZWFyY2hMaW1pdCA9IDIwMDsKCiAgICAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAjCiAgICAjIGFsbG9jYXRlIGN1c3RvbWVyIHVzZXIKICAgICMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICMKICAgICMgY2FwZUlUCiAgICBpZiAoICRTZWxmLT57U3ViYWN0aW9ufSBlcSAnQWxsb2NhdGVDdXN0b21lckNvbXBhbnknICkgewoKICAgICAgICAjIGdldCBwYXJhbXMKICAgICAgICAkUGFyYW17Q3VzdG9tZXJJRH0gPSAkU2VsZi0+e1BhcmFtT2JqZWN0fS0+R2V0UGFyYW0oIFBhcmFtID0+ICdDdXN0b21lcklEJyApCiAgICAgICAgICAgIHx8ICc8REVGQVVMVD4nOwogICAgICAgICRQYXJhbXtDdXN0b21lckNvbXBhbnlTZWFyY2h9ID0KICAgICAgICAgICAgJFNlbGYtPntQYXJhbU9iamVjdH0tPkdldFBhcmFtKCBQYXJhbSA9PiAnQ3VzdG9tZXJDb21wYW55U2VhcmNoJyApCiAgICAgICAgICAgIHx8ICcqJzsKCiAgICAgICAgIyBFTyBjYXBlSVQKICAgICAgICAkUGFyYW17U2VydmljZVNlYXJjaH0gPSAkU2VsZi0+e1BhcmFtT2JqZWN0fS0+R2V0UGFyYW0oIFBhcmFtID0+ICdTZXJ2aWNlU2VhcmNoJyApIHx8ICcqJzsKCiAgICAgICAgIyBvdXRwdXQgaGVhZGVyCiAgICAgICAgbXkgJE91dHB1dCA9ICRTZWxmLT57TGF5b3V0T2JqZWN0fS0+SGVhZGVyKCk7CiAgICAgICAgJE91dHB1dCAuPSAkU2VsZi0+e0xheW91dE9iamVjdH0tPk5hdmlnYXRpb25CYXIoKTsKCiAgICAgICAgIyBvdXRwdXQgc2VhcmNoIGJsb2NrCiAgICAgICAgJFNlbGYtPntMYXlvdXRPYmplY3R9LT5CbG9jaygKICAgICAgICAgICAgTmFtZSA9PiAnU2VhcmNoJywKICAgICAgICAgICAgRGF0YSA9PiB7CiAgICAgICAgICAgICAgICAlUGFyYW0sCgogICAgICAgICAgICAgICAgIyBjYXBlSVQKICAgICAgICAgICAgICAgIEN1c3RvbWVyQ29tcGFueVNlYXJjaCA9PiAkUGFyYW17Q3VzdG9tZXJDb21wYW55U2VhcmNofSwKCiAgICAgICAgICAgICAgICAjIEVPIGNhcGVJVAogICAgICAgICAgICAgICAgU2VydmljZVNlYXJjaCA9PiAkUGFyYW17U2VydmljZVNlYXJjaH0sCiAgICAgICAgICAgIH0sCiAgICAgICAgKTsKCiAgICAgICAgIyBvdXRwdXQgZGVmYXVsdCBibG9jawogICAgICAgICRTZWxmLT57TGF5b3V0T2JqZWN0fS0+QmxvY2soIE5hbWUgPT4gJ0RlZmF1bHQnLCApOwoKICAgICAgICAjIGdldCBzZXJ2aWNlIG1lbWJlcgogICAgICAgICMgY2FwZUlUCiAgICAgICAgbXkgJVNlcnZpY2VNZW1iZXJMaXN0ID0gJFNlbGYtPntTZXJ2aWNlT2JqZWN0fS0+Q3VzdG9tZXJDb21wYW55U2VydmljZU1lbWJlckxpc3QoCiAgICAgICAgICAgIEN1c3RvbWVySUQgICAgICA9PiAkUGFyYW17Q3VzdG9tZXJJRH0sCiAgICAgICAgICAgIFJlc3VsdCAgICAgICAgICA9PiAnSEFTSCcsCiAgICAgICAgICAgIERlZmF1bHRTZXJ2aWNlcyA9PiAwLAogICAgICAgICk7CgogICAgICAgICMgRU8gY2FwZUlUCgogICAgICAgICMgc2VhcmNoIHNlcnZpY2VzCiAgICAgICAgbXkgQFNlcnZpY2VMaXN0ID0gJFNlbGYtPntTZXJ2aWNlT2JqZWN0fS0+U2VydmljZVNlYXJjaCgKICAgICAgICAgICAgTmFtZSAgID0+ICRQYXJhbXtTZXJ2aWNlU2VhcmNofSwKICAgICAgICAgICAgTGltaXQgID0+ICRTZWFyY2hMaW1pdCArIDEsCiAgICAgICAgICAgIFVzZXJJRCA9PiAkU2VsZi0+e1VzZXJJRH0sCiAgICAgICAgKTsKCiAgICAgICAgIyBzZXQgbWF4IGNvdW50CiAgICAgICAgbXkgJE1heENvdW50ID0gQFNlcnZpY2VMaXN0OwogICAgICAgIGlmICggJE1heENvdW50ID4gJFNlYXJjaExpbWl0ICkgewogICAgICAgICAgICAkTWF4Q291bnQgPSAkU2VhcmNoTGltaXQ7CiAgICAgICAgfQoKICAgICAgICAjIGNhcGVJVAogICAgICAgICMgb3V0cHV0IGFsbG9jYXRlIGJsb2NrCiAgICAgICAgJFNlbGYtPntMYXlvdXRPYmplY3R9LT5CbG9jaygKICAgICAgICAgICAgTmFtZSA9PiAnQWxsb2NhdGVDdXN0b21lckNvbXBhbnknLAogICAgICAgICAgICBEYXRhID0+IHsKICAgICAgICAgICAgICAgIEN1c3RvbWVyQ29tcGFueSA9PiAkUGFyYW17Q3VzdG9tZXJDb21wYW55TG9naW59LAogICAgICAgICAgICAgICAgU2VydmljZUNvdW50ID0+IEBTZXJ2aWNlTGlzdCB8fCAwLAogICAgICAgICAgICAgICAgJVBhcmFtLAogICAgICAgICAgICB9LAogICAgICAgICk7CgogICAgICAgICMgb3V0cHV0IGNvdW50IGJsb2NrCiAgICAgICAgaWYgKCAhQFNlcnZpY2VMaXN0ICkgewogICAgICAgICAgICAkU2VsZi0+e0xheW91dE9iamVjdH0tPkJsb2NrKAogICAgICAgICAgICAgICAgTmFtZSA9PiAnQWxsb2NhdGVDdXN0b21lckNvbXBhbnlTZXJ2aWNlQ291bnRMaW1pdCcsCiAgICAgICAgICAgICAgICBEYXRhID0+IHsgU2VydmljZUNvdW50ID0+IDAsIH0sCiAgICAgICAgICAgICk7CiAgICAgICAgfQogICAgICAgIGVsc2lmICggQFNlcnZpY2VMaXN0ID4gJFNlYXJjaExpbWl0ICkgewogICAgICAgICAgICAkU2VsZi0+e0xheW91dE9iamVjdH0tPkJsb2NrKAogICAgICAgICAgICAgICAgTmFtZSA9PiAnQWxsb2NhdGVDdXN0b21lckNvbXBhbnlTZXJ2aWNlQ291bnRMaW1pdCcsCiAgICAgICAgICAgICAgICBEYXRhID0+IHsgU2VydmljZUNvdW50ID0+ICI+IiAuICRTZWFyY2hMaW1pdCwgfSwKICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICRTZWxmLT57TGF5b3V0T2JqZWN0fS0+QmxvY2soCiAgICAgICAgICAgICAgICBOYW1lID0+ICdBbGxvY2F0ZUN1c3RvbWVyQ29tcGFueVNlcnZpY2VDb3VudCcsCiAgICAgICAgICAgICAgICBEYXRhID0+IHsgU2VydmljZUNvdW50ID0+IHNjYWxhciBAU2VydmljZUxpc3QsIH0sCiAgICAgICAgICAgICk7CiAgICAgICAgfQoKICAgICAgICAjIEVPIGNhcGVJVAoKICAgICAgICBteSAkQ3NzOwoKICAgICAgICAjIG91dHB1dCByb3dzCiAgICAgICAgZm9yIG15ICRDb3VudGVyICggMSAuLiAkTWF4Q291bnQgKSB7CgogICAgICAgICAgICAjIHNldCBvdXRwdXQgY2xhc3MKICAgICAgICAgICAgJENzcyA9ICRDc3MgJiYgJENzcyBlcSAnc2VhcmNoYWN0aXZlJyA/ICdzZWFyY2hwYXNzaXZlJyA6ICdzZWFyY2hhY3RpdmUnOwoKICAgICAgICAgICAgIyBnZXQgc2VydmljZQogICAgICAgICAgICBteSAlU2VydmljZSA9ICRTZWxmLT57U2VydmljZU9iamVjdH0tPlNlcnZpY2VHZXQoCiAgICAgICAgICAgICAgICBTZXJ2aWNlSUQgPT4gJFNlcnZpY2VMaXN0WyAkQ291bnRlciAtIDEgXSwKICAgICAgICAgICAgICAgIFVzZXJJRCAgICA9PiAkU2VsZi0+e1VzZXJJRH0sCiAgICAgICAgICAgICk7CgogICAgICAgICAgICAjIHNldCBjaGVja2VkCiAgICAgICAgICAgIG15ICRDaGVja2VkID0gJFNlcnZpY2VNZW1iZXJMaXN0eyAkU2VydmljZXtTZXJ2aWNlSUR9IH0gPyAnY2hlY2tlZCcgOiAnJzsKCiAgICAgICAgICAgICMgY2FwZUlUCiAgICAgICAgICAgICMgb3V0cHV0IHJvdyBibG9jawogICAgICAgICAgICAkU2VsZi0+e0xheW91dE9iamVjdH0tPkJsb2NrKAogICAgICAgICAgICAgICAgTmFtZSA9PiAnQWxsb2NhdGVDdXN0b21lckNvbXBhbnlSb3cnLAogICAgICAgICAgICAgICAgRGF0YSA9PiB7CiAgICAgICAgICAgICAgICAgICAgU2VydmljZSAgID0+ICRTZXJ2aWNle05hbWV9LAogICAgICAgICAgICAgICAgICAgIFNlcnZpY2VJRCA9PiAkU2VydmljZXtTZXJ2aWNlSUR9LAogICAgICAgICAgICAgICAgICAgIENoZWNrZWQgICA9PiAkQ2hlY2tlZCwKICAgICAgICAgICAgICAgICAgICBDc3NDbGFzcyAgPT4gJENzcywKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICk7CgogICAgICAgICAgICAjIEVPIGNhcGVJVAogICAgICAgIH0KCiAgICAgICAgIyBnZW5lcmF0ZSBvdXRwdXQKICAgICAgICAjIGNhcGVJVAogICAgICAgICRPdXRwdXQgLj0gJFNlbGYtPntMYXlvdXRPYmplY3R9LT5PdXRwdXQoCiAgICAgICAgICAgIFRlbXBsYXRlRmlsZSA9PiAnQWRtaW5DdXN0b21lckNvbXBhbnlTZXJ2aWNlJywKICAgICAgICAgICAgRGF0YSAgICAgICAgID0+IFwlUGFyYW0sCiAgICAgICAgKTsKCiAgICAgICAgIyBFTyBjYXBlSVQKICAgICAgICAkT3V0cHV0IC49ICRTZWxmLT57TGF5b3V0T2JqZWN0fS0+Rm9vdGVyKCk7CgogICAgICAgIHJldHVybiAkT3V0cHV0OwogICAgfQoKICAgICMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICMKICAgICMgYWxsb2NhdGUgc2VydmljZQogICAgIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gIwogICAgZWxzaWYgKCAkU2VsZi0+e1N1YmFjdGlvbn0gZXEgJ0FsbG9jYXRlU2VydmljZScgKSB7CgogICAgICAgICMgY2FwZUlUCiAgICAgICAgIyBnZXQgcGFyYW1zCiAgICAgICAgJFBhcmFte1NlcnZpY2VJRH0gPSAkU2VsZi0+e1BhcmFtT2JqZWN0fS0+R2V0UGFyYW0oIFBhcmFtID0+ICJTZXJ2aWNlSUQiICk7CiAgICAgICAgJFBhcmFte0N1c3RvbWVyQ29tcGFueVNlYXJjaH0gPQogICAgICAgICAgICAkU2VsZi0+e1BhcmFtT2JqZWN0fS0+R2V0UGFyYW0oIFBhcmFtID0+ICJDdXN0b21lckNvbXBhbnlTZWFyY2giICkKICAgICAgICAgICAgfHwgJyonOwoKICAgICAgICAjIEVPIGNhcGVJVAogICAgICAgICRQYXJhbXtTZXJ2aWNlU2VhcmNofSA9ICRTZWxmLT57UGFyYW1PYmplY3R9LT5HZXRQYXJhbSggUGFyYW0gPT4gIlNlcnZpY2VTZWFyY2giICkgfHwgJyonOwoKICAgICAgICAjIG91dHB1dCBoZWFkZXIKICAgICAgICBteSAkT3V0cHV0ID0gJFNlbGYtPntMYXlvdXRPYmplY3R9LT5IZWFkZXIoKTsKICAgICAgICAkT3V0cHV0IC49ICRTZWxmLT57TGF5b3V0T2JqZWN0fS0+TmF2aWdhdGlvbkJhcigpOwoKICAgICAgICAjIGNhcGVJVAogICAgICAgICMgb3V0cHV0IHNlYXJjaCBibG9jawogICAgICAgICRTZWxmLT57TGF5b3V0T2JqZWN0fS0+QmxvY2soCiAgICAgICAgICAgIE5hbWUgPT4gJ1NlYXJjaCcsCiAgICAgICAgICAgIERhdGEgPT4gewogICAgICAgICAgICAgICAgJVBhcmFtLAogICAgICAgICAgICAgICAgQ3VzdG9tZXJDb21wYW55U2VhcmNoID0+ICRQYXJhbXtDdXN0b21lckNvbXBhbnlTZWFyY2h9LAogICAgICAgICAgICAgICAgU2VydmljZVNlYXJjaCAgICAgICAgID0+ICRQYXJhbXtTZXJ2aWNlU2VhcmNofSwKICAgICAgICAgICAgfSwKICAgICAgICApOwoKICAgICAgICAjIEVPIGNhcGVJVAoKICAgICAgICAjIG91dHB1dCBkZWZhdWx0IGJsb2NrCiAgICAgICAgJFNlbGYtPntMYXlvdXRPYmplY3R9LT5CbG9jayggTmFtZSA9PiAnRGVmYXVsdCcsICk7CgogICAgICAgICMgZ2V0IHNlcnZpY2UKICAgICAgICBteSAlU2VydmljZSA9ICRTZWxmLT57U2VydmljZU9iamVjdH0tPlNlcnZpY2VHZXQoCiAgICAgICAgICAgIFNlcnZpY2VJRCA9PiAkUGFyYW17U2VydmljZUlEfSwKICAgICAgICAgICAgVXNlcklEICAgID0+ICRTZWxmLT57VXNlcklEfSwKICAgICAgICApOwoKICAgICAgICAjIGNhcGVJVAogICAgICAgICMgZ2V0IGN1c3RvbWVyIGNvbXBhbnkgbWVtYmVyCiAgICAgICAgbXkgJUN1c3RvbWVyQ29tcGFueU1lbWJlckxpc3QgPSAkU2VsZi0+e1NlcnZpY2VPYmplY3R9LT5DdXN0b21lckNvbXBhbnlTZXJ2aWNlTWVtYmVyTGlzdCgKICAgICAgICAgICAgU2VydmljZUlEICAgICAgID0+ICRQYXJhbXtTZXJ2aWNlSUR9LAogICAgICAgICAgICBSZXN1bHQgICAgICAgICAgPT4gJ0hBU0gnLAogICAgICAgICAgICBEZWZhdWx0U2VydmljZXMgPT4gMCwKICAgICAgICApOwoKICAgICAgICAjIHNlYXJjaCBjdXN0b21lciBjb21wYW55CiAgICAgICAgbXkgJUN1c3RvbWVyQ29tcGFueUxpc3QKICAgICAgICAgICAgPSAkU2VsZi0+e0N1c3RvbWVyQ29tcGFueU9iamVjdH0KICAgICAgICAgICAgLT5DdXN0b21lckNvbXBhbnlMaXN0KCBTZWFyY2ggPT4gJFBhcmFte0N1c3RvbWVyQ29tcGFueVNlYXJjaH0sICk7CiAgICAgICAgbXkgQEN1c3RvbWVyQ29tcGFueUtleUxpc3QKICAgICAgICAgICAgPSBzb3J0IHsgJEN1c3RvbWVyQ29tcGFueUxpc3R7JGF9IGNtcCAkQ3VzdG9tZXJDb21wYW55TGlzdHskYn0gfQogICAgICAgICAgICBrZXlzICVDdXN0b21lckNvbXBhbnlMaXN0OwoKICAgICAgICAjIHNldCBtYXggY291bnQKICAgICAgICBteSAkTWF4Q291bnQgPSBAQ3VzdG9tZXJDb21wYW55S2V5TGlzdDsKICAgICAgICBpZiAoICRNYXhDb3VudCA+ICRTZWFyY2hMaW1pdCApIHsKICAgICAgICAgICAgJE1heENvdW50ID0gJFNlYXJjaExpbWl0OwogICAgICAgIH0KCiAgICAgICAgIyBvdXRwdXQgYWxsb2NhdGUgYmxvY2sKICAgICAgICAkU2VsZi0+e0xheW91dE9iamVjdH0tPkJsb2NrKAogICAgICAgICAgICBOYW1lID0+ICdBbGxvY2F0ZVNlcnZpY2UnLAogICAgICAgICAgICBEYXRhID0+IHsKICAgICAgICAgICAgICAgIFNlcnZpY2UgPT4gJFNlcnZpY2V7TmFtZX0sCiAgICAgICAgICAgICAgICBDdXN0b21lckNvbXBhbnlDb3VudCA9PiBAQ3VzdG9tZXJDb21wYW55S2V5TGlzdCB8fCAwLAogICAgICAgICAgICAgICAgJVBhcmFtLAogICAgICAgICAgICB9LAogICAgICAgICk7CgogICAgICAgICMgb3V0cHV0IGNvdW50IGJsb2NrCiAgICAgICAgaWYgKCAhQEN1c3RvbWVyQ29tcGFueUtleUxpc3QgKSB7CiAgICAgICAgICAgICRTZWxmLT57TGF5b3V0T2JqZWN0fS0+QmxvY2soCiAgICAgICAgICAgICAgICBOYW1lID0+ICdBbGxvY2F0ZVNlcnZpY2VDdXN0b21lckNvbXBhbnlDb3VudExpbWl0JywKICAgICAgICAgICAgICAgIERhdGEgPT4geyBDdXN0b21lckNvbXBhbnlDb3VudCA9PiAwLCB9LAogICAgICAgICAgICApOwogICAgICAgIH0KICAgICAgICBlbHNpZiAoIEBDdXN0b21lckNvbXBhbnlLZXlMaXN0ID4gJFNlYXJjaExpbWl0ICkgewogICAgICAgICAgICAkU2VsZi0+e0xheW91dE9iamVjdH0tPkJsb2NrKAogICAgICAgICAgICAgICAgTmFtZSA9PiAnQWxsb2NhdGVTZXJ2aWNlQ3VzdG9tZXJDb21wYW55Q291bnRMaW1pdCcsCiAgICAgICAgICAgICAgICBEYXRhID0+IHsgQ3VzdG9tZXJDb21wYW55Q291bnQgPT4gIj4iIC4gJFNlYXJjaExpbWl0LCB9LAogICAgICAgICAgICApOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgJFNlbGYtPntMYXlvdXRPYmplY3R9LT5CbG9jaygKICAgICAgICAgICAgICAgIE5hbWUgPT4gJ0FsbG9jYXRlU2VydmljZUN1c3RvbWVyQ29tcGFueUNvdW50JywKICAgICAgICAgICAgICAgIERhdGEgPT4geyBDdXN0b21lckNvbXBhbnlDb3VudCA9PiBzY2FsYXIgQEN1c3RvbWVyQ29tcGFueUtleUxpc3QsIH0sCiAgICAgICAgICAgICk7CiAgICAgICAgfQoKICAgICAgICAjIEVPIGNhcGVJVAoKICAgICAgICAjIG91dHB1dCByb3dzCiAgICAgICAgbXkgJENzczsKICAgICAgICBmb3IgbXkgJENvdW50ZXIgKCAxIC4uICRNYXhDb3VudCApIHsKCiAgICAgICAgICAgICMgc2V0IG91dHB1dCBjbGFzcwogICAgICAgICAgICAkQ3NzID0gJENzcyAmJiAkQ3NzIGVxICdzZWFyY2hhY3RpdmUnID8gJ3NlYXJjaHBhc3NpdmUnIDogJ3NlYXJjaGFjdGl2ZSc7CgogICAgICAgICAgICAjIGNhcGVJVAogICAgICAgICAgICAjIHNldCBjaGVja2VkCiAgICAgICAgICAgIG15ICRDaGVja2VkCiAgICAgICAgICAgICAgICA9ICRDdXN0b21lckNvbXBhbnlNZW1iZXJMaXN0eyAkQ3VzdG9tZXJDb21wYW55S2V5TGlzdFsgJENvdW50ZXIgLSAxIF0gfQogICAgICAgICAgICAgICAgPyAnY2hlY2tlZCcKICAgICAgICAgICAgICAgIDogJyc7CgogICAgICAgICAgICAjIG91dHB1dCByb3cgYmxvY2sKICAgICAgICAgICAgJFNlbGYtPntMYXlvdXRPYmplY3R9LT5CbG9jaygKICAgICAgICAgICAgICAgIE5hbWUgPT4gJ0FsbG9jYXRlU2VydmljZVJvdycsCiAgICAgICAgICAgICAgICBEYXRhID0+IHsKICAgICAgICAgICAgICAgICAgICBDdXN0b21lckNvbXBhbnlMb2dpbiA9PiAkQ3VzdG9tZXJDb21wYW55S2V5TGlzdFsgJENvdW50ZXIgLSAxIF0sCiAgICAgICAgICAgICAgICAgICAgQ3VzdG9tZXJDb21wYW55ID0+CiAgICAgICAgICAgICAgICAgICAgICAgICRDdXN0b21lckNvbXBhbnlMaXN0eyAkQ3VzdG9tZXJDb21wYW55S2V5TGlzdFsgJENvdW50ZXIgLSAxIF0gfSwKICAgICAgICAgICAgICAgICAgICBDaGVja2VkICA9PiAkQ2hlY2tlZCwKICAgICAgICAgICAgICAgICAgICBDc3NDbGFzcyA9PiAkQ3NzLAogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgKTsKICAgICAgICB9CgogICAgICAgICMgZ2VuZXJhdGUgb3V0cHV0CiAgICAgICAgJE91dHB1dCAuPSAkU2VsZi0+e0xheW91dE9iamVjdH0tPk91dHB1dCgKICAgICAgICAgICAgVGVtcGxhdGVGaWxlID0+ICdBZG1pbkN1c3RvbWVyQ29tcGFueVNlcnZpY2UnLAogICAgICAgICAgICBEYXRhICAgICAgICAgPT4gXCVQYXJhbSwKICAgICAgICApOwoKICAgICAgICAjIEVPIGNhcGVJVAogICAgICAgICRPdXRwdXQgLj0gJFNlbGYtPntMYXlvdXRPYmplY3R9LT5Gb290ZXIoKTsKCiAgICAgICAgcmV0dXJuICRPdXRwdXQ7CiAgICB9CgogICAgIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gIwogICAgIyBhbGxvY2F0ZSBjdXN0b21lciB1c2VyIHNhdmUKICAgICMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICMKICAgIGVsc2lmICggJFNlbGYtPntTdWJhY3Rpb259IGVxICdBbGxvY2F0ZUN1c3RvbWVyQ29tcGFueVNhdmUnICkgewoKICAgICAgICAjIGNhcGVJVAogICAgICAgICMgZ2V0IHBhcmFtcwogICAgICAgICRQYXJhbXtDdXN0b21lcklEfSA9ICRTZWxmLT57UGFyYW1PYmplY3R9LT5HZXRQYXJhbSggUGFyYW0gPT4gJ0N1c3RvbWVySUQnICk7CiAgICAgICAgJFBhcmFte0N1c3RvbWVyQ29tcGFueVNlYXJjaH0gPQogICAgICAgICAgICAkU2VsZi0+e1BhcmFtT2JqZWN0fS0+R2V0UGFyYW0oIFBhcmFtID0+ICdDdXN0b21lckNvbXBhbnlTZWFyY2gnICkKICAgICAgICAgICAgfHwgJyonOwoKICAgICAgICAjIEVPIGNhcGVJVAogICAgICAgICRQYXJhbXtTZXJ2aWNlU2VhcmNofSA9ICRTZWxmLT57UGFyYW1PYmplY3R9LT5HZXRQYXJhbSggUGFyYW0gPT4gJ1NlcnZpY2VTZWFyY2gnICkgfHwgJyonOwogICAgICAgIG15IEBTZXJ2aWNlSURzU2VsZWN0ZWQgPSAkU2VsZi0+e1BhcmFtT2JqZWN0fS0+R2V0QXJyYXkoIFBhcmFtID0+ICdTZXJ2aWNlSURzU2VsZWN0ZWQnICk7CiAgICAgICAgbXkgQFNlcnZpY2VJRHNBbGwgICAgICA9ICRTZWxmLT57UGFyYW1PYmplY3R9LT5HZXRBcnJheSggUGFyYW0gPT4gJ1NlcnZpY2VJRHNBbGwnICk7CgogICAgICAgICMgY3JlYXRlIGhhc2ggd2l0aCBzZWxlY3RlZCBpZHMKICAgICAgICBteSAlU2VydmljZUlEU2VsZWN0ZWQgPSBtYXAgeyAkXyA9PiAxIH0gQFNlcnZpY2VJRHNTZWxlY3RlZDsKCiAgICAgICAgIyBjaGVjayBhbGwgdXNlZCBzZXJ2aWNlIGlkcwogICAgICAgIGZvciBteSAkU2VydmljZUlEIChAU2VydmljZUlEc0FsbCkgewogICAgICAgICAgICBteSAkQWN0aXZlID0gJFNlcnZpY2VJRFNlbGVjdGVkeyRTZXJ2aWNlSUR9ID8gMSA6IDA7CgogICAgICAgICAgICAjIGNhcGVJVAogICAgICAgICAgICAjIHNldCBjdXN0b21lciBjb21wYW55IHNlcnZpY2UgbWVtYmVyCiAgICAgICAgICAgICRTZWxmLT57U2VydmljZU9iamVjdH0tPkN1c3RvbWVyQ29tcGFueVNlcnZpY2VNZW1iZXJBZGQoCiAgICAgICAgICAgICAgICBDdXN0b21lcklEID0+ICRQYXJhbXtDdXN0b21lcklEfSwKICAgICAgICAgICAgICAgIFNlcnZpY2VJRCAgPT4gJFNlcnZpY2VJRCwKICAgICAgICAgICAgICAgIEFjdGl2ZSAgICAgPT4gJEFjdGl2ZSwKICAgICAgICAgICAgICAgIFVzZXJJRCAgICAgPT4gJFNlbGYtPntVc2VySUR9LAogICAgICAgICAgICApOwogICAgICAgIH0KCiAgICAgICAgIyByZWRpcmVjdCB0byBvdmVydmlldwogICAgICAgIHJldHVybiAkU2VsZi0+e0xheW91dE9iamVjdH0tPlJlZGlyZWN0KAogICAgICAgICAgICBPUCA9PgogICAgICAgICAgICAgICAgIkFjdGlvbj0kU2VsZi0+e0FjdGlvbn0mQ3VzdG9tZXJDb21wYW55U2VhcmNoPSRQYXJhbXtDdXN0b21lckNvbXBhbnlTZWFyY2h9JlNlcnZpY2VTZWFyY2g9JFBhcmFte1NlcnZpY2VTZWFyY2h9IgogICAgICAgICk7CgogICAgICAgICMgRU8gY2FwZUlUCiAgICB9CgogICAgIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gIwogICAgIyBhbGxvY2F0ZSBzZXJ2aWNlIHNhdmUKICAgICMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICMKICAgIGVsc2lmICggJFNlbGYtPntTdWJhY3Rpb259IGVxICdBbGxvY2F0ZVNlcnZpY2VTYXZlJyApIHsKCiAgICAgICAgIyBjYXBlSVQKICAgICAgICAjIGdldCBwYXJhbXMKICAgICAgICAkUGFyYW17U2VydmljZUlEfSA9ICRTZWxmLT57UGFyYW1PYmplY3R9LT5HZXRQYXJhbSggUGFyYW0gPT4gJ1NlcnZpY2VJRCcgKTsKICAgICAgICAkUGFyYW17Q3VzdG9tZXJDb21wYW55U2VhcmNofSA9CiAgICAgICAgICAgICRTZWxmLT57UGFyYW1PYmplY3R9LT5HZXRQYXJhbSggUGFyYW0gPT4gJ0N1c3RvbWVyQ29tcGFueVNlYXJjaCcgKQogICAgICAgICAgICB8fCAnKic7CgogICAgICAgICMgRU8gY2FwZUlUCiAgICAgICAgJFBhcmFte1NlcnZpY2VTZWFyY2h9ID0gJFNlbGYtPntQYXJhbU9iamVjdH0tPkdldFBhcmFtKCBQYXJhbSA9PiAnU2VydmljZVNlYXJjaCcgKSB8fCAnKic7CgogICAgICAgICMgY2FwZUlUCiAgICAgICAgbXkgQEN1c3RvbWVySURzU2VsZWN0ZWQKICAgICAgICAgICAgPSAkU2VsZi0+e1BhcmFtT2JqZWN0fS0+R2V0QXJyYXkoIFBhcmFtID0+ICdDdXN0b21lcklEc1NlbGVjdGVkJyApOwogICAgICAgIG15IEBDdXN0b21lcklEc0FsbAogICAgICAgICAgICA9ICRTZWxmLT57UGFyYW1PYmplY3R9LT5HZXRBcnJheSggUGFyYW0gPT4gJ0N1c3RvbWVySURzQWxsJyApOwoKICAgICAgICAjIGNyZWF0ZSBoYXNoIHdpdGggc2VsZWN0ZWQgY3VzdG9tZXIgY29tcGFuaWVzCiAgICAgICAgbXkgJUN1c3RvbWVySURzU2VsZWN0ZWQ7CiAgICAgICAgZm9yIG15ICRDdXN0b21lcklEIChAQ3VzdG9tZXJJRHNTZWxlY3RlZCkgewogICAgICAgICAgICAkQ3VzdG9tZXJJRHNTZWxlY3RlZHskQ3VzdG9tZXJJRH0gPSAxOwogICAgICAgIH0KCiAgICAgICAgIyBjaGVjayBhbGwgdXNlZCBjdXN0b21lciBjb21wYW5pZXMKICAgICAgICBmb3IgbXkgJEN1c3RvbWVySUQgKEBDdXN0b21lcklEc0FsbCkgewogICAgICAgICAgICBteSAkQWN0aXZlID0gJEN1c3RvbWVySURzU2VsZWN0ZWR7JEN1c3RvbWVySUR9ID8gMSA6IDA7CgogICAgICAgICAgICAjIHNldCBjdXN0b21lciBjb21wYW55IHNlcnZpY2UgbWVtYmVyCiAgICAgICAgICAgICRTZWxmLT57U2VydmljZU9iamVjdH0tPkN1c3RvbWVyQ29tcGFueVNlcnZpY2VNZW1iZXJBZGQoCiAgICAgICAgICAgICAgICBDdXN0b21lcklEID0+ICRDdXN0b21lcklELAogICAgICAgICAgICAgICAgU2VydmljZUlEICA9PiAkUGFyYW17U2VydmljZUlEfSwKICAgICAgICAgICAgICAgIEFjdGl2ZSAgICAgPT4gJEFjdGl2ZSwKICAgICAgICAgICAgICAgIFVzZXJJRCAgICAgPT4gJFNlbGYtPntVc2VySUR9LAogICAgICAgICAgICApOwogICAgICAgIH0KCiAgICAgICAgIyByZWRpcmVjdCB0byBvdmVydmlldwogICAgICAgIHJldHVybiAkU2VsZi0+e0xheW91dE9iamVjdH0tPlJlZGlyZWN0KAogICAgICAgICAgICBPUCA9PgogICAgICAgICAgICAgICAgIkFjdGlvbj0kU2VsZi0+e0FjdGlvbn0mQ3VzdG9tZXJDb21wYW55U2VhcmNoPSRQYXJhbXtDdXN0b21lckNvbXBhbnlTZWFyY2h9JlNlcnZpY2VTZWFyY2g9JFBhcmFte1NlcnZpY2VTZWFyY2h9IgogICAgICAgICk7CgogICAgICAgICMgRU8gY2FwZUlUCiAgICB9CgogICAgIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gIwogICAgIyBvdmVydmlldwogICAgIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gIwogICAgZWxzZSB7CgogICAgICAgICMgY2FwZUlUCiAgICAgICAgIyBnZXQgcGFyYW1zCiAgICAgICAgJFBhcmFte0N1c3RvbWVyQ29tcGFueVNlYXJjaH0gPQogICAgICAgICAgICAkU2VsZi0+e1BhcmFtT2JqZWN0fS0+R2V0UGFyYW0oIFBhcmFtID0+ICdDdXN0b21lckNvbXBhbnlTZWFyY2gnICkKICAgICAgICAgICAgfHwgJyonOwoKICAgICAgICAjIEVPIGNhcGVJVAogICAgICAgICRQYXJhbXtTZXJ2aWNlU2VhcmNofSA9ICRTZWxmLT57UGFyYW1PYmplY3R9LT5HZXRQYXJhbSggUGFyYW0gPT4gJ1NlcnZpY2VTZWFyY2gnICkgfHwgJyonOwoKICAgICAgICAjIG91dHB1dCBoZWFkZXIKICAgICAgICBteSAkT3V0cHV0ID0gJFNlbGYtPntMYXlvdXRPYmplY3R9LT5IZWFkZXIoKTsKICAgICAgICAkT3V0cHV0IC49ICRTZWxmLT57TGF5b3V0T2JqZWN0fS0+TmF2aWdhdGlvbkJhcigpOwoKICAgICAgICAjIGNhcGVJVAogICAgICAgICMgb3V0cHV0IHNlYXJjaCBibG9jawogICAgICAgICRTZWxmLT57TGF5b3V0T2JqZWN0fS0+QmxvY2soCiAgICAgICAgICAgIE5hbWUgPT4gJ1NlYXJjaCcsCiAgICAgICAgICAgIERhdGEgPT4gewogICAgICAgICAgICAgICAgJVBhcmFtLAogICAgICAgICAgICAgICAgQ3VzdG9tZXJDb21wYW55U2VhcmNoID0+ICRQYXJhbXtDdXN0b21lckNvbXBhbnlTZWFyY2h9LAogICAgICAgICAgICAgICAgU2VydmljZVNlYXJjaCAgICAgICAgID0+ICRQYXJhbXtTZXJ2aWNlU2VhcmNofSwKICAgICAgICAgICAgfSwKICAgICAgICApOwoKICAgICAgICAjIEVPIGNhcGVJVAoKICAgICAgICAjIG91dHB1dCBkZWZhdWx0IGJsb2NrCiAgICAgICAgJFNlbGYtPntMYXlvdXRPYmplY3R9LT5CbG9jayggTmFtZSA9PiAnRGVmYXVsdCcsICk7CgogICAgICAgICMgY2FwZUlUCiAgICAgICAgIyBzZWFyY2ggY3VzdG9tZXIgY29tcGFueQogICAgICAgIG15ICVDdXN0b21lckNvbXBhbnlMaXN0CiAgICAgICAgICAgID0gJFNlbGYtPntDdXN0b21lckNvbXBhbnlPYmplY3R9CiAgICAgICAgICAgIC0+Q3VzdG9tZXJDb21wYW55TGlzdCggU2VhcmNoID0+ICRQYXJhbXtDdXN0b21lckNvbXBhbnlTZWFyY2h9LCApOwogICAgICAgIG15IEBDdXN0b21lckNvbXBhbnlLZXlMaXN0CiAgICAgICAgICAgID0gc29ydCB7ICRDdXN0b21lckNvbXBhbnlMaXN0eyRhfSBjbXAgJEN1c3RvbWVyQ29tcGFueUxpc3R7JGJ9IH0KICAgICAgICAgICAga2V5cyAlQ3VzdG9tZXJDb21wYW55TGlzdDsKCiAgICAgICAgIyBFTyBjYXBlSVQKCiAgICAgICAgIyBzZWFyY2ggc2VydmljZXMKICAgICAgICBteSBAU2VydmljZUxpc3QgPSAkU2VsZi0+e1NlcnZpY2VPYmplY3R9LT5TZXJ2aWNlU2VhcmNoKAogICAgICAgICAgICBOYW1lICAgPT4gJFBhcmFte1NlcnZpY2VTZWFyY2h9LAogICAgICAgICAgICBMaW1pdCAgPT4gJFNlYXJjaExpbWl0ICsgMSwKICAgICAgICAgICAgVXNlcklEID0+ICRTZWxmLT57VXNlcklEfSwKICAgICAgICApOwoKICAgICAgICAjIGNhcGVJVAogICAgICAgICMgY291bnQgcmVzdWx0cwogICAgICAgIG15ICRDdXN0b21lckNvbXBhbnlDb3VudCA9IEBDdXN0b21lckNvbXBhbnlLZXlMaXN0OwoKICAgICAgICAjIEVPIGNhcGVJVAogICAgICAgIG15ICRTZXJ2aWNlQ291bnQgPSBAU2VydmljZUxpc3Q7CgogICAgICAgICMgY2FwZUlUCiAgICAgICAgIyBzZXQgbWF4IGNvdW50CiAgICAgICAgbXkgJE1heENvdW50ID0gJEN1c3RvbWVyQ29tcGFueUNvdW50OwoKICAgICAgICAjIEVPIGNhcGVJVAogICAgICAgIGlmICggJFNlcnZpY2VDb3VudCA+ICRNYXhDb3VudCApIHsKICAgICAgICAgICAgJE1heENvdW50ID0gJFNlcnZpY2VDb3VudDsKICAgICAgICB9CiAgICAgICAgaWYgKCAkTWF4Q291bnQgPiAkU2VhcmNoTGltaXQgKSB7CiAgICAgICAgICAgICRNYXhDb3VudCA9ICRTZWFyY2hMaW1pdDsKICAgICAgICB9CgogICAgICAgICMgY2FwZUlUCiAgICAgICAgIyBvdXRwdXQgcmVzdWx0IGJsb2NrCiAgICAgICAgJFNlbGYtPntMYXlvdXRPYmplY3R9LT5CbG9jaygKICAgICAgICAgICAgTmFtZSA9PiAnUmVzdWx0JywKICAgICAgICAgICAgRGF0YSA9PiB7CiAgICAgICAgICAgICAgICAlUGFyYW0sCiAgICAgICAgICAgICAgICBDdXN0b21lckNvbXBhbnlDb3VudCA9PiAkQ3VzdG9tZXJDb21wYW55Q291bnQsCiAgICAgICAgICAgICAgICBTZXJ2aWNlQ291bnQgICAgICAgICA9PiAkU2VydmljZUNvdW50LAogICAgICAgICAgICB9LAogICAgICAgICk7CgogICAgICAgICMgb3V0cHV0IGN1c3RvbWVyIGNvbXBhbnkgY291bnQgYmxvY2sKICAgICAgICBpZiAoICFAQ3VzdG9tZXJDb21wYW55S2V5TGlzdCApIHsKICAgICAgICAgICAgJFNlbGYtPntMYXlvdXRPYmplY3R9LT5CbG9jaygKICAgICAgICAgICAgICAgIE5hbWUgPT4gJ1Jlc3VsdEN1c3RvbWVyQ29tcGFueUNvdW50TGltaXQnLAogICAgICAgICAgICAgICAgRGF0YSA9PiB7IEN1c3RvbWVyQ29tcGFueUNvdW50ID0+IDAsIH0sCiAgICAgICAgICAgICk7CiAgICAgICAgfQogICAgICAgIGVsc2lmICggQEN1c3RvbWVyQ29tcGFueUtleUxpc3QgPiAkU2VhcmNoTGltaXQgKSB7CiAgICAgICAgICAgICRTZWxmLT57TGF5b3V0T2JqZWN0fS0+QmxvY2soCiAgICAgICAgICAgICAgICBOYW1lID0+ICdSZXN1bHRDdXN0b21lckNvbXBhbnlDb3VudExpbWl0JywKICAgICAgICAgICAgICAgIERhdGEgPT4geyBDdXN0b21lckNvbXBhbnlDb3VudCA9PiAiPiIgLiAkU2VhcmNoTGltaXQsIH0sCiAgICAgICAgICAgICk7CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICAkU2VsZi0+e0xheW91dE9iamVjdH0tPkJsb2NrKAogICAgICAgICAgICAgICAgTmFtZSA9PiAnUmVzdWx0Q3VzdG9tZXJDb21wYW55Q291bnQnLAogICAgICAgICAgICAgICAgRGF0YSA9PiB7IEN1c3RvbWVyQ29tcGFueUNvdW50ID0+IHNjYWxhciBAQ3VzdG9tZXJDb21wYW55S2V5TGlzdCwgfSwKICAgICAgICAgICAgKTsKICAgICAgICB9CgogICAgICAgICMgRU8gY2FwZUlUCgogICAgICAgICMgb3V0cHV0IHNlcnZpY2UgY291bnQgYmxvY2sKICAgICAgICBpZiAoICFAU2VydmljZUxpc3QgKSB7CiAgICAgICAgICAgICRTZWxmLT57TGF5b3V0T2JqZWN0fS0+QmxvY2soCiAgICAgICAgICAgICAgICBOYW1lID0+ICdSZXN1bHRTZXJ2aWNlQ291bnRMaW1pdCcsCiAgICAgICAgICAgICAgICBEYXRhID0+IHsgU2VydmljZUNvdW50ID0+IDAsIH0sCiAgICAgICAgICAgICk7CiAgICAgICAgfQogICAgICAgIGVsc2lmICggQFNlcnZpY2VMaXN0ID4gJFNlYXJjaExpbWl0ICkgewogICAgICAgICAgICAkU2VsZi0+e0xheW91dE9iamVjdH0tPkJsb2NrKAogICAgICAgICAgICAgICAgTmFtZSA9PiAnUmVzdWx0U2VydmljZUNvdW50TGltaXQnLAogICAgICAgICAgICAgICAgRGF0YSA9PiB7IFNlcnZpY2VDb3VudCA9PiAiPiIgLiAkU2VhcmNoTGltaXQsIH0sCiAgICAgICAgICAgICk7CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICAkU2VsZi0+e0xheW91dE9iamVjdH0tPkJsb2NrKAogICAgICAgICAgICAgICAgTmFtZSA9PiAnUmVzdWx0U2VydmljZUNvdW50JywKICAgICAgICAgICAgICAgIERhdGEgPT4geyBTZXJ2aWNlQ291bnQgPT4gc2NhbGFyIEBTZXJ2aWNlTGlzdCwgfSwKICAgICAgICAgICAgKTsKICAgICAgICB9CgogICAgICAgICMgb3V0cHV0IHJvd3MKICAgICAgICBteSAkQ3NzID0gJ3NlYXJjaHBhc3NpdmUnOwogICAgICAgIGZvciBteSAkQ291bnRlciAoIDEgLi4gJE1heENvdW50ICkgewoKICAgICAgICAgICAgIyBzZXQgb3V0cHV0IGNsYXNzCiAgICAgICAgICAgICRDc3MgPSAkQ3NzIGVxICdzZWFyY2hhY3RpdmUnID8gJ3NlYXJjaHBhc3NpdmUnIDogJ3NlYXJjaGFjdGl2ZSc7CgogICAgICAgICAgICBteSAlUm93UGFyYW07CgogICAgICAgICAgICAjIGNhcGVJVAogICAgICAgICAgICAjIHNldCBjdXN0b21lciBjb21wYW55IHJvdyBwYXJhbXMKICAgICAgICAgICAgaWYgKCBkZWZpbmVkKCAkQ3VzdG9tZXJDb21wYW55S2V5TGlzdFsgJENvdW50ZXIgLSAxIF0gKSApIHsKICAgICAgICAgICAgICAgICRSb3dQYXJhbXtDdXN0b21lcklEfSA9ICRDdXN0b21lckNvbXBhbnlLZXlMaXN0WyAkQ291bnRlciAtIDEgXTsKICAgICAgICAgICAgICAgICRSb3dQYXJhbXtDdXN0b21lckNvbXBhbnl9ID0KICAgICAgICAgICAgICAgICAgICAkQ3VzdG9tZXJDb21wYW55TGlzdHsgJEN1c3RvbWVyQ29tcGFueUtleUxpc3RbICRDb3VudGVyIC0gMSBdIH07CiAgICAgICAgICAgICAgICAkUm93UGFyYW17Q3VzdG9tZXJDb21wYW55Q3NzQ2xhc3N9ID0gJENzczsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgIyBFTyBjYXBlSVQKCiAgICAgICAgICAgICMgc2V0IHNlcnZpY2Ugcm93IHBhcmFtcwogICAgICAgICAgICBpZiAoICRTZXJ2aWNlTGlzdFsgJENvdW50ZXIgLSAxIF0gKSB7CiAgICAgICAgICAgICAgICBteSAlU2VydmljZSA9ICRTZWxmLT57U2VydmljZU9iamVjdH0tPlNlcnZpY2VHZXQoCiAgICAgICAgICAgICAgICAgICAgU2VydmljZUlEID0+ICRTZXJ2aWNlTGlzdFsgJENvdW50ZXIgLSAxIF0sCiAgICAgICAgICAgICAgICAgICAgVXNlcklEICAgID0+ICRTZWxmLT57VXNlcklEfSwKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAkUm93UGFyYW17U2VydmljZUlEfSAgICAgICA9ICRTZXJ2aWNle1NlcnZpY2VJRH07CiAgICAgICAgICAgICAgICAkUm93UGFyYW17U2VydmljZX0gICAgICAgICA9ICRTZXJ2aWNle05hbWV9OwogICAgICAgICAgICAgICAgJFJvd1BhcmFte1NlcnZpY2VDc3NDbGFzc30gPSAkQ3NzOwogICAgICAgICAgICB9CgogICAgICAgICAgICAjIG91dHB1dCByb3cgYmxvY2sKICAgICAgICAgICAgJFNlbGYtPntMYXlvdXRPYmplY3R9LT5CbG9jaygKICAgICAgICAgICAgICAgIE5hbWUgPT4gJ1Jlc3VsdFJvdycsCiAgICAgICAgICAgICAgICBEYXRhID0+IHsgJVBhcmFtLCAlUm93UGFyYW0sIH0sCiAgICAgICAgICAgICk7CiAgICAgICAgfQoKICAgICAgICAjIGNhcGVJVAogICAgICAgICMgZ2VuZXJhdGUgb3V0cHV0CiAgICAgICAgJE91dHB1dCAuPSAkU2VsZi0+e0xheW91dE9iamVjdH0tPk91dHB1dCgKICAgICAgICAgICAgVGVtcGxhdGVGaWxlID0+ICdBZG1pbkN1c3RvbWVyQ29tcGFueVNlcnZpY2UnLAogICAgICAgICAgICBEYXRhICAgICAgICAgPT4gXCVQYXJhbSwKICAgICAgICApOwoKICAgICAgICAjIEVPIGNhcGVJVAogICAgICAgICRPdXRwdXQgLj0gJFNlbGYtPntMYXlvdXRPYmplY3R9LT5Gb290ZXIoKTsKCiAgICAgICAgcmV0dXJuICRPdXRwdXQ7CiAgICB9Cn0KCjE7Cg== IyAtLQojIEFkbWluQ3VzdG9tZXJDb21wYW55U2VydmljZS5kdGwgLSBwcm92aWRlcyBIVE1MIGZvcm0gZm9yIEFkbWluSW50ZXJmYWNlCiMgb3JpZ2luYWwgQ29weXJpZ2h0IChDKSAyMDAxLTIwMDkgT1RSUyBBRywgaHR0cDovL290cnMub3JnLwojCiMgRXh0ZW5zaW9ucyBDb3B5cmlnaHQgKEMpIDIwMDYtMjAxMCBjLmEucC5lLiBJVCBHbWJILCBodHRwOi8vd3d3LmNhcGUtaXQuZGUKIwojIHdyaXR0ZW4vZWRpdGVkIGJ5OgojICAgUmVuZShkb3QpQm9laG0oYXQpY2FwZS1pdC5kZQojCiMgLS0KIyAkSWQ6IEFkbWluQ3VzdG9tZXJDb21wYW55U2VydmljZS5kdGwsdiAxLjIgMjAxMC0xMC0xNCAxMTozMTozNSByYm8gRXhwICQKIyAtLQojIFRoaXMgc29mdHdhcmUgY29tZXMgd2l0aCBBQlNPTFVURUxZIE5PIFdBUlJBTlRZLiBGb3IgZGV0YWlscywgc2VlCiMgdGhlIGVuY2xvc2VkIGZpbGUgQ09QWUlORyBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbiAoQUdQTCkuIElmIHlvdQojIGRpZCBub3QgcmVjZWl2ZSB0aGlzIGZpbGUsIHNlZSBodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC50eHQuCiMgLS0KCjx0YWJsZSBib3JkZXI9IjAiIHdpZHRoPSIxMDAlIiBjZWxsc3BhY2luZz0iMCIgY2VsbHBhZGRpbmc9IjMiPgogIDx0cj4KICAgIDx0ZCBjb2xzcGFuPSIyIiBjbGFzcz0ibWFpbmhlYWQiPgojIGNhcGVJVCAgICAKICAgICAgJEVudnsiQm94MCJ9JFRleHR7IkN1c3RvbWVyIENvbXBhbnkgPC0+IFNlcnZpY2VzIE1hbmFnZW1lbnQifSRFbnZ7IkJveDEifQojIEVPIGNhcGVJVAogICAgPC90ZD4KICA8L3RyPgogIDx0cj4KICAgIDx0ZCB3aWR0aD0iMzAlIiBjbGFzcz0ibWFpbmJvZHkiPgo8IS0tIGR0bDpibG9jazpTZWFyY2ggLS0+CiAgICAgIDxmb3JtIGFjdGlvbj0iJEVudnsiQ0dJSGFuZGxlIn0iIG1ldGhvZD0icG9zdCI+CiAgICAgICAgPGlucHV0IHR5cGU9ImhpZGRlbiIgbmFtZT0iQWN0aW9uIiB2YWx1ZT0iJEVudnsiQWN0aW9uIn0iLz4KICAgICAgICA8dGFibGUgd2lkdGg9IjEwMCUiIGNlbGxzcGFjaW5nPSIwIiBjZWxscGFkZGluZz0iNCI+CiAgICAgICAgICA8dHI+CiAgICAgICAgICAgIDx0ZCBjbGFzcz0iY29udGVudGhlYWQiPiRUZXh0eyJTZWFyY2gifTo8L3RkPgogICAgICAgICAgPC90cj4KICAgICAgICAgIDx0cj4KICAgICAgICAgICAgPHRkIGNsYXNzPSJjb250ZW50Ym9keSI+CiAgICAgICAgICAgICAgPHRhYmxlPgogICAgICAgICAgICAgICAgPHRyPgojIGNhcGVJVAogICAgICAgICAgICAgICAgICA8dGQgY2xhc3M9ImNvbnRlbnRrZXkiPiRUZXh0eyJTZWFyY2ggZm9yIn0gJFRleHR7IkN1c3RvbWVyIENvbXBhbnkifTo8L3RkPgogICAgICAgICAgICAgICAgICA8dGQgY2xhc3M9ImNvbnRlbnR2YWx1ZSI+PGlucHV0IHR5cGU9InRleHQiIG5hbWU9IkN1c3RvbWVyQ29tcGFueVNlYXJjaCIgdmFsdWU9IiRRRGF0YXsiQ3VzdG9tZXJDb21wYW55U2VhcmNoIn0iIHNpemU9IjIwIi8+PC90ZD4KIyBFTyBjYXBlSVQKICAgICAgICAgICAgICAgIDwvdHI+CiAgICAgICAgICAgICAgICA8dHI+CiAgICAgICAgICAgICAgICAgIDx0ZCBjbGFzcz0iY29udGVudGtleSI+JFRleHR7IlNlYXJjaCBmb3IifSAkVGV4dHsiU2VydmljZSJ9OjwvdGQ+CiAgICAgICAgICAgICAgICAgIDx0ZCBjbGFzcz0iY29udGVudHZhbHVlIj48aW5wdXQgdHlwZT0idGV4dCIgbmFtZT0iU2VydmljZVNlYXJjaCIgdmFsdWU9IiRRRGF0YXsiU2VydmljZVNlYXJjaCJ9IiBzaXplPSIyMCIvPjwvdGQ+CiAgICAgICAgICAgICAgICA8L3RyPgogICAgICAgICAgICAgIDwvdGFibGU+CiAgICAgICAgICAgIDwvdGQ+CiAgICAgICAgICA8L3RyPgogICAgICAgICAgPHRyPgogICAgICAgICAgICA8dGQgY2xhc3M9ImNvbnRlbnRmb290ZXIiPgogICAgICAgICAgICAgIDxpbnB1dCBjbGFzcz0iYnV0dG9uIiB0eXBlPSJzdWJtaXQiIHZhbHVlPSIkVGV4dHsiU2VhcmNoIn0iLz4KICAgICAgICAgICAgPC90ZD4KICAgICAgICAgIDwvdHI+CiAgICAgICAgPC90YWJsZT4KICAgICAgPC9mb3JtPgo8IS0tIGR0bDpibG9jazpTZWFyY2ggLS0+CjwhLS0gZHRsOmJsb2NrOkRlZmF1bHQgLS0+CiAgICAgIDxici8+CiAgICAgIDxmb3JtIGFjdGlvbj0iJEVudnsiQ0dJSGFuZGxlIn0iIG1ldGhvZD0icG9zdCI+CiAgICAgICAgPGlucHV0IHR5cGU9ImhpZGRlbiIgbmFtZT0iQWN0aW9uIiB2YWx1ZT0iJEVudnsiQWN0aW9uIn0iLz4KIyBjYXBlSVQKICAgICAgICA8aW5wdXQgdHlwZT0iaGlkZGVuIiBuYW1lPSJTdWJhY3Rpb24iIHZhbHVlPSJBbGxvY2F0ZUN1c3RvbWVyQ29tcGFueSIvPgojIEVPIGNhcGVJVAogICAgICAgIDx0YWJsZSB3aWR0aD0iMTAwJSIgY2VsbHNwYWNpbmc9IjAiIGNlbGxwYWRkaW5nPSI0Ij4KICAgICAgICAgIDx0cj4KICAgICAgICAgICAgPHRkIGNsYXNzPSJjb250ZW50aGVhZCI+JFRleHR7IkVkaXQifTo8L3RkPgogICAgICAgICAgPC90cj4KICAgICAgICAgIDx0cj4KICAgICAgICAgICAgPHRkIGNsYXNzPSJjb250ZW50Ym9keSI+CiAgICAgICAgICAgICAgJFRleHR7IkVkaXQgZGVmYXVsdCBzZXJ2aWNlcy4ifQogICAgICAgICAgICA8L3RkPgogICAgICAgICAgPC90cj4KICAgICAgICAgIDx0cj4KICAgICAgICAgICAgPHRkIGNsYXNzPSJjb250ZW50Zm9vdGVyIj4KICAgICAgICAgICAgICA8aW5wdXQgY2xhc3M9ImJ1dHRvbiIgdHlwZT0ic3VibWl0IiB2YWx1ZT0iJFRleHR7IkVkaXQifSIvPgogICAgICAgICAgICA8L3RkPgogICAgICAgICAgPC90cj4KICAgICAgICA8L3RhYmxlPgogICAgICA8L2Zvcm0+CjwhLS0gZHRsOmJsb2NrOkRlZmF1bHQgLS0+CiAgICA8L3RkPgogICAgPHRkIHdpZHRoPSI3MCUiIGNsYXNzPSJtYWluYm9keSI+CjwhLS0gZHRsOmJsb2NrOlJlc3VsdCAtLT4KICAgICAgPHRhYmxlIHdpZHRoPSIxMDAlIiBjZWxsc3BhY2luZz0iMCIgY2VsbHBhZGRpbmc9IjQiPgogICAgICAgIDx0cj4KICAgICAgICAgIDx0ZCBjbGFzcz0iY29udGVudGhlYWQiPiRUZXh0eyJTZWFyY2ggUmVzdWx0In06PC90ZD4KICAgICAgICA8L3RyPgogICAgICAgIDx0cj4KICAgICAgICAgIDx0ZCBjbGFzcz0iY29udGVudGJvZHkiPgogICAgICAgICAgICA8dGFibGUgd2lkdGg9IjEwMCUiIGJvcmRlcj0iMCIgY2VsbHNwYWNpbmc9IjAiIGNlbGxwYWRkaW5nPSIzIj4KICAgICAgICAgICAgICA8dHI+CiMgY2FwZUlUCiAgICAgICAgICAgICAgICA8dGQgY2xhc3M9ImNvbnRlbnRrZXkiIHdpZHRoPSI0OSUiPiRUZXh0eyJDdXN0b21lciBDb21wYW55In0KPCEtLSBkdGw6YmxvY2s6UmVzdWx0Q3VzdG9tZXJDb21wYW55Q291bnQgLS0+CiAgICAgICAgICAgICAgICAgICgkUURhdGF7IkN1c3RvbWVyQ29tcGFueUNvdW50In0pCjwhLS0gZHRsOmJsb2NrOlJlc3VsdEN1c3RvbWVyQ29tcGFueUNvdW50IC0tPgo8IS0tIGR0bDpibG9jazpSZXN1bHRDdXN0b21lckNvbXBhbnlDb3VudExpbWl0IC0tPgogICAgICAgICAgICAgICAgICAoPGZvbnQgY29sb3I9InJlZCI+JFFEYXRheyJDdXN0b21lckNvbXBhbnlDb3VudCJ9PC9mb250PikKPCEtLSBkdGw6YmxvY2s6UmVzdWx0Q3VzdG9tZXJDb21wYW55Q291bnRMaW1pdCAtLT4KIyBFTyBjYXBlSVQKICAgICAgICAgICAgICAgIDwvdGQ+CiAgICAgICAgICAgICAgICA8dGQgY2xhc3M9ImNvbnRlbnRrZXkiIHdpZHRoPSIxJSI+PC90ZD4KICAgICAgICAgICAgICAgIDx0ZCBjbGFzcz0iY29udGVudGtleSIgd2lkdGg9IjUwJSI+JFRleHR7IlNlcnZpY2UifQo8IS0tIGR0bDpibG9jazpSZXN1bHRTZXJ2aWNlQ291bnQgLS0+CiAgICAgICAgICAgICAgICAgICgkUURhdGF7IlNlcnZpY2VDb3VudCJ9KQo8IS0tIGR0bDpibG9jazpSZXN1bHRTZXJ2aWNlQ291bnQgLS0+CjwhLS0gZHRsOmJsb2NrOlJlc3VsdFNlcnZpY2VDb3VudExpbWl0IC0tPgogICAgICAgICAgICAgICAgICAoPGZvbnQgY29sb3I9InJlZCI+JFFEYXRheyJTZXJ2aWNlQ291bnQifTwvZm9udD4pCjwhLS0gZHRsOmJsb2NrOlJlc3VsdFNlcnZpY2VDb3VudExpbWl0IC0tPgogICAgICAgICAgICAgICAgPC90ZD4KICAgICAgICAgICAgICA8L3RyPgo8IS0tIGR0bDpibG9jazpSZXN1bHRSb3cgLS0+CiAgICAgICAgICAgICAgPHRyPgojIGNhcGVJVAogICAgICAgICAgICAgICAgPHRkIGNsYXNzPSIkUURhdGF7IkN1c3RvbWVyQ29tcGFueUNzc0NsYXNzIn0iPgogICAgICAgICAgICAgICAgICA8YSBocmVmPSIkRW52eyJCYXNlbGluayJ9QWN0aW9uPSRFbnZ7IkFjdGlvbiJ9JlN1YmFjdGlvbj1BbGxvY2F0ZUN1c3RvbWVyQ29tcGFueSZDdXN0b21lcklEPSRMUURhdGF7IkN1c3RvbWVySUQifSZDdXN0b21lckNvbXBhbnlTZWFyY2g9JExRRGF0YXsiQ3VzdG9tZXJDb21wYW55U2VhcmNoIn0mU2VydmljZVNlYXJjaD0kTFFEYXRheyJTZXJ2aWNlU2VhcmNoIn0iPiRRRGF0YXsiQ3VzdG9tZXJDb21wYW55In08L2E+CiMgRU8gY2FwZUlUCiAgICAgICAgICAgICAgICA8L3RkPgogICAgICAgICAgICAgICAgPHRkPjwvdGQ+CiAgICAgICAgICAgICAgICA8dGQgY2xhc3M9IiRRRGF0YXsiU2VydmljZUNzc0NsYXNzIn0iPgojIGNhcGVJVAogICAgICAgICAgICAgICAgICA8YSBocmVmPSIkRW52eyJCYXNlbGluayJ9QWN0aW9uPSRFbnZ7IkFjdGlvbiJ9JlN1YmFjdGlvbj1BbGxvY2F0ZVNlcnZpY2UmU2VydmljZUlEPSRMUURhdGF7IlNlcnZpY2VJRCJ9JkN1c3RvbWVyQ29tcGFueVNlYXJjaD0kTFFEYXRheyJDdXN0b21lckNvbXBhbnlTZWFyY2gifSZTZXJ2aWNlU2VhcmNoPSRMUURhdGF7IlNlcnZpY2VTZWFyY2gifSI+JFFEYXRheyJTZXJ2aWNlIn08L2E+CiMgRU8gY2FwZUlUCiAgICAgICAgICAgICAgICA8L3RkPgogICAgICAgICAgICAgIDwvdHI+CjwhLS0gZHRsOmJsb2NrOlJlc3VsdFJvdyAtLT4KICAgICAgICAgICAgPC90YWJsZT4KICAgICAgICAgIDwvdGQ+CiAgICAgICAgPC90cj4KICAgICAgICA8dHI+CiAgICAgICAgICA8dGQgY2xhc3M9ImNvbnRlbnRmb290ZXIiPgogICAgICAgICAgICAmbmJzcDsKICAgICAgICAgIDwvdGQ+CiAgICAgICAgPC90cj4KICAgICAgPC90YWJsZT4KPCEtLSBkdGw6YmxvY2s6UmVzdWx0IC0tPgojIGNhcGVJVAo8IS0tIGR0bDpibG9jazpBbGxvY2F0ZUN1c3RvbWVyQ29tcGFueSAtLT4KICAgICAgPGZvcm0gYWN0aW9uPSIkRW52eyJDR0lIYW5kbGUifSIgbWV0aG9kPSJwb3N0Ij4KICAgICAgICA8aW5wdXQgdHlwZT0iaGlkZGVuIiBuYW1lPSJBY3Rpb24iIHZhbHVlPSIkRW52eyJBY3Rpb24ifSIvPgogICAgICAgIDxpbnB1dCB0eXBlPSJoaWRkZW4iIG5hbWU9IlN1YmFjdGlvbiIgdmFsdWU9IkFsbG9jYXRlQ3VzdG9tZXJDb21wYW55U2F2ZSIvPgogICAgICAgIDxpbnB1dCB0eXBlPSJoaWRkZW4iIG5hbWU9IkN1c3RvbWVyQ29tcGFueVNlYXJjaCIgdmFsdWU9IiRRRGF0YXsiQ3VzdG9tZXJDb21wYW55U2VhcmNoIn0iLz4KICAgICAgICA8aW5wdXQgdHlwZT0iaGlkZGVuIiBuYW1lPSJTZXJ2aWNlU2VhcmNoIiB2YWx1ZT0iJFFEYXRheyJTZXJ2aWNlU2VhcmNoIn0iLz4KICAgICAgICA8aW5wdXQgdHlwZT0iaGlkZGVuIiBuYW1lPSJDdXN0b21lcklEIiB2YWx1ZT0iJFFEYXRheyJDdXN0b21lcklEIn0iLz4KICAgICAgICA8dGFibGUgd2lkdGg9IjEwMCUiIGNlbGxzcGFjaW5nPSIwIiBjZWxscGFkZGluZz0iNCI+CiAgICAgICAgICA8dHI+CiAgICAgICAgICAgIDx0ZCBjbGFzcz0iY29udGVudGhlYWQiPiRUZXh0eyJBbGxvY2F0ZSBzZXJ2aWNlcyB0byBDdXN0b21lciBDb21wYW55In0gIiRRRGF0YXsiQ3VzdG9tZXJJRCJ9Ijo8L3RkPgojIEVPIGNhcGVJVAogICAgICAgICAgPC90cj4KICAgICAgICAgIDx0cj4KICAgICAgICAgICAgPHRkIGNsYXNzPSJjb250ZW50Ym9keSI+CiAgICAgICAgICAgICAgPHRhYmxlIHdpZHRoPSIxMDAlIiBib3JkZXI9IjAiIGNlbGxzcGFjaW5nPSIwIiBjZWxscGFkZGluZz0iMyI+CiAgICAgICAgICAgICAgICA8dHI+CiAgICAgICAgICAgICAgICAgIDx0ZCBjbGFzcz0iY29udGVudGtleSI+JFRleHR7IlNlcnZpY2UifQojIGNhcGVJVAo8IS0tIGR0bDpibG9jazpBbGxvY2F0ZUN1c3RvbWVyQ29tcGFueVNlcnZpY2VDb3VudCAtLT4KICAgICAgICAgICAgICAgICAgICAoJFFEYXRheyJTZXJ2aWNlQ291bnQifSkKPCEtLSBkdGw6YmxvY2s6QWxsb2NhdGVDdXN0b21lckNvbXBhbnlTZXJ2aWNlQ291bnQgLS0+CjwhLS0gZHRsOmJsb2NrOkFsbG9jYXRlQ3VzdG9tZXJDb21wYW55U2VydmljZUNvdW50TGltaXQgLS0+CiAgICAgICAgICAgICAgICAgICAgKDxmb250IGNvbG9yPSJyZWQiPiRRRGF0YXsiU2VydmljZUNvdW50In08L2ZvbnQ+KQo8IS0tIGR0bDpibG9jazpBbGxvY2F0ZUN1c3RvbWVyQ29tcGFueVNlcnZpY2VDb3VudExpbWl0IC0tPgojIEVPIGNhcGVJVAogICAgICAgICAgICAgICAgICA8L3RkPgogICAgICAgICAgICAgICAgICA8dGQgY2xhc3M9ImNvbnRlbnRrZXkiIHdpZHRoPSIxMDAiPiRUZXh0eyJBY3RpdmUifTwvdGQ+CiAgICAgICAgICAgICAgICA8L3RyPgojIGNhcGVJVAo8IS0tIGR0bDpibG9jazpBbGxvY2F0ZUN1c3RvbWVyQ29tcGFueVJvdyAtLT4KIyBFTyBjYXBlSVQKICAgICAgICAgICAgICAgIDx0cj4KICAgICAgICAgICAgICAgICAgPHRkIGNsYXNzPSIkUURhdGF7IkNzc0NsYXNzIn0iPgogICAgICAgICAgICAgICAgICAgIDxhIGhyZWY9IiRFbnZ7IkJhc2VsaW5rIn1BY3Rpb249QWRtaW5TZXJ2aWNlJlN1YmFjdGlvbj1TZXJ2aWNlRWRpdCZTZXJ2aWNlSUQ9JFFEYXRheyJTZXJ2aWNlSUQifSI+CiAgICAgICAgICAgICAgICAgICAgJFFEYXRheyJTZXJ2aWNlIn0KICAgICAgICAgICAgICAgICAgICA8L2E+CiAgICAgICAgICAgICAgICAgIDwvdGQ+CiAgICAgICAgICAgICAgICAgIDx0ZCBjbGFzcz0iJFFEYXRheyJDc3NDbGFzcyJ9Ij4KICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT0iY2hlY2tib3giIG5hbWU9IlNlcnZpY2VJRHNTZWxlY3RlZCIgdmFsdWU9IiRRRGF0YXsiU2VydmljZUlEIn0iICRRRGF0YXsiQ2hlY2tlZCJ9Lz4KICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT0iaGlkZGVuIiBuYW1lPSJTZXJ2aWNlSURzQWxsIiB2YWx1ZT0iJFFEYXRheyJTZXJ2aWNlSUQifSIvPgogICAgICAgICAgICAgICAgICA8L3RkPgogICAgICAgICAgICAgICAgPC90cj4KIyBjYXBlSVQKPCEtLSBkdGw6YmxvY2s6QWxsb2NhdGVDdXN0b21lckNvbXBhbnlSb3cgLS0+CiMgRU8gY2FwZUlUCiAgICAgICAgICAgICAgPC90YWJsZT4KICAgICAgICAgICAgPC90ZD4KICAgICAgICAgIDwvdHI+CiAgICAgICAgICA8dHI+CiAgICAgICAgICAgIDx0ZCBjbGFzcz0iY29udGVudGZvb3RlciI+CiAgICAgICAgICAgICAgPGlucHV0IGNsYXNzPSJidXR0b24iIHR5cGU9InN1Ym1pdCIgdmFsdWU9IiRUZXh0eyJTdWJtaXQifSIvPgogICAgICAgICAgICA8L3RkPgogICAgICAgICAgPC90cj4KICAgICAgICA8L3RhYmxlPgogICAgICA8L2Zvcm0+CiMgY2FwZUlUCjwhLS0gZHRsOmJsb2NrOkFsbG9jYXRlQ3VzdG9tZXJDb21wYW55IC0tPgojIEVPIGNhcGVJVAo8IS0tIGR0bDpibG9jazpBbGxvY2F0ZVNlcnZpY2UgLS0+CiAgICAgIDxmb3JtIGFjdGlvbj0iJEVudnsiQ0dJSGFuZGxlIn0iIG1ldGhvZD0icG9zdCI+CiAgICAgICAgPGlucHV0IHR5cGU9ImhpZGRlbiIgbmFtZT0iQWN0aW9uIiB2YWx1ZT0iJEVudnsiQWN0aW9uIn0iLz4KICAgICAgICA8aW5wdXQgdHlwZT0iaGlkZGVuIiBuYW1lPSJTdWJhY3Rpb24iIHZhbHVlPSJBbGxvY2F0ZVNlcnZpY2VTYXZlIi8+CiMgY2FwZUlUCiAgICAgICAgPGlucHV0IHR5cGU9ImhpZGRlbiIgbmFtZT0iQ3VzdG9tZXJDb21wYW55U2VhcmNoIiB2YWx1ZT0iJFFEYXRheyJDdXN0b21lckNvbXBhbnlTZWFyY2gifSIvPgojIEVPIGNhcGVJVAogICAgICAgIDxpbnB1dCB0eXBlPSJoaWRkZW4iIG5hbWU9IlNlcnZpY2VTZWFyY2giIHZhbHVlPSIkUURhdGF7IlNlcnZpY2VTZWFyY2gifSIvPgogICAgICAgIDxpbnB1dCB0eXBlPSJoaWRkZW4iIG5hbWU9IlNlcnZpY2VJRCIgdmFsdWU9IiRRRGF0YXsiU2VydmljZUlEIn0iLz4KICAgICAgICA8dGFibGUgd2lkdGg9IjEwMCUiIGNlbGxzcGFjaW5nPSIwIiBjZWxscGFkZGluZz0iNCI+CiAgICAgICAgICA8dHI+CiMgY2FwZUlUCiAgICAgICAgICAgIDx0ZCBjbGFzcz0iY29udGVudGhlYWQiPiRUZXh0eyJBbGxvY2F0ZSBDdXN0b21lciBDb21wYW55IHRvIFNlcnZpY2UifSAiJFFEYXRheyJTZXJ2aWNlIn0iOjwvdGQ+CiMgRU8gY2FwZUlUCiAgICAgICAgICA8L3RyPgogICAgICAgICAgPHRyPgogICAgICAgICAgICA8dGQgY2xhc3M9ImNvbnRlbnRib2R5Ij4KICAgICAgICAgICAgICA8dGFibGUgd2lkdGg9IjEwMCUiIGJvcmRlcj0iMCIgY2VsbHNwYWNpbmc9IjAiIGNlbGxwYWRkaW5nPSIzIj4KICAgICAgICAgICAgICAgIDx0cj4KIyBjYXBlSVQKICAgICAgICAgICAgICAgICAgPHRkIGNsYXNzPSJjb250ZW50a2V5Ij4kVGV4dHsiQ3VzdG9tZXIgQ29tcGFueSJ9CjwhLS0gZHRsOmJsb2NrOkFsbG9jYXRlU2VydmljZUN1c3RvbWVyQ29tcGFueUNvdW50IC0tPgogICAgICAgICAgICAgICAgICAgICgkUURhdGF7IkN1c3RvbWVyQ29tcGFueUNvdW50In0pCjwhLS0gZHRsOmJsb2NrOkFsbG9jYXRlU2VydmljZUN1c3RvbWVyQ29tcGFueUNvdW50IC0tPgo8IS0tIGR0bDpibG9jazpBbGxvY2F0ZVNlcnZpY2VDdXN0b21lckNvbXBhbnlDb3VudExpbWl0IC0tPgogICAgICAgICAgICAgICAgICAgICg8Zm9udCBjb2xvcj0icmVkIj4kUURhdGF7IkN1c3RvbWVyQ29tcGFueUNvdW50In08L2ZvbnQ+KQo8IS0tIGR0bDpibG9jazpBbGxvY2F0ZVNlcnZpY2VDdXN0b21lckNvbXBhbnlDb3VudExpbWl0IC0tPgojIEVPIGNhcGVJVAogICAgICAgICAgICAgICAgICA8L3RkPgogICAgICAgICAgICAgICAgICA8dGQgY2xhc3M9ImNvbnRlbnRrZXkiIHdpZHRoPSIxMDAiPiRUZXh0eyJBY3RpdmUifTwvdGQ+CiAgICAgICAgICAgICAgICA8L3RyPgo8IS0tIGR0bDpibG9jazpBbGxvY2F0ZVNlcnZpY2VSb3cgLS0+CiAgICAgICAgICAgICAgICA8dHI+CiAgICAgICAgICAgICAgICAgIDx0ZCBjbGFzcz0iJFFEYXRheyJDc3NDbGFzcyJ9Ij4KIyBjYXBlSVQKICAgICAgICAgICAgICAgICAgICA8YSBocmVmPSIkRW52eyJCYXNlbGluayJ9QWN0aW9uPUFkbWluQ3VzdG9tZXJDb21wYW55JlN1YmFjdGlvbj1DaGFuZ2UmSUQ9JExRRGF0YXsiQ3VzdG9tZXJJRCJ9Ij4kUURhdGF7IkN1c3RvbWVyQ29tcGFueSJ9PC9hPgojIEVPIGNhcGVJVAogICAgICAgICAgICAgICAgICA8L3RkPgogICAgICAgICAgICAgICAgICA8dGQgY2xhc3M9IiRRRGF0YXsiQ3NzQ2xhc3MifSI+CiMgY2FwZUlUCiAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9ImNoZWNrYm94IiBuYW1lPSJDdXN0b21lcklEc1NlbGVjdGVkIiB2YWx1ZT0iJFFEYXRheyJDdXN0b21lcklEIn0iICRRRGF0YXsiQ2hlY2tlZCJ9Lz4KICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT0iaGlkZGVuIiBuYW1lPSJDdXN0b21lcklEc0FsbCIgdmFsdWU9IiRRRGF0YXsiQ3VzdG9tZXJJRCJ9Ii8+CiMgRU8gY2FwZUlUCiAgICAgICAgICAgICAgICAgIDwvdGQ+CiAgICAgICAgICAgICAgICA8L3RyPgo8IS0tIGR0bDpibG9jazpBbGxvY2F0ZVNlcnZpY2VSb3cgLS0+CiAgICAgICAgICAgICAgPC90YWJsZT4KICAgICAgICAgICAgPC90ZD4KICAgICAgICAgIDwvdHI+CiAgICAgICAgICA8dHI+CiAgICAgICAgICAgIDx0ZCBjbGFzcz0iY29udGVudGZvb3RlciI+CiAgICAgICAgICAgICAgPGlucHV0IGNsYXNzPSJidXR0b24iIHR5cGU9InN1Ym1pdCIgdmFsdWU9IiRUZXh0eyJTdWJtaXQifSIvPgogICAgICAgICAgICA8L3RkPgogICAgICAgICAgPC90cj4KICAgICAgICA8L3RhYmxlPgogICAgICA8L2Zvcm0+CjwhLS0gZHRsOmJsb2NrOkFsbG9jYXRlU2VydmljZSAtLT4KICAgIDwvdGQ+CiAgPC90cj4KPC90YWJsZT4K IyAtLQojIEtlcm5lbC9TeXN0ZW0vU2VydmljZS5wbSAtIGFsbCBzZXJ2aWNlIGZ1bmN0aW9uCiMgb3JpZ2luYWwgQ29weXJpZ2h0IChDKSAyMDAxLTIwMDkgT1RSUyBBRywgaHR0cDovL290cnMub3JnLwojCiMgRXh0ZW5zaW9ucyBDb3B5cmlnaHQgKEMpIDIwMDYtMjAxMCBjLmEucC5lLiBJVCBHbWJILCBodHRwOi8vd3d3LmNhcGUtaXQuZGUKIwojIHdyaXR0ZW4vZWRpdGVkIGJ5OgojICAgUmVuZShkb3QpQm9laG0oYXQpY2FwZS1pdC5kZQojCiMgLS0KIyAkSWQ6IFNlcnZpY2UucG0sdiAxLjEgMjAxMC0xMC0wNyAxNjoxNTo1OSByYm8gRXhwICQKIyAtLQojIFRoaXMgc29mdHdhcmUgY29tZXMgd2l0aCBBQlNPTFVURUxZIE5PIFdBUlJBTlRZLiBGb3IgZGV0YWlscywgc2VlCiMgdGhlIGVuY2xvc2VkIGZpbGUgQ09QWUlORyBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbiAoQUdQTCkuIElmIHlvdQojIGRpZCBub3QgcmVjZWl2ZSB0aGlzIGZpbGUsIHNlZSBodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC50eHQuCiMgLS0KCnBhY2thZ2UgS2VybmVsOjpTeXN0ZW06OlNlcnZpY2U7Cgp1c2Ugc3RyaWN0Owp1c2Ugd2FybmluZ3M7Cgp1c2UgS2VybmVsOjpTeXN0ZW06OkNoZWNrSXRlbTsKdXNlIEtlcm5lbDo6U3lzdGVtOjpWYWxpZDsKCnVzZSB2YXJzIHF3KEBJU0EgJFZFUlNJT04pOwokVkVSU0lPTiA9IHF3KCRSZXZpc2lvbjogMS4xICQpIFsxXTsKCj1oZWFkMSBOQU1FCgpLZXJuZWw6OlN5c3RlbTo6U2VydmljZSAtIHNlcnZpY2UgbGliCgo9aGVhZDEgU1lOT1BTSVMKCkFsbCBzZXJ2aWNlIGZ1bmN0aW9ucy4KCj1oZWFkMSBQVUJMSUMgSU5URVJGQUNFCgo9b3ZlciA0Cgo9Y3V0Cgo9aXRlbSBuZXcoKQoKY3JlYXRlIGFuIG9iamVjdAoKICAgIHVzZSBLZXJuZWw6OkNvbmZpZzsKICAgIHVzZSBLZXJuZWw6OlN5c3RlbTo6RW5jb2RlOwogICAgdXNlIEtlcm5lbDo6U3lzdGVtOjpMb2c7CiAgICB1c2UgS2VybmVsOjpTeXN0ZW06Ok1haW47CiAgICB1c2UgS2VybmVsOjpTeXN0ZW06OkRCOwogICAgdXNlIEtlcm5lbDo6U3lzdGVtOjpTZXJ2aWNlOwoKICAgIG15ICRDb25maWdPYmplY3QgPSBLZXJuZWw6OkNvbmZpZy0+bmV3KCk7CiAgICBteSAkRW5jb2RlT2JqZWN0ID0gS2VybmVsOjpTeXN0ZW06OkVuY29kZS0+bmV3KAogICAgICAgIENvbmZpZ09iamVjdCA9PiAkQ29uZmlnT2JqZWN0LAogICAgKTsKICAgIG15ICRMb2dPYmplY3QgPSBLZXJuZWw6OlN5c3RlbTo6TG9nLT5uZXcoCiAgICAgICAgQ29uZmlnT2JqZWN0ID0+ICRDb25maWdPYmplY3QsCiAgICAgICAgRW5jb2RlT2JqZWN0ID0+ICRFbmNvZGVPYmplY3QsCiAgICApOwogICAgbXkgJE1haW5PYmplY3QgPSBLZXJuZWw6OlN5c3RlbTo6TWFpbi0+bmV3KAogICAgICAgIENvbmZpZ09iamVjdCA9PiAkQ29uZmlnT2JqZWN0LAogICAgICAgIEVuY29kZU9iamVjdCA9PiAkRW5jb2RlT2JqZWN0LAogICAgICAgIExvZ09iamVjdCAgICA9PiAkTG9nT2JqZWN0LAogICAgKTsKICAgIG15ICREQk9iamVjdCA9IEtlcm5lbDo6U3lzdGVtOjpEQi0+bmV3KAogICAgICAgIENvbmZpZ09iamVjdCA9PiAkQ29uZmlnT2JqZWN0LAogICAgICAgIEVuY29kZU9iamVjdCA9PiAkRW5jb2RlT2JqZWN0LAogICAgICAgIExvZ09iamVjdCAgICA9PiAkTG9nT2JqZWN0LAogICAgICAgIE1haW5PYmplY3QgICA9PiAkTWFpbk9iamVjdCwKICAgICk7CiAgICBteSAkU2VydmljZU9iamVjdCA9IEtlcm5lbDo6U3lzdGVtOjpTZXJ2aWNlLT5uZXcoCiAgICAgICAgQ29uZmlnT2JqZWN0ID0+ICRDb25maWdPYmplY3QsCiAgICAgICAgRW5jb2RlT2JqZWN0ID0+ICRFbmNvZGVPYmplY3QsCiAgICAgICAgTG9nT2JqZWN0ICAgID0+ICRMb2dPYmplY3QsCiAgICAgICAgREJPYmplY3QgICAgID0+ICREQk9iamVjdCwKICAgICAgICBNYWluT2JqZWN0ICAgPT4gJE1haW5PYmplY3QsCiAgICApOwoKPWN1dAoKc3ViIG5ldyB7CiAgICBteSAoICRUeXBlLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgYWxsb2NhdGUgbmV3IGhhc2ggZm9yIG9iamVjdAogICAgbXkgJFNlbGYgPSB7fTsKICAgIGJsZXNzKCAkU2VsZiwgJFR5cGUgKTsKCiAgICAjIGNoZWNrIG5lZWRlZCBvYmplY3RzCiAgICBmb3IgbXkgJE9iamVjdCAocXcoREJPYmplY3QgQ29uZmlnT2JqZWN0IExvZ09iamVjdCBFbmNvZGVPYmplY3QgTWFpbk9iamVjdCkpIHsKICAgICAgICAkU2VsZi0+eyRPYmplY3R9ID0gJFBhcmFteyRPYmplY3R9IHx8IGRpZSAiR290IG5vICRPYmplY3QhIjsKICAgIH0KICAgICRTZWxmLT57Q2hlY2tJdGVtT2JqZWN0fSA9IEtlcm5lbDo6U3lzdGVtOjpDaGVja0l0ZW0tPm5ldyggJXskU2VsZn0gKTsKICAgICRTZWxmLT57VmFsaWRPYmplY3R9ICAgICA9IEtlcm5lbDo6U3lzdGVtOjpWYWxpZC0+bmV3KCAleyRTZWxmfSApOwoKICAgICMgbG9hZCBnZW5lcmF0b3IgcHJlZmVyZW5jZXMgbW9kdWxlCiAgICBteSAkR2VuZXJhdG9yTW9kdWxlID0gJFNlbGYtPntDb25maWdPYmplY3R9LT5HZXQoJ1NlcnZpY2U6OlByZWZlcmVuY2VzTW9kdWxlJykKICAgICAgICB8fCAnS2VybmVsOjpTeXN0ZW06OlNlcnZpY2U6OlByZWZlcmVuY2VzREInOwogICAgaWYgKCAkU2VsZi0+e01haW5PYmplY3R9LT5SZXF1aXJlKCRHZW5lcmF0b3JNb2R1bGUpICkgewogICAgICAgICRTZWxmLT57UHJlZmVyZW5jZXNPYmplY3R9ID0gJEdlbmVyYXRvck1vZHVsZS0+bmV3KCVQYXJhbSk7CiAgICB9CgogICAgcmV0dXJuICRTZWxmOwp9Cgo9aXRlbSBTZXJ2aWNlTGlzdCgpCgpyZXR1cm4gYSBoYXNoIGxpc3Qgb2Ygc2VydmljZXMKCiAgICBteSAlU2VydmljZUxpc3QgPSAkU2VydmljZU9iamVjdC0+U2VydmljZUxpc3QoCiAgICAgICAgVmFsaWQgID0+IDAsICAgIyAob3B0aW9uYWwpIGRlZmF1bHQgMSAoMHwxKQogICAgICAgIFVzZXJJRCA9PiAxLAogICAgKTsKCj1jdXQKCnN1YiBTZXJ2aWNlTGlzdCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgY2hlY2sgbmVlZGVkIHN0dWZmCiAgICBpZiAoICEkUGFyYW17VXNlcklEfSApIHsKICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZygKICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgTWVzc2FnZSAgPT4gJ05lZWQgVXNlcklEIScsCiAgICAgICAgKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgIyBjaGVjayB2YWxpZCBwYXJhbQogICAgaWYgKCAhZGVmaW5lZCAkUGFyYW17VmFsaWR9ICkgewogICAgICAgICRQYXJhbXtWYWxpZH0gPSAxOwogICAgfQoKICAgICMgYXNrIGRhdGFiYXNlCiAgICAkU2VsZi0+e0RCT2JqZWN0fS0+UHJlcGFyZSgKICAgICAgICBTUUwgPT4gJ1NFTEVDVCBpZCwgbmFtZSwgdmFsaWRfaWQgRlJPTSBzZXJ2aWNlJywKICAgICk7CgogICAgIyBmZXRjaCB0aGUgcmVzdWx0CiAgICBteSAlU2VydmljZUxpc3Q7CiAgICBteSAlU2VydmljZVZhbGlkTGlzdDsKICAgIHdoaWxlICggbXkgQFJvdyA9ICRTZWxmLT57REJPYmplY3R9LT5GZXRjaHJvd0FycmF5KCkgKSB7CiAgICAgICAgJFNlcnZpY2VMaXN0eyAkUm93WzBdIH0gICAgICA9ICRSb3dbMV07CiAgICAgICAgJFNlcnZpY2VWYWxpZExpc3R7ICRSb3dbMF0gfSA9ICRSb3dbMl07CiAgICB9CgogICAgcmV0dXJuICVTZXJ2aWNlTGlzdCBpZiAhJFBhcmFte1ZhbGlkfTsKCiAgICAjIGdldCB2YWxpZCBpZHMKICAgIG15IEBWYWxpZElEcyA9ICRTZWxmLT57VmFsaWRPYmplY3R9LT5WYWxpZElEc0dldCgpOwoKICAgICMgZHVwbGljYXRlIHNlcnZpY2UgbGlzdAogICAgbXkgJVNlcnZpY2VMaXN0VG1wID0gJVNlcnZpY2VMaXN0OwoKICAgICMgYWRkIHN1ZmZpeCBmb3IgY29ycmVjdCBzb3J0aW5nCiAgICBmb3IgbXkgJFNlcnZpY2VJRCAoIGtleXMgJVNlcnZpY2VMaXN0VG1wICkgewogICAgICAgICRTZXJ2aWNlTGlzdFRtcHskU2VydmljZUlEfSAuPSAnOjonOwogICAgfQoKICAgIG15ICVTZXJ2aWNlSW52YWxpZExpc3Q7CiAgICBTRVJWSUNFSUQ6CiAgICBmb3IgbXkgJFNlcnZpY2VJRCAoIHNvcnQgeyAkU2VydmljZUxpc3RUbXB7JGF9IGNtcCAkU2VydmljZUxpc3RUbXB7JGJ9IH0ga2V5cyAlU2VydmljZUxpc3RUbXAgKQogICAgewoKICAgICAgICBteSAkVmFsaWQgPSBzY2FsYXIgZ3JlcCB7ICRfIGVxICRTZXJ2aWNlVmFsaWRMaXN0eyRTZXJ2aWNlSUR9IH0gQFZhbGlkSURzOwoKICAgICAgICBuZXh0IFNFUlZJQ0VJRCBpZiAkVmFsaWQ7CgogICAgICAgICRTZXJ2aWNlSW52YWxpZExpc3R7ICRTZXJ2aWNlTGlzdHskU2VydmljZUlEfSB9ID0gMTsKICAgICAgICBkZWxldGUgJFNlcnZpY2VMaXN0eyRTZXJ2aWNlSUR9OwogICAgfQoKICAgICMgZGVsZXRlIGludmFsaWQgc2VydmljZXMgYW5kIGNoaWxkcwogICAgZm9yIG15ICRTZXJ2aWNlSUQgKCBrZXlzICVTZXJ2aWNlTGlzdCApIHsKCiAgICAgICAgSU5WQUxJRE5BTUU6CiAgICAgICAgZm9yIG15ICRJbnZhbGlkTmFtZSAoIGtleXMgJVNlcnZpY2VJbnZhbGlkTGlzdCApIHsKCiAgICAgICAgICAgIGlmICggJFNlcnZpY2VMaXN0eyRTZXJ2aWNlSUR9ID1+IG17IFxBICRJbnZhbGlkTmFtZSA6OiB9eG1zICkgewogICAgICAgICAgICAgICAgZGVsZXRlICRTZXJ2aWNlTGlzdHskU2VydmljZUlEfTsKICAgICAgICAgICAgICAgIGxhc3QgSU5WQUxJRE5BTUU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuICVTZXJ2aWNlTGlzdDsKfQoKPWl0ZW0gU2VydmljZUdldCgpCgpyZXR1cm4gYSBzZXJ2aWNlIGFzIGhhc2gKClJldHVybgogICAgJFNlcnZpY2VEYXRhe1NlcnZpY2VJRH0KICAgICRTZXJ2aWNlRGF0YXtQYXJlbnRJRH0KICAgICRTZXJ2aWNlRGF0YXtOYW1lfQogICAgJFNlcnZpY2VEYXRhe05hbWVTaG9ydH0KICAgICRTZXJ2aWNlRGF0YXtWYWxpZElEfQogICAgJFNlcnZpY2VEYXRhe0NvbW1lbnR9CiAgICAkU2VydmljZURhdGF7Q3JlYXRlVGltZX0KICAgICRTZXJ2aWNlRGF0YXtDcmVhdGVCeX0KICAgICRTZXJ2aWNlRGF0YXtDaGFuZ2VUaW1lfQogICAgJFNlcnZpY2VEYXRhe0NoYW5nZUJ5fQoKICAgIG15ICVTZXJ2aWNlRGF0YSA9ICRTZXJ2aWNlT2JqZWN0LT5TZXJ2aWNlR2V0KAogICAgICAgIFNlcnZpY2VJRCA9PiAxMjMsCiAgICAgICAgVXNlcklEICAgID0+IDEsCiAgICApOwoKPWN1dAoKc3ViIFNlcnZpY2VHZXQgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGNoZWNrIG5lZWRlZCBzdHVmZgogICAgZm9yIG15ICRBcmd1bWVudCAocXcoU2VydmljZUlEIFVzZXJJRCkpIHsKICAgICAgICBpZiAoICEkUGFyYW17JEFyZ3VtZW50fSApIHsKICAgICAgICAgICAgJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coCiAgICAgICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICAgICAgTWVzc2FnZSAgPT4gIk5lZWQgJEFyZ3VtZW50ISIsCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICB9CgogICAgIyBnZXQgc2VydmljZSBmcm9tIGRiCiAgICAkU2VsZi0+e0RCT2JqZWN0fS0+UHJlcGFyZSgKICAgICAgICBTUUwgPT4KICAgICAgICAgICAgJ1NFTEVDVCBpZCwgbmFtZSwgdmFsaWRfaWQsIGNvbW1lbnRzLCBjcmVhdGVfdGltZSwgY3JlYXRlX2J5LCBjaGFuZ2VfdGltZSwgY2hhbmdlX2J5ICcKICAgICAgICAgICAgLiAnRlJPTSBzZXJ2aWNlIFdIRVJFIGlkID0gPycsCiAgICAgICAgQmluZCAgPT4gWyBcJFBhcmFte1NlcnZpY2VJRH0gXSwKICAgICAgICBMaW1pdCA9PiAxLAogICAgKTsKCiAgICAjIGZldGNoIHRoZSByZXN1bHQKICAgIG15ICVTZXJ2aWNlRGF0YTsKICAgIHdoaWxlICggbXkgQFJvdyA9ICRTZWxmLT57REJPYmplY3R9LT5GZXRjaHJvd0FycmF5KCkgKSB7CiAgICAgICAgJFNlcnZpY2VEYXRhe1NlcnZpY2VJRH0gID0gJFJvd1swXTsKICAgICAgICAkU2VydmljZURhdGF7TmFtZX0gICAgICAgPSAkUm93WzFdOwogICAgICAgICRTZXJ2aWNlRGF0YXtWYWxpZElEfSAgICA9ICRSb3dbMl07CiAgICAgICAgJFNlcnZpY2VEYXRhe0NvbW1lbnR9ICAgID0gJFJvd1szXSB8fCAnJzsKICAgICAgICAkU2VydmljZURhdGF7Q3JlYXRlVGltZX0gPSAkUm93WzRdOwogICAgICAgICRTZXJ2aWNlRGF0YXtDcmVhdGVCeX0gICA9ICRSb3dbNV07CiAgICAgICAgJFNlcnZpY2VEYXRhe0NoYW5nZVRpbWV9ID0gJFJvd1s2XTsKICAgICAgICAkU2VydmljZURhdGF7Q2hhbmdlQnl9ICAgPSAkUm93WzddOwogICAgfQoKICAgICMgY2hlY2sgc2VydmljZQogICAgaWYgKCAhJFNlcnZpY2VEYXRhe1NlcnZpY2VJRH0gKSB7CiAgICAgICAgJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coCiAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgIE1lc3NhZ2UgID0+ICJObyBzdWNoIFNlcnZpY2VJRCAoJFBhcmFte1NlcnZpY2VJRH0pISIsCiAgICAgICAgKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgIyBjcmVhdGUgc2hvcnQgbmFtZSBhbmQgcGFyZW50aWQKICAgICRTZXJ2aWNlRGF0YXtOYW1lU2hvcnR9ID0gJFNlcnZpY2VEYXRhe05hbWV9OwogICAgaWYgKCAkU2VydmljZURhdGF7TmFtZX0gPX4gL14oLiopOjooLis/KSQvICkgewogICAgICAgICRTZXJ2aWNlRGF0YXtOYW1lU2hvcnR9ID0gJDI7CgogICAgICAgICMgbG9va3VwIHBhcmVudAogICAgICAgIG15ICRTZXJ2aWNlSUQgPSAkU2VsZi0+U2VydmljZUxvb2t1cCgKICAgICAgICAgICAgTmFtZSA9PiAkMSwKICAgICAgICApOwogICAgICAgICRTZXJ2aWNlRGF0YXtQYXJlbnRJRH0gPSAkU2VydmljZUlEOwogICAgfQoKICAgICMgZ2V0IHNlcnZpY2UgcHJlZmVyZW5jZXMKICAgIG15ICVQcmVmZXJlbmNlcyA9ICRTZWxmLT5TZXJ2aWNlUHJlZmVyZW5jZXNHZXQoCiAgICAgICAgU2VydmljZUlEID0+ICRQYXJhbXtTZXJ2aWNlSUR9LAogICAgKTsKCiAgICAjIG1lcmdlIGhhc2gKICAgIGlmICglUHJlZmVyZW5jZXMpIHsKICAgICAgICAlU2VydmljZURhdGEgPSAoICVTZXJ2aWNlRGF0YSwgJVByZWZlcmVuY2VzICk7CiAgICB9CgogICAgcmV0dXJuICVTZXJ2aWNlRGF0YTsKfQoKPWl0ZW0gU2VydmljZUxvb2t1cCgpCgpyZXR1cm4gYSBzZXJ2aWNlIG5hbWUgYW5kIGlkCgogICAgbXkgJFNlcnZpY2VOYW1lID0gJFNlcnZpY2VPYmplY3QtPlNlcnZpY2VMb29rdXAoCiAgICAgICAgU2VydmljZUlEID0+IDEyMywKICAgICk7CgogICAgb3IKCiAgICBteSAkU2VydmljZUlEID0gJFNlcnZpY2VPYmplY3QtPlNlcnZpY2VMb29rdXAoCiAgICAgICAgTmFtZSA9PiAnU2VydmljZTo6U3ViU2VydmljZScsCiAgICApOwoKPWN1dAoKc3ViIFNlcnZpY2VMb29rdXAgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGNoZWNrIG5lZWRlZCBzdHVmZgogICAgaWYgKCAhJFBhcmFte1NlcnZpY2VJRH0gJiYgISRQYXJhbXtOYW1lfSApIHsKICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZygKICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgTWVzc2FnZSAgPT4gJ05lZWQgU2VydmljZUlEIG9yIE5hbWUhJywKICAgICAgICApOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBpZiAoICRQYXJhbXtTZXJ2aWNlSUR9ICkgewoKICAgICAgICAjIGNoZWNrIGNhY2hlCiAgICAgICAgbXkgJENhY2hlS2V5ID0gJ0NhY2hlOjpTZXJ2aWNlTG9va3VwOjpJRDo6JyAuICRQYXJhbXtTZXJ2aWNlSUR9OwogICAgICAgIGlmICggZGVmaW5lZCAkU2VsZi0+eyRDYWNoZUtleX0gKSB7CiAgICAgICAgICAgIHJldHVybiAkU2VsZi0+eyRDYWNoZUtleX07CiAgICAgICAgfQoKICAgICAgICAjIGxvb2t1cAogICAgICAgICRTZWxmLT57REJPYmplY3R9LT5QcmVwYXJlKAogICAgICAgICAgICBTUUwgICA9PiAnU0VMRUNUIG5hbWUgRlJPTSBzZXJ2aWNlIFdIRVJFIGlkID0gPycsCiAgICAgICAgICAgIEJpbmQgID0+IFsgXCRQYXJhbXtTZXJ2aWNlSUR9IF0sCiAgICAgICAgICAgIExpbWl0ID0+IDEsCiAgICAgICAgKTsKICAgICAgICB3aGlsZSAoIG15IEBSb3cgPSAkU2VsZi0+e0RCT2JqZWN0fS0+RmV0Y2hyb3dBcnJheSgpICkgewogICAgICAgICAgICAkU2VsZi0+eyRDYWNoZUtleX0gPSAkUm93WzBdOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRTZWxmLT57JENhY2hlS2V5fTsKICAgIH0KICAgIGVsc2UgewoKICAgICAgICAjIGNoZWNrIGNhY2hlCiAgICAgICAgbXkgJENhY2hlS2V5ID0gJ0NhY2hlOjpTZXJ2aWNlTG9va3VwOjpOYW1lOjonIC4gJFBhcmFte05hbWV9OwogICAgICAgIGlmICggZGVmaW5lZCAkU2VsZi0+eyRDYWNoZUtleX0gKSB7CiAgICAgICAgICAgIHJldHVybiAkU2VsZi0+eyRDYWNoZUtleX07CiAgICAgICAgfQoKICAgICAgICAjIGxvb2t1cAogICAgICAgICRTZWxmLT57REJPYmplY3R9LT5QcmVwYXJlKAogICAgICAgICAgICBTUUwgICA9PiAnU0VMRUNUIGlkIEZST00gc2VydmljZSBXSEVSRSBuYW1lID0gPycsCiAgICAgICAgICAgIEJpbmQgID0+IFsgXCRQYXJhbXtOYW1lfSBdLAogICAgICAgICAgICBMaW1pdCA9PiAxLAogICAgICAgICk7CiAgICAgICAgd2hpbGUgKCBteSBAUm93ID0gJFNlbGYtPntEQk9iamVjdH0tPkZldGNocm93QXJyYXkoKSApIHsKICAgICAgICAgICAgJFNlbGYtPnskQ2FjaGVLZXl9ID0gJFJvd1swXTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkU2VsZi0+eyRDYWNoZUtleX07CiAgICB9Cn0KCj1pdGVtIFNlcnZpY2VBZGQoKQoKYWRkIGEgc2VydmljZQoKICAgIG15ICRTZXJ2aWNlSUQgPSAkU2VydmljZU9iamVjdC0+U2VydmljZUFkZCgKICAgICAgICBOYW1lICAgICA9PiAnU2VydmljZSBOYW1lJywKICAgICAgICBQYXJlbnRJRCA9PiAxLCAgICAgICAgICAgIyAob3B0aW9uYWwpCiAgICAgICAgVmFsaWRJRCAgPT4gMSwKICAgICAgICBDb21tZW50ICA9PiAnQ29tbWVudCcsICAgICMgKG9wdGlvbmFsKQogICAgICAgIFVzZXJJRCAgID0+IDEsCiAgICApOwoKPWN1dAoKc3ViIFNlcnZpY2VBZGQgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGNoZWNrIG5lZWRlZCBzdHVmZgogICAgZm9yIG15ICRBcmd1bWVudCAocXcoTmFtZSBWYWxpZElEIFVzZXJJRCkpIHsKICAgICAgICBpZiAoICEkUGFyYW17JEFyZ3VtZW50fSApIHsKICAgICAgICAgICAgJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coCiAgICAgICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICAgICAgTWVzc2FnZSAgPT4gIk5lZWQgJEFyZ3VtZW50ISIsCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICB9CgogICAgIyBzZXQgY29tbWVudAogICAgJFBhcmFte0NvbW1lbnR9IHx8PSAnJzsKCiAgICAjIGNsZWFudXAgZ2l2ZW4gcGFyYW1zCiAgICBmb3IgbXkgJEFyZ3VtZW50IChxdyhOYW1lIENvbW1lbnQpKSB7CiAgICAgICAgJFNlbGYtPntDaGVja0l0ZW1PYmplY3R9LT5TdHJpbmdDbGVhbigKICAgICAgICAgICAgU3RyaW5nUmVmICAgICAgICAgPT4gXCRQYXJhbXskQXJndW1lbnR9LAogICAgICAgICAgICBSZW1vdmVBbGxOZXdsaW5lcyA9PiAxLAogICAgICAgICAgICBSZW1vdmVBbGxUYWJzICAgICA9PiAxLAogICAgICAgICk7CiAgICB9CgogICAgIyBjaGVjayBzZXJ2aWNlIG5hbWUKICAgIGlmICggJFBhcmFte05hbWV9ID1+IC86Oi8gKSB7CiAgICAgICAgJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coCiAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgIE1lc3NhZ2UgID0+ICJDYW4ndCBhZGQgc2VydmljZSEgSW52YWxpZCBTZXJ2aWNlIG5hbWUgJyRQYXJhbXtOYW1lfSchIiwKICAgICAgICApOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAjIGNyZWF0ZSBmdWxsIG5hbWUKICAgICRQYXJhbXtGdWxsTmFtZX0gPSAkUGFyYW17TmFtZX07CgogICAgIyBnZXQgcGFyZW50IG5hbWUKICAgIGlmICggJFBhcmFte1BhcmVudElEfSApIHsKICAgICAgICBteSAkUGFyZW50TmFtZSA9ICRTZWxmLT5TZXJ2aWNlTG9va3VwKCBTZXJ2aWNlSUQgPT4gJFBhcmFte1BhcmVudElEfSwgKTsKICAgICAgICBpZiAoJFBhcmVudE5hbWUpIHsKICAgICAgICAgICAgJFBhcmFte0Z1bGxOYW1lfSA9ICRQYXJlbnROYW1lIC4gJzo6JyAuICRQYXJhbXtOYW1lfTsKICAgICAgICB9CiAgICB9CgogICAgIyBmaW5kIGV4aXN0aW5nIHNlcnZpY2UKICAgICRTZWxmLT57REJPYmplY3R9LT5QcmVwYXJlKAogICAgICAgIFNRTCAgID0+ICdTRUxFQ1QgaWQgRlJPTSBzZXJ2aWNlIFdIRVJFIG5hbWUgPSA/JywKICAgICAgICBCaW5kICA9PiBbIFwkUGFyYW17RnVsbE5hbWV9IF0sCiAgICAgICAgTGltaXQgPT4gMSwKICAgICk7CiAgICBteSAkRXhpc3RzOwogICAgd2hpbGUgKCAkU2VsZi0+e0RCT2JqZWN0fS0+RmV0Y2hyb3dBcnJheSgpICkgewogICAgICAgICRFeGlzdHMgPSAxOwogICAgfQoKICAgICMgYWRkIHNlcnZpY2UgdG8gZGF0YWJhc2UKICAgIGlmICgkRXhpc3RzKSB7CiAgICAgICAgJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coCiAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgIE1lc3NhZ2UgID0+ICdDYW5cJ3QgYWRkIHNlcnZpY2UhIFNlcnZpY2Ugd2l0aCBzYW1lIG5hbWUgYW5kIHBhcmVudCBhbHJlYWR5IGV4aXN0cy4nCiAgICAgICAgKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgcmV0dXJuIGlmICEkU2VsZi0+e0RCT2JqZWN0fS0+RG8oCiAgICAgICAgU1FMID0+ICdJTlNFUlQgSU5UTyBzZXJ2aWNlICcKICAgICAgICAgICAgLiAnKG5hbWUsIHZhbGlkX2lkLCBjb21tZW50cywgY3JlYXRlX3RpbWUsIGNyZWF0ZV9ieSwgY2hhbmdlX3RpbWUsIGNoYW5nZV9ieSkgJwogICAgICAgICAgICAuICdWQUxVRVMgKD8sID8sID8sIGN1cnJlbnRfdGltZXN0YW1wLCA/LCBjdXJyZW50X3RpbWVzdGFtcCwgPyknLAogICAgICAgIEJpbmQgPT4gWwogICAgICAgICAgICBcJFBhcmFte0Z1bGxOYW1lfSwgXCRQYXJhbXtWYWxpZElEfSwgXCRQYXJhbXtDb21tZW50fSwKICAgICAgICAgICAgXCRQYXJhbXtVc2VySUR9LCBcJFBhcmFte1VzZXJJRH0sCiAgICAgICAgXSwKICAgICk7CgogICAgIyBnZXQgc2VydmljZSBpZAogICAgJFNlbGYtPntEQk9iamVjdH0tPlByZXBhcmUoCiAgICAgICAgU1FMICAgPT4gJ1NFTEVDVCBpZCBGUk9NIHNlcnZpY2UgV0hFUkUgbmFtZSA9ID8nLAogICAgICAgIEJpbmQgID0+IFsgXCRQYXJhbXtGdWxsTmFtZX0gXSwKICAgICAgICBMaW1pdCA9PiAxLAogICAgKTsKICAgIG15ICRTZXJ2aWNlSUQ7CiAgICB3aGlsZSAoIG15IEBSb3cgPSAkU2VsZi0+e0RCT2JqZWN0fS0+RmV0Y2hyb3dBcnJheSgpICkgewogICAgICAgICRTZXJ2aWNlSUQgPSAkUm93WzBdOwogICAgfQoKICAgICMgcmVzZXQgY2FjaGUKICAgIGRlbGV0ZSAkU2VsZi0+eyAnQ2FjaGU6OlNlcnZpY2VMb29rdXA6OklEOjonIC4gJFNlcnZpY2VJRCB9OwogICAgZGVsZXRlICRTZWxmLT57ICdDYWNoZTo6U2VydmljZUxvb2t1cDo6TmFtZTo6JyAuICRQYXJhbXtGdWxsTmFtZX0gfTsKCiAgICByZXR1cm4gJFNlcnZpY2VJRDsKfQoKPWl0ZW0gU2VydmljZVVwZGF0ZSgpCgp1cGRhdGUgYSBleGlzdGluZyBzZXJ2aWNlCgogICAgbXkgJFRydWUgPSAkU2VydmljZU9iamVjdC0+U2VydmljZVVwZGF0ZSgKICAgICAgICBTZXJ2aWNlSUQgPT4gMTIzLAogICAgICAgIFBhcmVudElEICA9PiAxLCAgICAgICAgICAgIyAob3B0aW9uYWwpCiAgICAgICAgTmFtZSAgICAgID0+ICdTZXJ2aWNlIE5hbWUnLAogICAgICAgIFZhbGlkSUQgICA9PiAxLAogICAgICAgIENvbW1lbnQgICA9PiAnQ29tbWVudCcsICAgICMgKG9wdGlvbmFsKQogICAgICAgIFVzZXJJRCAgICA9PiAxLAogICAgKTsKCj1jdXQKCnN1YiBTZXJ2aWNlVXBkYXRlIHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgIyBjaGVjayBuZWVkZWQgc3R1ZmYKICAgIGZvciBteSAkQXJndW1lbnQgKHF3KFNlcnZpY2VJRCBOYW1lIFZhbGlkSUQgVXNlcklEKSkgewogICAgICAgIGlmICggISRQYXJhbXskQXJndW1lbnR9ICkgewogICAgICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZygKICAgICAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgICAgICBNZXNzYWdlICA9PiAiTmVlZCAkQXJndW1lbnQhIiwKICAgICAgICAgICAgKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgIH0KCiAgICAjIHNldCBkZWZhdWx0IGNvbW1lbnQKICAgICRQYXJhbXtDb21tZW50fSB8fD0gJyc7CgogICAgIyBjbGVhbnVwIGdpdmVuIHBhcmFtcwogICAgZm9yIG15ICRBcmd1bWVudCAocXcoTmFtZSBDb21tZW50KSkgewogICAgICAgICRTZWxmLT57Q2hlY2tJdGVtT2JqZWN0fS0+U3RyaW5nQ2xlYW4oCiAgICAgICAgICAgIFN0cmluZ1JlZiAgICAgICAgID0+IFwkUGFyYW17JEFyZ3VtZW50fSwKICAgICAgICAgICAgUmVtb3ZlQWxsTmV3bGluZXMgPT4gMSwKICAgICAgICAgICAgUmVtb3ZlQWxsVGFicyAgICAgPT4gMSwKICAgICAgICApOwogICAgfQoKICAgICMgY2hlY2sgc2VydmljZSBuYW1lCiAgICBpZiAoICRQYXJhbXtOYW1lfSA9fiAvOjovICkgewogICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKAogICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICBNZXNzYWdlICA9PiAiQ2FuJ3QgdXBkYXRlIHNlcnZpY2UhIEludmFsaWQgU2VydmljZSBuYW1lICckUGFyYW17TmFtZX0nISIsCiAgICAgICAgKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgIyBnZXQgb2xkIG5hbWUgb2Ygc2VydmljZQogICAgbXkgJE9sZFNlcnZpY2VOYW1lID0gJFNlbGYtPlNlcnZpY2VMb29rdXAoIFNlcnZpY2VJRCA9PiAkUGFyYW17U2VydmljZUlEfSwgKTsKCiAgICAjIHJlc2V0IGNhY2hlCiAgICBkZWxldGUgJFNlbGYtPnsgJ0NhY2hlOjpTZXJ2aWNlTG9va3VwOjpJRDo6JyAuICRQYXJhbXtTZXJ2aWNlSUR9IH07CiAgICBkZWxldGUgJFNlbGYtPnsgJ0NhY2hlOjpTZXJ2aWNlTG9va3VwOjpOYW1lOjonIC4gJE9sZFNlcnZpY2VOYW1lIH07CgogICAgIyBjcmVhdGUgZnVsbCBuYW1lCiAgICAkUGFyYW17RnVsbE5hbWV9ID0gJFBhcmFte05hbWV9OwoKICAgICMgZ2V0IHBhcmVudCBuYW1lCiAgICBpZiAoICRQYXJhbXtQYXJlbnRJRH0gKSB7CgogICAgICAgICMgbG9va3VwIHNlcnZpY2UKICAgICAgICBteSAkUGFyZW50TmFtZSA9ICRTZWxmLT5TZXJ2aWNlTG9va3VwKAogICAgICAgICAgICBTZXJ2aWNlSUQgPT4gJFBhcmFte1BhcmVudElEfSwKICAgICAgICApOwoKICAgICAgICBpZiAoJFBhcmVudE5hbWUpIHsKICAgICAgICAgICAgJFBhcmFte0Z1bGxOYW1lfSA9ICRQYXJlbnROYW1lIC4gJzo6JyAuICRQYXJhbXtOYW1lfTsKICAgICAgICB9CgogICAgICAgICMgY2hlY2ssIGlmIHNlbGVjdGVkIHBhcmVudCB3YXMgYSBjaGlsZCBvZiB0aGlzIHNlcnZpY2UKICAgICAgICBpZiAoICRQYXJhbXtGdWxsTmFtZX0gPX4gL14oXFEkT2xkU2VydmljZU5hbWVcRSk6Oi8gKSB7CiAgICAgICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKAogICAgICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgICAgIE1lc3NhZ2UgID0+ICdDYW5cJ3QgdXBkYXRlIHNlcnZpY2UhIEludmFsaWQgcGFyZW50IHdhcyBzZWxlY3RlZC4nCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICB9CgogICAgIyBmaW5kIGV4aXN0cyBzZXJ2aWNlCiAgICAkU2VsZi0+e0RCT2JqZWN0fS0+UHJlcGFyZSgKICAgICAgICBTUUwgICA9PiAnU0VMRUNUIGlkIEZST00gc2VydmljZSBXSEVSRSBuYW1lID0gPycsCiAgICAgICAgQmluZCAgPT4gWyBcJFBhcmFte0Z1bGxOYW1lfSBdLAogICAgICAgIExpbWl0ID0+IDEsCiAgICApOwogICAgbXkgJEV4aXN0czsKICAgIHdoaWxlICggbXkgQFJvdyA9ICRTZWxmLT57REJPYmplY3R9LT5GZXRjaHJvd0FycmF5KCkgKSB7CiAgICAgICAgaWYgKCAkUGFyYW17U2VydmljZUlEfSBuZSAkUm93WzBdICkgewogICAgICAgICAgICAkRXhpc3RzID0gMTsKICAgICAgICB9CiAgICB9CgogICAgIyB1cGRhdGUgc2VydmljZQogICAgaWYgKCRFeGlzdHMpIHsKICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZygKICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgTWVzc2FnZSAgPT4gJ0NhblwndCB1cGRhdGUgc2VydmljZSEgU2VydmljZSB3aXRoIHNhbWUgbmFtZSBhbmQgcGFyZW50IGFscmVhZHkgZXhpc3RzLicKICAgICAgICApOwogICAgICAgIHJldHVybjsKCiAgICB9CgogICAgIyB1cGRhdGUgc2VydmljZQogICAgcmV0dXJuIGlmICEkU2VsZi0+e0RCT2JqZWN0fS0+RG8oCiAgICAgICAgU1FMID0+ICdVUERBVEUgc2VydmljZSBTRVQgbmFtZSA9ID8sIHZhbGlkX2lkID0gPywgY29tbWVudHMgPSA/LCAnCiAgICAgICAgICAgIC4gJyBjaGFuZ2VfdGltZSA9IGN1cnJlbnRfdGltZXN0YW1wLCBjaGFuZ2VfYnkgPSA/IFdIRVJFIGlkID0gPycsCiAgICAgICAgQmluZCA9PiBbCiAgICAgICAgICAgIFwkUGFyYW17RnVsbE5hbWV9LCBcJFBhcmFte1ZhbGlkSUR9LCBcJFBhcmFte0NvbW1lbnR9LAogICAgICAgICAgICBcJFBhcmFte1VzZXJJRH0sIFwkUGFyYW17U2VydmljZUlEfSwKICAgICAgICBdLAogICAgKTsKCiAgICAjIGZpbmQgYWxsIGNoaWxkcwogICAgJFNlbGYtPntEQk9iamVjdH0tPlByZXBhcmUoCiAgICAgICAgU1FMID0+ICJTRUxFQ1QgaWQsIG5hbWUgRlJPTSBzZXJ2aWNlIFdIRVJFIG5hbWUgTElLRSAnIgogICAgICAgICAgICAuICRTZWxmLT57REJPYmplY3R9LT5RdW90ZSggJE9sZFNlcnZpY2VOYW1lLCAnTGlrZScgKQogICAgICAgICAgICAuICI6OiUnIiwKICAgICk7CiAgICBteSBAQ2hpbGRzOwogICAgd2hpbGUgKCBteSBAUm93ID0gJFNlbGYtPntEQk9iamVjdH0tPkZldGNocm93QXJyYXkoKSApIHsKICAgICAgICBteSAlQ2hpbGQ7CiAgICAgICAgJENoaWxke1NlcnZpY2VJRH0gPSAkUm93WzBdOwogICAgICAgICRDaGlsZHtOYW1lfSAgICAgID0gJFJvd1sxXTsKICAgICAgICBwdXNoIEBDaGlsZHMsIFwlQ2hpbGQ7CiAgICB9CgogICAgIyB1cGRhdGUgY2hpbGRzCiAgICBmb3IgbXkgJENoaWxkIChAQ2hpbGRzKSB7CiAgICAgICAgJENoaWxkLT57TmFtZX0gPX4gcy9eKFxRJE9sZFNlcnZpY2VOYW1lXEUpOjovJFBhcmFte0Z1bGxOYW1lfTo6LzsKICAgICAgICAkU2VsZi0+e0RCT2JqZWN0fS0+RG8oCiAgICAgICAgICAgIFNRTCA9PiAnVVBEQVRFIHNlcnZpY2UgU0VUIG5hbWUgPSA/IFdIRVJFIGlkID0gPycsCiAgICAgICAgICAgIEJpbmQgPT4gWyBcJENoaWxkLT57TmFtZX0sIFwkQ2hpbGQtPntTZXJ2aWNlSUR9IF0sCiAgICAgICAgKTsKICAgIH0KICAgIHJldHVybiAxOwp9Cgo9aXRlbSBTZXJ2aWNlU2VhcmNoKCkKCnJldHVybiBzZXJ2aWNlIGlkcyBhcyBhbiBhcnJheQoKICAgIG15IEBTZXJ2aWNlTGlzdCA9ICRTZXJ2aWNlT2JqZWN0LT5TZXJ2aWNlU2VhcmNoKAogICAgICAgIE5hbWUgICA9PiAnU2VydmljZSBOYW1lJywgIyAob3B0aW9uYWwpCiAgICAgICAgTGltaXQgID0+IDEyMiwgICAgICAgICAgICAjIChvcHRpb25hbCkgZGVmYXVsdCAxMDAwCiAgICAgICAgVXNlcklEID0+IDEsCiAgICApOwoKPWN1dAoKc3ViIFNlcnZpY2VTZWFyY2ggewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGNoZWNrIG5lZWRlZCBzdHVmZgogICAgaWYgKCAhJFBhcmFte1VzZXJJRH0gKSB7CiAgICAgICAgJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coCiAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgIE1lc3NhZ2UgID0+ICdOZWVkIFVzZXJJRCEnLAogICAgICAgICk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgICMgc2V0IGRlZmF1bHQgbGltaXQKICAgICRQYXJhbXtMaW1pdH0gfHw9IDEwMDA7CgogICAgIyBjcmVhdGUgc3FsIHF1ZXJ5CiAgICBteSAkU1FMCiAgICAgICAgPSAiU0VMRUNUIGlkIEZST00gc2VydmljZSBXSEVSRSB2YWxpZF9pZCBJTiAoICR7XChqb2luICcsICcsICRTZWxmLT57VmFsaWRPYmplY3R9LT5WYWxpZElEc0dldCgpKX0gKSI7CgogICAgaWYgKCAkUGFyYW17TmFtZX0gKSB7CgogICAgICAgICMgcXVvdGUKICAgICAgICAkUGFyYW17TmFtZX0gPSAkU2VsZi0+e0RCT2JqZWN0fS0+UXVvdGUoICRQYXJhbXtOYW1lfSwgJ0xpa2UnICk7CgogICAgICAgICMgcmVwbGFjZSAqIHdpdGggJSBhbmQgY2xlYW4gdGhlIHN0cmluZwogICAgICAgICRQYXJhbXtOYW1lfSA9fiBzeyBcKisgfXslfXhtc2c7CiAgICAgICAgJFBhcmFte05hbWV9ID1+IHN7ICUrIH17JX14bXNnOwoKICAgICAgICAkU1FMIC49ICIgQU5EIG5hbWUgTElLRSAnJFBhcmFte05hbWV9JyAiOwogICAgfQoKICAgICRTUUwgLj0gJyBPUkRFUiBCWSBuYW1lJzsKCiAgICAjIHNlYXJjaCBzZXJ2aWNlIGluIGRiCiAgICAkU2VsZi0+e0RCT2JqZWN0fS0+UHJlcGFyZSggU1FMID0+ICRTUUwgKTsKCiAgICBteSBAU2VydmljZUxpc3Q7CiAgICB3aGlsZSAoIG15IEBSb3cgPSAkU2VsZi0+e0RCT2JqZWN0fS0+RmV0Y2hyb3dBcnJheSgpICkgewogICAgICAgIHB1c2ggQFNlcnZpY2VMaXN0LCAkUm93WzBdOwogICAgfQoKICAgIHJldHVybiBAU2VydmljZUxpc3Q7Cn0KCj1pdGVtIEN1c3RvbWVyVXNlclNlcnZpY2VNZW1iZXJMaXN0KCkKCnJldHVybnMgYSBsaXN0IG9mIGN1c3RvbWVydXNlci9zZXJ2aWNlIG1lbWJlcnMKCiAgICBTZXJ2aWNlSUQ6IHNlcnZpY2UgaWQKICAgIEN1c3RvbWVyVXNlckxvZ2luOiBjdXN0b21lciB1c2VyIGxvZ2luCiAgICBEZWZhdWx0U2VydmljZXM6IGFjdGl2YXRlIG9yIGRlYWN0aXZhdGUgZGVmYXVsdCBzZXJ2aWNlcwoKICAgIFJlc3VsdDogSEFTSCAtPiByZXR1cm5zIGEgaGFzaCBvZiBrZXkgPT4gc2VydmljZSBpZCwgdmFsdWUgPT4gc2VydmljZSBuYW1lCiAgICAgICAgICAgIE5hbWUgLT4gcmV0dXJucyBhbiBhcnJheSBvZiB1c2VyIG5hbWVzCiAgICAgICAgICAgIElEICAgLT4gcmV0dXJucyBhbiBhcnJheSBvZiB1c2VyIGlkcwoKICAgIEV4YW1wbGUgKGdldCBzZXJ2aWNlcyBvZiBjdXN0b21lciB1c2VyKToKCiAgICAkU2VydmljZU9iamVjdC0+Q3VzdG9tZXJVc2VyU2VydmljZU1lbWJlckxpc3QoCiAgICAgICAgQ3VzdG9tZXJVc2VyTG9naW4gPT4gJ1Rlc3QnLAogICAgICAgIFJlc3VsdCAgICAgICAgICAgID0+ICdIQVNIJywKICAgICAgICBEZWZhdWx0U2VydmljZXMgICA9PiAwLAogICAgKTsKCiAgICBFeGFtcGxlIChnZXQgY3VzdG9tZXIgdXNlciBvZiBzZXJ2aWNlKToKCiAgICAkU2VydmljZU9iamVjdC0+Q3VzdG9tZXJVc2VyU2VydmljZU1lbWJlckxpc3QoCiAgICAgICAgU2VydmljZUlEID0+ICRJRCwKICAgICAgICBSZXN1bHQgICAgPT4gJ0hBU0gnLAogICAgKTsKCj1jdXQKCnN1YiBDdXN0b21lclVzZXJTZXJ2aWNlTWVtYmVyTGlzdCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgY2hlY2sgbmVlZGVkIHN0dWZmCiAgICBpZiAoICEkUGFyYW17UmVzdWx0fSApIHsKICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZygKICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgTWVzc2FnZSAgPT4gJ05lZWQgUmVzdWx0IScsCiAgICAgICAgKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBpZiAoICEkUGFyYW17U2VydmljZUlEfSAmJiAhJFBhcmFte0N1c3RvbWVyVXNlckxvZ2lufSApIHsKICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZygKICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgTWVzc2FnZSAgPT4gJ05lZWQgU2VydmljZUlEIG9yIEN1c3RvbWVyVXNlckxvZ2luIScsCiAgICAgICAgKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgIyBzZXQgZGVmYXVsdAogICAgaWYgKCAhZGVmaW5lZCAkUGFyYW17RGVmYXVsdFNlcnZpY2VzfSApIHsKICAgICAgICAkUGFyYW17RGVmYXVsdFNlcnZpY2VzfSA9IDE7CiAgICB9CgogICAgIyBkYiBxdW90ZQogICAgZm9yICgga2V5cyAlUGFyYW0gKSB7CiAgICAgICAgJFBhcmFteyRffSA9ICRTZWxmLT57REJPYmplY3R9LT5RdW90ZSggJFBhcmFteyRffSApOwogICAgfQogICAgZm9yIChxdyhTZXJ2aWNlSUQpKSB7CiAgICAgICAgJFBhcmFteyRffSA9ICRTZWxmLT57REJPYmplY3R9LT5RdW90ZSggJFBhcmFteyRffSwgJ0ludGVnZXInICk7CiAgICB9CgogICAgIyBjcmVhdGUgY2FjaGUga2V5CiAgICBteSAkQ2FjaGVLZXkgPSAnQ3VzdG9tZXJVc2VyU2VydmljZU1lbWJlckxpc3Q6OicgLiAkUGFyYW17UmVzdWx0fSAuICc6Oic7CiAgICBpZiAoICRQYXJhbXtTZXJ2aWNlSUR9ICkgewogICAgICAgICRDYWNoZUtleSAuPSAnU2VydmljZUlEOjonIC4gJFBhcmFte1NlcnZpY2VJRH07CiAgICB9CiAgICBlbHNpZiAoICRQYXJhbXtDdXN0b21lclVzZXJMb2dpbn0gKSB7CiAgICAgICAgJENhY2hlS2V5IC49ICdDdXN0b21lclVzZXJMb2dpbjo6JyAuICRQYXJhbXtDdXN0b21lclVzZXJMb2dpbn07CiAgICB9CgogICAgIyBjaGVjayBjYWNoZQogICAgaWYgKCAkUGFyYW17U2VydmljZUlEfSB8fCAkUGFyYW17Q3VzdG9tZXJVc2VyTG9naW59ICkgewogICAgICAgIGlmICggJFNlbGYtPntGb3JjZUNhY2hlfSApIHsKICAgICAgICAgICAgJFBhcmFte0NhY2hlZH0gPSAkU2VsZi0+e0ZvcmNlQ2FjaGV9OwogICAgICAgIH0KICAgICAgICBpZiAoICRQYXJhbXtDYWNoZWR9ICYmICRTZWxmLT57JENhY2hlS2V5fSApIHsKICAgICAgICAgICAgaWYgKCByZWYoICRTZWxmLT57JENhY2hlS2V5fSApIGVxICdBUlJBWScgKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gQHsgJFNlbGYtPnskQ2FjaGVLZXl9IH07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzaWYgKCByZWYoICRTZWxmLT57JENhY2hlS2V5fSApIGVxICdIQVNIJyApIHsKICAgICAgICAgICAgICAgIHJldHVybiAleyAkU2VsZi0+eyRDYWNoZUtleX0gfTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAjIHNxbAogICAgbXkgJURhdGE7CiAgICBteSBATmFtZTsKICAgIG15IEBJRDsKICAgIG15ICRTUUwgPSAnU0VMRUNUIHNjdS5zZXJ2aWNlX2lkLCBzY3UuY3VzdG9tZXJfdXNlcl9sb2dpbiwgcy5uYW1lICcKICAgICAgICAuICcgRlJPTSAnCiAgICAgICAgLiAnIHNlcnZpY2VfY3VzdG9tZXJfdXNlciBzY3UsIHNlcnZpY2UgcycKICAgICAgICAuICcgV0hFUkUgJwogICAgICAgIC4gIiBzLnZhbGlkX2lkIElOICggJHtcKGpvaW4gJywgJywgJFNlbGYtPntWYWxpZE9iamVjdH0tPlZhbGlkSURzR2V0KCkpfSApIEFORCAiCiAgICAgICAgLiAnIHMuaWQgPSBzY3Uuc2VydmljZV9pZCBBTkQgJzsKCiAgICBpZiAoICRQYXJhbXtTZXJ2aWNlSUR9ICkgewogICAgICAgICRTUUwgLj0gIiBzY3Uuc2VydmljZV9pZCA9ICRQYXJhbXtTZXJ2aWNlSUR9IjsKICAgIH0KICAgIGVsc2lmICggJFBhcmFte0N1c3RvbWVyVXNlckxvZ2lufSApIHsKICAgICAgICAkU1FMIC49ICIgc2N1LmN1c3RvbWVyX3VzZXJfbG9naW4gPSAnJFBhcmFte0N1c3RvbWVyVXNlckxvZ2lufSciOwogICAgfQoKICAgICRTZWxmLT57REJPYmplY3R9LT5QcmVwYXJlKCBTUUwgPT4gJFNRTCApOwoKICAgIHdoaWxlICggbXkgQFJvdyA9ICRTZWxmLT57REJPYmplY3R9LT5GZXRjaHJvd0FycmF5KCkgKSB7CgogICAgICAgIG15ICRLZXkgICA9ICcnOwogICAgICAgIG15ICRWYWx1ZSA9ICcnOwogICAgICAgIGlmICggJFBhcmFte1NlcnZpY2VJRH0gKSB7CiAgICAgICAgICAgICRLZXkgICA9ICRSb3dbMV07CiAgICAgICAgICAgICRWYWx1ZSA9ICRSb3dbMF07CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICAkS2V5ICAgPSAkUm93WzBdOwogICAgICAgICAgICAkVmFsdWUgPSAkUm93WzJdOwogICAgICAgIH0KCiAgICAgICAgIyByZW1lbWJlciBwZXJtaXNzaW9ucwogICAgICAgIGlmICggIWRlZmluZWQgJERhdGF7JEtleX0gKSB7CiAgICAgICAgICAgICREYXRheyRLZXl9ID0gJFZhbHVlOwogICAgICAgICAgICBwdXNoIEBOYW1lLCAkVmFsdWU7CiAgICAgICAgICAgIHB1c2ggQElELCAgICRLZXk7CiAgICAgICAgfQogICAgfQogICAgaWYgKCAkUGFyYW17Q3VzdG9tZXJVc2VyTG9naW59ICYmICRQYXJhbXtEZWZhdWx0U2VydmljZXN9ICYmICFrZXlzKCVEYXRhKSApIHsKICAgICAgICAlRGF0YSA9ICRTZWxmLT5DdXN0b21lclVzZXJTZXJ2aWNlTWVtYmVyTGlzdCgKICAgICAgICAgICAgQ3VzdG9tZXJVc2VyTG9naW4gPT4gJzxERUZBVUxUPicsCiAgICAgICAgICAgIFJlc3VsdCAgICAgICAgICAgID0+ICdIQVNIJywKICAgICAgICAgICAgRGVmYXVsdFNlcnZpY2VzICAgPT4gMCwKICAgICAgICApOwogICAgICAgIGZvciBteSAkS2V5ICgga2V5cyAlRGF0YSApIHsKICAgICAgICAgICAgcHVzaCBATmFtZSwgJERhdGF7JEtleX07CiAgICAgICAgICAgIHB1c2ggQElELCAgICRLZXk7CiAgICAgICAgfQogICAgfQoKICAgICMgcmV0dXJuIHJlc3VsdAogICAgaWYgKCAkUGFyYW17UmVzdWx0fSAmJiAkUGFyYW17UmVzdWx0fSBlcSAnSUQnICkgewogICAgICAgIGlmICggJFBhcmFte1NlcnZpY2VJRH0gfHwgJFBhcmFte0N1c3RvbWVyVXNlckxvZ2lufSApIHsKCiAgICAgICAgICAgICMgY2FjaGUgcmVzdWx0CiAgICAgICAgICAgICRTZWxmLT57JENhY2hlS2V5fSA9IFxASUQ7CiAgICAgICAgfQogICAgICAgIHJldHVybiBASUQ7CiAgICB9CiAgICBpZiAoICRQYXJhbXtSZXN1bHR9ICYmICRQYXJhbXtSZXN1bHR9IGVxICdOYW1lJyApIHsKICAgICAgICBpZiAoICRQYXJhbXtTZXJ2aWNlSUR9IHx8ICRQYXJhbXtDdXN0b21lclVzZXJMb2dpbn0gKSB7CgogICAgICAgICAgICAjIGNhY2hlIHJlc3VsdAogICAgICAgICAgICAkU2VsZi0+eyRDYWNoZUtleX0gPSBcQE5hbWU7CiAgICAgICAgfQogICAgICAgIHJldHVybiBATmFtZTsKICAgIH0KICAgIGVsc2UgewogICAgICAgIGlmICggJFBhcmFte1NlcnZpY2VJRH0gfHwgJFBhcmFte0N1c3RvbWVyVXNlckxvZ2lufSApIHsKCiAgICAgICAgICAgICMgY2FjaGUgcmVzdWx0CiAgICAgICAgICAgICRTZWxmLT57JENhY2hlS2V5fSA9IFwlRGF0YTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICVEYXRhOwogICAgfQp9Cgo9aXRlbSBDdXN0b21lclVzZXJTZXJ2aWNlTWVtYmVyQWRkKCkKCnRvIGFkZCBhIG1lbWJlciB0byBhIHNlcnZpY2UKCiAgICAkU2VydmljZU9iamVjdC0+Q3VzdG9tZXJVc2VyU2VydmljZU1lbWJlckFkZCgKICAgICAgICBDdXN0b21lclVzZXJMb2dpbiA9PiAnVGVzdDEnLAogICAgICAgIFNlcnZpY2VJRCAgICAgICAgID0+IDYsCiAgICAgICAgQWN0aXZlICAgICAgICAgICAgPT4gMSwKICAgICAgICBVc2VySUQgICAgICAgICAgICA9PiAxMjMsCiAgICApOwoKPWN1dAoKc3ViIEN1c3RvbWVyVXNlclNlcnZpY2VNZW1iZXJBZGQgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGNoZWNrIG5lZWRlZCBzdHVmZgogICAgZm9yIG15ICRBcmd1bWVudCAocXcoQ3VzdG9tZXJVc2VyTG9naW4gU2VydmljZUlEIFVzZXJJRCkpIHsKICAgICAgICBpZiAoICEkUGFyYW17JEFyZ3VtZW50fSApIHsKICAgICAgICAgICAgJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coCiAgICAgICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICAgICAgTWVzc2FnZSAgPT4gIk5lZWQgJEFyZ3VtZW50ISIsCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICB9CgogICAgIyBkZWxldGUgZXhpc3RpbmcgcmVsYXRpb24KICAgIHJldHVybiBpZiAhJFNlbGYtPntEQk9iamVjdH0tPkRvKAogICAgICAgIFNRTCA9PiAnREVMRVRFIEZST00gc2VydmljZV9jdXN0b21lcl91c2VyIFdIRVJFIGN1c3RvbWVyX3VzZXJfbG9naW4gPSA/IEFORCBzZXJ2aWNlX2lkID0gPycsCiAgICAgICAgQmluZCA9PiBbIFwkUGFyYW17Q3VzdG9tZXJVc2VyTG9naW59LCBcJFBhcmFte1NlcnZpY2VJRH0gXSwKICAgICk7CgogICAgIyByZXR1cm4gaWYgcmVsYXRpb24gaXMgbm90IGFjdGl2ZQogICAgcmV0dXJuIGlmICEkUGFyYW17QWN0aXZlfTsKCiAgICAjIGluc2VydCBuZXcgcmVsYXRpb24KICAgIHJldHVybiAkU2VsZi0+e0RCT2JqZWN0fS0+RG8oCiAgICAgICAgU1FMID0+ICdJTlNFUlQgSU5UTyBzZXJ2aWNlX2N1c3RvbWVyX3VzZXIgJwogICAgICAgICAgICAuICcoY3VzdG9tZXJfdXNlcl9sb2dpbiwgc2VydmljZV9pZCwgY3JlYXRlX3RpbWUsIGNyZWF0ZV9ieSkgJwogICAgICAgICAgICAuICdWQUxVRVMgKD8sID8sIGN1cnJlbnRfdGltZXN0YW1wLCA/KScsCiAgICAgICAgQmluZCA9PiBbIFwkUGFyYW17Q3VzdG9tZXJVc2VyTG9naW59LCBcJFBhcmFte1NlcnZpY2VJRH0sIFwkUGFyYW17VXNlcklEfSBdCiAgICApOwp9CgojIGNhcGVJVAoKPWl0ZW0gQ3VzdG9tZXJDb21wYW55U2VydmljZU1lbWJlckxpc3QoKQoKcmV0dXJucyBhIGxpc3Qgb2YgQ3VzdG9tZXJDb21wYW55L3NlcnZpY2UgbWVtYmVycwoKICAgIFNlcnZpY2VJRDogc2VydmljZSBpZAogICAgQ3VzdG9tZXJJRDogY3VzdG9tZXIgSUQKICAgIERlZmF1bHRTZXJ2aWNlczogYWN0aXZhdGUgb3IgZGVhY3RpdmF0ZSBkZWZhdWx0IHNlcnZpY2VzCgogICAgUmVzdWx0OiBIQVNIIC0+IHJldHVybnMgYSBoYXNoIG9mIGtleSA9PiBzZXJ2aWNlIGlkLCB2YWx1ZSA9PiBzZXJ2aWNlIG5hbWUKICAgICAgICAgICAgTmFtZSAtPiByZXR1cm5zIGFuIGFycmF5IG9mIG5hbWVzCiAgICAgICAgICAgIElEICAgLT4gcmV0dXJucyBhbiBhcnJheSBvZiBpZHMKCiAgICBFeGFtcGxlIChnZXQgc2VydmljZXMgb2YgY3VzdG9tZXIgdXNlcik6CgogICAgJFNlcnZpY2VPYmplY3QtPkN1c3RvbWVyQ29tcGFueVNlcnZpY2VNZW1iZXJMaXN0KAogICAgICAgIEN1c3RvbWVySUQgICAgICAgID0+ICdUZXN0JywKICAgICAgICBSZXN1bHQgICAgICAgICAgICA9PiAnSEFTSCcsCiAgICAgICAgRGVmYXVsdFNlcnZpY2VzICAgPT4gMCwKICAgICk7CgogICAgRXhhbXBsZSAoZ2V0IGN1c3RvbWVyIGNvbXBhbnkgb2Ygc2VydmljZSk6CgogICAgJFNlcnZpY2VPYmplY3QtPkN1c3RvbWVyQ29tcGFueVNlcnZpY2VNZW1iZXJMaXN0KAogICAgICAgIFNlcnZpY2VJRCA9PiAkSUQsCiAgICAgICAgUmVzdWx0ICAgID0+ICdIQVNIJywKICAgICk7Cgo9Y3V0CgpzdWIgQ3VzdG9tZXJDb21wYW55U2VydmljZU1lbWJlckxpc3QgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGNoZWNrIG5lZWRlZCBzdHVmZgogICAgaWYgKCAhJFBhcmFte1Jlc3VsdH0gKSB7CiAgICAgICAgJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coCiAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgIE1lc3NhZ2UgID0+ICdOZWVkIFJlc3VsdCEnLAogICAgICAgICk7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgaWYgKCAhJFBhcmFte1NlcnZpY2VJRH0gJiYgISRQYXJhbXtDdXN0b21lcklEfSApIHsKICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZygKICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgTWVzc2FnZSAgPT4gJ05lZWQgU2VydmljZUlEIG9yIEN1c3RvbWVySUQhJywKICAgICAgICApOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAjIHNldCBkZWZhdWx0CiAgICBpZiAoICFkZWZpbmVkICRQYXJhbXtEZWZhdWx0U2VydmljZXN9ICkgewogICAgICAgICRQYXJhbXtEZWZhdWx0U2VydmljZXN9ID0gMTsKICAgIH0KCiAgICAjIGRiIHF1b3RlCiAgICBmb3IgKCBrZXlzICVQYXJhbSApIHsKICAgICAgICAkUGFyYW17JF99ID0gJFNlbGYtPntEQk9iamVjdH0tPlF1b3RlKCAkUGFyYW17JF99ICk7CiAgICB9CiAgICBmb3IgKHF3KFNlcnZpY2VJRCkpIHsKICAgICAgICAkUGFyYW17JF99ID0gJFNlbGYtPntEQk9iamVjdH0tPlF1b3RlKCAkUGFyYW17JF99LCAnSW50ZWdlcicgKTsKICAgIH0KCiAgICAjIGNyZWF0ZSBjYWNoZSBrZXkKICAgIG15ICRDYWNoZUtleSA9ICdDdXN0b21lckNvbXBhbnlTZXJ2aWNlTWVtYmVyTGlzdDo6JyAuICRQYXJhbXtSZXN1bHR9IC4gJzo6JzsKICAgIGlmICggJFBhcmFte1NlcnZpY2VJRH0gKSB7CiAgICAgICAgJENhY2hlS2V5IC49ICdTZXJ2aWNlSUQ6OicgLiAkUGFyYW17U2VydmljZUlEfTsKICAgIH0KICAgIGVsc2lmICggJFBhcmFte0N1c3RvbWVySUR9ICkgewogICAgICAgICRDYWNoZUtleSAuPSAnQ3VzdG9tZXJJRDo6JyAuICRQYXJhbXtDdXN0b21lcklEfTsKICAgIH0KCiAgICAjIGNoZWNrIGNhY2hlCiAgICBpZiAoICRQYXJhbXtTZXJ2aWNlSUR9IHx8ICRQYXJhbXtDdXN0b21lcklEfSApIHsKICAgICAgICBpZiAoICRTZWxmLT57Rm9yY2VDYWNoZX0gKSB7CiAgICAgICAgICAgICRQYXJhbXtDYWNoZWR9ID0gJFNlbGYtPntGb3JjZUNhY2hlfTsKICAgICAgICB9CiAgICAgICAgaWYgKCAkUGFyYW17Q2FjaGVkfSAmJiAkU2VsZi0+eyRDYWNoZUtleX0gKSB7CiAgICAgICAgICAgIGlmICggcmVmKCAkU2VsZi0+eyRDYWNoZUtleX0gKSBlcSAnQVJSQVknICkgewogICAgICAgICAgICAgICAgcmV0dXJuIEB7ICRTZWxmLT57JENhY2hlS2V5fSB9OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2lmICggcmVmKCAkU2VsZi0+eyRDYWNoZUtleX0gKSBlcSAnSEFTSCcgKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJXsgJFNlbGYtPnskQ2FjaGVLZXl9IH07CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgIyBzcWwKICAgIG15ICVEYXRhOwogICAgbXkgQE5hbWU7CiAgICBteSBASUQ7CiAgICBteSAkU1FMID0gJ1NFTEVDVCBzY2Muc2VydmljZV9pZCwgc2NjLmN1c3RvbWVyX2lkLCBzLm5hbWUgJwogICAgICAgIC4gJyBGUk9NICcKICAgICAgICAuICcgc2VydmljZV9jdXN0b21lcl9jb21wYW55IHNjYywgc2VydmljZSBzJwogICAgICAgIC4gJyBXSEVSRSAnCiAgICAgICAgLiAiIHMudmFsaWRfaWQgSU4gKCAke1woam9pbiAnLCAnLCAkU2VsZi0+e1ZhbGlkT2JqZWN0fS0+VmFsaWRJRHNHZXQoKSl9ICkgQU5EICIKICAgICAgICAuICcgcy5pZCA9IHNjYy5zZXJ2aWNlX2lkIEFORCAnOwoKICAgIGlmICggJFBhcmFte1NlcnZpY2VJRH0gKSB7CiAgICAgICAgJFNRTCAuPSAiIHNjYy5zZXJ2aWNlX2lkID0gJFBhcmFte1NlcnZpY2VJRH0iOwogICAgfQogICAgZWxzaWYgKCAkUGFyYW17Q3VzdG9tZXJJRH0gKSB7CiAgICAgICAgJFNRTCAuPSAiIHNjYy5jdXN0b21lcl9pZCA9ICckUGFyYW17Q3VzdG9tZXJJRH0nIjsKICAgIH0KCiAgICAkU2VsZi0+e0RCT2JqZWN0fS0+UHJlcGFyZSggU1FMID0+ICRTUUwgKTsKCiAgICB3aGlsZSAoIG15IEBSb3cgPSAkU2VsZi0+e0RCT2JqZWN0fS0+RmV0Y2hyb3dBcnJheSgpICkgewoKICAgICAgICBteSAkS2V5ICAgPSAnJzsKICAgICAgICBteSAkVmFsdWUgPSAnJzsKICAgICAgICBpZiAoICRQYXJhbXtTZXJ2aWNlSUR9ICkgewogICAgICAgICAgICAkS2V5ICAgPSAkUm93WzFdOwogICAgICAgICAgICAkVmFsdWUgPSAkUm93WzBdOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgJEtleSAgID0gJFJvd1swXTsKICAgICAgICAgICAgJFZhbHVlID0gJFJvd1syXTsKICAgICAgICB9CgogICAgICAgICMgcmVtZW1iZXIgcGVybWlzc2lvbnMKICAgICAgICBpZiAoICFkZWZpbmVkICREYXRheyRLZXl9ICkgewogICAgICAgICAgICAkRGF0YXskS2V5fSA9ICRWYWx1ZTsKICAgICAgICAgICAgcHVzaCBATmFtZSwgJFZhbHVlOwogICAgICAgICAgICBwdXNoIEBJRCwgICAkS2V5OwogICAgICAgIH0KICAgIH0KICAgIGlmICggJFBhcmFte0N1c3RvbWVySUR9ICYmICRQYXJhbXtEZWZhdWx0U2VydmljZXN9ICYmICFrZXlzKCVEYXRhKSApIHsKICAgICAgICAlRGF0YSA9ICRTZWxmLT5DdXN0b21lckNvbXBhbnlTZXJ2aWNlTWVtYmVyTGlzdCgKICAgICAgICAgICAgQ3VzdG9tZXJJRCAgICAgID0+ICc8REVGQVVMVD4nLAogICAgICAgICAgICBSZXN1bHQgICAgICAgICAgPT4gJ0hBU0gnLAogICAgICAgICAgICBEZWZhdWx0U2VydmljZXMgPT4gMCwKICAgICAgICApOwogICAgICAgIGZvciBteSAkS2V5ICgga2V5cyAlRGF0YSApIHsKICAgICAgICAgICAgcHVzaCBATmFtZSwgJERhdGF7JEtleX07CiAgICAgICAgICAgIHB1c2ggQElELCAgICRLZXk7CiAgICAgICAgfQogICAgfQoKICAgICMgcmV0dXJuIHJlc3VsdAogICAgaWYgKCAkUGFyYW17UmVzdWx0fSAmJiAkUGFyYW17UmVzdWx0fSBlcSAnSUQnICkgewogICAgICAgIGlmICggJFBhcmFte1NlcnZpY2VJRH0gfHwgJFBhcmFte0N1c3RvbWVySUR9ICkgewoKICAgICAgICAgICAgIyBjYWNoZSByZXN1bHQKICAgICAgICAgICAgJFNlbGYtPnskQ2FjaGVLZXl9ID0gXEBJRDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIEBJRDsKICAgIH0KICAgIGlmICggJFBhcmFte1Jlc3VsdH0gJiYgJFBhcmFte1Jlc3VsdH0gZXEgJ05hbWUnICkgewogICAgICAgIGlmICggJFBhcmFte1NlcnZpY2VJRH0gfHwgJFBhcmFte0N1c3RvbWVySUR9ICkgewoKICAgICAgICAgICAgIyBjYWNoZSByZXN1bHQKICAgICAgICAgICAgJFNlbGYtPnskQ2FjaGVLZXl9ID0gXEBOYW1lOwogICAgICAgIH0KICAgICAgICByZXR1cm4gQE5hbWU7CiAgICB9CiAgICBlbHNlIHsKICAgICAgICBpZiAoICRQYXJhbXtTZXJ2aWNlSUR9IHx8ICRQYXJhbXtDdXN0b21lcklEfSApIHsKCiAgICAgICAgICAgICMgY2FjaGUgcmVzdWx0CiAgICAgICAgICAgICRTZWxmLT57JENhY2hlS2V5fSA9IFwlRGF0YTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICVEYXRhOwogICAgfQp9Cgo9aXRlbSBDdXN0b21lckNvbXBhbnlTZXJ2aWNlTWVtYmVyQWRkKCkKCnRvIGFkZCBhIG1lbWJlciB0byBhIHNlcnZpY2UKCiAgICAkU2VydmljZU9iamVjdC0+Q3VzdG9tZXJDb21wYW55U2VydmljZU1lbWJlckFkZCgKICAgICAgICBDdXN0b21lcklEICAgICAgICA9PiAnVGVzdDEnLAogICAgICAgIFNlcnZpY2VJRCAgICAgICAgID0+IDYsCiAgICAgICAgQWN0aXZlICAgICAgICAgICAgPT4gMSwKICAgICAgICBVc2VySUQgICAgICAgICAgICA9PiAxMjMsCiAgICApOwoKPWN1dAoKc3ViIEN1c3RvbWVyQ29tcGFueVNlcnZpY2VNZW1iZXJBZGQgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGNoZWNrIG5lZWRlZCBzdHVmZgogICAgZm9yIG15ICRBcmd1bWVudCAocXcoQ3VzdG9tZXJJRCBTZXJ2aWNlSUQgVXNlcklEKSkgewogICAgICAgIGlmICggISRQYXJhbXskQXJndW1lbnR9ICkgewogICAgICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZygKICAgICAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgICAgICBNZXNzYWdlICA9PiAiTmVlZCAkQXJndW1lbnQhIiwKICAgICAgICAgICAgKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgIH0KCiAgICAjIGRlbGV0ZSBleGlzdGluZyByZWxhdGlvbgogICAgcmV0dXJuIGlmICEkU2VsZi0+e0RCT2JqZWN0fS0+RG8oCiAgICAgICAgU1FMID0+ICdERUxFVEUgRlJPTSBzZXJ2aWNlX2N1c3RvbWVyX2NvbXBhbnkgV0hFUkUgY3VzdG9tZXJfaWQgPSA/IEFORCBzZXJ2aWNlX2lkID0gPycsCiAgICAgICAgQmluZCA9PiBbIFwkUGFyYW17Q3VzdG9tZXJJRH0sIFwkUGFyYW17U2VydmljZUlEfSBdLAogICAgKTsKCiAgICAjIHJldHVybiBpZiByZWxhdGlvbiBpcyBub3QgYWN0aXZlCiAgICByZXR1cm4gaWYgISRQYXJhbXtBY3RpdmV9OwoKICAgICMgaW5zZXJ0IG5ldyByZWxhdGlvbgogICAgcmV0dXJuICRTZWxmLT57REJPYmplY3R9LT5EbygKICAgICAgICBTUUwgPT4gJ0lOU0VSVCBJTlRPIHNlcnZpY2VfY3VzdG9tZXJfY29tcGFueSAnCiAgICAgICAgICAgIC4gJyhjdXN0b21lcl9pZCwgc2VydmljZV9pZCwgY3JlYXRlX3RpbWUsIGNyZWF0ZV9ieSkgJwogICAgICAgICAgICAuICdWQUxVRVMgKD8sID8sIGN1cnJlbnRfdGltZXN0YW1wLCA/KScsCiAgICAgICAgQmluZCA9PiBbIFwkUGFyYW17Q3VzdG9tZXJJRH0sIFwkUGFyYW17U2VydmljZUlEfSwgXCRQYXJhbXtVc2VySUR9IF0KICAgICk7Cn0KCiMgRU8gY2FwZUlUCgo9aXRlbSBTZXJ2aWNlUHJlZmVyZW5jZXNTZXQoKQoKc2V0IHF1ZXVlIHByZWZlcmVuY2VzCgogICAgJFNlcnZpY2VPYmplY3QtPlNlcnZpY2VQcmVmZXJlbmNlc1NldCgKICAgICAgICBTZXJ2aWNlSUQgPT4gMTIzLAogICAgICAgIEtleSAgICAgICA9PiAnVXNlckNvbW1lbnQnLAogICAgICAgIFZhbHVlICAgICA9PiAnc29tZSBjb21tZW50JywKICAgICAgICBVc2VySUQgICAgPT4gMTIzLAogICAgKTsKCj1jdXQKCnN1YiBTZXJ2aWNlUHJlZmVyZW5jZXNTZXQgewogICAgbXkgJFNlbGYgPSBzaGlmdDsKCiAgICByZXR1cm4gJFNlbGYtPntQcmVmZXJlbmNlc09iamVjdH0tPlNlcnZpY2VQcmVmZXJlbmNlc1NldChAXyk7Cn0KCj1pdGVtIFNlcnZpY2VQcmVmZXJlbmNlc0dldCgpCgpnZXQgcXVldWUgcHJlZmVyZW5jZXMKCiAgICBteSAlUHJlZmVyZW5jZXMgPSAkU2VydmljZU9iamVjdC0+U2VydmljZVByZWZlcmVuY2VzR2V0KAogICAgICAgIFNlcnZpY2VJRCA9PiAxMjMsCiAgICAgICAgVXNlcklEICAgID0+IDEyMywKICAgICk7Cgo9Y3V0CgpzdWIgU2VydmljZVByZWZlcmVuY2VzR2V0IHsKICAgIG15ICRTZWxmID0gc2hpZnQ7CgogICAgcmV0dXJuICRTZWxmLT57UHJlZmVyZW5jZXNPYmplY3R9LT5TZXJ2aWNlUHJlZmVyZW5jZXNHZXQoQF8pOwp9CgoxOwoKPWJhY2sKCj1oZWFkMSBURVJNUyBBTkQgQ09ORElUSU9OUwoKVGhpcyBzb2Z0d2FyZSBpcyBwYXJ0IG9mIHRoZSBPVFJTIHByb2plY3QgKGh0dHA6Ly9vdHJzLm9yZy8pLgoKVGhpcyBzb2Z0d2FyZSBjb21lcyB3aXRoIEFCU09MVVRFTFkgTk8gV0FSUkFOVFkuIEZvciBkZXRhaWxzLCBzZWUKdGhlIGVuY2xvc2VkIGZpbGUgQ09QWUlORyBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbiAoQUdQTCkuIElmIHlvdQpkaWQgbm90IHJlY2VpdmUgdGhpcyBmaWxlLCBzZWUgaHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwudHh0LgoKPWN1dAoKPWhlYWQxIFZFUlNJT04KCiRSZXZpc2lvbjogMS4xICQgJERhdGU6IDIwMTAtMTAtMDcgMTY6MTU6NTkgJAoKPWN1dAo= IyAtLQojIEtlcm5lbC9TeXN0ZW0vVGlja2V0L1RpY2tldEV4dGVuc2lvbkN1c3RvbWVyQ29tcGFueVNlcnZpY2UucG0gLSBjdXN0b20gdGlja2V0IGV4dGVuc2lvbgojCiMgQ29weXJpZ2h0IChDKSAyMDA2LTIwMTAgYy5hLnAuZS4gSVQgR21iSCwgaHR0cDovL3d3dy5jYXBlLWl0LmRlCiMKIyB3cml0dGVuL2VkaXRlZCBieToKIyAgIFJlbmUoZG90KUJvZWhtKGF0KWNhcGUtaXQuZGUKIwojIC0tCiMgJElkOiBUaWNrZXRFeHRlbnNpb25DdXN0b21lckNvbXBhbnlTZXJ2aWNlLnBtLHYgMS4xIDIwMTAtMTAtMDcgMTY6MTU6NTkgcmJvIEV4cCAkCiMgLS0KIyBUaGlzIHNvZnR3YXJlIGNvbWVzIHdpdGggQUJTT0xVVEVMWSBOTyBXQVJSQU5UWS4gRm9yIGRldGFpbHMsIHNlZQojIHRoZSBlbmNsb3NlZCBmaWxlIENPUFlJTkcgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24gKEdQTCkuIElmIHlvdQojIGRpZCBub3QgcmVjZWl2ZSB0aGlzIGZpbGUsIHNlZSBodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvZ3BsLTIuMC50eHQuCiMgLS0KCnBhY2thZ2UgS2VybmVsOjpTeXN0ZW06OlRpY2tldDo6VGlja2V0RXh0ZW5zaW9uQ3VzdG9tZXJDb21wYW55U2VydmljZTsKCnVzZSBzdHJpY3Q7CnVzZSB3YXJuaW5nczsKCnVzZSB2YXJzIHF3KCRWRVJTSU9OKTsKJFZFUlNJT04gPSBxdygkUmV2aXNpb246IDEuMSAkKSBbMV07CgojIGRpc2FibGUgcmVkZWZpbmUgd2FybmluZ3MgaW4gdGhpcyBzY29wZQp7CiAgICBubyB3YXJuaW5ncyAncmVkZWZpbmUnOwoKPWl0ZW0gVGlja2V0U2VydmljZUxpc3QoKQoKdG8gZ2V0IGFsbCBwb3NzaWJsZSBzZXJ2aWNlcyBmb3IgYSB0aWNrZXQgKGRlcGVuZHMgb24gd29ya2Zsb3csIGlmIGNvbmZpZ3VyZWQpCgogICAgbXkgJVNlcnZpY2VzID0gJFRpY2tldE9iamVjdC0+VGlja2V0U2VydmljZUxpc3QoCiAgICAgICAgUXVldWVJRCAgICAgICAgPT4gMTIzLAogICAgICAgIFVzZXJJRCAgICAgICAgID0+IDEyMywKICAgICk7CgogICAgbXkgJVNlcnZpY2VzID0gJFRpY2tldE9iamVjdC0+VGlja2V0U2VydmljZUxpc3QoCiAgICAgICAgQ3VzdG9tZXJVc2VySUQgPT4gMTIzLAogICAgICAgIFF1ZXVlSUQgICAgICAgID0+IDEyMywKICAgICk7CgogICAgbXkgJVNlcnZpY2VzID0gJFRpY2tldE9iamVjdC0+VGlja2V0U2VydmljZUxpc3QoCiAgICAgICAgQ3VzdG9tZXJVc2VySUQgPT4gMTIzLAogICAgICAgIFRpY2tldElEICAgICAgID0+IDEyMywKICAgICAgICBVc2VySUQgICAgICAgICA9PiAxMjMsCiAgICApOwoKPWN1dAoKICAgIHN1YiBLZXJuZWw6OlN5c3RlbTo6VGlja2V0OjpUaWNrZXRTZXJ2aWNlTGlzdCB7CiAgICAgICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICAgICAgIyBjaGVjayBuZWVkZWQgc3R1ZmYKICAgICAgICBpZiAoICEkUGFyYW17VXNlcklEfSAmJiAhJFBhcmFte0N1c3RvbWVyVXNlcklEfSApIHsKICAgICAgICAgICAgJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coCiAgICAgICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICAgICAgTWVzc2FnZSAgPT4gJ05lZWQgVXNlcklELCBDdXN0b21lclVzZXJJRCBvciBVc2VySUQgYW5kIEN1c3RvbWVyVXNlcklEIGlzIG5lZWRlZCEnLAogICAgICAgICAgICApOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAjIGNoZWNrIG5lZWRlZCBzdHVmZgogICAgICAgIGlmICggISRQYXJhbXtRdWV1ZUlEfSAmJiAhJFBhcmFte1RpY2tldElEfSApIHsKICAgICAgICAgICAgJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coCiAgICAgICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICAgICAgTWVzc2FnZSAgPT4gJ05lZWQgUXVldWVJRCBvciBUaWNrZXRJRCEnLAogICAgICAgICAgICApOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIG15ICVTZXJ2aWNlcyA9ICgpOwogICAgICAgIGlmICggISRQYXJhbXtDdXN0b21lclVzZXJJRH0gKSB7CiAgICAgICAgICAgICVTZXJ2aWNlcyA9ICRTZWxmLT57U2VydmljZU9iamVjdH0tPlNlcnZpY2VMaXN0KCBVc2VySUQgPT4gMSwgKTsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CgogICAgICAgICAgICAjIGNhcGVJVAogICAgICAgICAgICBteSAlU2VydmljZXNVc2VyID0gJFNlbGYtPntTZXJ2aWNlT2JqZWN0fS0+Q3VzdG9tZXJVc2VyU2VydmljZU1lbWJlckxpc3QoCiAgICAgICAgICAgICAgICBSZXN1bHQgICAgICAgICAgICA9PiAnSEFTSCcsCiAgICAgICAgICAgICAgICBDdXN0b21lclVzZXJMb2dpbiA9PiAkUGFyYW17Q3VzdG9tZXJVc2VySUR9LAogICAgICAgICAgICAgICAgVXNlcklEICAgICAgICAgICAgPT4gMSwKICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICMgZ2V0IGN1c3RvbWVyIHVzZXIgZGF0YQogICAgICAgICAgICBteSAlQ3VzdG9tZXJVc2VyID0gJFNlbGYtPntDdXN0b21lclVzZXJPYmplY3R9LT5DdXN0b21lclVzZXJEYXRhR2V0KAogICAgICAgICAgICAgICAgVXNlciA9PiAkUGFyYW17Q3VzdG9tZXJVc2VySUR9LAogICAgICAgICAgICApOwoKICAgICAgICAgICAgbXkgJVNlcnZpY2VzQ29tcGFueSA9ICRTZWxmLT57U2VydmljZU9iamVjdH0tPkN1c3RvbWVyQ29tcGFueVNlcnZpY2VNZW1iZXJMaXN0KAogICAgICAgICAgICAgICAgUmVzdWx0ICAgICA9PiAnSEFTSCcsCiAgICAgICAgICAgICAgICBDdXN0b21lcklEID0+ICRDdXN0b21lclVzZXJ7VXNlckN1c3RvbWVySUR9LAogICAgICAgICAgICAgICAgVXNlcklEICAgICA9PiAxLAogICAgICAgICAgICApOwoKICAgICAgICAgICAgIyBqb2luIHVzZXIgYW5kIGNvbXBhbnkgc2VydmljZXMKICAgICAgICAgICAgJVNlcnZpY2VzID0gKAogICAgICAgICAgICAgICAgJVNlcnZpY2VzQ29tcGFueSwKICAgICAgICAgICAgICAgICVTZXJ2aWNlc1VzZXIsICAgICMgdXNlciBzZXJ2aWNlcyBhcmUgaGlnaGVyIGluIHByaW9yaXR5CiAgICAgICAgICAgICk7CgogICAgICAgICAgICAjIEVPIGNhcGVJVAogICAgICAgIH0KCiAgICAgICAgIyB3b3JrZmxvdwogICAgICAgIG15ICRBQ0wgPSAkU2VsZi0+VGlja2V0QWNsKAogICAgICAgICAgICAlUGFyYW0sCiAgICAgICAgICAgIFJldHVyblR5cGUgICAgPT4gJ1RpY2tldCcsCiAgICAgICAgICAgIFJldHVyblN1YlR5cGUgPT4gJ1NlcnZpY2UnLAogICAgICAgICAgICBEYXRhICAgICAgICAgID0+IFwlU2VydmljZXMsCiAgICAgICAgKTsKICAgICAgICBpZiAoJEFDTCkgewogICAgICAgICAgICByZXR1cm4gJFNlbGYtPlRpY2tldEFjbERhdGEoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICVTZXJ2aWNlczsKICAgIH0KCiAgICAjIHJlc2V0IGFsbCB3YXJuaW5ncwp9CgoxOwoKPWhlYWQxIFRFUk1TIEFORCBDT05ESVRJT05TCgpUaGlzIHNvZnR3YXJlIGlzIHBhcnQgb2YgdGhlIE9UUlMgcHJvamVjdCAoaHR0cDovL290cnMub3JnLykuCgpUaGlzIHNvZnR3YXJlIGNvbWVzIHdpdGggQUJTT0xVVEVMWSBOTyBXQVJSQU5UWS4gRm9yIGRldGFpbHMsIHNlZQp0aGUgZW5jbG9zZWQgZmlsZSBDT1BZSU5HIGZvciBsaWNlbnNlIGluZm9ybWF0aW9uIChBR1BMKS4gSWYgeW91CmRpZCBub3QgcmVjZWl2ZSB0aGlzIGZpbGUsIHNlZSBodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC50eHQuCgo9Y3V0Cgo9aGVhZDEgVkVSU0lPTgoKJFJldmlzaW9uOiAxLjEgJCAkRGF0ZTogMjAxMC0xMC0wNyAxNjoxNTo1OSAkCgo9Y3V0Cg== IyAtLQojIEtlcm5lbC9TeXN0ZW0vU2VydmljZS5wbSAtIGFsbCBzZXJ2aWNlIGZ1bmN0aW9uCiMgb3JpZ2luYWwgQ29weXJpZ2h0IChDKSAyMDAxLTIwMTAgT1RSUyBBRywgaHR0cDovL290cnMub3JnLwojCiMgRXh0ZW5zaW9ucyBDb3B5cmlnaHQgKEMpIDIwMDYtMjAxMCBjLmEucC5lLiBJVCBHbWJILCBodHRwOi8vd3d3LmNhcGUtaXQuZGUKIwojIHdyaXR0ZW4vZWRpdGVkIGJ5OgojICAgUmVuZShkb3QpQm9laG0oYXQpY2FwZS1pdC5kZQojCiMgLS0KIyAkSWQ6IFNlcnZpY2UucG0sdiAxLjEgMjAxMC0xMC0wNyAxNjoxNTo1OSByYm8gRXhwICQKIyAkT2xkSWQ6IFNlcnZpY2UucG0sdiAxLjM5LjIuMSAyMDEwLzA0LzEzIDE3OjMxOjQ1IHViIEV4cCAkCiMgLS0KIyBUaGlzIHNvZnR3YXJlIGNvbWVzIHdpdGggQUJTT0xVVEVMWSBOTyBXQVJSQU5UWS4gRm9yIGRldGFpbHMsIHNlZQojIHRoZSBlbmNsb3NlZCBmaWxlIENPUFlJTkcgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24gKEFHUEwpLiBJZiB5b3UKIyBkaWQgbm90IHJlY2VpdmUgdGhpcyBmaWxlLCBzZWUgaHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwudHh0LgojIC0tCgpwYWNrYWdlIEtlcm5lbDo6U3lzdGVtOjpTZXJ2aWNlOwoKdXNlIHN0cmljdDsKdXNlIHdhcm5pbmdzOwoKdXNlIEtlcm5lbDo6U3lzdGVtOjpDaGVja0l0ZW07CnVzZSBLZXJuZWw6OlN5c3RlbTo6VmFsaWQ7CgojIC0tLQojIElUU00KIyAtLS0KdXNlIEtlcm5lbDo6U3lzdGVtOjpHZW5lcmFsQ2F0YWxvZzsKdXNlIEtlcm5lbDo6U3lzdGVtOjpMaW5rT2JqZWN0Owp1c2UgS2VybmVsOjpTeXN0ZW06OlRpbWU7CgojIC0tLQoKdXNlIHZhcnMgcXcoQElTQSAkVkVSU0lPTik7CiRWRVJTSU9OID0gcXcoJFJldmlzaW9uOiAxLjEgJCkgWzFdOwoKPWhlYWQxIE5BTUUKCktlcm5lbDo6U3lzdGVtOjpTZXJ2aWNlIC0gc2VydmljZSBsaWIKCj1oZWFkMSBTWU5PUFNJUwoKQWxsIHNlcnZpY2UgZnVuY3Rpb25zLgoKPWhlYWQxIFBVQkxJQyBJTlRFUkZBQ0UKCj1vdmVyIDQKCj1jdXQKCj1pdGVtIG5ldygpCgpjcmVhdGUgYW4gb2JqZWN0CgogICAgdXNlIEtlcm5lbDo6Q29uZmlnOwogICAgdXNlIEtlcm5lbDo6U3lzdGVtOjpFbmNvZGU7CiAgICB1c2UgS2VybmVsOjpTeXN0ZW06OkxvZzsKICAgIHVzZSBLZXJuZWw6OlN5c3RlbTo6TWFpbjsKICAgIHVzZSBLZXJuZWw6OlN5c3RlbTo6REI7CiAgICB1c2UgS2VybmVsOjpTeXN0ZW06OlNlcnZpY2U7CgogICAgbXkgJENvbmZpZ09iamVjdCA9IEtlcm5lbDo6Q29uZmlnLT5uZXcoKTsKICAgIG15ICRFbmNvZGVPYmplY3QgPSBLZXJuZWw6OlN5c3RlbTo6RW5jb2RlLT5uZXcoCiAgICAgICAgQ29uZmlnT2JqZWN0ID0+ICRDb25maWdPYmplY3QsCiAgICApOwogICAgbXkgJExvZ09iamVjdCA9IEtlcm5lbDo6U3lzdGVtOjpMb2ctPm5ldygKICAgICAgICBDb25maWdPYmplY3QgPT4gJENvbmZpZ09iamVjdCwKICAgICAgICBFbmNvZGVPYmplY3QgPT4gJEVuY29kZU9iamVjdCwKICAgICk7CiAgICBteSAkTWFpbk9iamVjdCA9IEtlcm5lbDo6U3lzdGVtOjpNYWluLT5uZXcoCiAgICAgICAgQ29uZmlnT2JqZWN0ID0+ICRDb25maWdPYmplY3QsCiAgICAgICAgRW5jb2RlT2JqZWN0ID0+ICRFbmNvZGVPYmplY3QsCiAgICAgICAgTG9nT2JqZWN0ICAgID0+ICRMb2dPYmplY3QsCiAgICApOwogICAgbXkgJERCT2JqZWN0ID0gS2VybmVsOjpTeXN0ZW06OkRCLT5uZXcoCiAgICAgICAgQ29uZmlnT2JqZWN0ID0+ICRDb25maWdPYmplY3QsCiAgICAgICAgRW5jb2RlT2JqZWN0ID0+ICRFbmNvZGVPYmplY3QsCiAgICAgICAgTG9nT2JqZWN0ICAgID0+ICRMb2dPYmplY3QsCiAgICAgICAgTWFpbk9iamVjdCAgID0+ICRNYWluT2JqZWN0LAogICAgKTsKICAgIG15ICRTZXJ2aWNlT2JqZWN0ID0gS2VybmVsOjpTeXN0ZW06OlNlcnZpY2UtPm5ldygKICAgICAgICBDb25maWdPYmplY3QgPT4gJENvbmZpZ09iamVjdCwKICAgICAgICBFbmNvZGVPYmplY3QgPT4gJEVuY29kZU9iamVjdCwKICAgICAgICBMb2dPYmplY3QgICAgPT4gJExvZ09iamVjdCwKICAgICAgICBEQk9iamVjdCAgICAgPT4gJERCT2JqZWN0LAogICAgICAgIE1haW5PYmplY3QgICA9PiAkTWFpbk9iamVjdCwKICAgICk7Cgo9Y3V0CgpzdWIgbmV3IHsKICAgIG15ICggJFR5cGUsICVQYXJhbSApID0gQF87CgogICAgIyBhbGxvY2F0ZSBuZXcgaGFzaCBmb3Igb2JqZWN0CiAgICBteSAkU2VsZiA9IHt9OwogICAgYmxlc3MoICRTZWxmLCAkVHlwZSApOwoKICAgICMgY2hlY2sgbmVlZGVkIG9iamVjdHMKICAgIGZvciBteSAkT2JqZWN0IChxdyhEQk9iamVjdCBDb25maWdPYmplY3QgTG9nT2JqZWN0IEVuY29kZU9iamVjdCBNYWluT2JqZWN0KSkgewogICAgICAgICRTZWxmLT57JE9iamVjdH0gPSAkUGFyYW17JE9iamVjdH0gfHwgZGllICJHb3Qgbm8gJE9iamVjdCEiOwogICAgfQogICAgJFNlbGYtPntDaGVja0l0ZW1PYmplY3R9ID0gS2VybmVsOjpTeXN0ZW06OkNoZWNrSXRlbS0+bmV3KCAleyRTZWxmfSApOwogICAgJFNlbGYtPntWYWxpZE9iamVjdH0gICAgID0gS2VybmVsOjpTeXN0ZW06OlZhbGlkLT5uZXcoICV7JFNlbGZ9ICk7CgogICAgIyAtLS0KICAgICMgSVRTTQogICAgIyAtLS0KICAgICRTZWxmLT57VGltZU9iamVjdH0gICAgICAgICAgID0gS2VybmVsOjpTeXN0ZW06OlRpbWUtPm5ldyggJXskU2VsZn0gKTsKICAgICRTZWxmLT57R2VuZXJhbENhdGFsb2dPYmplY3R9ID0gS2VybmVsOjpTeXN0ZW06OkdlbmVyYWxDYXRhbG9nLT5uZXcoICV7JFNlbGZ9ICk7CiAgICAkU2VsZi0+e0xpbmtPYmplY3R9ICAgICAgICAgICA9IEtlcm5lbDo6U3lzdGVtOjpMaW5rT2JqZWN0LT5uZXcoICV7JFNlbGZ9ICk7CgogICAgIyAtLS0KCiAgICAjIGxvYWQgZ2VuZXJhdG9yIHByZWZlcmVuY2VzIG1vZHVsZQogICAgbXkgJEdlbmVyYXRvck1vZHVsZSA9ICRTZWxmLT57Q29uZmlnT2JqZWN0fS0+R2V0KCdTZXJ2aWNlOjpQcmVmZXJlbmNlc01vZHVsZScpCiAgICAgICAgfHwgJ0tlcm5lbDo6U3lzdGVtOjpTZXJ2aWNlOjpQcmVmZXJlbmNlc0RCJzsKICAgIGlmICggJFNlbGYtPntNYWluT2JqZWN0fS0+UmVxdWlyZSgkR2VuZXJhdG9yTW9kdWxlKSApIHsKICAgICAgICAkU2VsZi0+e1ByZWZlcmVuY2VzT2JqZWN0fSA9ICRHZW5lcmF0b3JNb2R1bGUtPm5ldyglUGFyYW0pOwogICAgfQoKICAgIHJldHVybiAkU2VsZjsKfQoKPWl0ZW0gU2VydmljZUxpc3QoKQoKcmV0dXJuIGEgaGFzaCBsaXN0IG9mIHNlcnZpY2VzCgogICAgbXkgJVNlcnZpY2VMaXN0ID0gJFNlcnZpY2VPYmplY3QtPlNlcnZpY2VMaXN0KAogICAgICAgIFZhbGlkICA9PiAwLCAgICMgKG9wdGlvbmFsKSBkZWZhdWx0IDEgKDB8MSkKICAgICAgICBVc2VySUQgPT4gMSwKICAgICk7Cgo9Y3V0CgpzdWIgU2VydmljZUxpc3QgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGNoZWNrIG5lZWRlZCBzdHVmZgogICAgaWYgKCAhJFBhcmFte1VzZXJJRH0gKSB7CiAgICAgICAgJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coCiAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgIE1lc3NhZ2UgID0+ICdOZWVkIFVzZXJJRCEnLAogICAgICAgICk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgICMgY2hlY2sgdmFsaWQgcGFyYW0KICAgIGlmICggIWRlZmluZWQgJFBhcmFte1ZhbGlkfSApIHsKICAgICAgICAkUGFyYW17VmFsaWR9ID0gMTsKICAgIH0KCiAgICAjIGFzayBkYXRhYmFzZQogICAgJFNlbGYtPntEQk9iamVjdH0tPlByZXBhcmUoCiAgICAgICAgU1FMID0+ICdTRUxFQ1QgaWQsIG5hbWUsIHZhbGlkX2lkIEZST00gc2VydmljZScsCiAgICApOwoKICAgICMgZmV0Y2ggdGhlIHJlc3VsdAogICAgbXkgJVNlcnZpY2VMaXN0OwogICAgbXkgJVNlcnZpY2VWYWxpZExpc3Q7CiAgICB3aGlsZSAoIG15IEBSb3cgPSAkU2VsZi0+e0RCT2JqZWN0fS0+RmV0Y2hyb3dBcnJheSgpICkgewogICAgICAgICRTZXJ2aWNlTGlzdHsgJFJvd1swXSB9ICAgICAgPSAkUm93WzFdOwogICAgICAgICRTZXJ2aWNlVmFsaWRMaXN0eyAkUm93WzBdIH0gPSAkUm93WzJdOwogICAgfQoKICAgIHJldHVybiAlU2VydmljZUxpc3QgaWYgISRQYXJhbXtWYWxpZH07CgogICAgIyBnZXQgdmFsaWQgaWRzCiAgICBteSBAVmFsaWRJRHMgPSAkU2VsZi0+e1ZhbGlkT2JqZWN0fS0+VmFsaWRJRHNHZXQoKTsKCiAgICAjIGR1cGxpY2F0ZSBzZXJ2aWNlIGxpc3QKICAgIG15ICVTZXJ2aWNlTGlzdFRtcCA9ICVTZXJ2aWNlTGlzdDsKCiAgICAjIGFkZCBzdWZmaXggZm9yIGNvcnJlY3Qgc29ydGluZwogICAgZm9yIG15ICRTZXJ2aWNlSUQgKCBrZXlzICVTZXJ2aWNlTGlzdFRtcCApIHsKICAgICAgICAkU2VydmljZUxpc3RUbXB7JFNlcnZpY2VJRH0gLj0gJzo6JzsKICAgIH0KCiAgICBteSAlU2VydmljZUludmFsaWRMaXN0OwogICAgU0VSVklDRUlEOgogICAgZm9yIG15ICRTZXJ2aWNlSUQgKCBzb3J0IHsgJFNlcnZpY2VMaXN0VG1weyRhfSBjbXAgJFNlcnZpY2VMaXN0VG1weyRifSB9IGtleXMgJVNlcnZpY2VMaXN0VG1wICkKICAgIHsKCiAgICAgICAgbXkgJFZhbGlkID0gc2NhbGFyIGdyZXAgeyAkXyBlcSAkU2VydmljZVZhbGlkTGlzdHskU2VydmljZUlEfSB9IEBWYWxpZElEczsKCiAgICAgICAgbmV4dCBTRVJWSUNFSUQgaWYgJFZhbGlkOwoKICAgICAgICAkU2VydmljZUludmFsaWRMaXN0eyAkU2VydmljZUxpc3R7JFNlcnZpY2VJRH0gfSA9IDE7CiAgICAgICAgZGVsZXRlICRTZXJ2aWNlTGlzdHskU2VydmljZUlEfTsKICAgIH0KCiAgICAjIGRlbGV0ZSBpbnZhbGlkIHNlcnZpY2VzIGFuZCBjaGlsZHMKICAgIGZvciBteSAkU2VydmljZUlEICgga2V5cyAlU2VydmljZUxpc3QgKSB7CgogICAgICAgIElOVkFMSUROQU1FOgogICAgICAgIGZvciBteSAkSW52YWxpZE5hbWUgKCBrZXlzICVTZXJ2aWNlSW52YWxpZExpc3QgKSB7CgogICAgICAgICAgICBpZiAoICRTZXJ2aWNlTGlzdHskU2VydmljZUlEfSA9fiBteyBcQSAkSW52YWxpZE5hbWUgOjogfXhtcyApIHsKICAgICAgICAgICAgICAgIGRlbGV0ZSAkU2VydmljZUxpc3R7JFNlcnZpY2VJRH07CiAgICAgICAgICAgICAgICBsYXN0IElOVkFMSUROQU1FOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiAlU2VydmljZUxpc3Q7Cn0KCj1pdGVtIFNlcnZpY2VHZXQoKQoKcmV0dXJuIGEgc2VydmljZSBhcyBoYXNoCgpSZXR1cm4KICAgICRTZXJ2aWNlRGF0YXtTZXJ2aWNlSUR9CiAgICAkU2VydmljZURhdGF7UGFyZW50SUR9CiAgICAkU2VydmljZURhdGF7TmFtZX0KICAgICRTZXJ2aWNlRGF0YXtOYW1lU2hvcnR9CiAgICAkU2VydmljZURhdGF7VmFsaWRJRH0KICAgICRTZXJ2aWNlRGF0YXtDb21tZW50fQogICAgJFNlcnZpY2VEYXRhe0NyZWF0ZVRpbWV9CiAgICAkU2VydmljZURhdGF7Q3JlYXRlQnl9CiAgICAkU2VydmljZURhdGF7Q2hhbmdlVGltZX0KICAgICRTZXJ2aWNlRGF0YXtDaGFuZ2VCeX0KIyAtLS0KIyBJVFNNCiMgLS0tCiAgICAkU2VydmljZURhdGF7VHlwZUlEfQogICAgJFNlcnZpY2VEYXRhe1R5cGV9CiAgICAkU2VydmljZURhdGF7Q3JpdGljYWxpdHlJRH0KICAgICRTZXJ2aWNlRGF0YXtDcml0aWNhbGl0eX0KICAgICRTZXJ2aWNlRGF0YXtDdXJJbmNpU3RhdGVJRH0KICAgICRTZXJ2aWNlRGF0YXtDdXJJbmNpU3RhdGV9CiAgICAkU2VydmljZURhdGF7Q3VySW5jaVN0YXRlVHlwZX0KIyAtLS0KCiAgICBteSAlU2VydmljZURhdGEgPSAkU2VydmljZU9iamVjdC0+U2VydmljZUdldCgKICAgICAgICBTZXJ2aWNlSUQgPT4gMTIzLAogICAgICAgIFVzZXJJRCAgICA9PiAxLAogICAgKTsKCj1jdXQKCnN1YiBTZXJ2aWNlR2V0IHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgIyBjaGVjayBuZWVkZWQgc3R1ZmYKICAgIGZvciBteSAkQXJndW1lbnQgKHF3KFNlcnZpY2VJRCBVc2VySUQpKSB7CiAgICAgICAgaWYgKCAhJFBhcmFteyRBcmd1bWVudH0gKSB7CiAgICAgICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKAogICAgICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgICAgIE1lc3NhZ2UgID0+ICJOZWVkICRBcmd1bWVudCEiLAogICAgICAgICAgICApOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgfQoKICAgICMgZ2V0IHNlcnZpY2UgZnJvbSBkYgogICAgJFNlbGYtPntEQk9iamVjdH0tPlByZXBhcmUoCiAgICAgICAgU1FMID0+CiAgICAgICAgICAgICdTRUxFQ1QgaWQsIG5hbWUsIHZhbGlkX2lkLCBjb21tZW50cywgY3JlYXRlX3RpbWUsIGNyZWF0ZV9ieSwgY2hhbmdlX3RpbWUsIGNoYW5nZV9ieSAnCgogICAgICAgICAgICAjIC0tLQogICAgICAgICAgICAjIElUU00KICAgICAgICAgICAgIyAtLS0KICAgICAgICAgICAgLiAiLCB0eXBlX2lkLCBjcml0aWNhbGl0eV9pZCAiCgogICAgICAgICAgICAjIC0tLQogICAgICAgICAgICAuICdGUk9NIHNlcnZpY2UgV0hFUkUgaWQgPSA/JywKICAgICAgICBCaW5kICA9PiBbIFwkUGFyYW17U2VydmljZUlEfSBdLAogICAgICAgIExpbWl0ID0+IDEsCiAgICApOwoKICAgICMgZmV0Y2ggdGhlIHJlc3VsdAogICAgbXkgJVNlcnZpY2VEYXRhOwogICAgd2hpbGUgKCBteSBAUm93ID0gJFNlbGYtPntEQk9iamVjdH0tPkZldGNocm93QXJyYXkoKSApIHsKICAgICAgICAkU2VydmljZURhdGF7U2VydmljZUlEfSAgPSAkUm93WzBdOwogICAgICAgICRTZXJ2aWNlRGF0YXtOYW1lfSAgICAgICA9ICRSb3dbMV07CiAgICAgICAgJFNlcnZpY2VEYXRhe1ZhbGlkSUR9ICAgID0gJFJvd1syXTsKICAgICAgICAkU2VydmljZURhdGF7Q29tbWVudH0gICAgPSAkUm93WzNdIHx8ICcnOwogICAgICAgICRTZXJ2aWNlRGF0YXtDcmVhdGVUaW1lfSA9ICRSb3dbNF07CiAgICAgICAgJFNlcnZpY2VEYXRhe0NyZWF0ZUJ5fSAgID0gJFJvd1s1XTsKICAgICAgICAkU2VydmljZURhdGF7Q2hhbmdlVGltZX0gPSAkUm93WzZdOwogICAgICAgICRTZXJ2aWNlRGF0YXtDaGFuZ2VCeX0gICA9ICRSb3dbN107CgogICAgICAgICMgLS0tCiAgICAgICAgIyBJVFNNCiAgICAgICAgIyAtLS0KICAgICAgICAkU2VydmljZURhdGF7VHlwZUlEfSAgICAgICAgPSAkUm93WzhdOwogICAgICAgICRTZXJ2aWNlRGF0YXtDcml0aWNhbGl0eUlEfSA9ICRSb3dbOV07CgogICAgICAgICMgLS0tCiAgICB9CgogICAgIyBjaGVjayBzZXJ2aWNlCiAgICBpZiAoICEkU2VydmljZURhdGF7U2VydmljZUlEfSApIHsKICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZygKICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgTWVzc2FnZSAgPT4gIk5vIHN1Y2ggU2VydmljZUlEICgkUGFyYW17U2VydmljZUlEfSkhIiwKICAgICAgICApOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAjIGNyZWF0ZSBzaG9ydCBuYW1lIGFuZCBwYXJlbnRpZAogICAgJFNlcnZpY2VEYXRhe05hbWVTaG9ydH0gPSAkU2VydmljZURhdGF7TmFtZX07CiAgICBpZiAoICRTZXJ2aWNlRGF0YXtOYW1lfSA9fiAvXiguKik6OiguKz8pJC8gKSB7CiAgICAgICAgJFNlcnZpY2VEYXRhe05hbWVTaG9ydH0gPSAkMjsKCiAgICAgICAgIyBsb29rdXAgcGFyZW50CiAgICAgICAgbXkgJFNlcnZpY2VJRCA9ICRTZWxmLT5TZXJ2aWNlTG9va3VwKAogICAgICAgICAgICBOYW1lID0+ICQxLAogICAgICAgICk7CiAgICAgICAgJFNlcnZpY2VEYXRhe1BhcmVudElEfSA9ICRTZXJ2aWNlSUQ7CiAgICB9CgogICAgIyBnZXQgc2VydmljZSBwcmVmZXJlbmNlcwogICAgbXkgJVByZWZlcmVuY2VzID0gJFNlbGYtPlNlcnZpY2VQcmVmZXJlbmNlc0dldCgKICAgICAgICBTZXJ2aWNlSUQgPT4gJFBhcmFte1NlcnZpY2VJRH0sCiAgICApOwoKICAgICMgLS0tCiAgICAjIElUU00KICAgICMgLS0tCgogICAgIyBnZXQgc2VydmljZSB0eXBlIGxpc3QKICAgIG15ICRTZXJ2aWNlVHlwZUxpc3QgPSAkU2VsZi0+e0dlbmVyYWxDYXRhbG9nT2JqZWN0fS0+SXRlbUxpc3QoCiAgICAgICAgQ2xhc3MgPT4gJ0lUU006OlNlcnZpY2U6OlR5cGUnLAogICAgKTsKICAgICRTZXJ2aWNlRGF0YXtUeXBlfSA9ICRTZXJ2aWNlVHlwZUxpc3QtPnsgJFNlcnZpY2VEYXRhe1R5cGVJRH0gfSB8fCAnJzsKCiAgICAjIGdldCBjcml0aWNhbGl0eSBsaXN0CiAgICBteSAkQ3JpdGljYWxpdHlMaXN0ID0gJFNlbGYtPntHZW5lcmFsQ2F0YWxvZ09iamVjdH0tPkl0ZW1MaXN0KAogICAgICAgIENsYXNzID0+ICdJVFNNOjpDb3JlOjpDcml0aWNhbGl0eScsCiAgICApOwogICAgJFNlcnZpY2VEYXRhe0NyaXRpY2FsaXR5fSA9ICRDcml0aWNhbGl0eUxpc3QtPnsgJFNlcnZpY2VEYXRhe0NyaXRpY2FsaXR5SUR9IH0gfHwgJyc7CgogICAgIyBzZXQgZGVmYXVsdCBpbmNpZGVudCBzdGF0ZSB0eXBlCiAgICAkU2VydmljZURhdGF7Q3VySW5jaVN0YXRlVHlwZX0gPSAnb3BlcmF0aW9uYWwnOwoKICAgICMgZ2V0IElUU00gbW9kdWxlIGRpcmVjdG9yeQogICAgbXkgJENvbmZpZ0l0ZW1Nb2R1bGUgPSAkU2VsZi0+e0NvbmZpZ09iamVjdH0tPkdldCgnSG9tZScpIC4gJy9LZXJuZWwvU3lzdGVtL0lUU01Db25maWdJdGVtLnBtJzsKCiAgICAjIGNoZWNrIGlmIElUU01Db25maWd1cmF0aW9uTWFuYWdlbWVudCBwYWNrYWdlIGlzIGluc3RhbGxlZAogICAgaWYgKCAtZSAkQ29uZmlnSXRlbU1vZHVsZSApIHsKCiAgICAgICAgIyBjaGVjayBpZiBhIHByZWZlcmVuY2Ugc2V0dGluZyBmb3IgQ3VySW5jaVN0YXRlVHlwZUZyb21DSXMgZXhpc3RzCiAgICAgICAgaWYgKCAkUHJlZmVyZW5jZXN7Q3VySW5jaVN0YXRlVHlwZUZyb21DSXN9ICkgewoKICAgICAgICAgICAgIyBzZXQgZGVmYXVsdCBpbmNpZGVudCBzdGF0ZSB0eXBlIGZyb20gc2VydmljZSBwcmVmZXJlbmNlcyAnQ3VySW5jaVN0YXRlVHlwZUZyb21DSXMnCiAgICAgICAgICAgICRTZXJ2aWNlRGF0YXtDdXJJbmNpU3RhdGVUeXBlfSA9ICRQcmVmZXJlbmNlc3tDdXJJbmNpU3RhdGVUeXBlRnJvbUNJc307CiAgICAgICAgfQoKICAgICAgICAjIHNldCB0aGUgcHJlZmVyZW5jZXMgc2V0dGluZyBmb3IgQ3VySW5jaVN0YXRlVHlwZUZyb21DSXMKICAgICAgICBlbHNlIHsKCiAgICAgICAgICAgICMgZ2V0IHRoZSBpbmNpZGVudCBsaW5rIHR5cGUKICAgICAgICAgICAgbXkgJExpbmtUeXBlID0gJFNlbGYtPntDb25maWdPYmplY3R9LT5HZXQoJ0lUU006OkNvcmU6OkluY2lkZW50TGlua1R5cGUnKTsKCiAgICAgICAgICAgICMgZmluZCBhbGwgbGlua2VkIGNvbmZpZyBpdGVtcwogICAgICAgICAgICBteSAlTGlua2VkQ29uZmlnSXRlbUlEcyA9ICRTZWxmLT57TGlua09iamVjdH0tPkxpbmtLZXlMaXN0V2l0aERhdGEoCiAgICAgICAgICAgICAgICBPYmplY3QxID0+ICdTZXJ2aWNlJywKICAgICAgICAgICAgICAgIEtleTEgICAgPT4gJFBhcmFte1NlcnZpY2VJRH0sCiAgICAgICAgICAgICAgICBPYmplY3QyID0+ICdJVFNNQ29uZmlnSXRlbScsCiAgICAgICAgICAgICAgICBTdGF0ZSAgID0+ICdWYWxpZCcsCiAgICAgICAgICAgICAgICBUeXBlICAgID0+ICRMaW5rVHlwZSwKICAgICAgICAgICAgICAgIFVzZXJJRCAgPT4gMSwKICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICMgaW52ZXN0aWdhdGUgdGhlIGN1cnJlbnQgaW5jaWRlbnQgc3RhdGUgb2YgZWFjaCBjb25maWcgaXRlbQogICAgICAgICAgICBDT05GSUdJVEVNSUQ6CiAgICAgICAgICAgIGZvciBteSAkQ29uZmlnSXRlbUlEICgga2V5cyAlTGlua2VkQ29uZmlnSXRlbUlEcyApIHsKCiAgICAgICAgICAgICAgICAjIGV4dHJhY3QgY29uZmlnIGl0ZW0gZGF0YQogICAgICAgICAgICAgICAgbXkgJENvbmZpZ0l0ZW1EYXRhID0gJExpbmtlZENvbmZpZ0l0ZW1JRHN7JENvbmZpZ0l0ZW1JRH07CgogICAgICAgICAgICAgICAgbmV4dCBDT05GSUdJVEVNSUQgaWYgJENvbmZpZ0l0ZW1EYXRhLT57Q3VyRGVwbFN0YXRlVHlwZX0gbmUgJ3Byb2R1Y3RpdmUnOwogICAgICAgICAgICAgICAgbmV4dCBDT05GSUdJVEVNSUQgaWYgJENvbmZpZ0l0ZW1EYXRhLT57Q3VySW5jaVN0YXRlVHlwZX0gZXEgJ29wZXJhdGlvbmFsJzsKCiAgICAgICAgICAgICAgICAjIGNoZWNrIGlmIHNlcnZpY2UgbXVzdCBiZSBzZXQgdG8gJ3dhcm5pbmcnCiAgICAgICAgICAgICAgICBpZiAoICRDb25maWdJdGVtRGF0YS0+e0N1ckluY2lTdGF0ZVR5cGV9IGVxICd3YXJuaW5nJyApIHsKICAgICAgICAgICAgICAgICAgICAkU2VydmljZURhdGF7Q3VySW5jaVN0YXRlVHlwZX0gPSAnd2FybmluZyc7CiAgICAgICAgICAgICAgICAgICAgbmV4dCBDT05GSUdJVEVNSUQ7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgIyBjaGVjayBpZiBzZXJ2aWNlIG11c3QgYmUgc2V0IHRvICdpbmNpZGVudCcKICAgICAgICAgICAgICAgIGlmICggJENvbmZpZ0l0ZW1EYXRhLT57Q3VySW5jaVN0YXRlVHlwZX0gZXEgJ2luY2lkZW50JyApIHsKICAgICAgICAgICAgICAgICAgICAkU2VydmljZURhdGF7Q3VySW5jaVN0YXRlVHlwZX0gPSAnaW5jaWRlbnQnOwogICAgICAgICAgICAgICAgICAgIGxhc3QgQ09ORklHSVRFTUlEOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAjIHVwZGF0ZSB0aGUgY3VycmVudCBpbmNpZGVudCBzdGF0ZSB0eXBlIGZyb20gQ0lzIG9mIHRoZSBzZXJ2aWNlCiAgICAgICAgICAgICRTZWxmLT5TZXJ2aWNlUHJlZmVyZW5jZXNTZXQoCiAgICAgICAgICAgICAgICBTZXJ2aWNlSUQgPT4gJFBhcmFte1NlcnZpY2VJRH0sCiAgICAgICAgICAgICAgICBLZXkgICAgICAgPT4gJ0N1ckluY2lTdGF0ZVR5cGVGcm9tQ0lzJywKICAgICAgICAgICAgICAgIFZhbHVlICAgICA9PiAkU2VydmljZURhdGF7Q3VySW5jaVN0YXRlVHlwZX0sCiAgICAgICAgICAgICAgICBVc2VySUQgICAgPT4gMSwKICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICB9CgogICAgIyBpbnZlc3RpZ2F0ZSB0aGUgc3RhdGUgb2YgYWxsIGNoaWxkIHNlcnZpY2VzCiAgICBpZiAoICRTZXJ2aWNlRGF0YXtDdXJJbmNpU3RhdGVUeXBlfSBlcSAnb3BlcmF0aW9uYWwnICkgewoKICAgICAgICAjIGNyZWF0ZSB0aGUgdmFsaWQgc3RyaW5nCiAgICAgICAgbXkgJFZhbGlkSURTdHJpbmcgPSBqb2luIHF7LCB9LCAkU2VsZi0+e1ZhbGlkT2JqZWN0fS0+VmFsaWRJRHNHZXQoKTsKCiAgICAgICAgIyBwcmVwYXJlIG5hbWUKICAgICAgICBteSAkTmFtZSA9ICRTZXJ2aWNlRGF0YXtOYW1lfTsKICAgICAgICAkTmFtZSA9ICRTZWxmLT57REJPYmplY3R9LT5RdW90ZSggJE5hbWUsICdMaWtlJyApOwoKICAgICAgICAjIGdldCBsaXN0IG9mIGFsbCB2YWxpZCBjaGlsZHMKICAgICAgICAkU2VsZi0+e0RCT2JqZWN0fS0+UHJlcGFyZSgKICAgICAgICAgICAgU1FMID0+ICJTRUxFQ1QgaWQsIG5hbWUgRlJPTSBzZXJ2aWNlICIKICAgICAgICAgICAgICAgIC4gIldIRVJFIG5hbWUgTElLRSAnIiAuICROYW1lIC4gIjo6JScgIgogICAgICAgICAgICAgICAgLiAiQU5EIHZhbGlkX2lkIElOICgiIC4gJFZhbGlkSURTdHJpbmcgLiAiKSIsCiAgICAgICAgKTsKCiAgICAgICAgIyBmaW5kIGxlbmd0aCBvZiBjaGlsZHMgcHJlZml4CiAgICAgICAgbXkgJFByZWZpeExlbmd0aCA9IGxlbmd0aCAiJFNlcnZpY2VEYXRhe05hbWV9OjoiOwoKICAgICAgICAjIGZldGNoIHRoZSByZXN1bHQKICAgICAgICBteSBAQ2hpbGRJRHM7CiAgICAgICAgUk9XOgogICAgICAgIHdoaWxlICggbXkgQFJvdyA9ICRTZWxmLT57REJPYmplY3R9LT5GZXRjaHJvd0FycmF5KCkgKSB7CgogICAgICAgICAgICAjIGV4dHJhY3QgY2hpbGQgcGFydAogICAgICAgICAgICBteSAkQ2hpbGRQYXJ0ID0gc3Vic3RyICRSb3dbMV0sICRQcmVmaXhMZW5ndGg7CgogICAgICAgICAgICBuZXh0IFJPVyBpZiAkQ2hpbGRQYXJ0ID1+IG17IDo6IH14bXM7CgogICAgICAgICAgICBwdXNoIEBDaGlsZElEcywgJFJvd1swXTsKICAgICAgICB9CgogICAgICAgIFNFUlZJQ0VJRDoKICAgICAgICBmb3IgbXkgJFNlcnZpY2VJRCAoQENoaWxkSURzKSB7CgogICAgICAgICAgICAjIGdldCBkYXRhIG9mIGNoaWxkIHNlcnZpY2UKICAgICAgICAgICAgbXkgJUNoaWxkU2VydmljZURhdGEgPSAkU2VsZi0+U2VydmljZUdldCgKICAgICAgICAgICAgICAgIFNlcnZpY2VJRCA9PiAkU2VydmljZUlELAogICAgICAgICAgICAgICAgVXNlcklEICAgID0+ICRQYXJhbXtVc2VySUR9LAogICAgICAgICAgICApOwoKICAgICAgICAgICAgbmV4dCBTRVJWSUNFSUQgaWYgJENoaWxkU2VydmljZURhdGF7Q3VySW5jaVN0YXRlVHlwZX0gZXEgJ29wZXJhdGlvbmFsJzsKCiAgICAgICAgICAgICRTZXJ2aWNlRGF0YXtDdXJJbmNpU3RhdGVUeXBlfSA9ICd3YXJuaW5nJzsKICAgICAgICAgICAgbGFzdCBTRVJWSUNFSUQ7CiAgICAgICAgfQogICAgfQoKICAgICMgZGVmaW5lIGRlZmF1bHQgaW5jaWRlbnQgc3RhdGVzCiAgICBteSAlRGVmYXVsdEluY2lTdGF0ZXMgPSAoCiAgICAgICAgb3BlcmF0aW9uYWwgPT4gJ09wZXJhdGlvbmFsJywKICAgICAgICB3YXJuaW5nICAgICA9PiAnV2FybmluZycsCiAgICAgICAgaW5jaWRlbnQgICAgPT4gJ0luY2lkZW50JywKICAgICk7CgogICAgIyBnZXQgdGhlIGluY2lkZW50IHN0YXRlIGxpc3Qgb2YgdGhpcyB0eXBlCiAgICBteSAkSW5jaVN0YXRlTGlzdCA9ICRTZWxmLT57R2VuZXJhbENhdGFsb2dPYmplY3R9LT5JdGVtTGlzdCgKICAgICAgICBDbGFzcyAgICAgICA9PiAnSVRTTTo6Q29yZTo6SW5jaWRlbnRTdGF0ZScsCiAgICAgICAgUHJlZmVyZW5jZXMgPT4gewogICAgICAgICAgICBGdW5jdGlvbmFsaXR5ID0+ICRTZXJ2aWNlRGF0YXtDdXJJbmNpU3RhdGVUeXBlfSwKICAgICAgICB9LAogICAgKTsKCiAgICBteSAlUmV2ZXJzZUluY2lTdGF0ZUxpc3QgPSByZXZlcnNlICV7JEluY2lTdGF0ZUxpc3R9OwogICAgJFNlcnZpY2VEYXRhe0N1ckluY2lTdGF0ZUlEfQogICAgICAgID0gJFJldmVyc2VJbmNpU3RhdGVMaXN0eyAkRGVmYXVsdEluY2lTdGF0ZXN7ICRTZXJ2aWNlRGF0YXtDdXJJbmNpU3RhdGVUeXBlfSB9IH07CgogICAgIyBmYWxsYmFjayBpZiB0aGUgZGVmYXVsdCBpbmNpZGVudCBzdGF0ZSBpcyBkZWFjdGl2YXRlZAogICAgaWYgKCAhJFNlcnZpY2VEYXRhe0N1ckluY2lTdGF0ZUlEfSApIHsKICAgICAgICBteSBAU29ydGVkSW5jaUxpc3QgPSBzb3J0IGtleXMgJXskSW5jaVN0YXRlTGlzdH07CiAgICAgICAgJFNlcnZpY2VEYXRhe0N1ckluY2lTdGF0ZUlEfSA9ICRTb3J0ZWRJbmNpTGlzdFswXTsKICAgIH0KCiAgICAjIGdldCBpbmNpZGVudCBzdGF0ZSBmdW5jdGlvbmFsaXR5CiAgICBteSAkSW5jaVN0YXRlID0gJFNlbGYtPntHZW5lcmFsQ2F0YWxvZ09iamVjdH0tPkl0ZW1HZXQoCiAgICAgICAgSXRlbUlEID0+ICRTZXJ2aWNlRGF0YXtDdXJJbmNpU3RhdGVJRH0sCiAgICApOwoKICAgICRTZXJ2aWNlRGF0YXtDdXJJbmNpU3RhdGV9ICAgICA9ICRJbmNpU3RhdGUtPntOYW1lfTsKICAgICRTZXJ2aWNlRGF0YXtDdXJJbmNpU3RhdGVUeXBlfSA9ICRJbmNpU3RhdGUtPntGdW5jdGlvbmFsaXR5fTsKCiAgICAjIC0tLQoKICAgICMgbWVyZ2UgaGFzaAogICAgaWYgKCVQcmVmZXJlbmNlcykgewogICAgICAgICVTZXJ2aWNlRGF0YSA9ICggJVNlcnZpY2VEYXRhLCAlUHJlZmVyZW5jZXMgKTsKICAgIH0KCiAgICByZXR1cm4gJVNlcnZpY2VEYXRhOwp9Cgo9aXRlbSBTZXJ2aWNlTG9va3VwKCkKCnJldHVybiBhIHNlcnZpY2UgbmFtZSBhbmQgaWQKCiAgICBteSAkU2VydmljZU5hbWUgPSAkU2VydmljZU9iamVjdC0+U2VydmljZUxvb2t1cCgKICAgICAgICBTZXJ2aWNlSUQgPT4gMTIzLAogICAgKTsKCiAgICBvcgoKICAgIG15ICRTZXJ2aWNlSUQgPSAkU2VydmljZU9iamVjdC0+U2VydmljZUxvb2t1cCgKICAgICAgICBOYW1lID0+ICdTZXJ2aWNlOjpTdWJTZXJ2aWNlJywKICAgICk7Cgo9Y3V0CgpzdWIgU2VydmljZUxvb2t1cCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgY2hlY2sgbmVlZGVkIHN0dWZmCiAgICBpZiAoICEkUGFyYW17U2VydmljZUlEfSAmJiAhJFBhcmFte05hbWV9ICkgewogICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKAogICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICBNZXNzYWdlICA9PiAnTmVlZCBTZXJ2aWNlSUQgb3IgTmFtZSEnLAogICAgICAgICk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGlmICggJFBhcmFte1NlcnZpY2VJRH0gKSB7CgogICAgICAgICMgY2hlY2sgY2FjaGUKICAgICAgICBteSAkQ2FjaGVLZXkgPSAnQ2FjaGU6OlNlcnZpY2VMb29rdXA6OklEOjonIC4gJFBhcmFte1NlcnZpY2VJRH07CiAgICAgICAgaWYgKCBkZWZpbmVkICRTZWxmLT57JENhY2hlS2V5fSApIHsKICAgICAgICAgICAgcmV0dXJuICRTZWxmLT57JENhY2hlS2V5fTsKICAgICAgICB9CgogICAgICAgICMgbG9va3VwCiAgICAgICAgJFNlbGYtPntEQk9iamVjdH0tPlByZXBhcmUoCiAgICAgICAgICAgIFNRTCAgID0+ICdTRUxFQ1QgbmFtZSBGUk9NIHNlcnZpY2UgV0hFUkUgaWQgPSA/JywKICAgICAgICAgICAgQmluZCAgPT4gWyBcJFBhcmFte1NlcnZpY2VJRH0gXSwKICAgICAgICAgICAgTGltaXQgPT4gMSwKICAgICAgICApOwogICAgICAgIHdoaWxlICggbXkgQFJvdyA9ICRTZWxmLT57REJPYmplY3R9LT5GZXRjaHJvd0FycmF5KCkgKSB7CiAgICAgICAgICAgICRTZWxmLT57JENhY2hlS2V5fSA9ICRSb3dbMF07CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJFNlbGYtPnskQ2FjaGVLZXl9OwogICAgfQogICAgZWxzZSB7CgogICAgICAgICMgY2hlY2sgY2FjaGUKICAgICAgICBteSAkQ2FjaGVLZXkgPSAnQ2FjaGU6OlNlcnZpY2VMb29rdXA6Ok5hbWU6OicgLiAkUGFyYW17TmFtZX07CiAgICAgICAgaWYgKCBkZWZpbmVkICRTZWxmLT57JENhY2hlS2V5fSApIHsKICAgICAgICAgICAgcmV0dXJuICRTZWxmLT57JENhY2hlS2V5fTsKICAgICAgICB9CgogICAgICAgICMgbG9va3VwCiAgICAgICAgJFNlbGYtPntEQk9iamVjdH0tPlByZXBhcmUoCiAgICAgICAgICAgIFNRTCAgID0+ICdTRUxFQ1QgaWQgRlJPTSBzZXJ2aWNlIFdIRVJFIG5hbWUgPSA/JywKICAgICAgICAgICAgQmluZCAgPT4gWyBcJFBhcmFte05hbWV9IF0sCiAgICAgICAgICAgIExpbWl0ID0+IDEsCiAgICAgICAgKTsKICAgICAgICB3aGlsZSAoIG15IEBSb3cgPSAkU2VsZi0+e0RCT2JqZWN0fS0+RmV0Y2hyb3dBcnJheSgpICkgewogICAgICAgICAgICAkU2VsZi0+eyRDYWNoZUtleX0gPSAkUm93WzBdOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRTZWxmLT57JENhY2hlS2V5fTsKICAgIH0KfQoKPWl0ZW0gU2VydmljZUFkZCgpCgphZGQgYSBzZXJ2aWNlCgogICAgbXkgJFNlcnZpY2VJRCA9ICRTZXJ2aWNlT2JqZWN0LT5TZXJ2aWNlQWRkKAogICAgICAgIE5hbWUgICAgID0+ICdTZXJ2aWNlIE5hbWUnLAogICAgICAgIFBhcmVudElEID0+IDEsICAgICAgICAgICAjIChvcHRpb25hbCkKICAgICAgICBWYWxpZElEICA9PiAxLAogICAgICAgIENvbW1lbnQgID0+ICdDb21tZW50JywgICAgIyAob3B0aW9uYWwpCiAgICAgICAgVXNlcklEICAgPT4gMSwKIyAtLS0KIyBJVFNNCiMgLS0tCiAgICAgICAgVHlwZUlEICAgICAgICA9PiAyLAogICAgICAgIENyaXRpY2FsaXR5SUQgPT4gMSwKIyAtLS0KICAgICk7Cgo9Y3V0CgpzdWIgU2VydmljZUFkZCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgY2hlY2sgbmVlZGVkIHN0dWZmCiAgICAjIC0tLQogICAgIyBJVFNNCiAgICAjIC0tLQogICAgIyAgICBmb3IgbXkgJEFyZ3VtZW50IChxdyhOYW1lIFZhbGlkSUQgVXNlcklEKSkgewogICAgZm9yIG15ICRBcmd1bWVudCAocXcoTmFtZSBWYWxpZElEIFVzZXJJRCBUeXBlSUQgQ3JpdGljYWxpdHlJRCkpIHsKCiAgICAgICAgIyAtLS0KICAgICAgICBpZiAoICEkUGFyYW17JEFyZ3VtZW50fSApIHsKICAgICAgICAgICAgJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coCiAgICAgICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICAgICAgTWVzc2FnZSAgPT4gIk5lZWQgJEFyZ3VtZW50ISIsCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICB9CgogICAgIyBzZXQgY29tbWVudAogICAgJFBhcmFte0NvbW1lbnR9IHx8PSAnJzsKCiAgICAjIGNsZWFudXAgZ2l2ZW4gcGFyYW1zCiAgICBmb3IgbXkgJEFyZ3VtZW50IChxdyhOYW1lIENvbW1lbnQpKSB7CiAgICAgICAgJFNlbGYtPntDaGVja0l0ZW1PYmplY3R9LT5TdHJpbmdDbGVhbigKICAgICAgICAgICAgU3RyaW5nUmVmICAgICAgICAgPT4gXCRQYXJhbXskQXJndW1lbnR9LAogICAgICAgICAgICBSZW1vdmVBbGxOZXdsaW5lcyA9PiAxLAogICAgICAgICAgICBSZW1vdmVBbGxUYWJzICAgICA9PiAxLAogICAgICAgICk7CiAgICB9CgogICAgIyBjaGVjayBzZXJ2aWNlIG5hbWUKICAgIGlmICggJFBhcmFte05hbWV9ID1+IC86Oi8gKSB7CiAgICAgICAgJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coCiAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgIE1lc3NhZ2UgID0+ICJDYW4ndCBhZGQgc2VydmljZSEgSW52YWxpZCBTZXJ2aWNlIG5hbWUgJyRQYXJhbXtOYW1lfSchIiwKICAgICAgICApOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAjIGNyZWF0ZSBmdWxsIG5hbWUKICAgICRQYXJhbXtGdWxsTmFtZX0gPSAkUGFyYW17TmFtZX07CgogICAgIyBnZXQgcGFyZW50IG5hbWUKICAgIGlmICggJFBhcmFte1BhcmVudElEfSApIHsKICAgICAgICBteSAkUGFyZW50TmFtZSA9ICRTZWxmLT5TZXJ2aWNlTG9va3VwKCBTZXJ2aWNlSUQgPT4gJFBhcmFte1BhcmVudElEfSwgKTsKICAgICAgICBpZiAoJFBhcmVudE5hbWUpIHsKICAgICAgICAgICAgJFBhcmFte0Z1bGxOYW1lfSA9ICRQYXJlbnROYW1lIC4gJzo6JyAuICRQYXJhbXtOYW1lfTsKICAgICAgICB9CiAgICB9CgogICAgIyBmaW5kIGV4aXN0aW5nIHNlcnZpY2UKICAgICRTZWxmLT57REJPYmplY3R9LT5QcmVwYXJlKAogICAgICAgIFNRTCAgID0+ICdTRUxFQ1QgaWQgRlJPTSBzZXJ2aWNlIFdIRVJFIG5hbWUgPSA/JywKICAgICAgICBCaW5kICA9PiBbIFwkUGFyYW17RnVsbE5hbWV9IF0sCiAgICAgICAgTGltaXQgPT4gMSwKICAgICk7CiAgICBteSAkRXhpc3RzOwogICAgd2hpbGUgKCAkU2VsZi0+e0RCT2JqZWN0fS0+RmV0Y2hyb3dBcnJheSgpICkgewogICAgICAgICRFeGlzdHMgPSAxOwogICAgfQoKICAgICMgYWRkIHNlcnZpY2UgdG8gZGF0YWJhc2UKICAgIGlmICgkRXhpc3RzKSB7CiAgICAgICAgJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coCiAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgIE1lc3NhZ2UgID0+ICdDYW5cJ3QgYWRkIHNlcnZpY2UhIFNlcnZpY2Ugd2l0aCBzYW1lIG5hbWUgYW5kIHBhcmVudCBhbHJlYWR5IGV4aXN0cy4nCiAgICAgICAgKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgcmV0dXJuIGlmICEkU2VsZi0+e0RCT2JqZWN0fS0+RG8oCgogICAgICAgICMgLS0tCiAgICAgICAgIyBJVFNNCiAgICAgICAgIyAtLS0KICAgICAgICAjICAgICAgICBTUUwgPT4gJ0lOU0VSVCBJTlRPIHNlcnZpY2UgJwogICAgICAgICMgICAgICAgICAgICAuICcobmFtZSwgdmFsaWRfaWQsIGNvbW1lbnRzLCBjcmVhdGVfdGltZSwgY3JlYXRlX2J5LCBjaGFuZ2VfdGltZSwgY2hhbmdlX2J5KSAnCiAgICAgICAgIyAgICAgICAgICAgIC4gJ1ZBTFVFUyAoPywgPywgPywgY3VycmVudF90aW1lc3RhbXAsID8sIGN1cnJlbnRfdGltZXN0YW1wLCA/KScsCiAgICAgICAgIyAgICAgICAgQmluZCA9PiBbCiAgICAgICAgIyAgICAgICAgICAgIFwkUGFyYW17RnVsbE5hbWV9LCBcJFBhcmFte1ZhbGlkSUR9LCBcJFBhcmFte0NvbW1lbnR9LAogICAgICAgICMgICAgICAgICAgICBcJFBhcmFte1VzZXJJRH0sIFwkUGFyYW17VXNlcklEfSwKICAgICAgICAjICAgICAgICBdLAogICAgICAgIFNRTCA9PiAnSU5TRVJUIElOVE8gc2VydmljZSAnCiAgICAgICAgICAgIC4gJyhuYW1lLCB2YWxpZF9pZCwgY29tbWVudHMsIGNyZWF0ZV90aW1lLCBjcmVhdGVfYnksIGNoYW5nZV90aW1lLCBjaGFuZ2VfYnksICcKICAgICAgICAgICAgLiAndHlwZV9pZCwgY3JpdGljYWxpdHlfaWQpICcKICAgICAgICAgICAgLiAnVkFMVUVTICg/LCA/LCA/LCBjdXJyZW50X3RpbWVzdGFtcCwgPywgY3VycmVudF90aW1lc3RhbXAsID8sID8sID8pJywKICAgICAgICBCaW5kID0+IFsKICAgICAgICAgICAgXCRQYXJhbXtGdWxsTmFtZX0sIFwkUGFyYW17VmFsaWRJRH0sIFwkUGFyYW17Q29tbWVudH0sCiAgICAgICAgICAgIFwkUGFyYW17VXNlcklEfSwgXCRQYXJhbXtVc2VySUR9LCBcJFBhcmFte1R5cGVJRH0sIFwkUGFyYW17Q3JpdGljYWxpdHlJRH0sCiAgICAgICAgXSwKCiAgICAgICAgIyAtLS0KICAgICk7CgogICAgIyBnZXQgc2VydmljZSBpZAogICAgJFNlbGYtPntEQk9iamVjdH0tPlByZXBhcmUoCiAgICAgICAgU1FMICAgPT4gJ1NFTEVDVCBpZCBGUk9NIHNlcnZpY2UgV0hFUkUgbmFtZSA9ID8nLAogICAgICAgIEJpbmQgID0+IFsgXCRQYXJhbXtGdWxsTmFtZX0gXSwKICAgICAgICBMaW1pdCA9PiAxLAogICAgKTsKICAgIG15ICRTZXJ2aWNlSUQ7CiAgICB3aGlsZSAoIG15IEBSb3cgPSAkU2VsZi0+e0RCT2JqZWN0fS0+RmV0Y2hyb3dBcnJheSgpICkgewogICAgICAgICRTZXJ2aWNlSUQgPSAkUm93WzBdOwogICAgfQoKICAgICMgcmVzZXQgY2FjaGUKICAgIGRlbGV0ZSAkU2VsZi0+eyAnQ2FjaGU6OlNlcnZpY2VMb29rdXA6OklEOjonIC4gJFNlcnZpY2VJRCB9OwogICAgZGVsZXRlICRTZWxmLT57ICdDYWNoZTo6U2VydmljZUxvb2t1cDo6TmFtZTo6JyAuICRQYXJhbXtGdWxsTmFtZX0gfTsKCiAgICByZXR1cm4gJFNlcnZpY2VJRDsKfQoKPWl0ZW0gU2VydmljZVVwZGF0ZSgpCgp1cGRhdGUgYSBleGlzdGluZyBzZXJ2aWNlCgogICAgbXkgJFRydWUgPSAkU2VydmljZU9iamVjdC0+U2VydmljZVVwZGF0ZSgKICAgICAgICBTZXJ2aWNlSUQgPT4gMTIzLAogICAgICAgIFBhcmVudElEICA9PiAxLCAgICAgICAgICAgIyAob3B0aW9uYWwpCiAgICAgICAgTmFtZSAgICAgID0+ICdTZXJ2aWNlIE5hbWUnLAogICAgICAgIFZhbGlkSUQgICA9PiAxLAogICAgICAgIENvbW1lbnQgICA9PiAnQ29tbWVudCcsICAgICMgKG9wdGlvbmFsKQogICAgICAgIFVzZXJJRCAgICA9PiAxLAojIC0tLQojIElUU00KIyAtLS0KICAgICAgICBUeXBlSUQgICAgICAgID0+IDIsCiAgICAgICAgQ3JpdGljYWxpdHlJRCA9PiAxLAojIC0tLQogICAgKTsKCj1jdXQKCnN1YiBTZXJ2aWNlVXBkYXRlIHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgIyBjaGVjayBuZWVkZWQgc3R1ZmYKICAgICMgLS0tCiAgICAjIElUU00KICAgICMgLS0tCiAgICAjICAgIGZvciBteSAkQXJndW1lbnQgKHF3KFNlcnZpY2VJRCBOYW1lIFZhbGlkSUQgVXNlcklEKSkgewogICAgZm9yIG15ICRBcmd1bWVudCAocXcoU2VydmljZUlEIE5hbWUgVmFsaWRJRCBVc2VySUQgVHlwZUlEIENyaXRpY2FsaXR5SUQpKSB7CgogICAgICAgICMgLS0tCiAgICAgICAgaWYgKCAhJFBhcmFteyRBcmd1bWVudH0gKSB7CiAgICAgICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKAogICAgICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgICAgIE1lc3NhZ2UgID0+ICJOZWVkICRBcmd1bWVudCEiLAogICAgICAgICAgICApOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgfQoKICAgICMgc2V0IGRlZmF1bHQgY29tbWVudAogICAgJFBhcmFte0NvbW1lbnR9IHx8PSAnJzsKCiAgICAjIGNsZWFudXAgZ2l2ZW4gcGFyYW1zCiAgICBmb3IgbXkgJEFyZ3VtZW50IChxdyhOYW1lIENvbW1lbnQpKSB7CiAgICAgICAgJFNlbGYtPntDaGVja0l0ZW1PYmplY3R9LT5TdHJpbmdDbGVhbigKICAgICAgICAgICAgU3RyaW5nUmVmICAgICAgICAgPT4gXCRQYXJhbXskQXJndW1lbnR9LAogICAgICAgICAgICBSZW1vdmVBbGxOZXdsaW5lcyA9PiAxLAogICAgICAgICAgICBSZW1vdmVBbGxUYWJzICAgICA9PiAxLAogICAgICAgICk7CiAgICB9CgogICAgIyBjaGVjayBzZXJ2aWNlIG5hbWUKICAgIGlmICggJFBhcmFte05hbWV9ID1+IC86Oi8gKSB7CiAgICAgICAgJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coCiAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgIE1lc3NhZ2UgID0+ICJDYW4ndCB1cGRhdGUgc2VydmljZSEgSW52YWxpZCBTZXJ2aWNlIG5hbWUgJyRQYXJhbXtOYW1lfSchIiwKICAgICAgICApOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAjIGdldCBvbGQgbmFtZSBvZiBzZXJ2aWNlCiAgICBteSAkT2xkU2VydmljZU5hbWUgPSAkU2VsZi0+U2VydmljZUxvb2t1cCggU2VydmljZUlEID0+ICRQYXJhbXtTZXJ2aWNlSUR9LCApOwoKICAgICMgcmVzZXQgY2FjaGUKICAgIGRlbGV0ZSAkU2VsZi0+eyAnQ2FjaGU6OlNlcnZpY2VMb29rdXA6OklEOjonIC4gJFBhcmFte1NlcnZpY2VJRH0gfTsKICAgIGRlbGV0ZSAkU2VsZi0+eyAnQ2FjaGU6OlNlcnZpY2VMb29rdXA6Ok5hbWU6OicgLiAkT2xkU2VydmljZU5hbWUgfTsKCiAgICAjIGNyZWF0ZSBmdWxsIG5hbWUKICAgICRQYXJhbXtGdWxsTmFtZX0gPSAkUGFyYW17TmFtZX07CgogICAgIyBnZXQgcGFyZW50IG5hbWUKICAgIGlmICggJFBhcmFte1BhcmVudElEfSApIHsKCiAgICAgICAgIyBsb29rdXAgc2VydmljZQogICAgICAgIG15ICRQYXJlbnROYW1lID0gJFNlbGYtPlNlcnZpY2VMb29rdXAoCiAgICAgICAgICAgIFNlcnZpY2VJRCA9PiAkUGFyYW17UGFyZW50SUR9LAogICAgICAgICk7CgogICAgICAgIGlmICgkUGFyZW50TmFtZSkgewogICAgICAgICAgICAkUGFyYW17RnVsbE5hbWV9ID0gJFBhcmVudE5hbWUgLiAnOjonIC4gJFBhcmFte05hbWV9OwogICAgICAgIH0KCiAgICAgICAgIyBjaGVjaywgaWYgc2VsZWN0ZWQgcGFyZW50IHdhcyBhIGNoaWxkIG9mIHRoaXMgc2VydmljZQogICAgICAgIGlmICggJFBhcmFte0Z1bGxOYW1lfSA9fiAvXihcUSRPbGRTZXJ2aWNlTmFtZVxFKTo6LyApIHsKICAgICAgICAgICAgJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coCiAgICAgICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICAgICAgTWVzc2FnZSAgPT4gJ0NhblwndCB1cGRhdGUgc2VydmljZSEgSW52YWxpZCBwYXJlbnQgd2FzIHNlbGVjdGVkLicKICAgICAgICAgICAgKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgIH0KCiAgICAjIGZpbmQgZXhpc3RzIHNlcnZpY2UKICAgICRTZWxmLT57REJPYmplY3R9LT5QcmVwYXJlKAogICAgICAgIFNRTCAgID0+ICdTRUxFQ1QgaWQgRlJPTSBzZXJ2aWNlIFdIRVJFIG5hbWUgPSA/JywKICAgICAgICBCaW5kICA9PiBbIFwkUGFyYW17RnVsbE5hbWV9IF0sCiAgICAgICAgTGltaXQgPT4gMSwKICAgICk7CiAgICBteSAkRXhpc3RzOwogICAgd2hpbGUgKCBteSBAUm93ID0gJFNlbGYtPntEQk9iamVjdH0tPkZldGNocm93QXJyYXkoKSApIHsKICAgICAgICBpZiAoICRQYXJhbXtTZXJ2aWNlSUR9IG5lICRSb3dbMF0gKSB7CiAgICAgICAgICAgICRFeGlzdHMgPSAxOwogICAgICAgIH0KICAgIH0KCiAgICAjIHVwZGF0ZSBzZXJ2aWNlCiAgICBpZiAoJEV4aXN0cykgewogICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKAogICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICBNZXNzYWdlICA9PiAnQ2FuXCd0IHVwZGF0ZSBzZXJ2aWNlISBTZXJ2aWNlIHdpdGggc2FtZSBuYW1lIGFuZCBwYXJlbnQgYWxyZWFkeSBleGlzdHMuJwogICAgICAgICk7CiAgICAgICAgcmV0dXJuOwoKICAgIH0KCiAgICAjIHVwZGF0ZSBzZXJ2aWNlCiAgICByZXR1cm4gaWYgISRTZWxmLT57REJPYmplY3R9LT5EbygKCiAgICAgICAgIyAtLS0KICAgICAgICAjIElUU00KICAgICAgICAjIC0tLQogICAgICAgICMgICAgICAgIFNRTCA9PiAnVVBEQVRFIHNlcnZpY2UgU0VUIG5hbWUgPSA/LCB2YWxpZF9pZCA9ID8sIGNvbW1lbnRzID0gPywgJwogICAgICAgICMgICAgICAgICAgICAuICcgY2hhbmdlX3RpbWUgPSBjdXJyZW50X3RpbWVzdGFtcCwgY2hhbmdlX2J5ID0gPyBXSEVSRSBpZCA9ID8nLAogICAgICAgICMgICAgICAgIEJpbmQgPT4gWwogICAgICAgICMgICAgICAgICAgICBcJFBhcmFte0Z1bGxOYW1lfSwgXCRQYXJhbXtWYWxpZElEfSwgXCRQYXJhbXtDb21tZW50fSwKICAgICAgICAjICAgICAgICAgICAgXCRQYXJhbXtVc2VySUR9LCBcJFBhcmFte1NlcnZpY2VJRH0sCiAgICAgICAgIyAgICAgICAgXSwKICAgICAgICBTUUwgPT4gJ1VQREFURSBzZXJ2aWNlIFNFVCBuYW1lID0gPywgdmFsaWRfaWQgPSA/LCBjb21tZW50cyA9ID8sICcKICAgICAgICAgICAgLiAnIGNoYW5nZV90aW1lID0gY3VycmVudF90aW1lc3RhbXAsIGNoYW5nZV9ieSA9ID8sIHR5cGVfaWQgPSA/LCBjcml0aWNhbGl0eV9pZCA9ID8nCiAgICAgICAgICAgIC4gJyBXSEVSRSBpZCA9ID8nLAogICAgICAgIEJpbmQgPT4gWwogICAgICAgICAgICBcJFBhcmFte0Z1bGxOYW1lfSwgXCRQYXJhbXtWYWxpZElEfSwgXCRQYXJhbXtDb21tZW50fSwKICAgICAgICAgICAgXCRQYXJhbXtVc2VySUR9LCBcJFBhcmFte1R5cGVJRH0sIFwkUGFyYW17Q3JpdGljYWxpdHlJRH0sIFwkUGFyYW17U2VydmljZUlEfSwKICAgICAgICBdLAoKICAgICAgICAjIC0tLQogICAgKTsKCiAgICAjIGZpbmQgYWxsIGNoaWxkcwogICAgJFNlbGYtPntEQk9iamVjdH0tPlByZXBhcmUoCiAgICAgICAgU1FMID0+ICJTRUxFQ1QgaWQsIG5hbWUgRlJPTSBzZXJ2aWNlIFdIRVJFIG5hbWUgTElLRSAnIgogICAgICAgICAgICAuICRTZWxmLT57REJPYmplY3R9LT5RdW90ZSggJE9sZFNlcnZpY2VOYW1lLCAnTGlrZScgKQogICAgICAgICAgICAuICI6OiUnIiwKICAgICk7CiAgICBteSBAQ2hpbGRzOwogICAgd2hpbGUgKCBteSBAUm93ID0gJFNlbGYtPntEQk9iamVjdH0tPkZldGNocm93QXJyYXkoKSApIHsKICAgICAgICBteSAlQ2hpbGQ7CiAgICAgICAgJENoaWxke1NlcnZpY2VJRH0gPSAkUm93WzBdOwogICAgICAgICRDaGlsZHtOYW1lfSAgICAgID0gJFJvd1sxXTsKICAgICAgICBwdXNoIEBDaGlsZHMsIFwlQ2hpbGQ7CiAgICB9CgogICAgIyB1cGRhdGUgY2hpbGRzCiAgICBmb3IgbXkgJENoaWxkIChAQ2hpbGRzKSB7CiAgICAgICAgJENoaWxkLT57TmFtZX0gPX4gcy9eKFxRJE9sZFNlcnZpY2VOYW1lXEUpOjovJFBhcmFte0Z1bGxOYW1lfTo6LzsKICAgICAgICAkU2VsZi0+e0RCT2JqZWN0fS0+RG8oCiAgICAgICAgICAgIFNRTCA9PiAnVVBEQVRFIHNlcnZpY2UgU0VUIG5hbWUgPSA/IFdIRVJFIGlkID0gPycsCiAgICAgICAgICAgIEJpbmQgPT4gWyBcJENoaWxkLT57TmFtZX0sIFwkQ2hpbGQtPntTZXJ2aWNlSUR9IF0sCiAgICAgICAgKTsKICAgIH0KICAgIHJldHVybiAxOwp9Cgo9aXRlbSBTZXJ2aWNlU2VhcmNoKCkKCnJldHVybiBzZXJ2aWNlIGlkcyBhcyBhbiBhcnJheQoKICAgIG15IEBTZXJ2aWNlTGlzdCA9ICRTZXJ2aWNlT2JqZWN0LT5TZXJ2aWNlU2VhcmNoKAogICAgICAgIE5hbWUgICA9PiAnU2VydmljZSBOYW1lJywgIyAob3B0aW9uYWwpCiAgICAgICAgTGltaXQgID0+IDEyMiwgICAgICAgICAgICAjIChvcHRpb25hbCkgZGVmYXVsdCAxMDAwCiAgICAgICAgVXNlcklEID0+IDEsCiMgLS0tCiMgSVRTTQojIC0tLQogICAgICAgIFR5cGVJRHMgICAgICAgID0+IDIsCiAgICAgICAgQ3JpdGljYWxpdHlJRHMgPT4gMSwKIyAtLS0KICAgICk7Cgo9Y3V0CgpzdWIgU2VydmljZVNlYXJjaCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgY2hlY2sgbmVlZGVkIHN0dWZmCiAgICBpZiAoICEkUGFyYW17VXNlcklEfSApIHsKICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZygKICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgTWVzc2FnZSAgPT4gJ05lZWQgVXNlcklEIScsCiAgICAgICAgKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgIyBzZXQgZGVmYXVsdCBsaW1pdAogICAgJFBhcmFte0xpbWl0fSB8fD0gMTAwMDsKCiAgICAjIGNyZWF0ZSBzcWwgcXVlcnkKICAgIG15ICRTUUwKICAgICAgICA9ICJTRUxFQ1QgaWQgRlJPTSBzZXJ2aWNlIFdIRVJFIHZhbGlkX2lkIElOICggJHtcKGpvaW4gJywgJywgJFNlbGYtPntWYWxpZE9iamVjdH0tPlZhbGlkSURzR2V0KCkpfSApIjsKCiAgICBpZiAoICRQYXJhbXtOYW1lfSApIHsKCiAgICAgICAgIyBxdW90ZQogICAgICAgICRQYXJhbXtOYW1lfSA9ICRTZWxmLT57REJPYmplY3R9LT5RdW90ZSggJFBhcmFte05hbWV9LCAnTGlrZScgKTsKCiAgICAgICAgIyByZXBsYWNlICogd2l0aCAlIGFuZCBjbGVhbiB0aGUgc3RyaW5nCiAgICAgICAgJFBhcmFte05hbWV9ID1+IHN7IFwqKyB9eyV9eG1zZzsKICAgICAgICAkUGFyYW17TmFtZX0gPX4gc3sgJSsgfXslfXhtc2c7CgogICAgICAgICRTUUwgLj0gIiBBTkQgbmFtZSBMSUtFICckUGFyYW17TmFtZX0nICI7CiAgICB9CgogICAgIyAtLS0KICAgICMgSVRTTQogICAgIyAtLS0KICAgICMgYWRkIHR5cGUgaWRzCiAgICBpZiAoICRQYXJhbXtUeXBlSURzfSAmJiByZWYgJFBhcmFte1R5cGVJRHN9IGVxICdBUlJBWScgJiYgQHsgJFBhcmFte1R5cGVJRHN9IH0gKSB7CiAgICAgICAgJFNRTCAuPSAiQU5EIHR5cGVfaWQgSU4gKCIgLiBqb2luKCAnLCAnLCBAeyAkUGFyYW17VHlwZUlEc30gfSApIC4gIikgIjsKICAgIH0KCiAgICAjIGFkZCBjcml0aWNhbGl0eSBpZHMKICAgIGlmICggICAkUGFyYW17Q3JpdGljYWxpdHlJRHN9CiAgICAgICAgJiYgcmVmICRQYXJhbXtDcml0aWNhbGl0eUlEc30gZXEgJ0FSUkFZJwogICAgICAgICYmIEB7ICRQYXJhbXtDcml0aWNhbGl0eUlEc30gfSApCiAgICB7CiAgICAgICAgJFNRTCAuPSAiQU5EIGNyaXRpY2FsaXR5X2lkIElOICgiIC4gam9pbiggJywgJywgQHsgJFBhcmFte0NyaXRpY2FsaXR5SURzfSB9ICkgLiAiKSAiOwogICAgfQoKICAgICMgLS0tCgogICAgJFNRTCAuPSAnIE9SREVSIEJZIG5hbWUnOwoKICAgICMgc2VhcmNoIHNlcnZpY2UgaW4gZGIKICAgICRTZWxmLT57REJPYmplY3R9LT5QcmVwYXJlKCBTUUwgPT4gJFNRTCApOwoKICAgIG15IEBTZXJ2aWNlTGlzdDsKICAgIHdoaWxlICggbXkgQFJvdyA9ICRTZWxmLT57REJPYmplY3R9LT5GZXRjaHJvd0FycmF5KCkgKSB7CiAgICAgICAgcHVzaCBAU2VydmljZUxpc3QsICRSb3dbMF07CiAgICB9CgogICAgcmV0dXJuIEBTZXJ2aWNlTGlzdDsKfQoKPWl0ZW0gQ3VzdG9tZXJVc2VyU2VydmljZU1lbWJlckxpc3QoKQoKcmV0dXJucyBhIGxpc3Qgb2YgY3VzdG9tZXJ1c2VyL3NlcnZpY2UgbWVtYmVycwoKICAgIFNlcnZpY2VJRDogc2VydmljZSBpZAogICAgQ3VzdG9tZXJVc2VyTG9naW46IGN1c3RvbWVyIHVzZXIgbG9naW4KICAgIERlZmF1bHRTZXJ2aWNlczogYWN0aXZhdGUgb3IgZGVhY3RpdmF0ZSBkZWZhdWx0IHNlcnZpY2VzCgogICAgUmVzdWx0OiBIQVNIIC0+IHJldHVybnMgYSBoYXNoIG9mIGtleSA9PiBzZXJ2aWNlIGlkLCB2YWx1ZSA9PiBzZXJ2aWNlIG5hbWUKICAgICAgICAgICAgTmFtZSAtPiByZXR1cm5zIGFuIGFycmF5IG9mIHVzZXIgbmFtZXMKICAgICAgICAgICAgSUQgICAtPiByZXR1cm5zIGFuIGFycmF5IG9mIHVzZXIgaWRzCgogICAgRXhhbXBsZSAoZ2V0IHNlcnZpY2VzIG9mIGN1c3RvbWVyIHVzZXIpOgoKICAgICRTZXJ2aWNlT2JqZWN0LT5DdXN0b21lclVzZXJTZXJ2aWNlTWVtYmVyTGlzdCgKICAgICAgICBDdXN0b21lclVzZXJMb2dpbiA9PiAnVGVzdCcsCiAgICAgICAgUmVzdWx0ICAgICAgICAgICAgPT4gJ0hBU0gnLAogICAgICAgIERlZmF1bHRTZXJ2aWNlcyAgID0+IDAsCiAgICApOwoKICAgIEV4YW1wbGUgKGdldCBjdXN0b21lciB1c2VyIG9mIHNlcnZpY2UpOgoKICAgICRTZXJ2aWNlT2JqZWN0LT5DdXN0b21lclVzZXJTZXJ2aWNlTWVtYmVyTGlzdCgKICAgICAgICBTZXJ2aWNlSUQgPT4gJElELAogICAgICAgIFJlc3VsdCAgICA9PiAnSEFTSCcsCiAgICApOwoKPWN1dAoKc3ViIEN1c3RvbWVyVXNlclNlcnZpY2VNZW1iZXJMaXN0IHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgIyBjaGVjayBuZWVkZWQgc3R1ZmYKICAgIGlmICggISRQYXJhbXtSZXN1bHR9ICkgewogICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKAogICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICBNZXNzYWdlICA9PiAnTmVlZCBSZXN1bHQhJywKICAgICAgICApOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIGlmICggISRQYXJhbXtTZXJ2aWNlSUR9ICYmICEkUGFyYW17Q3VzdG9tZXJVc2VyTG9naW59ICkgewogICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKAogICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICBNZXNzYWdlICA9PiAnTmVlZCBTZXJ2aWNlSUQgb3IgQ3VzdG9tZXJVc2VyTG9naW4hJywKICAgICAgICApOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAjIHNldCBkZWZhdWx0CiAgICBpZiAoICFkZWZpbmVkICRQYXJhbXtEZWZhdWx0U2VydmljZXN9ICkgewogICAgICAgICRQYXJhbXtEZWZhdWx0U2VydmljZXN9ID0gMTsKICAgIH0KCiAgICAjIGRiIHF1b3RlCiAgICBmb3IgKCBrZXlzICVQYXJhbSApIHsKICAgICAgICAkUGFyYW17JF99ID0gJFNlbGYtPntEQk9iamVjdH0tPlF1b3RlKCAkUGFyYW17JF99ICk7CiAgICB9CiAgICBmb3IgKHF3KFNlcnZpY2VJRCkpIHsKICAgICAgICAkUGFyYW17JF99ID0gJFNlbGYtPntEQk9iamVjdH0tPlF1b3RlKCAkUGFyYW17JF99LCAnSW50ZWdlcicgKTsKICAgIH0KCiAgICAjIGNyZWF0ZSBjYWNoZSBrZXkKICAgIG15ICRDYWNoZUtleSA9ICdDdXN0b21lclVzZXJTZXJ2aWNlTWVtYmVyTGlzdDo6JyAuICRQYXJhbXtSZXN1bHR9IC4gJzo6JzsKICAgIGlmICggJFBhcmFte1NlcnZpY2VJRH0gKSB7CiAgICAgICAgJENhY2hlS2V5IC49ICdTZXJ2aWNlSUQ6OicgLiAkUGFyYW17U2VydmljZUlEfTsKICAgIH0KICAgIGVsc2lmICggJFBhcmFte0N1c3RvbWVyVXNlckxvZ2lufSApIHsKICAgICAgICAkQ2FjaGVLZXkgLj0gJ0N1c3RvbWVyVXNlckxvZ2luOjonIC4gJFBhcmFte0N1c3RvbWVyVXNlckxvZ2lufTsKICAgIH0KCiAgICAjIGNoZWNrIGNhY2hlCiAgICBpZiAoICRQYXJhbXtTZXJ2aWNlSUR9IHx8ICRQYXJhbXtDdXN0b21lclVzZXJMb2dpbn0gKSB7CiAgICAgICAgaWYgKCAkU2VsZi0+e0ZvcmNlQ2FjaGV9ICkgewogICAgICAgICAgICAkUGFyYW17Q2FjaGVkfSA9ICRTZWxmLT57Rm9yY2VDYWNoZX07CiAgICAgICAgfQogICAgICAgIGlmICggJFBhcmFte0NhY2hlZH0gJiYgJFNlbGYtPnskQ2FjaGVLZXl9ICkgewogICAgICAgICAgICBpZiAoIHJlZiggJFNlbGYtPnskQ2FjaGVLZXl9ICkgZXEgJ0FSUkFZJyApIHsKICAgICAgICAgICAgICAgIHJldHVybiBAeyAkU2VsZi0+eyRDYWNoZUtleX0gfTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNpZiAoIHJlZiggJFNlbGYtPnskQ2FjaGVLZXl9ICkgZXEgJ0hBU0gnICkgewogICAgICAgICAgICAgICAgcmV0dXJuICV7ICRTZWxmLT57JENhY2hlS2V5fSB9OwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgICMgc3FsCiAgICBteSAlRGF0YTsKICAgIG15IEBOYW1lOwogICAgbXkgQElEOwogICAgbXkgJFNRTCA9ICdTRUxFQ1Qgc2N1LnNlcnZpY2VfaWQsIHNjdS5jdXN0b21lcl91c2VyX2xvZ2luLCBzLm5hbWUgJwogICAgICAgIC4gJyBGUk9NICcKICAgICAgICAuICcgc2VydmljZV9jdXN0b21lcl91c2VyIHNjdSwgc2VydmljZSBzJwogICAgICAgIC4gJyBXSEVSRSAnCiAgICAgICAgLiAiIHMudmFsaWRfaWQgSU4gKCAke1woam9pbiAnLCAnLCAkU2VsZi0+e1ZhbGlkT2JqZWN0fS0+VmFsaWRJRHNHZXQoKSl9ICkgQU5EICIKICAgICAgICAuICcgcy5pZCA9IHNjdS5zZXJ2aWNlX2lkIEFORCAnOwoKICAgIGlmICggJFBhcmFte1NlcnZpY2VJRH0gKSB7CiAgICAgICAgJFNRTCAuPSAiIHNjdS5zZXJ2aWNlX2lkID0gJFBhcmFte1NlcnZpY2VJRH0iOwogICAgfQogICAgZWxzaWYgKCAkUGFyYW17Q3VzdG9tZXJVc2VyTG9naW59ICkgewogICAgICAgICRTUUwgLj0gIiBzY3UuY3VzdG9tZXJfdXNlcl9sb2dpbiA9ICckUGFyYW17Q3VzdG9tZXJVc2VyTG9naW59JyI7CiAgICB9CgogICAgJFNlbGYtPntEQk9iamVjdH0tPlByZXBhcmUoIFNRTCA9PiAkU1FMICk7CgogICAgd2hpbGUgKCBteSBAUm93ID0gJFNlbGYtPntEQk9iamVjdH0tPkZldGNocm93QXJyYXkoKSApIHsKCiAgICAgICAgbXkgJEtleSAgID0gJyc7CiAgICAgICAgbXkgJFZhbHVlID0gJyc7CiAgICAgICAgaWYgKCAkUGFyYW17U2VydmljZUlEfSApIHsKICAgICAgICAgICAgJEtleSAgID0gJFJvd1sxXTsKICAgICAgICAgICAgJFZhbHVlID0gJFJvd1swXTsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICRLZXkgICA9ICRSb3dbMF07CiAgICAgICAgICAgICRWYWx1ZSA9ICRSb3dbMl07CiAgICAgICAgfQoKICAgICAgICAjIHJlbWVtYmVyIHBlcm1pc3Npb25zCiAgICAgICAgaWYgKCAhZGVmaW5lZCAkRGF0YXskS2V5fSApIHsKICAgICAgICAgICAgJERhdGF7JEtleX0gPSAkVmFsdWU7CiAgICAgICAgICAgIHB1c2ggQE5hbWUsICRWYWx1ZTsKICAgICAgICAgICAgcHVzaCBASUQsICAgJEtleTsKICAgICAgICB9CiAgICB9CiAgICBpZiAoICRQYXJhbXtDdXN0b21lclVzZXJMb2dpbn0gJiYgJFBhcmFte0RlZmF1bHRTZXJ2aWNlc30gJiYgIWtleXMoJURhdGEpICkgewogICAgICAgICVEYXRhID0gJFNlbGYtPkN1c3RvbWVyVXNlclNlcnZpY2VNZW1iZXJMaXN0KAogICAgICAgICAgICBDdXN0b21lclVzZXJMb2dpbiA9PiAnPERFRkFVTFQ+JywKICAgICAgICAgICAgUmVzdWx0ICAgICAgICAgICAgPT4gJ0hBU0gnLAogICAgICAgICAgICBEZWZhdWx0U2VydmljZXMgICA9PiAwLAogICAgICAgICk7CiAgICAgICAgZm9yIG15ICRLZXkgKCBrZXlzICVEYXRhICkgewogICAgICAgICAgICBwdXNoIEBOYW1lLCAkRGF0YXskS2V5fTsKICAgICAgICAgICAgcHVzaCBASUQsICAgJEtleTsKICAgICAgICB9CiAgICB9CgogICAgIyByZXR1cm4gcmVzdWx0CiAgICBpZiAoICRQYXJhbXtSZXN1bHR9ICYmICRQYXJhbXtSZXN1bHR9IGVxICdJRCcgKSB7CiAgICAgICAgaWYgKCAkUGFyYW17U2VydmljZUlEfSB8fCAkUGFyYW17Q3VzdG9tZXJVc2VyTG9naW59ICkgewoKICAgICAgICAgICAgIyBjYWNoZSByZXN1bHQKICAgICAgICAgICAgJFNlbGYtPnskQ2FjaGVLZXl9ID0gXEBJRDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIEBJRDsKICAgIH0KICAgIGlmICggJFBhcmFte1Jlc3VsdH0gJiYgJFBhcmFte1Jlc3VsdH0gZXEgJ05hbWUnICkgewogICAgICAgIGlmICggJFBhcmFte1NlcnZpY2VJRH0gfHwgJFBhcmFte0N1c3RvbWVyVXNlckxvZ2lufSApIHsKCiAgICAgICAgICAgICMgY2FjaGUgcmVzdWx0CiAgICAgICAgICAgICRTZWxmLT57JENhY2hlS2V5fSA9IFxATmFtZTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIEBOYW1lOwogICAgfQogICAgZWxzZSB7CiAgICAgICAgaWYgKCAkUGFyYW17U2VydmljZUlEfSB8fCAkUGFyYW17Q3VzdG9tZXJVc2VyTG9naW59ICkgewoKICAgICAgICAgICAgIyBjYWNoZSByZXN1bHQKICAgICAgICAgICAgJFNlbGYtPnskQ2FjaGVLZXl9ID0gXCVEYXRhOwogICAgICAgIH0KICAgICAgICByZXR1cm4gJURhdGE7CiAgICB9Cn0KCj1pdGVtIEN1c3RvbWVyVXNlclNlcnZpY2VNZW1iZXJBZGQoKQoKdG8gYWRkIGEgbWVtYmVyIHRvIGEgc2VydmljZQoKICAgICRTZXJ2aWNlT2JqZWN0LT5DdXN0b21lclVzZXJTZXJ2aWNlTWVtYmVyQWRkKAogICAgICAgIEN1c3RvbWVyVXNlckxvZ2luID0+ICdUZXN0MScsCiAgICAgICAgU2VydmljZUlEICAgICAgICAgPT4gNiwKICAgICAgICBBY3RpdmUgICAgICAgICAgICA9PiAxLAogICAgICAgIFVzZXJJRCAgICAgICAgICAgID0+IDEyMywKICAgICk7Cgo9Y3V0CgpzdWIgQ3VzdG9tZXJVc2VyU2VydmljZU1lbWJlckFkZCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgY2hlY2sgbmVlZGVkIHN0dWZmCiAgICBmb3IgbXkgJEFyZ3VtZW50IChxdyhDdXN0b21lclVzZXJMb2dpbiBTZXJ2aWNlSUQgVXNlcklEKSkgewogICAgICAgIGlmICggISRQYXJhbXskQXJndW1lbnR9ICkgewogICAgICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZygKICAgICAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgICAgICBNZXNzYWdlICA9PiAiTmVlZCAkQXJndW1lbnQhIiwKICAgICAgICAgICAgKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgIH0KCiAgICAjIGRlbGV0ZSBleGlzdGluZyByZWxhdGlvbgogICAgcmV0dXJuIGlmICEkU2VsZi0+e0RCT2JqZWN0fS0+RG8oCiAgICAgICAgU1FMID0+ICdERUxFVEUgRlJPTSBzZXJ2aWNlX2N1c3RvbWVyX3VzZXIgV0hFUkUgY3VzdG9tZXJfdXNlcl9sb2dpbiA9ID8gQU5EIHNlcnZpY2VfaWQgPSA/JywKICAgICAgICBCaW5kID0+IFsgXCRQYXJhbXtDdXN0b21lclVzZXJMb2dpbn0sIFwkUGFyYW17U2VydmljZUlEfSBdLAogICAgKTsKCiAgICAjIHJldHVybiBpZiByZWxhdGlvbiBpcyBub3QgYWN0aXZlCiAgICByZXR1cm4gaWYgISRQYXJhbXtBY3RpdmV9OwoKICAgICMgaW5zZXJ0IG5ldyByZWxhdGlvbgogICAgcmV0dXJuICRTZWxmLT57REJPYmplY3R9LT5EbygKICAgICAgICBTUUwgPT4gJ0lOU0VSVCBJTlRPIHNlcnZpY2VfY3VzdG9tZXJfdXNlciAnCiAgICAgICAgICAgIC4gJyhjdXN0b21lcl91c2VyX2xvZ2luLCBzZXJ2aWNlX2lkLCBjcmVhdGVfdGltZSwgY3JlYXRlX2J5KSAnCiAgICAgICAgICAgIC4gJ1ZBTFVFUyAoPywgPywgY3VycmVudF90aW1lc3RhbXAsID8pJywKICAgICAgICBCaW5kID0+IFsgXCRQYXJhbXtDdXN0b21lclVzZXJMb2dpbn0sIFwkUGFyYW17U2VydmljZUlEfSwgXCRQYXJhbXtVc2VySUR9IF0KICAgICk7Cn0KCiMgY2FwZUlUCgo9aXRlbSBDdXN0b21lckNvbXBhbnlTZXJ2aWNlTWVtYmVyTGlzdCgpCgpyZXR1cm5zIGEgbGlzdCBvZiBDdXN0b21lckNvbXBhbnkvc2VydmljZSBtZW1iZXJzCgogICAgU2VydmljZUlEOiBzZXJ2aWNlIGlkCiAgICBDdXN0b21lcklEOiBjdXN0b21lciBJRAogICAgRGVmYXVsdFNlcnZpY2VzOiBhY3RpdmF0ZSBvciBkZWFjdGl2YXRlIGRlZmF1bHQgc2VydmljZXMKCiAgICBSZXN1bHQ6IEhBU0ggLT4gcmV0dXJucyBhIGhhc2ggb2Yga2V5ID0+IHNlcnZpY2UgaWQsIHZhbHVlID0+IHNlcnZpY2UgbmFtZQogICAgICAgICAgICBOYW1lIC0+IHJldHVybnMgYW4gYXJyYXkgb2YgbmFtZXMKICAgICAgICAgICAgSUQgICAtPiByZXR1cm5zIGFuIGFycmF5IG9mIGlkcwoKICAgIEV4YW1wbGUgKGdldCBzZXJ2aWNlcyBvZiBjdXN0b21lciB1c2VyKToKCiAgICAkU2VydmljZU9iamVjdC0+Q3VzdG9tZXJDb21wYW55U2VydmljZU1lbWJlckxpc3QoCiAgICAgICAgQ3VzdG9tZXJJRCAgICAgICAgPT4gJ1Rlc3QnLAogICAgICAgIFJlc3VsdCAgICAgICAgICAgID0+ICdIQVNIJywKICAgICAgICBEZWZhdWx0U2VydmljZXMgICA9PiAwLAogICAgKTsKCiAgICBFeGFtcGxlIChnZXQgY3VzdG9tZXIgY29tcGFueSBvZiBzZXJ2aWNlKToKCiAgICAkU2VydmljZU9iamVjdC0+Q3VzdG9tZXJDb21wYW55U2VydmljZU1lbWJlckxpc3QoCiAgICAgICAgU2VydmljZUlEID0+ICRJRCwKICAgICAgICBSZXN1bHQgICAgPT4gJ0hBU0gnLAogICAgKTsKCj1jdXQKCnN1YiBDdXN0b21lckNvbXBhbnlTZXJ2aWNlTWVtYmVyTGlzdCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgY2hlY2sgbmVlZGVkIHN0dWZmCiAgICBpZiAoICEkUGFyYW17UmVzdWx0fSApIHsKICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZygKICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgTWVzc2FnZSAgPT4gJ05lZWQgUmVzdWx0IScsCiAgICAgICAgKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBpZiAoICEkUGFyYW17U2VydmljZUlEfSAmJiAhJFBhcmFte0N1c3RvbWVySUR9ICkgewogICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKAogICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICBNZXNzYWdlICA9PiAnTmVlZCBTZXJ2aWNlSUQgb3IgQ3VzdG9tZXJJRCEnLAogICAgICAgICk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgICMgc2V0IGRlZmF1bHQKICAgIGlmICggIWRlZmluZWQgJFBhcmFte0RlZmF1bHRTZXJ2aWNlc30gKSB7CiAgICAgICAgJFBhcmFte0RlZmF1bHRTZXJ2aWNlc30gPSAxOwogICAgfQoKICAgICMgZGIgcXVvdGUKICAgIGZvciAoIGtleXMgJVBhcmFtICkgewogICAgICAgICRQYXJhbXskX30gPSAkU2VsZi0+e0RCT2JqZWN0fS0+UXVvdGUoICRQYXJhbXskX30gKTsKICAgIH0KICAgIGZvciAocXcoU2VydmljZUlEKSkgewogICAgICAgICRQYXJhbXskX30gPSAkU2VsZi0+e0RCT2JqZWN0fS0+UXVvdGUoICRQYXJhbXskX30sICdJbnRlZ2VyJyApOwogICAgfQoKICAgICMgY3JlYXRlIGNhY2hlIGtleQogICAgbXkgJENhY2hlS2V5ID0gJ0N1c3RvbWVyQ29tcGFueVNlcnZpY2VNZW1iZXJMaXN0OjonIC4gJFBhcmFte1Jlc3VsdH0gLiAnOjonOwogICAgaWYgKCAkUGFyYW17U2VydmljZUlEfSApIHsKICAgICAgICAkQ2FjaGVLZXkgLj0gJ1NlcnZpY2VJRDo6JyAuICRQYXJhbXtTZXJ2aWNlSUR9OwogICAgfQogICAgZWxzaWYgKCAkUGFyYW17Q3VzdG9tZXJJRH0gKSB7CiAgICAgICAgJENhY2hlS2V5IC49ICdDdXN0b21lcklEOjonIC4gJFBhcmFte0N1c3RvbWVySUR9OwogICAgfQoKICAgICMgY2hlY2sgY2FjaGUKICAgIGlmICggJFBhcmFte1NlcnZpY2VJRH0gfHwgJFBhcmFte0N1c3RvbWVySUR9ICkgewogICAgICAgIGlmICggJFNlbGYtPntGb3JjZUNhY2hlfSApIHsKICAgICAgICAgICAgJFBhcmFte0NhY2hlZH0gPSAkU2VsZi0+e0ZvcmNlQ2FjaGV9OwogICAgICAgIH0KICAgICAgICBpZiAoICRQYXJhbXtDYWNoZWR9ICYmICRTZWxmLT57JENhY2hlS2V5fSApIHsKICAgICAgICAgICAgaWYgKCByZWYoICRTZWxmLT57JENhY2hlS2V5fSApIGVxICdBUlJBWScgKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gQHsgJFNlbGYtPnskQ2FjaGVLZXl9IH07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzaWYgKCByZWYoICRTZWxmLT57JENhY2hlS2V5fSApIGVxICdIQVNIJyApIHsKICAgICAgICAgICAgICAgIHJldHVybiAleyAkU2VsZi0+eyRDYWNoZUtleX0gfTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAjIHNxbAogICAgbXkgJURhdGE7CiAgICBteSBATmFtZTsKICAgIG15IEBJRDsKICAgIG15ICRTUUwgPSAnU0VMRUNUIHNjYy5zZXJ2aWNlX2lkLCBzY2MuY3VzdG9tZXJfaWQsIHMubmFtZSAnCiAgICAgICAgLiAnIEZST00gJwogICAgICAgIC4gJyBzZXJ2aWNlX2N1c3RvbWVyX2NvbXBhbnkgc2NjLCBzZXJ2aWNlIHMnCiAgICAgICAgLiAnIFdIRVJFICcKICAgICAgICAuICIgcy52YWxpZF9pZCBJTiAoICR7XChqb2luICcsICcsICRTZWxmLT57VmFsaWRPYmplY3R9LT5WYWxpZElEc0dldCgpKX0gKSBBTkQgIgogICAgICAgIC4gJyBzLmlkID0gc2NjLnNlcnZpY2VfaWQgQU5EICc7CgogICAgaWYgKCAkUGFyYW17U2VydmljZUlEfSApIHsKICAgICAgICAkU1FMIC49ICIgc2NjLnNlcnZpY2VfaWQgPSAkUGFyYW17U2VydmljZUlEfSI7CiAgICB9CiAgICBlbHNpZiAoICRQYXJhbXtDdXN0b21lcklEfSApIHsKICAgICAgICAkU1FMIC49ICIgc2NjLmN1c3RvbWVyX2lkID0gJyRQYXJhbXtDdXN0b21lcklEfSciOwogICAgfQoKICAgICRTZWxmLT57REJPYmplY3R9LT5QcmVwYXJlKCBTUUwgPT4gJFNRTCApOwoKICAgIHdoaWxlICggbXkgQFJvdyA9ICRTZWxmLT57REJPYmplY3R9LT5GZXRjaHJvd0FycmF5KCkgKSB7CgogICAgICAgIG15ICRLZXkgICA9ICcnOwogICAgICAgIG15ICRWYWx1ZSA9ICcnOwogICAgICAgIGlmICggJFBhcmFte1NlcnZpY2VJRH0gKSB7CiAgICAgICAgICAgICRLZXkgICA9ICRSb3dbMV07CiAgICAgICAgICAgICRWYWx1ZSA9ICRSb3dbMF07CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICAkS2V5ICAgPSAkUm93WzBdOwogICAgICAgICAgICAkVmFsdWUgPSAkUm93WzJdOwogICAgICAgIH0KCiAgICAgICAgIyByZW1lbWJlciBwZXJtaXNzaW9ucwogICAgICAgIGlmICggIWRlZmluZWQgJERhdGF7JEtleX0gKSB7CiAgICAgICAgICAgICREYXRheyRLZXl9ID0gJFZhbHVlOwogICAgICAgICAgICBwdXNoIEBOYW1lLCAkVmFsdWU7CiAgICAgICAgICAgIHB1c2ggQElELCAgICRLZXk7CiAgICAgICAgfQogICAgfQogICAgaWYgKCAkUGFyYW17Q3VzdG9tZXJJRH0gJiYgJFBhcmFte0RlZmF1bHRTZXJ2aWNlc30gJiYgIWtleXMoJURhdGEpICkgewogICAgICAgICVEYXRhID0gJFNlbGYtPkN1c3RvbWVyQ29tcGFueVNlcnZpY2VNZW1iZXJMaXN0KAogICAgICAgICAgICBDdXN0b21lcklEICAgICAgPT4gJzxERUZBVUxUPicsCiAgICAgICAgICAgIFJlc3VsdCAgICAgICAgICA9PiAnSEFTSCcsCiAgICAgICAgICAgIERlZmF1bHRTZXJ2aWNlcyA9PiAwLAogICAgICAgICk7CiAgICAgICAgZm9yIG15ICRLZXkgKCBrZXlzICVEYXRhICkgewogICAgICAgICAgICBwdXNoIEBOYW1lLCAkRGF0YXskS2V5fTsKICAgICAgICAgICAgcHVzaCBASUQsICAgJEtleTsKICAgICAgICB9CiAgICB9CgogICAgIyByZXR1cm4gcmVzdWx0CiAgICBpZiAoICRQYXJhbXtSZXN1bHR9ICYmICRQYXJhbXtSZXN1bHR9IGVxICdJRCcgKSB7CiAgICAgICAgaWYgKCAkUGFyYW17U2VydmljZUlEfSB8fCAkUGFyYW17Q3VzdG9tZXJJRH0gKSB7CgogICAgICAgICAgICAjIGNhY2hlIHJlc3VsdAogICAgICAgICAgICAkU2VsZi0+eyRDYWNoZUtleX0gPSBcQElEOwogICAgICAgIH0KICAgICAgICByZXR1cm4gQElEOwogICAgfQogICAgaWYgKCAkUGFyYW17UmVzdWx0fSAmJiAkUGFyYW17UmVzdWx0fSBlcSAnTmFtZScgKSB7CiAgICAgICAgaWYgKCAkUGFyYW17U2VydmljZUlEfSB8fCAkUGFyYW17Q3VzdG9tZXJJRH0gKSB7CgogICAgICAgICAgICAjIGNhY2hlIHJlc3VsdAogICAgICAgICAgICAkU2VsZi0+eyRDYWNoZUtleX0gPSBcQE5hbWU7CiAgICAgICAgfQogICAgICAgIHJldHVybiBATmFtZTsKICAgIH0KICAgIGVsc2UgewogICAgICAgIGlmICggJFBhcmFte1NlcnZpY2VJRH0gfHwgJFBhcmFte0N1c3RvbWVySUR9ICkgewoKICAgICAgICAgICAgIyBjYWNoZSByZXN1bHQKICAgICAgICAgICAgJFNlbGYtPnskQ2FjaGVLZXl9ID0gXCVEYXRhOwogICAgICAgIH0KICAgICAgICByZXR1cm4gJURhdGE7CiAgICB9Cn0KCj1pdGVtIEN1c3RvbWVyQ29tcGFueVNlcnZpY2VNZW1iZXJBZGQoKQoKdG8gYWRkIGEgbWVtYmVyIHRvIGEgc2VydmljZQoKICAgICRTZXJ2aWNlT2JqZWN0LT5DdXN0b21lckNvbXBhbnlTZXJ2aWNlTWVtYmVyQWRkKAogICAgICAgIEN1c3RvbWVySUQgICAgICAgID0+ICdUZXN0MScsCiAgICAgICAgU2VydmljZUlEICAgICAgICAgPT4gNiwKICAgICAgICBBY3RpdmUgICAgICAgICAgICA9PiAxLAogICAgICAgIFVzZXJJRCAgICAgICAgICAgID0+IDEyMywKICAgICk7Cgo9Y3V0CgpzdWIgQ3VzdG9tZXJDb21wYW55U2VydmljZU1lbWJlckFkZCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgY2hlY2sgbmVlZGVkIHN0dWZmCiAgICBmb3IgbXkgJEFyZ3VtZW50IChxdyhDdXN0b21lcklEIFNlcnZpY2VJRCBVc2VySUQpKSB7CiAgICAgICAgaWYgKCAhJFBhcmFteyRBcmd1bWVudH0gKSB7CiAgICAgICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKAogICAgICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgICAgIE1lc3NhZ2UgID0+ICJOZWVkICRBcmd1bWVudCEiLAogICAgICAgICAgICApOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgfQoKICAgICMgZGVsZXRlIGV4aXN0aW5nIHJlbGF0aW9uCiAgICByZXR1cm4gaWYgISRTZWxmLT57REJPYmplY3R9LT5EbygKICAgICAgICBTUUwgPT4gJ0RFTEVURSBGUk9NIHNlcnZpY2VfY3VzdG9tZXJfY29tcGFueSBXSEVSRSBjdXN0b21lcl9pZCA9ID8gQU5EIHNlcnZpY2VfaWQgPSA/JywKICAgICAgICBCaW5kID0+IFsgXCRQYXJhbXtDdXN0b21lcklEfSwgXCRQYXJhbXtTZXJ2aWNlSUR9IF0sCiAgICApOwoKICAgICMgcmV0dXJuIGlmIHJlbGF0aW9uIGlzIG5vdCBhY3RpdmUKICAgIHJldHVybiBpZiAhJFBhcmFte0FjdGl2ZX07CgogICAgIyBpbnNlcnQgbmV3IHJlbGF0aW9uCiAgICByZXR1cm4gJFNlbGYtPntEQk9iamVjdH0tPkRvKAogICAgICAgIFNRTCA9PiAnSU5TRVJUIElOVE8gc2VydmljZV9jdXN0b21lcl9jb21wYW55ICcKICAgICAgICAgICAgLiAnKGN1c3RvbWVyX2lkLCBzZXJ2aWNlX2lkLCBjcmVhdGVfdGltZSwgY3JlYXRlX2J5KSAnCiAgICAgICAgICAgIC4gJ1ZBTFVFUyAoPywgPywgY3VycmVudF90aW1lc3RhbXAsID8pJywKICAgICAgICBCaW5kID0+IFsgXCRQYXJhbXtDdXN0b21lcklEfSwgXCRQYXJhbXtTZXJ2aWNlSUR9LCBcJFBhcmFte1VzZXJJRH0gXQogICAgKTsKfQoKIyBFTyBjYXBlSVQKCj1pdGVtIFNlcnZpY2VQcmVmZXJlbmNlc1NldCgpCgpzZXQgc2VydmljZSBwcmVmZXJlbmNlcwoKICAgICRTZXJ2aWNlT2JqZWN0LT5TZXJ2aWNlUHJlZmVyZW5jZXNTZXQoCiAgICAgICAgU2VydmljZUlEID0+IDEyMywKICAgICAgICBLZXkgICAgICAgPT4gJ1VzZXJDb21tZW50JywKICAgICAgICBWYWx1ZSAgICAgPT4gJ3NvbWUgY29tbWVudCcsCiAgICAgICAgVXNlcklEICAgID0+IDEyMywKICAgICk7Cgo9Y3V0CgpzdWIgU2VydmljZVByZWZlcmVuY2VzU2V0IHsKICAgIG15ICRTZWxmID0gc2hpZnQ7CgogICAgcmV0dXJuICRTZWxmLT57UHJlZmVyZW5jZXNPYmplY3R9LT5TZXJ2aWNlUHJlZmVyZW5jZXNTZXQoQF8pOwp9Cgo9aXRlbSBTZXJ2aWNlUHJlZmVyZW5jZXNHZXQoKQoKZ2V0IHNlcnZpY2UgcHJlZmVyZW5jZXMKCiAgICBteSAlUHJlZmVyZW5jZXMgPSAkU2VydmljZU9iamVjdC0+U2VydmljZVByZWZlcmVuY2VzR2V0KAogICAgICAgIFNlcnZpY2VJRCA9PiAxMjMsCiAgICAgICAgVXNlcklEICAgID0+IDEyMywKICAgICk7Cgo9Y3V0CgpzdWIgU2VydmljZVByZWZlcmVuY2VzR2V0IHsKICAgIG15ICRTZWxmID0gc2hpZnQ7CgogICAgcmV0dXJuICRTZWxmLT57UHJlZmVyZW5jZXNPYmplY3R9LT5TZXJ2aWNlUHJlZmVyZW5jZXNHZXQoQF8pOwp9CgoxOwoKPWJhY2sKCj1oZWFkMSBURVJNUyBBTkQgQ09ORElUSU9OUwoKVGhpcyBzb2Z0d2FyZSBpcyBwYXJ0IG9mIHRoZSBPVFJTIHByb2plY3QgKGh0dHA6Ly9vdHJzLm9yZy8pLgoKVGhpcyBzb2Z0d2FyZSBjb21lcyB3aXRoIEFCU09MVVRFTFkgTk8gV0FSUkFOVFkuIEZvciBkZXRhaWxzLCBzZWUKdGhlIGVuY2xvc2VkIGZpbGUgQ09QWUlORyBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbiAoQUdQTCkuIElmIHlvdQpkaWQgbm90IHJlY2VpdmUgdGhpcyBmaWxlLCBzZWUgaHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwudHh0LgoKPWN1dAoKPWhlYWQxIFZFUlNJT04KCiRSZXZpc2lvbjogMS4xICQgJERhdGU6IDIwMTAtMTAtMDcgMTY6MTU6NTkgJAoKPWN1dAo= IyAtLQojIEN1c3RvbWVyQ29tcGFueVNlcnZpY2UucG0gLSBjb2RlIHRvIGV4Y2VjdXRlIGR1cmluZyBwYWNrYWdlIGluc3RhbGxhdGlvbgojIENvcHlyaWdodCAoQykgMjAwNi0yMDEwIGMuYS5wLmUuIElUIEdtYkgsIGh0dHA6Ly93d3cuY2FwZS1pdC5kZQojIC0tCiMgJElkOiBDdXN0b21lckNvbXBhbnlTZXJ2aWNlLnBtLHYgMS4yIDIwMTAtMTAtMTQgMTE6MzI6MjYgcmJvIEV4cCAkCiMgLS0KIyBUaGlzIHNvZnR3YXJlIGNvbWVzIHdpdGggQUJTT0xVVEVMWSBOTyBXQVJSQU5UWS4gRm9yIGRldGFpbHMsIHNlZQojIHRoZSBlbmNsb3NlZCBmaWxlIENPUFlJTkcgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24gKEdQTCkuIElmIHlvdQojIGRpZCBub3QgcmVjZWl2ZSB0aGlzIGZpbGUsIHNlZSBodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvZ3BsLTIuMC50eHQuCiMgLS0KCnBhY2thZ2UgdmFyOjpwYWNrYWdlc2V0dXA6OkN1c3RvbWVyQ29tcGFueVNlcnZpY2U7Cgp1c2Ugc3RyaWN0Owp1c2Ugd2FybmluZ3M7Cgp1c2UgS2VybmVsOjpDb25maWc7CnVzZSBLZXJuZWw6OlN5c3RlbTo6Q29uZmlnOwp1c2UgS2VybmVsOjpTeXN0ZW06OlBhY2thZ2U7CnVzZSBLZXJuZWw6OlN5c3RlbTo6Q2lDU1V0aWxzOwoKdXNlIHZhcnMgcXcoQElTQSAkVkVSU0lPTik7CiRWRVJTSU9OID0gcXcoJFJldmlzaW9uOiAxLjIgJCkgWzFdOwoKPWhlYWQxIE5BTUUKCkN1c3RvbWVyQ29tcGFueVNlcnZpY2UucG0gLSBjb2RlIHRvIGV4Y2VjdXRlIGR1cmluZyBwYWNrYWdlIGluc3RhbGxhdGlvbgoKPWhlYWQxIFNZTk9QU0lTCgpBbGwgZnVuY3Rpb25zCgo9aGVhZDEgUFVCTElDIElOVEVSRkFDRQoKPW92ZXIgNAoKPWN1dAoKPWl0ZW0gbmV3KCkKCmNyZWF0ZSBhbiBvYmplY3QKCiAgICB1c2UgS2VybmVsOjpDb25maWc7CiAgICB1c2UgS2VybmVsOjpTeXN0ZW06OkxvZzsKICAgIHVzZSBLZXJuZWw6OlN5c3RlbTo6TWFpbjsKICAgIHVzZSBLZXJuZWw6OlN5c3RlbTo6VGltZTsKICAgIHVzZSBLZXJuZWw6OlN5c3RlbTo6REI7CiAgICB1c2UgS2VybmVsOjpTeXN0ZW06OlhNTDsKCiAgICBteSAkQ29uZmlnT2JqZWN0ID0gS2VybmVsOjpDb25maWctPm5ldygpOwogICAgbXkgJExvZ09iamVjdCAgICA9IEtlcm5lbDo6U3lzdGVtOjpMb2ctPm5ldygKICAgICAgICBDb25maWdPYmplY3QgPT4gJENvbmZpZ09iamVjdCwKICAgICk7CiAgICBteSAkTWFpbk9iamVjdCA9IEtlcm5lbDo6U3lzdGVtOjpNYWluLT5uZXcoCiAgICAgICAgQ29uZmlnT2JqZWN0ID0+ICRDb25maWdPYmplY3QsCiAgICAgICAgTG9nT2JqZWN0ICAgID0+ICRMb2dPYmplY3QsCiAgICApOwogICAgbXkgJFRpbWVPYmplY3QgPSBLZXJuZWw6OlN5c3RlbTo6VGltZS0+bmV3KAogICAgICAgIENvbmZpZ09iamVjdCA9PiAkQ29uZmlnT2JqZWN0LAogICAgICAgIExvZ09iamVjdCAgICA9PiAkTG9nT2JqZWN0LAogICAgKTsKICAgIG15ICREQk9iamVjdCA9IEtlcm5lbDo6U3lzdGVtOjpEQi0+bmV3KAogICAgICAgIENvbmZpZ09iamVjdCA9PiAkQ29uZmlnT2JqZWN0LAogICAgICAgIExvZ09iamVjdCAgICA9PiAkTG9nT2JqZWN0LAogICAgICAgIE1haW5PYmplY3QgICA9PiAkTWFpbk9iamVjdCwKICAgICk7CiAgICBteSAkWE1MT2JqZWN0ID0gS2VybmVsOjpTeXN0ZW06OlhNTC0+bmV3KAogICAgICAgIENvbmZpZ09iamVjdCA9PiAkQ29uZmlnT2JqZWN0LAogICAgICAgIExvZ09iamVjdCAgICA9PiAkTG9nT2JqZWN0LAogICAgICAgIERCT2JqZWN0ICAgICA9PiAkREJPYmplY3QsCiAgICAgICAgTWFpbk9iamVjdCAgID0+ICRNYWluT2JqZWN0LAogICAgKTsKICAgIG15ICRDb2RlT2JqZWN0ID0gdmFyOjpwYWNrYWdlc2V0dXA6OkZBUS0+bmV3KAogICAgICAgIENvbmZpZ09iamVjdCA9PiAkQ29uZmlnT2JqZWN0LAogICAgICAgIExvZ09iamVjdCAgICA9PiAkTG9nT2JqZWN0LAogICAgICAgIE1haW5PYmplY3QgICA9PiAkTWFpbk9iamVjdCwKICAgICAgICBUaW1lT2JqZWN0ICAgPT4gJFRpbWVPYmplY3QsCiAgICAgICAgREJPYmplY3QgICAgID0+ICREQk9iamVjdCwKICAgICAgICBYTUxPYmplY3QgICAgPT4gJFhNTE9iamVjdCwKICAgICk7Cgo9Y3V0CgpzdWIgbmV3IHsKICAgIG15ICggJFR5cGUsICVQYXJhbSApID0gQF87CgogICAgIyBhbGxvY2F0ZSBuZXcgaGFzaCBmb3Igb2JqZWN0CiAgICBteSAkU2VsZiA9IHt9OwogICAgYmxlc3MoICRTZWxmLCAkVHlwZSApOwoKICAgICMgY2hlY2sgbmVlZGVkIG9iamVjdHMKICAgIGZvciBteSAkT2JqZWN0ICgKICAgICAgICBxdyhDb25maWdPYmplY3QgTG9nT2JqZWN0IE1haW5PYmplY3QgVGltZU9iamVjdCBEQk9iamVjdCBYTUxPYmplY3QgRW5jb2RlT2JqZWN0KSkKICAgIHsKICAgICAgICAkU2VsZi0+eyRPYmplY3R9ID0gJFBhcmFteyRPYmplY3R9IHx8IGRpZSAiR290IG5vICRPYmplY3QhIjsKICAgIH0KCiAgICAjIGNyZWF0ZSBuZWVkZWQgc3lzY29uZmlnIG9iamVjdAogICAgJFNlbGYtPntTeXNDb25maWdPYmplY3R9ID0gS2VybmVsOjpTeXN0ZW06OkNvbmZpZy0+bmV3KCAleyRTZWxmfSApOwoKICAgICMgcmVidWlsZCBaWloqIGZpbGVzCiAgICAkU2VsZi0+e1N5c0NvbmZpZ09iamVjdH0tPldyaXRlRGVmYXVsdCgpOwoKICAgICMgZGVmaW5lIHRoZSBaWlogZmlsZXMKICAgIG15IEBaWlpGaWxlcyA9ICgKICAgICAgICAnWlpaQUF1dG8ucG0nLAogICAgICAgICdaWlpBdXRvLnBtJywKICAgICk7CgogICAgIyByZWxvYWQgdGhlIFpaWiBmaWxlcyAobW9kX3Blcmwgd29ya2Fyb3VuZCkKICAgIGZvciBteSAkWlpaRmlsZSAoQFpaWkZpbGVzKSB7CgogICAgICAgIFBSRUZJWDoKICAgICAgICBmb3IgbXkgJFByZWZpeCAoQElOQykgewogICAgICAgICAgICBteSAkRmlsZSA9ICRQcmVmaXggLiAnL0tlcm5lbC9Db25maWcvRmlsZXMvJyAuICRaWlpGaWxlOwogICAgICAgICAgICBuZXh0IFBSRUZJWCBpZiAhLWYgJEZpbGU7CiAgICAgICAgICAgIGRvICRGaWxlOwogICAgICAgICAgICBsYXN0IFBSRUZJWDsKICAgICAgICB9CiAgICB9CgogICAgJFNlbGYtPntQYWNrYWdlT2JqZWN0fSAgID0gS2VybmVsOjpTeXN0ZW06OlBhY2thZ2UtPm5ldyggJXskU2VsZn0gKTsKICAgICRTZWxmLT57Q2lDU1V0aWxzT2JqZWN0fSA9IEtlcm5lbDo6U3lzdGVtOjpDaUNTVXRpbHMtPm5ldyggJXskU2VsZn0gKTsKCiAgICAjIGRlZmluZSBmaWxlIHByZWZpeAogICAgJFNlbGYtPntGaWxlUHJlZml4fSA9ICdDdXN0b21lckNvbXBhbnlTZXJ2aWNlJzsKCiAgICByZXR1cm4gJFNlbGY7Cn0KCj1pdGVtIENvZGVJbnN0YWxsKCkKCnJ1biB0aGUgY29kZSBpbnN0YWxsIHBhcnQKCiAgICBteSAkUmVzdWx0ID0gJENvZGVPYmplY3QtPkNvZGVJbnN0YWxsKCk7Cgo9Y3V0CgpzdWIgQ29kZUluc3RhbGwgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICAkU2VsZi0+e0NpQ1NVdGlsc09iamVjdH0tPlJlZ2lzdGVyQ2lDU1BhY2thZ2UoCiAgICAgICAgUGFja2FnZU5hbWUgPT4gJ0N1c3RvbWVyQ29tcGFueVNlcnZpY2UnLAogICAgKTsKCiAgICBpZiAoICRTZWxmLT5fQ2hlY2tJVFNNKCkgKSB7CiAgICAgICAgJFNlbGYtPntDaUNTVXRpbHNPYmplY3R9LT5SZWdpc3RlckNpQ1NQYWNrYWdlKAogICAgICAgICAgICBQYWNrYWdlTmFtZSA9PiAnQ3VzdG9tZXJDb21wYW55U2VydmljZUlUU00nLAogICAgICAgICk7CiAgICB9CgogICAgcmV0dXJuIDE7Cn0KCj1pdGVtIENvZGVSZWluc3RhbGwoKQoKcnVuIHRoZSBjb2RlIHJlaW5zdGFsbCBwYXJ0CgogICAgbXkgJFJlc3VsdCA9ICRDb2RlT2JqZWN0LT5Db2RlUmVpbnN0YWxsKCk7Cgo9Y3V0CgpzdWIgQ29kZVJlaW5zdGFsbCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgIHJldHVybiAxOwp9Cgo9aXRlbSBDb2RlVXBncmFkZSgpCgpydW4gdGhlIGNvZGUgdXBncmFkZSBwYXJ0CgogICAgbXkgJFJlc3VsdCA9ICRDb2RlT2JqZWN0LT5Db2RlVXBncmFkZSgpOwoKPWN1dAoKc3ViIENvZGVVcGdyYWRlIHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgcmV0dXJuIDE7Cn0KCj1pdGVtIENvZGVVcGdyYWRlU3BlY2lhbCgpCgpydW4gc3BlY2lhbCBjb2RlIHVwZ3JhZGUgcGFydAoKICAgIG15ICRSZXN1bHQgPSAkQ29kZU9iamVjdC0+Q29kZVVwZ3JhZGVTcGVjaWFsKCk7Cgo9Y3V0CgpzdWIgQ29kZVVwZ3JhZGVTcGVjaWFsIHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgcmV0dXJuIDE7Cn0KCj1pdGVtIENvZGVVbmluc3RhbGwoKQoKcnVuIHRoZSBjb2RlIHVuaW5zdGFsbCBwYXJ0CgogICAgbXkgJFJlc3VsdCA9ICRDb2RlT2JqZWN0LT5Db2RlVW5pbnN0YWxsKCk7Cgo9Y3V0CgpzdWIgQ29kZVVuaW5zdGFsbCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgIGlmICggJFNlbGYtPl9DaGVja0lUU00oKSApIHsKICAgICAgICAkU2VsZi0+e0NpQ1NVdGlsc09iamVjdH0tPlVuUmVnaXN0ZXJDaUNTUGFja2FnZSgKICAgICAgICAgICAgUGFja2FnZU5hbWUgPT4gJ0N1c3RvbWVyQ29tcGFueVNlcnZpY2VJVFNNJywKICAgICAgICApOwogICAgfQoKICAgICRTZWxmLT57Q2lDU1V0aWxzT2JqZWN0fS0+VW5SZWdpc3RlckNpQ1NQYWNrYWdlKAogICAgICAgIFBhY2thZ2VOYW1lID0+ICdDdXN0b21lckNvbXBhbnlTZXJ2aWNlJywKICAgICk7CgogICAgcmV0dXJuIDE7Cn0KCj1pdGVtIF9DaGVja0lUU00oKQoKY2hlY2sgaWYgSVRTTSBpcyBpbnN0YWxsZWQKCiAgICBteSAkUmVzdWx0ID0gJENvZGVPYmplY3QtPl9DaGVja0lUU00oKTsKCj1jdXQKCnN1YiBfQ2hlY2tJVFNNIHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CiAgICBteSAkUmVzdWx0ID0gMDsKCiAgICBteSBAUGFja2FnZUxpc3QgPSAkU2VsZi0+e1BhY2thZ2VPYmplY3R9LT5SZXBvc2l0b3J5TGlzdCgpOwogICAgZm9yZWFjaCBteSAkUGFja2FnZSAoQFBhY2thZ2VMaXN0KSB7CiAgICAgICAgaWYgKCAkUGFja2FnZS0+e05hbWV9LT57Q29udGVudH0gZXEgJ0lUU01Db3JlJyApIHsKICAgICAgICAgICAgJFJlc3VsdCA9IDE7CiAgICAgICAgICAgIGxhc3Q7CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiAkUmVzdWx0Owp9CgoxOwoKPWJhY2sKCj1oZWFkMSBURVJNUyBBTkQgQ09ORElUSU9OUwoKVGhpcyBTb2Z0d2FyZSBpcyBwYXJ0IG9mIHRoZSBPVFJTIHByb2plY3QgKGh0dHA6Ly9vdHJzLm9yZy8pLgoKVGhpcyBzb2Z0d2FyZSBjb21lcyB3aXRoIEFCU09MVVRFTFkgTk8gV0FSUkFOVFkuIEZvciBkZXRhaWxzLCBzZWUKdGhlIGVuY2xvc2VkIGZpbGUgQ09QWUlORyBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbiAoR1BMKS4gSWYgeW91CmRpZCBub3QgcmVjZWl2ZSB0aGlzIGZpbGUsIHNlZSBodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvZ3BsLTIuMC50eHQuCgo9Y3V0Cgo9aGVhZDEgVkVSU0lPTgoKJFJldmlzaW9uOiAxLjIgJCAkRGF0ZTogMjAxMC0xMC0xNCAxMTozMjoyNiAkCgo9Y3V0Cg==