ZGlmZiAtLWdpdCBhL29yZy5lY2xpcHNlLmpkdC5jb3JlLnRlc3RzLm1vZGVsL3NyYy9vcmcvZWNsaXBzZS9qZHQvY29yZS90ZXN0cy9kb20vQVNUQ29udmVydGVyVGVzdEFTVDNfMi5qYXZhIGIvb3JnLmVjbGlwc2UuamR0LmNvcmUudGVzdHMubW9kZWwvc3JjL29yZy9lY2xpcHNlL2pkdC9jb3JlL3Rlc3RzL2RvbS9BU1RDb252ZXJ0ZXJUZXN0QVNUM18yLmphdmEKaW5kZXggMzFiNDE3Zi4uOWE2MTUwNiAxMDA2NDQKLS0tIGEvb3JnLmVjbGlwc2UuamR0LmNvcmUudGVzdHMubW9kZWwvc3JjL29yZy9lY2xpcHNlL2pkdC9jb3JlL3Rlc3RzL2RvbS9BU1RDb252ZXJ0ZXJUZXN0QVNUM18yLmphdmEKKysrIGIvb3JnLmVjbGlwc2UuamR0LmNvcmUudGVzdHMubW9kZWwvc3JjL29yZy9lY2xpcHNlL2pkdC9jb3JlL3Rlc3RzL2RvbS9BU1RDb252ZXJ0ZXJUZXN0QVNUM18yLmphdmEKQEAgLTUzNjAsMTYgKzUzNjAsNiBAQAogCQlkb21UeXBlLmdldENvbW1lbnQoKTsKIAkJYXNzZXJ0VHJ1ZSgiTm90IGFuIGludGVyZmFjZSIsIEZsYWdzLmlzSW50ZXJmYWNlKGRvbVR5cGUuZ2V0RmxhZ3MoKSkpOwogCX0KLQkKLQkvKioKLQkgKiBodHRwczovL2J1Z3MuZWNsaXBzZS5vcmcvYnVncy9zaG93X2J1Zy5jZ2k/aWQ9NzgzMDUKLQkgKi8KLQlwdWJsaWMgdm9pZCB0ZXN0MDU3NygpIHRocm93cyBKYXZhTW9kZWxFeGNlcHRpb24gewotCQlJQ29tcGlsYXRpb25Vbml0IHNvdXJjZVVuaXQgPSBnZXRDb21waWxhdGlvblVuaXQoIkNvbnZlcnRlciIsICJzcmMiLCAidGVzdDA1NzciLCAiWC5qYXZhIik7IC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJCAvLyROT04tTkxTLTMkIC8vJE5PTi1OTFMtNCQKLQkJQVNUTm9kZSByZXN1bHQgPSBydW5Db252ZXJzaW9uKEFTVC5KTFMzLCBzb3VyY2VVbml0LCB0cnVlKTsKLQkJYXNzZXJ0RXF1YWxzKCJub3QgYSBjb21waWxhdGlvbiB1bml0IiwgQVNUTm9kZS5DT01QSUxBVElPTl9VTklULCByZXN1bHQuZ2V0Tm9kZVR5cGUoKSk7IC8vJE5PTi1OTFMtMSQKLQl9Ci0KIAkvKioKIAkgKiBodHRwczovL2J1Z3MuZWNsaXBzZS5vcmcvYnVncy9zaG93X2J1Zy5jZ2k/aWQ9Nzc2NDUKIAkgKi8KZGlmZiAtLWdpdCBhL29yZy5lY2xpcHNlLmpkdC5jb3JlLnRlc3RzLm1vZGVsL3dvcmtzcGFjZS9Db252ZXJ0ZXIvc3JjL3Rlc3QwNTc3L1guamF2YSBiL29yZy5lY2xpcHNlLmpkdC5jb3JlLnRlc3RzLm1vZGVsL3dvcmtzcGFjZS9Db252ZXJ0ZXIvc3JjL3Rlc3QwNTc3L1guamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOTYwMDI5OC4uMDAwMDAwMAotLS0gYS9vcmcuZWNsaXBzZS5qZHQuY29yZS50ZXN0cy5tb2RlbC93b3Jrc3BhY2UvQ29udmVydGVyL3NyYy90ZXN0MDU3Ny9YLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMjgzICswLDAgQEAKLSMgLSotIGNvZGluZzogaXNvLTg4NTktMSAtKi0KLSIiIgotICAgIE1vaW5Nb2luIC0gRGF0YSBhc3NvY2lhdGVkIHdpdGggYSBzaW5nbGUgUmVxdWVzdAotCi0gICAgQGNvcHlyaWdodDogMjAwMS0yMDAzIGJ5IEr8cmdlbiBIZXJtYW5uIDxqaEB3ZWIuZGU+Ci0gICAgQGNvcHlyaWdodDogMjAwMy0yMDA0IGJ5IFRob21hcyBXYWxkbWFubgotICAgIEBsaWNlbnNlOiBHTlUgR1BMLCBzZWUgQ09QWUlORyBmb3IgZGV0YWlscy4KLSIiIgotCi1pbXBvcnQgb3MsIHRpbWUsIHN5cwotZnJvbSBNb2luTW9pbiBpbXBvcnQgY29uZmlnLCB3aWtpdXRpbAotZnJvbSBNb2luTW9pbi51dGlsIGltcG9ydCBNb2luTW9pbk5vRm9vdGVyCi0KLSMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCi0jIyMgVGltaW5nCi0jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwotCi1jbGFzcyBDbG9jazoKLSAgICAiIiIgSGVscGVyIGNsYXNzIGZvciBjb2RlIHByb2ZpbGluZwotICAgICAgICB3ZSBkbyBub3QgdXNlIHRpbWUuY2xvY2soKSBhcyB0aGlzIGRvZXMgbm90IHdvcmsgYWNyb3NzIHRocmVhZHMKLSAgICAiIiIKLQotICAgIGRlZiBfX2luaXRfXyhzZWxmKToKLSAgICAgICAgc2VsZi50aW1pbmdzID0geyd0b3RhbCc6IHRpbWUudGltZSgpfQotCi0gICAgZGVmIHN0YXJ0KHNlbGYsIHRpbWVyKToKLSAgICAgICAgc2VsZi50aW1pbmdzW3RpbWVyXSA9IHRpbWUudGltZSgpIC0gc2VsZi50aW1pbmdzLmdldCh0aW1lciwgMCkKLQotICAgIGRlZiBzdG9wKHNlbGYsIHRpbWVyKToKLSAgICAgICAgc2VsZi50aW1pbmdzW3RpbWVyXSA9IHRpbWUudGltZSgpIC0gc2VsZi50aW1pbmdzW3RpbWVyXQotCi0gICAgZGVmIHZhbHVlKHNlbGYsIHRpbWVyKToKLSAgICAgICAgcmV0dXJuICIlLjNmIiAlIChzZWxmLnRpbWluZ3NbdGltZXJdLCkKLQotICAgIGRlZiBkdW1wKHNlbGYpOgotICAgICAgICBvdXRsaXN0ID0gW10KLSAgICAgICAgZm9yIHRpbWluZyBpbiBzZWxmLnRpbWluZ3MuaXRlbXMoKToKLSAgICAgICAgICAgIG91dGxpc3QuYXBwZW5kKCIlcyA9ICUuM2ZzIiAlIHRpbWluZykKLSAgICAgICAgcmV0dXJuIG91dGxpc3QKLQotCi0jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwotIyMjIFJlcXVlc3QgRGF0YQotIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKLWNsYXNzIFJlcXVlc3RCYXNlOgotICAgICIiIiBBIGNvbGxlY3Rpb24gZm9yIGFsbCBkYXRhIGFzc29jaWF0ZWQgd2l0aCBPTkUgcmVxdWVzdC4gIiIiCi0KLSAgICAjIEhlYWRlciBzZXQgdG8gZm9yY2UgbWlzYmVoYXZlZCBwcm94aWVzIGFuZCBicm93c2VycyB0byBrZWVwIHRoZWlyCi0gICAgIyBoYW5kcyBvZmYgYSBwYWdlCi0gICAgIyBEZXRhaWxzOiBodHRwOi8vc3VwcG9ydC5taWNyb3NvZnQuY29tL3N1cHBvcnQva2IvYXJ0aWNsZXMvUTIzNC8wLzY3LkFTUAotICAgIG5vY2FjaGUgPSBbCi0gICAgICAgICJQcmFnbWE6IG5vLWNhY2hlIiwKLSAgICAgICAgIkNhY2hlLUNvbnRyb2w6IG5vLWNhY2hlIiwKLSAgICAgICAgIkV4cGlyZXM6IC0xIiwKLSAgICBdCi0KLSAgICBkZWYgX19pbml0X18oc2VsZiwgcHJvcGVydGllcz17fSk6Ci0gICAgICAgIHNlbGYud3JpdGVzdGFjayA9IFtdCi0gICAgICAgIHNlbGYuY2xvY2sgPSBDbG9jaygpCi0gICAgICAgICMgb3JkZXIgaXMgaW1wb3J0YW50IGhlcmUhCi0gICAgICAgIGZyb20gTW9pbk1vaW4gaW1wb3J0IHVzZXIKLSAgICAgICAgc2VsZi51c2VyID0gdXNlci5Vc2VyKHNlbGYpCi0gICAgICAgIHNlbGYuZGljdHMgPSBzZWxmLmluaXRkaWN0cygpCi0KLSAgICAgICAgZnJvbSBNb2luTW9pbiBpbXBvcnQgaTE4bgotCi0gICAgICAgIGlmIGNvbmZpZy50aGVtZV9mb3JjZToKLSAgICAgICAgICAgIHRoZW1lX25hbWUgPSBjb25maWcudGhlbWVfZGVmYXVsdAotICAgICAgICBlbHNlOgotICAgICAgICAgICAgdGhlbWVfbmFtZSA9IHNlbGYudXNlci50aGVtZV9uYW1lCi0gICAgICAgIHRyeToKLSAgICAgICAgICAgIHNlbGYudGhlbWUgPSB3aWtpdXRpbC5pbXBvcnRQbHVnaW4oJ3RoZW1lJywgdGhlbWVfbmFtZSkoc2VsZikKLSAgICAgICAgZXhjZXB0IFR5cGVFcnJvcjoKLSAgICAgICAgICAgIHRoZW1lX25hbWUgPSBjb25maWcudGhlbWVfZGVmYXVsdAotICAgICAgICAgICAgc2VsZi50aGVtZSA9IHdpa2l1dGlsLmltcG9ydFBsdWdpbigndGhlbWUnLCB0aGVtZV9uYW1lKShzZWxmKQotCi0gICAgICAgIHNlbGYuYXJncyA9IE5vbmUKLSAgICAgICAgc2VsZi5mb3JtID0gTm9uZQotICAgICAgICBzZWxmLmxvZ2dlciA9IE5vbmUKLSAgICAgICAgc2VsZi5wcmFnbWEgPSB7fQotICAgICAgICBzZWxmLm1vZGVfZ2V0cGFnZWxpbmtzID0gMAotICAgICAgICBzZWxmLm5vX2Nsb3NpbmdfaHRtbF9jb2RlID0gMAotCi0gICAgICAgIHNlbGYuc2VudF9oZWFkZXJzID0gMAotICAgICAgICBzZWxmLnVzZXJfaGVhZGVycyA9IFtdCi0KLSAgICAgICAgc2VsZi5fX2RpY3RfXy51cGRhdGUocHJvcGVydGllcykKLQotICAgICAgICBzZWxmLmkxOG4gPSBpMThuCi0gICAgICAgIHNlbGYubGFuZyA9IGkxOG4ucmVxdWVzdExhbmd1YWdlKHNlbGYpIAotICAgICAgICBzZWxmLmdldFRleHQgPSBsYW1iZGEgdGV4dCwgaTE4bj1zZWxmLmkxOG4sIHJlcXVlc3Q9c2VsZiwgbGFuZz1zZWxmLmxhbmc6IGkxOG4uZ2V0VGV4dCh0ZXh0LCByZXF1ZXN0LCBsYW5nKQotCi0gICAgICAgICMgWFhYIFJlbW92ZWQgY2FsbCB0byBpMThuLmFkYXB0Y2hhcnNldCgpCi0gIAotICAgICAgICBzZWxmLm9wZW5lZF9sb2dzID0gMCAjIFhYWCBmb3Igd2hhdCBkbyB3ZSBuZWVkIHRoYXQ/Pz8KLQotICAgICAgICBzZWxmLnJlc2V0KCkKLQotICAgIGRlZiBfc2V0dXBfdmFyc19mcm9tX3N0ZF9lbnYoc2VsZiwgZW52KToKLSAgICAgICAgIiIiIFNldHMgdGhlIGNvbW1vbiBSZXF1ZXN0IG1lbWJlcnMgYnkgcGFyc2luZyBhIHN0YW5kYXJkCi0gICAgICAgICAgICBIVFRQRCBlbnZpcm9ubWVudCAoYXMgY3JlYXRlZCBhcyBlbnZpcm9ubWVudCBieSBtb3N0IGNvbW1vbgotICAgICAgICAgICAgd2Vic2VydmVycy4gVG8gYmUgdXNlZCBieSBkZXJpdmVkIGNsYXNzZXMuCi0KLSAgICAgICAgICAgIEBwYXJhbSBlbnY6IHRoZSBlbnZpcm9ubWVudCB0byB1c2UKLSAgICAgICAgIiIiCi0gICAgICAgIHNlbGYuaHR0cF9hY2NlcHRfbGFuZ3VhZ2UgPSBlbnYuZ2V0KCdIVFRQX0FDQ0VQVF9MQU5HVUFHRScsICdlbicpCi0gICAgICAgIHNlbGYuc2VydmVyX25hbWUgPSBlbnYuZ2V0KCdTRVJWRVJfTkFNRScsICdsb2NhbGhvc3QnKQotICAgICAgICBzZWxmLnNlcnZlcl9wb3J0ID0gZW52LmdldCgnU0VSVkVSX1BPUlQnLCAnODAnKQotICAgICAgICBzZWxmLmh0dHBfaG9zdCA9IGVudi5nZXQoJ0hUVFBfSE9TVCcsJ2xvY2FsaG9zdCcpCi0gICAgICAgIHNlbGYuaHR0cF9yZWZlcmVyID0gZW52LmdldCgnSFRUUF9SRUZFUkVSJywgJycpCi0gICAgICAgIHNlbGYuc2F2ZWRfY29va2llID0gZW52LmdldCgnSFRUUF9DT09LSUUnLCAnJykKLSAgICAgICAgc2VsZi5zY3JpcHRfbmFtZSA9IGVudi5nZXQoJ1NDUklQVF9OQU1FJywgJycpCi0gICAgICAgIHNlbGYucGF0aF9pbmZvID0gZW52LmdldCgnUEFUSF9JTkZPJywgJycpCi0gICAgICAgIHNlbGYucXVlcnlfc3RyaW5nID0gZW52LmdldCgnUVVFUllfU1RSSU5HJywgJycpCi0gICAgICAgIHNlbGYucmVxdWVzdF9tZXRob2QgPSBlbnYuZ2V0KCdSRVFVRVNUX01FVEhPRCcsIE5vbmUpCi0gICAgICAgIHNlbGYucmVtb3RlX2FkZHIgPSBlbnYuZ2V0KCdSRU1PVEVfQUREUicsICcnKQotICAgICAgICBzZWxmLmh0dHBfdXNlcl9hZ2VudCA9IGVudi5nZXQoJ0hUVFBfVVNFUl9BR0VOVCcsICcnKQotICAgICAgICBzZWxmLmlzX3NzbCA9IGVudi5nZXQoJ1NTTF9QUk9UT0NPTCcsICcnKSAhPSAnJyBcCi0gICAgICAgICAgICBvciBlbnYuZ2V0KCdTU0xfUFJPVE9DT0xfVkVSU0lPTicsICcnKSAhPSAnJyBcCi0gICAgICAgICAgICBvciBlbnYuZ2V0KCdIVFRQUycsICdvZmYnKSA9PSAnb24nCi0KLSAgICAgICAgc2VsZi5hdXRoX3VzZXJuYW1lID0gTm9uZQotICAgICAgICBpZiBjb25maWcuYXV0aF9odHRwX2VuYWJsZWQgYW5kIGVudi5nZXQoJ0FVVEhfVFlQRScsJycpID09ICdCYXNpYyc6Ci0gICAgICAgICAgICBzZWxmLmF1dGhfdXNlcm5hbWUgPSBlbnYuZ2V0KCdSRU1PVEVfVVNFUicsJycpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKLSMjICAgICAgICBmPW9wZW4oJy90bXAvZW52LmxvZycsJ2EnKQotIyMgICAgICAgIGYud3JpdGUoJy0tLUVOVlxuJykKLSMjICAgICAgICBmLndyaXRlKCdzY3JpcHRfbmFtZSA9ICVzXG4nJShzZWxmLnNjcmlwdF9uYW1lKSkKLSMjICAgICAgICBmLndyaXRlKCdwYXRoX2luZm8gICA9ICVzXG4nJShzZWxmLnBhdGhfaW5mbykpCi0jIyAgICAgICAgZi53cml0ZSgnc2VydmVyX25hbWUgPSAlc1xuJyUoc2VsZi5zZXJ2ZXJfbmFtZSkpCi0jIyAgICAgICAgZi53cml0ZSgnc2VydmVyX3BvcnQgPSAlc1xuJyUoc2VsZi5zZXJ2ZXJfcG9ydCkpCi0jIyAgICAgICAgZi53cml0ZSgnaHR0cF9ob3N0ICAgPSAlc1xuJyUoc2VsZi5odHRwX2hvc3QpKQotIyMgICAgICAgIGYud3JpdGUoJy0tLS0tLVxuJykKLSMjICAgICAgICBmLndyaXRlKCclc1xuJyUocmVwcihlbnYpKSkKLSMjICAgICAgICBmLndyaXRlKCctLS0tLS1cbicpCi0jIyAgICAgICAgZi5jbG9zZSgpCi0gIAotICAgIGRlZiByZXNldChzZWxmKToKLSAgICAgICAgIiIiIFJlc2V0IHJlcXVlc3Qgc3RhdGUuCi0KLSAgICAgICAgQ2FsbGVkIGFmdGVyIHNhdmluZyBhIHBhZ2UsIGJlZm9yZSBzZXJ2aW5nIHRoZSB1cGRhdGVkCi0gICAgICAgIHBhZ2UuIFNvbHZlcyBzb21lIHByYWN0aWNhbCBwcm9ibGVtcyB3aXRoIHJlcXVlc3Qgc3RhdGUKLSAgICAgICAgbW9kaWZpZWQgZHVyaW5nIHNhdmluZy4KLQotICAgICAgICAiIiIKLSAgICAgICAgIyBUaGlzIGlzIHRoZSBjb250ZW50IGxhbmd1YWdlIGFuZCBoYXMgbm90aGluZyB0byBkbyB3aXRoCi0gICAgICAgICMgVGhlIHVzZXIgaW50ZXJmYWNlIGxhbmd1YWdlLiBUaGUgY29udGVudCBsYW5ndWFnZSBjYW4gY2hhbmdlCi0gICAgICAgICMgZHVyaW5nIHRoZSByZW5kZXJpbmcgb2YgYSBwYWdlIGJ5IGxhbmcgbWFjcm9zCi0gICAgICAgIHNlbGYuY3VycmVudF9sYW5nID0gY29uZmlnLmRlZmF1bHRfbGFuZwotICAgICAgICBzZWxmLl9mb290ZXJfZnJhZ21lbnRzID0ge30KLSAgICAgICAgc2VsZi5fYWxsX3BhZ2VzID0gTm9uZQotCi0gICAgICAgIGlmIGhhc2F0dHIoc2VsZiwgIl9mbXRfaGRfY291bnRlcnMiKToKLSAgICAgICAgICAgIGRlbCBzZWxmLl9mbXRfaGRfY291bnRlcnMKLQotCi0gICAgZGVmIGFkZDJmb290ZXIoc2VsZiwga2V5LCBodG1sY29kZSk6Ci0gICAgICAgICIiIiBBZGQgYSBuYW1lZCBIVE1MIGZyYWdtZW50IHRvIHRoZSBmb290ZXIsIGFmdGVyIHRoZSBkZWZhdWx0IGxpbmtzCi0gICAgICAgICIiIgotICAgICAgICBzZWxmLl9mb290ZXJfZnJhZ21lbnRzW2tleV0gPSBodG1sY29kZQotCi0KLSAgICBkZWYgZ2V0UHJhZ21hKHNlbGYsIGtleSwgZGVmdmFsPU5vbmUpOgotICAgICAgICAiIiIgUXVlcnkgYSBwcmFnbWEgdmFsdWUgKCNwcmFnbWEgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbikKLQotICAgICAgICAgICAgS2V5cyBhcmUgbm90IGNhc2Utc2Vuc2l0aXZlLgotICAgICAgICAiIiIKLSAgICAgICAgcmV0dXJuIHNlbGYucHJhZ21hLmdldChrZXkubG93ZXIoKSwgZGVmdmFsKQotCi0KLSAgICBkZWYgc2V0UHJhZ21hKHNlbGYsIGtleSwgdmFsdWUpOgotICAgICAgICAiIiIgU2V0IGEgcHJhZ21hIHZhbHVlICgjcHJhZ21hIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24pCi0KLSAgICAgICAgICAgIEtleXMgYXJlIG5vdCBjYXNlLXNlbnNpdGl2ZS4KLSAgICAgICAgIiIiCi0gICAgICAgIHNlbGYucHJhZ21hW2tleS5sb3dlcigpXSA9IHZhbHVlCi0KLQotICAgIGRlZiBnZXRQYWdlTGlzdChzZWxmKToKLSAgICAgICAgIiIiIEEgY2FjaGVkIHZlcnNpb24gb2Ygd2lraXV0aWwuZ2V0UGFnZUxpc3QoKS4KLSAgICAgICAgICAgIEFsc28sIHRoaXMgbGlzdCBpcyBhbHdheXMgc29ydGVkLgotICAgICAgICAiIiIKLSAgICAgICAgaWYgc2VsZi5fYWxsX3BhZ2VzIGlzIE5vbmU6Ci0gICAgICAgICAgICBzZWxmLl9hbGxfcGFnZXMgPSB3aWtpdXRpbC5nZXRQYWdlTGlzdChjb25maWcudGV4dF9kaXIpCi0gICAgICAgICAgICBzZWxmLl9hbGxfcGFnZXMuc29ydCgpCi0KLSAgICAgICAgcmV0dXJuIHNlbGYuX2FsbF9wYWdlcwotCi0gICAgZGVmIHJlZGlyZWN0KHNlbGYsIGZpbGU9Tm9uZSk6Ci0gICAgICAgIGlmIGZpbGU6ICMgcmVkaXJlY3Qgb3V0cHV0IHRvICJmaWxlIgotICAgICAgICAgICAgc2VsZi53cml0ZXN0YWNrLmFwcGVuZChzZWxmLndyaXRlKQotICAgICAgICAgICAgc2VsZi53cml0ZSA9IGZpbGUud3JpdGUKLSAgICAgICAgZWxzZTogIyByZXN0b3JlIHNhdmVkIG91dHB1dCBmaWxlCi0gICAgICAgICAgICBzZWxmLndyaXRlID0gc2VsZi53cml0ZXN0YWNrLnBvcCgpCi0KLSAgICBkZWYgcmVzZXRfb3V0cHV0KHNlbGYpOgotICAgICAgICAiIiIgcmVzdG9yZSBkZWZhdWx0IG91dHB1dCBtZXRob2QKLSAgICAgICAgICAgIGRlc3Ryb3kgb3V0cHV0IHN0YWNrCi0gICAgICAgICAgICAodXNlZnVsIGZvciBlcnJvciBtZXNzYWdlcykKLSAgICAgICAgIiIiCi0gICAgICAgIGlmIHNlbGYud3JpdGVzdGFjazoKLSAgICAgICAgICAgIHNlbGYud3JpdGUgPSBzZWxmLndyaXRlc3RhY2tbMF0KLSAgICAgICAgICAgIHNlbGYud3JpdGVzdGFjayA9IFtdCi0KLSAgICBkZWYgd3JpdGUoc2VsZiwgKmRhdGEpOgotICAgICAgICAiIiIgV3JpdGUgdG8gb3V0cHV0IHN0cmVhbS4KLSAgICAgICAgIiIiCi0gICAgICAgIHJhaXNlICJOb3RJbXBsZW1lbnRlZEVycm9yIgotCi0gICAgZGVmIHJlYWQoc2VsZiwgbik6Ci0gICAgICAgICIiIiBSZWFkIG4gYnl0ZXMgZnJvbSBpbnB1dCBzdHJlYW0uCi0gICAgICAgICIiIgotICAgICAgICByYWlzZSAiTm90SW1wbGVtZW50ZWRFcnJvciIKLQotICAgIGRlZiBmbHVzaChzZWxmKToKLSAgICAgICAgIiIiIEZsdXNoIG91dHB1dCBzdHJlYW0uCi0gICAgICAgICIiIgotICAgICAgICByYWlzZSAiTm90SW1wbGVtZW50ZWRFcnJvciIKLQotICAgIGRlZiBpbml0ZGljdHMoc2VsZik6Ci0gICAgICAgIGZyb20gTW9pbk1vaW4gaW1wb3J0IHdpa2lkaWN0cwotICAgICAgICBkaWN0cyA9IHdpa2lkaWN0cy5Hcm91cERpY3QoKQotICAgICAgICBkaWN0cy5zY2FuZGljdHMoKQotICAgICAgICByZXR1cm4gZGljdHMKLSAgICAgICAgCi0gICAgZGVmIGlzRm9yYmlkZGVuKHNlbGYpOgotICAgICAgICAiIiIgY2hlY2sgZm9yIHdlYiBzcGlkZXJzIGFuZCByZWZ1c2UgYW55dGhpbmcgZXhjZXB0IHZpZXdpbmcgIiIiCi0gICAgICAgIGZvcmJpZGRlbiA9IDAKLSAgICAgICAgaWYgKChzZWxmLnF1ZXJ5X3N0cmluZyAhPSAnJyBvciBzZWxmLnJlcXVlc3RfbWV0aG9kICE9ICdHRVQnKQotICAgICAgICAgICAgYW5kIHNlbGYucXVlcnlfc3RyaW5nICE9ICdhY3Rpb249cnNzX3JjJyk6Ci0gICAgICAgICAgICBmcm9tIE1vaW5Nb2luLnV0aWwgaW1wb3J0IHdlYgotICAgICAgICAgICAgZm9yYmlkZGVuID0gd2ViLmlzU3BpZGVyQWdlbnQocmVxdWVzdD1zZWxmKQotCi0gICAgICAgIGlmIG5vdCBmb3JiaWRkZW4gYW5kIGNvbmZpZy5ob3N0c19kZW55OgotICAgICAgICAgICAgaXAgPSBzZWxmLnJlbW90ZV9hZGRyCi0gICAgICAgICAgICBmb3IgaG9zdCBpbiBjb25maWcuaG9zdHNfZGVueToKLSAgICAgICAgICAgICAgICBpZiBpcCA9PSBob3N0IG9yIGhvc3RbLTFdID09ICcuJyBhbmQgaXAuc3RhcnRzd2l0aChob3N0KToKLSAgICAgICAgICAgICAgICAgICAgZm9yYmlkZGVuID0gMQotICAgICAgICAgICAgICAgICAgICBicmVhawotICAgICAgICByZXR1cm4gZm9yYmlkZGVuCi0KLQotICAgIGRlZiBzZXR1cF9hcmdzKHNlbGYsIGZvcm09Tm9uZSk6Ci0gICAgICAgIHJldHVybiB7fQotCi0gICAgZGVmIF9zZXR1cF9hcmdzX2Zyb21fY2dpX2Zvcm0oc2VsZiwgZm9ybT1Ob25lKToKLSAgICAgICAgIiIiIEEgbWV0aG9kIHRvIGNyZWF0ZSB0aGUgYXJncyBmcm9tIGEgc3RhbmRhcnQgY2dpLkZpZWxkU3RvcmFnZQotICAgICAgICAgICAgdG8gYmUgdXNlZCBiZSBkZXJpdmVkIGNsYXNzZXMuCi0KLSAgICAgICAgICAgIEBrZXl3b3JkIGZvcm06IGEgY2dpLkZpZWxkU3RvcmFnZSBsaXN0LiBkZWZhdWx0IGlzIHRvIGNhbGwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgIGNnaS5GaWVsZFN0b3JhZ2UoKS4KLSAgICAgICAgIiIiCi0gICAgICAgIGltcG9ydCB0eXBlcywgY2dpCi0gICAgICAgIAotICAgICAgICBpZiBmb3JtIGlzIE5vbmU6Ci0gICAgICAgICAgICBmb3JtID0gY2dpLkZpZWxkU3RvcmFnZSgpCi0KLSAgICAgICAgYXJncyA9IHt9Ci0gICAgICAgIGZvciBrZXkgaW4gZm9ybS5rZXlzKCk6Ci0gICAgICAgICAgICB2YWx1ZXMgPSBmb3JtW2tleV0KLSAgICAgICAgICAgIGlmIG5vdCBpc2luc3RhbmNlKHZhbHVlcywgdHlwZXMuTGlzdFR5cGUpOgotICAgICAgICAgICAgICAgIHZhbHVlcyA9IFt2YWx1ZXNdCi0gICAgICAgICAgICBmaXhlZFJlc3VsdCA9IFtdCi0gICAgICAgICAgICBmb3IgaSBpbiB2YWx1ZXM6Ci0gICAgICAgICAgICAgICAgaWYgaXNpbnN0YW5jZShpLCBjZ2kuTWluaUZpZWxkU3RvcmFnZSk6Ci0gICAgICAgICAgICAgICAgICAgIGZpeGVkUmVzdWx0LmFwcGVuZChpLnZhbHVlKQotICAgICAgICAgICAgICAgIGVsaWYgaXNpbnN0YW5jZShpLCBjZ2kuRmllbGRTdG9yYWdlKToKLSAgICAgICAgICAgICAgICAgICAgZml4ZWRSZXN1bHQuYXBwZW5kKGkudmFsdWUpCi0gICAgICAgICAgICAgICAgICAgICMgbXVsdGlwbGUgdXBsb2FkcyB0byBzYW1lIGZvcm0gZmllbGQgYXJlIHN0dXBpZCEKLSAgICAgICAgICAgICAgICAgICAgaWYgaS5maWxlbmFtZToKLSAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3Nba2V5KydfX2ZpbGVuYW1lX18nXT1pLmZpbGVuYW1lCi0KLSAgICAgICAgICAgIGFyZ3Nba2V5XSA9IGZpeGVkUmVzdWx0Ci0gICAgICAgIHJldHVybiBhcmdzCi0KLSAgICBkZWYgcmVjb2RlUGFnZU5hbWUoc2VsZiwgcGFnZW5hbWUpOgotICAgICAgICAjIGNoZWNrIGZvciBub24tVVJJIGNoYXJhY3RlcnMgYW5kIHRoZW4gaGFuZGxlIHRoZW0gYWNjb3JkaW5nIHRvCi0gICAgICAgICMgaHR0cDovL3d3dy53My5vcmcvVFIvUkVDLWh0bWw0MC9hcHBlbmRpeC9ub3Rlcy5odG1sI2gtQi4yLjEKLSAgICAgICAgaWYgcGFnZW5hbWU6Ci0gICAgICAgICAgICB0cnk6Ci0gICAgICAgICAgICAgICAgZHVtbXkgPSB1bmljb2RlKHBhZ2VuYW1lLCAnYXNjaWknKQotICAgICAgICAgICAgZXhjZXB0IFVuaWNvZGVFcnJvcjoKLSAgICAgICAgICAgICAgICAjIHdlIGhhdmUgc29tZXRoaW5nIGVsc2UgdGhhbiBwbGFpbiBBU0NJSSwgdHJ5Ci0gICAgICAgICAgICAgICAgIyBjb252ZXJ0aW5nIGZyb20gVVRGLTggdG8gbG9jYWwgY2hhcnNldCwgb3IganVzdCBnaXZlCi0gICAgICAgICAgICAgICAgIyB1cCBhbmQgdXNlIFVSSSB2YWx1ZSBsaXRlcmFsbHkgYW5kIHNlZSB3aGF0IGhhcHBlbnMKLSAgICAgICAgICAgICAgICBwYWdlbmFtZSA9IHNlbGYuaTE4bi5yZWNvZGUocGFnZW5hbWUsICd1dGYtOCcsIGNvbmZpZy5jaGFyc2V0KSBvciBwYWdlbmFtZQotICAgICAgICByZXR1cm4gcGFnZW5hbWUKLSAgICAgICAgIyBYWFggVU5JQ09ERSAtIHVzZSB1bmljb2RlIGZvciBwYWdlbmFtZXMgaW50ZXJuYWxseT8KLQotICAgIGRlZiBnZXRCYXNlVVJMKHNlbGYpOgotICAgICAgICAiIiIgUmV0dXJuIGEgZnVsbHkgcXVhbGlmaWVkIFVSTCB0byB0aGlzIHNjcmlwdC4gIiIiCi0gICAgICAgIHJldHVybiBzZWxmLmdldFF1YWxpZmllZFVSTChzZWxmLmdldFNjcmlwdG5hbWUoKSkKLQotCi0gICAgZGVmIGdldFF1YWxpZmllZFVSTChzZWxmLCB1cmk9Tm9uZSk6Ci0gICAgICAgICIiIiBSZXR1cm4gYSBmdWxsIFVSTCBzdGFydGluZyB3aXRoIHNjaGVtYSwgc2VydmVybmFtZSBhbmQgcG9ydC4KLQotICAgICAgICAgICAgKnVyaSogLS0gYXBwZW5kIHRoaXMgc2VydmVyLXJvb3RlZCB1cmkgKG11c3Qgc3RhcnQgd2l0aCBhIHNsYXNoKQotICAgICAgICAiIiIKLSAgICAgICAgaWYgdXJpIGFuZCB1cmlbOjRdID09ICJodHRwIjoKLSAgICAgICAgICAgIHJldHVybiB1cmkKLQotICAgICAgICBzY2hlbWEsIHN0ZHBvcnQgPSAoKCdodHRwJywgJzgwJyksICgnaHR0cHMnLCAnNDQzJykpW3NlbGYuaXNfc3NsXQotICAgICAgICBob3N0ID0gc2VsZi5odHRwX2hvc3QKLSAgICAgICAgaWYgbm90IGhvc3Q6Ci0gICAgICAgICAgICBob3N0ID0gc2VsZi5zZXJ2ZXJfbmFtZQotICAgICAgICAgICAgcG9ydCA9IHNlbGYuc2VydmVyX3BvcnQKLSAgICAgICAgICAgIGlmIHBvcnQgIT0gc3RkcG9ydDoKLSAgICAgICAgICAgICAgICBob3N0ID0gIiVzOiVzIiAlIChob3N0LCBwb3J0KQotCi0gICAgICAgIHJlc3VsdCA9ICIlczovLyVzIiAlIChzY2hlbWEsIGhvc3QpCi0gICAgICAgIGlmIHVyaToKLSAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHVyaQotCi0gICAgICAgIHJldHVybiByZXN1bHQKLQotCi0gICAgZGVmIGdldFVzZXJBZ2VudChzZWxmKToKLSAgICAgICAgIiIiIEdldCB0aGUgdXNlciBhZ2VudC4gIiIiCi0gICAgICAgIHJldHVybiBzZWxmLmh0dHBfdXNlcl9hZ2VudAotCi0KLSAgICBkZWYgcnVuKHNlbGYpOgotICAgICAgICBfID0gc2VsZi5nZXRUZXh0Ci0gICAgICAgIHNlbGYuY2xvY2suc3RhcnQoJ3J1bicpCi0gICAgICAgIHNlbGYub3Blbl9sb2dzKCkKLSAgICAgICAgaWYgc2VsZi5pc0ZvcmJpZGRlbigpOgotICAgICAgICAgICAgc2VsZi5odHRwX2hlYWRlcnMoWwotICAgICAgICAgICAgICAgICdTdGF0dXM6IDQwMyBGT1JCSURERU4nLAotICAgICAgICAgICAgICAgICdDb250ZW50LVR5cGU6IHRleHQvcGxhaW4nCi0gICAgICAgICAgICBdKQotICAgICAgICAgICAgc2VsZi53cml0ZSgnWW91IGFyZSBub3QgYWxsb3dlZCB0byBhY2Nlc3MgdGhpcyFcbicpCi0gICAgICAgICAgICByZXR1cm4gc2VsZi5maW5pc2goKQotCi0gICAgICAgICMgSW1wb3J0cwotICAgICAgICBmcm9tIE1vaW5Nb2luLlBhZ2UgaW1wb3J0IFBhZ2UKLQotICAgICAgICBpZiBzZWxmLnF1ZXJ5X3N0cmluZyA9PSAnYWN0aW9uPXhtbHJwYyc6Ci0gICAgICAgICAgICBmcm9tIE1vaW5Nb2luLndpa2lycGMgaW1wb3J0IHhtbHJwYwotICAgICAgICAgICAgeG1scnBjKHNlbGYpCi0gICAgICAgICAgICByZXR1cm4gc2VsZi5maW5pc2goKQotICAgICAgICAKLSAgICAgICAgaWYgc2VsZi5xdWVyeV9zdHJpbmcgPT0gJ2FjdGlvbj14bWxycGMyJzoKLSAgICAgICAgICAgIGZyb20gTW9pbk1vaW4ud2lraXJwYyBpbXBvcnQgeG1scnBjMgotICAgICAgICAgICAgeG1scnBjMihzZWxmKQotICAgICAgICAgICAgcmV0dXJuIHNlbGYuZmluaXNoKCkKLQotICAgICAgICAjIHBhcnNlIHJlcXVlc3QgZGF0YQotICAgICAgICB0cnk6Ci0gICAgICAgICAgICBzZWxmLmFyZ3MgPSBzZWxmLnNldHVwX2FyZ3MoKQotICAgICAgICAgICAgc2VsZi5mb3JtID0gc2VsZi5hcmdzIAotICAgICAgICAgICAgcGF0aF9pbmZvID0gc2VsZi5nZXRQYXRoaW5mbygpCi0KLSAgICAgICAgICAgICNmcm9tIHBwcmludCBpbXBvcnQgcGZvcm1hdAotICAgICAgICAgICAgI3N5cy5zdGRlcnIud3JpdGUocGZvcm1hdChzZWxmLl9fZGljdF9fKSkKLSAgICAKLSAgICAgICAgICAgIGFjdGlvbiA9IHNlbGYuZm9ybS5nZXQoJ2FjdGlvbicsW05vbmVdKVswXQotCi0gICAgICAgICAgICBwYWdlbmFtZSA9IE5vbmUKLSAgICAgICAgICAgIGlmIGxlbihwYXRoX2luZm8pIGFuZCBwYXRoX2luZm9bMF0gPT0gJy8nOgotICAgICAgICAgICAgICAgIHBhZ2VuYW1lID0gd2lraXV0aWwudW5xdW90ZVdpa2luYW1lKHBhdGhfaW5mb1sxOl0pCi0gICAgICAgIGV4Y2VwdDogIyBjYXRjaCBhbmQgcHJpbnQgYW55IGV4Y2VwdGlvbgotICAgICAgICAgICAgc2VsZi5yZXNldF9vdXRwdXQoKQotICAgICAgICAgICAgc2VsZi5odHRwX2hlYWRlcnMoKQotICAgICAgICAgICAgc2VsZi5wcmludF9leGNlcHRpb24oKQotICAgICAgICAgICAgcmV0dXJuIHNlbGYuZmluaXNoKCkKLQotICAgICAgICB0cnk6Ci0gICAgICAgICAgICAjIHBvc3NpYmx5IGp1bXAgdG8gcGFnZSB3aGVyZSB1c2VyIGxlZnQgb2ZmCi0gICAgICAgICAgICBpZiBub3QgcGFnZW5hbWUgYW5kIG5vdCBhY3Rpb24gYW5kIHNlbGYudXNlci5yZW1lbWJlcl9sYXN0X3Zpc2l0OgotICAgICAgICAgICAgICAgIHBhZ2V0cmFpbCA9IHNlbGYudXNlci5nZXRUcmFpbCgpCi0gICAgICAgICAgICAgICAgaWYgcGFnZXRyYWlsOgotICAgICAgICAgICAgICAgICAgICBzZWxmLmh0dHBfcmVkaXJlY3QoUGFnZShwYWdldHJhaWxbLTFdKS51cmwoc2VsZikpCi0gICAgICAgICAgICAgICAgICAgIHJldHVybiBzZWxmLmZpbmlzaCgpCi0KLSAgICAgICAgICAgICMgaGFuZGxlIHJlcXVlc3QKLSAgICAgICAgICAgIGZyb20gTW9pbk1vaW4gaW1wb3J0IHdpa2lhY3Rpb24KLQotICAgICAgICAgICAgcGFnZW5hbWUgPSBzZWxmLnJlY29kZVBhZ2VOYW1lKHBhZ2VuYW1lKQotCi0gICAgICAgICAgICBpZiBzZWxmLmZvcm0uaGFzX2tleSgnZmlsZXBhdGgnKSBhbmQgc2VsZi5mb3JtLmhhc19rZXkoJ25vcmVkaXJlY3QnKToKLSAgICAgICAgICAgICAgICAjIGxvb2tzIGxpa2UgdXNlciB3YW50cyB0byBzYXZlIGEgZHJhd2luZwotICAgICAgICAgICAgICAgIGZyb20gTW9pbk1vaW4uYWN0aW9uLkF0dGFjaEZpbGUgaW1wb3J0IGV4ZWN1dGUKLSAgICAgICAgICAgICAgICBleGVjdXRlKHBhZ2VuYW1lLCBzZWxmKQotICAgICAgICAgICAgICAgIHJhaXNlIE1vaW5Nb2luTm9Gb290ZXIKLQotICAgICAgICAgICAgaWYgYWN0aW9uOgotICAgICAgICAgICAgICAgIGhhbmRsZXIgPSB3aWtpYWN0aW9uLmdldEhhbmRsZXIoYWN0aW9uKQotICAgICAgICAgICAgICAgIGlmIGhhbmRsZXI6Ci0gICAgICAgICAgICAgICAgICAgIGhhbmRsZXIocGFnZW5hbWUgb3IKLSAgICAgICAgICAgICAgICAgICAgd2lraXV0aWwuZ2V0U3lzUGFnZShzZWxmLCBjb25maWcucGFnZV9mcm9udF9wYWdlKS5wYWdlX25hbWUsIHNlbGYpCi0gICAgICAgICAgICAgICAgZWxzZToKLSAgICAgICAgICAgICAgICAgICAgc2VsZi5odHRwX2hlYWRlcnMoKQotICAgICAgICAgICAgICAgICAgICBzZWxmLndyaXRlKCI8cD4iICsgXygiVW5rbm93biBhY3Rpb24iKSkKLSAgICAgICAgICAgIGVsc2U6Ci0gICAgICAgICAgICAgICAgaWYgc2VsZi5mb3JtLmhhc19rZXkoJ2dvdG8nKToKLSAgICAgICAgICAgICAgICAgICAgcXVlcnkgPSBzZWxmLmZvcm1bJ2dvdG8nXVswXS5zdHJpcCgpCi0gICAgICAgICAgICAgICAgZWxpZiBwYWdlbmFtZToKLSAgICAgICAgICAgICAgICAgICAgcXVlcnkgPSBwYWdlbmFtZQotICAgICAgICAgICAgICAgIGVsc2U6Ci0gICAgICAgICAgICAgICAgICAgIHF1ZXJ5ID0gd2lraXV0aWwudW5xdW90ZVdpa2luYW1lKHNlbGYucXVlcnlfc3RyaW5nKSBvciBcCi0gICAgICAgICAgICAgICAgICAgICAgICB3aWtpdXRpbC5nZXRTeXNQYWdlKHNlbGYsIGNvbmZpZy5wYWdlX2Zyb250X3BhZ2UpLnBhZ2VfbmFtZQotCi0gICAgICAgICAgICAgICAgaWYgY29uZmlnLmFsbG93X2V4dGVuZGVkX25hbWVzOgotICAgICAgICAgICAgICAgICAgICBQYWdlKHF1ZXJ5KS5zZW5kX3BhZ2Uoc2VsZiwgY291bnRfaGl0PTEpCi0gICAgICAgICAgICAgICAgZWxzZToKLSAgICAgICAgICAgICAgICAgICAgZnJvbSBNb2luTW9pbi5wYXJzZXIud2lraSBpbXBvcnQgUGFyc2VyCi0gICAgICAgICAgICAgICAgICAgIGltcG9ydCByZQotICAgICAgICAgICAgICAgICAgICB3b3JkX21hdGNoID0gcmUubWF0Y2goUGFyc2VyLndvcmRfcnVsZSwgcXVlcnkpCi0gICAgICAgICAgICAgICAgICAgIGlmIHdvcmRfbWF0Y2g6Ci0gICAgICAgICAgICAgICAgICAgICAgICB3b3JkID0gd29yZF9tYXRjaC5ncm91cCgwKQotICAgICAgICAgICAgICAgICAgICAgICAgUGFnZSh3b3JkKS5zZW5kX3BhZ2Uoc2VsZiwgY291bnRfaGl0PTEpCi0gICAgICAgICAgICAgICAgICAgIGVsc2U6Ci0gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmh0dHBfaGVhZGVycygpCi0gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLndyaXRlKCc8cD4nICsgXygiQ2FuJ3Qgd29yayBvdXQgcXVlcnkiKSArICcgIjxwcmU+JyArIHF1ZXJ5ICsgJzwvcHJlPiInKQotCi0gICAgICAgICAgICAjIGdlbmVyYXRlIHBhZ2UgZm9vdGVyCi0gICAgICAgICAgICAjIChhY3Rpb25zIHRoYXQgZG8gbm90IHdhbnQgdGhpcyBmb290ZXIgdXNlIHJhaXNlIHV0aWwuTW9pbk1vaW5Ob0Zvb3RlciB0byBicmVhayBvdXQKLSAgICAgICAgICAgICMgb2YgdGhlIGRlZmF1bHQgZXhlY3V0aW9uIHBhdGgsIHNlZSB0aGUgImV4Y2VwdCBNb2luTW9pbk5vRm9vdGVyIiBiZWxvdykKLQotICAgICAgICAgICAgc2VsZi5jbG9jay5zdG9wKCdydW4nKQotICAgICAgICAgICAgc2VsZi5jbG9jay5zdG9wKCd0b3RhbCcpCi0KLSAgICAgICAgICAgIGlmIG5vdCBzZWxmLm5vX2Nsb3NpbmdfaHRtbF9jb2RlOgotICAgICAgICAgICAgICAgIGlmIChjb25maWcuc2hvd190aW1pbmdzIGFuZAotICAgICAgICAgICAgICAgICAgICBzZWxmLmZvcm0uZ2V0KCdhY3Rpb24nLCBbTm9uZV0pWzBdICE9ICdwcmludCcpOgotICAgICAgICAgICAgICAgICAgICBzZWxmLndyaXRlKCc8dWwgaWQ9InRpbWluZ3MiPlxuJykKLSAgICAgICAgICAgICAgICAgICAgZm9yIHQgaW4gc2VsZi5jbG9jay5kdW1wKCk6Ci0gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLndyaXRlKCc8bGk+JXM8L2xpPlxuJyAlIHQpCi0gICAgICAgICAgICAgICAgICAgIHNlbGYud3JpdGUoJzwvdWw+XG4nKQotCi0gICAgICAgICAgICAgICAgaWYgMDogIyB0ZW1wb3JhcmlseSBkaXNhYmxlZCAtIGRvIHdlIG5lZWQgdGhhdD8KLSAgICAgICAgICAgICAgICAgICAgaW1wb3J0IHNvY2tldAotICAgICAgICAgICAgICAgICAgICBmcm9tIE1vaW5Nb2luIGltcG9ydCB2ZXJzaW9uCi0gICAgICAgICAgICAgICAgICAgIHNlbGYud3JpdGUoJzwhLS0gTW9pbk1vaW4gJXMgb24gJXMgc2VydmVkIHRoaXMgcGFnZSBpbiAlcyBzZWNzIC0tPicgJSAoCi0gICAgICAgICAgICAgICAgICAgICAgICB2ZXJzaW9uLnJldmlzaW9uLCBzb2NrZXQuZ2V0aG9zdG5hbWUoKSwgc2VsZi5jbG9jay52YWx1ZSgndG90YWwnKSkgKwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8L2JvZHk+PC9odG1sPicpCi0gICAgICAgICAgICAgICAgZWxzZToKLSAgICAgICAgICAgICAgICAgICAgc2VsZi53cml0ZSgnPC9ib2R5PlxuPC9odG1sPlxuXG4nKQotICAgICAgICAgICAgCi0gICAgICAgIGV4Y2VwdCBNb2luTW9pbk5vRm9vdGVyOgotICAgICAgICAgICAgcGFzcwotCi0gICAgICAgIGV4Y2VwdDogIyBjYXRjaCBhbmQgcHJpbnQgYW55IGV4Y2VwdGlvbgotICAgICAgICAgICAgc2F2ZWRfZXhjID0gc3lzLmV4Y19pbmZvKCkKLSAgICAgICAgICAgIHNlbGYucmVzZXRfb3V0cHV0KCkKLSAgICAgICAgICAgIHNlbGYuaHR0cF9oZWFkZXJzKCkKLSAgICAgICAgICAgIHNlbGYud3JpdGUoIlxuPCEtLSBFUlJPUiBSRVBPUlQgRk9MTE9XUyAtLT5cbiIpCi0gICAgICAgICAgICB0cnk6Ci0gICAgICAgICAgICAgICAgZnJvbSBNb2luTW9pbi5zdXBwb3J0IGltcG9ydCBjZ2l0YgotICAgICAgICAgICAgZXhjZXB0OgotICAgICAgICAgICAgICAgICMgbm8gY2dpdGIsIGZvciB3aGF0ZXZlciByZWFzb24KLSAgICAgICAgICAgICAgICBzZWxmLnByaW50X2V4Y2VwdGlvbigqc2F2ZWRfZXhjKQotICAgICAgICAgICAgZWxzZToKLSAgICAgICAgICAgICAgICB0cnk6Ci0gICAgICAgICAgICAgICAgICAgIGNnaXRiLkhvb2soZmlsZT1zZWxmKS5oYW5kbGUoc2F2ZWRfZXhjKQotICAgICAgICAgICAgICAgICAgICAjIHdhczogY2dpdGIuaGFuZGxlcigpCi0gICAgICAgICAgICAgICAgZXhjZXB0OgotICAgICAgICAgICAgICAgICAgICBzZWxmLnByaW50X2V4Y2VwdGlvbigqc2F2ZWRfZXhjKQotICAgICAgICAgICAgICAgICAgICBzZWxmLndyaXRlKCJcblxuPGhyPlxuIikKLSAgICAgICAgICAgICAgICAgICAgc2VsZi53cml0ZSgiPHA+PHN0cm9uZz5BZGRpdGlvbmFsbHksIGNnaXRiIHJhaXNlZCB0aGlzIGV4Y2VwdGlvbjo8L3N0cm9uZz48L3A+XG4iKQotICAgICAgICAgICAgICAgICAgICBzZWxmLnByaW50X2V4Y2VwdGlvbigpCi0gICAgICAgICAgICBkZWwgc2F2ZWRfZXhjCi0KLSAgICAgICAgcmV0dXJuIHNlbGYuZmluaXNoKCkKLQotCi0gICAgZGVmIGh0dHBfcmVkaXJlY3Qoc2VsZiwgdXJsKToKLSAgICAgICAgIiIiIFJlZGlyZWN0IHRvIGEgZnVsbHkgcXVhbGlmaWVkLCBvciBzZXJ2ZXItcm9vdGVkIFVSTCAiIiIKLSAgICAgICAgaWYgdXJsLmZpbmQoIjovLyIpID09IC0xOgotICAgICAgICAgICAgdXJsID0gc2VsZi5nZXRRdWFsaWZpZWRVUkwodXJsKQotCi0gICAgICAgIHNlbGYuaHR0cF9oZWFkZXJzKFsiU3RhdHVzOiAzMDIiLCAiTG9jYXRpb246ICVzIiAlIHVybF0pCi0KLQotICAgIGRlZiBwcmludF9leGNlcHRpb24oc2VsZiwgdHlwZT1Ob25lLCB2YWx1ZT1Ob25lLCB0Yj1Ob25lLCBsaW1pdD1Ob25lKToKLSAgICAgICAgaWYgdHlwZSBpcyBOb25lOgotICAgICAgICAgICAgdHlwZSwgdmFsdWUsIHRiID0gc3lzLmV4Y19pbmZvKCkKLSAgICAgICAgaW1wb3J0IHRyYWNlYmFjawotICAgICAgICBzZWxmLndyaXRlKCI8aDI+cmVxdWVzdC5wcmludF9leGNlcHRpb24gaGFuZGxlcjwvaDI+XG4iKQotICAgICAgICBzZWxmLndyaXRlKCI8aDM+VHJhY2ViYWNrIChtb3N0IHJlY2VudCBjYWxsIGxhc3QpOjwvaDM+XG4iKQotICAgICAgICBsaXN0ID0gdHJhY2ViYWNrLmZvcm1hdF90Yih0YiwgbGltaXQpICsgXAotICAgICAgICAgICAgICAgdHJhY2ViYWNrLmZvcm1hdF9leGNlcHRpb25fb25seSh0eXBlLCB2YWx1ZSkKLSAgICAgICAgc2VsZi53cml0ZSgiPHByZT4lczxzdHJvbmc+JXM8L3N0cm9uZz48L3ByZT5cbiIgJSAoCi0gICAgICAgICAgICB3aWtpdXRpbC5lc2NhcGUoIiIuam9pbihsaXN0WzotMV0pKSwKLSAgICAgICAgICAgIHdpa2l1dGlsLmVzY2FwZShsaXN0Wy0xXSksKSkKLSAgICAgICAgZGVsIHRiCi0KLQotICAgIGRlZiBvcGVuX2xvZ3Moc2VsZik6Ci0gICAgICAgIHBhc3MKLQotIyBDR0kgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0KLWNsYXNzIFJlcXVlc3RDR0koUmVxdWVzdEJhc2UpOgotICAgICIiIiBzcGVjaWFsaXplZCBvbiBDR0kgcmVxdWVzdHMgIiIiCi0KLSAgICBkZWYgX19pbml0X18oc2VsZiwgcHJvcGVydGllcz17fSk6Ci0gICAgICAgIHNlbGYuX3NldHVwX3ZhcnNfZnJvbV9zdGRfZW52KG9zLmVudmlyb24pCi0gICAgICAgICNzeXMuc3RkZXJyLndyaXRlKCItLS0tXG4iKQotICAgICAgICAjZm9yIGtleSBpbiBvcy5lbnZpcm9uLmtleXMoKTogICAgCi0gICAgICAgICMgICAgc3lzLnN0ZGVyci53cml0ZSgiICAgICVzID0gJyVzJ1xuIiAlIChrZXksIG9zLmVudmlyb25ba2V5XSkpCi0gICAgICAgIFJlcXVlc3RCYXNlLl9faW5pdF9fKHNlbGYsIHByb3BlcnRpZXMpCi0KLSAgICAgICAgIyBmb3JjZSBpbnB1dC9vdXRwdXQgdG8gYmluYXJ5Ci0gICAgICAgIGlmIHN5cy5wbGF0Zm9ybSA9PSAid2luMzIiOgotICAgICAgICAgICAgaW1wb3J0IG1zdmNydAotICAgICAgICAgICAgbXN2Y3J0LnNldG1vZGUoc3lzLnN0ZGluLmZpbGVubygpLCBvcy5PX0JJTkFSWSkKLSAgICAgICAgICAgIG1zdmNydC5zZXRtb2RlKHN5cy5zdGRvdXQuZmlsZW5vKCksIG9zLk9fQklOQVJZKQotCi0gICAgZGVmIG9wZW5fbG9ncyhzZWxmKToKLSAgICAgICAgIyBjcmVhdGUgQ0dJIGxvZyBmaWxlLCBhbmQgb25lIGZvciBjYXRjaGluZyBzdGRlcnIgb3V0cHV0Ci0gICAgICAgIGltcG9ydCBjZ2kgCi0gICAgICAgIGlmIG5vdCBzZWxmLm9wZW5lZF9sb2dzOgotICAgICAgICAgICAgY2dpLmxvZ2ZpbGUgPSBvcy5wYXRoLmpvaW4oY29uZmlnLmRhdGFfZGlyLCAnY2dpLmxvZycpCi0gICAgICAgICAgICBzeXMuc3RkZXJyID0gb3Blbihvcy5wYXRoLmpvaW4oY29uZmlnLmRhdGFfZGlyLCAnZXJyb3IubG9nJyksICdhdCcpCi0gICAgICAgICAgICBzZWxmLm9wZW5lZF9sb2dzID0gMQotCi0gICAgZGVmIHNldHVwX2FyZ3Moc2VsZiwgZm9ybT1Ob25lKToKLSAgICAgICAgcmV0dXJuIHNlbGYuX3NldHVwX2FyZ3NfZnJvbV9jZ2lfZm9ybShmb3JtKQotICAgICAgICAKLSAgICBkZWYgcmVhZChzZWxmLCBuPU5vbmUpOgotICAgICAgICAiIiIgUmVhZCBmcm9tIGlucHV0IHN0cmVhbS4KLSAgICAgICAgIiIiCi0gICAgICAgIGlmIG4gaXMgTm9uZToKLSAgICAgICAgICAgIHJldHVybiBzeXMuc3RkaW4ucmVhZCgpCi0gICAgICAgIGVsc2U6Ci0gICAgICAgICAgICByZXR1cm4gc3lzLnN0ZGluLnJlYWQobikKLQotICAgIGRlZiB3cml0ZShzZWxmLCAqZGF0YSk6Ci0gICAgICAgICIiIiBXcml0ZSB0byBvdXRwdXQgc3RyZWFtLgotICAgICAgICAiIiIKLSAgICAgICAgZm9yIHBpZWNlIGluIGRhdGE6Ci0gICAgICAgICAgICBzeXMuc3Rkb3V0LndyaXRlKHBpZWNlKQotCi0gICAgZGVmIGZsdXNoKHNlbGYpOgotICAgICAgICBzeXMuc3Rkb3V0LmZsdXNoKCkKLSAgICAgICAgCi0gICAgZGVmIGZpbmlzaChzZWxmKToKLSAgICAgICAgIyBmbHVzaCB0aGUgb3V0cHV0LCBpZ25vcmUgZXJyb3JzIGNhdXNlZCBieSB0aGUgdXNlciBjbG9zaW5nIHRoZSBzb2NrZXQKLSAgICAgICAgdHJ5OgotICAgICAgICAgICAgc3lzLnN0ZG91dC5mbHVzaCgpCi0gICAgICAgIGV4Y2VwdCBJT0Vycm9yLCBleDoKLSAgICAgICAgICAgIGltcG9ydCBlcnJubwotICAgICAgICAgICAgaWYgZXguZXJybm8gIT0gZXJybm8uRVBJUEU6IHJhaXNlCi0KLSAgICAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwotICAgICMjIyBBY2Nlc3NvcnMKLSAgICAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwotCi0gICAgZGVmIGdldFNjcmlwdG5hbWUoc2VsZik6Ci0gICAgICAgICIiIiBSZXR1cm4gdGhlIHNjcmlwdG5hbWUgcGFydCBvZiB0aGUgVVJMICgiL3BhdGgvdG8vbXkuY2dpIikuICIiIgotICAgICAgICBuYW1lID0gc2VsZi5zY3JpcHRfbmFtZQotICAgICAgICBpZiBuYW1lID09ICcvJzoKLSAgICAgICAgICAgIHJldHVybiAnJwotICAgICAgICByZXR1cm4gbmFtZQotCi0KLSAgICBkZWYgZ2V0UGF0aGluZm8oc2VsZik6Ci0gICAgICAgICIiIiBSZXR1cm4gdGhlIHJlbWFpbmluZyBwYXJ0IG9mIHRoZSBVUkwuICIiIgotICAgICAgICBwYXRoaW5mbyA9IHNlbGYucGF0aF9pbmZvCi0KLSAgICAgICAgIyBGaXggZm9yIGJ1ZyBpbiBJSVMvNC4wCi0gICAgICAgIGlmIG9zLm5hbWUgPT0gJ250JzoKLSAgICAgICAgICAgIHNjcmlwdG5hbWUgPSBzZWxmLmdldFNjcmlwdG5hbWUoKQotICAgICAgICAgICAgaWYgcGF0aGluZm8uc3RhcnRzd2l0aChzY3JpcHRuYW1lKToKLSAgICAgICAgICAgICAgICBwYXRoaW5mbyA9IHBhdGhpbmZvW2xlbihzY3JpcHRuYW1lKTpdCi0KLSAgICAgICAgcmV0dXJuIHBhdGhpbmZvCi0KLQotICAgICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCi0gICAgIyMjIEhlYWRlcnMKLSAgICAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwotCi0gICAgZGVmIHNldEh0dHBIZWFkZXIoc2VsZiwgaGVhZGVyKToKLSAgICAgICAgc2VsZi51c2VyX2hlYWRlcnMuYXBwZW5kKGhlYWRlcikKLQotCi0gICAgZGVmIGh0dHBfaGVhZGVycyhzZWxmLCBtb3JlX2hlYWRlcnM9W10pOgotICAgICAgICBpZiBzZWxmLnNlbnRfaGVhZGVyczoKLSAgICAgICAgICAgICNzZWxmLndyaXRlKCJIZWFkZXJzIGFscmVhZHkgc2VudCEhIVxuIikKLSAgICAgICAgICAgIHJldHVybgotICAgICAgICBzZWxmLnNlbnRfaGVhZGVycyA9IDEKLSAgICAgICAgaGF2ZV9jdCA9IDAKLQotICAgICAgICAjIHNlbmQgaHR0cCBoZWFkZXJzCi0gICAgICAgIGZvciBoZWFkZXIgaW4gbW9yZV9oZWFkZXJzICsgc2VsZi51c2VyX2hlYWRlcnM6Ci0gICAgICAgICAgICBpZiBoZWFkZXIubG93ZXIoKS5zdGFydHN3aXRoKCJjb250ZW50LXR5cGU6Iik6Ci0gICAgICAgICAgICAgICAgIyBkb24ndCBzZW5kIGNvbnRlbnQtdHlwZSBtdWx0aXBsZSB0aW1lcyEKLSAgICAgICAgICAgICAgICBpZiBoYXZlX2N0OiBjb250aW51ZQotICAgICAgICAgICAgICAgIGhhdmVfY3QgPSAxCi0gICAgICAgICAgICBzZWxmLndyaXRlKCIlc1xyXG4iICUgaGVhZGVyKQotCi0gICAgICAgIGlmIG5vdCBoYXZlX2N0OgotICAgICAgICAgICAgc2VsZi53cml0ZSgiQ29udGVudC10eXBlOiB0ZXh0L2h0bWw7Y2hhcnNldD0lc1xyXG4iICUgY29uZmlnLmNoYXJzZXQpCi0KLSAgICAgICAgc2VsZi53cml0ZSgnXHJcbicpCi0KLSAgICAgICAgI2Zyb20gcHByaW50IGltcG9ydCBwZm9ybWF0Ci0gICAgICAgICNzeXMuc3RkZXJyLndyaXRlKHBmb3JtYXQobW9yZV9oZWFkZXJzKSkKLSAgICAgICAgI3N5cy5zdGRlcnIud3JpdGUocGZvcm1hdChzZWxmLnVzZXJfaGVhZGVycykpCi0KLQotIyBUd2lzdGVkIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0KLWNsYXNzIFJlcXVlc3RUd2lzdGVkKFJlcXVlc3RCYXNlKToKLSAgICAiIiIgc3BlY2lhbGl6ZWQgb24gVHdpc3RlZCByZXF1ZXN0cyAiIiIKLQotICAgIGRlZiBfX2luaXRfXyhzZWxmLCB0d2lzdGVkUmVxdWVzdCwgcGFnZW5hbWUsIHJlYWN0b3IsIHByb3BlcnRpZXM9e30pOgotICAgICAgICBzZWxmLnR3aXN0ZCA9IHR3aXN0ZWRSZXF1ZXN0Ci0gICAgICAgIHNlbGYuaHR0cF9hY2NlcHRfbGFuZ3VhZ2UgPSBzZWxmLnR3aXN0ZC5nZXRIZWFkZXIoJ0FjY2VwdC1MYW5ndWFnZScpCi0gICAgICAgIHNlbGYucmVhY3RvciA9IHJlYWN0b3IKLSAgICAgICAgc2VsZi5zYXZlZF9jb29raWUgPSBzZWxmLnR3aXN0ZC5nZXRIZWFkZXIoJ0Nvb2tpZScpCi0gICAgICAgIHNlbGYuc2VydmVyX3Byb3RvY29sID0gc2VsZi50d2lzdGQuY2xpZW50cHJvdG8KLSAgICAgICAgc2VsZi5zZXJ2ZXJfbmFtZSA9IHNlbGYudHdpc3RkLmdldFJlcXVlc3RIb3N0bmFtZSgpLnNwbGl0KCc6JylbMF0KLSAgICAgICAgc2VsZi5zZXJ2ZXJfcG9ydCA9IHN0cihzZWxmLnR3aXN0ZC5nZXRIb3N0KClbMl0pCi0gICAgICAgIHNlbGYuaXNfc3NsID0gc2VsZi50d2lzdGQuaXNTZWN1cmUoKQotICAgICAgICBpZiBzZWxmLnNlcnZlcl9wb3J0ICE9ICgnODAnLCAnNDQzJylbc2VsZi5pc19zc2xdOgotICAgICAgICAgICAgc2VsZi5odHRwX2hvc3QgPSBzZWxmLnNlcnZlcl9uYW1lICsgJzonICsgc2VsZi5zZXJ2ZXJfcG9ydAotICAgICAgICBlbHNlOgotICAgICAgICAgICAgc2VsZi5odHRwX2hvc3QgPSBzZWxmLnNlcnZlcl9uYW1lCi0gICAgICAgIHNlbGYuc2NyaXB0X25hbWUgPSAiLyIgKyAnLycuam9pbihzZWxmLnR3aXN0ZC5wcmVwYXRoWzotMV0pICMgIiIgWFhYCi0gICAgICAgIHNlbGYucGF0aF9pbmZvID0gIi8iICsgcGFnZW5hbWUKLSAgICAgICAgaWYgc2VsZi50d2lzdGQucG9zdHBhdGg6Ci0gICAgICAgICAgICBzZWxmLnBhdGhfaW5mbyArPSAnLycgKyAnLycuam9pbihzZWxmLnR3aXN0ZC5wb3N0cGF0aCkKLSAgICAgICAgc2VsZi5yZXF1ZXN0X21ldGhvZCA9IHNlbGYudHdpc3RkLm1ldGhvZAotICAgICAgICBzZWxmLnJlbW90ZV9ob3N0ID0gc2VsZi50d2lzdGQuZ2V0Q2xpZW50KCkKLSAgICAgICAgc2VsZi5yZW1vdGVfYWRkciA9IHNlbGYudHdpc3RkLmdldENsaWVudElQKCkKLSAgICAgICAgc2VsZi5odHRwX3VzZXJfYWdlbnQgPSBzZWxmLnR3aXN0ZC5nZXRIZWFkZXIoJ1VzZXItQWdlbnQnKQotICAgICAgICBzZWxmLnJlcXVlc3RfdXJpID0gc2VsZi50d2lzdGQudXJpCi0gICAgICAgCi0gICAgICAgIHFpbmRleCA9IHNlbGYucmVxdWVzdF91cmkuZmluZCgnPycpCi0gICAgICAgIGlmIHFpbmRleCAhPSAtMToKLSAgICAgICAgICAgIHNlbGYucXVlcnlfc3RyaW5nID0gc2VsZi5yZXF1ZXN0X3VyaVtxaW5kZXgrMTpdCi0gICAgICAgIGVsc2U6Ci0gICAgICAgICAgICBzZWxmLnF1ZXJ5X3N0cmluZyA9ICcnCi0gICAgICAgIHNlbGYub3V0cHV0bGlzdCA9IFtdCi0gICAgICAgIHNlbGYuYXV0aF91c2VybmFtZSA9IE5vbmUgIyBUT0RPLCBzZWU6IHNlbGYudHdpc3RkLnVzZXIgLyAucGFzc3dvcmQgKGh0dHAgYXV0aCkKLSAgICAgICAgUmVxdWVzdEJhc2UuX19pbml0X18oc2VsZiwgcHJvcGVydGllcykKLSAgICAgICAgI3ByaW50ICJyZXF1ZXN0LlJlcXVlc3RUd2lzdGVkLl9faW5pdF9fOiByZWNlaXZlZF9oZWFkZXJzPVxuIiArIHN0cihzZWxmLnR3aXN0ZC5yZWNlaXZlZF9oZWFkZXJzKQotCi0gICAgZGVmIHNldHVwX2FyZ3Moc2VsZiwgZm9ybT1Ob25lKToKLSAgICAgICAgcmV0dXJuIHNlbGYudHdpc3RkLmFyZ3MKLSAgICAgICAgCi0gICAgZGVmIHJlYWQoc2VsZiwgbj1Ob25lKToKLSAgICAgICAgIiIiIFJlYWQgZnJvbSBpbnB1dCBzdHJlYW0uCi0gICAgICAgICIiIgotICAgICAgICAjIFhYWCB3aHkgaXMgdGhhdCB3cm9uZz86Ci0gICAgICAgICNyZCA9IHNlbGYucmVhY3Rvci5jYWxsRnJvbVRocmVhZChzZWxmLnR3aXN0ZC5yZWFkKQotICAgICAgICAKLSAgICAgICAgIyBYWFggZG8gd2UgbmVlZCBzZWxmLnJlYWN0b3IuY2FsbEZyb21UaHJlYWQgd2l0aCB0aGF0PwotICAgICAgICAjIFhYWCBpZiB5ZXMsIHdoeSBkb2VzbnQgaXQgd29yaz8KLSAgICAgICAgc2VsZi50d2lzdGQuY29udGVudC5zZWVrKDAsIDApCi0gICAgICAgIGlmIG4gaXMgTm9uZToKLSAgICAgICAgICAgIHJkID0gc2VsZi50d2lzdGQuY29udGVudC5yZWFkKCkKLSAgICAgICAgZWxzZToKLSAgICAgICAgICAgIHJkID0gc2VsZi50d2lzdGQuY29udGVudC5yZWFkKG4pCi0gICAgICAgICNwcmludCAicmVxdWVzdC5SZXF1ZXN0VHdpc3RlZC5yZWFkOiBkYXRhPVxuIiArIHN0cihyZCkKLSAgICAgICAgcmV0dXJuIHJkCi0gICAgCi0gICAgZGVmIHdyaXRlKHNlbGYsICpkYXRhKToKLSAgICAgICAgIiIiIFdyaXRlIHRvIG91dHB1dCBzdHJlYW0uCi0gICAgICAgICIiIgotICAgICAgICB3ZCA9ICcnLmpvaW4oZGF0YSkKLSAgICAgICAgIyBYWFggVU5JQ09ERSAtIGVuY29kZSB0byBjb25maWcuY2hhcnNldAotICAgICAgICAjd2QgPSB1Jycuam9pbihkYXRhKS5lbmNvZGUoY29uZmlnLmNoYXJzZXQpCi0gICAgICAgICNwcmludCAicmVxdWVzdC5SZXF1ZXN0VHdpc3RlZC53cml0ZTogZGF0YT1cbiIgKyB3ZAotICAgICAgICBzZWxmLnJlYWN0b3IuY2FsbEZyb21UaHJlYWQoc2VsZi50d2lzdGQud3JpdGUsIHdkKQotCi0gICAgZGVmIGZsdXNoKHNlbGYpOgotICAgICAgICBwYXNzICMgWFhYIGlzIHRoZXJlIGEgZmx1c2ggaW4gdHdpc3RlZD8KLQotICAgIGRlZiBmaW5pc2goc2VsZik6Ci0gICAgICAgICNwcmludCAicmVxdWVzdC5SZXF1ZXN0VHdpc3RlZC5maW5pc2giCi0gICAgICAgIHNlbGYucmVhY3Rvci5jYWxsRnJvbVRocmVhZChzZWxmLnR3aXN0ZC5maW5pc2gpCi0KLSAgICBkZWYgb3Blbl9sb2dzKHNlbGYpOgotICAgICAgICByZXR1cm4KLSAgICAgICAgIyBjcmVhdGUgbG9nIGZpbGUgZm9yIGNhdGNoaW5nIHN0ZGVyciBvdXRwdXQKLSAgICAgICAgaWYgbm90IHNlbGYub3BlbmVkX2xvZ3M6Ci0gICAgICAgICAgICBzeXMuc3RkZXJyID0gb3Blbihvcy5wYXRoLmpvaW4oY29uZmlnLmRhdGFfZGlyLCAnZXJyb3IubG9nJyksICdhdCcpCi0gICAgICAgICAgICBzZWxmLm9wZW5lZF9sb2dzID0gMQotCi0KLSAgICAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwotICAgICMjIyBBY2Nlc3NvcnMKLSAgICAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwotCi0gICAgZGVmIGdldFNjcmlwdG5hbWUoc2VsZik6Ci0gICAgICAgICIiIiBSZXR1cm4gdGhlIHNjcmlwdG5hbWUgcGFydCBvZiB0aGUgVVJMICgiL3BhdGgvdG8vbXkuY2dpIikuICIiIgotICAgICAgICBzY3JpcHRuYW1lID0gc2VsZi5zY3JpcHRfbmFtZQotICAgICAgICBpZiBzY3JpcHRuYW1lID09ICcvJzoKLSAgICAgICAgICAgIHNjcmlwdG5hbWUgPSAnJwotICAgICAgICByZXR1cm4gc2NyaXB0bmFtZQotCi0gICAgZGVmIGdldFBhdGhpbmZvKHNlbGYpOgotICAgICAgICAiIiIgUmV0dXJuIHRoZSByZW1haW5pbmcgcGFydCBvZiB0aGUgVVJMLiAiIiIKLSAgICAgICAgcmV0dXJuIHNlbGYucGF0aF9pbmZvCi0KLQotICAgICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCi0gICAgIyMjIEhlYWRlcnMKLSAgICAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwotCi0gICAgZGVmIHNldEh0dHBIZWFkZXIoc2VsZiwgaGVhZGVyKToKLSAgICAgICAgc2VsZi51c2VyX2hlYWRlcnMuYXBwZW5kKGhlYWRlcikKLQotICAgIGRlZiBfX3NldEh0dHBIZWFkZXIoc2VsZiwgaGVhZGVyKToKLSAgICAgICAga2V5LCB2YWx1ZSA9IGhlYWRlci5zcGxpdCgnOicsMSkKLSAgICAgICAgdmFsdWUgPSB2YWx1ZS5sc3RyaXAoKQotICAgICAgICBzZWxmLnR3aXN0ZC5zZXRIZWFkZXIoa2V5LCB2YWx1ZSkKLSAgICAgICAgI3ByaW50ICJyZXF1ZXN0LlJlcXVlc3RUd2lzdGVkLnNldEh0dHBIZWFkZXI6ICVzIiAlIGhlYWRlcgotCi0gICAgZGVmIGh0dHBfaGVhZGVycyhzZWxmLCBtb3JlX2hlYWRlcnM9W10pOgotICAgICAgICBpZiBzZWxmLnNlbnRfaGVhZGVyczoKLSAgICAgICAgICAgICNzZWxmLndyaXRlKCJIZWFkZXJzIGFscmVhZHkgc2VudCEhIVxuIikKLSAgICAgICAgICAgIHJldHVybgotICAgICAgICBzZWxmLnNlbnRfaGVhZGVycyA9IDEKLSAgICAgICAgaGF2ZV9jdCA9IDAKLQotICAgICAgICAjIHNldCBodHRwIGhlYWRlcnMKLSAgICAgICAgZm9yIGhlYWRlciBpbiBtb3JlX2hlYWRlcnMgKyBzZWxmLnVzZXJfaGVhZGVyczoKLSAgICAgICAgICAgIGlmIGhlYWRlci5sb3dlcigpLnN0YXJ0c3dpdGgoImNvbnRlbnQtdHlwZToiKToKLSAgICAgICAgICAgICAgICAjIGRvbid0IHNlbmQgY29udGVudC10eXBlIG11bHRpcGxlIHRpbWVzIQotICAgICAgICAgICAgICAgIGlmIGhhdmVfY3Q6IGNvbnRpbnVlCi0gICAgICAgICAgICAgICAgaGF2ZV9jdCA9IDEKLSAgICAgICAgICAgIHNlbGYuX19zZXRIdHRwSGVhZGVyKGhlYWRlcikKLQotICAgICAgICBpZiBub3QgaGF2ZV9jdDoKLSAgICAgICAgICAgIHNlbGYuX19zZXRIdHRwSGVhZGVyKCJDb250ZW50LXR5cGU6IHRleHQvaHRtbDtjaGFyc2V0PSVzIiAlIGNvbmZpZy5jaGFyc2V0KQotCi0KLSAgICBkZWYgaHR0cF9yZWRpcmVjdChzZWxmLCB1cmwpOgotICAgICAgICAiIiIgUmVkaXJlY3QgdG8gYSBmdWxseSBxdWFsaWZpZWQsIG9yIHNlcnZlci1yb290ZWQgVVJMICIiIgotICAgICAgICBpZiB1cmwuY291bnQoIjovLyIpID09IDA6Ci0gICAgICAgICAgICAjIG5vIGh0dHBzIG1ldGhvZD8/Ci0gICAgICAgICAgICB1cmwgPSAiaHR0cDovLyVzOiVzJXMiICUgKHNlbGYuc2VydmVyX25hbWUsIHNlbGYuc2VydmVyX3BvcnQsIHVybCkKLQotICAgICAgICBzZWxmLnR3aXN0ZC5yZWRpcmVjdCh1cmwpCi0gICAgICAgICMgY2FsbGluZyBmaW5pc2ggaGVyZSB3aWxsIHNlbmQgdGhlIHJlc3Qgb2YgdGhlIGRhdGEgdG8gdGhlIG5leHQKLSAgICAgICAgIyByZXF1ZXN0LiBsZWF2ZSB0aGUgZmluaXNoIGNhbGwgdG8gcnVuKCkKLSAgICAgICAgI3NlbGYudHdpc3RkLmZpbmlzaCgpCi0gICAgICAgIHJhaXNlIE1vaW5Nb2luTm9Gb290ZXIKLQotCi0jIENMSSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLWNsYXNzIFJlcXVlc3RDTEkoUmVxdWVzdEJhc2UpOgotICAgICIiIiBzcGVjaWFsaXplZCBvbiBjb21tYW5kbGluZSBpbnRlcmZhY2UgcmVxdWVzdHMgIiIiCi0KLSAgICBkZWYgX19pbml0X18oc2VsZiwgcGFnZW5hbWU9JycsIHByb3BlcnRpZXM9e30pOgotICAgICAgICBzZWxmLmh0dHBfYWNjZXB0X2xhbmd1YWdlID0gJycKLSAgICAgICAgc2VsZi5zYXZlZF9jb29raWUgPSAnJwotICAgICAgICBzZWxmLnBhdGhfaW5mbyA9ICcvJyArIHBhZ2VuYW1lCi0gICAgICAgIHNlbGYucXVlcnlfc3RyaW5nID0gJycKLSAgICAgICAgc2VsZi5yZW1vdGVfYWRkciA9ICcxMjcuMC4wLjEyNycKLSAgICAgICAgc2VsZi5pc19zc2wgPSAwCi0gICAgICAgIHNlbGYuYXV0aF91c2VybmFtZSA9IE5vbmUKLSAgICAgICAgUmVxdWVzdEJhc2UuX19pbml0X18oc2VsZiwgcHJvcGVydGllcykKLSAgICAgICAgc2VsZi5odHRwX3VzZXJfYWdlbnQgPSAnJwotICAgICAgICBzZWxmLm91dHB1dGxpc3QgPSBbXQotCi0gICAgZGVmIHJlYWQoc2VsZiwgbj1Ob25lKToKLSAgICAgICAgIiIiIFJlYWQgZnJvbSBpbnB1dCBzdHJlYW0uCi0gICAgICAgICIiIgotICAgICAgICBpZiBuIGlzIE5vbmU6Ci0gICAgICAgICAgICByZXR1cm4gc3lzLnN0ZGluLnJlYWQoKQotICAgICAgICBlbHNlOgotICAgICAgICAgICAgcmV0dXJuIHN5cy5zdGRpbi5yZWFkKG4pCi0KLSAgICBkZWYgd3JpdGUoc2VsZiwgKmRhdGEpOgotICAgICAgICAiIiIgV3JpdGUgdG8gb3V0cHV0IHN0cmVhbS4KLSAgICAgICAgIiIiCi0gICAgICAgIGZvciBwaWVjZSBpbiBkYXRhOgotICAgICAgICAgICAgc3lzLnN0ZG91dC53cml0ZShwaWVjZSkKLQotICAgIGRlZiBmbHVzaChzZWxmKToKLSAgICAgICAgc3lzLnN0ZG91dC5mbHVzaCgpCi0gICAgICAgIAotICAgIGRlZiBmaW5pc2goc2VsZik6Ci0gICAgICAgICMgZmx1c2ggdGhlIG91dHB1dCwgaWdub3JlIGVycm9ycyBjYXVzZWQgYnkgdGhlIHVzZXIgY2xvc2luZyB0aGUgc29ja2V0Ci0gICAgICAgIHRyeToKLSAgICAgICAgICAgIHN5cy5zdGRvdXQuZmx1c2goKQotICAgICAgICBleGNlcHQgSU9FcnJvciwgZXg6Ci0gICAgICAgICAgICBpbXBvcnQgZXJybm8KLSAgICAgICAgICAgIGlmIGV4LmVycm5vICE9IGVycm5vLkVQSVBFOiByYWlzZQotCi0gICAgZGVmIGlzRm9yYmlkZGVuKHNlbGYpOgotICAgICAgICAiIiIgY2hlY2sgZm9yIHdlYiBzcGlkZXJzIGFuZCByZWZ1c2UgYW55dGhpbmcgZXhjZXB0IHZpZXdpbmcgIiIiCi0gICAgICAgIHJldHVybiAwCi0KLQotICAgICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCi0gICAgIyMjIEFjY2Vzc29ycwotICAgICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCi0KLSAgICBkZWYgZ2V0U2NyaXB0bmFtZShzZWxmKToKLSAgICAgICAgIiIiIFJldHVybiB0aGUgc2NyaXB0bmFtZSBwYXJ0IG9mIHRoZSBVUkwgKCIvcGF0aC90by9teS5jZ2kiKS4gIiIiCi0gICAgICAgIHJldHVybiAnLicKLQotICAgIGRlZiBnZXRQYXRoaW5mbyhzZWxmKToKLSAgICAgICAgIiIiIFJldHVybiB0aGUgcmVtYWluaW5nIHBhcnQgb2YgdGhlIFVSTC4gIiIiCi0gICAgICAgIHJldHVybiBzZWxmLnBhdGhfaW5mbwotCi0KLSAgICBkZWYgZ2V0UXVhbGlmaWVkVVJMKHNlbGYsIHVyaSA9IE5vbmUpOgotICAgICAgICAiIiIgUmV0dXJuIGEgZnVsbCBVUkwgc3RhcnRpbmcgd2l0aCBzY2hlbWEsIHNlcnZlcm5hbWUgYW5kIHBvcnQuCi0KLSAgICAgICAgICAgICp1cmkqIC0tIGFwcGVuZCB0aGlzIHNlcnZlci1yb290ZWQgdXJpIChtdXN0IHN0YXJ0IHdpdGggYSBzbGFzaCkKLSAgICAgICAgIiIiCi0gICAgICAgIHJldHVybiB1cmkKLQotCi0gICAgZGVmIGdldEJhc2VVUkwoc2VsZik6Ci0gICAgICAgICIiIiBSZXR1cm4gYSBmdWxseSBxdWFsaWZpZWQgVVJMIHRvIHRoaXMgc2NyaXB0LiAiIiIKLSAgICAgICAgcmV0dXJuIHNlbGYuZ2V0UXVhbGlmaWVkVVJMKHNlbGYuZ2V0U2NyaXB0bmFtZSgpKQotCi0KLQotICAgICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCi0gICAgIyMjIEhlYWRlcnMKLSAgICAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwotCi0gICAgZGVmIHNldEh0dHBIZWFkZXIoc2VsZiwgaGVhZGVyKToKLSAgICAgICAgcGFzcwotCi0gICAgZGVmIGh0dHBfaGVhZGVycyhzZWxmLCBtb3JlX2hlYWRlcnM9W10pOgotICAgICAgICBwYXNzCi0KLSAgICBkZWYgaHR0cF9yZWRpcmVjdChzZWxmLCB1cmwpOgotICAgICAgICAiIiIgUmVkaXJlY3QgdG8gYSBmdWxseSBxdWFsaWZpZWQsIG9yIHNlcnZlci1yb290ZWQgVVJMICIiIgotICAgICAgICByYWlzZSBFeGNlcHRpb24oIlJlZGlyZWN0IG5vdCBzdXBwb3J0ZWQgZm9yIGNvbW1hbmQgbGluZSB0b29scyEiKQotCi0KLSMgU3RhbmRBbG9uZSBTZXJ2ZXIgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotY2xhc3MgUmVxdWVzdFN0YW5kQWxvbmUoUmVxdWVzdEJhc2UpOgotICAgICIiIgotICAgIHNwZWNpYWxpemVkIG9uIFN0YW5kQWxvbmUgU2VydmVyIChodHRwZG1haW4ucHkpIHJlcXVlc3RzCi0gICAgIiIiCi0KLSAgICBkZWYgX19pbml0X18oc2VsZiwgc2EsIHByb3BlcnRpZXM9e30pOgotICAgICAgICAiIiIKLSAgICAgICAgQHBhcmFtIHNhOiBzdGFuZCBhbG9uZSBzZXJ2ZXIgb2JqZWN0Ci0gICAgICAgIEBwYXJhbSBwcm9wZXJ0aWVzOiAuLi4KLSAgICAgICAgIiIiCi0gICAgICAgIGltcG9ydCB1cmxsaWIKLSAgICAgICAgc2VsZi53ZmlsZSA9IHNhLndmaWxlCi0gICAgICAgIHNlbGYucmZpbGUgPSBzYS5yZmlsZQotICAgICAgICBzZWxmLmhlYWRlcnMgPSBzYS5oZWFkZXJzCi0gICAgICAgIHNlbGYuaXNfc3NsID0gMAotICAgICAgICByZXN0ID0gc2EucGF0aAotICAgICAgICBpID0gcmVzdC5yZmluZCgnPycpCi0gICAgICAgIGlmIGkgPj0gMDoKLSAgICAgICAgICAgIHJlc3QsIHF1ZXJ5ID0gcmVzdFs6aV0sIHJlc3RbaSsxOl0KLSAgICAgICAgZWxzZToKLSAgICAgICAgICAgIHF1ZXJ5ID0gJycKLSAgICAgICAgdXFyZXN0ID0gdXJsbGliLnVucXVvdGUocmVzdCkKLSAgICAgICAgCi0gICAgICAgICNIVFRQIGhlYWRlcnMKLSAgICAgICAgc2VsZi5lbnYgPSB7fSAKLSAgICAgICAgZm9yIGhsaW5lIGluIHNhLmhlYWRlcnMuaGVhZGVyczoKLSAgICAgICAgICAgIGtleSA9IHNhLmhlYWRlcnMuaXNoZWFkZXIoaGxpbmUpCi0gICAgICAgICAgICBpZiBrZXk6Ci0gICAgICAgICAgICAgICAgaGRyID0gc2EuaGVhZGVycy5nZXRoZWFkZXIoa2V5KQotICAgICAgICAgICAgICAgIHNlbGYuZW52W2tleV0gPSBoZHIKLSAgICAgICAgICAgICAgICAKLSAgICAgICAgI2FjY2VwdCA9IFtdCi0gICAgICAgICNmb3IgbGluZSBpbiBzYS5oZWFkZXJzLmdldGFsbG1hdGNoaW5naGVhZGVycygnYWNjZXB0Jyk6Ci0gICAgICAgICMgICAgaWYgbGluZVs6MV0gaW4gc3RyaW5nLndoaXRlc3BhY2U6Ci0gICAgICAgICMgICAgICAgIGFjY2VwdC5hcHBlbmQobGluZS5zdHJpcCgpKQotICAgICAgICAjICAgIGVsc2U6Ci0gICAgICAgICMgICAgICAgIGFjY2VwdCA9IGFjY2VwdCArIGxpbmVbNzpdLnNwbGl0KCcsJykKLSAgICAgICAgIwotICAgICAgICAjZW52WydIVFRQX0FDQ0VQVCddID0gJywnLmpvaW4oYWNjZXB0KQotCi0gICAgICAgIGNvID0gZmlsdGVyKE5vbmUsIHNhLmhlYWRlcnMuZ2V0aGVhZGVycygnY29va2llJykpCi0KLSAgICAgICAgc2VsZi5odHRwX2FjY2VwdF9sYW5ndWFnZSA9IHNhLmhlYWRlcnMuZ2V0aGVhZGVyKCdBY2NlcHQtTGFuZ3VhZ2UnKQotICAgICAgICBzZWxmLnNlcnZlcl9uYW1lID0gc2Euc2VydmVyLnNlcnZlcl9uYW1lCi0gICAgICAgIHNlbGYuc2VydmVyX3BvcnQgPSBzdHIoc2Euc2VydmVyLnNlcnZlcl9wb3J0KQotICAgICAgICBzZWxmLmh0dHBfaG9zdCA9IHNhLmhlYWRlcnMuZ2V0aGVhZGVyKCdob3N0JykKLSAgICAgICAgc2VsZi5odHRwX3JlZmVyZXIgPSBzYS5oZWFkZXJzLmdldGhlYWRlcigncmVmZXJlcicpCi0gICAgICAgIHNlbGYuc2F2ZWRfY29va2llID0gJywgJy5qb2luKGNvKSBvciAnJwotICAgICAgICBzZWxmLnNjcmlwdF9uYW1lID0gJycKLSAgICAgICAgc2VsZi5wYXRoX2luZm8gPSB1cXJlc3QgCi0gICAgICAgIHNlbGYucXVlcnlfc3RyaW5nID0gcXVlcnkgb3IgJycKLSAgICAgICAgc2VsZi5yZXF1ZXN0X21ldGhvZCA9IHNhLmNvbW1hbmQKLSAgICAgICAgc2VsZi5yZW1vdGVfYWRkciA9IHNhLmNsaWVudF9hZGRyZXNzWzBdCi0gICAgICAgIHNlbGYuaHR0cF91c2VyX2FnZW50ID0gc2EuaGVhZGVycy5nZXRoZWFkZXIoJ3VzZXItYWdlbnQnKSBvciAnJwotICAgICAgICAjIGZyb20gc3RhbmRhbG9uZSBzY3JpcHQ6Ci0gICAgICAgICMgWFhYIEFVVEhfVFlQRQotICAgICAgICAjIFhYWCBSRU1PVEVfVVNFUgotICAgICAgICAjIFhYWCBSRU1PVEVfSURFTlQKLSAgICAgICAgc2VsZi5hdXRoX3VzZXJuYW1lID0gTm9uZQotICAgICAgICAjZW52WydQQVRIX1RSQU5TTEFURUQnXSA9IHVxcmVzdCAjc2VsZi50cmFuc2xhdGVfcGF0aCh1cXJlc3QpCi0gICAgICAgICNob3N0ID0gc2VsZi5hZGRyZXNzX3N0cmluZygpCi0gICAgICAgICNpZiBob3N0ICE9IHNlbGYuY2xpZW50X2FkZHJlc3NbMF06Ci0gICAgICAgICMgICAgZW52WydSRU1PVEVfSE9TVCddID0gaG9zdAotICAgICAgICAjIGVudlsnU0VSVkVSX1BST1RPQ09MJ10gPSBzZWxmLnByb3RvY29sX3ZlcnNpb24KLSAgICAgICAgUmVxdWVzdEJhc2UuX19pbml0X18oc2VsZiwgcHJvcGVydGllcykKLQotICAgIGRlZiBvcGVuX2xvZ3Moc2VsZik6Ci0gICAgICAgICMgY3JlYXRlIGVycm9yIGxvZyBmaWxlIGZvciBjYXRjaGluZyBzdGRlcnIgb3V0cHV0Ci0gICAgICAgIGlmIG5vdCBzZWxmLm9wZW5lZF9sb2dzOgotICAgICAgICAgICAgc3lzLnN0ZGVyciA9IG9wZW4ob3MucGF0aC5qb2luKGNvbmZpZy5kYXRhX2RpciwgJ2Vycm9yLmxvZycpLCAnYXQnKQotICAgICAgICAgICAgc2VsZi5vcGVuZWRfbG9ncyA9IDEKLQotICAgIGRlZiBzZXR1cF9hcmdzKHNlbGYsIGZvcm09Tm9uZSk6Ci0gICAgICAgIHNlbGYuZW52WydSRVFVRVNUX01FVEhPRCddID0gc2VsZi5yZXF1ZXN0X21ldGhvZAotICAgICAgICBzZWxmLmVudlsnUVVFUllfU1RSSU5HJ10gPSBzZWxmLnF1ZXJ5X3N0cmluZwotICAgICAgICBjdCA9IHNlbGYuaGVhZGVycy5nZXRoZWFkZXIoJ2NvbnRlbnQtdHlwZScpCi0gICAgICAgIGlmIGN0OgotICAgICAgICAgICAgc2VsZi5lbnZbJ0NPTlRFTlRfVFlQRSddID0gY3QKLSAgICAgICAgY2wgPSBzZWxmLmhlYWRlcnMuZ2V0aGVhZGVyKCdjb250ZW50LWxlbmd0aCcpCi0gICAgICAgIGlmIGNsOgotICAgICAgICAgICAgc2VsZi5lbnZbJ0NPTlRFTlRfTEVOR1RIJ10gPSBjbAotICAgICAgICAKLSAgICAgICAgaW1wb3J0IGNnaQotICAgICAgICAjcHJpbnQgImVudiA9ICIsIHNlbGYuZW52Ci0gICAgICAgICNmb3JtID0gY2dpLkZpZWxkU3RvcmFnZShzZWxmLCBoZWFkZXJzPXNlbGYuZW52LCBlbnZpcm9uPXNlbGYuZW52KQotICAgICAgICBpZiBmb3JtIGlzIE5vbmU6Ci0gICAgICAgICAgICBmb3JtID0gY2dpLkZpZWxkU3RvcmFnZShzZWxmLCBlbnZpcm9uPXNlbGYuZW52KQotICAgICAgICByZXR1cm4gc2VsZi5fc2V0dXBfYXJnc19mcm9tX2NnaV9mb3JtKGZvcm0pCi0gICAgICAgIAotICAgIGRlZiByZWFkKHNlbGYsIG49Tm9uZSk6Ci0gICAgICAgICIiIiBSZWFkIGZyb20gaW5wdXQgc3RyZWFtLgotICAgICAgICAiIiIKLSAgICAgICAgaWYgbiBpcyBOb25lOgotICAgICAgICAgICAgcmV0dXJuIHNlbGYucmZpbGUucmVhZCgpCi0gICAgICAgIGVsc2U6Ci0gICAgICAgICAgICByZXR1cm4gc2VsZi5yZmlsZS5yZWFkKG4pCi0KLSAgICBkZWYgcmVhZGxpbmUgKHNlbGYpOgotICAgICAgICBMID0gIiIKLSAgICAgICAgd2hpbGUgMToKLSAgICAgICAgICAgIGMgPSBzZWxmLnJlYWQoMSkKLSAgICAgICAgICAgIEwgKz0gYwotICAgICAgICAgICAgaWYgYyA9PSAnXG4nOgotICAgICAgICAgICAgICAgIGJyZWFrCi0gICAgICAgIHJldHVybiBMCi0JICAgIAotICAgIGRlZiB3cml0ZShzZWxmLCAqZGF0YSk6Ci0gICAgICAgICIiIiBXcml0ZSB0byBvdXRwdXQgc3RyZWFtLgotICAgICAgICAiIiIKLSAgICAgICAgZm9yIHBpZWNlIGluIGRhdGE6Ci0gICAgICAgICAgICBzZWxmLndmaWxlLndyaXRlKHBpZWNlKQotCi0gICAgZGVmIGZsdXNoKHNlbGYpOgotICAgICAgICBzZWxmLndmaWxlLmZsdXNoKCkKLSAgICAgICAgCi0gICAgZGVmIGZpbmlzaChzZWxmKToKLSAgICAgICAgIyBmbHVzaCB0aGUgb3V0cHV0LCBpZ25vcmUgZXJyb3JzIGNhdXNlZCBieSB0aGUgdXNlciBjbG9zaW5nIHRoZSBzb2NrZXQKLSAgICAgICAgdHJ5OgotICAgICAgICAgICAgc2VsZi53ZmlsZS5mbHVzaCgpCi0gICAgICAgIGV4Y2VwdCBJT0Vycm9yLCBleDoKLSAgICAgICAgICAgIGltcG9ydCBlcnJubwotICAgICAgICAgICAgaWYgZXguZXJybm8gIT0gZXJybm8uRVBJUEU6IHJhaXNlCi0KLSAgICAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwotICAgICMjIyBBY2Nlc3NvcnMKLSAgICAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwotCi0gICAgZGVmIGdldFNjcmlwdG5hbWUoc2VsZik6Ci0gICAgICAgICIiIiBSZXR1cm4gdGhlIHNjcmlwdG5hbWUgcGFydCBvZiB0aGUgVVJMICgiL3BhdGgvdG8vbXkuY2dpIikuICIiIgotICAgICAgICBuYW1lID0gc2VsZi5zY3JpcHRfbmFtZQotICAgICAgICBpZiBuYW1lID09ICcvJzoKLSAgICAgICAgICAgIHJldHVybiAnJwotICAgICAgICByZXR1cm4gbmFtZQotCi0KLSAgICBkZWYgZ2V0UGF0aGluZm8oc2VsZik6Ci0gICAgICAgICIiIiBSZXR1cm4gdGhlIHJlbWFpbmluZyBwYXJ0IG9mIHRoZSBVUkwuICIiIgotICAgICAgICByZXR1cm4gc2VsZi5wYXRoX2luZm8KLQotCi0gICAgIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKLSAgICAjIyMgSGVhZGVycwotICAgICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCi0KLSAgICBkZWYgc2V0SHR0cEhlYWRlcihzZWxmLCBoZWFkZXIpOgotICAgICAgICBzZWxmLnVzZXJfaGVhZGVycy5hcHBlbmQoaGVhZGVyKQotCi0gICAgZGVmIGh0dHBfaGVhZGVycyhzZWxmLCBtb3JlX2hlYWRlcnM9W10pOgotICAgICAgICBpZiBzZWxmLnNlbnRfaGVhZGVyczoKLSAgICAgICAgICAgICNzZWxmLndyaXRlKCJIZWFkZXJzIGFscmVhZHkgc2VudCEhIVxuIikKLSAgICAgICAgICAgIHJldHVybgotICAgICAgICBzZWxmLnNlbnRfaGVhZGVycyA9IDEKLSAgICAgICAgaGF2ZV9jdCA9IDAKLQotICAgICAgICAjIHNlbmQgaHR0cCBoZWFkZXJzCi0gICAgICAgIGZvciBoZWFkZXIgaW4gbW9yZV9oZWFkZXJzICsgc2VsZi51c2VyX2hlYWRlcnM6Ci0gICAgICAgICAgICBpZiBoZWFkZXIubG93ZXIoKS5zdGFydHN3aXRoKCJjb250ZW50LXR5cGU6Iik6Ci0gICAgICAgICAgICAgICAgIyBkb24ndCBzZW5kIGNvbnRlbnQtdHlwZSBtdWx0aXBsZSB0aW1lcyEKLSAgICAgICAgICAgICAgICBpZiBoYXZlX2N0OiBjb250aW51ZQotICAgICAgICAgICAgICAgIGhhdmVfY3QgPSAxCi0gICAgICAgICAgICBzZWxmLndyaXRlKCIlc1xyXG4iICUgaGVhZGVyKQotCi0gICAgICAgIGlmIG5vdCBoYXZlX2N0OgotICAgICAgICAgICAgc2VsZi53cml0ZSgiQ29udGVudC10eXBlOiB0ZXh0L2h0bWw7Y2hhcnNldD0lc1xyXG4iICUgY29uZmlnLmNoYXJzZXQpCi0KLSAgICAgICAgc2VsZi53cml0ZSgnXHJcbicpCi0KLSAgICAgICAgI2Zyb20gcHByaW50IGltcG9ydCBwZm9ybWF0Ci0gICAgICAgICNzeXMuc3RkZXJyLndyaXRlKHBmb3JtYXQobW9yZV9oZWFkZXJzKSkKLSAgICAgICAgI3N5cy5zdGRlcnIud3JpdGUocGZvcm1hdChzZWxmLnVzZXJfaGVhZGVycykpCi0KLQotIyBtb2RfcHl0aG9uL0FwYWNoZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi1jbGFzcyBSZXF1ZXN0TW9kUHkoUmVxdWVzdEJhc2UpOgotICAgICIiIiBzcGVjaWFsaXplZCBvbiBtb2RfcHl0aG9uIHJlcXVlc3RzICIiIgotCi0gICAgZGVmIF9faW5pdF9fKHNlbGYsIHJlcSk6Ci0gICAgICAgICIiIiBTYXZlcyBtb2RfcHl0aG9ucyByZXF1ZXN0IGFuZCBzZXRzIGJhc2ljIHZhcmlhYmxlcyB1c2luZwotICAgICAgICAgICAgdGhlIHJlcS5zdWJwcm9jZXNzX2VudiwgY2F1c2UgdGhpcyBwcm92aWRlcyBhIHN0YW5kYXJkCi0gICAgICAgICAgICB3YXkgdG8gYWNjZXNzIHRoZSB2YWx1ZXMgd2UgbmVlZCBoZXJlLgotCi0gICAgICAgICAgICBAcGFyYW0gcmVxOiB0aGUgbW9kX3B5dGhvbiByZXF1ZXN0IGluc3RhbmNlCi0gICAgICAgICIiIgotICAgICAgICByZXEuYWRkX2NvbW1vbl92YXJzKCkKLSAgICAgICAgc2VsZi5tcHlyZXEgPSByZXEKLSAgICAgICAgIyBzb21lIG1vZF9weXRob24gMi43LlggaGFzIG5vIGdldCBtZXRob2QgZm9yIHRhYmxlIG9iamVjdHMsCi0gICAgICAgICMgc28gd2UgbWFrZSBhIHJlYWwgZGljdCBvdXQgb2YgaXQgZmlyc3QuCi0gICAgICAgIGlmIG5vdCBoYXNhdHRyKHJlcS5zdWJwcm9jZXNzX2VudiwnZ2V0Jyk6Ci0gICAgICAgICAgICBlbnY9ZGljdChyZXEuc3VicHJvY2Vzc19lbnYpCi0gICAgICAgIGVsc2U6Ci0gICAgICAgICAgICBlbnY9cmVxLnN1YnByb2Nlc3NfZW52Ci0gICAgICAgIHNlbGYuX3NldHVwX3ZhcnNfZnJvbV9zdGRfZW52KGVudikKLSAgICAgICAgIyBmbGFncyBpZiBoZWFkZXJzIHNlbnQgb3V0IGNvbnRhaW5lZCBjb250ZW50LXR5cGUgb3Igc3RhdHVzCi0gICAgICAgIHNlbGYuX2hhdmVfY3QgPSAwCi0gICAgICAgIHNlbGYuX2hhdmVfc3RhdHVzID0gMAotICAgICAgICBSZXF1ZXN0QmFzZS5fX2luaXRfXyhzZWxmKQotICAgICAgICAKLSAgICAgICAgCi0gICAgZGVmIHNldHVwX2FyZ3Moc2VsZiwgZm9ybT1Ob25lKToKLSAgICAgICAgIiIiIFNldHMgdXAgYXJncyBieSB1c2luZyBtb2RfcHl0aG9uLnV0aWwuRmllbGRTdG9yYWdlLCB3aGljaAotICAgICAgICAgICAgaXMgZGlmZmVyZW50IHRvIGNnaS5GaWVsZFN0b3JhZ2UuIFNvIHdlIG5lZWQgYSBzZXBlcmF0ZQotICAgICAgICAgICAgbWV0aG9kIGZvciB0aGlzLgotICAgICAgICAiIiIKLSAgICAgICAgaW1wb3J0IHR5cGVzCi0gICAgICAgIGZyb20gbW9kX3B5dGhvbiBpbXBvcnQgdXRpbAotICAgICAgICBpZiBmb3JtIGlzIE5vbmU6Ci0gICAgICAgICAgICBmb3JtID0gdXRpbC5GaWVsZFN0b3JhZ2Uoc2VsZi5tcHlyZXEpCi0KLSAgICAgICAgYXJncyA9IHt9Ci0gICAgICAgIGZvciBrZXkgaW4gZm9ybS5rZXlzKCk6Ci0gICAgICAgICAgICB2YWx1ZXMgPSBmb3JtW2tleV0KLSAgICAgICAgICAgIGlmIG5vdCBpc2luc3RhbmNlKHZhbHVlcywgdHlwZXMuTGlzdFR5cGUpOgotICAgICAgICAgICAgICAgIHZhbHVlcyA9IFt2YWx1ZXNdCi0gICAgICAgICAgICBmaXhlZFJlc3VsdCA9IFtdCi0gICAgICAgICAgICBmb3IgaSBpbiB2YWx1ZXM6Ci0gICAgICAgICAgICAgICAgIyMgbW9kX3B5dGhvbiAyLjcgbWlnaHQgcmV0dXJuIHN0cmluZ3MgaW5zdGVhZAotICAgICAgICAgICAgICAgICMjIG9mIEZpZWxkIG9iamVjdHMKLSAgICAgICAgICAgICAgICBpZiBoYXNhdHRyKGksJ3ZhbHVlJyk6Ci0gICAgICAgICAgICAgICAgICAgIGZpeGVkUmVzdWx0LmFwcGVuZChpLnZhbHVlKQotICAgICAgICAgICAgICAgIGVsc2U6Ci0gICAgICAgICAgICAgICAgICAgIGZpeGVkUmVzdWx0LmFwcGVuZChpKQotICAgICAgICAgICAgICAgICMjIGlmIG9iamVjdCBoYXMgYSBmaWxlbmFtZSBhdHRyaWJ1dGUsIHJlbWVtYmVyIGl0Ci0gICAgICAgICAgICAgICAgIyMgd2l0aCBhIG5hbWUgaGFjawotICAgICAgICAgICAgICAgIGlmIGhhc2F0dHIoaSwnZmlsZW5hbWUnKSBhbmQgaS5maWxlbmFtZToKLSAgICAgICAgICAgICAgICAgICAgYXJnc1trZXkrJ19fZmlsZW5hbWVfXyddPWkuZmlsZW5hbWUKLSAgICAgICAgICAgIGFyZ3Nba2V5XSA9IGZpeGVkUmVzdWx0Ci0gICAgICAgIHJldHVybiBhcmdzCi0KLSAgICBkZWYgcnVuKHNlbGYsIHJlcSk6Ci0gICAgICAgICIiIiBtb2RfcHl0aG9uIGNhbGxzIHRoaXMgd2l0aCBpdHMgcmVxdWVzdCBvYmplY3QuIFdlIGRvbid0Ci0gICAgICAgICAgICBuZWVkIGl0IGNhdXNlIGl0cyBhbHJlYWR5IHBhc3NlZCB0byBfX2luaXRfXy4gU28gaWdub3JlCi0gICAgICAgICAgICBpdCBhbmQganVzdCByZXR1cm4gUmVxdWVzdEJhc2UucnVuLgotCi0gICAgICAgICAgICBAcGFyYW0gcmVxOiB0aGUgbW9kX3B5dGhvbiByZXF1ZXN0IGluc3RhbmNlCi0gICAgICAgICIiIgotICAgICAgICByZXR1cm4gUmVxdWVzdEJhc2UucnVuKHNlbGYpCi0KLSAgICBkZWYgcmVhZChzZWxmLCBuPU5vbmUpOgotICAgICAgICAiIiIgUmVhZCBmcm9tIGlucHV0IHN0cmVhbS4KLSAgICAgICAgIiIiCi0gICAgICAgIGlmIG4gaXMgTm9uZToKLSAgICAgICAgICAgIHJldHVybiBzZWxmLm1weXJlcS5yZWFkKCkKLSAgICAgICAgZWxzZToKLSAgICAgICAgICAgIHJldHVybiBzZWxmLm1weXJlcS5yZWFkKG4pCi0KLSAgICBkZWYgd3JpdGUoc2VsZiwgKmRhdGEpOgotICAgICAgICAiIiIgV3JpdGUgdG8gb3V0cHV0IHN0cmVhbS4KLSAgICAgICAgIiIiCi0gICAgICAgIGZvciBwaWVjZSBpbiBkYXRhOgotICAgICAgICAgICAgc2VsZi5tcHlyZXEud3JpdGUocGllY2UpCi0KLSAgICBkZWYgZmx1c2goc2VsZik6Ci0gICAgICAgICIiIiBXZSBjYW4ndCBmbHVzaCBpdCwgc28gZG8gbm90aGluZy4KLSAgICAgICAgIiIiCi0gICAgICAgIHBhc3MKLSAgICAgICAgCi0gICAgZGVmIGZpbmlzaChzZWxmKToKLSAgICAgICAgIiIiIEp1c3QgcmV0dXJuIGFwYWNoZS5PSy4gU3RhdHVzIGlzIHNldCBpbiByZXEuc3RhdHVzLgotICAgICAgICAiIiIKLSAgICAgICAgIyBpcyBpdCBwb3NzaWJsZSB0aGF0IHdlIG5lZWQgdG8gcmV0dXJuIHNvbWV0aGlnIGVsc2UgaGVyZT8KLSAgICAgICAgZnJvbSBtb2RfcHl0aG9uIGltcG9ydCBhcGFjaGUKLSAgICAgICAgcmV0dXJuIGFwYWNoZS5PSwotICAgICAgICAKLSAgICAKLSAgICAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwotICAgICMjIyBBY2Nlc3NvcnMKLSAgICAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwotCi0gICAgZGVmIGdldFNjcmlwdG5hbWUoc2VsZik6Ci0gICAgICAgICIiIiBSZXR1cm4gdGhlIHNjcmlwdG5hbWUgcGFydCBvZiB0aGUgVVJMICgnL3BhdGgvdG8vbXkuY2dpJykuICIiIgotICAgICAgICBuYW1lID0gc2VsZi5zY3JpcHRfbmFtZQotICAgICAgICBpZiBuYW1lID09ICcvJzoKLSAgICAgICAgICAgIHJldHVybiAnJwotICAgICAgICByZXR1cm4gbmFtZQotCi0KLSAgICBkZWYgZ2V0UGF0aGluZm8oc2VsZik6Ci0gICAgICAgICIiIiBSZXR1cm4gdGhlIHJlbWFpbmluZyBwYXJ0IG9mIHRoZSBVUkwuICIiIgotICAgICAgICByZXR1cm4gc2VsZi5wYXRoX2luZm8KLQotICAgICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCi0gICAgIyMjIEhlYWRlcnMKLSAgICAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwotCi0gICAgZGVmIHNldEh0dHBIZWFkZXIoc2VsZiwgaGVhZGVyKToKLSAgICAgICAgIiIiIEZpbHRlcnMgb3V0IGNvbnRlbnQtdHlwZSBhbmQgc3RhdHVzIHRvIHNldCB0aGVtIGRpcmVjdGx5Ci0gICAgICAgICAgICBpbiB0aGUgbW9kX3B5dGhvbiByZXF1ZXN0LiBSZXN0IGlzIHB1dCBpbnRvIHRoZSBoZWFkZXJzX291dAotICAgICAgICAgICAgbWVtYmVyIG9mIHRoZSBtb2RfcHl0aG9uIHJlcXVlc3QuCi0KLSAgICAgICAgICAgIEBwYXJhbSBoZWFkZXI6IHN0cmluZywgY29udGFpbmluZyB2YWxpZCBIVFRQIGhlYWRlci4KLSAgICAgICAgIiIiCi0gICAgICAgIGtleSwgdmFsdWUgPSBoZWFkZXIuc3BsaXQoJzonLDEpCi0gICAgICAgIHZhbHVlID0gdmFsdWUubHN0cmlwKCkKLSAgICAgICAgaWYga2V5Lmxvd2VyKCkgPT0gJ2NvbnRlbnQtdHlwZSc6Ci0gICAgICAgICAgICAjIHNhdmUgY29udGVudC10eXBlIGZvciBodHRwX2hlYWRlcnMKLSAgICAgICAgICAgIGlmIG5vdCBzZWxmLl9oYXZlX2N0OgotICAgICAgICAgICAgICAgICMgd2Ugb25seSB1c2UgdGhlIGZpcnN0IGNvbnRlbnQtdHlwZSEKLSAgICAgICAgICAgICAgICBzZWxmLm1weXJlcS5jb250ZW50X3R5cGUgPSB2YWx1ZQotICAgICAgICAgICAgICAgIHNlbGYuX2hhdmVfY3QgPSAxCi0gICAgICAgIGVsaWYga2V5Lmxvd2VyKCkgPT0gJ3N0YXR1cyc6Ci0gICAgICAgICAgICAjIHNhdmUgc3RhdHVzIGZvciBmaW5pc2gKLSAgICAgICAgICAgIHRyeToKLSAgICAgICAgICAgICAgICBzZWxmLm1weXJlcS5zdGF0dXMgPSBpbnQodmFsdWUuc3BsaXQoJyAnLDEpWzBdKQotICAgICAgICAgICAgZXhjZXB0OgotICAgICAgICAgICAgICAgIHBhc3MKLSAgICAgICAgICAgIGVsc2U6Ci0gICAgICAgICAgICAgICAgc2VsZi5faGF2ZV9zdGF0dXMgPSAxCi0gICAgICAgIGVsc2U6Ci0gICAgICAgICAgICAjIHRoaXMgaXMgYSBoZWFkZXIgd2Ugc2VudCBvdXQKLSAgICAgICAgICAgIHNlbGYubXB5cmVxLmhlYWRlcnNfb3V0W2tleV09dmFsdWUKLQotCi0gICAgZGVmIGh0dHBfaGVhZGVycyhzZWxmLCBtb3JlX2hlYWRlcnM9W10pOgotICAgICAgICAiIiIgU2VuZHMgb3V0IGhlYWRlcnMgYW5kIHBvc3NpYmx5IHNldHMgZGVmYXVsdCBjb250ZW50LXR5cGUKLSAgICAgICAgICAgIGFuZCBzdGF0dXMuCi0KLSAgICAgICAgICAgIEBrZXl3b3JkIG1vcmVfaGVhZGVyczogbGlzdCBvZiBzdHJpbmdzLCBkZWZhdWx0cyB0byBbXQotICAgICAgICAiIiIKLSAgICAgICAgZm9yIGhlYWRlciBpbiBtb3JlX2hlYWRlcnM6Ci0gICAgICAgICAgICBzZWxmLnNldEh0dHBIZWFkZXIoaGVhZGVyKQotICAgICAgICAjIGlmIHdlIGRvbid0IGhhZCBhbiBjb250ZW50LXR5cGUgaGVhZGVyLCBzZXQgdGV4dC9odG1sCi0gICAgICAgIGlmIHNlbGYuX2hhdmVfY3QgPT0gMDoKLSAgICAgICAgICAgIHNlbGYubXB5cmVxLmNvbnRlbnRfdHlwZSA9ICJ0ZXh0L2h0bWw7Y2hhcnNldD0lcyIgJSBjb25maWcuY2hhcnNldAotICAgICAgICAjIGlmIHdlIGRvbid0IGhhZCBhIHN0YXR1cyBoZWFkZXIsIHNldCAyMDAKLSAgICAgICAgaWYgc2VsZi5faGF2ZV9zdGF0dXMgPT0gMDoKLSAgICAgICAgICAgIHNlbGYubXB5cmVxLnN0YXR1cyA9IDIwMAotICAgICAgICAjIHRoaXMgaXMgZm9yIG1vZF9weXRob24gMi43LlgsIGZvciAzLlggaXQncyBhIE5PUAotICAgICAgICBzZWxmLm1weXJlcS5zZW5kX2h0dHBfaGVhZGVyKCkKLQotIyBGYXN0Q0dJIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0KLWNsYXNzIFJlcXVlc3RGYXN0Q0dJKFJlcXVlc3RCYXNlKToKLSAgICAiIiIgc3BlY2lhbGl6ZWQgb24gRmFzdENHSSByZXF1ZXN0cyAiIiIKLQotICAgIGRlZiBfX2luaXRfXyhzZWxmLCBmY2dSZXF1ZXN0LCBlbnYsIGZvcm0sIHByb3BlcnRpZXM9e30pOgotICAgICAgICAiIiIgSW5pdGlhbGl6ZXMgdmFyaWFibGVzIGZyb20gRmFzdENHSSBlbnZpcm9ubWVudCBhbmQgc2F2ZXMKLSAgICAgICAgICAgIEZhc3RDR0kgcmVxdWVzdCBhbmQgZm9ybSBmb3IgZnVydGhlciB1c2UuCi0KLSAgICAgICAgICAgIEBwYXJhbSBmY2dSZXF1ZXN0OiB0aGUgRmFzdENHSSByZXF1ZXN0IGluc3RhbmNlLgotICAgICAgICAgICAgQHBhcmFtIGVudjogZW52aXJvbm1lbnQgcGFzc2VkIGJ5IEZhc3RDR0kuCi0gICAgICAgICAgICBAcGFyYW0gZm9ybTogRmllbGRTdG9yYWdlIHBhc3NlZCBieSBGYXN0Q0dJLgotICAgICAgICAiIiIKLSAgICAgICAgc2VsZi5mY2dyZXEgPSBmY2dSZXF1ZXN0Ci0gICAgICAgIHNlbGYuZmNnZW52ID0gZW52Ci0gICAgICAgIHNlbGYuZmNnZm9ybSA9IGZvcm0KLSAgICAgICAgc2VsZi5fc2V0dXBfdmFyc19mcm9tX3N0ZF9lbnYoZW52KQotICAgICAgICBSZXF1ZXN0QmFzZS5fX2luaXRfXyhzZWxmLCBwcm9wZXJ0aWVzKQotCi0gICAgZGVmIHNldHVwX2FyZ3Moc2VsZiwgZm9ybT1Ob25lKToKLSAgICAgICAgIiIiIFVzZSB0aGUgRmFzdENHSSBmb3JtIHRvIHNldHVwIGFyZ3VtZW50cy4gIiIiCi0gICAgICAgIGlmIGZvcm0gaXMgTm9uZToKLSAgICAgICAgICAgIGZvcm0gPSBzZWxmLmZjZ2Zvcm0KLSAgICAgICAgcmV0dXJuIHNlbGYuX3NldHVwX2FyZ3NfZnJvbV9jZ2lfZm9ybShmb3JtKQotCi0gICAgZGVmIHJlYWQoc2VsZiwgbj1Ob25lKToKLSAgICAgICAgIiIiIFJlYWQgZnJvbSBpbnB1dCBzdHJlYW0uCi0gICAgICAgICIiIgotICAgICAgICBpZiBuIGlzIE5vbmU6Ci0gICAgICAgICAgICByZXR1cm4gc2VsZi5mY2dyZXEuc3RkaW4ucmVhZCgpCi0gICAgICAgIGVsc2U6Ci0gICAgICAgICAgICByZXR1cm4gc2VsZi5mY2dyZXEuc3RkaW4ucmVhZChuKQotCi0gICAgZGVmIHdyaXRlKHNlbGYsICpkYXRhKToKLSAgICAgICAgIiIiIFdyaXRlIHRvIG91dHB1dCBzdHJlYW0uCi0gICAgICAgICIiIgotICAgICAgICBzZWxmLmZjZ3JlcS5vdXQud3JpdGUoIiIuam9pbihkYXRhKSkKLQotICAgIGRlZiBmbHVzaChzZWxmKToKLSAgICAgICAgIiIiIEZsdXNoIG91dHB1dCBzdHJlYW0uCi0gICAgICAgICIiIgotICAgICAgICBzZWxmLmZjZ3JlcS5mbHVzaF9vdXQoKQotCi0gICAgZGVmIGZpbmlzaChzZWxmKToKLSAgICAgICAgIiIiIENhbGwgZmluaXNoIG1ldGhvZCBvZiBGYXN0Q0dJIHJlcXVlc3QgdG8gZmluaXNoIGhhbmRsaW5nCi0gICAgICAgICAgICBvZiB0aGlzIHJlcXVlc3QuCi0gICAgICAgICIiIgotICAgICAgICBzZWxmLmZjZ3JlcS5maW5pc2goKQotCi0KLSAgICAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwotICAgICMjIyBBY2Nlc3NvcnMKLSAgICAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwotCi0gICAgZGVmIGdldFNjcmlwdG5hbWUoc2VsZik6Ci0gICAgICAgICIiIiBSZXR1cm4gdGhlIHNjcmlwdG5hbWUgcGFydCBvZiB0aGUgVVJMICgnL3BhdGgvdG8vbXkuY2dpJykuICIiIgotICAgICAgICBuYW1lID0gc2VsZi5zY3JpcHRfbmFtZQotICAgICAgICBpZiBuYW1lID09ICcvJzoKLSAgICAgICAgICAgIHJldHVybiAnJwotICAgICAgICByZXR1cm4gbmFtZQotCi0KLSAgICBkZWYgZ2V0UGF0aGluZm8oc2VsZik6Ci0gICAgICAgICIiIiBSZXR1cm4gdGhlIHJlbWFpbmluZyBwYXJ0IG9mIHRoZSBVUkwuICIiIgotICAgICAgICBwYXRoaW5mbyA9IHNlbGYucGF0aF9pbmZvCi0KLSAgICAgICAgIyBGaXggZm9yIGJ1ZyBpbiBJSVMvNC4wCi0gICAgICAgIGlmIG9zLm5hbWUgPT0gJ250JzoKLSAgICAgICAgICAgIHNjcmlwdG5hbWUgPSBzZWxmLmdldFNjcmlwdG5hbWUoKQotICAgICAgICAgICAgaWYgcGF0aGluZm8uc3RhcnRzd2l0aChzY3JpcHRuYW1lKToKLSAgICAgICAgICAgICAgICBwYXRoaW5mbyA9IHBhdGhpbmZvW2xlbihzY3JpcHRuYW1lKTpdCi0KLSAgICAgICAgcmV0dXJuIHBhdGhpbmZvCi0KLQotICAgICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCi0gICAgIyMjIEhlYWRlcnMKLSAgICAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwotCi0gICAgZGVmIHNldEh0dHBIZWFkZXIoc2VsZiwgaGVhZGVyKToKLSAgICAgICAgIiIiIFNhdmUgaGVhZGVyIGZvciBsYXRlciBzZW5kLiAiIiIKLSAgICAgICAgc2VsZi51c2VyX2hlYWRlcnMuYXBwZW5kKGhlYWRlcikKLQotCi0gICAgZGVmIGh0dHBfaGVhZGVycyhzZWxmLCBtb3JlX2hlYWRlcnM9W10pOgotICAgICAgICAiIiIgU2VuZCBvdXQgSFRUUCBoZWFkZXJzLiBQb3NzaWJseSBzZXQgYSBkZWZhdWx0IGNvbnRlbnQtdHlwZS4KLSAgICAgICAgIiIiCi0gICAgICAgIGlmIHNlbGYuc2VudF9oZWFkZXJzOgotICAgICAgICAgICAgI3NlbGYud3JpdGUoIkhlYWRlcnMgYWxyZWFkeSBzZW50ISEhXG4iKQotICAgICAgICAgICAgcmV0dXJuCi0gICAgICAgIHNlbGYuc2VudF9oZWFkZXJzID0gMQotICAgICAgICBoYXZlX2N0ID0gMAotCi0gICAgICAgICMgc2VuZCBodHRwIGhlYWRlcnMKLSAgICAgICAgZm9yIGhlYWRlciBpbiBtb3JlX2hlYWRlcnMgKyBzZWxmLnVzZXJfaGVhZGVyczoKLSAgICAgICAgICAgIGlmIGhlYWRlci5sb3dlcigpLnN0YXJ0c3dpdGgoImNvbnRlbnQtdHlwZToiKToKLSAgICAgICAgICAgICAgICAjIGRvbid0IHNlbmQgY29udGVudC10eXBlIG11bHRpcGxlIHRpbWVzIQotICAgICAgICAgICAgICAgIGlmIGhhdmVfY3Q6IGNvbnRpbnVlCi0gICAgICAgICAgICAgICAgaGF2ZV9jdCA9IDEKLSAgICAgICAgICAgIHNlbGYud3JpdGUoIiVzXHJcbiIgJSBoZWFkZXIpCi0KLSAgICAgICAgaWYgbm90IGhhdmVfY3Q6Ci0gICAgICAgICAgICBzZWxmLndyaXRlKCJDb250ZW50LXR5cGU6IHRleHQvaHRtbDtjaGFyc2V0PSVzXHJcbiIgJSBjb25maWcuY2hhcnNldCkKLQotICAgICAgICBzZWxmLndyaXRlKCdcclxuJykKLQotICAgICAgICAjZnJvbSBwcHJpbnQgaW1wb3J0IHBmb3JtYXQKLSAgICAgICAgI3N5cy5zdGRlcnIud3JpdGUocGZvcm1hdChtb3JlX2hlYWRlcnMpKQotICAgICAgICAjc3lzLnN0ZGVyci53cml0ZShwZm9ybWF0KHNlbGYudXNlcl9oZWFkZXJzKSkKLQotcGFja2FnZSB0ZXN0MDU3NzsKLQotcHVibGljIGNsYXNzIFggewotCi0JcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nW10gYXJncykgewotCQkKLQl9Ci19Ci0K