Ly89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8KLy8gU3BsYXNoQml0bWFwLmNjCi8vCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLwovLyBNb2RpZmllZCB1bmRlciB0aGUgUG9wcGxlciBwcm9qZWN0IC0gaHR0cDovL3BvcHBsZXIuZnJlZWRlc2t0b3Aub3JnCi8vCi8vIEFsbCBjaGFuZ2VzIG1hZGUgdW5kZXIgdGhlIFBvcHBsZXIgcHJvamVjdCB0byB0aGlzIGZpbGUgYXJlIGxpY2Vuc2VkCi8vIHVuZGVyIEdQTCB2ZXJzaW9uIDIgb3IgbGF0ZXIKLy8KLy8gQ29weXJpZ2h0IChDKSAyMDA2LCAyMDA5LCAyMDEwLCAyMDEyLCAyMDE1IEFsYmVydCBBc3RhbHMgQ2lkIDxhYWNpZEBrZGUub3JnPgovLyBDb3B5cmlnaHQgKEMpIDIwMDcgSWxtYXJpIEhlaWtraW5lbiA8aWxtYXJpLmhlaWtraW5lbkBnbWFpbC5jb20+Ci8vIENvcHlyaWdodCAoQykgMjAwOSBTaGVuIExpYW5nIDxzaGVuemh1eGlAZ21haWwuY29tPgovLyBDb3B5cmlnaHQgKEMpIDIwMDkgU3RlZmFuIFRob21hcyA8dGhvbWFzQGVsb2FkMjQuY29tPgovLyBDb3B5cmlnaHQgKEMpIDIwMTAsIDIwMTIsIDIwMTcgQWRyaWFuIEpvaG5zb24gPGFqb2huc29uQHJlZG5lb24uY29tPgovLyBDb3B5cmlnaHQgKEMpIDIwMTAgSGFycnkgUm9iZXJ0cyA8aGFycnkucm9iZXJ0c0BtaWRuaWdodC1sYWJzLm9yZz4KLy8gQ29weXJpZ2h0IChDKSAyMDEwIENocmlzdGlhbiBGZXVlcnPkbmdlciA8Y2ZldWVyc2FlbmdlckBnb29nbGVtYWlsLmNvbT4KLy8gQ29weXJpZ2h0IChDKSAyMDEwLCAyMDE1IFdpbGxpYW0gQmFkZXIgPHdpbGxpYW1iYWRlckBob3RtYWlsLmNvbT4KLy8gQ29weXJpZ2h0IChDKSAyMDExLTIwMTMgVGhvbWFzIEZyZWl0YWcgPFRob21hcy5GcmVpdGFnQGFsZmEuZGU+Ci8vIENvcHlyaWdodCAoQykgMjAxMiBBbnRob255IFdlc2xleSA8YXdlc2xleUBzbWFydG5ldHdvcmtzLmNvbS5hdT4KLy8gQ29weXJpZ2h0IChDKSAyMDE1IEFkYW0gUmVpY2hvbGQgPGFkYW1yZWljaG9sZEBteW9wZXJhLmNvbT4KLy8gQ29weXJpZ2h0IChDKSAyMDE2IEtlbmppIFVubyA8a3VAZGlnaXRhbGRvbHBoaW5zLmpwPgovLwovLyBUbyBzZWUgYSBkZXNjcmlwdGlvbiBvZiB0aGUgY2hhbmdlcyBwbGVhc2Ugc2VlIHRoZSBDaGFuZ2Vsb2cgZmlsZSB0aGF0Ci8vIGNhbWUgd2l0aCB5b3VyIHRhcmJhbGwgb3IgdHlwZSBtYWtlIENoYW5nZUxvZyBpZiB5b3UgYXJlIGJ1aWxkaW5nIGZyb20gZ2l0Ci8vCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgojaW5jbHVkZSA8Y29uZmlnLmg+CgojaWZkZWYgVVNFX0dDQ19QUkFHTUFTCiNwcmFnbWEgaW1wbGVtZW50YXRpb24KI2VuZGlmCgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxsaW1pdHMuaD4KI2luY2x1ZGUgImdvby9nbWVtLmgiCiNpbmNsdWRlICJTcGxhc2hFcnJvckNvZGVzLmgiCiNpbmNsdWRlICJTcGxhc2hCaXRtYXAuaCIKI2luY2x1ZGUgInBvcHBsZXIvRXJyb3IuaCIKI2luY2x1ZGUgImdvby9KcGVnV3JpdGVyLmgiCiNpbmNsdWRlICJnb28vUE5HV3JpdGVyLmgiCiNpbmNsdWRlICJnb28vVGlmZldyaXRlci5oIgojaW5jbHVkZSAiZ29vL0ltZ1dyaXRlci5oIgojaW5jbHVkZSAiZ29vL0dvb0xpc3QuaCIKCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vIFNwbGFzaEJpdG1hcAovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKU3BsYXNoQml0bWFwOjpTcGxhc2hCaXRtYXAoaW50IHdpZHRoQSwgaW50IGhlaWdodEEsIGludCByb3dQYWRBLAoJCQkgICBTcGxhc2hDb2xvck1vZGUgbW9kZUEsIEdCb29sIGFscGhhQSwKCQkJICAgR0Jvb2wgdG9wRG93biwgR29vTGlzdCAqc2VwYXJhdGlvbkxpc3RBKSB7CiAgd2lkdGggPSB3aWR0aEE7CiAgaGVpZ2h0ID0gaGVpZ2h0QTsKICBtb2RlID0gbW9kZUE7CiAgcm93UGFkID0gcm93UGFkQTsKICBzd2l0Y2ggKG1vZGUpIHsKICBjYXNlIHNwbGFzaE1vZGVNb25vMToKICAgIGlmICh3aWR0aCA+IDApIHsKICAgICAgcm93U2l6ZSA9ICh3aWR0aCArIDcpID4+IDM7CiAgICB9IGVsc2UgewogICAgICByb3dTaXplID0gLTE7CiAgICB9CiAgICBicmVhazsKICBjYXNlIHNwbGFzaE1vZGVNb25vODoKICAgIGlmICh3aWR0aCA+IDApIHsKICAgICAgcm93U2l6ZSA9IHdpZHRoOwogICAgfSBlbHNlIHsKICAgICAgcm93U2l6ZSA9IC0xOwogICAgfQogICAgYnJlYWs7CiAgY2FzZSBzcGxhc2hNb2RlUkdCODoKICBjYXNlIHNwbGFzaE1vZGVCR1I4OgogICAgaWYgKHdpZHRoID4gMCAmJiB3aWR0aCA8PSBJTlRfTUFYIC8gMykgewogICAgICByb3dTaXplID0gd2lkdGggKiAzOwogICAgfSBlbHNlIHsKICAgICAgcm93U2l6ZSA9IC0xOwogICAgfQogICAgYnJlYWs7CiAgY2FzZSBzcGxhc2hNb2RlWEJHUjg6CiAgICBpZiAod2lkdGggPiAwICYmIHdpZHRoIDw9IElOVF9NQVggLyA0KSB7CiAgICAgIHJvd1NpemUgPSB3aWR0aCAqIDQ7CiAgICB9IGVsc2UgewogICAgICByb3dTaXplID0gLTE7CiAgICB9CiAgICBicmVhazsKI2lmZGVmIFNQTEFTSF9DTVlLCiAgY2FzZSBzcGxhc2hNb2RlQ01ZSzg6CiAgICBpZiAod2lkdGggPiAwICYmIHdpZHRoIDw9IElOVF9NQVggLyA0KSB7CiAgICAgIHJvd1NpemUgPSB3aWR0aCAqIDQ7CiAgICB9IGVsc2UgewogICAgICByb3dTaXplID0gLTE7CiAgICB9CiAgICBicmVhazsKICBjYXNlIHNwbGFzaE1vZGVEZXZpY2VOODoKICAgIGlmICh3aWR0aCA+IDAgJiYgd2lkdGggPD0gSU5UX01BWCAvIDQpIHsKICAgICAgcm93U2l6ZSA9IHdpZHRoICogKFNQT1RfTkNPTVBTICsgNCk7CiAgICB9IGVsc2UgewogICAgICByb3dTaXplID0gLTE7CiAgICB9CiAgICBicmVhazsKI2VuZGlmCiAgfQogIGlmIChyb3dTaXplID4gMCkgewogICAgcm93U2l6ZSArPSByb3dQYWQgLSAxOwogICAgcm93U2l6ZSAtPSByb3dTaXplICUgcm93UGFkOwogIH0KICBkYXRhID0gKFNwbGFzaENvbG9yUHRyKWdtYWxsb2NuX2NoZWNrb3ZlcmZsb3cocm93U2l6ZSwgaGVpZ2h0KTsKICBpZiAoZGF0YSAhPSBudWxscHRyKSB7CiAgICBpZiAoIXRvcERvd24pIHsKICAgICAgZGF0YSArPSAoaGVpZ2h0IC0gMSkgKiByb3dTaXplOwogICAgICByb3dTaXplID0gLXJvd1NpemU7CiAgICB9CiAgICBpZiAoYWxwaGFBKSB7CiAgICAgIGFscGhhID0gKEd1Y2hhciAqKWdtYWxsb2NuKHdpZHRoLCBoZWlnaHQpOwogICAgfSBlbHNlIHsKICAgICAgYWxwaGEgPSBudWxscHRyOwogICAgfQogIH0gZWxzZSB7CiAgICBhbHBoYSA9IG51bGxwdHI7CiAgfQogIHNlcGFyYXRpb25MaXN0ID0gbmV3IEdvb0xpc3QoKTsKICBpZiAoc2VwYXJhdGlvbkxpc3RBICE9IG51bGxwdHIpCiAgICBmb3IgKGludCBpID0gMDsgaSA8IHNlcGFyYXRpb25MaXN0QS0+Z2V0TGVuZ3RoKCk7IGkrKykKICAgICAgc2VwYXJhdGlvbkxpc3QtPmFwcGVuZCgoKEdmeFNlcGFyYXRpb25Db2xvclNwYWNlICopIHNlcGFyYXRpb25MaXN0QS0+Z2V0KGkpKS0+Y29weSgpKTsKfQoKU3BsYXNoQml0bWFwICpTcGxhc2hCaXRtYXA6OmNvcHkoU3BsYXNoQml0bWFwICpzcmMpIHsKICBTcGxhc2hCaXRtYXAgKnJlc3VsdCA9IG5ldyBTcGxhc2hCaXRtYXAoc3JjLT5nZXRXaWR0aCgpLCBzcmMtPmdldEhlaWdodCgpLCBzcmMtPmdldFJvd1BhZCgpLCAKICAgIHNyYy0+Z2V0TW9kZSgpLCBzcmMtPmdldEFscGhhUHRyKCkgIT0gbnVsbHB0ciwgc3JjLT5nZXRSb3dTaXplKCkgPj0gMCwgc3JjLT5nZXRTZXBhcmF0aW9uTGlzdCgpKTsKICBHdWNoYXIgKmRhdGFTb3VyY2UgPSBzcmMtPmdldERhdGFQdHIoKTsKICBHdWNoYXIgKmRhdGFEZXN0ID0gcmVzdWx0LT5nZXREYXRhUHRyKCk7CiAgaW50IGFtb3VudCA9IHNyYy0+Z2V0Um93U2l6ZSgpOwogIGlmIChhbW91bnQgPCAwKSB7CiAgICBkYXRhU291cmNlID0gZGF0YVNvdXJjZSArIChzcmMtPmdldEhlaWdodCgpIC0gMSkgKiBhbW91bnQ7CiAgICBkYXRhRGVzdCA9IGRhdGFEZXN0ICsgKHNyYy0+Z2V0SGVpZ2h0KCkgLSAxKSAqIGFtb3VudDsKICAgIGFtb3VudCAqPSAtc3JjLT5nZXRIZWlnaHQoKTsKICB9IGVsc2UgewogICAgYW1vdW50ICo9IHNyYy0+Z2V0SGVpZ2h0KCk7CiAgfQogIG1lbWNweShkYXRhRGVzdCwgZGF0YVNvdXJjZSwgYW1vdW50KTsKICBpZiAoc3JjLT5nZXRBbHBoYVB0cigpICE9IG51bGxwdHIpIHsKICAgIG1lbWNweShyZXN1bHQtPmdldEFscGhhUHRyKCksIHNyYy0+Z2V0QWxwaGFQdHIoKSwgc3JjLT5nZXRXaWR0aCgpICogc3JjLT5nZXRIZWlnaHQoKSk7CiAgfQogIHJldHVybiByZXN1bHQ7Cn0KClNwbGFzaEJpdG1hcDo6flNwbGFzaEJpdG1hcCgpIHsKICBpZiAoZGF0YSkgewogICAgaWYgKHJvd1NpemUgPCAwKSB7CiAgICAgIGdmcmVlKGRhdGEgKyAoaGVpZ2h0IC0gMSkgKiByb3dTaXplKTsKICAgIH0gZWxzZSB7CiAgICAgIGdmcmVlKGRhdGEpOwogICAgfQogIH0KICBnZnJlZShhbHBoYSk7CiAgZGVsZXRlR29vTGlzdChzZXBhcmF0aW9uTGlzdCwgR2Z4U2VwYXJhdGlvbkNvbG9yU3BhY2UpOwp9CgoKU3BsYXNoRXJyb3IgU3BsYXNoQml0bWFwOjp3cml0ZVBOTUZpbGUoY2hhciAqZmlsZU5hbWUpIHsKICBGSUxFICpmOwogIFNwbGFzaEVycm9yIGU7CgogIGlmICghKGYgPSBmb3BlbihmaWxlTmFtZSwgIndiIikpKSB7CiAgICByZXR1cm4gc3BsYXNoRXJyT3BlbkZpbGU7CiAgfQoKICBlID0gdGhpcy0+d3JpdGVQTk1GaWxlKGYpOwogIAogIGZjbG9zZShmKTsKICByZXR1cm4gZTsKfQoKClNwbGFzaEVycm9yIFNwbGFzaEJpdG1hcDo6d3JpdGVQTk1GaWxlKEZJTEUgKmYpIHsKICBTcGxhc2hDb2xvclB0ciByb3csIHA7CiAgaW50IHgsIHk7CgogIHN3aXRjaCAobW9kZSkgewoKICBjYXNlIHNwbGFzaE1vZGVNb25vMToKICAgIGZwcmludGYoZiwgIlA0XG4lZCAlZFxuIiwgd2lkdGgsIGhlaWdodCk7CiAgICByb3cgPSBkYXRhOwogICAgZm9yICh5ID0gMDsgeSA8IGhlaWdodDsgKyt5KSB7CiAgICAgIHAgPSByb3c7CiAgICAgIGZvciAoeCA9IDA7IHggPCB3aWR0aDsgeCArPSA4KSB7CglmcHV0YygqcCBeIDB4ZmYsIGYpOwoJKytwOwogICAgICB9CiAgICAgIHJvdyArPSByb3dTaXplOwogICAgfQogICAgYnJlYWs7CgogIGNhc2Ugc3BsYXNoTW9kZU1vbm84OgogICAgZnByaW50ZihmLCAiUDVcbiVkICVkXG4yNTVcbiIsIHdpZHRoLCBoZWlnaHQpOwogICAgcm93ID0gZGF0YTsKICAgIGZvciAoeSA9IDA7IHkgPCBoZWlnaHQ7ICsreSkgewogICAgICBmd3JpdGUocm93LCAxLCB3aWR0aCwgZik7CiAgICAgIHJvdyArPSByb3dTaXplOwogICAgfQogICAgYnJlYWs7CgogIGNhc2Ugc3BsYXNoTW9kZVJHQjg6CiAgICBmcHJpbnRmKGYsICJQNlxuJWQgJWRcbjI1NVxuIiwgd2lkdGgsIGhlaWdodCk7CiAgICByb3cgPSBkYXRhOwogICAgZm9yICh5ID0gMDsgeSA8IGhlaWdodDsgKyt5KSB7CiAgICAgIGZ3cml0ZShyb3csIDEsIDMgKiB3aWR0aCwgZik7CiAgICAgIHJvdyArPSByb3dTaXplOwogICAgfQogICAgYnJlYWs7CgogIGNhc2Ugc3BsYXNoTW9kZVhCR1I4OgogICAgZnByaW50ZihmLCAiUDZcbiVkICVkXG4yNTVcbiIsIHdpZHRoLCBoZWlnaHQpOwogICAgcm93ID0gZGF0YTsKICAgIGZvciAoeSA9IDA7IHkgPCBoZWlnaHQ7ICsreSkgewogICAgICBwID0gcm93OwogICAgICBmb3IgKHggPSAwOyB4IDwgd2lkdGg7ICsreCkgewoJZnB1dGMoc3BsYXNoQkdSOFIocCksIGYpOwoJZnB1dGMoc3BsYXNoQkdSOEcocCksIGYpOwoJZnB1dGMoc3BsYXNoQkdSOEIocCksIGYpOwoJcCArPSA0OwogICAgICB9CiAgICAgIHJvdyArPSByb3dTaXplOwogICAgfQogICAgYnJlYWs7CgoKICBjYXNlIHNwbGFzaE1vZGVCR1I4OgogICAgZnByaW50ZihmLCAiUDZcbiVkICVkXG4yNTVcbiIsIHdpZHRoLCBoZWlnaHQpOwogICAgcm93ID0gZGF0YTsKICAgIGZvciAoeSA9IDA7IHkgPCBoZWlnaHQ7ICsreSkgewogICAgICBwID0gcm93OwogICAgICBmb3IgKHggPSAwOyB4IDwgd2lkdGg7ICsreCkgewoJZnB1dGMoc3BsYXNoQkdSOFIocCksIGYpOwoJZnB1dGMoc3BsYXNoQkdSOEcocCksIGYpOwoJZnB1dGMoc3BsYXNoQkdSOEIocCksIGYpOwoJcCArPSAzOwogICAgICB9CiAgICAgIHJvdyArPSByb3dTaXplOwogICAgfQogICAgYnJlYWs7CgojaWZkZWYgU1BMQVNIX0NNWUsKICBjYXNlIHNwbGFzaE1vZGVDTVlLODoKICBjYXNlIHNwbGFzaE1vZGVEZXZpY2VOODoKICAgIC8vIFBOTSBkb2Vzbid0IHN1cHBvcnQgQ01ZSwogICAgZXJyb3IoZXJySW50ZXJuYWwsIC0xLCAidW5zdXBwb3J0ZWQgU3BsYXNoQml0bWFwIG1vZGUiKTsKICAgIHJldHVybiBzcGxhc2hFcnJHZW5lcmljOwogICAgYnJlYWs7CiNlbmRpZgogIH0KICByZXR1cm4gc3BsYXNoT2s7Cn0KClNwbGFzaEVycm9yIFNwbGFzaEJpdG1hcDo6d3JpdGVBbHBoYVBHTUZpbGUoY2hhciAqZmlsZU5hbWUpIHsKICBGSUxFICpmOwoKICBpZiAoIWFscGhhKSB7CiAgICByZXR1cm4gc3BsYXNoRXJyTW9kZU1pc21hdGNoOwogIH0KICBpZiAoIShmID0gZm9wZW4oZmlsZU5hbWUsICJ3YiIpKSkgewogICAgcmV0dXJuIHNwbGFzaEVyck9wZW5GaWxlOwogIH0KICBmcHJpbnRmKGYsICJQNVxuJWQgJWRcbjI1NVxuIiwgd2lkdGgsIGhlaWdodCk7CiAgZndyaXRlKGFscGhhLCAxLCB3aWR0aCAqIGhlaWdodCwgZik7CiAgZmNsb3NlKGYpOwogIHJldHVybiBzcGxhc2hPazsKfQoKdm9pZCBTcGxhc2hCaXRtYXA6OmdldFBpeGVsKGludCB4LCBpbnQgeSwgU3BsYXNoQ29sb3JQdHIgcGl4ZWwpIHsKICBTcGxhc2hDb2xvclB0ciBwOwoKICBpZiAoeSA8IDAgfHwgeSA+PSBoZWlnaHQgfHwgeCA8IDAgfHwgeCA+PSB3aWR0aCB8fCAhZGF0YSkgewogICAgcmV0dXJuOwogIH0KICBzd2l0Y2ggKG1vZGUpIHsKICBjYXNlIHNwbGFzaE1vZGVNb25vMToKICAgIHAgPSAmZGF0YVt5ICogcm93U2l6ZSArICh4ID4+IDMpXTsKICAgIHBpeGVsWzBdID0gKHBbMF0gJiAoMHg4MCA+PiAoeCAmIDcpKSkgPyAweGZmIDogMHgwMDsKICAgIGJyZWFrOwogIGNhc2Ugc3BsYXNoTW9kZU1vbm84OgogICAgcCA9ICZkYXRhW3kgKiByb3dTaXplICsgeF07CiAgICBwaXhlbFswXSA9IHBbMF07CiAgICBicmVhazsKICBjYXNlIHNwbGFzaE1vZGVSR0I4OgogICAgcCA9ICZkYXRhW3kgKiByb3dTaXplICsgMyAqIHhdOwogICAgcGl4ZWxbMF0gPSBwWzBdOwogICAgcGl4ZWxbMV0gPSBwWzFdOwogICAgcGl4ZWxbMl0gPSBwWzJdOwogICAgYnJlYWs7CiAgY2FzZSBzcGxhc2hNb2RlWEJHUjg6CiAgICBwID0gJmRhdGFbeSAqIHJvd1NpemUgKyA0ICogeF07CiAgICBwaXhlbFswXSA9IHBbMl07CiAgICBwaXhlbFsxXSA9IHBbMV07CiAgICBwaXhlbFsyXSA9IHBbMF07CiAgICBwaXhlbFszXSA9IHBbM107CiAgICBicmVhazsKICBjYXNlIHNwbGFzaE1vZGVCR1I4OgogICAgcCA9ICZkYXRhW3kgKiByb3dTaXplICsgMyAqIHhdOwogICAgcGl4ZWxbMF0gPSBwWzJdOwogICAgcGl4ZWxbMV0gPSBwWzFdOwogICAgcGl4ZWxbMl0gPSBwWzBdOwogICAgYnJlYWs7CiNpZmRlZiBTUExBU0hfQ01ZSwogIGNhc2Ugc3BsYXNoTW9kZUNNWUs4OgogICAgcCA9ICZkYXRhW3kgKiByb3dTaXplICsgNCAqIHhdOwogICAgcGl4ZWxbMF0gPSBwWzBdOwogICAgcGl4ZWxbMV0gPSBwWzFdOwogICAgcGl4ZWxbMl0gPSBwWzJdOwogICAgcGl4ZWxbM10gPSBwWzNdOwogICAgYnJlYWs7CiAgY2FzZSBzcGxhc2hNb2RlRGV2aWNlTjg6CiAgICBwID0gJmRhdGFbeSAqIHJvd1NpemUgKyAoU1BPVF9OQ09NUFMgKyA0KSAqIHhdOwogICAgZm9yIChpbnQgY3AgPSAwOyBjcCA8IFNQT1RfTkNPTVBTICsgNDsgY3ArKykKICAgICAgcGl4ZWxbY3BdID0gcFtjcF07CiAgICBicmVhazsKI2VuZGlmCiAgfQp9CgpHdWNoYXIgU3BsYXNoQml0bWFwOjpnZXRBbHBoYShpbnQgeCwgaW50IHkpIHsKICByZXR1cm4gYWxwaGFbeSAqIHdpZHRoICsgeF07Cn0KClNwbGFzaENvbG9yUHRyIFNwbGFzaEJpdG1hcDo6dGFrZURhdGEoKSB7CiAgU3BsYXNoQ29sb3JQdHIgZGF0YTI7CgogIGRhdGEyID0gZGF0YTsKICBkYXRhID0gbnVsbHB0cjsKICByZXR1cm4gZGF0YTI7Cn0KClNwbGFzaEVycm9yIFNwbGFzaEJpdG1hcDo6d3JpdGVJbWdGaWxlKFNwbGFzaEltYWdlRmlsZUZvcm1hdCBmb3JtYXQsIGNoYXIgKmZpbGVOYW1lLCBpbnQgaERQSSwgaW50IHZEUEksIFdyaXRlSW1nUGFyYW1zKiBwYXJhbXMpIHsKICBGSUxFICpmOwogIFNwbGFzaEVycm9yIGU7CgogIGlmICghKGYgPSBmb3BlbihmaWxlTmFtZSwgIndiIikpKSB7CiAgICByZXR1cm4gc3BsYXNoRXJyT3BlbkZpbGU7CiAgfQoKICBlID0gd3JpdGVJbWdGaWxlKGZvcm1hdCwgZiwgaERQSSwgdkRQSSwgcGFyYW1zKTsKCiAgZmNsb3NlKGYpOwogIHJldHVybiBlOwp9Cgp2b2lkIFNwbGFzaEJpdG1hcDo6c2V0SnBlZ1BhcmFtcyhJbWdXcml0ZXIgKndyaXRlciwgV3JpdGVJbWdQYXJhbXMqIHBhcmFtcykKewojaWZkZWYgRU5BQkxFX0xJQkpQRUcKICBpZiAocGFyYW1zKSB7CiAgICBzdGF0aWNfY2FzdDxKcGVnV3JpdGVyKj4od3JpdGVyKS0+c2V0UHJvZ3Jlc3NpdmUocGFyYW1zLT5qcGVnUHJvZ3Jlc3NpdmUpOwogICAgaWYgKHBhcmFtcy0+anBlZ1F1YWxpdHkgPj0gMCkKICAgICAgc3RhdGljX2Nhc3Q8SnBlZ1dyaXRlcio+KHdyaXRlciktPnNldFF1YWxpdHkocGFyYW1zLT5qcGVnUXVhbGl0eSk7CiAgfQojZW5kaWYKfQoKU3BsYXNoRXJyb3IgU3BsYXNoQml0bWFwOjp3cml0ZUltZ0ZpbGUoU3BsYXNoSW1hZ2VGaWxlRm9ybWF0IGZvcm1hdCwgRklMRSAqZiwgaW50IGhEUEksIGludCB2RFBJLCBXcml0ZUltZ1BhcmFtcyogcGFyYW1zKSB7CiAgSW1nV3JpdGVyICp3cml0ZXI7CglTcGxhc2hFcnJvciBlOwogIAogIFNwbGFzaENvbG9yTW9kZSBpbWFnZVdyaXRlckZvcm1hdCA9IHNwbGFzaE1vZGVSR0I4OwoKICBzd2l0Y2ggKGZvcm1hdCkgewogICAgI2lmZGVmIEVOQUJMRV9MSUJQTkcKICAgIGNhc2Ugc3BsYXNoRm9ybWF0UG5nOgoJICB3cml0ZXIgPSBuZXcgUE5HV3JpdGVyKCk7CiAgICAgIGJyZWFrOwogICAgI2VuZGlmCgogICAgI2lmZGVmIEVOQUJMRV9MSUJKUEVHCiAgICAjaWZkZWYgU1BMQVNIX0NNWUsKICAgIGNhc2Ugc3BsYXNoRm9ybWF0SnBlZ0NNWUs6CiAgICAgIHdyaXRlciA9IG5ldyBKcGVnV3JpdGVyKEpwZWdXcml0ZXI6OkNNWUspOwogICAgICBzZXRKcGVnUGFyYW1zKHdyaXRlciwgcGFyYW1zKTsKICAgICAgYnJlYWs7CiAgICAjZW5kaWYKICAgIGNhc2Ugc3BsYXNoRm9ybWF0SnBlZzoKICAgICAgd3JpdGVyID0gbmV3IEpwZWdXcml0ZXIoKTsKICAgICAgc2V0SnBlZ1BhcmFtcyh3cml0ZXIsIHBhcmFtcyk7CiAgICAgIGJyZWFrOwogICAgI2VuZGlmCgkKICAgICNpZmRlZiBFTkFCTEVfTElCVElGRgogICAgY2FzZSBzcGxhc2hGb3JtYXRUaWZmOgogICAgICBzd2l0Y2ggKG1vZGUpIHsKICAgICAgY2FzZSBzcGxhc2hNb2RlTW9ubzE6CiAgICAgICAgd3JpdGVyID0gbmV3IFRpZmZXcml0ZXIoVGlmZldyaXRlcjo6TU9OT0NIUk9NRSk7CiAgICAgICAgaW1hZ2VXcml0ZXJGb3JtYXQgPSBzcGxhc2hNb2RlTW9ubzE7CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2Ugc3BsYXNoTW9kZU1vbm84OgogICAgICAgIHdyaXRlciA9IG5ldyBUaWZmV3JpdGVyKFRpZmZXcml0ZXI6OkdSQVkpOwogICAgICAgIGltYWdlV3JpdGVyRm9ybWF0ID0gc3BsYXNoTW9kZU1vbm84OwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIHNwbGFzaE1vZGVSR0I4OgogICAgICBjYXNlIHNwbGFzaE1vZGVCR1I4OgogICAgICAgIHdyaXRlciA9IG5ldyBUaWZmV3JpdGVyKFRpZmZXcml0ZXI6OlJHQik7CiAgICAgICAgYnJlYWs7CiNpZmRlZiBTUExBU0hfQ01ZSwogICAgICBjYXNlIHNwbGFzaE1vZGVDTVlLODoKICAgICAgY2FzZSBzcGxhc2hNb2RlRGV2aWNlTjg6CiAgICAgICAgd3JpdGVyID0gbmV3IFRpZmZXcml0ZXIoVGlmZldyaXRlcjo6Q01ZSyk7CiAgICAgICAgYnJlYWs7CiNlbmRpZgogICAgICBkZWZhdWx0OgogICAgICAgIGZwcmludGYoc3RkZXJyLCAiVGlmZldyaXRlcjogTW9kZSAlZCBub3Qgc3VwcG9ydGVkXG4iLCBtb2RlKTsKICAgICAgICB3cml0ZXIgPSBuZXcgVGlmZldyaXRlcigpOwogICAgICB9CiAgICAgIGlmICh3cml0ZXIgJiYgcGFyYW1zKSB7CiAgICAgICAgKChUaWZmV3JpdGVyICopd3JpdGVyKS0+c2V0Q29tcHJlc3Npb25TdHJpbmcocGFyYW1zLT50aWZmQ29tcHJlc3Npb24uZ2V0Q1N0cmluZygpKTsKICAgICAgfQogICAgICBicmVhazsKICAgICNlbmRpZgoKICAgIGRlZmF1bHQ6CiAgICAgIC8vIE5vdCB0aGUgZ3JlYXRlc3QgZXJyb3IgbWVzc2FnZSwgYnV0IHVzZXJzIG9mIHRoaXMgZnVuY3Rpb24gc2hvdWxkCiAgICAgIC8vIGhhdmUgYWxyZWFkeSBjaGVja2VkIHdoZXRoZXIgdGhlaXIgZGVzaXJlZCBmb3JtYXQgaXMgY29tcGlsZWQgaW4uCiAgICAgIGVycm9yKGVyckludGVybmFsLCAtMSwgIlN1cHBvcnQgZm9yIHRoaXMgaW1hZ2UgdHlwZSBub3QgY29tcGlsZWQgaW4iKTsKICAgICAgcmV0dXJuIHNwbGFzaEVyckdlbmVyaWM7CiAgfQoKCWUgPSB3cml0ZUltZ0ZpbGUod3JpdGVyLCBmLCBoRFBJLCB2RFBJLCBpbWFnZVdyaXRlckZvcm1hdCk7CglkZWxldGUgd3JpdGVyOwoJcmV0dXJuIGU7Cn0KCiNpbmNsdWRlICJwb3BwbGVyL0dmeFN0YXRlX2hlbHBlcnMuaCIKCnZvaWQgU3BsYXNoQml0bWFwOjpnZXRSR0JMaW5lKGludCB5bCwgU3BsYXNoQ29sb3JQdHIgbGluZSkgewogIFNwbGFzaENvbG9yIGNvbDsKICBkb3VibGUgYywgbSwgeSwgaywgYzEsIG0xLCB5MSwgazEsIHIsIGcsIGI7CgogIGZvciAoaW50IHggPSAwOyB4IDwgd2lkdGg7IHgrKykgewogICAgZ2V0UGl4ZWwoeCwgeWwsIGNvbCk7CiAgICBjID0gYnl0ZVRvRGJsKGNvbFswXSk7CiAgICBtID0gYnl0ZVRvRGJsKGNvbFsxXSk7CiAgICB5ID0gYnl0ZVRvRGJsKGNvbFsyXSk7CiAgICBrID0gYnl0ZVRvRGJsKGNvbFszXSk7CiNpZmRlZiBTUExBU0hfQ01ZSwogICAgaWYgKHNlcGFyYXRpb25MaXN0LT5nZXRMZW5ndGgoKSA+IDApIHsKICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzZXBhcmF0aW9uTGlzdC0+Z2V0TGVuZ3RoKCk7IGkrKykgewogICAgICAgIGlmIChjb2xbaSs0XSA+IDApIHsKICAgICAgICAgIEdmeENNWUsgY215azsKICAgICAgICAgIEdmeENvbG9yIGlucHV0OwogICAgICAgICAgaW5wdXQuY1swXSA9IGJ5dGVUb0NvbChjb2xbaSs0XSk7CiAgICAgICAgICBHZnhTZXBhcmF0aW9uQ29sb3JTcGFjZSAqc2VwQ1MgPSAoR2Z4U2VwYXJhdGlvbkNvbG9yU3BhY2UgKilzZXBhcmF0aW9uTGlzdC0+Z2V0KGkpOwogICAgICAgICAgc2VwQ1MtPmdldENNWUsoJmlucHV0LCAmY215ayk7CiAgICAgICAgICBjb2xbMF0gPSBjb2xUb0J5dGUoY215ay5jKTsKICAgICAgICAgIGNvbFsxXSA9IGNvbFRvQnl0ZShjbXlrLm0pOwogICAgICAgICAgY29sWzJdID0gY29sVG9CeXRlKGNteWsueSk7CiAgICAgICAgICBjb2xbM10gPSBjb2xUb0J5dGUoY215ay5rKTsKICAgICAgICAgIGMgKz0gYnl0ZVRvRGJsKGNvbFswXSk7CiAgICAgICAgICBtICs9IGJ5dGVUb0RibChjb2xbMV0pOwogICAgICAgICAgeSArPSBieXRlVG9EYmwoY29sWzJdKTsKICAgICAgICAgIGsgKz0gYnl0ZVRvRGJsKGNvbFszXSk7CiAgICAgICAgfQogICAgICB9CiAgICAgIGlmIChjID4gMSkgYyA9IDE7CiAgICAgIGlmIChtID4gMSkgbSA9IDE7CiAgICAgIGlmICh5ID4gMSkgeSA9IDE7CiAgICAgIGlmIChrID4gMSkgayA9IDE7CiAgICB9CiNlbmRpZgogICAgYzEgPSAxIC0gYzsKICAgIG0xID0gMSAtIG07CiAgICB5MSA9IDEgLSB5OwogICAgazEgPSAxIC0gazsKICAgIGNteWtUb1JHQk1hdHJpeE11bHRpcGxpY2F0aW9uKGMsIG0sIHksIGssIGMxLCBtMSwgeTEsIGsxLCByLCBnLCBiKTsKICAgICpsaW5lKysgPSBkYmxUb0J5dGUoY2xpcDAxKHIpKTsKICAgICpsaW5lKysgPSBkYmxUb0J5dGUoY2xpcDAxKGcpKTsKICAgICpsaW5lKysgPSBkYmxUb0J5dGUoY2xpcDAxKGIpKTsKICB9Cn0KCnZvaWQgU3BsYXNoQml0bWFwOjpnZXRYQkdSTGluZShpbnQgeWwsIFNwbGFzaENvbG9yUHRyIGxpbmUsIENvbnZlcnNpb25Nb2RlIGNvbnZlcnNpb25Nb2RlKSB7CiAgU3BsYXNoQ29sb3IgY29sOwogIGRvdWJsZSBjLCBtLCB5LCBrLCBjMSwgbTEsIHkxLCBrMSwgciwgZywgYjsKCiAgZm9yIChpbnQgeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7CiAgICBnZXRQaXhlbCh4LCB5bCwgY29sKTsKICAgIGMgPSBieXRlVG9EYmwoY29sWzBdKTsKICAgIG0gPSBieXRlVG9EYmwoY29sWzFdKTsKICAgIHkgPSBieXRlVG9EYmwoY29sWzJdKTsKICAgIGsgPSBieXRlVG9EYmwoY29sWzNdKTsKI2lmZGVmIFNQTEFTSF9DTVlLCiAgICBpZiAoc2VwYXJhdGlvbkxpc3QtPmdldExlbmd0aCgpID4gMCkgewogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNlcGFyYXRpb25MaXN0LT5nZXRMZW5ndGgoKTsgaSsrKSB7CiAgICAgICAgaWYgKGNvbFtpKzRdID4gMCkgewogICAgICAgICAgR2Z4Q01ZSyBjbXlrOwogICAgICAgICAgR2Z4Q29sb3IgaW5wdXQ7CiAgICAgICAgICBpbnB1dC5jWzBdID0gYnl0ZVRvQ29sKGNvbFtpKzRdKTsKICAgICAgICAgIEdmeFNlcGFyYXRpb25Db2xvclNwYWNlICpzZXBDUyA9IChHZnhTZXBhcmF0aW9uQ29sb3JTcGFjZSAqKXNlcGFyYXRpb25MaXN0LT5nZXQoaSk7CiAgICAgICAgICBzZXBDUy0+Z2V0Q01ZSygmaW5wdXQsICZjbXlrKTsKICAgICAgICAgIGNvbFswXSA9IGNvbFRvQnl0ZShjbXlrLmMpOwogICAgICAgICAgY29sWzFdID0gY29sVG9CeXRlKGNteWsubSk7CiAgICAgICAgICBjb2xbMl0gPSBjb2xUb0J5dGUoY215ay55KTsKICAgICAgICAgIGNvbFszXSA9IGNvbFRvQnl0ZShjbXlrLmspOwogICAgICAgICAgYyArPSBieXRlVG9EYmwoY29sWzBdKTsKICAgICAgICAgIG0gKz0gYnl0ZVRvRGJsKGNvbFsxXSk7CiAgICAgICAgICB5ICs9IGJ5dGVUb0RibChjb2xbMl0pOwogICAgICAgICAgayArPSBieXRlVG9EYmwoY29sWzNdKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgaWYgKGMgPiAxKSBjID0gMTsKICAgICAgaWYgKG0gPiAxKSBtID0gMTsKICAgICAgaWYgKHkgPiAxKSB5ID0gMTsKICAgICAgaWYgKGsgPiAxKSBrID0gMTsKICAgIH0KI2VuZGlmCiAgICBjMSA9IDEgLSBjOwogICAgbTEgPSAxIC0gbTsKICAgIHkxID0gMSAtIHk7CiAgICBrMSA9IDEgLSBrOwogICAgY215a1RvUkdCTWF0cml4TXVsdGlwbGljYXRpb24oYywgbSwgeSwgaywgYzEsIG0xLCB5MSwgazEsIHIsIGcsIGIpOwoKICAgIGlmIChjb252ZXJzaW9uTW9kZSA9PSBjb252ZXJzaW9uQWxwaGFQcmVtdWx0aXBsaWVkKSB7CiAgICAgICAgY29uc3QgZG91YmxlIGEgPSBnZXRBbHBoYSh4LCB5bCkgLyAyNTUuMDsKCiAgICAgICAgKmxpbmUrKyA9IGRibFRvQnl0ZShjbGlwMDEoYiAqIGEpKTsKICAgICAgICAqbGluZSsrID0gZGJsVG9CeXRlKGNsaXAwMShnICogYSkpOwogICAgICAgICpsaW5lKysgPSBkYmxUb0J5dGUoY2xpcDAxKHIgKiBhKSk7CiAgICB9IGVsc2UgewogICAgICAgICpsaW5lKysgPSBkYmxUb0J5dGUoY2xpcDAxKGIpKTsKICAgICAgICAqbGluZSsrID0gZGJsVG9CeXRlKGNsaXAwMShnKSk7CiAgICAgICAgKmxpbmUrKyA9IGRibFRvQnl0ZShjbGlwMDEocikpOwogICAgfQoKICAgIGlmIChjb252ZXJzaW9uTW9kZSAhPSBjb252ZXJzaW9uT3BhcXVlKSB7CiAgICAgICAgKmxpbmUrKyA9IGdldEFscGhhKHgsIHlsKTsKICAgIH0gZWxzZSB7CiAgICAgICAgKmxpbmUrKyA9IDI1NTsKICAgIH0KICB9Cn0KCnN0YXRpYyBpbmxpbmUgR3VjaGFyIGRpdjI1NShpbnQgeCkgewogIHJldHVybiAoR3VjaGFyKSgoeCArICh4ID4+IDgpICsgMHg4MCkgPj4gOCk7Cn0KCkdCb29sIFNwbGFzaEJpdG1hcDo6Y29udmVydFRvWEJHUihDb252ZXJzaW9uTW9kZSBjb252ZXJzaW9uTW9kZSkgewogIGlmIChtb2RlID09IHNwbGFzaE1vZGVYQkdSOCkgewogICAgaWYgKGNvbnZlcnNpb25Nb2RlICE9IGNvbnZlcnNpb25PcGFxdWUpIHsKICAgICAgLy8gQ29weSB0aGUgYWxwaGEgY2hhbm5lbCBpbnRvIHRoZSBmb3VydGggY29tcG9uZW50IHNvIHRoYXQgWEJHUiBiZWNvbWVzIEFCR1IuCiAgICAgIGNvbnN0IFNwbGFzaENvbG9yUHRyIGRiZWdpbiA9IGRhdGE7CiAgICAgIGNvbnN0IFNwbGFzaENvbG9yUHRyIGRlbmQgPSBkYXRhICsgcm93U2l6ZSAqIGhlaWdodDsKCiAgICAgIEd1Y2hhciAqY29uc3QgYWJlZ2luID0gYWxwaGE7CiAgICAgIEd1Y2hhciAqY29uc3QgYWVuZCA9IGFscGhhICsgd2lkdGggKiBoZWlnaHQ7CgogICAgICBTcGxhc2hDb2xvclB0ciBkID0gZGJlZ2luOwogICAgICBHdWNoYXIgKmEgPSBhYmVnaW47CgogICAgICBpZiAoY29udmVyc2lvbk1vZGUgPT0gY29udmVyc2lvbkFscGhhUHJlbXVsdGlwbGllZCkgewogICAgICAgICAgZm9yICg7IGQgPCBkZW5kICYmIGEgPCBhZW5kOyBkICs9IDQsIGEgKz0gMSkgewogICAgICAgICAgICAgIGRbMF0gPSBkaXYyNTUoZFswXSAqICphKTsKICAgICAgICAgICAgICBkWzFdID0gZGl2MjU1KGRbMV0gKiAqYSk7CiAgICAgICAgICAgICAgZFsyXSA9IGRpdjI1NShkWzJdICogKmEpOwogICAgICAgICAgICAgIGRbM10gPSAqYTsKICAgICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZvciAoZCArPSAzOyBkIDwgZGVuZCAmJiBhIDwgYWVuZDsgZCArPSA0LCBhICs9IDEpIHsKICAgICAgICAgICAgICAqZCA9ICphOwogICAgICAgICAgfQogICAgICB9CiAgICB9CgogICAgcmV0dXJuIGdUcnVlOwogIH0KICAKICBpbnQgbmV3cm93U2l6ZSA9IHdpZHRoICogNDsKICBTcGxhc2hDb2xvclB0ciBuZXdkYXRhID0gKFNwbGFzaENvbG9yUHRyKWdtYWxsb2NuX2NoZWNrb3ZlcmZsb3cobmV3cm93U2l6ZSwgaGVpZ2h0KTsKICBpZiAobmV3ZGF0YSAhPSBudWxscHRyKSB7CiAgICBmb3IgKGludCB5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CiAgICAgIHVuc2lnbmVkIGNoYXIgKnJvdyA9IG5ld2RhdGEgKyB5ICogbmV3cm93U2l6ZTsKICAgICAgZ2V0WEJHUkxpbmUoeSwgcm93LCBjb252ZXJzaW9uTW9kZSk7CiAgICB9CiAgICBpZiAocm93U2l6ZSA8IDApIHsKICAgICAgZ2ZyZWUoZGF0YSArIChoZWlnaHQgLSAxKSAqIHJvd1NpemUpOwogICAgfSBlbHNlIHsKICAgICAgZ2ZyZWUoZGF0YSk7CiAgICB9CiAgICBkYXRhID0gbmV3ZGF0YTsKICAgIHJvd1NpemUgPSBuZXdyb3dTaXplOwogICAgbW9kZSA9IHNwbGFzaE1vZGVYQkdSODsKICB9CiAgcmV0dXJuIG5ld2RhdGEgIT0gbnVsbHB0cjsKfQoKI2lmZGVmIFNQTEFTSF9DTVlLCnZvaWQgU3BsYXNoQml0bWFwOjpnZXRDTVlLTGluZShpbnQgeWwsIFNwbGFzaENvbG9yUHRyIGxpbmUpIHsKICBTcGxhc2hDb2xvciBjb2w7CgogIGZvciAoaW50IHggPSAwOyB4IDwgd2lkdGg7IHgrKykgewogICAgZ2V0UGl4ZWwoeCwgeWwsIGNvbCk7CiAgICBpZiAoc2VwYXJhdGlvbkxpc3QtPmdldExlbmd0aCgpID4gMCkgewogICAgICBkb3VibGUgYywgbSwgeSwgazsKICAgICAgYyA9IGJ5dGVUb0RibChjb2xbMF0pOwogICAgICBtID0gYnl0ZVRvRGJsKGNvbFsxXSk7CiAgICAgIHkgPSBieXRlVG9EYmwoY29sWzJdKTsKICAgICAgayA9IGJ5dGVUb0RibChjb2xbM10pOwogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNlcGFyYXRpb25MaXN0LT5nZXRMZW5ndGgoKTsgaSsrKSB7CiAgICAgICAgaWYgKGNvbFtpKzRdID4gMCkgewogICAgICAgICAgR2Z4Q01ZSyBjbXlrOwogICAgICAgICAgR2Z4Q29sb3IgaW5wdXQ7CiAgICAgICAgICBpbnB1dC5jWzBdID0gYnl0ZVRvQ29sKGNvbFtpKzRdKTsKICAgICAgICAgIEdmeFNlcGFyYXRpb25Db2xvclNwYWNlICpzZXBDUyA9IChHZnhTZXBhcmF0aW9uQ29sb3JTcGFjZSAqKXNlcGFyYXRpb25MaXN0LT5nZXQoaSk7CiAgICAgICAgICBzZXBDUy0+Z2V0Q01ZSygmaW5wdXQsICZjbXlrKTsKICAgICAgICAgIGNvbFswXSA9IGNvbFRvQnl0ZShjbXlrLmMpOwogICAgICAgICAgY29sWzFdID0gY29sVG9CeXRlKGNteWsubSk7CiAgICAgICAgICBjb2xbMl0gPSBjb2xUb0J5dGUoY215ay55KTsKICAgICAgICAgIGNvbFszXSA9IGNvbFRvQnl0ZShjbXlrLmspOwogICAgICAgICAgYyArPSBieXRlVG9EYmwoY29sWzBdKTsKICAgICAgICAgIG0gKz0gYnl0ZVRvRGJsKGNvbFsxXSk7CiAgICAgICAgICB5ICs9IGJ5dGVUb0RibChjb2xbMl0pOwogICAgICAgICAgayArPSBieXRlVG9EYmwoY29sWzNdKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgY29sWzBdID0gZGJsVG9CeXRlKGNsaXAwMShjKSk7CiAgICAgIGNvbFsxXSA9IGRibFRvQnl0ZShjbGlwMDEobSkpOwogICAgICBjb2xbMl0gPSBkYmxUb0J5dGUoY2xpcDAxKHkpKTsKICAgICAgY29sWzNdID0gZGJsVG9CeXRlKGNsaXAwMShrKSk7CiAgICB9CiAgICAqbGluZSsrID0gY29sWzBdOwogICAgKmxpbmUrKyA9IGNvbFsxXTsKICAgICpsaW5lKysgPSBjb2xbMl07CiAgICAqbGluZSsrID0gY29sWzNdOwogIH0KfQojZW5kaWYKClNwbGFzaEVycm9yIFNwbGFzaEJpdG1hcDo6d3JpdGVJbWdGaWxlKEltZ1dyaXRlciAqd3JpdGVyLCBGSUxFICpmLCBpbnQgaERQSSwgaW50IHZEUEksIFNwbGFzaENvbG9yTW9kZSBpbWFnZVdyaXRlckZvcm1hdCkgewogIGlmIChtb2RlICE9IHNwbGFzaE1vZGVSR0I4ICYmIG1vZGUgIT0gc3BsYXNoTW9kZU1vbm84ICYmIG1vZGUgIT0gc3BsYXNoTW9kZU1vbm8xICYmIG1vZGUgIT0gc3BsYXNoTW9kZVhCR1I4ICYmIG1vZGUgIT0gc3BsYXNoTW9kZUJHUjgKI2lmZGVmIFNQTEFTSF9DTVlLCiAgICAgICYmIG1vZGUgIT0gc3BsYXNoTW9kZUNNWUs4ICYmIG1vZGUgIT0gc3BsYXNoTW9kZURldmljZU44CiNlbmRpZgogICAgICkgewogICAgZXJyb3IoZXJySW50ZXJuYWwsIC0xLCAidW5zdXBwb3J0ZWQgU3BsYXNoQml0bWFwIG1vZGUiKTsKICAgIHJldHVybiBzcGxhc2hFcnJHZW5lcmljOwogIH0KCiAgaWYgKCF3cml0ZXItPmluaXQoZiwgd2lkdGgsIGhlaWdodCwgaERQSSwgdkRQSSkpIHsKICAgIHJldHVybiBzcGxhc2hFcnJHZW5lcmljOwogIH0KCiAgc3dpdGNoIChtb2RlKSB7CiNpZmRlZiBTUExBU0hfQ01ZSwogICAgY2FzZSBzcGxhc2hNb2RlQ01ZSzg6CiAgICAgIGlmICh3cml0ZXItPnN1cHBvcnRDTVlLKCkpIHsKICAgICAgICBTcGxhc2hDb2xvclB0ciByb3c7CiAgICAgICAgdW5zaWduZWQgY2hhciAqKnJvd19wb2ludGVycyA9IG5ldyB1bnNpZ25lZCBjaGFyKltoZWlnaHRdOwogICAgICAgIHJvdyA9IGRhdGE7CgogICAgICAgIGZvciAoaW50IHkgPSAwOyB5IDwgaGVpZ2h0OyArK3kpIHsKICAgICAgICAgIHJvd19wb2ludGVyc1t5XSA9IHJvdzsKICAgICAgICAgIHJvdyArPSByb3dTaXplOwogICAgICAgIH0KICAgICAgICBpZiAoIXdyaXRlci0+d3JpdGVQb2ludGVycyhyb3dfcG9pbnRlcnMsIGhlaWdodCkpIHsKICAgICAgICAgIGRlbGV0ZVtdIHJvd19wb2ludGVyczsKICAgICAgICAgIHJldHVybiBzcGxhc2hFcnJHZW5lcmljOwogICAgICAgIH0KICAgICAgICBkZWxldGVbXSByb3dfcG9pbnRlcnM7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdW5zaWduZWQgY2hhciAqcm93ID0gbmV3IHVuc2lnbmVkIGNoYXJbMyAqIHdpZHRoXTsKICAgICAgICBmb3IgKGludCB5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CiAgICAgICAgICBnZXRSR0JMaW5lKHksIHJvdyk7CiAgICAgICAgICBpZiAoIXdyaXRlci0+d3JpdGVSb3coJnJvdykpIHsKICAgICAgICAgICAgZGVsZXRlW10gcm93OwogICAgICAgICAgICByZXR1cm4gc3BsYXNoRXJyR2VuZXJpYzsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZGVsZXRlW10gcm93OwogICAgICB9CiAgICBicmVhazsKICAgIGNhc2Ugc3BsYXNoTW9kZURldmljZU44OgogICAgICBpZiAod3JpdGVyLT5zdXBwb3J0Q01ZSygpKSB7CiAgICAgICAgdW5zaWduZWQgY2hhciAqcm93ID0gbmV3IHVuc2lnbmVkIGNoYXJbNCAqIHdpZHRoXTsKICAgICAgICBmb3IgKGludCB5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CiAgICAgICAgICBnZXRDTVlLTGluZSh5LCByb3cpOwogICAgICAgICAgaWYgKCF3cml0ZXItPndyaXRlUm93KCZyb3cpKSB7CiAgICAgICAgICAgIGRlbGV0ZVtdIHJvdzsKICAgICAgICAgICAgcmV0dXJuIHNwbGFzaEVyckdlbmVyaWM7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGRlbGV0ZVtdIHJvdzsKICAgICAgfSBlbHNlIHsKICAgICAgICB1bnNpZ25lZCBjaGFyICpyb3cgPSBuZXcgdW5zaWduZWQgY2hhclszICogd2lkdGhdOwogICAgICAgIGZvciAoaW50IHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKICAgICAgICAgIGdldFJHQkxpbmUoeSwgcm93KTsKICAgICAgICAgIGlmICghd3JpdGVyLT53cml0ZVJvdygmcm93KSkgewogICAgICAgICAgICBkZWxldGVbXSByb3c7CiAgICAgICAgICAgIHJldHVybiBzcGxhc2hFcnJHZW5lcmljOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBkZWxldGVbXSByb3c7CiAgICAgIH0KICAgIGJyZWFrOwojZW5kaWYKICAgIGNhc2Ugc3BsYXNoTW9kZVJHQjg6CiAgICB7CiAgICAgIFNwbGFzaENvbG9yUHRyIHJvdzsKICAgICAgdW5zaWduZWQgY2hhciAqKnJvd19wb2ludGVycyA9IG5ldyB1bnNpZ25lZCBjaGFyKltoZWlnaHRdOwogICAgICByb3cgPSBkYXRhOwoKICAgICAgZm9yIChpbnQgeSA9IDA7IHkgPCBoZWlnaHQ7ICsreSkgewogICAgICAgIHJvd19wb2ludGVyc1t5XSA9IHJvdzsKICAgICAgICByb3cgKz0gcm93U2l6ZTsKICAgICAgfQogICAgICBpZiAoIXdyaXRlci0+d3JpdGVQb2ludGVycyhyb3dfcG9pbnRlcnMsIGhlaWdodCkpIHsKICAgICAgICBkZWxldGVbXSByb3dfcG9pbnRlcnM7CiAgICAgICAgcmV0dXJuIHNwbGFzaEVyckdlbmVyaWM7CiAgICAgIH0KICAgICAgZGVsZXRlW10gcm93X3BvaW50ZXJzOwogICAgfQogICAgYnJlYWs7CiAgICAKICAgIGNhc2Ugc3BsYXNoTW9kZUJHUjg6CiAgICB7CiAgICAgIHVuc2lnbmVkIGNoYXIgKnJvdyA9IG5ldyB1bnNpZ25lZCBjaGFyWzMgKiB3aWR0aF07CiAgICAgIGZvciAoaW50IHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKICAgICAgICAvLyBDb252ZXJ0IGludG8gYSBQTkcgcm93CiAgICAgICAgZm9yIChpbnQgeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7CiAgICAgICAgICByb3dbMyp4XSA9IGRhdGFbeSAqIHJvd1NpemUgKyB4ICogMyArIDJdOwogICAgICAgICAgcm93WzMqeCsxXSA9IGRhdGFbeSAqIHJvd1NpemUgKyB4ICogMyArIDFdOwogICAgICAgICAgcm93WzMqeCsyXSA9IGRhdGFbeSAqIHJvd1NpemUgKyB4ICogM107CiAgICAgICAgfQoKICAgICAgICBpZiAoIXdyaXRlci0+d3JpdGVSb3coJnJvdykpIHsKICAgICAgICAgIGRlbGV0ZVtdIHJvdzsKICAgICAgICAgIHJldHVybiBzcGxhc2hFcnJHZW5lcmljOwogICAgICAgIH0KICAgICAgfQogICAgICBkZWxldGVbXSByb3c7CiAgICB9CiAgICBicmVhazsKICAgIAogICAgY2FzZSBzcGxhc2hNb2RlWEJHUjg6CiAgICB7CiAgICAgIHVuc2lnbmVkIGNoYXIgKnJvdyA9IG5ldyB1bnNpZ25lZCBjaGFyWzMgKiB3aWR0aF07CiAgICAgIGZvciAoaW50IHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKICAgICAgICAvLyBDb252ZXJ0IGludG8gYSBQTkcgcm93CiAgICAgICAgZm9yIChpbnQgeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7CiAgICAgICAgICByb3dbMyp4XSA9IGRhdGFbeSAqIHJvd1NpemUgKyB4ICogNCArIDJdOwogICAgICAgICAgcm93WzMqeCsxXSA9IGRhdGFbeSAqIHJvd1NpemUgKyB4ICogNCArIDFdOwogICAgICAgICAgcm93WzMqeCsyXSA9IGRhdGFbeSAqIHJvd1NpemUgKyB4ICogNF07CiAgICAgICAgfQoKICAgICAgICBpZiAoIXdyaXRlci0+d3JpdGVSb3coJnJvdykpIHsKICAgICAgICAgIGRlbGV0ZVtdIHJvdzsKICAgICAgICAgIHJldHVybiBzcGxhc2hFcnJHZW5lcmljOwogICAgICAgIH0KICAgICAgfQogICAgICBkZWxldGVbXSByb3c7CiAgICB9CiAgICBicmVhazsKICAgIAogICAgY2FzZSBzcGxhc2hNb2RlTW9ubzg6CiAgICB7CiAgICAgIGlmIChpbWFnZVdyaXRlckZvcm1hdCA9PSBzcGxhc2hNb2RlTW9ubzgpIHsKICAgICAgICBTcGxhc2hDb2xvclB0ciByb3c7CiAgICAgICAgdW5zaWduZWQgY2hhciAqKnJvd19wb2ludGVycyA9IG5ldyB1bnNpZ25lZCBjaGFyKltoZWlnaHRdOwogICAgICAgIHJvdyA9IGRhdGE7CgogICAgICAgIGZvciAoaW50IHkgPSAwOyB5IDwgaGVpZ2h0OyArK3kpIHsKICAgICAgICAgIHJvd19wb2ludGVyc1t5XSA9IHJvdzsKICAgICAgICAgIHJvdyArPSByb3dTaXplOwogICAgICAgIH0KICAgICAgICBpZiAoIXdyaXRlci0+d3JpdGVQb2ludGVycyhyb3dfcG9pbnRlcnMsIGhlaWdodCkpIHsKICAgICAgICAgIGRlbGV0ZVtdIHJvd19wb2ludGVyczsKICAgICAgICAgIHJldHVybiBzcGxhc2hFcnJHZW5lcmljOwogICAgICAgIH0KICAgICAgICBkZWxldGVbXSByb3dfcG9pbnRlcnM7CiAgICAgIH0gZWxzZSBpZiAoaW1hZ2VXcml0ZXJGb3JtYXQgPT0gc3BsYXNoTW9kZVJHQjgpIHsKICAgICAgICB1bnNpZ25lZCBjaGFyICpyb3cgPSBuZXcgdW5zaWduZWQgY2hhclszICogd2lkdGhdOwogICAgICAgIGZvciAoaW50IHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKICAgICAgICAgIC8vIENvbnZlcnQgaW50byBhIFBORyByb3cKICAgICAgICAgIGZvciAoaW50IHggPSAwOyB4IDwgd2lkdGg7IHgrKykgewogICAgICAgICAgICByb3dbMyp4XSA9IGRhdGFbeSAqIHJvd1NpemUgKyB4XTsKICAgICAgICAgICAgcm93WzMqeCsxXSA9IGRhdGFbeSAqIHJvd1NpemUgKyB4XTsKICAgICAgICAgICAgcm93WzMqeCsyXSA9IGRhdGFbeSAqIHJvd1NpemUgKyB4XTsKICAgICAgICAgIH0KCiAgICAgICAgICBpZiAoIXdyaXRlci0+d3JpdGVSb3coJnJvdykpIHsKICAgICAgICAgICAgZGVsZXRlW10gcm93OwogICAgICAgICAgICByZXR1cm4gc3BsYXNoRXJyR2VuZXJpYzsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZGVsZXRlW10gcm93OwogICAgICB9CiAgICAgIGVsc2UgewogICAgICAgIC8vIG9ubHkgc3BsYXNoTW9kZU1vbm84IG9yIHNwbGFzaE1vZGVSR0I4CiAgICAgICAgcmV0dXJuIHNwbGFzaEVyckdlbmVyaWM7CiAgICAgIH0KICAgIH0KICAgIGJyZWFrOwogICAgCiAgICBjYXNlIHNwbGFzaE1vZGVNb25vMToKICAgIHsKICAgICAgaWYgKGltYWdlV3JpdGVyRm9ybWF0ID09IHNwbGFzaE1vZGVNb25vMSkgewogICAgICAgIFNwbGFzaENvbG9yUHRyIHJvdzsKICAgICAgICB1bnNpZ25lZCBjaGFyICoqcm93X3BvaW50ZXJzID0gbmV3IHVuc2lnbmVkIGNoYXIqW2hlaWdodF07CiAgICAgICAgcm93ID0gZGF0YTsKCiAgICAgICAgZm9yIChpbnQgeSA9IDA7IHkgPCBoZWlnaHQ7ICsreSkgewogICAgICAgICAgcm93X3BvaW50ZXJzW3ldID0gcm93OwogICAgICAgICAgcm93ICs9IHJvd1NpemU7CiAgICAgICAgfQogICAgICAgIGlmICghd3JpdGVyLT53cml0ZVBvaW50ZXJzKHJvd19wb2ludGVycywgaGVpZ2h0KSkgewogICAgICAgICAgZGVsZXRlW10gcm93X3BvaW50ZXJzOwogICAgICAgICAgcmV0dXJuIHNwbGFzaEVyckdlbmVyaWM7CiAgICAgICAgfQogICAgICAgIGRlbGV0ZVtdIHJvd19wb2ludGVyczsKICAgICAgfSBlbHNlIGlmIChpbWFnZVdyaXRlckZvcm1hdCA9PSBzcGxhc2hNb2RlUkdCOCkgewogICAgICAgIHVuc2lnbmVkIGNoYXIgKnJvdyA9IG5ldyB1bnNpZ25lZCBjaGFyWzMgKiB3aWR0aF07CiAgICAgICAgZm9yIChpbnQgeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewogICAgICAgICAgLy8gQ29udmVydCBpbnRvIGEgUE5HIHJvdwogICAgICAgICAgZm9yIChpbnQgeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7CiAgICAgICAgICAgIGdldFBpeGVsKHgsIHksICZyb3dbMyp4XSk7CiAgICAgICAgICAgIHJvd1szKngrMV0gPSByb3dbMyp4XTsKICAgICAgICAgICAgcm93WzMqeCsyXSA9IHJvd1szKnhdOwogICAgICAgICAgfQoKICAgICAgICAgIGlmICghd3JpdGVyLT53cml0ZVJvdygmcm93KSkgewogICAgICAgICAgICBkZWxldGVbXSByb3c7CiAgICAgICAgICAgIHJldHVybiBzcGxhc2hFcnJHZW5lcmljOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBkZWxldGVbXSByb3c7CiAgICAgIH0KICAgICAgZWxzZSB7CiAgICAgICAgLy8gb25seSBzcGxhc2hNb2RlTW9ubzEgb3Igc3BsYXNoTW9kZVJHQjgKICAgICAgICByZXR1cm4gc3BsYXNoRXJyR2VuZXJpYzsKICAgICAgfQogICAgfQogICAgYnJlYWs7CiAgICAKICAgIGRlZmF1bHQ6CiAgICAvLyBjYW4ndCBoYXBwZW4KICAgIGJyZWFrOwogIH0KICAKICBpZiAoIXdyaXRlci0+Y2xvc2UoKSkgewogICAgcmV0dXJuIHNwbGFzaEVyckdlbmVyaWM7CiAgfQoKICByZXR1cm4gc3BsYXNoT2s7Cn0K