Ly8gTW9yZ2VuR3JhdWVuIE1VRGxpYgovLwovLyAtIFByb3RvdHlwZW4gdW5kIFByb3BlcnRpZXMgaW4gdGhpbmcvbWF0ZXJpYWwuaAovLyAtIExpc3RlIGluIG1hdGVyaWFscy5oCi8vCi8vIFRPRE86IHByb3BlcnRpZXMuaCB1bSBtYXRlcmlhbHMuaCBlcndlaXRlcm4KLy8KLy8gLSBpbXBsaXppdGUgR3J1cHBlbnp1b3JkbnVuZyBlbnRmZXJuZW4sIGRhIGpldHp0IGV4cGxpeml0IGluCi8vICAgRGVmaW5pdGlvbnNkYXRlaWVuIHZvcmhhbmRlbgovLyAtIE1hdGVyaWFsZG9rdSB1ZWJlcmFyYmVpdGVuLCBkYWJlaSBIaW53ZWlzIGF1ZiBuaWNodCBtZWhyIGltcGxpeml0ZQovLyAgIEdydXBwZW56dW9yZG51bmcKLy8gL3AvZGFlbW9uL21hdGVyaWFsZGIuYyAtLSBNYXRlcmlhbGRhdGVuYmFuawovLwovLyAkSWQ6IG1hdGVyaWFsZGIuYyA4NzU1IDIwMTQtMDQtMjYgMTM6MTM6NDBaIFplc3N0cmEgJAoKI3ByYWdtYSBzdHJvbmdfdHlwZXMKI3ByYWdtYSBub19jbG9uZQojcHJhZ21hIG5vX2luaGVyaXQKI3ByYWdtYSBub19zaGFkb3cKI3ByYWdtYSBwZWRhbnRpYwoKLy8gRGllIFByb3BlcnR5ZGVmaW5pdGlvbiByZWluaG9sZW4KI2luY2x1ZGUgPGxhbmd1YWdlLmg+CiNpbmNsdWRlIDx0aGluZy9kZXNjcmlwdGlvbi5oPgovLyBNYXRlcmlhbGxpc3RlIG5pY2h0IG1pdCByZWluemllaGVuCiNkZWZpbmUgX1NLSVBfTUFURVJJQUxTXwojaW5jbHVkZSA8dGhpbmcvbWF0ZXJpYWwuaD4KI2luY2x1ZGUgPHBsYXllci9kZXNjcmlwdGlvbi5oPgojaW5jbHVkZSA8cnRsaW1pdHMuaD4KCi8vIEJhc2lzdmVyemVpY2huaXMgZGVyIE1hdGVyaWFsaWVuCiNkZWZpbmUgTUFUX0RJUiAiL2RvYy9tYXRlcmlhbHMiCgovLyBBdXNnYWJldmVyemVpY2huaXMgZnVlciBEb2t1CiNkZWZpbmUgRE9DX0RJUih4KSAoIi9kb2MvbWF0ZXJpYWxzLyIreCkKCi8vIERhdGVpbmFtZSBkZXMgSGVhZGVycyBtaXQgTWF0ZXJpYWxkZWZpbml0aW9uZW4KI2RlZmluZSBIRUFERVJGSUxFICIvc3lzL21hdGVyaWFscy5oIgoKLy8gU2F2ZWZpbGUuCiNkZWZpbmUgU0FWRUZJTEUgRE9DX0RJUigibWF0ZXJpYWxkYiIpCgovLyBSZWluIGludGVybiB2ZXJ3ZW5kZXRlIE5hbWVuCiNkZWZpbmUgUF9SRUNPQyAicmVjb2duaXphYmlsaXR5IgojZGVmaW5lIFBfSUQgICAgImlkIgojZGVmaW5lIFBfREVGU1RSICJkZWZzdHIiCiNkZWZpbmUgUF9NRU1CRVJTICJtZW1iZXJzIgojZGVmaW5lIFBfTUdfRlJBQ1RJT05TICJtZ19mcmFjdGlvbnMiCgojZGVmaW5lIExPR19FUlJPUih4KSBpZihmaW5kX3BsYXllcigicmFzY2hhdWEiKSYmZmluZF9wbGF5ZXIoInJhc2NoYXVhIiktPlF1ZXJ5UHJvcCgibWRiLWRlYnVnIikpdGVsbF9vYmplY3QoZmluZF9wbGF5ZXIoInJhc2NoYXVhIiksIk1EQi1FcnJvcjoiK3gpCiNkZWZpbmUgTE9HX1dBUk4oeCkgaWYoZmluZF9wbGF5ZXIoInJhc2NoYXVhIikmJmZpbmRfcGxheWVyKCJyYXNjaGF1YSIpLT5RdWVyeVByb3AoIm1kYi1kZWJ1ZyIpKXRlbGxfb2JqZWN0KGZpbmRfcGxheWVyKCJyYXNjaGF1YSIpLCJNREItV2FybjoiK3gpCgovLyBQcm90b3R5cGVzOgovLyAoTGllZmVydCBkZW4gQW50ZWlsIGRlciBNYXRlcmlhbGdydXBwZSBncnAgYW4gbWF0cykKaW50IE1hdGVyaWFsR3JvdXAobWFwcGluZyBtYXRzLCBzdHJpbmcgZ3JwKTsKLy8gS29udmVydGllcnQgZWluZSBMaXN0ZSB2b24gTWF0ZXJpYWxpZW4genUgaWhyZW4gTmFtZW4sIGRhYmVpIHdpcmQgZGllCi8vIEVya2VubnVuZ3NmYWVoaWdrZWl0IGJlcnVlY2tzaWNodGlndCB1bmQgZXZ0bC4gZmFsc2NoIGVya2FubnQKdmFyYXJncyBzdHJpbmcgQ29udk1hdGVyaWFsTGlzdChtaXhlZCBtYXRzLCBpbnQgY2FzdXMsIG1peGVkIGlkaW5mKTsKdmFyYXJncyBzdHJpbmcgTWF0ZXJpYWxOYW1lKHN0cmluZyBtYXQsIGludCBjYXN1cywgbWl4ZWQgaWRpbmYpOwovLyBHaWJ0IGRlbiBOYW1lbiBlaW5lciBNYXRlcmlhbGdydXBwZSB6dXJ1ZWNrCnN0cmluZyBHcm91cE5hbWUoc3RyaW5nIGdycCk7Ci8vIEdpYnQgYWxsZSBNYXRlcmlhbGllbiB6dXJ1ZWNrCnN0cmluZyAqQWxsTWF0ZXJpYWxzKCk7Ci8vIEdpYnQgYWxsZSBHcnVwcGVuIHp1cnVlY2sKc3RyaW5nICpBbGxHcm91cHMoKTsKLy8gR2lidCBhbGxlIEdydXBwZW4genVydWVjaywgaW4gZGVuZW4gbWF0IGVudGhhbHRlbiBpc3QKc3RyaW5nICpHZXRNYXRNZW1iZXJzaGlwKHN0cmluZyBtYXQpOwovLyBHaWJ0IGFsbGUgTWF0ZXJpYWxpZW4genVydWVjaywgZGllIGluIGdycCBlbnRoYWx0ZW4gc2luZApzdHJpbmcgKkdldEdyb3VwTWVtYmVycyhzdHJpbmcgZ3JwKTsKLy8gRXJuZXVlcnQgZGllIE1hdGVyaWFsaWVuIGR1cmNoIFNjYW5uZW4gZGVzIE1hdGVyaWFsdmVyemVpY2huaXNzZXMKdm9pZCBVcGRhdGUoKTsKLy8gZ2VuZXJpZXJ0IEhlYWRlcmZpbGUgYXVzIGRlbiBEYXRlbgp2YXJhcmdzIHZvaWQgR2VuSGVhZGVyRmlsZShzdHJpbmcgZm4pOwoKbWFwcGluZyBtYXRlcmlhbHM7Cm1hcHBpbmcgbWF0ZXJpYWxfZ3JvdXBzOwpwcml2YXRlIHN0YXR1cyBpbml0aWFsaXplZDsKbWFwcGluZyBvbGRfbWF0X2tleXM7ICAgICAvLyBBbHRlciBNYXRlcmlhbGtleSAtPiBuZXVlciBLZXkgKEtvbXBhdGliaWxpdGFldCkKbm9zYXZlIG1hcHBpbmcgbmV3X21hdGVyaWFsczsgICAgICAgLy8gTWF0ZXJpYWxpZW4gd2FlaHJlbmQgZGVzIFNjYW5uZW5zCm5vc2F2ZSBtYXBwaW5nIG5ld19tYXRlcmlhbF9ncm91cHM7IC8vIE1hdGVyaWFsZ3J1cHBlbiB3YWVocmVuZCBkZXMgU2Nhbm5lbnMKcHJpdmF0ZSBub3NhdmUgc3RhdHVzIGlzU2Nhbm5pbmc7CnByaXZhdGUgbm9zYXZlIGludCB1cGRhdGVUaWNrczsKCnZvaWQgY3JlYXRlKCkgewogIHNldGV1aWQoZ2V0dWlkKCkpOwogIC8vIFNhdmVmaWxlIGVpbmxlc2VuLCBmYWxscyBtb2VnbGljaCwgZGFtaXQgZGllIERCIGRpcmVrdCBpbml0aWFsaXNlcnQgaXN0LAogIC8vIHdlbm4gYXVjaCBnZ2YuIG1pdCBhbHRlbiBEYXRlbi4KICByZXN0b3JlX29iamVjdChTQVZFRklMRSk7CiAgaWYgKGluaXRpYWxpemVkKSB7CiAgICAvLyBmYWxscyBlcmZvbGdyZWljaCwgZGlyZWt0IEhlYWRlciBmdWVyIGRpZSBNdWRsaWIgc2NocmVpYmVuCiAgICBHZW5IZWFkZXJGaWxlKCk7CiAgfQogIC8vIGpldHp0IFVwZGF0ZSBkZXIgRGF0ZW4gZHVyY2hmdWVocmVuLgogIFVwZGF0ZSgpOwp9CgovLz09PT09PT09PT09PT09PT09PT09IFVtd2FuZGVsbiBkZXIgU3RyaW5ncyBhdXMgZGVyIHRoaW5nL21hdGVyaWFsLmgKcHJpdmF0ZSBzdHJpbmcgZ2V0TWF0SWQoc3RyaW5nIGtleSkgewogIC8vIEFsdGUgQmV6ZWljaG5lciB1bXdhbmRlbG4KICBpZiAoIW1lbWJlcihtYXRlcmlhbHMsIGtleSkpCiAgICBrZXkgPSBvbGRfbWF0X2tleXNba2V5XTsKICByZXR1cm4ga2V5Owp9CnByaXZhdGUgc3RyaW5nIGdldE1hdEdyb3VwSWQoc3RyaW5nIGtleSkgewogIC8vIEFsdGUgQmV6ZWljaG5lciB1bXdhbmRlbG4KICBpZiAoIW1lbWJlcihtYXRlcmlhbF9ncm91cHMsIGtleSkpCiAgICBrZXkgPSAiTUFUR1JPVVBfIit1cHBlcnN0cmluZyhrZXlbMy4uXSk7CiAgcmV0dXJuIGtleTsKfQpwcml2YXRlIHN0cmluZyBtYXRLZXkyRGVmc3RyKHN0cmluZyBrZXksIG1hcHBpbmcgbWF0cykgewogIHN0cmluZyBpZDsKICBpZiAobWVtYmVyKG1hdHNba2V5XSwgUF9ERUZTVFIpKQogICAgaWQgPSBtYXRzW2tleV1bUF9ERUZTVFJdOwogIGVsc2UKICAgIGlkID0ga2V5OwogIHJldHVybiBpZDsKfQpwcml2YXRlIHN0cmluZyBncm91cEtleTJEZWZzdHIoc3RyaW5nIGtleSkgewogIGlmIChzaXplb2Yoa2V5KSA+IDkpCiAgICBrZXkgPSAibWdfIitsb3dlcnN0cmluZyhrZXlbOS4uXSk7CiAgZWxzZQogICAga2V5ID0gIiI7CiAgcmV0dXJuIGtleTsKfQoKLy89PT09PT09PT09PT09PT09PT09PSBTY2huaXR0c3RlbGxlbmZ1bmt0aW9uZW4genVyIFZlcndlbmR1bmcgZGVyIERCCnZhcmFyZ3Mgc3RyaW5nIE1hdGVyaWFsTmFtZShzdHJpbmcgbWF0LCBpbnQgY2FzdXMsIG1peGVkIGlkaW5mKSB7CiAgaWYgKGluaXRpYWxpemVkKSB7CiAgICBzdHJpbmcgKm5hbWVzOwogICAgbWFwcGluZyBwcm9wczsKICAgIG1peGVkICpkaWY7CiAgICAvLyBBbnBhc3NlbiBkZXIgTWF0ZXJpYWxpZAogICAgbWF0ID0gZ2V0TWF0SWQobWF0KTsKCiAgICBpZiAoIW1hcHBpbmdwKHByb3BzPW1hdGVyaWFsc1ttYXRdKSkKICAgICAgcHJvcHM9KFtdKTsKCiAgICAvLyBKZSBuYWNoIEtvZW5uZW4gZGVzIFNwaWVsZXJzIGthbm4gbWFuIGRhcyBleGFrdGUgTWF0ZXJpYWwKICAgIC8vIG1laHIgb2RlciB3ZW5pZ2VyIGd1dCBlcmtlbm5lbjoKICAgIGlmIChwb2ludGVycChkaWY9cHJvcHNbUF9SRUNPQ10pCiYmICghaW50cChpZGluZil8fGlkaW5mPDEwMCkgKSB7IC8vIDEwMD1leGFrdGUgRXJrZW5udW5nCiAgICAgIGludCBpLCBuLCByZWN2YWw7CiAgICAgIG1peGVkICpncnBzLCB0bXAsIHg7CgogICAgICByZWN2YWw9MDsKICAgICAgZ3Jwcz1wcm9wc1tQX01HX0ZSQUNUSU9OU107CiAgICAgIGlmICghcG9pbnRlcnAoaWRpbmYpKQogICAgICAgIGlkaW5mPSh7aWRpbmZ9KTsKCiAgICAgIC8vIFp1bmFlY2hzdCBkaWUgRmFlaGlna2VpdCBkZXMgU3BpZWxlcnMgKGRhIGtvZW5uZW4gbm9jaAogICAgICAvLyBHaWxkZW5mYWVoaWdrZWl0ZW4gaGluenUga29tbWVuKSBlcm1pdHRlbG4sIGRpZXNlcwogICAgICAvLyBNYXRlcmlhbCB6dSBlcmtlbm5lbjoKICAgICAgaT1zaXplb2YoaWRpbmYpOwogICAgICB3aGlsZShpLS0pIHsKICAgICAgICB0bXA9aWRpbmZbaV07CiAgICAgICAgaWYgKG9iamVjdHAodG1wKSkgLy8gRGllc2UgUHJvcGVydHkgaXN0IGhhdXB0c2FlY2hsaWNoIGZ1ZXIgUmFzc2VuOgogICAgICAgICAgdG1wPXRtcC0+UXVlcnlQcm9wKFBfTUFURVJJQUxfS05PV0xFREdFKTsKICAgICAgICBpZiAoaW50cCh0bXApKSB7CiAgICAgICAgICByZWN2YWwrPXRtcDsgLy8gQWxsZ2VtZWluZSBFcmtlbm51bmdzZmFlaGlna2VpdAogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGlmIChjbG9zdXJlcCh0bXApICYmIGludHAoeD1mdW5jYWxsKHRtcCxtYXQsZ3JwcykpKSB7CiAgICAgICAgICByZWN2YWwrPXg7CiAgICAgICAgICBicmVhazsgLy8gQ2xvc3VyZXMga29lbm5lbiBpbW1lciBudWV0emxpY2ggc2VpbiA6KQogICAgICAgIH0KICAgICAgICBpZiAobWFwcGluZ3AodG1wKSkgewogICAgICAgICAgaW50IGo7CiAgICAgICAgICBpZiAoKHg9dG1wW21hdF0pICYmIGludHAoeCkpewogICAgICAgICAgICAvLyBFcmtlbm51bmcgdm9uIHNwZXppZWxsIGRpZXNlbSBNYXRlcmlhbAogICAgICAgICAgICByZWN2YWwrPXg7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgLy8gRXJrZW5udW5nIHZvbiBHcnVwcGVuCiAgICAgICAgICBqPXNpemVvZihncnBzKTsKICAgICAgICAgIHdoaWxlKGotLSkKICAgICAgICAgICAgaWYoKHg9dG1wW2dycHNbal1dKSAmJiBpbnRwKHgpKQogICAgICAgICAgICAgIHJlY3ZhbCs9eDsKICAgICAgICAgIGlmIChwb2ludGVycCh0bXA9dG1wW01BVEVSSUFMX1NZTU1FVFJJQ19SRUNPR05JWkFCSUxJVFldKSkgewogICAgICAgICAgICBmb3IgKGo9c2l6ZW9mKHRtcCktMjtqPj0wO2otPTIpIHsKICAgICAgICAgICAgICBpZiAoIWludHAoeD10bXBbaisxXSkpCiAgICAgICAgICAgICAgICByYWlzZV9lcnJvcigibWF0ZXJpYWxkYjogaWxsZWdhbCBzeW0ucmVjb2MuIGZvcm1hdFxuIik7CiAgICAgICAgICAgICAgaWYgKHByb3BzW3RtcFtqXV0pCiAgICAgICAgICAgICAgICByZWN2YWwrPXg7CiAgICAgICAgICAgICAgZWxzZSAvLyBiZWkgcGFzc2VuZGVuIEdydXBwZW4gKywgYmVpIGFuZGVyZW4gLQogICAgICAgICAgICAgICAgcmVjdmFsLT14OwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CgogICAgICAvLyBKZXR6dCB3aXJkIGVybWl0dGVsdCwgb2IgdmllbGxlaWNodCBlaW5lIHVuZ2VuYXVlcmUKICAgICAgLy8gQmVzY2hyZWlidW5nIGdlZ2ViZW4gd2VyZGVuIHNvbGw6CiAgICAgIHg9ZGlmWzBdOwogICAgICBuID0gc2l6ZW9mKGRpZiktMTsKICAgICAgZm9yIChpPTI7aTw9bjtpKz0yKSB7CiAgICAgICAgaWYgKHJlY3ZhbD49ZGlmW2ktMV0pCiAgICAgICAgICB4PWRpZltpXTsKICAgICAgfQogICAgICAvLyBXZW5uIGRpZSBGYWVoaWdrZWl0ZW4gZGVzIFNwaWVsZXJzIG5pY2h0IGZ1ZXIgZGVuIGVjaHRlbiBLbGFybmFtZW4KICAgICAgLy8gYXVzcmVpY2hlbiwgZ2liIGRpZSBBbHRlcm5hdGl2ZSB6dXJ1ZWNrOgogICAgICBpZiAoeCE9bWF0KQogICAgICAgIHJldHVybiBNYXRlcmlhbE5hbWUoeCwgY2FzdXMsIDEwMCk7CiAgICB9CgogICAgaWYgKCFwb2ludGVycChuYW1lcz1wcm9wc1tQX05BTUVdKSB8fCBzaXplb2YobmFtZXMpPDQpCiAgICAgIG5hbWVzPSh7InVuYmVrYW5udGVzIE1hdGVyaWFsIiwgInVuYmVrYW5udGVuIE1hdGVyaWFscyIsCiAgICAgICAgICAgICAgInVuYmVrYW5udGVtIE1hdGVyaWFsIiwgInVuYmVrYW5udGVuIE1hdGVyaWFsIn0pOwogICAgaWYgKGNhc3VzPDAgfHwgY2FzdXM+MykKICAgICAgY2FzdXM9MDsKICAgIHJldHVybiBuYW1lc1tjYXN1c107CiAgfQp9Cgp2YXJhcmdzIHN0cmluZyBDb252TWF0ZXJpYWxMaXN0KG1peGVkIG1hdHMsIGludCBjYXN1cywgbWl4ZWQgaWRpbmYpIHsKICBpZiAoaW5pdGlhbGl6ZWQpIHsKICAgIHN0cmluZyAqbXMsbWw7CiAgICBpbnQgaTsKCiAgICBtbD0iIjsKICAgIGlmIChtYXBwaW5ncChtYXRzKSkKICAgICAgbXM9bV9pbmRpY2VzKG1hdHMpOwogICAgZWxzZSBpZiAoc3RyaW5ncChtYXRzKSkKICAgICAgbXM9KHttYXRzfSk7CiAgICBlbHNlIGlmIChwb2ludGVycChtYXRzKSkKICAgICAgbXM9bWF0czsKICAgIGVsc2UKICAgICAgbXM9KHt9KTsKICAgIGk9c2l6ZW9mKG1zKTsKICAgIHdoaWxlKGkpIHsKICAgICAgbWwrPU1hdGVyaWFsTmFtZShtc1stLWldLGNhc3VzLGlkaW5mKTsKICAgICAgaWYgKGkpCiAgICAgICAgbWwrPSgoaT4xKT8iLCAiOiIgdW5kICIpOwogICAgfQogICAgcmV0dXJuIG1sOwogIH0KfQoKaW50IE1hdGVyaWFsR3JvdXAobWFwcGluZyBtYXRzLCBzdHJpbmcgZ3JwKSB7CiAgIGlmIChpbml0aWFsaXplZCkgewogICAgIHN0cmluZyAqbXM7CiAgICAgaW50IGkscmVzOwoKICAgICByZXM9MDsKICAgICBpZiAoIW1hcHBpbmdwKG1hdHMpIHx8ICFzdHJpbmdwKGdycCkpCiAgICAgICByZXR1cm4gcmVzOwogICAgIG1zPW1faW5kaWNlcyhtYXRzKTsKICAgICBpPXNpemVvZihtcyk7CiAgICAgd2hpbGUoaS0tKSB7CiAgICAgICBzdHJpbmcgbWF0OwogICAgICAgbWFwcGluZyBwcm9wczsKICAgICAgIG1hdD1tc1tpXTsKICAgICAgIGlmIChtYXBwaW5ncChwcm9wcz1tYXRlcmlhbHNbZ2V0TWF0SWQobWF0KV0pKQogICAgICAgICByZXMrPShtYXRzW21hdF0qcHJvcHNbUF9NR19GUkFDVElPTlNdW2dldE1hdEdyb3VwSWQoZ3JwKV0pLzEwMDsKICAgICB9CiAgICAgaWYgKHJlczwtMTAwKSAvLyBWaWVsbGVpY2h0IG5vY2ggQW50aW1hdGVyaWUgenVsYXNzZW4KICAgICAgIHJlcz0tMTAwOyAgIC8vIChub2NoIG5pY2h0IHNpY2hlciBvYiBkYXMgc28gYmxlaWJlbiB3aXJkIG9kZXIgMCBzZWluIHdpcmQpCiAgICAgaWYgKHJlcz4xMDApCiAgICAgICByZXM9MTAwOwogICAgIHJldHVybiByZXM7CiAgIH0KfQoKc3RyaW5nICpBbGxNYXRlcmlhbHMoKSB7CiAgaWYgKGluaXRpYWxpemVkKSB7CiAgICAvLyBBdXMgS29tcGF0aWJpbGl0YWV0c2dydWVuZGVuIGRpZSBhbHRlbiBTY2hsdWVzc2VsICgjZGVmaW5lLVN0cmluZykKICAgIC8vIHp1cnVlY2tnZWJlbgogICAgcmV0dXJuIG1faW5kaWNlcyhvbGRfbWF0X2tleXMpOwogIH0KICByZXR1cm4gMDsKfQoKc3RyaW5nICpBbGxHcm91cHMoKSB7CiAgaWYgKGluaXRpYWxpemVkKSB7CiAgICAvLyBBdXMgS29tcGF0aWJpbGl0YWV0c2dydWVuZGVuIGRpZSBhbHRlbiBTY2hsdWVzc2VsICgjZGVmaW5lLVN0cmluZykKICAgIC8vIHp1cnVlY2tnZWJlbgogICAgcmV0dXJuIG1hcChtX2luZGljZXMobWF0ZXJpYWxfZ3JvdXBzKSwgIydncm91cEtleTJEZWZzdHIpOwogIH0KICByZXR1cm4gMDsKfQoKc3RyaW5nICpHZXRNYXRNZW1iZXJzaGlwKHN0cmluZyBtYXQpIHsKICBpZiAoaW5pdGlhbGl6ZWQpIHsKICAgIG1hcHBpbmcgcHJvcHM7CiAgICAvLyBBbnBhc3NlbiBkZXIgTWF0ZXJpYWxpZAogICAgbWF0ID0gZ2V0TWF0SWQobWF0KTsKCiAgICBpZiAoIW1hcHBpbmdwKHByb3BzPW1hdGVyaWFsc1ttYXRdKSkKICAgICAgcmV0dXJuICh7fSk7CiAgICByZXR1cm4gbWFwKG1faW5kaWNlcyhwcm9wc1tQX01HX0ZSQUNUSU9OU10pLCAjJ2dyb3VwS2V5MkRlZnN0cik7CiAgfQogIHJldHVybiAwOwp9CgpzdHJpbmcgKkdldEdyb3VwTWVtYmVycyhzdHJpbmcgZ3JwKSB7CiAgaWYgKGluaXRpYWxpemVkKSB7CiAgICBzdHJpbmcgKm1hdHM7CiAgICAvLyBBbnBhc3NlbiBkZXIgTWF0ZXJpYWxpZAogICAgZ3JwID0gZ2V0TWF0R3JvdXBJZChncnApOwogICAgaWYgKCFtZW1iZXIobWF0ZXJpYWxfZ3JvdXBzLCBncnApIHx8CgkhcG9pbnRlcnAobWF0cz1tYXRlcmlhbF9ncm91cHNbZ3JwXVtQX01FTUJFUlNdKSkKICAgICAgcmV0dXJuICh7fSk7CiAgICByZXR1cm4gbWFwKG1hdHMsICMnbWF0S2V5MkRlZnN0ciwgbWF0ZXJpYWxzKTsKICB9CiAgcmV0dXJuIDA7Cn0KCnN0cmluZyBHcm91cE5hbWUoc3RyaW5nIGdycCkgewogIGlmIChpbml0aWFsaXplZCkgewogICAgaWYgKG1lbWJlcihtYXRlcmlhbF9ncm91cHMsIGdldE1hdEdyb3VwSWQoZ3JwKSkpCiAgICAgIHJldHVybiBtYXRlcmlhbF9ncm91cHNbZ2V0TWF0R3JvdXBJZChncnApXVtQX05BTUVdOwogICAgZWxzZQogICAgICByZXR1cm4gIlVuYmVrYW5udGVzIjsKICB9Cn0KCnN0cmluZyBHcm91cERlc2NyaXB0aW9uKHN0cmluZyBncnApIHsKICBpZiAoaW5pdGlhbGl6ZWQpIHsKICAgIGlmIChtZW1iZXIobWF0ZXJpYWxfZ3JvdXBzLCBnZXRNYXRHcm91cElkKGdycCkpKQogICAgICByZXR1cm4gbWF0ZXJpYWxfZ3JvdXBzW2dldE1hdEdyb3VwSWQoZ3JwKV1bUF9ERVNDUklQVElPTl07CiAgICBlbHNlCiAgICAgIHJldHVybiAiR3J1cHBlIHVuYmVrYW5udCI7CiAgfQp9CgovLz09PT09PT09PT09PT09PT09PT09IEdlbmVyaWVyZW4gdm9uIEhlYWRlcmZpbGUgdW5kIE1hbnBhZ2VzCnByaXZhdGUgc3RyaW5nICpnZXRfb3JkZXJlZF9ncm91cHMoKQp7CiAgcmV0dXJuICh7Ik1BVEdST1VQX1dPT0QiLCAiTUFUR1JPVVBfSkVXRUwiLCAiTUFUR1JPVVBfU1RPTkUiLCAiTUFUR1JPVVBfTUFHTkVUSUMiLAogICAgICAgICAgICJNQVRHUk9VUF9NRVRBTCIsICJNQVRHUk9VUF9EUlVHIiwgIk1BVEdST1VQX0hFUkJBTCIsICJNQVRHUk9VUF9GTEVYSUJMRSIsCiAgICAgICAgICAgIk1BVEdST1VQX0JJTyIsICJNQVRHUk9VUF9BQ0lESUMiLCAiTUFUR1JPVVBfQkFTSUMiLCAiTUFUR1JPVVBfUE9JU09OT1VTIiwKICAgICAgICAgICAiTUFUR1JPVVBfRVhQTE9TSVZFIiwgIk1BVEdST1VQX0lORkxBTU1BQkxFIiwKICAgICAgICAgICAiTUFUR1JPVVBfRUxFTUVOVEFMIiwgIk1BVEdST1VQX0VMRUNUUklDQUwiLCAiTUFUR1JPVVBfTUFHSUMiLAogICAgICAgICAgICJNQVRHUk9VUF9IT0xZIiwgIk1BVEdST1VQX1VOSE9MWSIsICJNQVRHUk9VUF9JTlZJUyIsCiAgICAgICAgICAgIk1BVEdST1VQX1NPTElEIiwgIk1BVEdST1VQX0ZMVUlEIiwgIk1BVEdST1VQX0dBUyJ9KTsKfQpwcml2YXRlIHN0cmluZyBnZW5fbWF0ZXJpYWxfaF9oZWFkKCkKewogIHJldHVybgogICAgIi8vIE1vcmdlbkdyYXVlbiBNVURsaWJcbi8vXG4iCiAgICAiLy8gbWF0ZXJpYWxzLmggLS0gbWF0ZXJpYWwgZGVmaW5pdGlvbnNcbi8vXG4iCiAgICAiLy8gVGhpcyBmaWxlIGlzIGdlbmVyYXRlZCBieSAvc2VjdXJlL21hdGVyaWFsZGIuY1xuLy9cbiIKICAgICIvLyBETyBOT1QgRURJVCFcbi8vXG4iCiAgICAiLy8gJElkOiBtYXRlcmlhbGRiLmMgODc1NSAyMDE0LTA0LTI2IDEzOjEzOjQwWiBaZXNzdHJhICRcblxuIgogICAgIiNpZm5kZWYgX19NQVRFUklBTFNfSF9fXG4iCiAgICAiI2RlZmluZSBfX01BVEVSSUFMU19IX19cblxuIjsKfQpwcml2YXRlIHN0cmluZyBnZW5fbWF0ZXJpYWxfaF9tYXRlcmlhbChzdHJpbmcgbWF0LCBzdHJpbmcgbGFzdF9ncnApCnsKICBtYXQgPSBvbGRfbWF0X2tleXNbbWF0XTsKICByZXR1cm4gc3ByaW50ZigiI2RlZmluZSAlLTI0c1wiJS0yMHMgLy8gJXNcbiIsIG1hdCwKICAgICAgICAgICAgICAgIChtZW1iZXIobWF0ZXJpYWxzW21hdF0sIFBfREVGU1RSKT9tYXRlcmlhbHNbbWF0XVtQX0RFRlNUUl06bWF0KSsiXCIiLAogICAgICAgICAgICAgICAgbWF0ZXJpYWxzW21hdF1bUF9ERVNDUklQVElPTl18fG1hdGVyaWFsc1ttYXRdW1BfTkFNRV1bV0VSXSk7Cn0KcHJpdmF0ZSBzdHJpbmcgZ2VuX21hdGVyaWFsX2hfbWF0ZXJpYWxzX2dycChzdHJpbmcgZ3JwLCBzdHJpbmcgKmxlZnQpCnsKICBzdHJpbmcgdHh0LCAqbWF0czsKICB0eHQgPSBzcHJpbnRmKCJcbi8vIEdydXBwZTogJXNcbiIsIEdyb3VwTmFtZShncnApKTsKICBtYXRzID0gR2V0R3JvdXBNZW1iZXJzKGdycCkgLSAoR2V0R3JvdXBNZW1iZXJzKGdycCkgLSBsZWZ0KTsKICB0eHQgKz0gc3ByaW50ZigiJUBzIiwgbWFwKHNvcnRfYXJyYXkobWF0cywgIyc+KSwgIydnZW5fbWF0ZXJpYWxfaF9tYXRlcmlhbCkpOwogIGxlZnQgLT0gR2V0R3JvdXBNZW1iZXJzKGdycCk7CiAgcmV0dXJuIHR4dDsKfQpwcml2YXRlIHN0cmluZyBnZW5fbWF0ZXJpYWxfaF9tYXRlcmlhbHMoKQp7CiAgc3RyaW5nIHR4dCwgbGFzdF9ncnA7CiAgc3RyaW5nICpncnBzLCAqbWF0czsKICB0eHQgPSAiLy8gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqIE1hdGVyaWFsaWVuICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuIjsKICAvLyBHcnVwcGVud2Vpc2Ugb3JkbmVuCiAgZ3JwcyA9IGdldF9vcmRlcmVkX2dyb3VwcygpOwogIG1hdHMgPSBBbGxNYXRlcmlhbHMoKTsKICB0eHQgKz0gc3ByaW50ZigiJUBzIiwgbWFwKGdycHMsICMnZ2VuX21hdGVyaWFsX2hfbWF0ZXJpYWxzX2dycCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZtYXRzKSk7CiAgLy8g3GJyaWdnZWJsaWVuZSBNYXRlcmlhbGllbiBhdXNnZWJlbgogIHR4dCArPSAiLy8gc29uc3RpZ2UgTWF0ZXJpYWxpZW46XG4iOwogIHR4dCArPSBzcHJpbnRmKCIlQHMiLCBtYXAobWF0cywgIydnZW5fbWF0ZXJpYWxfaF9tYXRlcmlhbCkpOwogIHJldHVybiB0eHQ7Cn0KcHJpdmF0ZSBzdHJpbmcgZ2VuX21hdGVyaWFsX2hfZ3JvdXAoc3RyaW5nIGdycCkKewogIHJldHVybiBzcHJpbnRmKCIjZGVmaW5lICUtMjdzXCIlLTE4cyAvLyAlc1xuIiwKICAgICAgICAgICAgICAgICBncnAsIGdyb3VwS2V5MkRlZnN0cihncnApKyJcIiIsIEdyb3VwTmFtZShncnApKTsKfQpwcml2YXRlIHN0cmluZyBnZW5fbWF0ZXJpYWxfaF9ncm91cHMoKQp7CiAgc3RyaW5nIHR4dDsKICB0eHQgPSAiXG4vLyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqIE1hdGVyaWFsZ3J1cHBlbiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG5cbiIKICAgICIjaWZuZGVmIF9JU19NQVRFUklBTERCX1xuIjsKICB0eHQgKz0gc3ByaW50ZigiJUBzXG4iLCBtYXAoc29ydF9hcnJheShtX2luZGljZXMobWF0ZXJpYWxfZ3JvdXBzKSwgIyc+KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIydnZW5fbWF0ZXJpYWxfaF9ncm91cCkpOwogIHR4dCArPSAiXG4jZW5kaWYgLy8gX0lTX01BVEVSSUFMREJfXG4iOwogIHJldHVybiB0eHQ7Cn0KcHJpdmF0ZSBzdHJpbmcgZ2VuX21hdGVyaWFsX2hfZm9vdCgpCnsKICByZXR1cm4KICAgICIjZW5kaWYgLy8gX19USElOR19NQVRFUklBTF9IX19cbiI7Cn0KcHJpdmF0ZSBpbnQgZHVtcF9tYXRlcmlhbF9oKHN0cmluZyBmbikKewogIHJldHVybiAod3JpdGVfZmlsZShmbiwgZ2VuX21hdGVyaWFsX2hfaGVhZCgpKSAmJgogICAgICAgICAgd3JpdGVfZmlsZShmbiwgZ2VuX21hdGVyaWFsX2hfbWF0ZXJpYWxzKCkpICYmCiAgICAgICAgICB3cml0ZV9maWxlKGZuLCBnZW5fbWF0ZXJpYWxfaF9ncm91cHMoKSkgJiYKICAgICAgICAgIHdyaXRlX2ZpbGUoZm4sIGdlbl9tYXRlcmlhbF9oX2Zvb3QoKSkpOwp9CnByaXZhdGUgc3RyaW5nIGdlbl9tYXRlcmlhbF9saXN0X21hdGVyaWFsKHN0cmluZyBtYXQpCnsKICBtYXQgPSBvbGRfbWF0X2tleXNbbWF0XTsKICByZXR1cm4gc3ByaW50ZigiICAlLTI4cyU9LTQ1c1xuIiwgbWF0LAogICAgICAgICAgICAgICAgIG1hdGVyaWFsc1ttYXRdW1BfREVTQ1JJUFRJT05dfHxtYXRlcmlhbHNbbWF0XVtQX05BTUVdW1dFUl0pOwp9CnByaXZhdGUgc3RyaW5nIGdlbl9tYXRlcmlhbF9saXN0X21hdGVyaWFsc19ncnAoc3RyaW5nIGdycCwgc3RyaW5nICpsZWZ0KQp7CiAgc3RyaW5nIHR4dCwgKm1hdHM7CiAgdHh0ID0gc3ByaW50ZigiJXM6XG4iLCBjYXBpdGFsaXplKEdyb3VwTmFtZShncnApKSk7CiAgbWF0cyA9IHNvcnRfYXJyYXkoR2V0R3JvdXBNZW1iZXJzKGdycCkgLSAoR2V0R3JvdXBNZW1iZXJzKGdycCkgLSBsZWZ0KSwgIyc+KTsKICB0eHQgKz0gc3ByaW50ZigiJUBzXG4iLCBtYXAobWF0cywgIydnZW5fbWF0ZXJpYWxfbGlzdF9tYXRlcmlhbCkpOwogIGxlZnQgLT0gR2V0R3JvdXBNZW1iZXJzKGdycCk7CiAgcmV0dXJuIHR4dDsKfQpwcml2YXRlIHZvaWQgZHVtcF9tYXRlcmlhbChzdHJpbmcgZm4pCnsKICBzdHJpbmcgdHh0OwogIHN0cmluZyAqZ3JwcywgKm1hdHM7CiAgLy8gR3J1cHBlbndlaXNlIG9yZG5lbgogIGdycHMgPSBnZXRfb3JkZXJlZF9ncm91cHMoKTsKICBtYXRzID0gQWxsTWF0ZXJpYWxzKCk7CiAgdHh0ID0gc3ByaW50ZigiJUBzIiwgbWFwKGdycHMsICMnZ2VuX21hdGVyaWFsX2xpc3RfbWF0ZXJpYWxzX2dycCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJm1hdHMpKTsKICAvLyDcYnJpZ2dlYmxpZW5lIE1hdGVyaWFsaWVuIGF1c2dlYmVuCiAgdHh0ICs9ICJzb25zdGlnZSBNYXRlcmlhbGllbjpcbiI7CiAgdHh0ICs9IHNwcmludGYoIiVAcyIsIG1hcChtYXRzLCAjJ2dlbl9tYXRlcmlhbF9saXN0X21hdGVyaWFsKSk7CiAgd3JpdGVfZmlsZShmbiwgdHh0KSB8fAogICAgcmFpc2VfZXJyb3Ioc3ByaW50ZigiS29ubnRlIExpc3RlIG5pY2h0IHdlaXRlciBpbiBEYXRlaSAlcyBzY2hyZWliZW4sIgogICAgICAgICAgICAgICAgICAgICAgICAiIEFiYnJ1Y2hcbiIsIGZuKSk7Cn0KcHJpdmF0ZSB2b2lkIGR1bXBfZ3JvdXAoc3RyaW5nIGdycCwgc3RyaW5nIGZuKQp7CiAgLy8gdXBwZXJzdHJpbmcgbGFuZ3NhbWUgc2ltdWxfZWZ1biwgd2FydW0/CiAgd3JpdGVfZmlsZShmbiwgc3ByaW50ZigiICAlLTI4cyU9LTQ4c1xuIiwgKGdycCksCiAgICAgICAgICAgICAgICAgICAgICAgICBHcm91cE5hbWUoZ3JwKSkpIHx8CiAgICByYWlzZV9lcnJvcihzcHJpbnRmKCJLb25udGUgTGlzdGUgbmljaHQgd2VpdGVyIGluIERhdGVpICVzIHNjaHJlaWJlbiwiCiAgICAgICAgICAgICAgICAgICAgICAgICIgQWJicnVjaFxuIiwgZm4pKTsKfQpwcml2YXRlIHN0cmluZyBnZW5fZG9jX2Zvb3Qoc3RyaW5nIG90aGVyKQp7CiAgcmV0dXJuIHNwcmludGYoIlxuU0lFSEUgQVVDSDpcbiIKICAgICAgICAgICAgICAgICAiICAgICBLb256ZXB0ZTogICAgbWF0ZXJpYWwsIG1hdGVyaWFsZXJrZW5udW5nXG4iCiAgICAgICAgICAgICAgICAgIiAgICAgR3J1bmRsZWdlbmQ6IFBfTUFURVJJQUwsIC9zeXMvbWF0ZXJpYWxzLmgsIC9zeXMvdGhpbmcvbWF0ZXJpYWwuaFxuIgogICAgICAgICAgICAgICAgICIgICAgIE1ldGhvZGVuOiAgICBRdWVyeU1hdGVyaWFsKCksIFF1ZXJ5TWF0ZXJpYWxHcm91cCgpLCBNYXRlcmlhbExpc3QoKSxcbiIKICAgICAgICAgICAgICAgICAiICAgICBMaXN0ZW46ICAgICAgQWxsTWF0ZXJpYWxzKCksIEFsbEdyb3VwcygpXG4iCiAgICAgICAgICAgICAgICAgIiAgICAgICAgICAgICAgICAgICVzXG4iCiAgICAgICAgICAgICAgICAgIiAgICAgTWFzdGVyOiAgICAgIENvbnZNYXRlcmlhbExpc3QoKSwgTWF0ZXJpYWxHcm91cCgpLFxuIgogICAgICAgICAgICAgICAgICIgICAgICAgICAgICAgICAgICBHcm91cE5hbWUoKSwgTWF0ZXJpYWxOYW1lKCksXG4iCiAgICAgICAgICAgICAgICAgIiAgICAgICAgICAgICAgICAgIEdldEdyb3VwTWVtYmVycygpLCBHZXRNYXRNZW1iZXJzaGlwKClcbiIKICAgICAgICAgICAgICAgICAiICAgICBTb25zdGlnZXM6ICAgUF9NQVRFUklBTF9LTk9XTEVER0VcblxuIgogICAgICAgICAgICAgICAgICIlcyBnZW5lcmllcnQgYXVzIC9zZWN1cmUvbWF0ZXJpYWxkYlxuIiwgb3RoZXIsIGR0aW1lKHRpbWUoKSkpOwp9CgovKiBHZW5NYXRMaXN0CiAqCiAqIEdlbmVyaWVydCBEYXRlaSBtaXQgcmVnaXN0cmllcnRlbiBNYXRlcmlhbGllbiBmdWVyIGRpZSBEb2t1bWVudGF0aW9uLAogKi8KdmFyYXJncyB2b2lkIEdlbk1hdExpc3Qoc3RyaW5nIGZuKQp7CiAgaWYgKGluaXRpYWxpemVkKSB7CiAgICBzdHJpbmcgdHh0OwogICAgaWYgKCFzdHJpbmdwKGZuKSB8fCAhc2l6ZW9mKGZuKSkKICAgICAgZm4gPSBET0NfRElSKCJtYXRlcmlhbGxpc3RlIik7CiAgICBpZiAoZmlsZV9zaXplKGZuKSA+PSAwKSB7CiAgICAgIHByaW50ZigiRGF0ZWkgJXMgZXhpc3RpZXJ0IGJlcmVpdHMsIGxvZXNjaGUgc2llXG4iLCBmbik7CiAgICAgIHJtKGZuKTsKICAgIH0KICAgIGlmICh3cml0ZV9maWxlKGZuLCAiTWF0ZXJpYWwgTGlzdGVcbj09PT09PT09PT09PT09XG5cbiIpKSB7CiAgICAgIGR1bXBfbWF0ZXJpYWwoZm4pOwogICAgICB3cml0ZV9maWxlKGZuLCBnZW5fZG9jX2Zvb3QoIm1hdGVyaWFsZ3J1cHBlbiIpKTsKICAgICAgcHJpbnRmKCJNYXRlcmlhbGxpc3RlIGVyZm9sZ3JlaWNoIGluIERhdGVpICVzIGdlc2NocmllYmVuXG4iLCBmbik7CiAgICB9IGVsc2UKICAgICAgcHJpbnRmKCJLb25udGUgTGlzdGUgbmljaHQgaW4gRGF0ZWkgJXMgc2NocmVpYmVuLCBBYmJydWNoXG4iLCBmbik7CiAgfQp9CgovKiBHZW5NYXRHcm91cExpc3QKICoKICogR2VuZXJpZXJ0IERhdGVpIG1pdCByZWdpc3RyaWVydGVuIE1hdGVyaWFsZ3J1cHBlbiBmdWVyIGRpZSBEb2t1bWVudGF0aW9uLAogKi8KdmFyYXJncyB2b2lkIEdlbk1hdEdyb3VwTGlzdChzdHJpbmcgZm4pCnsKICBpZiAoaW5pdGlhbGl6ZWQpIHsKICAgIHN0cmluZyB0eHQ7CiAgICBpZiAoIXN0cmluZ3AoZm4pIHx8ICFzaXplb2YoZm4pKQogICAgICBmbiA9IERPQ19ESVIoIm1hdGVyaWFsZ3J1cHBlbiIpOwogICAgaWYgKGZpbGVfc2l6ZShmbikgPj0gMCkgewogICAgICBwcmludGYoIkRhdGVpICVzIGV4aXN0aWVydCBiZXJlaXRzLCBsb2VzY2hlIHNpZVxuIiwgZm4pOwogICAgICBybShmbik7CiAgICB9CiAgICBpZiAod3JpdGVfZmlsZShmbiwgIk1hdGVyaWFsZ3J1cHBlblxuPT09PT09PT09PT09PT09XG4iKSkgewogICAgICBtYXAoc29ydF9hcnJheShtX2luZGljZXMobWF0ZXJpYWxfZ3JvdXBzKSwgIyc+KSwgIydkdW1wX2dyb3VwLCBmbik7CiAgICAgIHdyaXRlX2ZpbGUoZm4sIGdlbl9kb2NfZm9vdCgibWF0ZXJpYWxsaXN0ZSIpKTsKICAgICAgcHJpbnRmKCJNYXRlcmlhbGxpc3RlIGVyZm9sZ3JlaWNoIGluIERhdGVpICVzIGdlc2NocmllYmVuXG4iLCBmbik7CiAgICB9IGVsc2UKICAgICAgcHJpbnRmKCJLb25udGUgTGlzdGUgbmljaHQgaW4gRGF0ZWkgJXMgc2NocmVpYmVuLCBBYmJydWNoXG4iLCBmbik7CiAgfQp9CgovKiBHZW5IZWFkZXJGaWxlCiAqCiAqIEdlbmVyaWVydCBIZWFkZXJmaWxlIG1pdCBEZWZpbml0aW9uZW4gZGVyIG1vZWdsaWNoZW4gTWF0ZXJpYWxpZW4gdW5kCiAqIEdydXBwZW4KICovCnZhcmFyZ3Mgdm9pZCBHZW5IZWFkZXJGaWxlKHN0cmluZyBmbikKewogIGlmIChpbml0aWFsaXplZCkgewogICAgc3RyaW5nIHR4dDsKICAgIGlmICghc3RyaW5ncChmbikgfHwgIXNpemVvZihmbikpCiAgICAgIGZuID0gSEVBREVSRklMRTsKICAgIGlmIChmaWxlX3NpemUoZm4pID49IDApIHsKICAgICAgcHJpbnRmKCJEYXRlaSAlcyBleGlzdGllcnQgYmVyZWl0cywgbG9lc2NoZSBzaWVcbiIsIGZuKTsKICAgICAgcm0oZm4pOwogICAgfQogICAgaWYgKGR1bXBfbWF0ZXJpYWxfaChmbikpCiAgICAgIHByaW50ZigiSGVhZGVyZGF0ZWkgZXJmb2xncmVpY2ggaW4gJXMgZ2VzY2hyaWViZW5cbiIsIGZuKTsKICAgIGVsc2UKICAgICAgcHJpbnRmKCJLb25udGUgSGVhZGVyZGF0ZWkgbmljaHQgaW4gRGF0ZWkgJXMgc2NocmVpYmVuLCBBYmJydWNoXG4iLCBmbik7CiAgfQp9CgovLz09PT09PT09PT09PT09PT09PT09IFBydWVmLSB1bmQgSGlsZnNmdW5rdGlvbmVuIGZ1ZXIgTWF0ZXJpYWxpZW4KcHJpdmF0ZSB2b2lkIHVwZGF0ZUdyb3VwTWVtYmVycyhtYXBwaW5nIGdyb3Vwcywgc3RyaW5nIG1hdF9pZCwgbWFwcGluZyBtYXQpIHsKICBtaXhlZCAqYWRkZ3JwczsgLy8gQXJyYXkgenVtIEFibGVpdGVuIHZvbiBHcnVwcGVuenVnZWhvZXJpZ2tlaXRlbgogIHN0cmluZyAqaDsKICBpbnQgaSwgdmFsOwogIG1hcHBpbmcgZnJhY3Rpb25zOyAvLyBNYXBwaW5nIG1pdCBBbnRlaWxlbiBhbiBHcnVwcGVuCiAgZnJhY3Rpb25zID0gbWF0W1BfTUdfRlJBQ1RJT05TXTsKICBpZiAoIW1hcHBpbmdwKGZyYWN0aW9ucykpCiAgICBmcmFjdGlvbnMgPSAoW10pOwogIGFkZGdycHM9KHsgLy8gUmVpaGVuZm9sZ2Ugd2lyZCBydWVja3dhZXJ0cyBhYmdlYXJiZWl0ZXQKICAgIC8vIEFibGVpdHVuZ2VuIHNpbmQgei5ULiBhYmVudGV1ZXJsaWNoIGdld2VzZW4sIG1hbCBvcmRlbnRsaWNoCiAgICAvLyBhdXNtaXN0ZW4uIERpZSBadWdlaG9lcmlna2VpdCBnZWhvZXJ0IGV4cGxpeml0IGluIGRpZQogICAgLy8gTWF0ZXJpYWxkZWZpbml0aW9uCiAgICAvLyBHYXNlIHNpZWh0IG1hbiBub3JtYWxlcndlaXNlIG5pY2h0OgogICAgKHsiTUFUR1JPVVBfSU5WSVMiLCAiTUFUR1JPVVBfR0FTIn0pLAogICAgLy8gTWluZXJhbGllbiBzaW5kIGF1Y2ggU3RlaW5lCiAgICAoeyJNQVRHUk9VUF9TVE9ORSIsIk1BVEdST1VQX01JTkVSQUwifSksCiAgICAvLyBFZGVsbWV0YWxsZSBzaW5kIE1ldGFsbGU6CiAgICAoeyJNQVRHUk9VUF9NRVRBTCIsIk1BVEdST1VQX1BSRUNJT1VTX01FVEFMIn0pLAogICAgLy8gTGViZXdlc2VuIHVuZCBkZXJlbiBVZWJlcnJlc3RlLCBQYWllcmUgdW5kIFN0b2ZmZSBzaW5kIGJpb2xvZ2lzY2gKICAgICh7Ik1BVEdST1VQX0JJTyIsIk1BVEdST1VQX0xJVklORyIsIk1BVEdST1VQX0RFQUQiLAogICAgICAiTUFUR1JPVVBfUEFQRVIifSksCiAgICAvLyBIb2x6IGlzdCBwZmxhbnpsaWNoOgogICAgKHsiTUFUR1JPVVBfSEVSQkFMIiwgIk1BVEdST1VQX1dPT0QifSksCiAgICAvLyBIb2x6IGlzdCBtZWlzdGVucyB0b3Q6CiAgICAoeyJNQVRHUk9VUF9ERUFEIiwiTUFUR1JPVVBfV09PRCJ9KSwKICAgIC8vIEhvbHosIFBhcGllciB1bmQgU3RvZmZlIGJyZW5uZW46CiAgICAoeyJNQVRHUk9VUF9JTkZMQU1NQUJMRSIsIk1BVEdST1VQX1dPT0QiLCJNQVRHUk9VUF9QQVBFUiJ9KSwKICAgIC8vIExhdWJob2VsemVyLCBOYWRlbGhvZWx6ZXIgdW5kIFRyb3BlbmhvZWx6ZXIgc2luZCBIb2x6CiAgICAoeyJNQVRHUk9VUF9XT09EIiwiTUFUR1JPVVBfVFJPUElDQUxfV09PRCIsIk1BVEdST1VQX0RFQ0lEVU9VU19XT09EIiwKICAgICAgIk1BVEdST1VQX0NPTklGRVJfV09PRCJ9KSwKICAgIC8vIEV4cGxvc2l2ZSBEaW5nZSBzaW5kIGltbWVyIGVudHp1ZW5kbGljaDoKICAgICh7Ik1BVEdST1VQX0lORkxBTU1BQkxFIiwiTUFUR1JPVVBfRVhQTE9TSVZFIn0pCiAgfSk7CiAgaT1zaXplb2YoYWRkZ3Jwcyk7CiAgd2hpbGUoaS0tKSB7CiAgICBpbnQgajsKICAgIGg9YWRkZ3Jwc1tpXTsKICAgIGlmIChtZW1iZXIoZnJhY3Rpb25zLGhbMF0pKSAvLyBFeGlzdGllcnQgc2Nob24gZWlnZW5lciBFaW50cmFnPwogICAgICBjb250aW51ZTsgLy8gQXV0b21hdGlzY2hlIEVpbnRyYWd1bmcgdW5ub2V0aWcKICAgIHZhbD0wOwogICAgZm9yIChqPXNpemVvZihoKS0xO2o+PTE7ai0tKQogICAgICB2YWwrPWZyYWN0aW9uc1toW2pdXTsKICAgIGlmICghdmFsKQogICAgICBjb250aW51ZTsKICAgIGlmICh2YWw+MTAwKQogICAgICB2YWw9MTAwOwogICAgZWxzZSBpZiAodmFsPC0xMDApCiAgICAgIHZhbD0tMTAwOwogICAgZnJhY3Rpb25zW2hbMF1dPXZhbDsKICB9CiAgaWYgKGZyYWN0aW9uc1siTUFUR1JPVVBfTElWSU5HIl0pIC8vIEltIEZhbGxlIHZvbiBsZWJlbmRlbSBIb2x6LCB0b3QgbG9lc2NoZW4KICAgIG1fZGVsZXRlKGZyYWN0aW9ucywiTUFUR1JPVVBfREVBRCIpOwogIC8vIEFsbGVzLCB3YXMgbmljaHQgYWxzIGdhc2ZvZXJtaW5nLCBmbHVlc3NpZyBvZGVyIGZlc3QgZWluZ2VvcmRuZXQgaXN0LCBpc3QKICAvLyBzb25zdHdhczoKICBpZiAoIW1lbWJlcihmcmFjdGlvbnMsICJNQVRHUk9VUF9GTFVJRCIpCiAgICAgICYmICFtZW1iZXIoZnJhY3Rpb25zLCAiTUFUR1JPVVBfR0FTIikKICAgICAgJiYgIW1lbWJlcihmcmFjdGlvbnMsICJNQVRHUk9VUF9TT0xJRCIpKQogICAgZnJhY3Rpb25zWyJNQVRHUk9VUF9NSVNDIl09MTAwOwogIC8vIE1hdGVyaWFsaWVuIGFscyBNaXRnbGllZGVyIGluIGRpZSBHcnVwcGVuIGVpbnRyYWdlbgogIGFkZGdycHM9bV9pbmRpY2VzKGZyYWN0aW9ucyk7CiAgaT1zaXplb2YoYWRkZ3Jwcyk7CiAgd2hpbGUoaS0tKSB7CiAgICBtaXhlZCBpbmQ7CiAgICBpbmQ9YWRkZ3Jwc1tpXTsKICAgIGlmICghZnJhY3Rpb25zW2luZF0gfHwgIW1lbWJlcihncm91cHMsIGluZCkpIHsKICAgICAgLy8gVW5iZWthbm50ZSBHcnVwcGUgdW5kIEdydXBwZSBvaG5lIEFudGVpbCBhdXMgTWFwcGluZyBsb2VzY2hlbgogICAgICBtX2RlbGV0ZShmcmFjdGlvbnMsaW5kKTsKICAgICAgY29udGludWU7CiAgICB9CiAgICBpZiAoIXBvaW50ZXJwKGg9Z3JvdXBzW2luZF1bUF9NRU1CRVJTXSkpCiAgICAgIGg9KHt9KTsKICAgIGgrPSh7bWF0X2lkfSk7CiAgICBncm91cHNbaW5kXVtQX01FTUJFUlNdPWg7CiAgfQogIG1hdFtQX01HX0ZSQUNUSU9OU10gPSBmcmFjdGlvbnM7Cn0KCi8vPT09PT09PT09PT09PT09PT09PT0gRWlubGVzZW4gZGVyIE1hcHBpbmdzIGF1cyBEYXRlaWVuCgojZGVmaW5lIE1ERVNDX0VSUk9SKHgsIHkpIExPR19FUlJPUihzcHJpbnRmKCJNYXRlcmlhbGJlc2NocmVpYnVuZyAnJXMnOiAlc1xuIiwgeCwgeSkpCiNkZWZpbmUgTURFU0NfV0FSTih4LCB5KSAvL0xPR19XQVJOKHNwcmludGYoIk1hdGVyaWFsYmVzY2hyZWlidW5nICclcyc6ICVzXG4iLCB4LCB5KSkKCnByaXZhdGUgbWFwcGluZyBnZXREZXNjUGFydHMoc3RyaW5nIHMpIHsKICBzdHJpbmcqIGxpbmVzOwogIHN0cmluZyBrZXksIHZhbDsKICBpbnQgaSwgbjsKICBtYXBwaW5nIG07CiAgbSA9IChbXSk7CiAgdmFsID0gIiI7CiAgbGluZXMgPSBleHBsb2RlKHMsICJcbiIpOwogIG4gPSBzaXplb2YobGluZXMpOwogIGlmIChuID4gMCkgewogICAgd2hpbGUgKGkgPCBuKSB7CiAgICAgIGlmIChzc2NhbmYobGluZXNbaV0sICIlczoiLCBrZXkpKSB7CiAgICAgICAgc3RhdHVzIG11bHRpbGluZTsKICAgICAgICBtdWx0aWxpbmUgPSAwOwogICAgICAgIC8vIFNjaGx1ZXNzZWwgZ2VmdW5kZW4sIFdlcnQgYXVzbGVzZW4KICAgICAgICB3aGlsZSAoICgrK2kgPCBuKSAmJiBzaXplb2YobGluZXNbaV0pKSB7CiAgICAgICAgICAvLyBNZWhyemVpbGlnZSBXZXJ0ZSBtaXQgbmV3bGluZSB2ZXJrZXR0ZW4KICAgICAgICAgIGlmIChtdWx0aWxpbmUpIHsKICAgICAgICAgICAgdmFsICs9ICJcbiI7CiAgICAgICAgICB9CiAgICAgICAgICB2YWwgKz0gbGluZXNbaV07CiAgICAgICAgICBtdWx0aWxpbmUgPSAxOwogICAgICAgIH0KICAgICAgICBtICs9IChba2V5OnZhbF0pOwogICAgICAgIHZhbCA9ICIiOwogICAgICB9CiAgICAgIGkrKzsKICAgIH0KICB9CiAgcmV0dXJuIG07Cn0KcHJpdmF0ZSB2YXJhcmdzIGludCBpc0ZpbGUoc3RyaW5nIGZuLCBzdHJpbmcgcGF0aCkgewogIGlmIChzdHJpbmdwKHBhdGgpICYmIHNpemVvZihwYXRoKSkKICAgIGZuID0gcGF0aCsiLyIrZm47CiAgcmV0dXJuIChmaWxlX3NpemUoZm4pID49IDApOwp9Cgpwcml2YXRlIHZhcmFyZ3MgbWl4ZWQgcmVhZEdyb3VwRGVzYyhzdHJpbmcgaWQpIHsKICBtaXhlZCBtOwogIHN0cmluZyBmbjsKICBmbiA9IE1BVF9ESVIrIi9ncm91cHMvIitpZDsKICBpZiAoZmlsZV9zaXplKGZuKSA+IDApIHsKICAgIG1hcHBpbmcgcGFydHM7CiAgICBzdHJpbmcgZGVzYzsKICAgIHBhcnRzID0gZ2V0RGVzY1BhcnRzKHJlYWRfZmlsZShmbikpOwogICAgbSA9IChbUF9OQU1FOnBhcnRzWyJOYW1lIl0sCiAgICAgICAgICBQX01FTUJFUlM6KHt9KV0pOwogICAgaWYgKG1lbWJlcihwYXJ0cywiQmVzY2hyZWlidW5nIikpCiAgICAgIG0gKz0gKFtQX0RFU0NSSVBUSU9OOnBhcnRzWyJCZXNjaHJlaWJ1bmciXV0pOwogICAgaWYgKHBhcnRzWyJHcnVwcGVuaWQiXSAhPSBpZCkKICAgICAgTE9HX1dBUk4oc3ByaW50ZigiVW5zdGltbWlna2VpdCBHcnVwcGVuaWQgYmVpICclcydcbiIsIGlkKSk7CiAgfSBlbHNlIHsKICAgIExPR19FUlJPUihzcHJpbnRmKCJLYW5uIEdydXBwZW5iZXNjaHJlaWJ1bmcgJXMgbmljaHQgbGFkZW5cbiIsIGZuKSk7CiAgfQogIHJldHVybiBtOwp9Cgpwcml2YXRlIG1hcHBpbmcgY29udk1hdElkKHN0cmluZyBzKSB7CiAgbWFwcGluZyBtOwogIHN0cmluZyogcGFydHM7CiAgcGFydHMgPSBleHBsb2RlKHMsICJcIiIpOwogIGlmIChzaXplb2YocGFydHMpKSB7CiAgICBpbnQgZW5kZTsKICAgIGVuZGUgPSBzdHJzdHIocGFydHNbMF0sIiAiKS0xOwogICAgaWYgKGVuZGUgPCAwKQogICAgICBlbmRlID0gc2l6ZW9mKHBhcnRzWzBdKTsKICAgIG0gPSAoW1BfSUQ6cGFydHNbMF1bMC4uZW5kZV1dKTsKICAgIGlmIChzaXplb2YocGFydHMpID4gMSkKICAgICAgbSArPSAoW1BfREVGU1RSOnBhcnRzWzFdXSk7CiAgfQogIHJldHVybiBtOwp9CnByaXZhdGUgc3RyaW5nKiBjb252TWF0TmFtZXMoc3RyaW5nIHMpIHsKICBzdHJpbmcqIG5hbWVzOwogIG5hbWVzID0gZmlsdGVyKGV4cGxvZGUocywgIlwiIiksCiAgICAgICAgICAgICAgICAgICAgICAgbGFtYmRhKCAoeyd4fSksICh7Iyc+LCAoeyMnc2l6ZW9mLCAneH0pLCAxfSkgKSk7CiAgaWYgKHNpemVvZihuYW1lcyk8MSkKICAgIG5hbWVzPTA7CiAgZWxzZSB7CiAgICBpZiAoc2l6ZW9mKG5hbWVzKTwyKQogICAgICBuYW1lcys9KHtuYW1lc1swXSsicyJ9KTsKICAgIGlmIChzaXplb2YobmFtZXMpPDMpCiAgICAgIG5hbWVzKz0oe25hbWVzWzBdfSk7CiAgICBpZiAoc2l6ZW9mKG5hbWVzKTw0KQogICAgICBuYW1lcys9KHtuYW1lc1swXX0pOwogIH0KICByZXR1cm4gbmFtZXM7Cn0KcHJpdmF0ZSBpbnQgY29udk1hdEdlbmRlcihzdHJpbmcgcykgewogIGludCBnZW5kZXI7CiAgcyA9IGxvd2Vyc3RyaW5nKHMpOwogIC8vIEVpbiBCdWNoc3RhYmUgcmVpY2h0IHp1ciBCZXN0aW1tdW5nLiBXZW5uIG51ciB3ZWlibGljaHxmZW1hbGUKICAvLyBiencuIG1hZW5ubGljaHxtYWxlIHZlcndlbmRldCB3aXJkLiBEYWJlaSBpc3QgZGFubiBhbGxlcmRpbmdzIGRpZQogIC8vIFJlaWhlbmZvbGdlIGRlciBBdXN3ZXJ0dW5nIHdpY2h0aWcsIGRhbWl0IGRhcyBtIGJlaSBNQUxFIG5pY2h0IG1laHIgYmVpCiAgLy8gZmVtYWxlIHBhc3N0LgogIGlmIChzaXplb2YocmVnZXhwKCAoe3N9KSwgImZ8dyIpKSkgewogICAgZ2VuZGVyID0gRkVNQUxFOwogIH0gZWxzZSBpZiAoc2l6ZW9mKHJlZ2V4cCggKHtzfSksICJtIikpKSB7CiAgICBnZW5kZXIgPSBNQUxFOwogIH0gZWxzZSB7CiAgICBnZW5kZXIgPSBORVVURVI7CiAgfQogIHJldHVybiBnZW5kZXI7Cn0KcHJpdmF0ZSBzdHJpbmcgY29udk1hdERlc2Moc3RyaW5nIHMpIHsKICBpZiAoc2l6ZW9mKHJlZ2V4cCggKHtzfSksICItIG5pY2h0IHZvcmhhbmRlbiAtIikpKSB7CiAgICBzID0gMDsKICB9IGVsc2UgewogICAgLy8gTWVocnplaWxpZ2UgQmVzY2hyZWlidW5nZW4genUgZWluZXIgWmVpbGUgenVzYW1tZW5mYXNzZW4KICAgIHMgPSBpbXBsb2RlKGV4cGxvZGUocywgIlxuIiksICIgIik7CiAgfQogIHJldHVybiBzOwp9CnByaXZhdGUgdm9pZCBhZGRSZWNvY0xpbmUoc3RyaW5nIHMsIG1peGVkKiByKSB7CiAgLy8gRGllIHdlaXRlcmUgQmV3ZXJ0dW5nIGRlciBTY2h3aWVyaWdrZWl0IGthbm4gZXJzdCB2b3JnZW5vbW1lbiB3ZXJkZW4sCiAgLy8gd2VubiBhbGxlIE1hdGVyaWFsaWVuIGJla2FubnQgc2luZCB1bmQgcGFzc2llcnQgc3BhZXRlci4gWnVlcnN0IHdlcmRlbgogIC8vIG51ciBkaWUgRWxlbWVudGUgZGVzIEFycmF5cyBrb252ZXJ0aWVydCB1bmQgZWluZ2V0cmFnZW4KICBzdHJpbmcgbWF0OwogIGludCB2YWw7CiAgaWYgKHNzY2FuZihzLCAiJXM6JWQiLCBtYXQsIHZhbCkpIHsKICAgIHIgKz0gKHttYXQsdmFsfSk7CiAgfSBlbHNlIGlmIChzc2NhbmYocywgIiVkIiwgdmFsKSkgewogICAgciArPSAoe3ZhbH0pOwogIH0gZWxzZSB7CiAgICByICs9ICh7c30pOwogIH0KfQpwcml2YXRlIG1peGVkIGNvbnZNYXRSZWMoc3RyaW5nIHMpIHsKICBtaXhlZCBkaWZmaWN1bHRpZXM7CiAgaWYgKHNpemVvZihyZWdleHAoICh7c30pLCAiLSBrZWluZSBFaW5zY2hyYWVua3VuZyAtIikpKSB7CiAgICBkaWZmaWN1bHRpZXMgPSAwOwogIH0gZWxzZSB7CiAgICBkaWZmaWN1bHRpZXMgPSAoe30pOwogICAgLy8gSmVkZSBaZWlsZSBlbnRoYWVsdCBlaW5lIEJlZGluZ3VuZwogICAgbWFwKGV4cGxvZGUocywgIlxuIiksICMnYWRkUmVjb2NMaW5lLCAmZGlmZmljdWx0aWVzKTsKICB9CiAgcmV0dXJuIGRpZmZpY3VsdGllczsKfQpwcml2YXRlIHZvaWQgYWRkR3JvdXBMaW5lKHN0cmluZyBzLCBtYXBwaW5nIGcpIHsKICAvLyBEaWUgd2VpdGVyZSBCZXdlcnR1bmcgZGVyIFp1Z2Vob2VyaWdrZWl0IHBhc3NpZXJ0IHNwYWV0ZXIuCiAgc3RyaW5nIGdycDsKICBpbnQgdmFsOwogIGlmIChzc2NhbmYocywgIiVzOiVkIiwgZ3JwLCB2YWwpKSB7CiAgICBnICs9IChbZ3JwOnZhbF0pOwogIH0gZWxzZSB7CiAgICBnICs9IChbZ3JwOjEwMF0pOwogIH0KfQpwcml2YXRlIG1hcHBpbmcgY29udk1hdEdyb3VwcyhzdHJpbmcgcykgewogIG1hcHBpbmcgZ3JvdXBzOwogIGlmICghc2l6ZW9mKHJlZ2V4cCggKHtzfSksICItIGtlaW5lIC0iKSkpIHsKICAgIGdyb3VwcyA9IChbXSk7CiAgICAvLyBKZWRlIFplaWxlIGVudGhhZWx0IGVpbmUgQmVkaW5ndW5nCiAgICBtYXAoZXhwbG9kZShzLCAiXG4iKSwgIydhZGRHcm91cExpbmUsIGdyb3Vwcyk7CiAgfQogIHJldHVybiBncm91cHM7Cn0KcHJpdmF0ZSBtYXBwaW5nIGNvbnZNYXRlcmlhbERlc2Moc3RyaW5nIGlkLCBtYXBwaW5nIGRlc2MpIHsKICAvKiBTdHJ1a3R1ciBNYXRlcmlhbG1hcHBpbmc6CiAgICAgUF9HRU5ERVIsCiAgICAgUF9OQU1FOih7bmFtZV9ub20sIG5hbWVfZ2VuLCBuYW1lX2RhdGl2LCBuYW1lX2Fra3VzYXRpdn0pLAogICAgIChQX1JFQ09DOih7bWF0MSxmYWVoaWdrZWl0MSxtYXQyLGZhZWhpZ2tlaXQyLC4uLn0pLCkKICAgICAoUF9ERUZTVFI6IGJlaSBiZWRhcmYpLAogICAgIFBfREVTQ1JJUFRJT04sCiAgICAgKGdydXBwMTphbnRlaWwxLAogICAgIGdydXBwZTI6YW50ZWlsMiwKICAgICAuLi4pCiAgKi8KICBtYXBwaW5nIG07CiAgbWl4ZWQgdmFsLCB2YWwyOwogIG0gPSAoW10pOwogIC8vIERlciBzdHJpbmcgZnVlciBkYXMgI2RlZmluZSB6dWVyc3Q6CiAgdmFsID0gY29udk1hdElkKGRlc2NbIk1hdGVyaWFsaWQiXSk7CiAgaWYgKG1hcHBpbmdwKHZhbCkpIHsKICAgIGlmICh2YWxbUF9JRF0gIT0gaWQpCiAgICAgIExPR19XQVJOKHNwcmludGYoIlVuc3RpbW1pZ2tlaXQgTWF0ZXJpYWxpZCBiZWkgJyVzJzolT1xuIiwgaWQsIHZhbFtQX0lEXSkpOwogICAgaWYgKG1lbWJlcih2YWwsIFBfREVGU1RSKSkgewogICAgICBtICs9IChbUF9ERUZTVFI6dmFsW1BfREVGU1RSXV0pOwogICAgfSBlbHNlIHsKICAgICAgLy8gV2VubiBrZWluIFN0cmluZyBmdWVycyAjZGVmaW5lIGFuZ2VnZWJlbiB3dXJkZSwgZGFubiBkaXJla3QgSUQgdmVyd2VuZGVuCiAgICAgIC8vbSArPSAoW1BfREVGU1RSOmxvd2Vyc3RyaW5nKGlkKVs0Li5dXSk7CiAgICB9CiAgfQogIC8vIERpZSBOYW1lbgogIGlmICh2YWwgPSBjb252TWF0TmFtZXMoZGVzY1siTmFtZSJdKSkgewogICAgbSArPSAoW1BfTkFNRTp2YWxdKTsKICB9IGVsc2UgewogICAgTURFU0NfV0FSTihpZCwgImtlaW5lIE5hbWVuIik7CiAgICBtICs9IChbUF9OQU1FOih7IiIsICIiLCAiIiwgIiJ9KV0pOwogIH0KICAvLyBEYXMgR2VzY2hsZWNodCwgc3RhbmRhcmQgaXN0IE5FVVRFUgogIG0gKz0gKFtQX0dFTkRFUjpjb252TWF0R2VuZGVyKGRlc2NbIkdlc2NobGVjaHQiXSkgXSk7CiAgLy8gRGllIEJlc2NocmVpYnVuZwogIHZhbCA9IGNvbnZNYXREZXNjKGRlc2NbIkJlc2NocmVpYnVuZyJdKTsKICBpZiAoc2l6ZW9mKHZhbCkpIHsKICAgIG0gKz0gKFtQX0RFU0NSSVBUSU9OOnZhbF0pOwogIH0gZWxzZSB7CiAgICBNREVTQ19XQVJOKGlkLCAia2VpbmUgQmVzY2hyZWlidW5nIik7CiAgfQogIC8vIERpZSBFcmtlbm5iYXJrZWl0CiAgdmFsID0gY29udk1hdFJlYyhkZXNjWyJFcmtlbm5iYXJrZWl0Il0pOwogIGlmIChzaXplb2YodmFsKSkgewogICAgbSArPSAoW1BfUkVDT0M6dmFsXSk7CiAgfQogIC8vIHVuZCB6dW0gU2NobHVzcyBkaWUgR3J1cHBlbnp1Z2Vob2VyaWdrZWl0CiAgdmFsID0gY29udk1hdEdyb3VwcyhkZXNjWyJHcnVwcGVuenVnZWhvZXJpZ2tlaXQiXSk7CiAgaWYgKG1hcHBpbmdwKHZhbCkgJiYgc2l6ZW9mKHZhbCkpIHsKICAgIG0gKz0gKFtQX01HX0ZSQUNUSU9OUzp2YWxdKTsKICB9CiAgcmV0dXJuIG07Cn0KcHJpdmF0ZSB2YXJhcmdzIG1peGVkIHJlYWRNYXRlcmlhbERlc2Moc3RyaW5nIGlkKSB7CiAgbWl4ZWQgbTsKICBzdHJpbmcgZm47CiAgZm4gPSBNQVRfRElSKyIvbWF0ZXJpYWxzLyIraWQ7CiAgaWYgKGZpbGVfc2l6ZShmbikgPiAwKSB7CiAgICBtYXBwaW5nIHBhcnRzOwogICAgc3RyaW5nIGRlc2M7CiAgICBwYXJ0cyA9IGdldERlc2NQYXJ0cyhyZWFkX2ZpbGUoZm4pKTsKICAgIG0gPSBjb252TWF0ZXJpYWxEZXNjKGlkLCBwYXJ0cyk7CiAgfSBlbHNlIHsKICAgIExPR19FUlJPUihzcHJpbnRmKCJNREI6S2FubiBNYXRlcmlhbGJlc2NocmVpYnVuZyAlcyBuaWNodCBsYWRlblxuIiwgZm4pKTsKICB9CiAgcmV0dXJuIG07Cn0KCnB1YmxpYyBpbnQgR2V0VXBkYXRlVGlja3MoKSB7CiAgcmV0dXJuIHVwZGF0ZVRpY2tzOwp9Cgpwcml2YXRlIHZvaWQgc2NhbkZpbmlzaGVkKCkgewogIGlzU2Nhbm5pbmcgPSAwOwogIGluaXRpYWxpemVkID0gMTsKICAvLyBNYXBwaW5ncyB1bWtvcGllcmVuCiAgbWF0ZXJpYWxzID0gbmV3X21hdGVyaWFsczsKICBtYXRlcmlhbF9ncm91cHMgPSBuZXdfbWF0ZXJpYWxfZ3JvdXBzOwogIC8vIExldHp0ZXIgU2Nocml0dDogTWFwcGluZyBtaXQgYWx0ZW4gU2NobHVlc3NlbG4gYW5sZWdlbgogIG9sZF9tYXRfa2V5cyA9IG1rbWFwcGluZyhtYXAobV9pbmRpY2VzKG1hdGVyaWFscyksICMnbWF0S2V5MkRlZnN0ciwgbWF0ZXJpYWxzKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgbV9pbmRpY2VzKG1hdGVyaWFscykpOwogIC8vIEdlbmVyaWVyZW4gZGVyIERva3UgdW5kIGRlcyBNYXRlcmlhbGhlYWRlcnMKICBHZW5IZWFkZXJGaWxlKCk7CiAgR2VuTWF0TGlzdCgpOwogIEdlbk1hdEdyb3VwTGlzdCgpOwogIC8vIFNhdmVmaWxlIHNjaHJlaWJlbgogIHNhdmVfb2JqZWN0KFNBVkVGSUxFKTsKfQoKcHVibGljIGludCBJc1NjYW5uaW5nKCkgewogIHJldHVybiBpc1NjYW5uaW5nOwp9Cgpwcml2YXRlIHZhcmFyZ3Mgdm9pZCBkb1NjYW5NYXRlcmlhbHMoc3RyaW5nKiBtYXRzLCBpbnQgaSwgaW50IHN0ZXApIHsKICBpbnQgdGlja3MsIHN0YXJ0OwogIHN0cmluZyBtYXRpZDsKICBzdGFydCA9IGdldF9ldmFsX2Nvc3QoKTsKICBpZiAoc3RlcCA8IDIpIHsKICAgIHdoaWxlICggKGkgPCBzaXplb2YobWF0cykpICYmCiAgICAgICAgICAgICgoc3RhcnQgLSBnZXRfZXZhbF9jb3N0KCkpIDwgcXVlcnlfbGltaXRzKClbTElNSVRfRVZBTF0vMyApICkgewogICAgICBtYXRpZCA9IG1hdHNbaV07CiAgICAgIHN3aXRjaCAoc3RlcCkgewogICAgICBjYXNlIDA6CiAgICAgICAgLy8gRXJzdGVyIFNjaHJpdHQ6IEVpbmxlc2VuIGRlciBEYXRlaWVuCiAgICAgICAgbmV3X21hdGVyaWFsc1ttYXRpZF0gPSByZWFkTWF0ZXJpYWxEZXNjKG1hdGlkKTsKICAgICAgICBicmVhazsKICAgICAgY2FzZSAxOgogICAgICAgIC8vIFp3ZWl0ZXIgU2Nocml0dDogQmVhcmJlaXRlbiBkZXIgRXJrZW5udW5nIHVuZCBHcnVwcGVuenVnZWhvZXJpZ2tlaXQKICAgICAgICB1cGRhdGVHcm91cE1lbWJlcnMobmV3X21hdGVyaWFsX2dyb3VwcywgbWF0aWQsIG5ld19tYXRlcmlhbHNbbWF0aWRdKTsKICAgICAgICBicmVhazsKICAgICAgZGVmYXVsdDoKICAgICAgICBicmVhazsKICAgICAgfQogICAgICBpKys7CiAgICB9CiAgfQogIGlmIChpIDwgc2l6ZW9mKG1hdHMpKSB7CiAgICBjYXRjaChyYWlzZV9lcnJvcihzcHJpbnRmKCJNYXRlcmlhbERCOiBJbml0aWFsaXNpZXJ1bmcgbm9jaCBuaWNodCBiZWVuZGV0LCIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiBmZWhsZW5kZSBNYXRlcmlhbGJlc2NocmVpYnVuZ2VuIG1vZWdsaWNoIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIChQaGFzZSAlZDolZC8lZClcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZXAsIGksIHNpemVvZihtYXRzKSkpO3B1Ymxpc2gpOwogICAgY2FsbF9vdXQoIydkb1NjYW5NYXRlcmlhbHMsIDIsIG1hdHMsIGksIHN0ZXApOwogIH0gZWxzZSB7CiAgICAvLyBad2VpdGUgU3R1ZmUgYXVzbG9lc2VuIG9kZXIgYmVlbmRlbgogICAgaWYgKHN0ZXAgPCAxKSB7CiAgICAgIGlmICgoc3RhcnQgLSBnZXRfZXZhbF9jb3N0KCkpIDwgcXVlcnlfbGltaXRzKClbTElNSVRfRVZBTF0vMiApCiAgICAgICAgICBkb1NjYW5NYXRlcmlhbHMobWF0cywgMCwgc3RlcCsxKTsKICAgICAgZWxzZQogICAgICAgICAgY2FsbF9vdXQoIydkb1NjYW5NYXRlcmlhbHMsIDIsIG1hdHMsIDAsIHN0ZXArMSk7CiAgICB9CiAgICBlbHNlCiAgICAgIHNjYW5GaW5pc2hlZCgpOwogIH0KICB1cGRhdGVUaWNrcyArPSBzdGFydCAtIGdldF9ldmFsX2Nvc3QoKTsKfQoKcHJpdmF0ZSBtYXBwaW5nIFNjYW5Hcm91cHMoKSB7CiAgbWFwcGluZyBncm91cHM7CiAgc3RyaW5nKiBncnBmaWxlczsKICBncm91cHMgPSAoW10pOwogIGdycGZpbGVzID0gZmlsdGVyKGdldF9kaXIoTUFUX0RJUisiL2dyb3Vwcy9NQVRHUk9VUF8qIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIydpc0ZpbGUsIE1BVF9ESVIrIi9ncm91cHMiKTsKICBncm91cHMgPSBta21hcHBpbmcoZ3JwZmlsZXMsIG1hcChncnBmaWxlcywgIydyZWFkR3JvdXBEZXNjLCAxKSk7CiAgcmV0dXJuIGdyb3VwczsKfQoKcHJpdmF0ZSB2b2lkIFNjYW5NYXRlcmlhbHMoKSB7CiAgc3RyaW5nICptYXRmaWxlczsKICBtYXRmaWxlcyA9IGZpbHRlcihnZXRfZGlyKE1BVF9ESVIrIi9tYXRlcmlhbHMvTUFUXyoiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAjJ2lzRmlsZSwgTUFUX0RJUisiL21hdGVyaWFscyIpOwogIGRvU2Nhbk1hdGVyaWFscyhtYXRmaWxlcyk7Cn0KCnZvaWQgVXBkYXRlKCkgewogIGludCBzdGFydDsKICB1cGRhdGVUaWNrcyA9IDA7CiAgc3RhcnQgPSBnZXRfZXZhbF9jb3N0KCk7CiAgaWYgKCFpc1NjYW5uaW5nKSB7CiAgICBpZiAoc2l6ZW9mKGdldF9kaXIoTUFUX0RJUikpKSB7CiAgICAgIGlzU2Nhbm5pbmcgPSAxOwogICAgICBuZXdfbWF0ZXJpYWxfZ3JvdXBzID0gU2Nhbkdyb3VwcygpOwogICAgICBuZXdfbWF0ZXJpYWxzID0gKFtdKTsKICAgICAgdXBkYXRlVGlja3MgPSBzdGFydCAtIGdldF9ldmFsX2Nvc3QoKTsKICAgICAgU2Nhbk1hdGVyaWFscygpOwogICAgfSBlbHNlIHsKICAgICAgTE9HX0VSUk9SKCJLYW5uIE1hdGVyaWFsdmVyemVpY2huaXMgbmljaHQgZmluZGVuLCBrZWluZSBNYXRlcmlhbGllbiBhbmdlbGVndCFcbiIpOwogICAgfQogIH0KfQo=