Ly8gTmV1UXVhbnQgTmV1cmFsLU5ldCBRdWFudGl6YXRpb24gQWxnb3JpdGhtCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLwovLyBDb3B5cmlnaHQgKGMpIDE5OTQgQW50aG9ueSBEZWtrZXIKLy8KLy8gTkVVUVVBTlQgTmV1cmFsLU5ldCBxdWFudGl6YXRpb24gYWxnb3JpdGhtIGJ5IEFudGhvbnkgRGVra2VyLCAxOTk0LgovLyBTZWUgIktvaG9uZW4gbmV1cmFsIG5ldHdvcmtzIGZvciBvcHRpbWFsIGNvbG91ciBxdWFudGl6YXRpb24iCi8vIGluICJOZXR3b3JrOiBDb21wdXRhdGlvbiBpbiBOZXVyYWwgU3lzdGVtcyIgVm9sLiA1ICgxOTk0KSBwcCAzNTEtMzY3LgovLyBmb3IgYSBkaXNjdXNzaW9uIG9mIHRoZSBhbGdvcml0aG0uCi8vCi8vIEFueSBwYXJ0eSBvYnRhaW5pbmcgYSBjb3B5IG9mIHRoZXNlIGZpbGVzIGZyb20gdGhlIGF1dGhvciwgZGlyZWN0bHkgb3IKLy8gaW5kaXJlY3RseSwgaXMgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIGEgZnVsbCBhbmQgdW5yZXN0cmljdGVkIGlycmV2b2NhYmxlLAovLyB3b3JsZC13aWRlLCBwYWlkIHVwLCByb3lhbHR5LWZyZWUsIG5vbmV4Y2x1c2l2ZSByaWdodCBhbmQgbGljZW5zZSB0byBkZWFsCi8vIGluIHRoaXMgc29mdHdhcmUgYW5kIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSAiU29mdHdhcmUiKSwgaW5jbHVkaW5nIHdpdGhvdXQKLy8gbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwKLy8gYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHdobyByZWNlaXZlCi8vIGNvcGllcyBmcm9tIGFueSBzdWNoIHBhcnR5IHRvIGRvIHNvLCB3aXRoIHRoZSBvbmx5IHJlcXVpcmVtZW50IGJlaW5nCi8vIHRoYXQgdGhpcyBjb3B5cmlnaHQgbm90aWNlIHJlbWFpbiBpbnRhY3QuCgovLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwovLyBIaXN0b3J5Ci8vIC0tLS0tLS0KLy8gSmFudWFyeSAyMDAxOiBBZGFwdGF0aW9uIG9mIHRoZSBOZXVyYWwtTmV0IFF1YW50aXphdGlvbiBBbGdvcml0aG0KLy8gICAgICAgICAgICAgICBmb3IgdGhlIEZyZWVJbWFnZSAyIGxpYnJhcnkKLy8gICAgICAgICAgICAgICBBdXRob3I6IEhlcnbpIERyb2xvbiAoZHJvbG9uQGluZm9uaWUuZnIpCi8vIE1hcmNoIDIwMDQ6ICAgQWRhcHRhdGlvbiBmb3IgdGhlIEZyZWVJbWFnZSAzIGxpYnJhcnkgKHBvcnQgdG8gYmlnIGVuZGlhbiBwcm9jZXNzb3JzKQovLyAgICAgICAgICAgICAgIEF1dGhvcjogSGVydukgRHJvbG9uIChkcm9sb25AaW5mb25pZS5mcikKLy8gQXByaWwgMjAwNDogICBBbGdvcml0aG0gcmV3cml0dGVuIGFzIGEgQysrIGNsYXNzLiAKLy8gICAgICAgICAgICAgICBGaXhlZCBhIGJ1ZyBpbiB0aGUgYWxnb3JpdGhtIHdpdGggaGFuZGxpbmcgb2YgNC1ieXRlIGJvdW5kYXJ5IGFsaWdubWVudC4KLy8gICAgICAgICAgICAgICBBdXRob3I6IEhlcnbpIERyb2xvbiAoZHJvbG9uQGluZm9uaWUuZnIpCi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCgojaW5jbHVkZSAiUXVhbnRpemVycy5oIgojaW5jbHVkZSAiRnJlZUltYWdlLmgiCiNpbmNsdWRlICJVdGlsaXRpZXMuaCIKCgovLyBGb3VyIHByaW1lcyBuZWFyIDUwMCAtIGFzc3VtZSBubyBpbWFnZSBoYXMgYSBsZW5ndGggc28gbGFyZ2UKLy8gdGhhdCBpdCBpcyBkaXZpc2libGUgYnkgYWxsIGZvdXIgcHJpbWVzCi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiNkZWZpbmUgcHJpbWUxCQk0OTkKI2RlZmluZSBwcmltZTIJCTQ5MQojZGVmaW5lIHByaW1lMwkJNDg3CiNkZWZpbmUgcHJpbWU0CQk1MDMKCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCk5OUXVhbnRpemVyOjpOTlF1YW50aXplcihpbnQgUGFsZXR0ZVNpemUpCnsKCW5ldHNpemUgPSBQYWxldHRlU2l6ZTsKCW1heG5ldHBvcyA9IG5ldHNpemUgLSAxOwoJaW5pdHJhZCA9IG5ldHNpemUgPCA4ID8gMSA6IChuZXRzaXplID4+IDMpOwoJaW5pdHJhZGl1cyA9IChpbml0cmFkICogcmFkaXVzYmlhcyk7CgoJbmV0d29yayA9IE5VTEw7CgoJbmV0d29yayA9IChwaXhlbCAqKW1hbGxvYyhuZXRzaXplICogc2l6ZW9mKHBpeGVsKSk7CgliaWFzID0gKGludCAqKW1hbGxvYyhuZXRzaXplICogc2l6ZW9mKGludCkpOwoJZnJlcSA9IChpbnQgKiltYWxsb2MobmV0c2l6ZSAqIHNpemVvZihpbnQpKTsKCXJhZHBvd2VyID0gKGludCAqKW1hbGxvYyhpbml0cmFkICogc2l6ZW9mKGludCkpOwoKCWlmKCAhbmV0d29yayB8fCAhYmlhcyB8fCAhZnJlcSB8fCAhcmFkcG93ZXIgKSB7CgkJaWYobmV0d29yaykgZnJlZShuZXR3b3JrKTsKCQlpZihiaWFzKSBmcmVlKGJpYXMpOwoJCWlmKGZyZXEpIGZyZWUoZnJlcSk7CgkJaWYocmFkcG93ZXIpIGZyZWUocmFkcG93ZXIpOwoJCXRocm93IEZJX01TR19FUlJPUl9NRU1PUlk7Cgl9Cn0KCk5OUXVhbnRpemVyOjp+Tk5RdWFudGl6ZXIoKQp7CglpZihuZXR3b3JrKSBmcmVlKG5ldHdvcmspOwoJaWYoYmlhcykgZnJlZShiaWFzKTsKCWlmKGZyZXEpIGZyZWUoZnJlcSk7CglpZihyYWRwb3dlcikgZnJlZShyYWRwb3dlcik7Cn0KCi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwovLyBJbml0aWFsaXNlIG5ldHdvcmsgaW4gcmFuZ2UgKDAsMCwwKSB0byAoMjU1LDI1NSwyNTUpIGFuZCBzZXQgcGFyYW1ldGVycwovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKdm9pZCBOTlF1YW50aXplcjo6aW5pdG5ldCgpIHsKCWludCBpLCAqcDsKCglmb3IgKGkgPSAwOyBpIDwgbmV0c2l6ZTsgaSsrKSB7CgkJcCA9IG5ldHdvcmtbaV07CgkJcFtGSV9SR0JBX0JMVUVdID0gcFtGSV9SR0JBX0dSRUVOXSA9IHBbRklfUkdCQV9SRURdID0gKGkgPDwgKG5ldGJpYXNzaGlmdCs4KSkvbmV0c2l6ZTsKCQlmcmVxW2ldID0gaW50Ymlhcy9uZXRzaXplOwkvKiAxL25ldHNpemUgKi8KCQliaWFzW2ldID0gMDsKCX0KfQoKLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCQovLyBVbmJpYXMgbmV0d29yayB0byBnaXZlIGJ5dGUgdmFsdWVzIDAuLjI1NSBhbmQgcmVjb3JkIHBvc2l0aW9uIGkgdG8gcHJlcGFyZSBmb3Igc29ydAovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgTk5RdWFudGl6ZXI6OnVuYmlhc25ldCgpIHsKCWludCBpLCBqLCB0ZW1wOwoKCWZvciAoaSA9IDA7IGkgPCBuZXRzaXplOyBpKyspIHsKCQlmb3IgKGogPSAwOyBqIDwgMzsgaisrKSB7CgkJCS8vIE9MRCBDT0RFOiBuZXR3b3JrW2ldW2pdID4+PSBuZXRiaWFzc2hpZnQ7IAoJCQkvLyBGaXggYmFzZWQgb24gYnVnIHJlcG9ydCBieSBKdWVyZ2VuIFdlaWdlcnQgandAc3VzZS5kZQoJCQl0ZW1wID0gKG5ldHdvcmtbaV1bal0gKyAoMSA8PCAobmV0Ymlhc3NoaWZ0IC0gMSkpKSA+PiBuZXRiaWFzc2hpZnQ7CgkJCWlmICh0ZW1wID4gMjU1KSB0ZW1wID0gMjU1OwoJCQluZXR3b3JrW2ldW2pdID0gdGVtcDsKCQl9CgkJbmV0d29ya1tpXVszXSA9IGk7CQkJLy8gcmVjb3JkIGNvbG91ciBubyAKCX0KfQoKLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwovLyBJbnNlcnRpb24gc29ydCBvZiBuZXR3b3JrIGFuZCBidWlsZGluZyBvZiBuZXRpbmRleFswLi4yNTVdICh0byBkbyBhZnRlciB1bmJpYXMpCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgTk5RdWFudGl6ZXI6OmlueGJ1aWxkKCkgewoJaW50IGksaixzbWFsbHBvcyxzbWFsbHZhbDsKCWludCAqcCwqcTsKCWludCBwcmV2aW91c2NvbCxzdGFydHBvczsKCglwcmV2aW91c2NvbCA9IDA7CglzdGFydHBvcyA9IDA7Cglmb3IgKGkgPSAwOyBpIDwgbmV0c2l6ZTsgaSsrKSB7CgkJcCA9IG5ldHdvcmtbaV07CgkJc21hbGxwb3MgPSBpOwoJCXNtYWxsdmFsID0gcFtGSV9SR0JBX0dSRUVOXTsJCQkvLyBpbmRleCBvbiBnCgkJLy8gZmluZCBzbWFsbGVzdCBpbiBpLi5uZXRzaXplLTEKCQlmb3IgKGogPSBpKzE7IGogPCBuZXRzaXplOyBqKyspIHsKCQkJcSA9IG5ldHdvcmtbal07CgkJCWlmIChxW0ZJX1JHQkFfR1JFRU5dIDwgc21hbGx2YWwpIHsJLy8gaW5kZXggb24gZwoJCQkJc21hbGxwb3MgPSBqOwoJCQkJc21hbGx2YWwgPSBxW0ZJX1JHQkFfR1JFRU5dOwkvLyBpbmRleCBvbiBnCgkJCX0KCQl9CgkJcSA9IG5ldHdvcmtbc21hbGxwb3NdOwoJCS8vIHN3YXAgcCAoaSkgYW5kIHEgKHNtYWxscG9zKSBlbnRyaWVzCgkJaWYgKGkgIT0gc21hbGxwb3MpIHsKCQkJaiA9IHFbRklfUkdCQV9CTFVFXTsgIHFbRklfUkdCQV9CTFVFXSAgPSBwW0ZJX1JHQkFfQkxVRV07ICBwW0ZJX1JHQkFfQkxVRV0gID0gajsKCQkJaiA9IHFbRklfUkdCQV9HUkVFTl07IHFbRklfUkdCQV9HUkVFTl0gPSBwW0ZJX1JHQkFfR1JFRU5dOyBwW0ZJX1JHQkFfR1JFRU5dID0gajsKCQkJaiA9IHFbRklfUkdCQV9SRURdOyAgIHFbRklfUkdCQV9SRURdICAgPSBwW0ZJX1JHQkFfUkVEXTsgICBwW0ZJX1JHQkFfUkVEXSAgID0gajsKCQkJaiA9IHFbM107ICAgcVszXSA9IHBbM107ICAgcFszXSA9IGo7CgkJfQoJCS8vIHNtYWxsdmFsIGVudHJ5IGlzIG5vdyBpbiBwb3NpdGlvbiBpCgkJaWYgKHNtYWxsdmFsICE9IHByZXZpb3VzY29sKSB7CgkJCW5ldGluZGV4W3ByZXZpb3VzY29sXSA9IChzdGFydHBvcytpKT4+MTsKCQkJZm9yIChqID0gcHJldmlvdXNjb2wrMTsgaiA8IHNtYWxsdmFsOyBqKyspCgkJCQluZXRpbmRleFtqXSA9IGk7CgkJCXByZXZpb3VzY29sID0gc21hbGx2YWw7CgkJCXN0YXJ0cG9zID0gaTsKCQl9Cgl9CgluZXRpbmRleFtwcmV2aW91c2NvbF0gPSAoc3RhcnRwb3MrbWF4bmV0cG9zKT4+MTsKCWZvciAoaiA9IHByZXZpb3VzY29sKzE7IGogPCAyNTY7IGorKykKCQluZXRpbmRleFtqXSA9IG1heG5ldHBvczsgLy8gcmVhbGx5IDI1Ngp9CgovLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi8vIFNlYXJjaCBmb3IgQkdSIHZhbHVlcyAwLi4yNTUgKGFmdGVyIG5ldCBpcyB1bmJpYXNlZCkgYW5kIHJldHVybiBjb2xvdXIgaW5kZXgKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKaW50IE5OUXVhbnRpemVyOjppbnhzZWFyY2goaW50IGIsIGludCBnLCBpbnQgcikgewoJaW50IGksIGosIGRpc3QsIGEsIGJlc3RkOwoJaW50ICpwOwoJaW50IGJlc3Q7CgoJYmVzdGQgPSAxMDAwOwkJLy8gYmlnZ2VzdCBwb3NzaWJsZSBkaXN0IGlzIDI1NiozCgliZXN0ID0gLTE7CglpID0gbmV0aW5kZXhbZ107CS8vIGluZGV4IG9uIGcKCWogPSBpLTE7CQkJLy8gc3RhcnQgYXQgbmV0aW5kZXhbZ10gYW5kIHdvcmsgb3V0d2FyZHMKCgl3aGlsZSAoKGkgPCBuZXRzaXplKSB8fCAoaiA+PSAwKSkgewoJCWlmIChpIDwgbmV0c2l6ZSkgewoJCQlwID0gbmV0d29ya1tpXTsKCQkJZGlzdCA9IHBbRklfUkdCQV9HUkVFTl0gLSBnOwkJCQkvLyBpbngga2V5CgkJCWlmIChkaXN0ID49IGJlc3RkKQoJCQkJaSA9IG5ldHNpemU7CS8vIHN0b3AgaXRlcgoJCQllbHNlIHsKCQkJCWkrKzsKCQkJCWlmIChkaXN0IDwgMCkKCQkJCQlkaXN0ID0gLWRpc3Q7CgkJCQlhID0gcFtGSV9SR0JBX0JMVUVdIC0gYjsKCQkJCWlmIChhIDwgMCkKCQkJCQlhID0gLWE7CgkJCQlkaXN0ICs9IGE7CgkJCQlpZiAoZGlzdCA8IGJlc3RkKSB7CgkJCQkJYSA9IHBbRklfUkdCQV9SRURdIC0gcjsKCQkJCQlpZiAoYTwwKQoJCQkJCQlhID0gLWE7CgkJCQkJZGlzdCArPSBhOwoJCQkJCWlmIChkaXN0IDwgYmVzdGQpIHsKCQkJCQkJYmVzdGQgPSBkaXN0OwoJCQkJCQliZXN0ID0gcFszXTsKCQkJCQl9CgkJCQl9CgkJCX0KCQl9CgkJaWYgKGogPj0gMCkgewoJCQlwID0gbmV0d29ya1tqXTsKCQkJZGlzdCA9IGcgLSBwW0ZJX1JHQkFfR1JFRU5dOwkJCS8vIGlueCBrZXkgLSByZXZlcnNlIGRpZgoJCQlpZiAoZGlzdCA+PSBiZXN0ZCkKCQkJCWogPSAtMTsJLy8gc3RvcCBpdGVyCgkJCWVsc2UgewoJCQkJai0tOwoJCQkJaWYgKGRpc3QgPCAwKQoJCQkJCWRpc3QgPSAtZGlzdDsKCQkJCWEgPSBwW0ZJX1JHQkFfQkxVRV0gLSBiOwoJCQkJaWYgKGE8MCkKCQkJCQlhID0gLWE7CgkJCQlkaXN0ICs9IGE7CgkJCQlpZiAoZGlzdCA8IGJlc3RkKSB7CgkJCQkJYSA9IHBbRklfUkdCQV9SRURdIC0gcjsKCQkJCQlpZiAoYTwwKQoJCQkJCQlhID0gLWE7CgkJCQkJZGlzdCArPSBhOwoJCQkJCWlmIChkaXN0IDwgYmVzdGQpIHsKCQkJCQkJYmVzdGQgPSBkaXN0OwoJCQkJCQliZXN0ID0gcFszXTsKCQkJCQl9CgkJCQl9CgkJCX0KCQl9Cgl9CglyZXR1cm4gYmVzdDsKfQoKLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwovLyBTZWFyY2ggZm9yIGJpYXNlZCBCR1IgdmFsdWVzCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCmludCBOTlF1YW50aXplcjo6Y29udGVzdChpbnQgYiwgaW50IGcsIGludCByKSB7CgkvLyBmaW5kcyBjbG9zZXN0IG5ldXJvbiAobWluIGRpc3QpIGFuZCB1cGRhdGVzIGZyZXEKCS8vIGZpbmRzIGJlc3QgbmV1cm9uIChtaW4gZGlzdC1iaWFzKSBhbmQgcmV0dXJucyBwb3NpdGlvbgoJLy8gZm9yIGZyZXF1ZW50bHkgY2hvc2VuIG5ldXJvbnMsIGZyZXFbaV0gaXMgaGlnaCBhbmQgYmlhc1tpXSBpcyBuZWdhdGl2ZQoJLy8gYmlhc1tpXSA9IGdhbW1hKigoMS9uZXRzaXplKS1mcmVxW2ldKQoKCWludCBpLGRpc3QsYSxiaWFzZGlzdCxiZXRhZnJlcTsKCWludCBiZXN0cG9zLGJlc3RiaWFzcG9zLGJlc3RkLGJlc3RiaWFzZDsKCWludCAqcCwqZiwgKm47CgoJYmVzdGQgPSB+KCgoaW50KSAxKTw8MzEpOwoJYmVzdGJpYXNkID0gYmVzdGQ7CgliZXN0cG9zID0gLTE7CgliZXN0Ymlhc3BvcyA9IGJlc3Rwb3M7CglwID0gYmlhczsKCWYgPSBmcmVxOwoKCWZvciAoaSA9IDA7IGkgPCBuZXRzaXplOyBpKyspIHsKCQluID0gbmV0d29ya1tpXTsKCQlkaXN0ID0gbltGSV9SR0JBX0JMVUVdIC0gYjsKCQlpZiAoZGlzdCA8IDApCgkJCWRpc3QgPSAtZGlzdDsKCQlhID0gbltGSV9SR0JBX0dSRUVOXSAtIGc7CgkJaWYgKGEgPCAwKQoJCQlhID0gLWE7CgkJZGlzdCArPSBhOwoJCWEgPSBuW0ZJX1JHQkFfUkVEXSAtIHI7CgkJaWYgKGEgPCAwKQoJCQlhID0gLWE7CgkJZGlzdCArPSBhOwoJCWlmIChkaXN0IDwgYmVzdGQpIHsKCQkJYmVzdGQgPSBkaXN0OwoJCQliZXN0cG9zID0gaTsKCQl9CgkJYmlhc2Rpc3QgPSBkaXN0IC0gKCgqcCk+PihpbnRiaWFzc2hpZnQtbmV0Ymlhc3NoaWZ0KSk7CgkJaWYgKGJpYXNkaXN0IDwgYmVzdGJpYXNkKSB7CgkJCWJlc3RiaWFzZCA9IGJpYXNkaXN0OwoJCQliZXN0Ymlhc3BvcyA9IGk7CgkJfQoJCWJldGFmcmVxID0gKCpmID4+IGJldGFzaGlmdCk7CgkJKmYrKyAtPSBiZXRhZnJlcTsKCQkqcCsrICs9IChiZXRhZnJlcSA8PCBnYW1tYXNoaWZ0KTsKCX0KCWZyZXFbYmVzdHBvc10gKz0gYmV0YTsKCWJpYXNbYmVzdHBvc10gLT0gYmV0YWdhbW1hOwoJcmV0dXJuIGJlc3RiaWFzcG9zOwp9CgovLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi8vIE1vdmUgbmV1cm9uIGkgdG93YXJkcyBiaWFzZWQgKGIsZyxyKSBieSBmYWN0b3IgYWxwaGEKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAKCnZvaWQgTk5RdWFudGl6ZXI6OmFsdGVyc2luZ2xlKGludCBhbHBoYSwgaW50IGksIGludCBiLCBpbnQgZywgaW50IHIpIHsKCWludCAqbjsKCgluID0gbmV0d29ya1tpXTsJCQkJLy8gYWx0ZXIgaGl0IG5ldXJvbgoJbltGSV9SR0JBX0JMVUVdCSAtPSAoYWxwaGEgKiAobltGSV9SR0JBX0JMVUVdICAtIGIpKSAvIGluaXRhbHBoYTsKCW5bRklfUkdCQV9HUkVFTl0gLT0gKGFscGhhICogKG5bRklfUkdCQV9HUkVFTl0gLSBnKSkgLyBpbml0YWxwaGE7CgluW0ZJX1JHQkFfUkVEXSAgIC09IChhbHBoYSAqIChuW0ZJX1JHQkFfUkVEXSAgIC0gcikpIC8gaW5pdGFscGhhOwp9CgovLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLy8gTW92ZSBhZGphY2VudCBuZXVyb25zIGJ5IHByZWNvbXB1dGVkIGFscGhhKigxLSgoaS1qKV4yL1tyXV4yKSkgaW4gcmFkcG93ZXJbfGktanxdCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKdm9pZCBOTlF1YW50aXplcjo6YWx0ZXJuZWlnaChpbnQgcmFkLCBpbnQgaSwgaW50IGIsIGludCBnLCBpbnQgcikgewoJaW50IGosIGssIGxvLCBoaSwgYTsKCWludCAqcCwgKnE7CgoJbG8gPSBpIC0gcmFkOyAgIGlmIChsbyA8IC0xKSBsbyA9IC0xOwoJaGkgPSBpICsgcmFkOyAgIGlmIChoaSA+IG5ldHNpemUpIGhpID0gbmV0c2l6ZTsKCglqID0gaSsxOwoJayA9IGktMTsKCXEgPSByYWRwb3dlcjsKCXdoaWxlICgoaiA8IGhpKSB8fCAoayA+IGxvKSkgewoJCWEgPSAoKigrK3EpKTsKCQlpZiAoaiA8IGhpKSB7CgkJCXAgPSBuZXR3b3JrW2pdOwoJCQlwW0ZJX1JHQkFfQkxVRV0gIC09IChhICogKHBbRklfUkdCQV9CTFVFXSAtIGIpKSAvIGFscGhhcmFkYmlhczsKCQkJcFtGSV9SR0JBX0dSRUVOXSAtPSAoYSAqIChwW0ZJX1JHQkFfR1JFRU5dIC0gZykpIC8gYWxwaGFyYWRiaWFzOwoJCQlwW0ZJX1JHQkFfUkVEXSAgIC09IChhICogKHBbRklfUkdCQV9SRURdIC0gcikpIC8gYWxwaGFyYWRiaWFzOwoJCQlqKys7CgkJfQoJCWlmIChrID4gbG8pIHsKCQkJcCA9IG5ldHdvcmtba107CgkJCXBbRklfUkdCQV9CTFVFXSAgLT0gKGEgKiAocFtGSV9SR0JBX0JMVUVdIC0gYikpIC8gYWxwaGFyYWRiaWFzOwoJCQlwW0ZJX1JHQkFfR1JFRU5dIC09IChhICogKHBbRklfUkdCQV9HUkVFTl0gLSBnKSkgLyBhbHBoYXJhZGJpYXM7CgkJCXBbRklfUkdCQV9SRURdICAgLT0gKGEgKiAocFtGSV9SR0JBX1JFRF0gLSByKSkgLyBhbHBoYXJhZGJpYXM7CgkJCWstLTsKCQl9Cgl9Cn0KCi8vLy8vLy8vLy8vLy8vLy8vLy8vLwovLyBNYWluIExlYXJuaW5nIExvb3AKLy8gLS0tLS0tLS0tLS0tLS0tLS0tCgovKioKIEdldCBhIHBpeGVsIHNhbXBsZSBhdCBwb3NpdGlvbiBwb3MuIEhhbmRsZSA0LWJ5dGUgYm91bmRhcnkgYWxpZ25tZW50LgogQHBhcmFtIHBvcyBwaXhlbCBwb3NpdGlvbiBpbiBhIFd4SHgzIHBpeGVsIGJ1ZmZlcgogQHBhcmFtIGIgYmx1ZSBwaXhlbCBjb21wb25lbnQKIEBwYXJhbSBnIGdyZWVuIHBpeGVsIGNvbXBvbmVudAogQHBhcmFtIHIgcmVkIHBpeGVsIGNvbXBvbmVudAoqLwp2b2lkIE5OUXVhbnRpemVyOjpnZXRTYW1wbGUobG9uZyBwb3MsIGludCAqYiwgaW50ICpnLCBpbnQgKnIpIHsKCS8vIGdldCBlcXVpdmFsZW50IHBpeGVsIGNvb3JkaW5hdGVzIAoJLy8gLSBhc3N1bWUgaXQncyBhIDI0LWJpdCBpbWFnZSAtCglpbnQgeCA9IHBvcyAlIGltZ19saW5lOwoJaW50IHkgPSBwb3MgLyBpbWdfbGluZTsKCglCWVRFICpiaXRzID0gRnJlZUltYWdlX0dldFNjYW5MaW5lKGRpYl9wdHIsIHkpICsgeDsKCgkqYiA9IGJpdHNbRklfUkdCQV9CTFVFXSA8PCBuZXRiaWFzc2hpZnQ7CgkqZyA9IGJpdHNbRklfUkdCQV9HUkVFTl0gPDwgbmV0Ymlhc3NoaWZ0OwoJKnIgPSBiaXRzW0ZJX1JHQkFfUkVEXSA8PCBuZXRiaWFzc2hpZnQ7Cn0KCnZvaWQgTk5RdWFudGl6ZXI6OmxlYXJuKGludCBzYW1wbGluZ19mYWN0b3IpIHsKCWludCBpLCBqLCBiLCBnLCByOwoJaW50IHJhZGl1cywgcmFkLCBhbHBoYSwgc3RlcCwgZGVsdGEsIHNhbXBsZXBpeGVsczsKCWludCBhbHBoYWRlYzsgLy8gYmlhc2VkIGJ5IDEwIGJpdHMKCWxvbmcgcG9zLCBsZW5ndGhjb3VudDsKCgkvLyBpbWFnZSBzaXplIGFzIHZpZXdlZCBieSB0aGUgc2NhbiBhbGdvcml0aG0KCWxlbmd0aGNvdW50ID0gaW1nX3dpZHRoICogaW1nX2hlaWdodCAqIDM7CgoJLy8gbnVtYmVyIG9mIHNhbXBsZXMgdXNlZCBmb3IgdGhlIGxlYXJuaW5nIHBoYXNlCglzYW1wbGVwaXhlbHMgPSBsZW5ndGhjb3VudCAvICgzICogc2FtcGxpbmdfZmFjdG9yKTsKCgkvLyBkZWNyZWFzZSBsZWFybmluZyByYXRlIGFmdGVyIGRlbHRhIHBpeGVsIHByZXNlbnRhdGlvbnMKCWRlbHRhID0gc2FtcGxlcGl4ZWxzIC8gbmN5Y2xlczsKCWlmKGRlbHRhID09IDApIHsKCQkvLyBhdm9pZCBhICdkaXZpZGUgYnkgemVybycgZXJyb3Igd2l0aCB2ZXJ5IHNtYWxsIGltYWdlcwoJCWRlbHRhID0gMTsKCX0KCgkvLyBpbml0aWFsaXplIGxlYXJuaW5nIHBhcmFtZXRlcnMKCWFscGhhZGVjID0gMzAgKyAoKHNhbXBsaW5nX2ZhY3RvciAtIDEpIC8gMyk7CglhbHBoYSA9IGluaXRhbHBoYTsKCXJhZGl1cyA9IGluaXRyYWRpdXM7CgkKCXJhZCA9IHJhZGl1cyA+PiByYWRpdXNiaWFzc2hpZnQ7CglpZiAocmFkIDw9IDEpIHJhZCA9IDA7Cglmb3IgKGkgPSAwOyBpIDwgcmFkOyBpKyspIAoJCXJhZHBvd2VyW2ldID0gYWxwaGEqKCgocmFkKnJhZCAtIGkqaSkqcmFkYmlhcykvKHJhZCpyYWQpKTsKCQoJLy8gaW5pdGlhbGl6ZSBwc2V1ZG8tcmFuZG9tIHNjYW4KCWlmICgobGVuZ3RoY291bnQgJSBwcmltZTEpICE9IDApCgkJc3RlcCA9IDMqcHJpbWUxOwoJZWxzZSB7CgkJaWYgKChsZW5ndGhjb3VudCAlIHByaW1lMikgIT0gMCkKCQkJc3RlcCA9IDMqcHJpbWUyOwoJCWVsc2UgewoJCQlpZiAoKGxlbmd0aGNvdW50ICUgcHJpbWUzKSAhPSAwKSAKCQkJCXN0ZXAgPSAzKnByaW1lMzsKCQkJZWxzZQoJCQkJc3RlcCA9IDMqcHJpbWU0OwoJCX0KCX0KCQoJaSA9IDA7CQkvLyBpdGVyYXRpb24KCXBvcyA9IDA7CS8vIHBpeGVsIHBvc2l0aW9uCgoJd2hpbGUgKGkgPCBzYW1wbGVwaXhlbHMpIHsKCQkvLyBnZXQgbmV4dCBsZWFybmluZyBzYW1wbGUKCQlnZXRTYW1wbGUocG9zLCAmYiwgJmcsICZyKTsKCgkJLy8gZmluZCB3aW5uaW5nIG5ldXJvbgoJCWogPSBjb250ZXN0KGIsIGcsIHIpOwoKCQkvLyBhbHRlciB3aW5uZXIKCQlhbHRlcnNpbmdsZShhbHBoYSwgaiwgYiwgZywgcik7CgoJCS8vIGFsdGVyIG5laWdoYm91cnMgCgkJaWYgKHJhZCkgYWx0ZXJuZWlnaChyYWQsIGosIGIsIGcsIHIpOwoKCQkvLyBuZXh0IHNhbXBsZQoJCXBvcyArPSBzdGVwOwoJCXdoaWxlIChwb3MgPj0gbGVuZ3RoY291bnQpIHBvcyAtPSBsZW5ndGhjb3VudDsKCQoJCWkrKzsKCQlpZiAoaSAlIGRlbHRhID09IDApIHsJCgkJCS8vIGRlY3JlYXNlIGxlYXJuaW5nIHJhdGUgYW5kIGFsc28gdGhlIG5laWdoYm9yaG9vZAoJCQlhbHBoYSAtPSBhbHBoYSAvIGFscGhhZGVjOwoJCQlyYWRpdXMgLT0gcmFkaXVzIC8gcmFkaXVzZGVjOwoJCQlyYWQgPSByYWRpdXMgPj4gcmFkaXVzYmlhc3NoaWZ0OwoJCQlpZiAocmFkIDw9IDEpIHJhZCA9IDA7CgkJCWZvciAoaiA9IDA7IGogPCByYWQ7IGorKykgCgkJCQlyYWRwb3dlcltqXSA9IGFscGhhICogKCgocmFkKnJhZCAtIGoqaikgKiByYWRiaWFzKSAvIChyYWQqcmFkKSk7CgkJfQoJfQoJCn0KCi8vLy8vLy8vLy8vLy8vCi8vIFF1YW50aXplcgovLyAtLS0tLS0tLS0tLQoKRklCSVRNQVAqIE5OUXVhbnRpemVyOjpRdWFudGl6ZShGSUJJVE1BUCAqZGliLCBpbnQgUmVzZXJ2ZVNpemUsIFJHQlFVQUQgKlJlc2VydmVQYWxldHRlLCBpbnQgc2FtcGxpbmcpIHsKCglpZiAoKCFkaWIpIHx8IChGcmVlSW1hZ2VfR2V0QlBQKGRpYikgIT0gMjQpKSB7CgkJcmV0dXJuIE5VTEw7Cgl9CgoJLy8gMSkgU2VsZWN0IGEgc2FtcGxpbmcgZmFjdG9yIGluIHJhbmdlIDEuLjMwIChpbnB1dCBwYXJhbWV0ZXIgJ3NhbXBsaW5nJykKCS8vICAgIDEgPT4gc2xvd2VyLCAzMCA9PiBmYXN0ZXIuIERlZmF1bHQgdmFsdWUgaXMgMQoKCgkvLyAyKSBHZXQgRElCIHBhcmFtZXRlcnMKCglkaWJfcHRyID0gZGliOwoJCglpbWdfd2lkdGggID0gRnJlZUltYWdlX0dldFdpZHRoKGRpYik7CS8vIERJQiB3aWR0aAoJaW1nX2hlaWdodCA9IEZyZWVJbWFnZV9HZXRIZWlnaHQoZGliKTsJLy8gRElCIGhlaWdodAoJaW1nX2xpbmUgICA9IEZyZWVJbWFnZV9HZXRMaW5lKGRpYik7CS8vIERJQiBsaW5lIGxlbmd0aCBpbiBieXRlcyAoc2hvdWxkIGJlIGVxdWFsIHRvIDMgeCBXKQoKCS8vIEZvciBzbWFsbCBpbWFnZXMsIGFkanVzdCB0aGUgc2FtcGxpbmcgZmFjdG9yIHRvIGF2b2lkIGEgJ2RpdmlkZSBieSB6ZXJvJyBlcnJvciBsYXRlciAKCS8vIChzZWUgZGVsdGEgaW4gbGVhcm4oKSByb3V0aW5lKQoJaW50IGFkanVzdCA9IChpbWdfd2lkdGggKiBpbWdfaGVpZ2h0KSAvIG5jeWNsZXM7CglpZihzYW1wbGluZyA+PSBhZGp1c3QpCgkJc2FtcGxpbmcgPSAxOwoKCgkvLyAzKSBJbml0aWFsaXplIHRoZSBuZXR3b3JrIGFuZCBhcHBseSB0aGUgbGVhcm5pbmcgYWxnb3JpdGhtCgoJaWYoIG5ldHNpemUgPiBSZXNlcnZlU2l6ZSApIHsKCQluZXRzaXplIC09IFJlc2VydmVTaXplOwoJCWluaXRuZXQoKTsKCQlsZWFybihzYW1wbGluZyk7CgkJdW5iaWFzbmV0KCk7CgkJbmV0c2l6ZSArPSBSZXNlcnZlU2l6ZTsKCX0KCgkvLyAzLjUpIE92ZXJ3cml0ZSB0aGUgbGFzdCBmZXcgcGFsZXR0ZSBlbnRyaWVzIHdpdGggdGhlIHJlc2VydmVkIG9uZXMKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgUmVzZXJ2ZVNpemU7IGkrKykgewoJCW5ldHdvcmtbbmV0c2l6ZSAtIFJlc2VydmVTaXplICsgaV1bRklfUkdCQV9CTFVFXSA9IFJlc2VydmVQYWxldHRlW2ldLnJnYkJsdWU7CgkJbmV0d29ya1tuZXRzaXplIC0gUmVzZXJ2ZVNpemUgKyBpXVtGSV9SR0JBX0dSRUVOXSA9IFJlc2VydmVQYWxldHRlW2ldLnJnYkdyZWVuOwoJCW5ldHdvcmtbbmV0c2l6ZSAtIFJlc2VydmVTaXplICsgaV1bRklfUkdCQV9SRURdID0gUmVzZXJ2ZVBhbGV0dGVbaV0ucmdiUmVkOwoJCW5ldHdvcmtbbmV0c2l6ZSAtIFJlc2VydmVTaXplICsgaV1bM10gPSBuZXRzaXplIC0gUmVzZXJ2ZVNpemUgKyBpOwoJfQoKCS8vIDQpIEFsbG9jYXRlIGEgbmV3IDgtYml0IERJQgoKCUZJQklUTUFQICpuZXdfZGliID0gRnJlZUltYWdlX0FsbG9jYXRlKGltZ193aWR0aCwgaW1nX2hlaWdodCwgOCk7CgoJaWYgKG5ld19kaWIgPT0gTlVMTCkKCQlyZXR1cm4gTlVMTDsKCgkvLyA1KSBXcml0ZSB0aGUgcXVhbnRpemVkIHBhbGV0dGUKCglSR0JRVUFEICpuZXdfcGFsID0gRnJlZUltYWdlX0dldFBhbGV0dGUobmV3X2RpYik7CgogICAgZm9yIChpbnQgaiA9IDA7IGogPCBuZXRzaXplOyBqKyspIHsKCQluZXdfcGFsW2pdLnJnYkJsdWUgID0gKEJZVEUpbmV0d29ya1tqXVtGSV9SR0JBX0JMVUVdOwoJCW5ld19wYWxbal0ucmdiR3JlZW4gPSAoQllURSluZXR3b3JrW2pdW0ZJX1JHQkFfR1JFRU5dOwoJCW5ld19wYWxbal0ucmdiUmVkCT0gKEJZVEUpbmV0d29ya1tqXVtGSV9SR0JBX1JFRF07Cgl9CgoJaW54YnVpbGQoKTsKCgkvLyA2KSBXcml0ZSBvdXRwdXQgaW1hZ2UgdXNpbmcgaW54c2VhcmNoKGIsZyxyKQoKCWZvciAoV09SRCByb3dzID0gMDsgcm93cyA8IGltZ19oZWlnaHQ7IHJvd3MrKykgewoJCUJZVEUgKm5ld19iaXRzID0gRnJlZUltYWdlX0dldFNjYW5MaW5lKG5ld19kaWIsIHJvd3MpOwkJCQoJCUJZVEUgKmJpdHMgPSBGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZGliX3B0ciwgcm93cyk7CgoJCWZvciAoV09SRCBjb2xzID0gMDsgY29scyA8IGltZ193aWR0aDsgY29scysrKSB7CgkJCW5ld19iaXRzW2NvbHNdID0gKEJZVEUpaW54c2VhcmNoKGJpdHNbRklfUkdCQV9CTFVFXSwgYml0c1tGSV9SR0JBX0dSRUVOXSwgYml0c1tGSV9SR0JBX1JFRF0pOwoKCQkJYml0cyArPSAzOwoJCX0KCX0KCglyZXR1cm4gKEZJQklUTUFQKikgbmV3X2RpYjsKfQo=