LyoKICogRE9TIChNWikgbG9hZGVyCiAqCiAqIENvcHlyaWdodCAxOTk4IE92ZSBL5XZlbgogKgogKiBUaGlzIGNvZGUgaGFzbid0IGJlZW4gY29tcGxldGVseSBjbGVhbmVkIHVwIHlldC4KICovCgojaW5jbHVkZSAiY29uZmlnLmgiCgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxlcnJuby5oPgojaW5jbHVkZSA8ZmNudGwuaD4KI2luY2x1ZGUgPHNpZ25hbC5oPgojaW5jbHVkZSA8dW5pc3RkLmg+CiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNpbmNsdWRlIDxzeXMvdGltZS5oPgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5lL3dpbmJhc2UxNi5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIm1vZHVsZS5oIgojaW5jbHVkZSAibmVleGUuaCIKI2luY2x1ZGUgInRhc2suaCIKI2luY2x1ZGUgInNlbGVjdG9ycy5oIgojaW5jbHVkZSAiZmlsZS5oIgojaW5jbHVkZSAibGR0LmgiCiNpbmNsdWRlICJwcm9jZXNzLmgiCiNpbmNsdWRlICJtaXNjZW11LmgiCiNpbmNsdWRlICJkZWJ1Z3Rvb2xzLmgiCiNpbmNsdWRlICJkb3NleGUuaCIKI2luY2x1ZGUgImRvc21vZC5oIgojaW5jbHVkZSAib3B0aW9ucy5oIgojaW5jbHVkZSAidmdhLmgiCgpERUZBVUxUX0RFQlVHX0NIQU5ORUwobW9kdWxlKTsKCnN0YXRpYyBMUERPU1RBU0sgZG9zX2N1cnJlbnQ7CgojaWZkZWYgTVpfU1VQUE9SVEVECgojaWZkZWYgSEFWRV9TWVNfTU1BTl9ICiMgaW5jbHVkZSA8c3lzL21tYW4uaD4KI2VuZGlmCgovKiBkZWZpbmUgdGhpcyB0byB0cnkgbWFwcGluZyB0aHJvdWdoIC9wcm9jL3BpZC9tZW0gaW5zdGVhZCBvZiBhIHRlbXAgZmlsZSwKICAgYnV0IExpbnVzIGRvZXNuJ3QgbGlrZSBtbWFwcGluZyAvcHJvYy9waWQvbWVtLCBzbyBpdCBkb2Vzbid0IHdvcmsgZm9yIG1lICovCiN1bmRlZiBNWl9NQVBTRUxGCgojZGVmaW5lIEJJT1NfREFUQV9TRUdNRU5UIDB4NDAKI2RlZmluZSBQU1BfU0laRSAweDEwCgojZGVmaW5lIFNFRzE2KHB0cixzZWcpICgoTFBWT0lEKSgoQllURSopcHRyKygoRFdPUkQpKHNlZyk8PDQpKSkKI2RlZmluZSBTRUdQVFIxNihwdHIsc2VncHRyKSAoKExQVk9JRCkoKEJZVEUqKXB0cisoKERXT1JEKVNFTEVDVE9ST0Yoc2VncHRyKTw8NCkrT0ZGU0VUT0Yoc2VncHRyKSkpCgpzdGF0aWMgV09SRCBpbml0X2NzLGluaXRfaXAsaW5pdF9zcyxpbml0X3NwOwpzdGF0aWMgY2hhciBtbV9uYW1lWzEyOF07CgppbnQgcmVhZF9waXBlLCB3cml0ZV9waXBlOwpIQU5ETEUgaFJlYWRQaXBlLCBoV3JpdGVQaXBlOwpwaWRfdCBkb3Ntb2RfcGlkOwoKc3RhdGljIHZvaWQgTVpfTGF1bmNoKHZvaWQpOwpzdGF0aWMgQk9PTCBNWl9Jbml0VGFzayh2b2lkKTsKc3RhdGljIHZvaWQgTVpfS2lsbFRhc2sodm9pZCk7CgpzdGF0aWMgdm9pZCBNWl9DcmVhdGVQU1AoIExQVk9JRCBscFBTUCwgV09SRCBlbnYgKQp7CiBQREIxNipwc3A9bHBQU1A7CgogcHNwLT5pbnQyMD0weDIwQ0Q7IC8qIGludCAyMCAqLwogLyogc29tZSBwcm9ncmFtcyB1c2UgdGhpcyB0byBjYWxjdWxhdGUgaG93IG11Y2ggbWVtb3J5IHRoZXkgbmVlZCAqLwogcHNwLT5uZXh0UGFyYWdyYXBoPTB4OUZGRjsKIHBzcC0+ZW52aXJvbm1lbnQ9ZW52OwogLyogRklYTUU6IG1vcmUgUFNQIHN0dWZmICovCn0KCnN0YXRpYyB2b2lkIE1aX0ZpbGxQU1AoIExQVk9JRCBscFBTUCwgTFBDU1RSIGNtZGxpbmUgKQp7CiBQREIxNipwc3A9bHBQU1A7CiBjb25zdCBjaGFyKmNtZD1jbWRsaW5lP3N0cmNocihjbWRsaW5lLCcgJyk6TlVMTDsKCiAvKiBjb3B5IHBhcmFtZXRlcnMgKi8KIGlmIChjbWQpIHsKI2lmIDAKICAvKiBjb21tYW5kLmNvbSBkb2Vzbid0IGRvIHRoaXMgKi8KICB3aGlsZSAoKmNtZCA9PSAnICcpIGNtZCsrOwojZW5kaWYKICBwc3AtPmNtZExpbmVbMF09c3RybGVuKGNtZCk7CiAgc3RyY3B5KHBzcC0+Y21kTGluZSsxLGNtZCk7CiAgcHNwLT5jbWRMaW5lW3BzcC0+Y21kTGluZVswXSsxXT0nXHInOwogfSBlbHNlIHBzcC0+Y21kTGluZVsxXT0nXHInOwogLyogRklYTUU6IG1vcmUgUFNQIHN0dWZmICovCn0KCi8qIGRlZmF1bHQgSU5UIDA4IGhhbmRsZXI6IGluY3JlYXNlcyB0aW1lciB0aWNrIGNvdW50ZXIgYnV0IG5vdCBtdWNoIG1vcmUgKi8Kc3RhdGljIGNoYXIgaW50MDhbXT17CiAweENELDB4MUMsICAgICAgICAgICAvKiBpbnQgJDB4MWMgKi8KIDB4NTAsICAgICAgICAgICAgICAgIC8qIHB1c2h3ICVheCAqLwogMHgxRSwgICAgICAgICAgICAgICAgLyogcHVzaHcgJWRzICovCiAweEI4LDB4NDAsMHgwMCwgICAgICAvKiBtb3Z3ICQweDQwLCVheCAqLwogMHg4RSwweEQ4LCAgICAgICAgICAgLyogbW92dyAlYXgsJWRzICovCiNpZiAwCiAweDgzLDB4MDYsMHg2QywweDAwLDB4MDEsIC8qIGFkZHcgJDEsKDB4NmMpICovCiAweDgzLDB4MTYsMHg2RSwweDAwLDB4MDAsIC8qIGFkY3cgJDAsKDB4NmUpICovCiNlbHNlCiAweDY2LDB4RkYsMHgwNiwweDZDLDB4MDAsIC8qIGluY2wgKDB4NmMpICovCiNlbmRpZgogMHhCMCwweDIwLCAgICAgICAgICAgLyogbW92YiAkMHgyMCwlYWwgKi8KIDB4RTYsMHgyMCwgICAgICAgICAgIC8qIG91dGIgJWFsLCQweDIwICovCiAweDFGLCAgICAgICAgICAgICAgICAvKiBwb3B3ICVheCAqLwogMHg1OCwgICAgICAgICAgICAgICAgLyogcG9wdyAlYXggKi8KIDB4Q0YgICAgICAgICAgICAgICAgIC8qIGlyZXQgKi8KfTsKCnN0YXRpYyB2b2lkIE1aX0luaXRIYW5kbGVycyh2b2lkKQp7CiBXT1JEIHNlZzsKIExQQllURSBzdGFydD1ET1NNRU1fR2V0QmxvY2soc2l6ZW9mKGludDA4KSwmc2VnKTsKIG1lbWNweShzdGFydCxpbnQwOCxzaXplb2YoaW50MDgpKTsKLyogSU5UIDA4OiBwb2ludCBpdCBhdCBvdXIgdGljay1pbmNyZW1lbnRpbmcgaGFuZGxlciAqLwogKChTRUdQVFIqKTApWzB4MDhdPVBUUl9TRUdfT0ZGX1RPX1NFR1BUUihzZWcsMCk7Ci8qIElOVCAxQzoganVzdCBwb2ludCBpdCB0byBJUkVULCB3ZSBkb24ndCB3YW50IHRvIGhhbmRsZSBpdCBvdXJzZWx2ZXMgKi8KICgoU0VHUFRSKikwKVsweDFDXT1QVFJfU0VHX09GRl9UT19TRUdQVFIoc2VnLHNpemVvZihpbnQwOCktMSk7Cn0KCnN0YXRpYyBXT1JEIE1aX0luaXRFbnZpcm9ubWVudCggTFBDU1RSIGVudiwgTFBDU1RSIG5hbWUgKQp7CiB1bnNpZ25lZCBzej0wOwogV09SRCBzZWc7CiBMUFNUUiBlbnZibGs7CgogaWYgKGVudikgewogIC8qIGdldCBzaXplIG9mIGVudmlyb25tZW50IGJsb2NrICovCiAgd2hpbGUgKGVudltzeisrXSkgc3orPXN0cmxlbihlbnYrc3opKzE7CiB9IGVsc2Ugc3orKzsKIC8qIGFsbG9jYXRlIGl0ICovCiBlbnZibGs9RE9TTUVNX0dldEJsb2NrKHN6K3NpemVvZihXT1JEKStzdHJsZW4obmFtZSkrMSwmc2VnKTsKIC8qIGZpbGwgaXQgKi8KIGlmIChlbnYpIHsKICBtZW1jcHkoZW52YmxrLGVudixzeik7CiB9IGVsc2UgZW52YmxrWzBdPTA7CiAvKiBET1MgMy54OiB0aGUgYmxvY2sgY29udGFpbnMgMSBhZGRpdGlvbmFsIHN0cmluZyAqLwogKihXT1JEKikoZW52YmxrK3N6KT0xOwogLyogYmVpbmcgdGhlIHByb2dyYW0gbmFtZSBpdHNlbGYgKi8KIHN0cmNweShlbnZibGsrc3orc2l6ZW9mKFdPUkQpLG5hbWUpOwogcmV0dXJuIHNlZzsKfQoKc3RhdGljIEJPT0wgTVpfSW5pdE1lbW9yeSh2b2lkKQp7CiAgICBpbnQgbW1fZmQ7CiAgICB2b2lkICppbWdfYmFzZTsKCiAgICAvKiBpbml0aWFsaXplIHRoZSBtZW1vcnkgKi8KICAgIFRSQUNFKCJJbml0aWFsaXppbmcgRE9TIG1lbW9yeSBzdHJ1Y3R1cmVzXG4iKTsKICAgIERPU01FTV9Jbml0KFRSVUUpOwoKICAgIC8qIGFsbG9jYXRlIDFNQis2NEsgc2hhcmVkIG1lbW9yeSAqLwogICAgdG1wbmFtKG1tX25hbWUpOwogICAgLyogc3RyY3B5KG1tX25hbWUsIi90bXAvbXlkb3NpbWFnZSIpOyAqLwogICAgbW1fZmQgPSBvcGVuKG1tX25hbWUsT19SRFdSfE9fQ1JFQVQgLyogfE9fVFJVTkMgKi8sU19JUlVTUnxTX0lXVVNSKTsKICAgIGlmIChtbV9mZCA8IDApIEVSUigiZmlsZSAlcyBjb3VsZCBub3QgYmUgb3BlbmVkXG4iLG1tX25hbWUpOwogICAgLyogZmlsbCB0aGUgZmlsZSB3aXRoIHRoZSBET1MgbWVtb3J5ICovCiAgICBpZiAod3JpdGUoIG1tX2ZkLCBOVUxMLCAweDExMDAwMCApICE9IDB4MTEwMDAwKSBFUlIoImNhbm5vdCB3cml0ZSBET1MgbWVtXG4iKTsKICAgIC8qIG1hcCBpdCBpbiAqLwogICAgaW1nX2Jhc2UgPSBtbWFwKE5VTEwsMHgxMTAwMDAsUFJPVF9SRUFEfFBST1RfV1JJVEV8UFJPVF9FWEVDLE1BUF9TSEFSRUR8TUFQX0ZJWEVELG1tX2ZkLDApOwogICAgY2xvc2UoIG1tX2ZkICk7CgogICAgaWYgKGltZ19iYXNlKQogICAgewogICAgICAgIEVSUigiY291bGQgbm90IG1hcCBzaGFyZWQgbWVtb3J5LCBlcnJvcj0lc1xuIixzdHJlcnJvcihlcnJubykpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KICAgIE1aX0luaXRIYW5kbGVycygpOwogICAgcmV0dXJuIFRSVUU7Cn0KCkJPT0wgTVpfTG9hZEltYWdlKCBITU9EVUxFIG1vZHVsZSwgSEFORExFIGhGaWxlLCBMUENTVFIgZmlsZW5hbWUgKQp7CiAgTFBET1NUQVNLIGxwRG9zVGFzayA9IGRvc19jdXJyZW50OwogIElNQUdFX05UX0hFQURFUlMgKndpbl9oZHIgPSBQRV9IRUFERVIobW9kdWxlKTsKICBJTUFHRV9ET1NfSEVBREVSIG16X2hlYWRlcjsKICBEV09SRCBpbWFnZV9zdGFydCxpbWFnZV9zaXplLG1pbl9zaXplLG1heF9zaXplLGF2YWlsOwogIEJZVEUqcHNwX3N0YXJ0LCpsb2FkX3N0YXJ0OwogIGludCB4LCBvbGRfY29tPTAsIGFsbG9jPTA7CiAgU0VHUFRSIHJlbG9jOwogIFdPUkQgZW52X3NlZywgbG9hZF9zZWc7CiAgRFdPUkQgbGVuOwoKICB3aW5faGRyLT5PcHRpb25hbEhlYWRlci5TdWJzeXN0ZW0gPSBJTUFHRV9TVUJTWVNURU1fV0lORE9XU19DVUk7CiAgd2luX2hkci0+T3B0aW9uYWxIZWFkZXIuQWRkcmVzc09mRW50cnlQb2ludCA9IChMUEJZVEUpTVpfTGF1bmNoIC0gKExQQllURSltb2R1bGU7CgogIGlmICghbHBEb3NUYXNrKSB7CiAgICBhbGxvYz0xOwogICAgbHBEb3NUYXNrID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihET1NUQVNLKSk7CiAgICBkb3NfY3VycmVudCA9IGxwRG9zVGFzazsKICB9CgogU2V0RmlsZVBvaW50ZXIoaEZpbGUsMCxOVUxMLEZJTEVfQkVHSU4pOwogaWYgKCAgICFSZWFkRmlsZShoRmlsZSwmbXpfaGVhZGVyLHNpemVvZihtel9oZWFkZXIpLCZsZW4sTlVMTCkKICAgICB8fCBsZW4gIT0gc2l6ZW9mKG16X2hlYWRlcikgCiAgICAgfHwgbXpfaGVhZGVyLmVfbWFnaWMgIT0gSU1BR0VfRE9TX1NJR05BVFVSRSkgewogIG9sZF9jb209MTsgLyogYXNzdW1lIC5DT00gZmlsZSAqLwogIGltYWdlX3N0YXJ0PTA7CiAgaW1hZ2Vfc2l6ZT1HZXRGaWxlU2l6ZShoRmlsZSxOVUxMKTsKICBtaW5fc2l6ZT0weDEwMDAwOyBtYXhfc2l6ZT0weDEwMDAwMDsKICBtel9oZWFkZXIuZV9jcmxjPTA7CiAgbXpfaGVhZGVyLmVfc3M9MDsgbXpfaGVhZGVyLmVfc3A9MHhGRkZFOwogIG16X2hlYWRlci5lX2NzPTA7IG16X2hlYWRlci5lX2lwPTB4MTAwOwogfSBlbHNlIHsKICAvKiBjYWxjdWxhdGUgbG9hZCBzaXplICovCiAgaW1hZ2Vfc3RhcnQ9bXpfaGVhZGVyLmVfY3Bhcmhkcjw8NDsKICBpbWFnZV9zaXplPW16X2hlYWRlci5lX2NwPDw5OyAvKiBwYWdlcyBhcmUgNTEyIGJ5dGVzICovCiAgaWYgKChtel9oZWFkZXIuZV9jYmxwIT0wKSYmKG16X2hlYWRlci5lX2NibHAhPTQpKSBpbWFnZV9zaXplLT01MTItbXpfaGVhZGVyLmVfY2JscDsKICBpbWFnZV9zaXplLT1pbWFnZV9zdGFydDsKICBtaW5fc2l6ZT1pbWFnZV9zaXplKygoRFdPUkQpbXpfaGVhZGVyLmVfbWluYWxsb2M8PDQpKyhQU1BfU0laRTw8NCk7CiAgbWF4X3NpemU9aW1hZ2Vfc2l6ZSsoKERXT1JEKW16X2hlYWRlci5lX21heGFsbG9jPDw0KSsoUFNQX1NJWkU8PDQpOwogfQoKIE1aX0luaXRNZW1vcnkoKTsKCiAvKiBhbGxvY2F0ZSBlbnZpcm9ubWVudCBibG9jayAqLwogZW52X3NlZz1NWl9Jbml0RW52aXJvbm1lbnQoR2V0RW52aXJvbm1lbnRTdHJpbmdzQSgpLGZpbGVuYW1lKTsKCiAvKiBhbGxvY2F0ZSBtZW1vcnkgZm9yIHRoZSBleGVjdXRhYmxlICovCiBUUkFDRSgiQWxsb2NhdGluZyBET1MgbWVtb3J5IChtaW49JWxkLCBtYXg9JWxkKVxuIixtaW5fc2l6ZSxtYXhfc2l6ZSk7CiBhdmFpbD1ET1NNRU1fQXZhaWxhYmxlKCk7CiBpZiAoYXZhaWw8bWluX3NpemUpIHsKICBFUlIoImluc3VmZmljaWVudCBET1MgbWVtb3J5XG4iKTsKICBTZXRMYXN0RXJyb3IoRVJST1JfTk9UX0VOT1VHSF9NRU1PUlkpOwogIGdvdG8gbG9hZF9lcnJvcjsKIH0KIGlmIChhdmFpbD5tYXhfc2l6ZSkgYXZhaWw9bWF4X3NpemU7CiBwc3Bfc3RhcnQ9RE9TTUVNX0dldEJsb2NrKGF2YWlsLCZscERvc1Rhc2stPnBzcF9zZWcpOwogaWYgKCFwc3Bfc3RhcnQpIHsKICBFUlIoImVycm9yIGFsbG9jYXRpbmcgRE9TIG1lbW9yeVxuIik7CiAgU2V0TGFzdEVycm9yKEVSUk9SX05PVF9FTk9VR0hfTUVNT1JZKTsKICBnb3RvIGxvYWRfZXJyb3I7CiB9CiBsb2FkX3NlZz1scERvc1Rhc2stPnBzcF9zZWcrKG9sZF9jb20/MDpQU1BfU0laRSk7CiBsb2FkX3N0YXJ0PXBzcF9zdGFydCsoUFNQX1NJWkU8PDQpOwogTVpfQ3JlYXRlUFNQKHBzcF9zdGFydCwgZW52X3NlZyk7CgogLyogbG9hZCBleGVjdXRhYmxlIGltYWdlICovCiBUUkFDRSgibG9hZGluZyBET1MgJXMgaW1hZ2UsICUwOGx4IGJ5dGVzXG4iLG9sZF9jb20/IkNPTSI6IkVYRSIsaW1hZ2Vfc2l6ZSk7CiBTZXRGaWxlUG9pbnRlcihoRmlsZSxpbWFnZV9zdGFydCxOVUxMLEZJTEVfQkVHSU4pOwogaWYgKCFSZWFkRmlsZShoRmlsZSxsb2FkX3N0YXJ0LGltYWdlX3NpemUsJmxlbixOVUxMKSB8fCBsZW4gIT0gaW1hZ2Vfc2l6ZSkgewogIFNldExhc3RFcnJvcihFUlJPUl9CQURfRk9STUFUKTsKICBnb3RvIGxvYWRfZXJyb3I7CiB9CgogaWYgKG16X2hlYWRlci5lX2NybGMpIHsKICAvKiBsb2FkIHJlbG9jYXRpb24gdGFibGUgKi8KICBUUkFDRSgibG9hZGluZyBET1MgRVhFIHJlbG9jYXRpb24gdGFibGUsICVkIGVudHJpZXNcbiIsbXpfaGVhZGVyLmVfY3JsYyk7CiAgLyogRklYTUU6IGlzIHRoaXMgdG9vIHNsb3cgd2l0aG91dCByZWFkIGJ1ZmZlcmluZz8gKi8KICBTZXRGaWxlUG9pbnRlcihoRmlsZSxtel9oZWFkZXIuZV9sZmFybGMsTlVMTCxGSUxFX0JFR0lOKTsKICBmb3IgKHg9MDsgeDxtel9oZWFkZXIuZV9jcmxjOyB4KyspIHsKICAgaWYgKCFSZWFkRmlsZShoRmlsZSwmcmVsb2Msc2l6ZW9mKHJlbG9jKSwmbGVuLE5VTEwpIHx8IGxlbiAhPSBzaXplb2YocmVsb2MpKSB7CiAgICBTZXRMYXN0RXJyb3IoRVJST1JfQkFEX0ZPUk1BVCk7CiAgICBnb3RvIGxvYWRfZXJyb3I7CiAgIH0KICAgKihXT1JEKilTRUdQVFIxNihsb2FkX3N0YXJ0LHJlbG9jKSs9bG9hZF9zZWc7CiAgfQogfQoKIGluaXRfY3MgPSBsb2FkX3NlZyttel9oZWFkZXIuZV9jczsKIGluaXRfaXAgPSBtel9oZWFkZXIuZV9pcDsKIGluaXRfc3MgPSBsb2FkX3NlZyttel9oZWFkZXIuZV9zczsKIGluaXRfc3AgPSBtel9oZWFkZXIuZV9zcDsKCiAgVFJBQ0UoImVudHJ5IHBvaW50OiAlMDR4OiUwNHhcbiIsaW5pdF9jcyxpbml0X2lwKTsKCiAgaWYgKCFNWl9Jbml0VGFzaygpKSB7CiAgICBNWl9LaWxsVGFzaygpOwogICAgU2V0TGFzdEVycm9yKEVSUk9SX0dFTl9GQUlMVVJFKTsKICAgIHJldHVybiBGQUxTRTsKICB9CgogIHJldHVybiBUUlVFOwoKbG9hZF9lcnJvcjoKICBpZiAoYWxsb2MpIHsKICAgIGRvc19jdXJyZW50ID0gTlVMTDsKICAgIGlmIChtbV9uYW1lWzBdIT0wKSB1bmxpbmsobW1fbmFtZSk7CiAgfQoKICByZXR1cm4gRkFMU0U7Cn0KCkxQRE9TVEFTSyBNWl9BbGxvY0RQTUlUYXNrKCB2b2lkICkKewogIExQRE9TVEFTSyBscERvc1Rhc2sgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKERPU1RBU0spKTsKCiAgaWYgKGxwRG9zVGFzaykgewogICAgZG9zX2N1cnJlbnQgPSBscERvc1Rhc2s7CiAgICBNWl9Jbml0TWVtb3J5KCk7CiAgICBNWl9Jbml0VGFzaygpOwogIH0KICByZXR1cm4gbHBEb3NUYXNrOwp9CgpzdGF0aWMgdm9pZCBNWl9Jbml0VGltZXIoIGludCB2ZXIgKQp7CiBpZiAodmVyPDEpIHsKICAvKiBjYW4ndCBtYWtlIHRpbWVyIHRpY2tzICovCiB9IGVsc2UgewogIGludCBmdW5jOwogIHN0cnVjdCB0aW1ldmFsIHRpbTsKCiAgLyogc3RhcnQgZG9zbW9kIHRpbWVyIGF0IDU1bXMgKDE4LjJIeikgKi8KICBmdW5jPURPU01PRF9TRVRfVElNRVI7CiAgdGltLnR2X3NlYz0wOyB0aW0udHZfdXNlYz01NDkyNTsKICB3cml0ZSh3cml0ZV9waXBlLCZmdW5jLHNpemVvZihmdW5jKSk7CiAgd3JpdGUod3JpdGVfcGlwZSwmdGltLHNpemVvZih0aW0pKTsKIH0KfQoKc3RhdGljIEJPT0wgTVpfSW5pdFRhc2sodm9pZCkKewogIGludCB3cml0ZV9mZFsyXSx4X2ZkOwogIHBpZF90IGNoaWxkOwogIGNoYXIgcGF0aFsyNTZdLCpmcGF0aDsKCiAgLyogY3JlYXRlIHBpcGVzICovCiAgaWYgKCFDcmVhdGVQaXBlKCZoUmVhZFBpcGUsJmhXcml0ZVBpcGUsTlVMTCwwKSkgcmV0dXJuIEZBTFNFOwogIGlmIChwaXBlKHdyaXRlX2ZkKTwwKSB7CiAgICBDbG9zZUhhbmRsZShoUmVhZFBpcGUpOwogICAgQ2xvc2VIYW5kbGUoaFdyaXRlUGlwZSk7CiAgICByZXR1cm4gRkFMU0U7CiAgfQoKICByZWFkX3BpcGUgPSBGSUxFX0dldFVuaXhIYW5kbGUoIGhSZWFkUGlwZSwgR0VORVJJQ19SRUFEICk7CiAgeF9mZCA9IEZJTEVfR2V0VW5peEhhbmRsZSggaFdyaXRlUGlwZSwgR0VORVJJQ19XUklURSApOwoKICBUUkFDRSgid2luMzIgcGlwZTogcmVhZD0lZCwgd3JpdGU9JWQsIHVuaXggcGlwZTogcmVhZD0lZCwgd3JpdGU9JWRcbiIsCiAgICAgICAgaFJlYWRQaXBlLGhXcml0ZVBpcGUscmVhZF9waXBlLHhfZmQpOwogIFRSQUNFKCJvdXRib3VuZCB1bml4IHBpcGU6IHJlYWQ9JWQsIHdyaXRlPSVkLCBwaWQ9JWRcbiIsd3JpdGVfZmRbMF0sd3JpdGVfZmRbMV0sZ2V0cGlkKCkpOwoKICB3cml0ZV9waXBlPXdyaXRlX2ZkWzFdOwoKICBUUkFDRSgiTG9hZGluZyBET1MgVk0gc3VwcG9ydCBtb2R1bGVcbiIpOwogIGlmICgoY2hpbGQ9Zm9yaygpKTwwKSB7CiAgICBjbG9zZSh3cml0ZV9mZFswXSk7CiAgICBjbG9zZShyZWFkX3BpcGUpOwogICAgY2xvc2Uod3JpdGVfcGlwZSk7CiAgICBjbG9zZSh4X2ZkKTsKICAgIENsb3NlSGFuZGxlKGhSZWFkUGlwZSk7CiAgICBDbG9zZUhhbmRsZShoV3JpdGVQaXBlKTsKICAgIHJldHVybiBGQUxTRTsKICB9CiBpZiAoY2hpbGQhPTApIHsKICAvKiBwYXJlbnQgcHJvY2VzcyAqLwogIGludCByZXQ7CgogIGNsb3NlKHdyaXRlX2ZkWzBdKTsKICBjbG9zZSh4X2ZkKTsKICBkb3Ntb2RfcGlkID0gY2hpbGQ7CiAgLyogd2FpdCBmb3IgY2hpbGQgcHJvY2VzcyB0byBzaWduYWwgcmVhZGluZXNzICovCiAgd2hpbGUgKDEpIHsKICAgIGlmIChyZWFkKHJlYWRfcGlwZSwmcmV0LHNpemVvZihyZXQpKT09c2l6ZW9mKHJldCkpIGJyZWFrOwogICAgaWYgKChlcnJubz09RUlOVFIpfHwoZXJybm89PUVBR0FJTikpIGNvbnRpbnVlOwogICAgLyogZmFpbHVyZSAqLwogICAgRVJSKCJkb3Ntb2QgaGFzIGZhaWxlZCB0byBpbml0aWFsaXplXG4iKTsKICAgIGlmIChtbV9uYW1lWzBdIT0wKSB1bmxpbmsobW1fbmFtZSk7CiAgICByZXR1cm4gRkFMU0U7CiAgfQogIC8qIHRoZSBjaGlsZCBoYXMgbm93IG1tYXBlZCB0aGUgdGVtcCBmaWxlLCBpdCdzIG5vdyBzYWZlIHRvIHVubGluay4KICAgKiBkbyBpdCBoZXJlIHRvIGF2b2lkIGxlYXZpbmcgYSBtZXNzIGluIC90bXAgaWYvd2hlbiBXaW5lIGNyYXNoZXMuLi4gKi8KICBpZiAobW1fbmFtZVswXSE9MCkgdW5saW5rKG1tX25hbWUpOwogIC8qIHN0YXJ0IHNpbXVsYXRlZCBzeXN0ZW0gdGltZXIgKi8KICBNWl9Jbml0VGltZXIocmV0KTsKICBpZiAocmV0PDIpIHsKICAgIEVSUigiZG9zbW9kIHZlcnNpb24gdG9vIG9sZCEgUGxlYXNlIGluc3RhbGwgbmV3ZXIgZG9zbW9kIHByb3Blcmx5XG4iKTsKICAgIEVSUigiSWYgeW91IGRvbid0LCB0aGUgbmV3IGRvc21vZCBldmVudCBoYW5kbGluZyBzeXN0ZW0gd2lsbCBub3Qgd29ya1xuIik7CiAgfQogIC8qIGFsbCBzeXN0ZW1zIGFyZSBub3cgZ28gKi8KIH0gZWxzZSB7CiAgLyogY2hpbGQgcHJvY2VzcyAqLwogIGNsb3NlKHJlYWRfcGlwZSk7CiAgY2xvc2Uod3JpdGVfcGlwZSk7CiAgLyogcHV0IG91ciBwaXBlcyBzb21ld2hlcmUgZG9zbW9kIGNhbiBmaW5kIHRoZW0gKi8KICBkdXAyKHdyaXRlX2ZkWzBdLDApOyAvKiBzdGRpbiAqLwogIGR1cDIoeF9mZCwxKTsgICAgICAgIC8qIHN0ZG91dCAqLwogIC8qIG5vdyBsb2FkIGRvc21vZCAqLwogIC8qIGNoZWNrIGFyZ3ZbMF0tZGVyaXZlZCBwYXRocyBmaXJzdCwgc2luY2UgdGhlIG5ld2VzdCBkb3Ntb2QgaXMgbW9zdCBsaWtlbHkgdGhlcmUKICAgKiAoYXQgbGVhc3QgaXQgd2FzIG9uY2UgZm9yIEFuZHJlYXMgTW9ociwgc28gSSBkZWNpZGVkIHRvIG1ha2UgaXQgZWFzaWVyIGZvciBoaW0pICovCiAgZnBhdGg9c3RycmNocihzdHJjcHkocGF0aCxmdWxsX2FyZ3YwKSwnLycpOwogIGlmIChmcGF0aCkgewogICBzdHJjcHkoZnBhdGgsIi9kb3Ntb2QiKTsKICAgZXhlY2wocGF0aCxtbV9uYW1lLE5VTEwpOwogICBzdHJjcHkoZnBhdGgsIi9sb2FkZXIvZG9zL2Rvc21vZCIpOwogICBleGVjbChwYXRoLG1tX25hbWUsTlVMTCk7CiAgfQogIC8qIG9rYXksIGl0IHdhc24ndCB0aGVyZSwgdHJ5IGluIHRoZSBwYXRoICovCiAgZXhlY2xwKCJkb3Ntb2QiLG1tX25hbWUsTlVMTCk7CiAgLyogbGFzdCBkZXNwZXJhdGUgYXR0ZW1wdHM6IGN1cnJlbnQgZGlyZWN0b3J5ICovCiAgZXhlY2woImRvc21vZCIsbW1fbmFtZSxOVUxMKTsKICAvKiBhbmQsIGp1c3QgZm9yIGNvbXBsZXRlbmVzcy4uLiAqLwogIGV4ZWNsKCJsb2FkZXIvZG9zL2Rvc21vZCIsbW1fbmFtZSxOVUxMKTsKICAvKiBpZiBmYWlsdXJlLCBleGl0ICovCiAgRVJSKCJGYWlsZWQgdG8gc3Bhd24gZG9zbW9kLCBlcnJvcj0lc1xuIixzdHJlcnJvcihlcnJubykpOwogIGV4aXQoMSk7CiB9CiByZXR1cm4gVFJVRTsKfQoKc3RhdGljIHZvaWQgTVpfTGF1bmNoKHZvaWQpCnsKICBMUERPU1RBU0sgbHBEb3NUYXNrID0gTVpfQ3VycmVudCgpOwogIENPTlRFWFQgY29udGV4dDsKICBUREIgKnBUYXNrID0gKFREQiAqKUdsb2JhbExvY2sxNiggR2V0Q3VycmVudFRhc2soKSApOwogIEJZVEUgKnBzcF9zdGFydCA9IFBUUl9SRUFMX1RPX0xJTiggbHBEb3NUYXNrLT5wc3Bfc2VnLCAwICk7CgogIE1aX0ZpbGxQU1AocHNwX3N0YXJ0LCBHZXRDb21tYW5kTGluZUEoKSk7CiAgcFRhc2stPmZsYWdzIHw9IFREQkZfV0lOT0xEQVA7CgogIG1lbXNldCggJmNvbnRleHQsIDAsIHNpemVvZihjb250ZXh0KSApOwogIGNvbnRleHQuU2VnQ3MgID0gaW5pdF9jczsKICBjb250ZXh0LkVpcCAgICA9IGluaXRfaXA7CiAgY29udGV4dC5TZWdTcyAgPSBpbml0X3NzOwogIGNvbnRleHQuRXNwICAgID0gaW5pdF9zcDsKICBjb250ZXh0LlNlZ0RzICA9IGxwRG9zVGFzay0+cHNwX3NlZzsKICBjb250ZXh0LlNlZ0VzICA9IGxwRG9zVGFzay0+cHNwX3NlZzsKICBjb250ZXh0LkVGbGFncyA9IDB4MDAwODAwMDA7ICAvKiB2aXJ0dWFsIGludGVycnVwdCBmbGFnICovCiAgRE9TVk1fRW50ZXIoICZjb250ZXh0ICk7Cn0KCnN0YXRpYyB2b2lkIE1aX0tpbGxUYXNrKHZvaWQpCnsKICBUUkFDRSgia2lsbGluZyBET1MgdGFza1xuIik7CiAgVkdBX0NsZWFuKCk7CiAga2lsbChkb3Ntb2RfcGlkLFNJR1RFUk0pOwp9CgojZWxzZSAvKiAhTVpfU1VQUE9SVEVEICovCgpCT09MIE1aX0xvYWRJbWFnZSggSE1PRFVMRSBtb2R1bGUsIEhBTkRMRSBoRmlsZSwgTFBDU1RSIGZpbGVuYW1lICkKewogV0FSTigiRE9TIGV4ZWN1dGFibGVzIG5vdCBzdXBwb3J0ZWQgb24gdGhpcyBhcmNoaXRlY3R1cmVcbiIpOwogU2V0TGFzdEVycm9yKEVSUk9SX0JBRF9GT1JNQVQpOwogcmV0dXJuIEZBTFNFOwp9CgpMUERPU1RBU0sgTVpfQWxsb2NEUE1JVGFzayggdm9pZCApCnsKICAgIEVSUigiQWN0dWFsIHJlYWwtbW9kZSBjYWxscyBub3Qgc3VwcG9ydGVkIG9uIHRoaXMgYXJjaGl0ZWN0dXJlIVxuIik7CiAgICByZXR1cm4gTlVMTDsKfQoKI2VuZGlmIC8qICFNWl9TVVBQT1JURUQgKi8KCkxQRE9TVEFTSyBNWl9DdXJyZW50KCB2b2lkICkKewogIHJldHVybiBkb3NfY3VycmVudDsKfQo=