Ly89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8KLy8gU3BsYXNoQml0bWFwLmNjCi8vCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLwovLyBNb2RpZmllZCB1bmRlciB0aGUgUG9wcGxlciBwcm9qZWN0IC0gaHR0cDovL3BvcHBsZXIuZnJlZWRlc2t0b3Aub3JnCi8vCi8vIEFsbCBjaGFuZ2VzIG1hZGUgdW5kZXIgdGhlIFBvcHBsZXIgcHJvamVjdCB0byB0aGlzIGZpbGUgYXJlIGxpY2Vuc2VkCi8vIHVuZGVyIEdQTCB2ZXJzaW9uIDIgb3IgbGF0ZXIKLy8KLy8gQ29weXJpZ2h0IChDKSAyMDA2LCAyMDA5LCAyMDEwLCAyMDEyLCAyMDE1IEFsYmVydCBBc3RhbHMgQ2lkIDxhYWNpZEBrZGUub3JnPgovLyBDb3B5cmlnaHQgKEMpIDIwMDcgSWxtYXJpIEhlaWtraW5lbiA8aWxtYXJpLmhlaWtraW5lbkBnbWFpbC5jb20+Ci8vIENvcHlyaWdodCAoQykgMjAwOSBTaGVuIExpYW5nIDxzaGVuemh1eGlAZ21haWwuY29tPgovLyBDb3B5cmlnaHQgKEMpIDIwMDkgU3RlZmFuIFRob21hcyA8dGhvbWFzQGVsb2FkMjQuY29tPgovLyBDb3B5cmlnaHQgKEMpIDIwMTAsIDIwMTIgQWRyaWFuIEpvaG5zb24gPGFqb2huc29uQHJlZG5lb24uY29tPgovLyBDb3B5cmlnaHQgKEMpIDIwMTAgSGFycnkgUm9iZXJ0cyA8aGFycnkucm9iZXJ0c0BtaWRuaWdodC1sYWJzLm9yZz4KLy8gQ29weXJpZ2h0IChDKSAyMDEwIENocmlzdGlhbiBGZXVlcnPkbmdlciA8Y2ZldWVyc2FlbmdlckBnb29nbGVtYWlsLmNvbT4KLy8gQ29weXJpZ2h0IChDKSAyMDEwLCAyMDE1IFdpbGxpYW0gQmFkZXIgPHdpbGxpYW1iYWRlckBob3RtYWlsLmNvbT4KLy8gQ29weXJpZ2h0IChDKSAyMDExLTIwMTMgVGhvbWFzIEZyZWl0YWcgPFRob21hcy5GcmVpdGFnQGFsZmEuZGU+Ci8vIENvcHlyaWdodCAoQykgMjAxMiBBbnRob255IFdlc2xleSA8YXdlc2xleUBzbWFydG5ldHdvcmtzLmNvbS5hdT4KLy8gQ29weXJpZ2h0IChDKSAyMDE1IEFkYW0gUmVpY2hvbGQgPGFkYW1yZWljaG9sZEBteW9wZXJhLmNvbT4KLy8KLy8gVG8gc2VlIGEgZGVzY3JpcHRpb24gb2YgdGhlIGNoYW5nZXMgcGxlYXNlIHNlZSB0aGUgQ2hhbmdlbG9nIGZpbGUgdGhhdAovLyBjYW1lIHdpdGggeW91ciB0YXJiYWxsIG9yIHR5cGUgbWFrZSBDaGFuZ2VMb2cgaWYgeW91IGFyZSBidWlsZGluZyBmcm9tIGdpdAovLwovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKI2luY2x1ZGUgPGNvbmZpZy5oPgoKI2lmZGVmIFVTRV9HQ0NfUFJBR01BUwojcHJhZ21hIGltcGxlbWVudGF0aW9uCiNlbmRpZgoKI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8bGltaXRzLmg+CiNpbmNsdWRlICJnb28vZ21lbS5oIgojaW5jbHVkZSAiU3BsYXNoRXJyb3JDb2Rlcy5oIgojaW5jbHVkZSAiU3BsYXNoQml0bWFwLmgiCiNpbmNsdWRlICJwb3BwbGVyL0Vycm9yLmgiCiNpbmNsdWRlICJnb28vSnBlZ1dyaXRlci5oIgojaW5jbHVkZSAiZ29vL1BOR1dyaXRlci5oIgojaW5jbHVkZSAiZ29vL1RpZmZXcml0ZXIuaCIKI2luY2x1ZGUgImdvby9JbWdXcml0ZXIuaCIKI2luY2x1ZGUgImdvby9Hb29MaXN0LmgiCgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyBTcGxhc2hCaXRtYXAKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KClNwbGFzaEJpdG1hcDo6U3BsYXNoQml0bWFwKGludCB3aWR0aEEsIGludCBoZWlnaHRBLCBpbnQgcm93UGFkQSwKCQkJICAgU3BsYXNoQ29sb3JNb2RlIG1vZGVBLCBHQm9vbCBhbHBoYUEsCgkJCSAgIEdCb29sIHRvcERvd24sIEdvb0xpc3QgKnNlcGFyYXRpb25MaXN0QSkgewogIHdpZHRoID0gd2lkdGhBOwogIGhlaWdodCA9IGhlaWdodEE7CiAgbW9kZSA9IG1vZGVBOwogIHJvd1BhZCA9IHJvd1BhZEE7CiAgc3dpdGNoIChtb2RlKSB7CiAgY2FzZSBzcGxhc2hNb2RlTW9ubzE6CiAgICBpZiAod2lkdGggPiAwKSB7CiAgICAgIHJvd1NpemUgPSAod2lkdGggKyA3KSA+PiAzOwogICAgfSBlbHNlIHsKICAgICAgcm93U2l6ZSA9IC0xOwogICAgfQogICAgYnJlYWs7CiAgY2FzZSBzcGxhc2hNb2RlTW9ubzg6CiAgICBpZiAod2lkdGggPiAwKSB7CiAgICAgIHJvd1NpemUgPSB3aWR0aDsKICAgIH0gZWxzZSB7CiAgICAgIHJvd1NpemUgPSAtMTsKICAgIH0KICAgIGJyZWFrOwogIGNhc2Ugc3BsYXNoTW9kZVJHQjg6CiAgY2FzZSBzcGxhc2hNb2RlQkdSODoKICAgIGlmICh3aWR0aCA+IDAgJiYgd2lkdGggPD0gSU5UX01BWCAvIDMpIHsKICAgICAgcm93U2l6ZSA9IHdpZHRoICogMzsKICAgIH0gZWxzZSB7CiAgICAgIHJvd1NpemUgPSAtMTsKICAgIH0KICAgIGJyZWFrOwogIGNhc2Ugc3BsYXNoTW9kZVhCR1I4OgogICAgaWYgKHdpZHRoID4gMCAmJiB3aWR0aCA8PSBJTlRfTUFYIC8gNCkgewogICAgICByb3dTaXplID0gd2lkdGggKiA0OwogICAgfSBlbHNlIHsKICAgICAgcm93U2l6ZSA9IC0xOwogICAgfQogICAgYnJlYWs7CiNpZiBTUExBU0hfQ01ZSwogIGNhc2Ugc3BsYXNoTW9kZUNNWUs4OgogICAgaWYgKHdpZHRoID4gMCAmJiB3aWR0aCA8PSBJTlRfTUFYIC8gNCkgewogICAgICByb3dTaXplID0gd2lkdGggKiA0OwogICAgfSBlbHNlIHsKICAgICAgcm93U2l6ZSA9IC0xOwogICAgfQogICAgYnJlYWs7CiAgY2FzZSBzcGxhc2hNb2RlRGV2aWNlTjg6CiAgICBpZiAod2lkdGggPiAwICYmIHdpZHRoIDw9IElOVF9NQVggLyA0KSB7CiAgICAgIHJvd1NpemUgPSB3aWR0aCAqIChTUE9UX05DT01QUyArIDQpOwogICAgfSBlbHNlIHsKICAgICAgcm93U2l6ZSA9IC0xOwogICAgfQogICAgYnJlYWs7CiNlbmRpZgogIH0KICBpZiAocm93U2l6ZSA+IDApIHsKICAgIHJvd1NpemUgKz0gcm93UGFkIC0gMTsKICAgIHJvd1NpemUgLT0gcm93U2l6ZSAlIHJvd1BhZDsKICB9CiAgZGF0YSA9IChTcGxhc2hDb2xvclB0cilnbWFsbG9jbl9jaGVja292ZXJmbG93KHJvd1NpemUsIGhlaWdodCk7CiAgaWYgKGRhdGEgIT0gTlVMTCkgewogICAgaWYgKCF0b3BEb3duKSB7CiAgICAgIGRhdGEgKz0gKGhlaWdodCAtIDEpICogcm93U2l6ZTsKICAgICAgcm93U2l6ZSA9IC1yb3dTaXplOwogICAgfQogICAgaWYgKGFscGhhQSkgewogICAgICBhbHBoYSA9IChHdWNoYXIgKilnbWFsbG9jbih3aWR0aCwgaGVpZ2h0KTsKICAgIH0gZWxzZSB7CiAgICAgIGFscGhhID0gTlVMTDsKICAgIH0KICB9IGVsc2UgewogICAgYWxwaGEgPSBOVUxMOwogIH0KICBzZXBhcmF0aW9uTGlzdCA9IG5ldyBHb29MaXN0KCk7CiAgaWYgKHNlcGFyYXRpb25MaXN0QSAhPSBOVUxMKQogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzZXBhcmF0aW9uTGlzdEEtPmdldExlbmd0aCgpOyBpKyspCiAgICAgIHNlcGFyYXRpb25MaXN0LT5hcHBlbmQoKChHZnhTZXBhcmF0aW9uQ29sb3JTcGFjZSAqKSBzZXBhcmF0aW9uTGlzdEEtPmdldChpKSktPmNvcHkoKSk7Cn0KClNwbGFzaEJpdG1hcCAqU3BsYXNoQml0bWFwOjpjb3B5KFNwbGFzaEJpdG1hcCAqc3JjKSB7CiAgU3BsYXNoQml0bWFwICpyZXN1bHQgPSBuZXcgU3BsYXNoQml0bWFwKHNyYy0+Z2V0V2lkdGgoKSwgc3JjLT5nZXRIZWlnaHQoKSwgc3JjLT5nZXRSb3dQYWQoKSwgCiAgICBzcmMtPmdldE1vZGUoKSwgc3JjLT5nZXRBbHBoYVB0cigpICE9IE5VTEwsIHNyYy0+Z2V0Um93U2l6ZSgpID49IDAsIHNyYy0+Z2V0U2VwYXJhdGlvbkxpc3QoKSk7CiAgR3VjaGFyICpkYXRhU291cmNlID0gc3JjLT5nZXREYXRhUHRyKCk7CiAgR3VjaGFyICpkYXRhRGVzdCA9IHJlc3VsdC0+Z2V0RGF0YVB0cigpOwogIGludCBhbW91bnQgPSBzcmMtPmdldFJvd1NpemUoKTsKICBpZiAoYW1vdW50IDwgMCkgewogICAgZGF0YVNvdXJjZSA9IGRhdGFTb3VyY2UgKyAoc3JjLT5nZXRIZWlnaHQoKSAtIDEpICogYW1vdW50OwogICAgZGF0YURlc3QgPSBkYXRhRGVzdCArIChzcmMtPmdldEhlaWdodCgpIC0gMSkgKiBhbW91bnQ7CiAgICBhbW91bnQgKj0gLXNyYy0+Z2V0SGVpZ2h0KCk7CiAgfSBlbHNlIHsKICAgIGFtb3VudCAqPSBzcmMtPmdldEhlaWdodCgpOwogIH0KICBtZW1jcHkoZGF0YURlc3QsIGRhdGFTb3VyY2UsIGFtb3VudCk7CiAgaWYgKHNyYy0+Z2V0QWxwaGFQdHIoKSAhPSBOVUxMKSB7CiAgICBtZW1jcHkocmVzdWx0LT5nZXRBbHBoYVB0cigpLCBzcmMtPmdldEFscGhhUHRyKCksIHNyYy0+Z2V0V2lkdGgoKSAqIHNyYy0+Z2V0SGVpZ2h0KCkpOwogIH0KICByZXR1cm4gcmVzdWx0Owp9CgpTcGxhc2hCaXRtYXA6On5TcGxhc2hCaXRtYXAoKSB7CiAgaWYgKGRhdGEpIHsKICAgIGlmIChyb3dTaXplIDwgMCkgewogICAgICBnZnJlZShkYXRhICsgKGhlaWdodCAtIDEpICogcm93U2l6ZSk7CiAgICB9IGVsc2UgewogICAgICBnZnJlZShkYXRhKTsKICAgIH0KICB9CiAgZ2ZyZWUoYWxwaGEpOwogIGRlbGV0ZUdvb0xpc3Qoc2VwYXJhdGlvbkxpc3QsIEdmeFNlcGFyYXRpb25Db2xvclNwYWNlKTsKfQoKClNwbGFzaEVycm9yIFNwbGFzaEJpdG1hcDo6d3JpdGVQTk1GaWxlKGNoYXIgKmZpbGVOYW1lKSB7CiAgRklMRSAqZjsKICBTcGxhc2hFcnJvciBlOwoKICBpZiAoIShmID0gZm9wZW4oZmlsZU5hbWUsICJ3YiIpKSkgewogICAgcmV0dXJuIHNwbGFzaEVyck9wZW5GaWxlOwogIH0KCiAgZSA9IHRoaXMtPndyaXRlUE5NRmlsZShmKTsKICAKICBmY2xvc2UoZik7CiAgcmV0dXJuIGU7Cn0KCgpTcGxhc2hFcnJvciBTcGxhc2hCaXRtYXA6OndyaXRlUE5NRmlsZShGSUxFICpmKSB7CiAgU3BsYXNoQ29sb3JQdHIgcm93LCBwOwogIGludCB4LCB5OwoKICBzd2l0Y2ggKG1vZGUpIHsKCiAgY2FzZSBzcGxhc2hNb2RlTW9ubzE6CiAgICBmcHJpbnRmKGYsICJQNFxuJWQgJWRcbiIsIHdpZHRoLCBoZWlnaHQpOwogICAgcm93ID0gZGF0YTsKICAgIGZvciAoeSA9IDA7IHkgPCBoZWlnaHQ7ICsreSkgewogICAgICBwID0gcm93OwogICAgICBmb3IgKHggPSAwOyB4IDwgd2lkdGg7IHggKz0gOCkgewoJZnB1dGMoKnAgXiAweGZmLCBmKTsKCSsrcDsKICAgICAgfQogICAgICByb3cgKz0gcm93U2l6ZTsKICAgIH0KICAgIGJyZWFrOwoKICBjYXNlIHNwbGFzaE1vZGVNb25vODoKICAgIGZwcmludGYoZiwgIlA1XG4lZCAlZFxuMjU1XG4iLCB3aWR0aCwgaGVpZ2h0KTsKICAgIHJvdyA9IGRhdGE7CiAgICBmb3IgKHkgPSAwOyB5IDwgaGVpZ2h0OyArK3kpIHsKICAgICAgZndyaXRlKHJvdywgMSwgd2lkdGgsIGYpOwogICAgICByb3cgKz0gcm93U2l6ZTsKICAgIH0KICAgIGJyZWFrOwoKICBjYXNlIHNwbGFzaE1vZGVSR0I4OgogICAgZnByaW50ZihmLCAiUDZcbiVkICVkXG4yNTVcbiIsIHdpZHRoLCBoZWlnaHQpOwogICAgcm93ID0gZGF0YTsKICAgIGZvciAoeSA9IDA7IHkgPCBoZWlnaHQ7ICsreSkgewogICAgICBmd3JpdGUocm93LCAxLCAzICogd2lkdGgsIGYpOwogICAgICByb3cgKz0gcm93U2l6ZTsKICAgIH0KICAgIGJyZWFrOwoKICBjYXNlIHNwbGFzaE1vZGVYQkdSODoKICAgIGZwcmludGYoZiwgIlA2XG4lZCAlZFxuMjU1XG4iLCB3aWR0aCwgaGVpZ2h0KTsKICAgIHJvdyA9IGRhdGE7CiAgICBmb3IgKHkgPSAwOyB5IDwgaGVpZ2h0OyArK3kpIHsKICAgICAgcCA9IHJvdzsKICAgICAgZm9yICh4ID0gMDsgeCA8IHdpZHRoOyArK3gpIHsKCWZwdXRjKHNwbGFzaEJHUjhSKHApLCBmKTsKCWZwdXRjKHNwbGFzaEJHUjhHKHApLCBmKTsKCWZwdXRjKHNwbGFzaEJHUjhCKHApLCBmKTsKCXAgKz0gNDsKICAgICAgfQogICAgICByb3cgKz0gcm93U2l6ZTsKICAgIH0KICAgIGJyZWFrOwoKCiAgY2FzZSBzcGxhc2hNb2RlQkdSODoKICAgIGZwcmludGYoZiwgIlA2XG4lZCAlZFxuMjU1XG4iLCB3aWR0aCwgaGVpZ2h0KTsKICAgIHJvdyA9IGRhdGE7CiAgICBmb3IgKHkgPSAwOyB5IDwgaGVpZ2h0OyArK3kpIHsKICAgICAgcCA9IHJvdzsKICAgICAgZm9yICh4ID0gMDsgeCA8IHdpZHRoOyArK3gpIHsKCWZwdXRjKHNwbGFzaEJHUjhSKHApLCBmKTsKCWZwdXRjKHNwbGFzaEJHUjhHKHApLCBmKTsKCWZwdXRjKHNwbGFzaEJHUjhCKHApLCBmKTsKCXAgKz0gMzsKICAgICAgfQogICAgICByb3cgKz0gcm93U2l6ZTsKICAgIH0KICAgIGJyZWFrOwoKI2lmIFNQTEFTSF9DTVlLCiAgY2FzZSBzcGxhc2hNb2RlQ01ZSzg6CiAgY2FzZSBzcGxhc2hNb2RlRGV2aWNlTjg6CiAgICAvLyBQTk0gZG9lc24ndCBzdXBwb3J0IENNWUsKICAgIGVycm9yKGVyckludGVybmFsLCAtMSwgInVuc3VwcG9ydGVkIFNwbGFzaEJpdG1hcCBtb2RlIik7CiAgICByZXR1cm4gc3BsYXNoRXJyR2VuZXJpYzsKICAgIGJyZWFrOwojZW5kaWYKICB9CiAgcmV0dXJuIHNwbGFzaE9rOwp9CgpTcGxhc2hFcnJvciBTcGxhc2hCaXRtYXA6OndyaXRlQWxwaGFQR01GaWxlKGNoYXIgKmZpbGVOYW1lKSB7CiAgRklMRSAqZjsKCiAgaWYgKCFhbHBoYSkgewogICAgcmV0dXJuIHNwbGFzaEVyck1vZGVNaXNtYXRjaDsKICB9CiAgaWYgKCEoZiA9IGZvcGVuKGZpbGVOYW1lLCAid2IiKSkpIHsKICAgIHJldHVybiBzcGxhc2hFcnJPcGVuRmlsZTsKICB9CiAgZnByaW50ZihmLCAiUDVcbiVkICVkXG4yNTVcbiIsIHdpZHRoLCBoZWlnaHQpOwogIGZ3cml0ZShhbHBoYSwgMSwgd2lkdGggKiBoZWlnaHQsIGYpOwogIGZjbG9zZShmKTsKICByZXR1cm4gc3BsYXNoT2s7Cn0KCnZvaWQgU3BsYXNoQml0bWFwOjpnZXRQaXhlbChpbnQgeCwgaW50IHksIFNwbGFzaENvbG9yUHRyIHBpeGVsKSB7CiAgU3BsYXNoQ29sb3JQdHIgcDsKCiAgaWYgKHkgPCAwIHx8IHkgPj0gaGVpZ2h0IHx8IHggPCAwIHx8IHggPj0gd2lkdGggfHwgIWRhdGEpIHsKICAgIHJldHVybjsKICB9CiAgc3dpdGNoIChtb2RlKSB7CiAgY2FzZSBzcGxhc2hNb2RlTW9ubzE6CiAgICBwID0gJmRhdGFbeSAqIHJvd1NpemUgKyAoeCA+PiAzKV07CiAgICBwaXhlbFswXSA9IChwWzBdICYgKDB4ODAgPj4gKHggJiA3KSkpID8gMHhmZiA6IDB4MDA7CiAgICBicmVhazsKICBjYXNlIHNwbGFzaE1vZGVNb25vODoKICAgIHAgPSAmZGF0YVt5ICogcm93U2l6ZSArIHhdOwogICAgcGl4ZWxbMF0gPSBwWzBdOwogICAgYnJlYWs7CiAgY2FzZSBzcGxhc2hNb2RlUkdCODoKICAgIHAgPSAmZGF0YVt5ICogcm93U2l6ZSArIDMgKiB4XTsKICAgIHBpeGVsWzBdID0gcFswXTsKICAgIHBpeGVsWzFdID0gcFsxXTsKICAgIHBpeGVsWzJdID0gcFsyXTsKICAgIGJyZWFrOwogIGNhc2Ugc3BsYXNoTW9kZVhCR1I4OgogICAgcCA9ICZkYXRhW3kgKiByb3dTaXplICsgNCAqIHhdOwogICAgcGl4ZWxbMF0gPSBwWzJdOwogICAgcGl4ZWxbMV0gPSBwWzFdOwogICAgcGl4ZWxbMl0gPSBwWzBdOwogICAgcGl4ZWxbM10gPSBwWzNdOwogICAgYnJlYWs7CiAgY2FzZSBzcGxhc2hNb2RlQkdSODoKICAgIHAgPSAmZGF0YVt5ICogcm93U2l6ZSArIDMgKiB4XTsKICAgIHBpeGVsWzBdID0gcFsyXTsKICAgIHBpeGVsWzFdID0gcFsxXTsKICAgIHBpeGVsWzJdID0gcFswXTsKICAgIGJyZWFrOwojaWYgU1BMQVNIX0NNWUsKICBjYXNlIHNwbGFzaE1vZGVDTVlLODoKICAgIHAgPSAmZGF0YVt5ICogcm93U2l6ZSArIDQgKiB4XTsKICAgIHBpeGVsWzBdID0gcFswXTsKICAgIHBpeGVsWzFdID0gcFsxXTsKICAgIHBpeGVsWzJdID0gcFsyXTsKICAgIHBpeGVsWzNdID0gcFszXTsKICAgIGJyZWFrOwogIGNhc2Ugc3BsYXNoTW9kZURldmljZU44OgogICAgcCA9ICZkYXRhW3kgKiByb3dTaXplICsgKFNQT1RfTkNPTVBTICsgNCkgKiB4XTsKICAgIGZvciAoaW50IGNwID0gMDsgY3AgPCBTUE9UX05DT01QUyArIDQ7IGNwKyspCiAgICAgIHBpeGVsW2NwXSA9IHBbY3BdOwogICAgYnJlYWs7CiNlbmRpZgogIH0KfQoKR3VjaGFyIFNwbGFzaEJpdG1hcDo6Z2V0QWxwaGEoaW50IHgsIGludCB5KSB7CiAgcmV0dXJuIGFscGhhW3kgKiB3aWR0aCArIHhdOwp9CgpTcGxhc2hDb2xvclB0ciBTcGxhc2hCaXRtYXA6OnRha2VEYXRhKCkgewogIFNwbGFzaENvbG9yUHRyIGRhdGEyOwoKICBkYXRhMiA9IGRhdGE7CiAgZGF0YSA9IE5VTEw7CiAgcmV0dXJuIGRhdGEyOwp9CgpTcGxhc2hFcnJvciBTcGxhc2hCaXRtYXA6OndyaXRlSW1nRmlsZShTcGxhc2hJbWFnZUZpbGVGb3JtYXQgZm9ybWF0LCBjaGFyICpmaWxlTmFtZSwgaW50IGhEUEksIGludCB2RFBJLCBjb25zdCBjaGFyICpjb21wcmVzc2lvblN0cmluZykgewogIEZJTEUgKmY7CiAgU3BsYXNoRXJyb3IgZTsKCiAgaWYgKCEoZiA9IGZvcGVuKGZpbGVOYW1lLCAid2IiKSkpIHsKICAgIHJldHVybiBzcGxhc2hFcnJPcGVuRmlsZTsKICB9CgogIGUgPSB3cml0ZUltZ0ZpbGUoZm9ybWF0LCBmLCBoRFBJLCB2RFBJLCBjb21wcmVzc2lvblN0cmluZyk7CiAgCiAgZmNsb3NlKGYpOwogIHJldHVybiBlOwp9CgpTcGxhc2hFcnJvciBTcGxhc2hCaXRtYXA6OndyaXRlSW1nRmlsZShTcGxhc2hJbWFnZUZpbGVGb3JtYXQgZm9ybWF0LCBGSUxFICpmLCBpbnQgaERQSSwgaW50IHZEUEksIGNvbnN0IGNoYXIgKmNvbXByZXNzaW9uU3RyaW5nKSB7CiAgSW1nV3JpdGVyICp3cml0ZXI7CglTcGxhc2hFcnJvciBlOwogIAogIHN3aXRjaCAoZm9ybWF0KSB7CiAgICAjaWZkZWYgRU5BQkxFX0xJQlBORwogICAgY2FzZSBzcGxhc2hGb3JtYXRQbmc6CgkgIHdyaXRlciA9IG5ldyBQTkdXcml0ZXIoKTsKICAgICAgYnJlYWs7CiAgICAjZW5kaWYKCiAgICAjaWZkZWYgRU5BQkxFX0xJQkpQRUcKICAgICNpZiBTUExBU0hfQ01ZSwogICAgY2FzZSBzcGxhc2hGb3JtYXRKcGVnQ01ZSzoKICAgICAgd3JpdGVyID0gbmV3IEpwZWdXcml0ZXIoSnBlZ1dyaXRlcjo6Q01ZSyk7CiAgICAgIGJyZWFrOwogICAgI2VuZGlmCiAgICBjYXNlIHNwbGFzaEZvcm1hdEpwZWc6CiAgICAgIHdyaXRlciA9IG5ldyBKcGVnV3JpdGVyKCk7CiAgICAgIGJyZWFrOwogICAgI2VuZGlmCgkKICAgICNpZmRlZiBFTkFCTEVfTElCVElGRgogICAgY2FzZSBzcGxhc2hGb3JtYXRUaWZmOgogICAgICBzd2l0Y2ggKG1vZGUpIHsKICAgICAgY2FzZSBzcGxhc2hNb2RlTW9ubzE6CiAgICAgICAgd3JpdGVyID0gbmV3IFRpZmZXcml0ZXIoVGlmZldyaXRlcjo6TU9OT0NIUk9NRSk7CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2Ugc3BsYXNoTW9kZU1vbm84OgogICAgICAgIHdyaXRlciA9IG5ldyBUaWZmV3JpdGVyKFRpZmZXcml0ZXI6OkdSQVkpOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIHNwbGFzaE1vZGVSR0I4OgogICAgICBjYXNlIHNwbGFzaE1vZGVCR1I4OgogICAgICAgIHdyaXRlciA9IG5ldyBUaWZmV3JpdGVyKFRpZmZXcml0ZXI6OlJHQik7CiAgICAgICAgYnJlYWs7CiNpZiBTUExBU0hfQ01ZSwogICAgICBjYXNlIHNwbGFzaE1vZGVDTVlLODoKICAgICAgY2FzZSBzcGxhc2hNb2RlRGV2aWNlTjg6CiAgICAgICAgd3JpdGVyID0gbmV3IFRpZmZXcml0ZXIoVGlmZldyaXRlcjo6Q01ZSyk7CiAgICAgICAgYnJlYWs7CiNlbmRpZgogICAgICBkZWZhdWx0OgogICAgICAgIGZwcmludGYoc3RkZXJyLCAiVGlmZldyaXRlcjogTW9kZSAlZCBub3Qgc3VwcG9ydGVkXG4iLCBtb2RlKTsKICAgICAgICB3cml0ZXIgPSBuZXcgVGlmZldyaXRlcigpOwogICAgICB9CiAgICAgIGlmICh3cml0ZXIpIHsKICAgICAgICAoKFRpZmZXcml0ZXIgKil3cml0ZXIpLT5zZXRDb21wcmVzc2lvblN0cmluZyhjb21wcmVzc2lvblN0cmluZyk7CiAgICAgIH0KICAgICAgYnJlYWs7CiAgICAjZW5kaWYKCiAgICBkZWZhdWx0OgogICAgICAvLyBOb3QgdGhlIGdyZWF0ZXN0IGVycm9yIG1lc3NhZ2UsIGJ1dCB1c2VycyBvZiB0aGlzIGZ1bmN0aW9uIHNob3VsZAogICAgICAvLyBoYXZlIGFscmVhZHkgY2hlY2tlZCB3aGV0aGVyIHRoZWlyIGRlc2lyZWQgZm9ybWF0IGlzIGNvbXBpbGVkIGluLgogICAgICBlcnJvcihlcnJJbnRlcm5hbCwgLTEsICJTdXBwb3J0IGZvciB0aGlzIGltYWdlIHR5cGUgbm90IGNvbXBpbGVkIGluIik7CiAgICAgIHJldHVybiBzcGxhc2hFcnJHZW5lcmljOwogIH0KCgllID0gd3JpdGVJbWdGaWxlKHdyaXRlciwgZiwgaERQSSwgdkRQSSk7CglkZWxldGUgd3JpdGVyOwoJcmV0dXJuIGU7Cn0KCiNpbmNsdWRlICJwb3BwbGVyL0dmeFN0YXRlX2hlbHBlcnMuaCIKCnZvaWQgU3BsYXNoQml0bWFwOjpnZXRSR0JMaW5lKGludCB5bCwgU3BsYXNoQ29sb3JQdHIgbGluZSkgewogIFNwbGFzaENvbG9yIGNvbDsKICBkb3VibGUgYywgbSwgeSwgaywgYzEsIG0xLCB5MSwgazEsIHIsIGcsIGI7CgogIGZvciAoaW50IHggPSAwOyB4IDwgd2lkdGg7IHgrKykgewogICAgZ2V0UGl4ZWwoeCwgeWwsIGNvbCk7CiAgICBjID0gYnl0ZVRvRGJsKGNvbFswXSk7CiAgICBtID0gYnl0ZVRvRGJsKGNvbFsxXSk7CiAgICB5ID0gYnl0ZVRvRGJsKGNvbFsyXSk7CiAgICBrID0gYnl0ZVRvRGJsKGNvbFszXSk7CiNpZiBTUExBU0hfQ01ZSwogICAgaWYgKHNlcGFyYXRpb25MaXN0LT5nZXRMZW5ndGgoKSA+IDApIHsKICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzZXBhcmF0aW9uTGlzdC0+Z2V0TGVuZ3RoKCk7IGkrKykgewogICAgICAgIGlmIChjb2xbaSs0XSA+IDApIHsKICAgICAgICAgIEdmeENNWUsgY215azsKICAgICAgICAgIEdmeENvbG9yIGlucHV0OwogICAgICAgICAgaW5wdXQuY1swXSA9IGJ5dGVUb0NvbChjb2xbaSs0XSk7CiAgICAgICAgICBHZnhTZXBhcmF0aW9uQ29sb3JTcGFjZSAqc2VwQ1MgPSAoR2Z4U2VwYXJhdGlvbkNvbG9yU3BhY2UgKilzZXBhcmF0aW9uTGlzdC0+Z2V0KGkpOwogICAgICAgICAgc2VwQ1MtPmdldENNWUsoJmlucHV0LCAmY215ayk7CiAgICAgICAgICBjb2xbMF0gPSBjb2xUb0J5dGUoY215ay5jKTsKICAgICAgICAgIGNvbFsxXSA9IGNvbFRvQnl0ZShjbXlrLm0pOwogICAgICAgICAgY29sWzJdID0gY29sVG9CeXRlKGNteWsueSk7CiAgICAgICAgICBjb2xbM10gPSBjb2xUb0J5dGUoY215ay5rKTsKICAgICAgICAgIGMgKz0gYnl0ZVRvRGJsKGNvbFswXSk7CiAgICAgICAgICBtICs9IGJ5dGVUb0RibChjb2xbMV0pOwogICAgICAgICAgeSArPSBieXRlVG9EYmwoY29sWzJdKTsKICAgICAgICAgIGsgKz0gYnl0ZVRvRGJsKGNvbFszXSk7CiAgICAgICAgfQogICAgICB9CiAgICAgIGlmIChjID4gMSkgYyA9IDE7CiAgICAgIGlmIChtID4gMSkgbSA9IDE7CiAgICAgIGlmICh5ID4gMSkgeSA9IDE7CiAgICAgIGlmIChrID4gMSkgayA9IDE7CiAgICB9CiNlbmRpZgogICAgYzEgPSAxIC0gYzsKICAgIG0xID0gMSAtIG07CiAgICB5MSA9IDEgLSB5OwogICAgazEgPSAxIC0gazsKICAgIGNteWtUb1JHQk1hdHJpeE11bHRpcGxpY2F0aW9uKGMsIG0sIHksIGssIGMxLCBtMSwgeTEsIGsxLCByLCBnLCBiKTsKICAgICpsaW5lKysgPSBkYmxUb0J5dGUoY2xpcDAxKHIpKTsKICAgICpsaW5lKysgPSBkYmxUb0J5dGUoY2xpcDAxKGcpKTsKICAgICpsaW5lKysgPSBkYmxUb0J5dGUoY2xpcDAxKGIpKTsKICB9Cn0KCnZvaWQgU3BsYXNoQml0bWFwOjpnZXRYQkdSTGluZShpbnQgeWwsIFNwbGFzaENvbG9yUHRyIGxpbmUsIENvbnZlcnNpb25Nb2RlIGNvbnZlcnNpb25Nb2RlKSB7CiAgU3BsYXNoQ29sb3IgY29sOwogIGRvdWJsZSBjLCBtLCB5LCBrLCBjMSwgbTEsIHkxLCBrMSwgciwgZywgYjsKCiAgZm9yIChpbnQgeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7CiAgICBnZXRQaXhlbCh4LCB5bCwgY29sKTsKICAgIGMgPSBieXRlVG9EYmwoY29sWzBdKTsKICAgIG0gPSBieXRlVG9EYmwoY29sWzFdKTsKICAgIHkgPSBieXRlVG9EYmwoY29sWzJdKTsKICAgIGsgPSBieXRlVG9EYmwoY29sWzNdKTsKI2lmIFNQTEFTSF9DTVlLCiAgICBpZiAoc2VwYXJhdGlvbkxpc3QtPmdldExlbmd0aCgpID4gMCkgewogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNlcGFyYXRpb25MaXN0LT5nZXRMZW5ndGgoKTsgaSsrKSB7CiAgICAgICAgaWYgKGNvbFtpKzRdID4gMCkgewogICAgICAgICAgR2Z4Q01ZSyBjbXlrOwogICAgICAgICAgR2Z4Q29sb3IgaW5wdXQ7CiAgICAgICAgICBpbnB1dC5jWzBdID0gYnl0ZVRvQ29sKGNvbFtpKzRdKTsKICAgICAgICAgIEdmeFNlcGFyYXRpb25Db2xvclNwYWNlICpzZXBDUyA9IChHZnhTZXBhcmF0aW9uQ29sb3JTcGFjZSAqKXNlcGFyYXRpb25MaXN0LT5nZXQoaSk7CiAgICAgICAgICBzZXBDUy0+Z2V0Q01ZSygmaW5wdXQsICZjbXlrKTsKICAgICAgICAgIGNvbFswXSA9IGNvbFRvQnl0ZShjbXlrLmMpOwogICAgICAgICAgY29sWzFdID0gY29sVG9CeXRlKGNteWsubSk7CiAgICAgICAgICBjb2xbMl0gPSBjb2xUb0J5dGUoY215ay55KTsKICAgICAgICAgIGNvbFszXSA9IGNvbFRvQnl0ZShjbXlrLmspOwogICAgICAgICAgYyArPSBieXRlVG9EYmwoY29sWzBdKTsKICAgICAgICAgIG0gKz0gYnl0ZVRvRGJsKGNvbFsxXSk7CiAgICAgICAgICB5ICs9IGJ5dGVUb0RibChjb2xbMl0pOwogICAgICAgICAgayArPSBieXRlVG9EYmwoY29sWzNdKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgaWYgKGMgPiAxKSBjID0gMTsKICAgICAgaWYgKG0gPiAxKSBtID0gMTsKICAgICAgaWYgKHkgPiAxKSB5ID0gMTsKICAgICAgaWYgKGsgPiAxKSBrID0gMTsKICAgIH0KI2VuZGlmCiAgICBjMSA9IDEgLSBjOwogICAgbTEgPSAxIC0gbTsKICAgIHkxID0gMSAtIHk7CiAgICBrMSA9IDEgLSBrOwogICAgY215a1RvUkdCTWF0cml4TXVsdGlwbGljYXRpb24oYywgbSwgeSwgaywgYzEsIG0xLCB5MSwgazEsIHIsIGcsIGIpOwoKICAgIGlmIChjb252ZXJzaW9uTW9kZSA9PSBjb252ZXJzaW9uQWxwaGFQcmVtdWx0aXBsaWVkKSB7CiAgICAgICAgY29uc3QgZG91YmxlIGEgPSBnZXRBbHBoYSh4LCB5bCkgLyAyNTUuMDsKCiAgICAgICAgKmxpbmUrKyA9IGRibFRvQnl0ZShjbGlwMDEoYiAqIGEpKTsKICAgICAgICAqbGluZSsrID0gZGJsVG9CeXRlKGNsaXAwMShnICogYSkpOwogICAgICAgICpsaW5lKysgPSBkYmxUb0J5dGUoY2xpcDAxKHIgKiBhKSk7CiAgICB9IGVsc2UgewogICAgICAgICpsaW5lKysgPSBkYmxUb0J5dGUoY2xpcDAxKGIpKTsKICAgICAgICAqbGluZSsrID0gZGJsVG9CeXRlKGNsaXAwMShnKSk7CiAgICAgICAgKmxpbmUrKyA9IGRibFRvQnl0ZShjbGlwMDEocikpOwogICAgfQoKICAgIGlmIChjb252ZXJzaW9uTW9kZSAhPSBjb252ZXJzaW9uT3BhcXVlKSB7CiAgICAgICAgKmxpbmUrKyA9IGdldEFscGhhKHgsIHlsKTsKICAgIH0gZWxzZSB7CiAgICAgICAgKmxpbmUrKyA9IDI1NTsKICAgIH0KICB9Cn0KCnN0YXRpYyBpbmxpbmUgR3VjaGFyIGRpdjI1NShpbnQgeCkgewogIHJldHVybiAoR3VjaGFyKSgoeCArICh4ID4+IDgpICsgMHg4MCkgPj4gOCk7Cn0KCkdCb29sIFNwbGFzaEJpdG1hcDo6Y29udmVydFRvWEJHUihDb252ZXJzaW9uTW9kZSBjb252ZXJzaW9uTW9kZSkgewogIGlmIChtb2RlID09IHNwbGFzaE1vZGVYQkdSOCkgewogICAgaWYgKGNvbnZlcnNpb25Nb2RlICE9IGNvbnZlcnNpb25PcGFxdWUpIHsKICAgICAgLy8gQ29weSB0aGUgYWxwaGEgY2hhbm5lbCBpbnRvIHRoZSBmb3VydGggY29tcG9uZW50IHNvIHRoYXQgWEJHUiBiZWNvbWVzIEFCR1IuCiAgICAgIGNvbnN0IFNwbGFzaENvbG9yUHRyIGRiZWdpbiA9IGRhdGE7CiAgICAgIGNvbnN0IFNwbGFzaENvbG9yUHRyIGRlbmQgPSBkYXRhICsgcm93U2l6ZSAqIGhlaWdodDsKCiAgICAgIEd1Y2hhciAqY29uc3QgYWJlZ2luID0gYWxwaGE7CiAgICAgIEd1Y2hhciAqY29uc3QgYWVuZCA9IGFscGhhICsgd2lkdGggKiBoZWlnaHQ7CgogICAgICBTcGxhc2hDb2xvclB0ciBkID0gZGJlZ2luOwogICAgICBHdWNoYXIgKmEgPSBhYmVnaW47CgogICAgICBpZiAoY29udmVyc2lvbk1vZGUgPT0gY29udmVyc2lvbkFscGhhUHJlbXVsdGlwbGllZCkgewogICAgICAgICAgZm9yICg7IGQgPCBkZW5kICYmIGEgPCBhZW5kOyBkICs9IDQsIGEgKz0gMSkgewogICAgICAgICAgICAgIGRbMF0gPSBkaXYyNTUoZFswXSAqICphKTsKICAgICAgICAgICAgICBkWzFdID0gZGl2MjU1KGRbMV0gKiAqYSk7CiAgICAgICAgICAgICAgZFsyXSA9IGRpdjI1NShkWzJdICogKmEpOwogICAgICAgICAgICAgIGRbM10gPSAqYTsKICAgICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZvciAoZCArPSAzOyBkIDwgZGVuZCAmJiBhIDwgYWVuZDsgZCArPSA0LCBhICs9IDEpIHsKICAgICAgICAgICAgICAqZCA9ICphOwogICAgICAgICAgfQogICAgICB9CiAgICB9CgogICAgcmV0dXJuIGdUcnVlOwogIH0KICAKICBpbnQgbmV3cm93U2l6ZSA9IHdpZHRoICogNDsKICBTcGxhc2hDb2xvclB0ciBuZXdkYXRhID0gKFNwbGFzaENvbG9yUHRyKWdtYWxsb2NuX2NoZWNrb3ZlcmZsb3cobmV3cm93U2l6ZSwgaGVpZ2h0KTsKICBpZiAobmV3ZGF0YSAhPSBOVUxMKSB7CiAgICBmb3IgKGludCB5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CiAgICAgIHVuc2lnbmVkIGNoYXIgKnJvdyA9IG5ld2RhdGEgKyB5ICogbmV3cm93U2l6ZTsKICAgICAgZ2V0WEJHUkxpbmUoeSwgcm93LCBjb252ZXJzaW9uTW9kZSk7CiAgICB9CiAgICBpZiAocm93U2l6ZSA8IDApIHsKICAgICAgZ2ZyZWUoZGF0YSArIChoZWlnaHQgLSAxKSAqIHJvd1NpemUpOwogICAgfSBlbHNlIHsKICAgICAgZ2ZyZWUoZGF0YSk7CiAgICB9CiAgICBkYXRhID0gbmV3ZGF0YTsKICAgIHJvd1NpemUgPSBuZXdyb3dTaXplOwogICAgbW9kZSA9IHNwbGFzaE1vZGVYQkdSODsKICB9CiAgcmV0dXJuIG5ld2RhdGEgIT0gTlVMTDsKfQoKI2lmIFNQTEFTSF9DTVlLCnZvaWQgU3BsYXNoQml0bWFwOjpnZXRDTVlLTGluZShpbnQgeWwsIFNwbGFzaENvbG9yUHRyIGxpbmUpIHsKICBTcGxhc2hDb2xvciBjb2w7CgogIGZvciAoaW50IHggPSAwOyB4IDwgd2lkdGg7IHgrKykgewogICAgZ2V0UGl4ZWwoeCwgeWwsIGNvbCk7CiAgICBpZiAoc2VwYXJhdGlvbkxpc3QtPmdldExlbmd0aCgpID4gMCkgewogICAgICBkb3VibGUgYywgbSwgeSwgazsKICAgICAgYyA9IGJ5dGVUb0RibChjb2xbMF0pOwogICAgICBtID0gYnl0ZVRvRGJsKGNvbFsxXSk7CiAgICAgIHkgPSBieXRlVG9EYmwoY29sWzJdKTsKICAgICAgayA9IGJ5dGVUb0RibChjb2xbM10pOwogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNlcGFyYXRpb25MaXN0LT5nZXRMZW5ndGgoKTsgaSsrKSB7CiAgICAgICAgaWYgKGNvbFtpKzRdID4gMCkgewogICAgICAgICAgR2Z4Q01ZSyBjbXlrOwogICAgICAgICAgR2Z4Q29sb3IgaW5wdXQ7CiAgICAgICAgICBpbnB1dC5jWzBdID0gYnl0ZVRvQ29sKGNvbFtpKzRdKTsKICAgICAgICAgIEdmeFNlcGFyYXRpb25Db2xvclNwYWNlICpzZXBDUyA9IChHZnhTZXBhcmF0aW9uQ29sb3JTcGFjZSAqKXNlcGFyYXRpb25MaXN0LT5nZXQoaSk7CiAgICAgICAgICBzZXBDUy0+Z2V0Q01ZSygmaW5wdXQsICZjbXlrKTsKICAgICAgICAgIGNvbFswXSA9IGNvbFRvQnl0ZShjbXlrLmMpOwogICAgICAgICAgY29sWzFdID0gY29sVG9CeXRlKGNteWsubSk7CiAgICAgICAgICBjb2xbMl0gPSBjb2xUb0J5dGUoY215ay55KTsKICAgICAgICAgIGNvbFszXSA9IGNvbFRvQnl0ZShjbXlrLmspOwogICAgICAgICAgYyArPSBieXRlVG9EYmwoY29sWzBdKTsKICAgICAgICAgIG0gKz0gYnl0ZVRvRGJsKGNvbFsxXSk7CiAgICAgICAgICB5ICs9IGJ5dGVUb0RibChjb2xbMl0pOwogICAgICAgICAgayArPSBieXRlVG9EYmwoY29sWzNdKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgY29sWzBdID0gZGJsVG9CeXRlKGNsaXAwMShjKSk7CiAgICAgIGNvbFsxXSA9IGRibFRvQnl0ZShjbGlwMDEobSkpOwogICAgICBjb2xbMl0gPSBkYmxUb0J5dGUoY2xpcDAxKHkpKTsKICAgICAgY29sWzNdID0gZGJsVG9CeXRlKGNsaXAwMShrKSk7CiAgICB9CiAgICAqbGluZSsrID0gY29sWzBdOwogICAgKmxpbmUrKyA9IGNvbFsxXTsKICAgICpsaW5lKysgPSBjb2xbMl07CiAgICAqbGluZSsrID0gY29sWzNdOwogIH0KfQojZW5kaWYKClNwbGFzaEVycm9yIFNwbGFzaEJpdG1hcDo6d3JpdGVJbWdGaWxlKEltZ1dyaXRlciAqd3JpdGVyLCBGSUxFICpmLCBpbnQgaERQSSwgaW50IHZEUEkpIHsKICBpZiAobW9kZSAhPSBzcGxhc2hNb2RlUkdCOCAmJiBtb2RlICE9IHNwbGFzaE1vZGVNb25vOCAmJiBtb2RlICE9IHNwbGFzaE1vZGVNb25vMSAmJiBtb2RlICE9IHNwbGFzaE1vZGVYQkdSOCAmJiBtb2RlICE9IHNwbGFzaE1vZGVCR1I4CiNpZiBTUExBU0hfQ01ZSwogICAgICAmJiBtb2RlICE9IHNwbGFzaE1vZGVDTVlLOCAmJiBtb2RlICE9IHNwbGFzaE1vZGVEZXZpY2VOOAojZW5kaWYKICAgICApIHsKICAgIGVycm9yKGVyckludGVybmFsLCAtMSwgInVuc3VwcG9ydGVkIFNwbGFzaEJpdG1hcCBtb2RlIik7CiAgICByZXR1cm4gc3BsYXNoRXJyR2VuZXJpYzsKICB9CgogIGlmICghd3JpdGVyLT5pbml0KGYsIHdpZHRoLCBoZWlnaHQsIGhEUEksIHZEUEkpKSB7CiAgICByZXR1cm4gc3BsYXNoRXJyR2VuZXJpYzsKICB9CgogIHN3aXRjaCAobW9kZSkgewojaWYgU1BMQVNIX0NNWUsKICAgIGNhc2Ugc3BsYXNoTW9kZUNNWUs4OgogICAgICBpZiAod3JpdGVyLT5zdXBwb3J0Q01ZSygpKSB7CiAgICAgICAgU3BsYXNoQ29sb3JQdHIgcm93OwogICAgICAgIHVuc2lnbmVkIGNoYXIgKipyb3dfcG9pbnRlcnMgPSBuZXcgdW5zaWduZWQgY2hhcipbaGVpZ2h0XTsKICAgICAgICByb3cgPSBkYXRhOwoKICAgICAgICBmb3IgKGludCB5ID0gMDsgeSA8IGhlaWdodDsgKyt5KSB7CiAgICAgICAgICByb3dfcG9pbnRlcnNbeV0gPSByb3c7CiAgICAgICAgICByb3cgKz0gcm93U2l6ZTsKICAgICAgICB9CiAgICAgICAgaWYgKCF3cml0ZXItPndyaXRlUG9pbnRlcnMocm93X3BvaW50ZXJzLCBoZWlnaHQpKSB7CiAgICAgICAgICBkZWxldGVbXSByb3dfcG9pbnRlcnM7CiAgICAgICAgICByZXR1cm4gc3BsYXNoRXJyR2VuZXJpYzsKICAgICAgICB9CiAgICAgICAgZGVsZXRlW10gcm93X3BvaW50ZXJzOwogICAgICB9IGVsc2UgewogICAgICAgIHVuc2lnbmVkIGNoYXIgKnJvdyA9IG5ldyB1bnNpZ25lZCBjaGFyWzMgKiB3aWR0aF07CiAgICAgICAgZm9yIChpbnQgeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewogICAgICAgICAgZ2V0UkdCTGluZSh5LCByb3cpOwogICAgICAgICAgaWYgKCF3cml0ZXItPndyaXRlUm93KCZyb3cpKSB7CiAgICAgICAgICAgIGRlbGV0ZVtdIHJvdzsKICAgICAgICAgICAgcmV0dXJuIHNwbGFzaEVyckdlbmVyaWM7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGRlbGV0ZVtdIHJvdzsKICAgICAgfQogICAgYnJlYWs7CiAgICBjYXNlIHNwbGFzaE1vZGVEZXZpY2VOODoKICAgICAgaWYgKHdyaXRlci0+c3VwcG9ydENNWUsoKSkgewogICAgICAgIHVuc2lnbmVkIGNoYXIgKnJvdyA9IG5ldyB1bnNpZ25lZCBjaGFyWzQgKiB3aWR0aF07CiAgICAgICAgZm9yIChpbnQgeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewogICAgICAgICAgZ2V0Q01ZS0xpbmUoeSwgcm93KTsKICAgICAgICAgIGlmICghd3JpdGVyLT53cml0ZVJvdygmcm93KSkgewogICAgICAgICAgICBkZWxldGVbXSByb3c7CiAgICAgICAgICAgIHJldHVybiBzcGxhc2hFcnJHZW5lcmljOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBkZWxldGVbXSByb3c7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdW5zaWduZWQgY2hhciAqcm93ID0gbmV3IHVuc2lnbmVkIGNoYXJbMyAqIHdpZHRoXTsKICAgICAgICBmb3IgKGludCB5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CiAgICAgICAgICBnZXRSR0JMaW5lKHksIHJvdyk7CiAgICAgICAgICBpZiAoIXdyaXRlci0+d3JpdGVSb3coJnJvdykpIHsKICAgICAgICAgICAgZGVsZXRlW10gcm93OwogICAgICAgICAgICByZXR1cm4gc3BsYXNoRXJyR2VuZXJpYzsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZGVsZXRlW10gcm93OwogICAgICB9CiAgICBicmVhazsKI2VuZGlmCiAgICBjYXNlIHNwbGFzaE1vZGVSR0I4OgogICAgewogICAgICBTcGxhc2hDb2xvclB0ciByb3c7CiAgICAgIHVuc2lnbmVkIGNoYXIgKipyb3dfcG9pbnRlcnMgPSBuZXcgdW5zaWduZWQgY2hhcipbaGVpZ2h0XTsKICAgICAgcm93ID0gZGF0YTsKCiAgICAgIGZvciAoaW50IHkgPSAwOyB5IDwgaGVpZ2h0OyArK3kpIHsKICAgICAgICByb3dfcG9pbnRlcnNbeV0gPSByb3c7CiAgICAgICAgcm93ICs9IHJvd1NpemU7CiAgICAgIH0KICAgICAgaWYgKCF3cml0ZXItPndyaXRlUG9pbnRlcnMocm93X3BvaW50ZXJzLCBoZWlnaHQpKSB7CiAgICAgICAgZGVsZXRlW10gcm93X3BvaW50ZXJzOwogICAgICAgIHJldHVybiBzcGxhc2hFcnJHZW5lcmljOwogICAgICB9CiAgICAgIGRlbGV0ZVtdIHJvd19wb2ludGVyczsKICAgIH0KICAgIGJyZWFrOwogICAgCiAgICBjYXNlIHNwbGFzaE1vZGVCR1I4OgogICAgewogICAgICB1bnNpZ25lZCBjaGFyICpyb3cgPSBuZXcgdW5zaWduZWQgY2hhclszICogd2lkdGhdOwogICAgICBmb3IgKGludCB5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CiAgICAgICAgLy8gQ29udmVydCBpbnRvIGEgUE5HIHJvdwogICAgICAgIGZvciAoaW50IHggPSAwOyB4IDwgd2lkdGg7IHgrKykgewogICAgICAgICAgcm93WzMqeF0gPSBkYXRhW3kgKiByb3dTaXplICsgeCAqIDMgKyAyXTsKICAgICAgICAgIHJvd1szKngrMV0gPSBkYXRhW3kgKiByb3dTaXplICsgeCAqIDMgKyAxXTsKICAgICAgICAgIHJvd1szKngrMl0gPSBkYXRhW3kgKiByb3dTaXplICsgeCAqIDNdOwogICAgICAgIH0KCiAgICAgICAgaWYgKCF3cml0ZXItPndyaXRlUm93KCZyb3cpKSB7CiAgICAgICAgICBkZWxldGVbXSByb3c7CiAgICAgICAgICByZXR1cm4gc3BsYXNoRXJyR2VuZXJpYzsKICAgICAgICB9CiAgICAgIH0KICAgICAgZGVsZXRlW10gcm93OwogICAgfQogICAgYnJlYWs7CiAgICAKICAgIGNhc2Ugc3BsYXNoTW9kZVhCR1I4OgogICAgewogICAgICB1bnNpZ25lZCBjaGFyICpyb3cgPSBuZXcgdW5zaWduZWQgY2hhclszICogd2lkdGhdOwogICAgICBmb3IgKGludCB5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CiAgICAgICAgLy8gQ29udmVydCBpbnRvIGEgUE5HIHJvdwogICAgICAgIGZvciAoaW50IHggPSAwOyB4IDwgd2lkdGg7IHgrKykgewogICAgICAgICAgcm93WzMqeF0gPSBkYXRhW3kgKiByb3dTaXplICsgeCAqIDQgKyAyXTsKICAgICAgICAgIHJvd1szKngrMV0gPSBkYXRhW3kgKiByb3dTaXplICsgeCAqIDQgKyAxXTsKICAgICAgICAgIHJvd1szKngrMl0gPSBkYXRhW3kgKiByb3dTaXplICsgeCAqIDRdOwogICAgICAgIH0KCiAgICAgICAgaWYgKCF3cml0ZXItPndyaXRlUm93KCZyb3cpKSB7CiAgICAgICAgICBkZWxldGVbXSByb3c7CiAgICAgICAgICByZXR1cm4gc3BsYXNoRXJyR2VuZXJpYzsKICAgICAgICB9CiAgICAgIH0KICAgICAgZGVsZXRlW10gcm93OwogICAgfQogICAgYnJlYWs7CiAgICAKICAgIGNhc2Ugc3BsYXNoTW9kZU1vbm84OgogICAgewogICAgICB1bnNpZ25lZCBjaGFyICpyb3cgPSBuZXcgdW5zaWduZWQgY2hhclszICogd2lkdGhdOwogICAgICBmb3IgKGludCB5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CiAgICAgICAgLy8gQ29udmVydCBpbnRvIGEgUE5HIHJvdwogICAgICAgIGZvciAoaW50IHggPSAwOyB4IDwgd2lkdGg7IHgrKykgewogICAgICAgICAgcm93WzMqeF0gPSBkYXRhW3kgKiByb3dTaXplICsgeF07CiAgICAgICAgICByb3dbMyp4KzFdID0gZGF0YVt5ICogcm93U2l6ZSArIHhdOwogICAgICAgICAgcm93WzMqeCsyXSA9IGRhdGFbeSAqIHJvd1NpemUgKyB4XTsKICAgICAgICB9CgogICAgICAgIGlmICghd3JpdGVyLT53cml0ZVJvdygmcm93KSkgewogICAgICAgICAgZGVsZXRlW10gcm93OwogICAgICAgICAgcmV0dXJuIHNwbGFzaEVyckdlbmVyaWM7CiAgICAgICAgfQogICAgICB9CiAgICAgIGRlbGV0ZVtdIHJvdzsKICAgIH0KICAgIGJyZWFrOwogICAgCiAgICBjYXNlIHNwbGFzaE1vZGVNb25vMToKICAgIHsKICAgICAgdW5zaWduZWQgY2hhciAqcm93ID0gbmV3IHVuc2lnbmVkIGNoYXJbMyAqIHdpZHRoXTsKICAgICAgZm9yIChpbnQgeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewogICAgICAgIC8vIENvbnZlcnQgaW50byBhIFBORyByb3cKICAgICAgICBmb3IgKGludCB4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHsKICAgICAgICAgIGdldFBpeGVsKHgsIHksICZyb3dbMyp4XSk7CiAgICAgICAgICByb3dbMyp4KzFdID0gcm93WzMqeF07CiAgICAgICAgICByb3dbMyp4KzJdID0gcm93WzMqeF07CiAgICAgICAgfQoKICAgICAgICBpZiAoIXdyaXRlci0+d3JpdGVSb3coJnJvdykpIHsKICAgICAgICAgIGRlbGV0ZVtdIHJvdzsKICAgICAgICAgIHJldHVybiBzcGxhc2hFcnJHZW5lcmljOwogICAgICAgIH0KICAgICAgfQogICAgICBkZWxldGVbXSByb3c7CiAgICB9CiAgICBicmVhazsKICAgIAogICAgZGVmYXVsdDoKICAgIC8vIGNhbid0IGhhcHBlbgogICAgYnJlYWs7CiAgfQogIAogIGlmICghd3JpdGVyLT5jbG9zZSgpKSB7CiAgICByZXR1cm4gc3BsYXNoRXJyR2VuZXJpYzsKICB9CgogIHJldHVybiBzcGxhc2hPazsKfQo=