ZGlmZiAtLWdpdCBhL29iai90b29scy9NR3Rvb2wuYyBiL29iai90b29scy9NR3Rvb2wuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43MjdmMzRmCi0tLSAvZGV2L251bGwKKysrIGIvb2JqL3Rvb2xzL01HdG9vbC5jCkBAIC0wLDAgKzEsMTgyMyBAQAorLyoKKyAqICBNR3Rvb2wtMS4zCisgKiAgRmlsZTogTUd0b29sLmMKKyAqICBNYWludGFpbmVyOiBLaXJrQE1vcmdlbkdyYXVlbgorICovCisKKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKy8qIHRoZSBvcmlnaW5hbCBYdG9vbCBpcyBjb3B5cmlnaHRlZCBieSBIeXAgKi8KKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKworI3ByYWdtYSBzdHJpY3RfdHlwZXMKKworaW5oZXJpdCAiL3N0ZC90aGluZy9wcm9wZXJ0aWVzIjsKKworI2luY2x1ZGUgPHByb3BlcnRpZXMuaD4KKyNpZiAhZGVmaW5lZChRVUVSWUNBQ0hFRCkKKyNkZWZpbmUgUVVFUllDQUNIRUQgNDA5NgorI2VuZGlmCisjaWYgIWRlZmluZWQgKFNFVENBQ0hFRCkKKyNkZWZpbmUgU0VUQ0FDSEVEIDQwOTYKKyNlbmRpZgorI2luY2x1ZGUgPG1vdmluZy5oPgorI2luY2x1ZGUgIi9zZWN1cmUvd2l6bGV2ZWxzLmgiCisjaW5jbHVkZSAiL3NlY3VyZS9jb25maWcuaCIKKyNpbmNsdWRlIDx1c2VyaW5mby5oPgorI2luY2x1ZGUgPGRlZmluZXMuaD4KKworI2luY2x1ZGUgIk1HdG9vbC90b29sLmgiCisKKyNpbmNsdWRlICJNR3Rvb2wvdG9vbGxpYi5oIgorCisjZGVmaW5lIFhEQkcgMQorCitub3NhdmUgb2JqZWN0ICBjbG9uZXI7Citub3NhdmUgb2JqZWN0ICBtc2d0bz1OVUxMOworbm9zYXZlIHN0cmluZyAqbWFucGF0aD0oe1RPT0xfUEFUSCsiL21hbi5kLyIsCisJCQkgIi9kb2MvZWZ1bi8iLAorCQkJICIvZG9jL2xmdW4vIiwKKwkJCSAiL2RvYy93LyIsCisJCQkgIi9kb2MvaGVscGRpci8iLAorCQkJICIvZG9jL0xQQy8iLAorCQkJICIvZG9jL3N0ZC8iLAorCQkJICIvZG9jL2NvbmNlcHRzLyIsCisJCQkgIiJ9KTsKK25vc2F2ZSBzdHJpbmcgIG1vcmVmaWxlPU5VTEw7Citub3NhdmUgc3RyaW5nICpzY3JpcHRsaW5lPU5VTEw7Citub3NhdmUgc3RyaW5nICpoaXN0b3J5PWFsbG9jYXRlKE1BWF9ISVNUT1JZKTsKK25vc2F2ZSBpbnQgICAgIG1vcmVmbGFnPUZBTFNFOworbm9zYXZlIGludCAgICAgbW9yZW9mZnNldD0xOworbm9zYXZlIGludCAgICAgdGVybT1OVUxMOworbm9zYXZlIGludCAgICAgc2NyaXB0c2l6ZT1OVUxMOworbm9zYXZlIGludCAgICAgbm9zdG9yZT1GQUxTRTsKK25vc2F2ZSBpbnQgICAgIHhsaWdodD0wOworbm9zYXZlIGludCAgICAgcGlwZV9pbj1GQUxTRTsKK25vc2F2ZSBpbnQgICAgIHBpcGVfb3V0PUZBTFNFOworbm9zYXZlIGludCAgICAgcGlwZV9vdnI9VFJVRTsKK25vc2F2ZSBzdHJpbmcgIHBpcGVfaWY9TlVMTDsKK25vc2F2ZSBzdHJpbmcgIHBpcGVfb2Y9TlVMTDsKK25vc2F2ZSBpbnQgICAgIHh0az1GQUxTRTsKK25vc2F2ZSBtYXBwaW5nIHZhcmlhYmxlPShbXSk7Citub3NhdmUgc3RyaW5nICpjbWRzOworcHJpdmF0ZSBub3NhdmUgbWFwcGluZyBsaW5lX2J1ZmZlcj0oW10pOworcHJpdmF0ZSBub3NhdmUgc3RyaW5nIGxpbmVfYnVmZmVyX25hbWU9IiI7Citwcml2YXRlIG5vc2F2ZSBzdHJpbmcgbW9yZV9zZWFyY2hleHByPSIiOworaW50ICAgIG1vcmVsaW5lcz1NT1JFX0xJTkVTOworaW50ICAgIG1vZGk9KE1PREVfRklSU1R8TU9ERV9QUk9URUNUfE1PREVfU0hPUlQpOworCisjaW5jbHVkZSAiTUd0b29sL3Rvb2xsaWIuYyIKKyNpbmNsdWRlICJNR3Rvb2wvdG9vbGNtZC5jIgorCisjZGVmaW5lIFNhZmVSZXR1cm4oeCkgXAoreyBcCisgIGNtZHM9KHt9KTsgXAorICBwaXBlX2luPUZBTFNFOyBcCisgIHBpcGVfb2Y9TlVMTDsgXAorICBwaXBlX292cj1UUlVFOyBcCisgIHBpcGVfb3V0PUZBTFNFOyBcCisgIHBpcGVfb2Y9TlVMTDsgXAorICByZXR1cm4gKHgpOyBcCit9CisKKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICogY2hlY2sgc29tZSBzZWN1cml0eSBhc3BlY3RzCisgKi8KKworc3RhdGljIGludCBzZWN1cml0eSgpCit7CisgIG9iamVjdCBwcmV2OworIAorICBpZiggcHJvY2Vzc19jYWxsKCkgfHwgZ2V0dWlkKCkhPWdldHVpZChjbG9uZXIpICkgcmV0dXJuIEZBTFNFOyAvLyBSdW1hdGEKKworICBUSygiVUlEOiAiK2dldHVpZChNRSkrIiBjbG9uZXI6IitnZXR1aWQoY2xvbmVyKSk7CisvLyAgVEsoInByZXY6ICIrb2JqZWN0X25hbWUoUFJFVikrIiBtZToiK29iamVjdF9uYW1lKE1FKSk7CisgIGlmKHByZXY9UFJFVikKKyAgeworICAgIGlmKCFjbG9uZXIpCisgICAgICByZXR1cm4gVFJVRTsKKyAgICBpZihnZXR1aWQocHJldik9PVJPT1RJRHx8SVNfQVJDSChwcmV2KSkKKyAgICAgIHJldHVybiBUUlVFOworICAgIGlmKHByZXY9PU1FKQorICAgICAgcmV0dXJuIFRSVUU7CisgICAgcmV0dXJuIHNlY3VyZV9sZXZlbCgpPj1xdWVyeV93aXpfbGV2ZWwoY2xvbmVyKTsgLy8gUnVtYXRhCisgICAgLy9yZXR1cm4gZ2V0dWlkKHByZXYpPT1nZXR1aWQoKSYmZ2V0ZXVpZChwcmV2KT09Z2V0ZXVpZCgpJiZjbG9uZXI9PVJUUDsKKyAgfQorICBlbHNlCisgICAgcmV0dXJuIGNsb25lcj09TlVMTDsKK30KKworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgKiBvd24gd3JpdGUgZnVuY3Rpb24KKyAqLworCitzdGF0aWMgaW50IFdyaXRlKHN0cmluZyBzdHIpCit7CisgIGlmKCFzdHJpbmdwKHN0cikgfHwgc3RyPT0iIikKKyAgICByZXR1cm4gRkFMU0U7CisgIGlmKCFjbG9uZXIgJiYgb2JqZWN0cCh0aGlzX3BsYXllcigpKSkKKyAgICB3cml0ZShzdHIpOworICBlbHNlCisgICAgdGVsbF9vYmplY3QoY2xvbmVyLCBzdHIpOworICByZXR1cm4gVFJVRTsKK30KKworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgKiBvd24gY29tbWFuZCBmdW5jdGlvbgorICovCisKK3N0YXRpYyBpbnQgQ29tbWFuZChzdHJpbmcgc3RyKQoreworICBpbnQgaTsKKyAgVEsoIkNvbW1hbmQ6IHN0cjogIisoc3RyP3N0cjoiKE5VTEwpIikpOworICBub3N0b3JlKys7CisgIGlmKE1PREUoTU9ERV9FQ0hPKSkKKyAgICBXTE4oIkRvaW5nOiAiK3N0cik7CisgIGk9KGludCljbG9uZXItPmNvbW1hbmRfbWUoc3RyKTsKKyAgbm9zdG9yZS0tOworICByZXR1cm4gaTsKK30KKworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgKiBvYmplY3Qgc2VhcmNoaW5nCisgKi8KKworc3RhdGljIHZhcmFyZ3Mgb2JqZWN0IFhGaW5kT2JqKHN0cmluZyBzdHIsIGludCBzaWxlbnQpCit7CisgIG9iamVjdCBvYmosIGVudjsKKyAgc3RyaW5nICpzdHJzOworICBpbnQgaSwgcywgY250OworICAKKyAgaWYoIXN0cikKKyAgICByZXR1cm4gTlVMTDsKKyAgVEsoIlhGaW5kT2JqOiBzdHI6ICIrKHN0cj9zdHI6IihOVUxMKSIpKTsKKyAgZW52PUVOVihjbG9uZXIpOworICBzdHI9c3RyaW5nX3JlcGxhY2Uoc3RyLCAiXFwuIiwisDAxIik7CisgIHN0cj1zdHJpbmdfcmVwbGFjZShzdHIsICJcXF4iLCAisDAyIik7CisgIHN0cj1zdHJpbmdfcmVwbGFjZShzdHIsICJcXCQiLCAisDAzIik7CisgIHN0cj1zdHJpbmdfcmVwbGFjZShzdHIsICJcXFxcIiwgIlxcIik7CisgIGlmIChmaW5kX29iamVjdChzdHIpKSByZXR1cm4gZmluZF9vYmplY3Qoc3RyKTsKKyAgaWYgKGZpbGVfc2l6ZShzdHIpPjEpIHsKKyAgICAgY2FsbF9vdGhlcihzdHIsICI/Pz8iKTsKKyAgICAgcmV0dXJuIGZpbmRfb2JqZWN0KHN0cik7CisgIH0KKyAgcz1zaXplb2Yoc3Rycz1zdHJpcF9leHBsb2RlKHN0ciwgIi4iKSk7CisgIHdoaWxlKHMtLSkKKyAgeworICAgIGlmKHN0cnNbaV09PSJtInx8c3Ryc1tpXT09Im1lIikKKyAgICAgIHN0cnNbaV09Uk5BTUUoY2xvbmVyKTsKKyAgICBlbHNlIGlmKHN0cnNbaV09PSJoInx8c3Ryc1tpXT09ImhlcmUiKQorICAgICAgc3Ryc1tpXT1vYmplY3RfbmFtZShFTlYoY2xvbmVyKSk7CisgICAgaWYob2JqPUZpbmRPYmooc3Ryc1tpKytdLGVudiwoc2lsZW50PzE6MCkpKQorICAgICAgZW52PW9iajsKKyAgICBlbHNlCisgICAgICBicmVhazsKKyAgfQorICByZXR1cm4gb2JqOworfQorCitzdGF0aWMgdmFyYXJncyBvYmplY3QgRmluZE9iaihzdHJpbmcgc3RyLCBvYmplY3QgZW52LCBpbnQgc2lsZW50KQoreworICBvYmplY3Qgb2JqLCAqaW52OworICBzdHJpbmcgdG1wOworICBpbnQgbnVtLCBlOworICAKKyAgaWYgKCFzdHJpbmdwKHN0cikgfHwgIXNpemVvZihzdHIpIHx8ICFvYmplY3RwKGVudikpCisgICAgcmV0dXJuIE5VTEw7CisgIHN0cj1zdHJpbmdfcmVwbGFjZShzdHIsICKwMDEiLCAiLiIpOworICB3aGlsZShzdHJbZSsrXT09J14nKQorICAgIDsKKyAgc3RyPXN0clstLWUuLjwxXTsKKyAgc3RyPXN0cmluZ19yZXBsYWNlKHN0ciwgIrAwMiIsICJeIik7CisgIGlmKG9iaj1WYXJUb09iaihzdHIpKQorICAgIDsKKyAgZWxzZSBpZihzdHJbMF09PScDJykKKyAgICBzdHI9c3RyaW5nX3JlcGxhY2Uoc3RyLCAisDAzIiwgIiQiKTsKKyAgZWxzZSBpZihzc2NhbmYoc3RyLCAiJWQiLCBudW0pJiYoaW52PWFsbF9pbnZlbnRvcnkoZW52KSkpCisgIHsKKyAgICBpZihudW0+MCYmbnVtPD1zaXplb2YoaW52KSkKKyAgICAgIG9iaj1pbnZbbnVtLTFdOworICAgIGVsc2UKKyAgICB7CisgICAgICBXRExOKCJTcGVjaWZpZWQgb2JqZWN0IG51bWJlciBvdXQgb2YgcmFuZ2UgWzEtIitzaXplb2YoaW52KSsiXSIpOworICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICB9CisgIGlmKG9ianx8KG9iaj1wcmVzZW50KHN0ciwgZW52KSl8fAorICAgICAob2JqPWZpbmRfcGxheWVyKExPV0VSKHN0cikpKXx8CisgICAgIChvYmo9ZmluZF9saXZpbmcoc3RyKSl8fAorICAgICAob2JqPWZpbmRfb2JqZWN0KGxvbmdfcGF0aChzdHIpKSkpCisgIHsKKyAgICB3aGlsZShlLS0pCisgICAgeworICAgICAgaWYoIShvYmo9RU5WKG9iaikpKQorICAgICAgeworCVcoIlNwZWNpZmllZCBvYmplY3QgaGFzIG5vIGVudmlyb25tZW50IFsiKTsKKwl3aGlsZShlLS0pCisJICBXKCJeIik7CisJV0RMTihzdHIrIl0iKTsKKwlyZXR1cm4gTlVMTDsKKyAgICAgIH0KKyAgICB9CisgIH0KKyAgZWxzZQorICAgIGlmKCFzaWxlbnQpCisgICAgICBXRExOKCJTcGVjaWZpZWQgb2JqZWN0IGRvZXMgbm90IGV4aXN0IFsiK3N0cisiXSIpOworICByZXR1cm4gb2JqOworfQorCisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAqIG9iamVjdCB2YXJpYWJsZSBoYW5kbGluZworICovCisKK3N0YXRpYyBvYmplY3QgVmFyVG9PYmooc3RyaW5nIHN0cikKK3sKKyAgaWYgKCFzdHJpbmdwKHN0cikgfHwgIXNpemVvZihzdHIpIHx8IHN0clswXSE9JyQnKQorICAgIHJldHVybiBOVUxMOworICBzd2l0Y2goc3RyKQorICB7CisgICAgY2FzZSAiJG0iOgorICAgIGNhc2UgIiRtZSI6CisgICAgcmV0dXJuIGNsb25lcjsKKyAgICBjYXNlICIkaCI6CisgICAgY2FzZSAiJGhlcmUiOgorICAgIHJldHVybiBFTlYoY2xvbmVyKTsKKyAgICBkZWZhdWx0OgorICAgIHJldHVybiB2YXJpYWJsZVtzdHJbMS4uPDFdXTsKKyAgfQorICByZXR1cm4oTlVMTCk7IC8vbmV2ZXIgcmVhY2hlZAorfQorCitzdGF0aWMgc3RyaW5nIFZhclRvRmlsZShzdHJpbmcgc3RyKQoreworICByZXR1cm4gc291cmNlX2ZpbGVfbmFtZShWYXJUb09iaihzdHIpKTsKK30KKworc3RhdGljIHN0cmluZyBWYXJUb1B1cmVGaWxlKHN0cmluZyBzdHIpCit7CisgIHJldHVybiBwdXJlX2ZpbGVfbmFtZShWYXJUb09iaihzdHIpKTsKK30KKworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgKiBvYmplY3QgZGVzY3JpcHRpb24gcHJpbnRpbmcKKyAqLworCitzdGF0aWMgdm9pZCBQcmludE9iaihvYmplY3Qgb2JqLCBzdHJpbmcgZmlsZSkKK3sKKyAgb2JqZWN0IGl0ZW0sIHRtcDsKKyAgc3RyaW5nIHN0cjsKKyAgaW50IGk7CisKKyAgU0VDVVJFMSgpOworICBpZighb2JqKQorICAgIHJldHVybjsKKyAgUHJpbnRTaG9ydCgiU2hvcnQ6ICIsIG9iaiwgZmlsZSk7CisgIGlmKCFmaWxlfHxmaWxlPT0iIikKKyAgICBXTE4oIkxvbmcgOiIpOworICBlbHNlCisgICAgd3JpdGVfZmlsZShmaWxlLCJMb25nIDpcbiIpOworICBpZihxdWVyeV9vbmNlX2ludGVyYWN0aXZlKG9iaikpCisgICAgc3RyPWNhcGl0YWxpemUoZ2V0dWlkKG9iaikpOworICBlbHNlCisgIHsKKyAgICBpZihvYmplY3RfbmFtZShvYmopWzAuLjI2XT09Ii9kL3VudGVyd2VsdC9vYmpla3RlL3RlZGR5IyIgJiYKKyAgICAgICBJU19BUkNIKHRoaXNfaW50ZXJhY3RpdmUoKSkpCisgICAgICBzdHI9IkVpbiBUZWRkeSAoc3R1bW0pIjsKKyAgICBlbHNlCisgICAgeworICAgICAgaWYoc3RyPShzdHJpbmcpb2JqLT5RdWVyeVByb3AoUF9JTlRfTE9ORykpCisJOworICAgICAgZWxzZSBpZihzdHI9KHN0cmluZylvYmotPlF1ZXJ5UHJvcChQX0xPTkcpKQorCTsKKyAgICAgIGVsc2UKKwlzdHI9Ii0gbm8gbG9uZyBkZXNjcmlwdGlvbiAtXG4iOworICAgIH0KKyAgfQorICBpZighZmlsZXx8ZmlsZT09IiIpCisgICAgVyhzdHIpOworICBlbHNlCisgICAgd3JpdGVfZmlsZShmaWxlLHN0cik7CisgIEZPUkFMTChpdGVtLCBvYmopCisgIHsKKyAgICBpZighaSkKKyAgICAgIGlmKCFmaWxlfHxmaWxlPT0iIikKKwlXTE4oIkNvbnRlbnQ6Iik7CisgICAgICBlbHNlCisJd3JpdGVfZmlsZShmaWxlLCJDb250ZW50OlxuIik7CisgICAgUHJpbnRTaG9ydChBUklHSFQoKytpKyIuICIsIDQsICIgIiksIGl0ZW0sIGZpbGUpOworICB9Cit9CisKK3N0YXRpYyBzdHJpbmcgT2JqRmlsZShvYmplY3Qgb2JqKQoreworICByZXR1cm4gIlsiK3Nob3J0X3BhdGgob2JqZWN0X25hbWUob2JqKSkrIl0iOworfQorCitzdGF0aWMgdmFyYXJncyB2b2lkIFByaW50U2hvcnQoc3RyaW5nIHByZSwgb2JqZWN0IG9iaiwgc3RyaW5nIGZpbGUpCit7CisgIHN0cmluZyBzdHI7CisKKyAgU0VDVVJFMSgpOworICBpZighb2JqKQorICAgIHJldHVybjsKKyAgaWYoTU9ERShNT0RFX1NIT1JUKSkKKyAgeworICAgIGlmIChxdWVyeV9vbmNlX2ludGVyYWN0aXZlKG9iaikpCisgICAgICBzdHI9Y2FwaXRhbGl6ZShnZXR1aWQob2JqKSk7CisgICAgZWxzZQorICAgIHsKKyAgICAgIGlmKCEoKHN0cj0oc3RyaW5nKW9iai0+UXVlcnlQcm9wKFBfSU5UX1NIT1JUKSl8fAorCSAgIChzdHI9KHN0cmluZylvYmotPlF1ZXJ5UHJvcChQX1NIT1JUKSkpKQorCWlmKGlzX3BsYXllcihvYmopKQorCSAgc3RyPUNSTkFNRShvYmopKyIgKGludmlzaWJsZSkiOworCWVsc2UKKwkgIHN0cj0iLSBubyBzaG9ydCBkZXNjcmlwdGlvbiAtIjsKKyAgICB9CisgICAgc3RyPUFMRUZUKHNwcmludGYoIiVPICIsc3RyKSwgMzQsICIuIikrIiAiOworICB9CisgIGVsc2UKKyAgICBzdHI9IiI7CisgIGlmKGludGVyYWN0aXZlKG9iaikpCisgICAgc3RyKz0iaSI7CisgIGVsc2UgaWYobGl2aW5nKG9iaikpCisgICAgc3RyKz0ibCI7CisgIGVsc2UKKyAgICBzdHIrPSIuIjsKKyAgc3RyKz0oc2hhZG93KG9iaiwgMCkgPyAicyIgOiAiLiIpOworICBpZighZmlsZXx8ZmlsZT09IiIpCisgICAgV0xOKChwcmUrQ0FQKHN0cikrIiAiK09iakZpbGUob2JqKSlbMC4uNzldKTsKKyAgZWxzZQorICAgIHdyaXRlX2ZpbGUoZmlsZSwocHJlK0NBUChzdHIpKyIgIitPYmpGaWxlKG9iaikpWzAuLjc5XSsiXG4iKTsKK30KKworc3RhdGljIHZhcmFyZ3Mgdm9pZCBEZWVwUHJpbnRTaG9ydChvYmplY3QgZW52LCBpbnQgaW5kZW50LCBzdHJpbmcgcHJlLCBzdHJpbmcgZmlsZSkKK3sKKyAgaW50IGk7CisgIG9iamVjdCBpdGVtOworICBzdHJpbmcgc3RyOworICAKKyAgU0VDVVJFMSgpOworICBpZighZW52KQorICAgIHJldHVybjsKKyAgZm9yKGk9aW5kZW50LHN0cj0iIjsgaS0tOyBzdHIrPSIgICIpOworICBpZihwcmUpCisgICAgc3RyKz1wcmU7CisgIGlmKCFmaWxlfHxmaWxlPT0iIikKKyAgICBXKHN0cik7CisgIGVsc2UKKyAgICB3cml0ZV9maWxlKGZpbGUsc3RyKTsKKyAgaSsrOworICBQcmludFNob3J0KCIiLGVudixmaWxlKTsKKyAgRk9SQUxMKGl0ZW0sIGVudikKKyAgICBEZWVwUHJpbnRTaG9ydChpdGVtLGluZGVudCsxLEFSSUdIVCgoKytpKSsiLiAiLDQsIiAiKSxmaWxlKTsKK30KKworc3RhdGljIHN0cmluZyBicmVha19zdHJpbmdfaGFyZChzdHJpbmcgc3RyLCBpbnQgbGVuLCBzdHJpbmcgcHJlKQoreworICBpbnQgcyxwLHQ7CisgIHN0cmluZyB0bXA7CisKKyAgaWYoIXN0cnx8IShzPXNpemVvZihzdHIpKSkKKyAgICByZXR1cm4gIiI7CisgIHQ9bGVuLShwPXNpemVvZihwcmUpKS0xOworCisgIHRtcD0iIjsKKyAgd2hpbGUocCtzPmxlbikKKyAgeworICAgIHRtcCs9cHJlK3N0clswLi50XSsiXG4iOworCXN0cj1zdHJbdCsxLi5dOworCXMtPXQ7CisgIH0KKyAgaWYoc2l6ZW9mKHN0cikpCisgICAgdG1wKz1wcmUrc3RyWzAuLl0rIlxuIjsKKyAgcmV0dXJuIHRtcDsKK30KKyAgCitzdGF0aWMgdm9pZCBkcHJvcChzdHJpbmcga2V5LCBtaXhlZCBkYXRhLCBvYmplY3Qgb2JqKQoreworICBpZihwaXBlX291dCYmcGlwZV9vZikKKyAgICB3cml0ZV9maWxlKHBpcGVfb2YsYnJlYWtfc3RyaW5nX2hhcmQobWl4ZWRfdG9fc3RyaW5nKG9iai0+UXVlcnlQcm9wKGtleSksTUFYX1JFQ1VSU0lPTiksNzgsQUxFRlQoa2V5KyIgIiwxOCwiLiIpKyIgPSAiKSk7CisgIGVsc2UKKyAgICBXKGJyZWFrX3N0cmluZ19oYXJkKG1peGVkX3RvX3N0cmluZyhvYmotPlF1ZXJ5UHJvcChrZXkpLE1BWF9SRUNVUlNJT04pLDc4LEFMRUZUKGtleSsiICIsMTgsIi4iKSsiID0gIikpOworfQorCitzdGF0aWMgc3RyaW5nIHByb3BmbGFncyhzdHJpbmcga2V5LCBvYmplY3Qgb2IpCit7CisgIGludCB0bXA7CisgIHN0cmluZyAqZmxhZ3M7CisgIHRtcD0oaW50KW9iLT5RdWVyeShrZXksMSk7CisgIGZsYWdzPSh7fSk7CisgIHRtcCZTQVZFID8JICAgICAgIGZsYWdzKz0oeyJTQVYifSkgOiBmbGFncys9KHsiICAgIn0pOworICB0bXAmUFJPVEVDVEVEID8gICAgICBmbGFncys9KHsiUFJPIn0pIDogZmxhZ3MrPSh7IiAgICJ9KTsKKyAgdG1wJlNFQ1VSRUQgPyAgICAgICAgZmxhZ3MrPSh7IlNFQyJ9KSA6IGZsYWdzKz0oeyIgICAifSk7CisgIHRtcCZOT1NFVE1FVEhPRCA/ICAgIGZsYWdzKz0oeyJOU00ifSkgOiBmbGFncys9KHsiICAgIn0pOworICB0bXAmU0VUTU5PVEZPVU5EID8gICBmbGFncys9KHsiU01OIn0pIDogZmxhZ3MrPSh7IiAgICJ9KTsKKyAgdG1wJlFVRVJZTU5PVEZPVU5EID8gZmxhZ3MrPSh7IlFNTiJ9KSA6IGZsYWdzKz0oeyIgICAifSk7CisgIHRtcCZRVUVSWUNBQ0hFRCA/ICAgIGZsYWdzKz0oeyJRQ0EifSkgOiBmbGFncys9KHsiICAgIn0pOworICB0bXAmU0VUQ0FDSEVEID8gICAgICBmbGFncys9KHsiU0NBIn0pIDogZmxhZ3MrPSh7IiAgICJ9KTsKKyAgcmV0dXJuICIiK2ltcGxvZGUoZmxhZ3MsInwiKTsKK30KKworc3RhdGljIHZvaWQgZHByb3AyKHN0cmluZyBrZXksIG1peGVkIGRhdGEsIG9iamVjdCBvYikKK3sKKyAgaWYocGlwZV9vdXQmJnBpcGVfb2YpCisgICAgd3JpdGVfZmlsZShwaXBlX29mLGJyZWFrX3N0cmluZ19oYXJkKG1peGVkX3RvX3N0cmluZyhwcm9wZmxhZ3Moa2V5LG9iKSxNQVhfUkVDVVJTSU9OKSw3OCxBTEVGVChrZXkrIiAiLDE4LCIuIikrIiA9ICIpKTsKKyAgZWxzZQorICAgIFcoYnJlYWtfc3RyaW5nX2hhcmQobWl4ZWRfdG9fc3RyaW5nKHByb3BmbGFncyhrZXksb2IpLE1BWF9SRUNVUlNJT04pLDc4LEFMRUZUKGtleSsiICIsMTgsIi4iKSsiID0gIikpOworfQorCitzdGF0aWMgbWl4ZWQgcHJvcG1ldGhvZHMoc3RyaW5nIGtleSwgb2JqZWN0IG9iKQoreworICByZXR1cm4gKG1peGVkKW9iLT5RdWVyeShrZXksMik7Cit9CisKK3N0YXRpYyB2b2lkIGRwcm9wMyhzdHJpbmcga2V5LCBtaXhlZCBkYXRhLCBvYmplY3Qgb2IpCit7CisgIGlmKHBpcGVfb3V0JiZwaXBlX29mKQorICAgIHdyaXRlX2ZpbGUocGlwZV9vZixicmVha19zdHJpbmdfaGFyZChtaXhlZF90b19zdHJpbmcocHJvcG1ldGhvZHMoa2V5LG9iKSxNQVhfUkVDVVJTSU9OKSw3OCxBTEVGVChrZXkrIiAiLDE4LCIuIikrIiA9ICIpKTsKKyAgZWxzZQorICAgIFcoYnJlYWtfc3RyaW5nX2hhcmQobWl4ZWRfdG9fc3RyaW5nKHByb3BtZXRob2RzKGtleSxvYiksTUFYX1JFQ1VSU0lPTiksNzgsQUxFRlQoa2V5KyIgIiwxOCwiLiIpKyIgPSAiKSk7Cit9CisKK3N0YXRpYyB2b2lkIER1bXBQcm9wZXJ0aWVzKG9iamVjdCBvYmosIGludCBmbGFnKQoreworICBTRUNVUkUxKCk7CisgIGlmKCFvYmopCisgICAgcmV0dXJuOworICBQSVBFX0RFTEVURShwaXBlX29mKTsKKyAgc3dpdGNoIChmbGFnKSB7CisgICAgY2FzZSAwOgorICAgICAgd2Fsa19tYXBwaW5nKCgobWFwcGluZyAqKShvYmotPl9fcXVlcnlfcHJvcGVydGllcygpKSlbMF0sIydkcHJvcCxvYmopOyAvLycpCisgICAgICBicmVhazsKKyAgICBjYXNlIDE6CisgICAgICB3YWxrX21hcHBpbmcoKChtYXBwaW5nICopKG9iai0+X19xdWVyeV9wcm9wZXJ0aWVzKCkpKVswXSwjJ2Rwcm9wMixvYmopOyAvLycpCisgICAgICBicmVhazsKKyAgICBjYXNlIDI6CisgICAgICB3YWxrX21hcHBpbmcoKChtYXBwaW5nICopKG9iai0+X19xdWVyeV9wcm9wZXJ0aWVzKCkpKVswXSwjJ2Rwcm9wMyxvYmopOyAvLycpCisgICAgICBicmVhazsKKyAgfQorfQorCisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAqIG1vdmluZyBvYmplY3RzCisgKi8KKworc3RhdGljIGludCBNb3ZlT2JqKG9iamVjdCBvYmoxLCBvYmplY3Qgb2JqMiwgaW50IHNpbGVudCkKK3sKKyAgaW50IGVycjsKKyAgb2JqZWN0IG9sZGVudjsKKworICBTRUNVUkUyKEZBTFNFKTsKKyAgaWYoIShvYmoxJiZvYmoyKSkKKyAgICByZXR1cm4gRkFMU0U7CisgIG9sZGVudj1FTlYob2JqMSk7CisgIGVycj0oaW50KW9iajEtPm1vdmUob2JqMiwgTV9TSUxFTlR8TV9OT0NIRUNLKTsKKyAgaWYoIXNpbGVudCkKKyAgICBzd2l0Y2goZXJyKQorICAgIHsKKyAgICAgIGNhc2UgTUVfUExBWUVSOgorICAgICAgV0RMTigiT2JqZWN0IHJldHVybmVkIE1FX1BMQVlFUiIpOworICAgICAgaWYob2xkZW52ICYmIG9sZGVudiAhPSBFTlYob2JqMSkpCisJV0RMTigiT2JqZWN0IGhhcyBiZWVuIG1vdmVkIik7CisgICAgICByZXR1cm4gRkFMU0U7CisgICAgICBjYXNlIE1FX1RPT19IRUFWWToKKyAgICAgIFdETE4oIk9iamVjdCByZXR1cm5lZCBNRV9UT09fSEVBVlkiKTsKKyAgICAgIGlmKG9sZGVudiAmJiBvbGRlbnYgIT0gRU5WKG9iajEpKQorCVdETE4oIk9iamVjdCBoYXMgYmVlbiBtb3ZlZCIpOworICAgICAgcmV0dXJuIEZBTFNFOworICAgICAgY2FzZSBNRV9DQU5UX1RQT1JUX0lOOgorICAgICAgV0RMTigiT2JqZWN0IHJldHVybmVkIE1FX0NBTlRfVFBPUlRfSU4iKTsKKyAgICAgIGlmKG9sZGVudiAmJiBvbGRlbnYgIT0gRU5WKG9iajEpKQorCVdETE4oIk9iamVjdCBoYXMgYmVlbiBtb3ZlZCIpOworICAgICAgcmV0dXJuIEZBTFNFOworICAgICAgY2FzZSBNRV9DQU5UX1RQT1JUX09VVDoKKyAgICAgIFdETE4oIk9iamVjdCByZXR1cm5lZCBNRV9DQU5UX1RQT1JUX09VVCIpOworICAgICAgaWYob2xkZW52ICYmIG9sZGVudiAhPSBFTlYob2JqMSkpCisJV0RMTigiT2JqZWN0IGhhcyBiZWVuIG1vdmVkIik7CisgICAgICByZXR1cm4gRkFMU0U7CisgICAgICBkZWZhdWx0OgorICAgICAgV0RMTigiT2JqZWN0IHJldHVybmVkIHVua25vd24gcmV0dXJuIHZhbHVlIik7CisgICAgICByZXR1cm4gRkFMU0U7CisgICAgfQorICByZXR1cm4gVFJVRTsKK30KKworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgKiBzYXZlIGRlc3RydWN0aW5nIG9mIG9iamVjdHMKKyAqLworCitzdGF0aWMgdm9pZCBEZXN0cnVjdChvYmplY3Qgb2JqKQoreworICBpZighb2JqIHx8ICF0aGlzX29iamVjdCgpKQorICAgIHJldHVybjsKKyAgY2F0Y2gob2JqLT5yZW1vdmUoKSk7CisgIGlmKG9iamVjdHAob2JqKSAmJiAhcXVlcnlfb25jZV9pbnRlcmFjdGl2ZShvYmopKQorICAgIGRlc3RydWN0KG9iaik7Cit9CisKK3N0YXRpYyB2b2lkIERlZXBDbGVhbihvYmplY3Qgb2JqKQoreworICBpZighb2JqKQorICAgIHJldHVybjsKKyAgZmlsdGVyKGZpbHRlcihkZWVwX2ludmVudG9yeShvYmopLCAiaXNfbm90X3BsYXllciIsIE1FKSwKKwkgICAgICAgIkRlc3RydWN0IiwgTUUpOworICBpZihpc19ub3RfcGxheWVyKG9iaikpCisgICAgRGVzdHJ1Y3Qob2JqKTsKK30KKworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgKiBTaG93IHRoZSBpbmhlcml0YW5jZSB0cmVlIG9mIG9iamVjdHMKKyAqLworCitzdGF0aWMgb2JqZWN0ICpTdWJOb2RlcyhvYmplY3Qgb2JqKQoreworICBpbnQgczsKKyAgb2JqZWN0ICpvYmpzOworICBzdHJpbmcgKmlubGlzdDsKKyAgCisgIGlmKCFvYmopCisgICAgcmV0dXJuIE5VTEw7CisgIGlubGlzdD1pbmhlcml0X2xpc3Qob2JqKTsKKyAgcz1zaXplb2YoaW5saXN0KTsKKyAgb2Jqcz0oe30pOworICB3aGlsZShzLS0+MSkKKyAgICBvYmpzPSh7ZmluZF9vYmplY3QoaW5saXN0W3NdKX0pK29ianM7CisgIHJldHVybiBvYmpzOworfQorCitzdGF0aWMgdm9pZCBJbmhlcml0YW5jZShvYmplY3Qgb2JqLCBzdHJpbmcgZnVuYywgc3RyaW5nIHByZSkKK3sKKyAgaW50IGksIHM7CisgIG9iamVjdCAqbG47CisgIHN0cmluZyBzdHI7CisgIAorICBpZighb2JqKQorICAgIHJldHVybjsKKyAgc3RyPXByZSsiICIrT2JqRmlsZShvYmopOworICBpZihmdW5jKQorICB7CisgICAgc3RyPUFMRUZUKHN0cisiICIsIDUwLCAiLiIpOworICAgIGlmKGZ1bmN0aW9uX2V4aXN0cyhmdW5jLCBvYmopPT1vYmplY3RfbmFtZShvYmopKQorICAgICAgc3RyKz1BUklHSFQoIiAiK2Z1bmMsIDE5LCAiLiIpOworICAgIGVsc2UKKyAgICAgIHN0cis9QVJJR0hUKCIiLCAxOSwgIi4iKTsKKyAgfQorICBpZihwaXBlX291dCYmcGlwZV9vZikKKyAgICB3cml0ZV9maWxlKHBpcGVfb2Ysc3RyKyJcbiIpOworICBlbHNlCisgICAgV0xOKHN0cik7CisgIGxuPVN1Yk5vZGVzKG9iaik7CisgIGZvcihpPTA7IGk8c2l6ZW9mKGxuKTsgaSsrKQorICAgIGxuPWxuLVN1Yk5vZGVzKGxuW2ldKTsKKyAgcz1zaXplb2YobG4pOworICBmb3IoaT0wOyBpPHM7IGkrKykKKyAgICBJbmhlcml0YW5jZShsbltpXSwgZnVuYywgcHJlKyIuLi4uLiIpOworfQorCisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAqIGZpbGUgbmFtZSBoYW5kbGluZworICovCisKK3N0YXRpYyBzdHJpbmcgWEZpbGUoc3RyaW5nIGZpbGUpCit7CisgIFRLKCJYRmlsZTogZmlsZTogIisoZmlsZT9maWxlOiIoTlVMTCkiKSk7CisgIGlmKGZpbGUpCisgICAgc3dpdGNoKGZpbGVbMF0pCisgICAgeworICAgICAgY2FzZSAnQCc6CisJcmV0dXJuIHNvdXJjZV9maWxlX25hbWUoWEZpbmRPYmooZmlsZVsxLi48MV0pKTsKKyAgICAgIGNhc2UgJyQnOgorCXJldHVybiBzb3VyY2VfZmlsZV9uYW1lKFhGaW5kT2JqKGZpbGUpKTsKKyAgICAgIGRlZmF1bHQ6CisJcmV0dXJuIG9sZF9leHBsb2RlKGxvbmdfcGF0aChmaWxlKSwiIyIpWzBdOworICAgIH0KKyAgcmV0dXJuIE5VTEw7Cit9CisKK3N0YXRpYyBzdHJpbmcgWEZpbmRGaWxlKHN0cmluZyBmaWxlKQoreworICBUSygiWEZpbmRGaWxlOiBmaWxlOiAiKyhmaWxlP2ZpbGU6IihOVUxMKSIpKTsKKyAgaWYoZmlsZT1YRmlsZShmaWxlKSkKKyAgeworICAgIGlmKGZpbGVfc2l6ZShmaWxlKT49MCkKKyAgICAgIHJldHVybiBmaWxlOworICAgIGlmKGZpbGVbPDMuLjwxXSE9Ii5jIiAmJiBmaWxlX3NpemUoZmlsZSsiLmMiKT4wKQorICAgICAgcmV0dXJuIGZpbGUrIi5jIjsKKyAgfQorICBXRExOKCJGaWxlIG5vdCBmb3VuZCBvciBub3QgcmVhZGFibGUgWyIrc2hvcnRfcGF0aChmaWxlKSsiXSIpOworICByZXR1cm4gTlVMTDsKK30KKworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgKiBmaWxlIHByaW50aW5nLCBzZWFyY2hpbmcgYW5kIGV4ZWN1dGluZworICovCisKK3N0YXRpYyB2b2lkIFhNb3JlRmlsZShzdHJpbmcgZmlsZSwgaW50IGZsYWcpCit7CisgIGludCBzLHNpemU7CisgIAorICBTRUNVUkUxKCk7CisgIGlmKCFmaWxlKQorICAgIHJldHVybjsKKyAgCisgIC8vIHRlcm09KHN0cmluZyljbG9uZXItPlF1ZXJ5UHJvcChQX1RUWSkhPSJkdW1iIjsKKyAgaWYoKHNpemU9KGZpbGVfc2l6ZShtb3JlZmlsZT1sb25nX3BhdGgoZmlsZSkpKSk+MCkKKyAgeworICAgIGlmKHNpemU+MTAwMDAwKQorICAgICAgV0RMTigiV2FybmluZzogbGFyZ2UgZmlsZSIpOworICAgIE1vcmVGaWxlKE5VTEwpOworICB9CisgIGVsc2UgaWYoZmxhZykKKyAgICBXRExOKCJDYW5ub3QgcmVhZCBmaWxlIik7Cit9CisKKy8qCitzdGF0aWMgc3RyaW5nIHJlYWRfYnVmZmVyKHN0cmluZyBmaWxlbmFtZSwgaW50IHN0YXJ0LCBpbnQgbnVtYmVyKQoreworICBtaXhlZCB0bXA7CisgIHN0cmluZyByZXN1bHQ7CisgIGludCBjdXJyZW50OworCisgIGlmKCFmaWxlbmFtZXx8ZmlsZW5hbWU9PSIiKQorICAgIHJldHVybiAiIjsKKyAgaWYobnVtYmVyPD0xKQorICAgIG51bWJlcj0xOworICBudW1iZXItLTsKKyAgcmVzdWx0PSIiOworICBpZihmaWxlbmFtZSE9bGluZV9idWZmZXJfbmFtZSkKKyAgeworICAgIC8vIFRLKCJyZWFkX2J1ZmZlcjogaW5pdGlhbGl6aW5nIik7CisgICAgbGluZV9idWZmZXI9KFtdKTsKKyAgICBsaW5lX2J1ZmZlcl9uYW1lPWZpbGVuYW1lOworICAgIGN1cnJlbnQ9MDsKKyAgfQorICBlbHNlCisgICAgY3VycmVudD1zdGFydDsKKworICB3aGlsZShjdXJyZW50PD1zdGFydCtudW1iZXIgJiYgc3RyaW5ncCgodG1wPWxvYWRfYnVmZmVyKGN1cnJlbnQrKykpKSkKKyAgICBpZihjdXJyZW50Pj1zdGFydCkKKyAgICAgIHJlc3VsdCs9dG1wOworICByZXR1cm4gcmVzdWx0OworfQorCitzdGF0aWMgc3RyaW5nIGxvYWRfYnVmZmVyKGludCBsaW5lKQoreworICBpbnQgaSwgY3VycmVudCwgc3RhcnQsIGxlbmd0aCwgKmlkeDsKKworICBpZihpbnRwKGxpbmVfYnVmZmVyW2xpbmVdKSkKKyAgeworICAgIC8vIFRLKCJsb2FkX2J1ZmZlcjogTm90Zm91bmQ6ICIrbGluZSk7CisgICAgY3VycmVudD1saW5lOworICAgIHdoaWxlKGN1cnJlbnQ+MCYmaW50cChsaW5lX2J1ZmZlclstLWN1cnJlbnRdKSk7CisgICAgZm9yKGk9Y3VycmVudDtpPD1saW5lO2krKykKKyAgICB7CisgICAgICAvLyBUSygibG9hZF9idWZmZXI6IHRyeWluZzogIitpKTsKKyAgICAgIGlmKGk+MCkKKwlpZHg9bGluZV9idWZmZXJbaS0xXTsKKyAgICAgIGVsc2UKKwlpZHg9KHswLDB9KTsKKyAgICAgIGxlbmd0aD1yZWFkX2xpbmUoKHN0YXJ0PWlkeFswXStpZHhbMV0pKTsKKyAgICAgIC8vIFRLKCJsb2FkX2J1ZmZlcjogIitzdGFydCsiLyIrbGVuZ3RoKTsKKyAgICAgIGxpbmVfYnVmZmVyW2ldPSh7c3RhcnQsbGVuZ3RofSk7CisgICAgfQorICB9CisgIGlkeD1saW5lX2J1ZmZlcltsaW5lXTsKKyAgcmV0dXJuCisgICAgcmVhZF9ieXRlcyhsaW5lX2J1ZmZlcl9uYW1lLGlkeFswXSxpZHhbMV0pOworfQorCitzdGF0aWMgaW50IHJlYWRfbGluZShpbnQgb2Zmc2V0KQoreworICBtaXhlZCBsb2NfYnVmOworICBpbnQgbGVuZ3RoLCBwb3M7CisKKyAgLy8gVEsoInJlYWRfbGluZTogIitvZmZzZXQpOworICBsZW5ndGg9MDsKKyAgd2hpbGUoIWludHAoKGxvY19idWY9cmVhZF9ieXRlcyhsaW5lX2J1ZmZlcl9uYW1lLG9mZnNldCtsZW5ndGgsMTAyNCkpKSkKKyAgeworICAgIGlmKChwb3M9bWVtYmVyKGxvY19idWYsJ1xuJykpPj0wKQorICAgICAgcmV0dXJuIGxlbmd0aCtwb3MrMTsKKyAgICBsZW5ndGgrPTEwMjQ7CisgIH0KKyAgcmV0dXJuIGxlbmd0aDsKK30KKyovCisKK3N0YXRpYyB2b2lkIE1vcmVGaWxlKHN0cmluZyBzdHIpCit7CisgIGludCBpLCBvZmY7CisgIHN0cmluZyBmLCBsLCByOworICAKKyAgU0VDVVJFMSgpOworICAKKyAgaWYgKHN0ciAvKiYmIHNpemVvZihzdHIpKi8pCisgIHsKKwkJaWYoICFzaXplb2Yoc3RyKSApIHN0cj0iXDAiOworICAgIGlmKHRlcm0pCisgICAgICBXKCIbTRtbMU0iKTsKKyAgICBzd2l0Y2goc3RyWzBdKQorICAgIHsKKyAgICAgIGNhc2UgJ3EnOgorICAgICAgY2FzZSAneCc6CisgICAgICBtb3JlZmxhZz1GQUxTRTsKKyAgICAgIG1vcmVvZmZzZXQ9MTsKKyAgICAgIGlmKG1vcmVmaWxlPT1UTVBfRklMRXx8bW9yZWZpbGU9PVBJUEVfRklMRSkKKwlybShtb3JlZmlsZSk7CisgICAgICByZXR1cm4gTlVMTDsKKyAgICAgIGJyZWFrOworICAgICAgY2FzZSAnUCc6CisgICAgICBjYXNlICdVJzoKKyAgICAgIG1vcmVmbGFnPUZBTFNFOworICAgICAgbW9yZW9mZnNldD1tb3Jlb2Zmc2V0LW1vcmVsaW5lczsKKyAgICAgIGNhc2UgJ3AnOgorICAgICAgY2FzZSAndSc6CisgICAgICBtb3Jlb2Zmc2V0PW1vcmVvZmZzZXQtMiptb3JlbGluZXM7CisgICAgICBicmVhazsKKyAgICAgIGNhc2UgJ0QnOgorICAgICAgY2FzZSAnTic6CisgICAgICBtb3Jlb2Zmc2V0Kz1tb3JlbGluZXM7CisgICAgICBjYXNlIDA6CS8qIFJFVFVSTiAqLworICAgICAgY2FzZSAnZCc6CisgICAgICBpZihtb3JlZmxhZykKKyAgICAgIHsKKwltb3JlZmxhZz1GQUxTRTsKKwltb3Jlb2Zmc2V0PTE7CisJaWYobW9yZWZpbGU9PVRNUF9GSUxFKQorCSAgcm0obW9yZWZpbGUpOworCXJldHVybjsKKyAgICAgIH0KKyAgICAgIGJyZWFrOworICAgICAgY2FzZSAnLyc6CisgICAgICBtb3Jlb2Zmc2V0LS07CisgICAgICBtb3JlX3NlYXJjaGV4cHI9c3RyWzEuLjwxXTsKKyAgICAgIGNhc2UgJ24nOgorICAgICAgaT1tb3Jlb2Zmc2V0LW1vcmVsaW5lcysxOworICAgICAgaWYobW9yZV9zZWFyY2hleHByPT0iIikKKyAgICAgIHsKKwlXRExOKCJObyBwcmV2aW91cyByZWd1bGFyIGV4cHJlc3Npb24iKTsKKwlyZXR1cm47CisgICAgICB9CisgICAgICBpZighcmVnZXhwKCh7ImR1bW15In0pLCBtb3JlX3NlYXJjaGV4cHIpKQorCVdETE4oIkJhZCByZWd1bGFyIGV4cHJlc3Npb24iKTsKKyAgICAgIGVsc2UKKwl3aGlsZSgobD1yZWFkX2ZpbGUobW9yZWZpbGUsIGkrKywgMSkpJiYKKwkgICAgICAhc2l6ZW9mKHJlZ2V4cCgoe2x9KSwgbW9yZV9zZWFyY2hleHByKSkpCisJICA7CisgICAgICBpZihsKQorICAgICAgeworCVdMTigiKioqIFNraXBwaW5nIC4uLiIpOworCW1vcmVvZmZzZXQ9aS0xOworICAgICAgfQorICAgICAgZWxzZQorICAgICAgeworCVdMTigiKioqIFBhdHRlcm4gbm90IGZvdW5kIik7CisJbW9yZW9mZnNldC09bW9yZWxpbmVzOworICAgICAgfQorICAgICAgYnJlYWs7CisgICAgICBjYXNlICcwJy4uJzknOgorICAgICAgc3NjYW5mKHN0ciwgIiVkIiwgaSk7CisgICAgICBtb3Jlb2Zmc2V0PWk7CisgICAgICBicmVhazsKKyAgICB9CisgIH0KKyAgZWxzZQorICB7CisgICAgbW9yZW9mZnNldD0xOworICAgIG1vcmVmbGFnPUZBTFNFOworICB9CisgIGlmKG1vcmVvZmZzZXQ8MSkKKyAgICBtb3Jlb2Zmc2V0PTE7CisgIGlmKENhdEZpbGUoKSkKKyAgICBXKCIqKiogTW9yZTogcSx1LFUsZCxELC88cmVnZXhwPiw8bGluZT4gWyIrKG1vcmVvZmZzZXQtMSkrIl0gKioqICIpOworICBlbHNlCisgIHsKKyAgICBXKCIqKiogTW9yZTogcSx1LFUsZCxELC88cmVnZXhwPiw8bGluZT4gWyIrKG1vcmVvZmZzZXQtMSkrIj1FT0ZdICoqKiAiKTsKKyAgICBtb3JlZmxhZz1UUlVFOworICB9CisgIGlucHV0X3RvKCJNb3JlRmlsZSIpOworICByZXR1cm47Cit9CisKKy8vIFNjaGFkZSBlaWdlbnRsaWNoIGRhcyBpY2ggZXMgbmV1c2NocmVpYmVuIG11c3N0ZSwgYWJlciBlcyBpc3QKKy8vIHNjaG5lbGxlciBuZXUgZ2VzY2hyaWViZW4gYWxzIGR1cmNoIGRpZSB1bmRva3VtZW50aWVyZW4gYWx0ZW4gRnVua3Rpb25lbgorLy8gZHVyY2h6dXN0ZWlnZW4uLi4gKnNldWZ6KgorLy8JCQkJCSAgUGFkcmVpYworCitzdGF0aWMgc3RyaW5nIGxhc3RfZmlsZSwgKmxhc3RfZmlsZV9idWZmZXI7CitzdGF0aWMgaW50ICAgIGxhc3RfZmlsZV9kYXRlLCBsYXN0X2ZpbGVfc2l6ZSwgbGFzdF9maWxlX2NvbXBsZXRlOworCitzdGF0aWMgc3RyaW5nIHNyZWFkX2xpbmUoaW50IG51bSkKK3sKKyAgIGlmICghbW9yZWZpbGUpIHJldHVybiAiIjsKKyAgIGlmIChsYXN0X2ZpbGUhPW1vcmVmaWxlIHx8IGxhc3RfZmlsZV9kYXRlIT1maWxlX3RpbWUobW9yZWZpbGUpKSB7CisgICAgICBpZiAoIShsYXN0X2ZpbGU9cmVhZF9ieXRlcyhtb3JlZmlsZSwgMCwgNTAwMDApKSkgcmV0dXJuICIiOworICAgICAgbGFzdF9maWxlX2RhdGU9ZmlsZV90aW1lKG1vcmVmaWxlKTsKKyAgICAgIGxhc3RfZmlsZV9idWZmZXI9ZXhwbG9kZShsYXN0X2ZpbGUsICJcbiIpOworICAgICAgbGFzdF9maWxlX3NpemU9c2l6ZW9mKGxhc3RfZmlsZV9idWZmZXIpOworICAgICAgaWYgKHNpemVvZihsYXN0X2ZpbGUpPT01MDAwMCAmJiBsYXN0X2ZpbGVbPDFdIT0nXG4nKSB7CisJIGxhc3RfZmlsZV9zaXplLS07IC8vIGxldHp0ZSBaZWlsZSBuaWNodCB2b2xsc3RhZW5kaWcgZ2VsZXNlbgorCSBsYXN0X2ZpbGVfY29tcGxldGU9MDsKKyAgICAgIH0KKyAgICAgIGVsc2UgaWYgKGZpbGVfc2l6ZShtb3JlZmlsZSk+NTAwMDApCisJbGFzdF9maWxlX2NvbXBsZXRlPTA7CisgICAgICBlbHNlIGxhc3RfZmlsZV9jb21wbGV0ZT0xOworICAgICAgbGFzdF9maWxlPW1vcmVmaWxlOworICAgfQorICAgaWYgKG51bT09MCkgbnVtPTE7CisgICAvLyBiZWkgenUgZ3Jvc3NlbiBGaWxlcyBuaWNodCBtZWhyIGFsbGVzIGJ1ZmZlcm4uLi4KKyAgIGlmIChudW0+bGFzdF9maWxlX3NpemUpIHsKKyAgICAgIGlmIChsYXN0X2ZpbGVfY29tcGxldGUpIHJldHVybiAiIjsKKyAgICAgIHJldHVybiAocmVhZF9maWxlKG1vcmVmaWxlLCBudW0sIDEpIHx8ICIiKTsKKyAgIH0KKyAgIHJldHVybiBsYXN0X2ZpbGVfYnVmZmVyW251bS0xXSsiXG4iOworfQorCitzdGF0aWMgaW50IENhdEZpbGUoKQoreworICBpbnQgZW5kOworICBzdHJpbmcgbDsKKyAgCisgIGVuZD1tb3Jlb2Zmc2V0K21vcmVsaW5lczsKKyAgd2hpbGUobW9yZW9mZnNldDxlbmQpCisvLyAgICBpZigobD1yZWFkX2ZpbGUobW9yZWZpbGUsIG1vcmVvZmZzZXQsIDEpKSE9IiIpCisgICAgaWYoKGw9c3JlYWRfbGluZShtb3Jlb2Zmc2V0KSkhPSIiKQorICAgIHsKKyAgICAgIG1vcmVvZmZzZXQrKzsKKyAgICAgIFcobCk7CisgICAgfQorICAgIGVsc2UKKyAgICAgIHJldHVybiBGQUxTRTsKKy8vICBpZihyZWFkX2ZpbGUobW9yZWZpbGUsIG1vcmVvZmZzZXQrMSwgMSkhPSIiKQorICBpZihzcmVhZF9saW5lKG1vcmVvZmZzZXQrMSkhPSIiKQorICAgIHJldHVybiBUUlVFOworICBlbHNlCisgICAgcmV0dXJuIEZBTFNFOworfQorCitzdGF0aWMgaW50IFhHcmVwRmlsZShzdHJpbmcgcGF0LCBzdHJpbmcgZmlsZSwgaW50IG1vZGUpCit7CisgIGludCBpLCBqLCBmLCBzLCBmc2l6ZTsKKyAgc3RyaW5nIHRmaWxlLCAqdG1wLCAqdHMsIHQ7CisgIAorICBTRUNVUkUyKEZBTFNFKTsKKyAgVEsoIlhHcmVwRmlsZTogcGF0OiAiK3BhdCsiIGZpbGU6ICIrZmlsZSsiIG1vZGU6ICIrbW9kZSk7CisgIGlmKCEocGF0JiZmaWxlKSkKKyAgICByZXR1cm4gRkFMU0U7CisgIHRmaWxlPVRNUF9GSUxFOworICBmc2l6ZT1maWxlX3NpemUoZmlsZSk7CisgIGZvcihpPTAsZj0wOyBpPGZzaXplICYmIHQ9cmVhZF9ieXRlcyhmaWxlLCBpLCA1MDAwMCk7IGkrPTUwMDAwKQorICAgIHRtcD1zdHJpcF9leHBsb2RlKHQsIlxuIik7CisgICAgaWYgKHQgJiYgdFs8MV0hPSdcbicgJiYgc2l6ZW9mKHQpPT01MDAwMCkgeworICAgICAgIGktPXNpemVvZih0bXBbPDFdKTsKKyAgICAgICB0bXA9dG1wWzAuLjwyXTsKKyAgICB9CisgICAgaWYocz1zaXplb2YodG1wKSkKKyAgICB7CisgICAgICBmb3Ioaj0wO2o8cztqKyspCisgICAgICB7CisJaWYoc2l6ZW9mKHRzPXJlZ2V4cCgoeyhtb2RlJlhHUkVQX0lDQVNFP2xvd2VyX2Nhc2UodG1wW2pdKTp0bXBbal0pfSkscGF0KSkpCisJeworCSAgaWYoIShtb2RlJlhHUkVQX1JFVkVSVCkpCisJICAgeworCSAgICAgaWYoIWYrKykKKwkgICAgICAgd3JpdGVfZmlsZSh0ZmlsZSwgIioqKiBGaWxlOiAiK2ZpbGUrIiAqKipcbiIpOworCSAgICAgd3JpdGVfZmlsZSh0ZmlsZSwgdG1wW2pdKyJcbiIpOworCSAgIH0KKwl9CisJZWxzZSBpZihtb2RlJlhHUkVQX1JFVkVSVCkKKwl7CisJICBpZighZisrKQorCSAgICB3cml0ZV9maWxlKHRmaWxlLCAiKioqIEZpbGU6ICIrZmlsZSsiICoqKlxuIik7CisJICB3cml0ZV9maWxlKHRmaWxlLCB0bXBbal0rIlxuIik7CisJfQorICAgICAgfQorICAgIH0KKyAgcmV0dXJuIFRSVUU7Cit9CisKK3N0YXRpYyB2b2lkIFhFeGVjRmlsZShpbnQgbGluZSkKK3sKKyAgaW50IGk7CisgIAorICBpZighc2NyaXB0bGluZSkKKyAgICByZXR1cm47CisgIGZvcihpPWxpbmU7IGk8c2NyaXB0c2l6ZSYmaTxsaW5lK0VYRUNfTElORVM7IGkrKykKKyAgeworICAgIGlmKCFzY3JpcHRsaW5lW2ldKQorICAgICAgY29udGludWU7CisgICAgaWYoIUNvbW1hbmQoc2NyaXB0bGluZVtpXSkpCisgICAgeworICAgICAgc2NyaXB0bGluZT1OVUxMOworICAgICAgcmV0dXJuOworICAgIH0KKyAgfQorICBpZihpPHNjcmlwdHNpemUpCisgICAgY2FsbF9vdXQoIlhFeGVjRmlsZSIsIEVYRUNfVElNRSwgaSk7CisgIGVsc2UKKyAgICBzY3JpcHRsaW5lPU5VTEw7Cit9CisKK3N0YXRpYyB2b2lkIFhtdHBTY3JpcHQoc3RyaW5nIGRpciwgc3RyaW5nIGZpbGUsIHN0cmluZyBvcHQpCit7CisgIGludCBzLCB0OworICBzdHJpbmcgKmZpbGVzOworICAKKyAgcz1zaXplb2YoZmlsZXM9Z2V0X2RpcihkaXIrIi8qIikpOworICB3aGlsZShzLS0pCisgIHsKKyAgICB0PXNpemVvZihmaWxlc1tzXSktMTsKKyAgICBpZihmaWxlc1tzXSA9PSAiLi4iIHx8IGZpbGVzW3NdID09ICIuIiB8fCBmaWxlc1tzXVt0XSA9PSAnficgfHwKKyAgICAgICAoZmlsZXNbc11bMF0gPT0gJyMnICYmIGZpbGVzW3NdW3RdID09ICcjJykpCisgICAgICBjb250aW51ZTsKKyAgICBpZihmaWxlX3NpemUoZGlyKyIvIitmaWxlc1tzXSk9PS0yKQorICAgIHsKKyAgICAgIHdyaXRlX2ZpbGUoZmlsZSwgIm1rZGlyICIrZmlsZXNbc10rIiA7IGNkICIrZmlsZXNbc10rIlxuIik7CisgICAgICBYbXRwU2NyaXB0KGRpcisiLyIrZmlsZXNbc10sIGZpbGUsIG9wdCk7CisgICAgICB3cml0ZV9maWxlKGZpbGUsICJjZCAuLlxuIik7CisgICAgfQorICAgIGVsc2UKKyAgICAgIHdyaXRlX2ZpbGUoZmlsZSwgIm10cCAtciAiK29wdCsiICIrZGlyKyIvIitmaWxlc1tzXSsiXG4iKTsKKyAgfQorfQorCisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAqICBwbGF5ZXIgcHJvcGVydGllcyBoYW5kbGluZworICovCisKK3N0YXRpYyBzdHJpbmcgUGxheWVySWRsZShvYmplY3Qgb2JqKQoreworICBzdHJpbmcgc3RyOworICBpbnQgaSwgdG1wOworICAKKyAgaWYoIW9iaikKKyAgICByZXR1cm4gTlVMTDsKKyAgaWYoKGk9cXVlcnlfaWRsZShvYmopKT49NjApCisgIHsKKyAgICBzdHI9QVJJR0hUKCIiKyhpLzM2MDApLCAyLCAiMCIpOworICAgIGktPShpLzM2MDApKjM2MDA7CisgICAgc3RyKz0iJyIrQVJJR0hUKCIiKyhpLzYwKSwgMiwgIjAiKTsKKyAgfQorICBlbHNlCisgICAgc3RyPSIuLi4uLiI7CisgIHJldHVybiBzdHI7Cit9CisKK3N0YXRpYyBzdHJpbmcgUGxheWVyQWdlKG9iamVjdCBvYmopCit7CisgIHN0cmluZyBzdHI7CisgIGludCBpLCB0bXA7CisgIAorICBpZighb2JqKQorICAgIHJldHVybiBOVUxMOworICBpPShpbnQpb2JqLT5RdWVyeVByb3AoUF9BR0UpOworICBzdHI9IiAiK0FSSUdIVCgiIisoaS80MzIwMCksIDQsICIuIik7CisgIGktPShpLzQzMjAwKSo0MzIwMDsKKyAgcmV0dXJuIHN0cisiOiIrQVJJR0hUKCIiKyhpLzE4MDApLCAyLCAiMCIpOworfQorCitzdGF0aWMgc3RyaW5nIGNybmFtZShvYmplY3Qgd2hvKQoreworICBzdHJpbmcgdWlkLCBsbmFtZTsKKworICBpZigodWlkPWdldHVpZCh3aG8pKT09Uk9PVElEICYmIAorICAgICBvYmplY3RfbmFtZSh3aG8pWzAuLjddPT0iL3NlY3VyZS8iICYmCisgICAgIChsbmFtZT0oc3RyaW5nKXdoby0+bG9naW5uYW1lKCkpKQorICAgIHJldHVybiBDQVAobG5hbWUpOworICByZXR1cm4gQ0FQKHVpZCk7Cit9CisKK3N0YXRpYyBzdHJpbmcgUGxheWVyV2hvKG9iamVjdCBvYmopCit7CisgIG9iamVjdCB0bXA7CisgIHN0cmluZyBzdHIsIHN0bXA7CisgIHN0cj1BUklHSFQoIiIrTEVWRUwob2JqKSAgLCAgMywgIiAiKTsKKyAgc3RyKz1BTEVGVCgiICIrY3JuYW1lKG9iaikrIiAiLCAxMiwgIi4iKTsKKyAgc3RyKz1QbGF5ZXJBZ2Uob2JqKTsKKyAgc3RyKz0oKGludClvYmotPlF1ZXJ5UHJvcChQX0dFTkRFUik9PTEgPyAiIG0gIiA6ICIgZiAiKTsKKyAgc3RyKz0ob2JqLT5RdWVyeVByb3AoUF9GUk9HKSkgID8gImYiIDogIi4iOworICBzdHIrPShvYmotPlF1ZXJ5UHJvcChQX0dIT1NUKSkgPyAiZyIgOiAiLiI7CisgIHN0cis9KG9iai0+UXVlcnlQcm9wKFBfSU5WSVMpKSA/ICJpIiA6ICIuIjsKKyAgc3RyKz0ocXVlcnlfZWRpdGluZyhvYmopfHxxdWVyeV9pbnB1dF9wZW5kaW5nKG9iaikgPyAiZSIgOiAiLiIpOworICBzdHIrPShvYmotPlF1ZXJ5UHJvcChQX0FXQVkpKSAgPyAiYSIgOiAiLiI7CisgIHN0cis9IiAiK1BsYXllcklkbGUob2JqKSsiICI7CisgIHN0cis9KHRtcD1FTlYob2JqKSkgPyBPYmpGaWxlKHRtcCkgOiAiLSBmYWJyaWMgb2Ygc3BhY2UgLSI7CisgIHJldHVybiBzdHI7Cit9CisKK3N0YXRpYyBzdHJpbmcgUGxheWVyTWFpbChvYmplY3Qgb2JqLCBpbnQgZmxhZykKK3sKKyAgc3RyaW5nIHByZTsKKyAgCisgIHByZT0oZmxhZykgPyBBTEVGVChjcm5hbWUob2JqKSsiICIsIDEyLCAiLiIpKyIgIiA6ICIiOworICByZXR1cm4gcHJlKyJtYWlsOiAiK29iai0+UXVlcnlQcm9wKFBfTUFJTEFERFIpOworfQorCitzdGF0aWMgc3RyaW5nIFBsYXllcklQKG9iamVjdCBvYmosIGludCBmbGFnKQoreworICBzdHJpbmcgcHJlOworICAKKyAgcHJlPShmbGFnKSA/IEFMRUZUKGNybmFtZShvYmopKyIgIiwgMTIsICIuIikrIiAiIDogIiI7CisgIHJldHVybiBwcmUrImhvc3Q6ICIrcXVlcnlfaXBfbmFtZShvYmopKyIgKCIrcXVlcnlfaXBfbnVtYmVyKG9iaikrIikiOworfQorCitzdGF0aWMgc3RyaW5nIFBsYXllclJhY2Uob2JqZWN0IG9iaiwgaW50IGZsYWcpCit7CisgIHN0cmluZyB0bXAsIHByZTsKKyAgCisgIHByZT0oZmxhZykgPyBBTEVGVChjcm5hbWUob2JqKSsiICIsIDEyLCAiLiIpKyIgIiA6ICIiOworICBwcmU9cHJlKyJyYWNlOiAiK0FMRUZUKG9iai0+UXVlcnlQcm9wKFBfUkFDRSkrIiAiLCAxMCwgIi4iKSsiIGd1aWxkOiAiOworICB0bXA9KHN0cmluZylvYmotPlF1ZXJ5UHJvcChQX0dVSUxEKTsKKyAgcmV0dXJuIHRtcCA/IHByZSt0bXAgOiBwcmUrIi0gbm9uZSAtIjsKK30KKworc3RhdGljIHN0cmluZyBQbGF5ZXJEb21haW4ob2JqZWN0IG9iaiwgaW50IGZsYWcpCit7CisgIGludCBpLCBzOworICBtaXhlZCAqdWluZm87CisgIHN0cmluZyAqZG9tYWlucywgcHJlOworICAKKyAgcHJlPShmbGFnKSA/IEFMRUZUKGNybmFtZShvYmopKyIgIiwgMTIsICIuIikrIiAiIDogIiI7CisgIHByZSs9ImRvbWFpbmxvcmQgb2Y6ICI7CisgIHVpbmZvPShtaXhlZCopTUFTVEVSLT5nZXRfdXNlcmluZm8oZ2V0dWlkKG9iaikpOworICBpZih1aW5mbyYmKGRvbWFpbnM9dWluZm9bM10pJiYocz1zaXplb2YoZG9tYWlucykpKQorICB7CisgICAgZm9yKGk9MDsgaTxzOyBpKyspCisgICAgeworICAgICAgcHJlICs9IENBUChkb21haW5zW2ldKTsKKyAgICAgIGlmKGk8cy0xKQorCXByZSArPSAiLCAiOworICAgIH0KKyAgfQorICByZXR1cm4gcHJlOworfQorCitzdGF0aWMgc3RyaW5nIFBsYXllclN0YXRzKG9iamVjdCBvYmosIGludCBmbGFnKQoreworICBzdHJpbmcgcHJlOworICAKKyAgcHJlPShmbGFnKSA/IEFMRUZUKGNybmFtZShvYmopKyIgIiwgMTIsICIuIikrIiAiIDogIiI7CisgIHByZSs9ImhwPSIrQVJJR0hUKG9iai0+UXVlcnlQcm9wKFBfSFApLCAzLCAiMCIpOworICBwcmUrPSIvIitBUklHSFQob2JqLT5RdWVyeVByb3AoUF9NQVhfSFApLCAzLCAiMCIpOworICBwcmUrPSIgc3A9IitBUklHSFQob2JqLT5RdWVyeVByb3AoUF9TUCksIDMsICIwIik7CisgIHByZSs9Ii8iK0FSSUdIVChvYmotPlF1ZXJ5UHJvcChQX01BWF9TUCksIDMsICIwIik7CisgIHByZSs9IiBmb29kPSIrQVJJR0hUKG9iai0+UXVlcnlQcm9wKFBfRk9PRCksIDMsICIwIik7CisgIHByZSs9Ii8iK0FSSUdIVChvYmotPlF1ZXJ5UHJvcChQX01BWF9GT09EKSwgMywgIjAiKTsKKyAgcHJlKz0iIGRyaW5rPSIrQVJJR0hUKG9iai0+UXVlcnlQcm9wKFBfRFJJTkspLCAzLCAiMCIpOworICBwcmUrPSIvIitBUklHSFQob2JqLT5RdWVyeVByb3AoUF9NQVhfRFJJTkspLCAzLCAiMCIpOworICBwcmUrPSIgZXhwcz0iK29iai0+UXVlcnlQcm9wKFBfWFApOworICByZXR1cm4gcHJlOworfQorCitzdGF0aWMgc3RyaW5nIFBsYXllclNub29wKG9iamVjdCBvYmosIGludCBmbGFnKQoreworICBzdHJpbmcgdG1wLCBwcmU7CisgIG9iamVjdCB2aWN0aW07CisgIAorICBwcmU9KGZsYWcpID8gQUxFRlQoY3JuYW1lKG9iaikrIiAiLCAxMiwgIi4iKSsiICIgOiAiIjsKKyAgcHJlPXByZSsiaXMgc25vb3BlZCBieTogIjsKKyAgaWYodmljdGltPXF1ZXJ5X3Nub29wKG9iaikpCisgICAgcHJlKz1BUklHSFQoIiAiK2NybmFtZSh2aWN0aW0pLCAxMiwgIi4iKTsKKyAgZWxzZQorICAgIHByZSs9Ii4uLi4uLi4uLi4uLiI7CisgIHJldHVybiBwcmU7Cit9CisKK3N0YXRpYyBzdHJpbmcgUGxheWVyQ21kQXZnKG9iamVjdCBvYmosIGludCBmbGFnKQoreworICBzdHJpbmcgcHJlOworICAKKyAgcHJlPShmbGFnKSA/IEFMRUZUKGNybmFtZShvYmopKyIgIiwgMTIsICIuIikrIiAiIDogIiI7CisgIHJldHVybiBwcmUrImNtZGF2ZzogIisoaW50KW9iai0+X3F1ZXJ5X2NvbW1hbmRfYXZlcmFnZSgpOworfQorCisKKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICogbXNnIGlucHV0IHRvIG9iamVjdHMKKyAqLworCitzdGF0aWMgdm9pZCBYTXNnU2F5KHN0cmluZyBzdHIpCit7CisgIGlmKHN0cj09Ii4ifHxzdHI9PSIqKiIpCisgIHsKKyAgICBXTE4oIltFbmQgb2YgbWVzc2FnZV0iKTsKKyAgICBzYXkoIltFbmQgb2YgbWVzc2FnZV1cbiIpOworICB9CisgIGVsc2UKKyAgeworICAgIHNheShzdHIrIlxuIik7CisgICAgaW5wdXRfdG8oIlhNc2dTYXkiKTsKKyAgfQorfQorCitzdGF0aWMgdm9pZCBYTXNnVGVsbChzdHJpbmcgc3RyKQoreworICBpZihzdHI9PSIuInx8c3RyPT0iKioiKQorICB7CisgICAgV0xOKCJbRW5kIG9mIG1lc3NhZ2VdIik7CisgICAgdGVsbF9vYmplY3QobXNndG8sICJbRW5kIG9mIG1lc3NhZ2VdXG4iKTsKKyAgfQorICBlbHNlCisgIHsKKyAgICB0ZWxsX29iamVjdChtc2d0bywgc3RyKyJcbiIpOworICAgIGlucHV0X3RvKCJYTXNnVGVsbCIpOworICB9Cit9CisKK3N0YXRpYyB2b2lkIFhNc2dTaG91dChzdHJpbmcgc3RyKQoreworICBpZihzdHI9PSIuInx8c3RyPT0iKioiKQorICB7CisgICAgV0xOKCJbRW5kIG9mIG1lc3NhZ2VdIik7CisgICAgc2hvdXQoIltFbmQgb2YgbWVzc2FnZV1cbiIpOworICB9CisgIGVsc2UKKyAgeworICAgIHNob3V0KHN0cisiXG4iKTsKKyAgICBpbnB1dF90bygiWE1zZ1Nob3V0Iik7CisgIH0KK30KKworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgKiBvd24gb2JqZWN0IG1vdmluZworICovCisKK2ludCBtb3ZlKG1peGVkIGRlc3QpCit7CisgIG1vdmVfb2JqZWN0KE1FLCBjbG9uZXI/Y2xvbmVyOmRlc3QpOworICByZXR1cm4gVFJVRTsKK30KKworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgKiBvYmplY3QgaWQKKyAqLworCitpbnQgaWQoc3RyaW5nIHN0cikKK3sKKyAgaWYoIXNlY3VyaXR5KCkmJk1PREUoTU9ERV9TQ0FOQ0hLKSYmUlRQJiYhSVNfQVJDSChSVFApKQorICAgIFdETE4oY3JuYW1lKFJUUCkrIiBzY2FubmVkIHlvdSAoaWQpIFsiK3F1ZXJ5X3ZlcmIoKSsiXSAiKworCSAoUFJFViA/IE9iakZpbGUoUFJFVikgOiAiW2Rlc3RydWN0ZWQgb2JqZWN0XSIpKTsKKyAgcmV0dXJuIExPV0VSKHN0cik9PUxPV0VSKFRPT0xfTkFNRSk7Cit9CisKKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICogc2hvcnQgYW5kIGxvbmcgZGVzY3JpcHRpb24KKyAqLworCitzdHJpbmcgc2hvcnQoKQoreworICByZXR1cm4gX3F1ZXJ5X3Nob3J0KCkrIi5cbiI7Cit9CisKK3N0cmluZyBfcXVlcnlfc2hvcnQoKQoreworICBzdHJpbmcgc2g7IC8vIGFkZGVkIGJ5IFJ1bWF0YQorICBpZihjbG9uZXIpCisgIHsKKyAgICBpZigoIXNlY3VyaXR5KCkpJiZNT0RFKE1PREVfU0NBTkNISykmJiFJU19BUkNIKFJUUCkpCisgICAgICBXRExOKGNybmFtZShSVFApKyIgc2Nhbm5lZCB5b3UgKHNob3J0KSBbIitxdWVyeV92ZXJiKCkrIl0gIisKKwkgICAoUFJFViA/IE9iakZpbGUoUFJFVikgOiAiW2Rlc3RydWN0ZWQgb2JqZWN0XSIpKTsKKwlpZiggc2g9UXVlcnkoUF9TSE9SVCkgKSByZXR1cm4gc2g7IC8vIGFkZGVkIGJ5IFJ1bWF0YQorICAgIHJldHVybiBjbG9uZXItPm5hbWUoV0VTU0VOKSsiICIrVE9PTF9USVRMRSsiIFsiKworICAgICAgY3RpbWUodGltZSgpKVsxMS4uMThdKyJdIjsKKyAgfQorICByZXR1cm4gVE9PTF9USVRMRTsKK30KKworc3RyaW5nIGxvbmcoKQoreworICByZXR1cm4gX3F1ZXJ5X2xvbmcoKTsKK30KKworc3RyaW5nIF9xdWVyeV9sb25nKCkKK3sKKyAgaWYoY2xvbmVyJiYhc2VjdXJpdHkoKSYmTU9ERShNT0RFX1NDQU5DSEspJiYhSVNfQVJDSChSVFApKQorICB7CisgICAgV0RMTihjcm5hbWUoUlRQKSsiIHNjYW5uZWQgeW91IChsb25nKSBbIitxdWVyeV92ZXJiKCkrIl0gIisKKwkgKFBSRVYgPyBPYmpGaWxlKFBSRVYpIDogIltkZXN0cnVjdGVkIG9iamVjdF0iKSk7CisgIH0KKyAgcmV0dXJuIAorICAgICJUaGlzIGlzICIrVE9PTF9OQU1FKyIgdmVyc2lvbiAiK1RPT0xfVkVSU0lPTisKKyAgICAiIChtYWludGFpbmVkIGJ5IEtpcmtATW9yZ2VuR3JhdWVuKVxuIisKKyAgICAiT3JpZ2luYWwgY29weXJpZ2h0IGhlbGQgYnkgSHlwLlxuIisKKyAgICAiR2FtZWRyaXZlciBwYXRjaGxldmVsOiAiK19fVkVSU0lPTl9fKyIgbWFzdGVyIG9iamVjdDogIitfX01BU1RFUl9PQkpFQ1RfXysKKyAgICAiXG5cbkRvICd4aGVscCcgZm9yIG1vcmUgaW5mb3JtYXRpb24uXG4iOworfQorCitzdHJpbmcgbmFtZShtaXhlZCBkdW1teTEsIG1peGVkIGR1bW15MikKK3sKKyAgcmV0dXJuIF9xdWVyeV9zaG9ydCgpOworfQorCisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAqIGxpZ2h0IHN0dWZmCisgKi8KKworaW50IF9xdWVyeV9saWdodCgpCit7CisgIHJldHVybiB4bGlnaHQ7Cit9CisKK2ludCBfc2V0X2xpZ2h0KGludCB4KQoreworICByZXR1cm4geGxpZ2h0OworfQorCisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAqIEF1dG9sb2FkaW5nCisgKi8KKworbWl4ZWQgKl9xdWVyeV9hdXRvbG9hZG9iaigpCit7CisgIHJldHVybiBBVVRPTE9BRF9BUkdTOworfQorCit2b2lkIF9zZXRfYXV0b2xvYWRvYmoobWl4ZWQgKmFyZ3MpCit7CisgIFdMTihUT09MX1RJVExFKyIgLi4uIik7CisgIGlmKCFwb2ludGVycChhcmdzKSkKKyAgICA7CisgIGVsc2UgaWYoc2l6ZW9mKGFyZ3MpIT0zKQorICAgIDsKKyAgZWxzZSBpZighc3RyaW5ncChhcmdzWzBdKSkKKyAgICA7CisgIGVsc2UgaWYoIWludHAoYXJnc1sxXSkpCisgICAgOworICBlbHNlIGlmKCFpbnRwKGFyZ3NbMl0pKQorICAgIDsKKyAgZWxzZQorICB7CisgICAgaWYoKHN0cmluZylhcmdzWzBdIT1UT09MX0lOVEVSTkFMKQorICAgIHsKKyAgICAgIFdMTigiKioqKioqKioqKioqKioqKioqKioqKioqKioqKioiKTsKKyAgICAgIFdMTigiKioqCSAgICBORVcgRURJVElPTiAgICAgICoqKiIpOworICAgICAgV0xOKCIqKioJZG8gJ3h0b29sIG5ld3MnIGZvciAgKioqIik7CisgICAgICBXTE4oIioqKgkgbW9yZSBpbmZvcm1hdGlvbiAgICAqKioiKTsKKyAgICAgIFdMTigiKioqKioqKioqKioqKioqKioqKioqKioqKioqKioiKTsKKyAgICB9CisgICAgbW9kaT0oaW50KWFyZ3NbMV07CisgICAgbW9yZWxpbmVzPShpbnQpYXJnc1syXTsKKyAgICByZXR1cm47CisgIH0KKyAgVygiKGJhZCBhdXRvbG9hZCwgdXNpbmcgZGVmYXVsdClcbiIpOworfQorCisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAqIGNyZWF0aW9uLCB1cGRhdGluZyBhbmQgaW5pdGlhbGl6YXRpb24gc3R1ZmYKKyAqLworCit2b2lkIHVwZGF0ZV90b29sKG1peGVkICphcmdzLCBvYmplY3Qgb2JqKQoreworICBTRUNVUkUxKCk7CisgIGlmKCEob2JqJiZhcmdzKSkKKyAgICByZXR1cm47CisgIERlc3RydWN0KFBSRVYpOworICBfc2V0X2F1dG9sb2Fkb2JqKGFyZ3MpOworICBtb3ZlKG9iaik7Cit9CisKK3ZvaWQgY3JlYXRlKCkKK3sKKyAgb2JqZWN0IG9iajsKKyAgCisgIGlmKG1lbWJlcihvYmplY3RfbmFtZSgpLCcjJyk8MCkKKyAgICByZXR1cm47CisgIGlmKCFjbG9uZXImJiEoKGNsb25lcj1UUCl8fChjbG9uZXI9RU5WKE1FKSkpJiYhaW50ZXJhY3RpdmUoY2xvbmVyKSkKKyAgICBkZXN0cnVjdChNRSk7CisgIGlmKCFJU19MRUFSTkVSKGNsb25lcikpCisgICAgZGVzdHJ1Y3QoTUUpOworICBTZXRQcm9wKFBfTk9EUk9QLCJEYXMgd2FlcmUgenUgZ2VmYWVocmxpY2guXG4iKTsKKyAgU2V0UHJvcChQX05FVkVSRFJPUCwxKTsKKyAgU2V0UHJvcChQX05PQlVZLDEpOworICBpZihmaWxlX3NpemUoU0FWRV9GSUxFKyIubyIpPjApCisgIHsKKyAgICBXRExOKCJMb2FkaW5nICIrVE9PTF9USVRMRSsiIHNldHRpbmdzIik7CisgICAgcmVzdG9yZV9vYmplY3QoU0FWRV9GSUxFKTsKKyAgfQorICBpZihNT0RFKE1PREVfRklSU1QpKQorICAgIGNhbGxfb3V0KCJtb3ZlIiwwLGNsb25lcik7CisgIGNhbGxfb3V0KCJhZGRfaW5zZXJ0X2hvb2siLDEsTUUpOworfQorCit2b2lkIFRLKHN0cmluZyBzdHIpCit7CisgIGlmICgheHRrKQorICAgIHJldHVybjsKKyAgdGVsbF9vYmplY3QoY2xvbmVyLCJYVE9PTDogIitzdHIrIlxuIik7Cit9CisKK2ludCBYdGsoc3RyaW5nIHN0cikKK3sKKyAgeHRrPSF4dGs7CisgIFdETE4oIlh0b29sIGludGVybmFsIHRyYWNpbmcgIisoeHRrPyJlbmFibGVkIjoiZGlzYWJsZWQiKSk7CisgIHJldHVybiBUUlVFOworfQorCit2b2lkIGFkZF9pbnNlcnRfaG9vayhvYmplY3Qgb2JqKQoreworICBpZihvYmplY3RwKG9iaikpCisgICAgY2xvbmVyLT5BZGRJbnNlcnRIb29rKG9iaik7Cit9CisKK3ZvaWQgaW5pdCgpCit7CisgIG9iamVjdCBmaXJzdCwgcHJldjsKKyAgCisgIGlmKG1lbWJlcihvYmplY3RfbmFtZSgpLCcjJyk8MCkgcmV0dXJuOworICBmaXJzdD1maXJzdF9pbnZlbnRvcnkoRU5WKE1FKSk7CisgIGlmKE1PREUoTU9ERV9QUk9URUNUKSYmaXNfcGxheWVyKGZpcnN0KSYmIUlTX0FSQ0goZmlyc3QpKQorICB7CisgICAgV0RMTigiV0FSTklORzogIitjcm5hbWUoZmlyc3QpKyIgdHJpZWQgdG8gbW92ZSBpbnRvIHlvdXIgaW52ZW50b3J5Iik7CisgICAgdGVsbF9vYmplY3QoZmlyc3QsICJZb3UgY2Fubm90IG1vdmUgeW91cnNlbGYgaW50byAiKworCQljcm5hbWUoY2xvbmVyKSsiJ3MgaW52ZW50b3J5LlxuIik7CisgICAgY2FsbF9vdXQoIkRyb3BPYmoiLDAsZmlyc3QpOworICAgIHJldHVybjsKKyAgfQorICBlbHNlIGlmKE1PREUoTU9ERV9GSVJTVCkmJmZpcnN0IT1NRSkKKyAgICBtb3ZlKGNsb25lcik7CisgIGVsc2UgYWN0aW9ucygpOworfQorCit2b2lkIERyb3BPYmoob2JqZWN0IG9iaikKK3sKKyAgaWYoIW9ianx8IW9iamVjdHAob2JqKSkKKyAgICByZXR1cm47CisgIG9iai0+bW92ZShFTlYoY2xvbmVyKSxNX05PQ0hFQ0t8TV9OT19TSE9XKTsKK30KKworI2RlZmluZSBBQ1RJT05TXAorKFtcCisgICJ4Y2FsbG91dHMiIDogIlhjYWxsb3V0cyI7MDsxLFwKKyAgInhjYWxsIiAgICAgOiAiWGNhbGwiOzA7MSxcCisgICJ4Y2F0IiAgICAgIDogIlhjYXQiOzE7MSxcCisgICJ4Y2QiICAgICAgIDogIlhjZCI7MDswLFwKKyAgInhjbGVhbiIgICAgOiAiWGNsZWFuIjswOzAsXAorICAieGNsb25lIiAgICA6ICJYY2xvbmUiOzA7MCxcCisgICJ4dWNsb25lIiAgIDogIlh1Y2xvbmUiOzA7MCxcCisgICJ4Y21kcyIgICAgIDogIlhjbWRzIjswOzEsXAorICAieGRiZyIgICAgICA6ICJYZGJnIjswOzAsXAorICAieGRjbGVhbiIgICA6ICJYZGNsZWFuIjswOzAsXAorICAieGRkZXMiICAgICA6ICJYZGRlcyI7MDswLFwKKyAgInhkZXMiICAgICAgOiAiWGRlcyI7MDswLFwKKyAgInhkZXN0IiAgICAgOiAiWGRlcyI7MDswLFwKKyAgInhkbG9vayIgICAgOiAiWGRsb29rIjswOzEsXAorICAieGRvIiAgICAgICA6ICJYZG8iOzA7MCxcCisgICJ4ZHVwZGF0ZSIgIDogIlhkdXBkYXRlIjswOzAsXAorICAieGVjaG8iICAgICA6ICJYZWNobyI7MDswLFwKKyAgInhldmFsIiAgICAgOiAiWGV2YWwiOzA7MSxcCisgICJ4Zm9yYWxsIiAgIDogIlhmb3JhbGwiOzA7MCxcCisgICJ4Z290byIgICAgIDogIlhnb3RvIjswOzAsXAorICAieGhiZWF0cyIgICA6ICJYaGJlYXRzIjswOzEsXAorICAieGdyZXAiICAgICA6ICJYZ3JlcCI7MTsxLFwKKyAgInhoZWFkIiAgICAgOiAiWGhlYWQiOzE7MSxcCisgICJ4aGVscCIgICAgIDogIlhoZWxwIjswOzAsXAorICAieGludmVudG9yeSI6ICJYaW52ZW50b3J5IjswOzEsXAorICAieGlkcyIgICAgICA6ICJYaWRzIjswOzAsXAorICAieGluZm8iICAgICA6ICJYaW5mbyI7MDswLFwKKyAgInhpbmhlcml0IiAgOiAiWGluaGVyaXQiOzA7MSxcCisgICJ4bGFnIiAgICAgIDogIlhsYWciOzA7MCxcCisgICJ4bGlnaHQiICAgIDogIlhsaWdodCI7MDswLFwKKyAgInhsb2FkIiAgICAgOiAiWGxvYWQiOzA7MCxcCisgICJ4bG9vayIgICAgIDogIlhsb29rIjswOzEsXAorICAieGxwYyIgICAgICA6ICJYbHBjIjswOzAsXAorICAieG1hbiIgICAgICA6ICJYbWFuIjswOzAsXAorICAieG1vcmUiICAgICA6ICJYbW9yZSI7MTswLFwKKyAgInhtb3ZlIiAgICAgOiAiWG1vdmUiOzA7MCxcCisgICJ4bXNnIiAgICAgIDogIlhtc2ciOzE7MCxcCisgICJ4bXRwIiAgICAgIDogIlhtdHAiOzA7MCxcCisgICJ4cHJvYyIgICAgIDogIlhwcm9jIjswOzEsXAorICAieHByb2YiICAgICA6ICJYcHJvZiI7MDswLFwKKyAgInhwcm9wcyIgICAgOiAiWHByb3BzIjswOzEsXAorICAieHF1aXQiICAgICA6ICJYcXVpdCI7MDswLFwKKyAgInhzY2FuIiAgICAgOiAiWHNjYW4iOzA7MCxcCisgICJ4c2V0IiAgICAgIDogIlhzZXQiOzA7MCxcCisgICJ4c2giICAgICAgIDogIlhzaCI7MDswLFwKKyAgInhzb3J0IiAgICAgOiAiWHNvcnQiOzE7MSxcCisgICJ4dGFpbCIgICAgIDogIlh0YWlsIjsxOzEsXAorICAieHRrIiAgICAgICA6ICJYdGsiOzA7MCxcCisgICJ4dG9vbCIgICAgIDogIlh0b29sIjswOzAsXAorICAieHRyYWNlIiAgICA6ICJYdHJhY2UiOzA7MCxcCisgICJ4dHJhbnMiICAgIDogIlh0cmFucyI7MDswLFwKKyAgInh1cGRhdGUiICAgOiAiWHVwZGF0ZSI7MDswLFwKKyAgInh3YyIgICAgICAgOiAiWHdjIjsxOzAsXAorICAieHdobyIgICAgICA6ICJYd2hvIjswOzEsXAorICBdKQorCitzdGF0aWMgc3RyaW5nIFByZXBhcmVMaW5lKHN0cmluZyBzdHIpCit7CisgIHJldHVybiBzdHI7Cit9CisKK3N0YXRpYyBzdHJpbmcgUXVvdGVMaW5lKHN0cmluZyBzdHIpCit7CisgIHN0cmluZyAqdG1wLCp0bXAyOworICBpbnQgaSwgaTIsIGxlbiwgbGVuMiwgcWQsIHFzOworCisgIHN0cj1zdHJpbmdfcmVwbGFjZShzdHIsIlxcXFwiLCKwQlNITCIpOworICBzdHI9c3RyaW5nX3JlcGxhY2Uoc3RyLCJcXFwiIiwisERCTFEiKTsKKyAgc3RyPXN0cmluZ19yZXBsYWNlKHN0ciwiXFxcJyIsIrBTR0xRIik7CisgIHN0cj1zdHJpbmdfcmVwbGFjZShzdHIsIlxcfCIsIrBQSVBFIik7CisgIHN0cj1zdHJpbmdfcmVwbGFjZShzdHIsInx8IiwisE9ST1IiKTsKKyAgc3RyPXN0cmluZ19yZXBsYWNlKHN0ciwiLT4iLCKwTEFSUiIpOworICBzdHI9c3RyaW5nX3JlcGxhY2Uoc3RyLCJcXCQiLCKwRE9MUiIpOworICB0bXA9cmVnZXhwbG9kZShzdHIsIihcInwnKSIpOworICBsZW49c2l6ZW9mKHRtcCk7CisgIHFkPXFzPTA7CisgIGZvcihpPTA7aTxsZW47aSsrKQorICB7CisgICAgaWYoaSUyKQorICAgIHsKKyAgICAgIGlmKHRtcFtpXT09IiciKQorCXFkPSghcXM/IXFkOnFkKTsKKyAgICAgIGVsc2UKKwlxcz0oIXFkPyFxczpxcyk7CisgICAgICBpZigodG1wW2ldPT0iXCIiJiYhcWQpfHwodG1wW2ldPT0iJyImJiFxcykpCisJdG1wW2ldPSIiOworICAgIH0KKyAgICBlbHNlCisgICAgeworICAgICAgaWYoIXFkKQorICAgICAgeworCWxlbjI9c2l6ZW9mKHRtcDI9cmVnZXhwbG9kZSh0bXBbaV0sIlxcJFteIF1bXiBdKiIpKTsKKwlmb3IoaTI9MDtpMjxsZW4yO2kyKyspCisJICBpZihpMiUyKQorCSAgeworCSAgICBUSygiUXVvdGVMaW5lOiAiK3RtcDJbaTJdWzEuLl0pOworCSAgICB0bXAyW2kyXT0oc3RyaW5nKVhGaW5kT2JqKCh0bXAyW2kyXSlbMS4uXSk7CisJICB9CisJdG1wW2ldPWltcGxvZGUodG1wMiwiIik7CisgICAgICB9CisgICAgfQorICB9CisgIGlmKHFkfHxxcykKKyAgICByZXR1cm4gTlVMTDsKKyAgc3RyPWltcGxvZGUodG1wLCIiKTsKKyAgVEsoIlF1b3RlTGluZTogc3RyOiAiK3N0cik7CisgIHJldHVybiBzdHI7Cit9CisKK3N0YXRpYyBzdHJpbmcgVW5xdW90ZUxpbmUoc3RyaW5nIHN0cikKK3sKKyAgc3RyPXN0cmluZ19yZXBsYWNlKHN0ciwisEJTSEwiLCJcXCIpOworICBzdHI9c3RyaW5nX3JlcGxhY2Uoc3RyLCKwREJMUSIsIlwiIik7CisgIHN0cj1zdHJpbmdfcmVwbGFjZShzdHIsIrBTR0xRIiwiXCciKTsKKyAgc3RyPXN0cmluZ19yZXBsYWNlKHN0ciwisERRVU8iLCIiKTsKKyAgc3RyPXN0cmluZ19yZXBsYWNlKHN0ciwisFNRVU8iLCIiKTsKKyAgc3RyPXN0cmluZ19yZXBsYWNlKHN0ciwisFBJUEUiLCJ8Iik7CisgIHN0cj1zdHJpbmdfcmVwbGFjZShzdHIsIrBPUk9SIiwifHwiKTsKKyAgc3RyPXN0cmluZ19yZXBsYWNlKHN0ciwisExBUlIiLCItPiIpOworICBzdHI9c3RyaW5nX3JlcGxhY2Uoc3RyLCKwRE9MUiIsIiQiKTsKKyAgVEsoIlVucXVvdGVMaW5lOiBzdHI6ICIrc3RyKTsKKyAgcmV0dXJuIHN0cjsKK30KKworc3RhdGljIHN0cmluZyAqRXhwbG9kZUNtZHMoc3RyaW5nIHN0cikKK3sKKyAgc3RyaW5nICp0bXA7CisgIAorICB0bXA9cmVnZXhwbG9kZShzdHIsIlxcfHw+fD4+Iik7CisgIHdoaWxlKHRtcFs8MV09PSIiKQorICAgIHRtcD10bXBbMC4uPDJdOworICByZXR1cm4gdG1wOworfQorCit2YXJhcmdzIGludCBQYXJzZUxpbmUoc3RyaW5nIHN0cikKK3sKKyAgc3RyaW5nIHZlcmIsIGFyZzsKKyAgaW50IHJldDsKKyAgCisgIFRLKCJQYXJzZUxpbmU6IHN0cjogIisoc3RyP3N0cjoiIikpOworICBpZighc2l6ZW9mKGNtZHMpKQorICB7CisgICAgLy8gdGhpcyBpcyBhIHNpbmdsZSBjb21tYW5kIG9yIGJlZ2lubmluZyBvZiBhIGNvbW1hbmQgcGlwZQorICAgIHZlcmI9cXVlcnlfdmVyYigpOworCisgICAgLy8gcmV0dXJuIG9uIHVua25vd24gY29tbWFuZHMKKyAgICBpZighdmVyYnx8IXNpemVvZih2ZXJiKXx8IUdldEZ1bmModmVyYixUUlVFKSkKKyAgICAgIHJldHVybiBGQUxTRTsKKworICAgIHN0cj0oc3RyaW5nKXRoaXNfcGxheWVyKCktPl91bnBhcnNlZF9hcmdzKCk7CisgICAgcGlwZV9pbj1GQUxTRTsKKyAgICBwaXBlX29mPU5VTEw7CisgICAgcGlwZV9vdnI9VFJVRTsKKyAgICBwaXBlX291dD1GQUxTRTsKKyAgICBwaXBlX29mPU5VTEw7CisgICAgLy8gcGFzcyBhcmd1bWVudHMgdG8gc29tZSBzcGVjaWFsIGZ1bmN0aW9ucyB1bnBhcnNlZAorICAgIGlmKG1lbWJlcigoeyJ4bHBjIiwieGNhbGwiLCJ4ZXZhbCJ9KSx2ZXJiKT49MCkKKyAgICB7CisjaWZkZWYgWERCRworICAgICAgVEsoIlBhcnNlTGluZTogc3BlY2lhbCBmdW5jOiAiK3ZlcmIpOworI2VuZGlmCisgICAgICByZXQ9Q2FsbEZ1bmModmVyYixzdHIpOworICAgICAgU2FmZVJldHVybihyZXQpOworICAgIH0KKyAgICAvLyBvaywgaGVyZSB3ZSBnbworICAgIHBpcGVfaW49cGlwZV9vdXQ9RkFMU0U7CisgICAgcGlwZV9pZj1waXBlX29mPU5VTEw7CisgICAgcGlwZV9vdnI9VFJVRTsKKyAgICBpZihmaWxlX3NpemUoUElQRV9GSUxFKT49MCkKKyAgICAgIHJtKFBJUEVfRklMRSk7CisgICAgaWYgKHN0ciYmc3RyIT0iIikJICAKKyAgICB7CisgICAgICBpZighKHN0cj1RdW90ZUxpbmUoc3RyKSkpCisgICAgICB7CisJV0RMTigiVW50ZXJtaW5hdGVkIHF1b3RhdGlvbiIpOworCVNhZmVSZXR1cm4oVFJVRSk7CisgICAgICB9CisgICAgICBjbWRzPUV4cGxvZGVDbWRzKHN0cik7CisgICAgfQorICAgIGVsc2UKKyAgICAgIGNtZHM9KHsiIn0pOworICAgIGFyZz1zdHJpcF9zdHJpbmcoY21kc1swXSk7CisgIH0KKyAgZWxzZQorICB7CisgICAgY21kc1swXT1zdHJpcF9zdHJpbmcoY21kc1swXSk7CisgICAgVEsoIlBhcnNlTGluZTogY21kc1swXTogIitjbWRzWzBdKTsKKyAgICBpZihzc2NhbmYoY21kc1swXSwiJXMgJXMiLHZlcmIsYXJnKSE9MikKKyAgICB7CisgICAgICB2ZXJiPWNtZHNbMF07CisgICAgICBhcmc9IiI7CisgICAgfQorICB9CisgIGNtZHM9Y21kc1sxLi5dOworICBUSygiUGFyc2VMaW5lOiB2ZXJiOiAiK3ZlcmIpOworICBpZiAoIXZlcmJ8fCFzaXplb2YodmVyYil8fCFHZXRGdW5jKHZlcmIsVFJVRSkpCisgICAgU2FmZVJldHVybihGQUxTRSk7CisgIFRLKCJQYXJzZUxpbmUoMSk6IGFyZzogIithcmcrIiBjbWRzOiAiK3NwcmludGYoIiVPIixjbWRzKSk7CisgIHN3aXRjaChzaXplb2YoY21kcykpCisgIHsKKyAgICBjYXNlIDA6CisgICAgcmV0PUNhbGxGdW5jKHZlcmIsc3RyaXBfc3RyaW5nKFVucXVvdGVMaW5lKGFyZykpKTsKKyAgICBTYWZlUmV0dXJuKHJldCk7CisgICAgYnJlYWs7CisgICAgCisgICAgY2FzZSAxOgorICAgIFdETE4oIk1pc3NpbmcgcmhzIG9mIGNvbW1hbmQgcGlwZSIpOworICAgIFNhZmVSZXR1cm4oVFJVRSk7CisgICAgYnJlYWs7CisgICAgCisgICAgZGVmYXVsdDoKKyAgICBwaXBlX291dD1UUlVFOworICAgIHN3aXRjaChjbWRzWzBdKQorICAgIHsKKyAgICAgIGNhc2UgInwiOgorICAgICAgcGlwZV9vZj1QSVBFX0ZJTEU7CisgICAgICBwaXBlX292cj1UUlVFOworICAgICAgY21kcz1jbWRzWzEuLl07CisgICAgICBicmVhazsKKyAgICAgIAorICAgICAgY2FzZSAiPiI6CisgICAgICBwaXBlX292cj1UUlVFOworICAgICAgaWYoc2l6ZW9mKGNtZHMpIT0yKQorICAgICAgeworCVdETE4oIklsbGVnYWwgSU8gcmVkaXJlY3Rpb24iKTsKKwlTYWZlUmV0dXJuKFRSVUUpOworICAgICAgfQorICAgICAgcGlwZV9vZj1jbWRzWzFdOworICAgICAgY21kcz0oe30pOworICAgICAgYnJlYWs7CisgICAgICAKKyAgICAgIGNhc2UgIj4+IjoKKyAgICAgIHBpcGVfb3ZyPUZBTFNFOworICAgICAgaWYoc2l6ZW9mKGNtZHMpIT0yKQorICAgICAgeworCVdETE4oIklsbGVnYWwgSU8gcmVkaXJlY3Rpb24iKTsKKwlTYWZlUmV0dXJuKFRSVUUpOworICAgICAgfQorICAgICAgcGlwZV9vZj1jbWRzWzFdOworICAgICAgY21kcz0oe30pOworICAgICAgYnJlYWs7CisgICAgfQorICB9CisgIFRLKCJQYXJzZUxpbmUoMik6IGFyZzogIithcmcrIiBjbWRzOiAiK3NwcmludGYoIiVPIixjbWRzKSk7CisgIGlmKCFDYWxsRnVuYyh2ZXJiLHN0cmlwX3N0cmluZyhhcmcpKSkKKyAgICBTYWZlUmV0dXJuKEZBTFNFKTsKKyAgcGlwZV9pbj1waXBlX291dDsKKyAgcGlwZV9pZj1waXBlX29mOworICBwaXBlX292cj1GQUxTRTsKKyAgcGlwZV9vdXQ9RkFMU0U7CisgIHBpcGVfb2Y9TlVMTDsKKyAgaWYoc2l6ZW9mKGNtZHMpKQorICAgIGNhbGxfb3V0KCJQYXJzZUxpbmUiLDApOworICBlbHNlCisgICAgU2FmZVJldHVybihUUlVFKTsKKyAgcmV0dXJuIFRSVUU7Cit9CisKK3N0YXRpYyBpbnQgQ2FsbEZ1bmMoc3RyaW5nIHZlcmIsIHN0cmluZyBzdHIpCit7CisgIHN0cmluZyBmdW47CisKKyAgZnVuPUdldEZ1bmModmVyYixGQUxTRSk7CisjaWZkZWYgWERCRworICBUSygiQ2FsbEZ1bmM6IHZlcmI6ICIrdmVyYisiIHN0cjogIitzdHIpOworICBUSygiQ2FsbEZ1bmM6IHJlc29sdmVkIGZ1bmN0aW9uOiAiKyhmdW4/ZnVuOiIodW5yZXNvbHZlZCkiKSk7CisjZW5kaWYKKyAgaWYoc3RyPT0iIikKKyAgICBzdHI9TlVMTDsKKyAgcmV0dXJuIGZ1bj8oaW50KWNhbGxfb3RoZXIoTUUsZnVuLHN0cik6RkFMU0U7Cit9CisKK3N0YXRpYyBzdHJpbmcgR2V0RnVuYyhzdHJpbmcgdmVyYiwgaW50IHRlc3QpCit7CisgIHN0cmluZyBmdW4sKmtleXMsa2V5OworICBpbnQgaSxsZW47CisKKyAgVEsoIkdldEZ1bmM6IHZlcmI6ICIrdmVyYik7CisKKyAgaWYodmVyYlswLi4wXSE9IngiKSAvLyBBc3N1bWUgYWxsIGNvbW1hbmRzIHN0YXJ0IHdpdGggIngiCisgICAgcmV0dXJuIDA7CisKKyAgaWYgKCEoZnVuPShzdHJpbmcpQUNUSU9OU1t2ZXJiLDBdKSkgeyAvLyBUcnkgZXhhY3QgaGl0IGZpcnN0CisgICAga2V5PSIiOworICAgIGxlbj1zaXplb2YodmVyYik7CisgICAgZm9yIChpPXNpemVvZihrZXlzPW1faW5kaWNlcyhBQ1RJT05TKSktMTtpPj0wO2ktLSkgeworICAgICAgVEsoIiAgdHJ5aW5nOiAiK2tleXNbaV0pOworICAgICAgaWYoc2l6ZW9mKGtleXNbaV0pPj1sZW4mJmtleXNbaV1bMC4ubGVuLTFdPT12ZXJiKSB7CisJaWYoc2l6ZW9mKGtleSkpIHsKKwkgIFdMTigiRGFzIGlzdCBuaWNodCBlaW5kZXV0aWcgLi4uIik7CisJICByZXR1cm4gMDsKKwl9CisJZnVuPUFDVElPTlNba2V5c1tpXSwwXTsKKwlrZXk9a2V5c1tpXTsKKwkvL2JyZWFrOworICAgICAgfQorICAgIH0KKyAgfSBlbHNlCisgICAga2V5PXZlcmI7CisKKyAgaWYodGVzdCkKKyAgICByZXR1cm4gZnVuOworICAKKyAgaWYgKGtleSkgeworI2lmZGVmIFhEQkcKKyAgICBUSygiR2V0RnVuYzogZnVuOiAiK2Z1bisiIChrZXk6ICIra2V5KyIpXG4iKworICAgICAgICJwaXBlX2luOiAiKyhwaXBlX2luPyJUUlVFICAiOiJGQUxTRSAiKSsocGlwZV9pZj9waXBlX2lmOiIoTlVMTCkiKSsiXG4iKworICAgICAgICJwaXBlX291dDogIisocGlwZV9vdXQ/IlRSVUUgICI6IkZBTFNFICIpKyhwaXBlX29mP3BpcGVfb2Y6IihOVUxMKSIpKyJcbiIrCisgICAgICAgInBpcGVfb3ZyOiAiKyhwaXBlX292cj8iVFJVRSI6IkZBTFNFIikpOworI2VuZGlmCisgICAgaWYgKHBpcGVfaW4mJiFBQ1RJT05TW2tleSxQSVBFX0lOXSkKKyAgICB7CisgICAgICAvLyB0aGlzIGNvbW1hbmQgZG9lcyBub3QgcmVhZCBwaXBlcworI2lmZGVmIFhEQkcKKyAgICAgIFRLKCJJbGxlZ2FsIHJocyBvZiBjb21tYW5kIHBpcGUgXCIiK2Z1bisiXCJcbiIpOworI2VuZGlmCisgICAgICBub3RpZnlfZmFpbCgiSWxsZWdhbCByaHMgb2YgY29tbWFuZCBwaXBlIFwiIitmdW4rIlwiXG4iKTsKKyAgICAgIHJldHVybiAwOworICAgIH0KKyAgICBlbHNlIGlmIChwaXBlX291dCYmIUFDVElPTlNba2V5LFBJUEVfT1VUXSkKKyAgICB7CisgICAgICAvLyB0aGlzIGNvbW1hbmQgZG9lcyBub3QgZmVlZCBwaXBlcworI2lmZGVmIFhEQkcKKyAgICAgIFRLKCJJbGxlZ2FsIGxocyBvZiBjb21tYW5kIHBpcGUgXCIiK2Z1bisiXCJcbiIpOworI2VuZGlmCisgICAgICBub3RpZnlfZmFpbCgiSWxsZWdhbCBsaHMgb2YgY29tbWFuZCBwaXBlIFwiIitmdW4rIlwiXG4iKTsKKyAgICAgIHJldHVybiAwOworICAgIH0KKyAgfQorICByZXR1cm4gZnVuOworfQorCit2b2lkIGFjdGlvbnMoKQoreworICBpZiAoIWNsb25lcnx8IVJUUHx8Y2xvbmVyPT1SVFB8fHF1ZXJ5X3dpel9sZXZlbChjbG9uZXIpPD1xdWVyeV93aXpfbGV2ZWwoUlRQKSkKKyAgICBhZGRfYWN0aW9uKCJQYXJzZUxpbmUiLCIiLDEpOworICBhZGRfYWN0aW9uKCJDb21tYW5kU2NhbiIsICIiLCAxKTsKK30KKworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgKiAgdGhlIGNoZWNraW5nIHN0dWZmCisgKi8KKwordm9pZCBJbnNlcnROb3RpZnkob2JqZWN0IG9iaikKK3sKKyAgaWYoIWNsb25lcikKKyAgICByZXR1cm47CisgIGlmKE1PREUoTU9ERV9GSVJTVCkgJiYgZmluZF9jYWxsX291dCgibW92ZSIpPT0tMSkKKyAgICBjYWxsX291dCgibW92ZSIsMCxjbG9uZXIpOworICBpZihNT0RFKE1PREVfSU5WQ0hFQ0spKQorICAgIHdyaXRlX25ld2ludm9iaihvYmopOworfQorCitzdGF0aWMgdm9pZCBWYXJDaGVjayhpbnQgc2hvdykKK3sKKyAgaW50IGksIHM7CisgIGZvcmVhY2goc3RyaW5nIGssIG1peGVkIHYgOiB2YXJpYWJsZSkKKyAgeworICAgIGlmICh2KSBjb250aW51ZTsKKyAgICBpZihzaG93KSBXRExOKCIqKiogVmFyaWFibGUgJCIraysiIGhhcyBiZWVuIGRlc3RydWN0ZWQiKTsKKyAgICBtX2RlbGV0ZSh2YXJpYWJsZSwgayk7CisgIH0KK30KKworCitpbnQgd3JpdGVfbmV3aW52b2JqKG9iamVjdCBvYmopCit7CisgIGlmKG9iaikgV0RMTigiKioqIE5ldyBvYmplY3QgaW4gaW52ZW50b3J5ICIrT2JqRmlsZShvYmopKTsKKyAgcmV0dXJuKDEpOworfQorCisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAqICBjYXRjaCBhbGwgY29tbWFuZHMsIGFic29yYiBmb3JjZXMgYW5kIGNoZWNrIGhpc3RvcnkKKyAqLworCitpbnQgQ29tbWFuZFNjYW4oc3RyaW5nIGFyZykKK3sKKyAgc3RyaW5nIHZlcmIsIGNtZDsKKyAgb2JqZWN0IHJ0cDsKKyAgcnRwPVJUUDsKKworICBpZighY2xvbmVyJiYhKGNsb25lcj1ydHApKSBkZXN0cnVjdChNRSk7CisKKyAgaWYoKCFNT0RFKE1PREVfUFJPVEVDVCkpfHxzZWN1cml0eSgpfHwKKyAgICAgcXVlcnlfd2l6X2xldmVsKGNsb25lcik8cXVlcnlfd2l6X2xldmVsKHJ0cCkpCisgIHsKKyAgICB2ZXJiPXF1ZXJ5X3ZlcmIoKTsKKyAgICBpZih2ZXJiJiZEb0hpc3RvcnkodmVyYisoYXJnID8gIiAiK2FyZyA6ICIiKSkpCisgICAgICByZXR1cm4gVFJVRTsKKyAgICBub3N0b3JlPUZBTFNFOworICAgIHJldHVybiBGQUxTRTsKKyAgfQorICBlbHNlCisgIHsKKyAgICBpZihydHApCisgICAgeworICAgICAgV0RMTigiWW91ciAiK1RPT0xfVElUTEUrIiBwcm90ZWN0cyB5b3UgZnJvbSBhIGZvcmNlIGJ5ICIrY3JuYW1lKHJ0cCkrCisJICAgIiBbIitxdWVyeV92ZXJiKCkrKGFyZyA/ICIgIithcmcrIl0iIDogIl0iKSk7CisgICAgICB0ZWxsX29iamVjdChydHAsIGNybmFtZShjbG9uZXIpKyIncyAiK1RPT0xfVElUTEUrCisJCSAgIiBhYnNvcmJlcyB5b3VyIGZvcmNlLlxuIik7CisgICAgfQorICAgIGVsc2UKKyAgICB7CisgICAgICBXRExOKCJZb3VyICIrVE9PTF9USVRMRSsiIHByb3RlY3RzIHlvdSBmcm9tIGEgZm9yY2UgWyIrCisJICAgcXVlcnlfdmVyYigpKyhhcmcgPyAiICIrYXJnKyJdIiA6ICJdIikpOworICAgIH0KKyAgICByZXR1cm4gVFJVRTsKKyAgfQorfQorCitpbnQgRG9IaXN0b3J5KHN0cmluZyBsaW5lKQoreworICBpbnQgaTsKKyAgc3RyaW5nIGNtZCwgKnN0cnM7CisgIAorICBTRUNVUkUyKEZBTFNFKTsKKyAgaWYoIXN0cmluZ3AobGluZSkgfHwgIXNpemVvZihsaW5lKSkKKyAgICByZXR1cm4gVFJVRTsKKyAgZWxzZSBpZihsaW5lPT0iJSEiKQorICB7CisgICAgV0xOKCJDdXJyZW50IGNvbW1hbmQgaGlzdG9yeToiKTsKKyAgICBmb3IoaT1NQVhfSElTVE9SWTsgaTsgLS1pKQorICAgICAgaWYoaGlzdG9yeVtpLTFdKQorICAgICAgeworCVcoIiAiK0FSSUdIVCgiIitpLCAyLCAiICIpKyI6ICIpOworCWlmKHNpemVvZihoaXN0b3J5W2ktMV0pPjcwKQorCSAgV0xOKEFMRUZUKGhpc3RvcnlbaS0xXSwgNzAsICIgIikpOworCWVsc2UKKwkgIFdMTihoaXN0b3J5W2ktMV0pOworICAgICAgfQorICAgIHJldHVybiBUUlVFOworICB9CisgIGVsc2UgaWYobGluZVswLi4xXT09IiUlIiAmJiAoY21kPWhpc3RvcnlbMF0rbGluZVsyLi48MV0pKQorICB7CisgICAgQ29tbWFuZChjbWQpOworICAgIHJldHVybiBUUlVFOworICB9CisgIGVsc2UgaWYobGluZVswXT09J14nJiYoc3Rycz1zdHJpcF9leHBsb2RlKGxpbmUsICJeIikpKQorICB7CisgICAgaWYoc2l6ZW9mKHN0cnMpJiZzdHJzWzBdJiYoY21kPWhpc3RvcnlbMF0pKQorICAgIHsKKyAgICAgIGlmKHNpemVvZihzdHJzKT09MikKKwljbWQ9c3RyaW5nX3JlcGxhY2UoY21kLCBzdHJzWzBdLCBzdHJzWzFdKTsKKyAgICAgIGVsc2UKKwljbWQ9c3RyaW5nX3JlcGxhY2UoY21kLCBzdHJzWzBdLCAiIik7CisgICAgICBub3N0b3JlLS07CisgICAgICBDb21tYW5kKGNtZCk7CisgICAgICBub3N0b3JlKys7CisgICAgICByZXR1cm4gVFJVRTsKKyAgICB9CisgIH0KKyAgZWxzZSBpZihsaW5lWzBdPT0nJScgJiYgKHNzY2FuZihsaW5lWzEuLjwxXSwgIiVkIiwgaSkpKQorICB7CisgICAgaT0gaT4wID8gaSA6IDE7CisgICAgaT0gaTw9TUFYX0hJU1RPUlkgPyBpIDogTUFYX0hJU1RPUlk7CisgICAgaWYoY21kPWhpc3RvcnlbaS0xXSkKKyAgICAgIENvbW1hbmQoY21kKTsKKyAgICByZXR1cm4gVFJVRTsKKyAgfQorICBlbHNlIGlmKGxpbmVbMF09PSclJykKKyAgeworICAgIGZvcihpPTA7IGk8TUFYX0hJU1RPUlk7IGkrKykKKyAgICB7CisgICAgICBpZihoaXN0b3J5W2ldJiYKKwkgaGlzdG9yeVtpXVswLi5zaXplb2YobGluZSktMl09PWxpbmVbMS4uIDwxXSkKKyAgICAgIHsKKwlDb21tYW5kKGhpc3RvcnlbaV0pOworCXJldHVybiBUUlVFOworICAgICAgfQorICAgIH0KKyAgfQorICBlbHNlIGlmKG5vc3RvcmU8MSkKKyAgICBoaXN0b3J5PSh7bGluZX0pK2hpc3RvcnlbMC4uTUFYX0hJU1RPUlktMl07CisgIHJldHVybiBGQUxTRTsKK30KKwo=