LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBDb3B5cmlnaHQgKEMpIDIwMTUtMjAxNyBieSBTYXZvaXItZmFpcmUgTGludXggICAgICAgICAgICAgICAgICAgICAgICAgICAqCiAqIEF1dGhvcjogRWRyaWMgTGFkZW50IE1pbGFyZXQgPGVkcmljLmxhZGVudC1taWxhcmV0QHNhdm9pcmZhaXJlbGludXguY29tPioKICogQXV0aG9yOiBBbmRyZWFzIFRyYWN6eWsgPGFuZHJlYXMudHJhY3p5a0BzYXZvaXJmYWlyZWxpbnV4LmNvbT4gICAgICAgICAgKgogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5ICAgICoKICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgICAgKgogKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvciAgICAgICAqCiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKgogKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgICAgICAgICAqCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mICAgICAgICAgICoKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSAgICAgICAgICAgKgogKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAqCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgICAgICAgKgogKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbS4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi4gICAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiNpbmNsdWRlICJjb252ZXJzYXRpb25pdGVtZGVsZWdhdGUuaCIKCiNpbmNsdWRlIDxRQXBwbGljYXRpb24+CiNpbmNsdWRlIDxRUGFpbnRlcj4KI2luY2x1ZGUgPFFQaXhtYXA+CgovLyBDbGllbnQKI2luY2x1ZGUgInNtYXJ0bGlzdG1vZGVsLmgiCiNpbmNsdWRlICJyaW5ndGhlbWV1dGlscy5oIgojaW5jbHVkZSAidXRpbHMuaCIKI2luY2x1ZGUgImxyY2luc3RhbmNlLmgiCiNpbmNsdWRlICJtYWlud2luZG93LmgiCgojaW5jbHVkZSA8Y2lzbzY0Nj4KCkNvbnZlcnNhdGlvbkl0ZW1EZWxlZ2F0ZTo6Q29udmVyc2F0aW9uSXRlbURlbGVnYXRlKFFPYmplY3QqIHBhcmVudCkKICAgIDogUUl0ZW1EZWxlZ2F0ZShwYXJlbnQpCnsKfQoKdm9pZApDb252ZXJzYXRpb25JdGVtRGVsZWdhdGU6OnBhaW50KFFQYWludGVyKiBwYWludGVyCiAgICAgICAgICAgICAgICAgICAgICAgICwgY29uc3QgUVN0eWxlT3B0aW9uVmlld0l0ZW0mIG9wdGlvbgogICAgICAgICAgICAgICAgICAgICAgICAsIGNvbnN0IFFNb2RlbEluZGV4JiBpbmRleAogICAgICAgICAgICAgICAgICAgICAgICApIGNvbnN0CnsKICAgIFFTdHlsZU9wdGlvblZpZXdJdGVtIG9wdChvcHRpb24pOwogICAgcGFpbnRlci0+c2V0UmVuZGVySGludChRUGFpbnRlcjo6QW50aWFsaWFzaW5nLCB0cnVlKTsKCiAgICAvLyBOb3QgaGF2aW5nIGZvY3VzIHJlbW92ZXMgZG90dGVkIGxpbmVzIGFyb3VuZCB0aGUgaXRlbQogICAgaWYgKG9wdC5zdGF0ZSAmIFFTdHlsZTo6U3RhdGVfSGFzRm9jdXMpCiAgICAgICAgb3B0LnN0YXRlIF49IFFTdHlsZTo6U3RhdGVfSGFzRm9jdXM7CgogICAgYXV0byBpc0NvbnRleHRNZW51T3BlbiA9IGluZGV4LmRhdGEoc3RhdGljX2Nhc3Q8aW50PihTbWFydExpc3RNb2RlbDo6Um9sZTo6Q29udGV4dE1lbnVPcGVuKSkudmFsdWU8Ym9vbD4oKTsKICAgIGJvb2wgc2VsZWN0ZWQgPSBmYWxzZTsKICAgIGlmIChvcHRpb24uc3RhdGUgJiBRU3R5bGU6OlN0YXRlX1NlbGVjdGVkKSB7CiAgICAgICAgc2VsZWN0ZWQgPSB0cnVlOwogICAgICAgIG9wdC5zdGF0ZSBePSBRU3R5bGU6OlN0YXRlX1NlbGVjdGVkOwogICAgfSBlbHNlIGlmICghaXNDb250ZXh0TWVudU9wZW4pIHsKICAgICAgICBoaWdobGlnaHRNYXBfW2luZGV4LnJvdygpXSA9IG9wdGlvbi5zdGF0ZSAmIFFTdHlsZTo6U3RhdGVfTW91c2VPdmVyOwogICAgfQoKICAgIC8vIE9uZSBkb2VzIG5vdCBzaW1wbHkga2VlcCB0aGUgaGlnaGxpZ2h0ZWQgc3RhdGUgZHJhd24gd2hlbiB0aGUgY29udGV4dAogICAgLy8gbWVudSBpcyBvcGVuhQogICAgYXV0byByb3dIaWdobGlnaHQgPSBoaWdobGlnaHRNYXBfLmZpbmQoaW5kZXgucm93KCkpOwogICAgaWYgKHNlbGVjdGVkKSB7CiAgICAgICBwYWludGVyLT5maWxsUmVjdChvcHRpb24ucmVjdCwgUmluZ1RoZW1lOjpzbWFydGxpc3RTZWxlY3Rpb25fKTsKICAgIH0gZWxzZSBpZiAocm93SGlnaGxpZ2h0ICE9IGhpZ2hsaWdodE1hcF8uZW5kKCkgJiYgKCpyb3dIaWdobGlnaHQpLnNlY29uZCkgewogICAgICAgcGFpbnRlci0+ZmlsbFJlY3Qob3B0aW9uLnJlY3QsIFJpbmdUaGVtZTo6c21hcnRsaXN0SGlnaGxpZ2h0Xyk7CiAgICB9CiAgICBhdXRvIGNvbnZVaWQgPSBpbmRleC5kYXRhKHN0YXRpY19jYXN0PGludD4oU21hcnRMaXN0TW9kZWw6OlJvbGU6OlVJRCkpLnZhbHVlPFFTdHJpbmc+KCkudG9TdGRTdHJpbmcoKTsKICAgIGF1dG8gY29udmVyc2F0aW9uID0gVXRpbHM6OmdldENvbnZlcnNhdGlvbkZyb21VaWQoY29udlVpZCwgKkxSQ0luc3RhbmNlOjpnZXRDdXJyZW50Q29udmVyc2F0aW9uTW9kZWwoKSk7CiAgICBpZiAoTFJDSW5zdGFuY2U6OmdldEN1cnJlbnRDYWxsTW9kZWwoKS0+aGFzQ2FsbChjb252ZXJzYXRpb24tPmNhbGxJZCkpIHsKICAgICAgICBhdXRvIGNvbG9yID0gUUNvbG9yKFJpbmdUaGVtZTo6Ymx1ZV8ubGlnaHRlcigxODApKTsgY29sb3Iuc2V0QWxwaGEoMTI4KTsKICAgICAgICBwYWludGVyLT5maWxsUmVjdChvcHRpb24ucmVjdCwgY29sb3IpOwogICAgfQoKICAgIFFSZWN0ICZyZWN0ID0gb3B0LnJlY3Q7CgogICAgLy8gQXZhdGFyIGRyYXdpbmcKICAgIG9wdC5kZWNvcmF0aW9uU2l6ZSA9IFFTaXplKHNpemVJbWFnZV8sIHNpemVJbWFnZV8pOwogICAgb3B0LmRlY29yYXRpb25Qb3NpdGlvbiA9IFFTdHlsZU9wdGlvblZpZXdJdGVtOjpMZWZ0OwogICAgb3B0LmRlY29yYXRpb25BbGlnbm1lbnQgPSBRdDo6QWxpZ25DZW50ZXI7CgogICAgUVJlY3QgcmVjdEF2YXRhcihkeF8gKyByZWN0LmxlZnQoKSwgcmVjdC50b3AoKSArIGR5Xywgc2l6ZUltYWdlXywgc2l6ZUltYWdlXyk7CiAgICBkcmF3RGVjb3JhdGlvbihwYWludGVyLCBvcHQsIHJlY3RBdmF0YXIsCiAgICAgICAgICAgICAgICAgICBRUGl4bWFwOjpmcm9tSW1hZ2UoaW5kZXguZGF0YShRdDo6RGVjb3JhdGlvblJvbGUpLnZhbHVlPFFJbWFnZT4oKSkKICAgICAgICAgICAgICAgICAgIC5zY2FsZWQoc2l6ZUltYWdlXywgc2l6ZUltYWdlXywgUXQ6OktlZXBBc3BlY3RSYXRpbywgUXQ6OlNtb290aFRyYW5zZm9ybWF0aW9uKSk7CgogICAgUUZvbnQgZm9udChwYWludGVyLT5mb250KCkpOwoKICAgIC8vIElmIHRoZXJlJ3MgdW5yZWFkIG1lc3NhZ2VzLCBhIG1lc3NhZ2UgY291bnQgaXMgZGlzcGxheWVkCiAgICBpZiAoYXV0byBtZXNzYWdlQ291bnQgPSBpbmRleC5kYXRhKHN0YXRpY19jYXN0PGludD4oU21hcnRMaXN0TW9kZWw6OlJvbGU6OlVucmVhZE1lc3NhZ2VzQ291bnQpKS50b0ludCgpKSB7CiAgICAgICAgUVN0cmluZyBtZXNzYWdlQ291bnRUZXh0ID0gKG1lc3NhZ2VDb3VudCA+IDkpID8gIjkrIiA6IFFTdHJpbmc6Om51bWJlcihtZXNzYWdlQ291bnQpOwogICAgICAgIHFyZWFsIGZvbnRTaXplID0gbWVzc2FnZUNvdW50VGV4dC5jb3VudCgpID4gMSA/IDcgOiA4OwogICAgICAgIGZvbnQuc2V0UG9pbnRTaXplKGZvbnRTaXplKTsKCiAgICAgICAgLy8gZWxsaXBzZQogICAgICAgIFFQYWludGVyUGF0aCBlbGxpcHNlOwogICAgICAgIHFyZWFsIGVsbGlwc2VIZWlnaHQgPSBzaXplSW1hZ2VfIC8gNjsKICAgICAgICBxcmVhbCBlbGxpcHNlV2lkdGggPSBlbGxpcHNlSGVpZ2h0OwogICAgICAgIFFQb2ludEYgZWxsaXBzZUNlbnRlcihyZWN0QXZhdGFyLnJpZ2h0KCkgLSBlbGxpcHNlV2lkdGgsIHJlY3RBdmF0YXIudG9wKCkgKyBlbGxpcHNlSGVpZ2h0ICsgMSk7CiAgICAgICAgUVJlY3QgZWxsaXBzZVJlY3QoZWxsaXBzZUNlbnRlci54KCkgLSBlbGxpcHNlV2lkdGgsIGVsbGlwc2VDZW50ZXIueSgpIC0gZWxsaXBzZUhlaWdodCwKICAgICAgICAgICAgZWxsaXBzZVdpZHRoICogMiwgZWxsaXBzZUhlaWdodCAqIDIpOwogICAgICAgIGVsbGlwc2UuYWRkUm91bmRlZFJlY3QoZWxsaXBzZVJlY3QsIGVsbGlwc2VXaWR0aCwgZWxsaXBzZUhlaWdodCk7CiAgICAgICAgcGFpbnRlci0+ZmlsbFBhdGgoZWxsaXBzZSwgUmluZ1RoZW1lOjpub3RpZmljYXRpb25SZWRfKTsKCiAgICAgICAgLy8gdGV4dAogICAgICAgIHBhaW50ZXItPnNldFBlbihRdDo6d2hpdGUpOwogICAgICAgIHBhaW50ZXItPnNldE9wYWNpdHkoMSk7CiAgICAgICAgcGFpbnRlci0+c2V0Rm9udChmb250KTsKICAgICAgICBlbGxpcHNlUmVjdC5zZXRUb3AoZWxsaXBzZVJlY3QudG9wKCkgLSAyKTsKICAgICAgICBwYWludGVyLT5kcmF3VGV4dChlbGxpcHNlUmVjdCwgUXQ6OkFsaWduQ2VudGVyLCBtZXNzYWdlQ291bnRUZXh0KTsKICAgIH0KCiAgICAvLyBQcmVzZW5jZSBpbmRpY2F0b3IKICAgIGlmIChpbmRleC5kYXRhKHN0YXRpY19jYXN0PGludD4oU21hcnRMaXN0TW9kZWw6OlJvbGU6OlByZXNlbmNlKSkudmFsdWU8Ym9vbD4oKSkgewogICAgICAgIHFyZWFsIHJhZGl1cyA9IHNpemVJbWFnZV8gLyA2OwogICAgICAgIFFQYWludGVyUGF0aCBvdXRlckNpcmNsZSwgaW5uZXJDaXJjbGU7CiAgICAgICAgUVBvaW50RiBjZW50ZXIocmVjdEF2YXRhci5yaWdodCgpIC0gcmFkaXVzLCAocmVjdEF2YXRhci5ib3R0b20oKSAtIHJhZGl1cykgKyAxKTsKICAgICAgICBxcmVhbCBvdXRlckNSYWRpdXMgPSByYWRpdXM7CiAgICAgICAgcXJlYWwgaW5uZXJDUmFkaXVzID0gb3V0ZXJDUmFkaXVzICogMC43NTsKICAgICAgICBvdXRlckNpcmNsZS5hZGRFbGxpcHNlKGNlbnRlciwgb3V0ZXJDUmFkaXVzLCBvdXRlckNSYWRpdXMpOwogICAgICAgIGlubmVyQ2lyY2xlLmFkZEVsbGlwc2UoY2VudGVyLCBpbm5lckNSYWRpdXMsIGlubmVyQ1JhZGl1cyk7CiAgICAgICAgcGFpbnRlci0+ZmlsbFBhdGgob3V0ZXJDaXJjbGUsIFF0Ojp3aGl0ZSk7CiAgICAgICAgcGFpbnRlci0+ZmlsbFBhdGgoaW5uZXJDaXJjbGUsIFJpbmdUaGVtZTo6cHJlc2VuY2VHcmVlbl8pOwogICAgfQoKICAgIHVzaW5nIG5hbWVzcGFjZSBscmM6OmFwaTsKICAgIGF1dG8gdHlwZSA9IFV0aWxzOjp0b0VudW08cHJvZmlsZTo6VHlwZT4oCiAgICAgICAgICAgIGluZGV4LmRhdGEoc3RhdGljX2Nhc3Q8aW50PihTbWFydExpc3RNb2RlbDo6Um9sZTo6Q29udGFjdFR5cGUpKS52YWx1ZTxpbnQ+KCkKICAgICAgICApOwogICAgc3dpdGNoICh0eXBlKSB7CiAgICBjYXNlIHByb2ZpbGU6OlR5cGU6OlJJTkc6CiAgICBjYXNlIHByb2ZpbGU6OlR5cGU6OlRFTVBPUkFSWToKICAgICAgICBwYWludFJpbmdDb252ZXJzYXRpb25JdGVtKHBhaW50ZXIsIG9wdGlvbiwgcmVjdCwgaW5kZXgpOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBwcm9maWxlOjpUeXBlOjpQRU5ESU5HOgogICAgICAgIHBhaW50UmluZ0ludml0ZUNvbnZlcnNhdGlvbkl0ZW0ocGFpbnRlciwgb3B0aW9uLCByZWN0LCBpbmRleCk7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIHByb2ZpbGU6OlR5cGU6OlNJUDoKICAgICAgICBicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgICAgcGFpbnRSaW5nQ29udmVyc2F0aW9uSXRlbShwYWludGVyLCBvcHRpb24sIHJlY3QsIGluZGV4KTsKICAgICAgICBicmVhazsKICAgIH0KfQoKUVNpemUKQ29udmVyc2F0aW9uSXRlbURlbGVnYXRlOjpzaXplSGludChjb25zdCBRU3R5bGVPcHRpb25WaWV3SXRlbSYgb3B0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFFNb2RlbEluZGV4JiBpbmRleCkgY29uc3QKewogICAgUV9VTlVTRUQob3B0aW9uKTsKICAgIFFfVU5VU0VEKGluZGV4KTsKICAgIHJldHVybiBRU2l6ZSgwLCBjZWxsSGVpZ2h0Xyk7Cn0KCnZvaWQKQ29udmVyc2F0aW9uSXRlbURlbGVnYXRlOjpwYWludFJpbmdDb252ZXJzYXRpb25JdGVtKFFQYWludGVyKiBwYWludGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUVN0eWxlT3B0aW9uVmlld0l0ZW0mIG9wdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFFSZWN0JiByZWN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUU1vZGVsSW5kZXgmIGluZGV4KSBjb25zdAp7CiAgICBRX1VOVVNFRChvcHRpb24pOwogICAgUUZvbnQgZm9udChwYWludGVyLT5mb250KCkpOwogICAgUVBlbiBwZW4ocGFpbnRlci0+cGVuKCkpOwogICAgcGFpbnRlci0+c2V0UGVuKHBlbik7CgogICAgaW50IGluZm9UZXh0V2lkdGhNb2RpZmllciA9IDA7CiAgICBpbnQgaW5mb1RleHQySGVpZ2h0TW9kaWZpZXIgPSAwOwogICAgYXV0byBzY2FsaW5nUmF0aW8gPSBNYWluV2luZG93OjppbnN0YW5jZSgpLmdldEN1cnJlbnRTY2FsaW5nUmF0aW8oKTsKICAgIGlmIChzY2FsaW5nUmF0aW8gPiAxLjApIHsKICAgICAgICBmb250LnNldFBvaW50U2l6ZShmb250U2l6ZV8gLSAyKTsKICAgICAgICBpbmZvVGV4dFdpZHRoTW9kaWZpZXIgPSAxMjsKICAgICAgICBpbmZvVGV4dDJIZWlnaHRNb2RpZmllciA9IDI7CiAgICB9IGVsc2UgewogICAgICAgIGZvbnQuc2V0UG9pbnRTaXplKGZvbnRTaXplXyk7CiAgICB9CgogICAgYXV0byBsZWZ0TWFyZ2luID0gZHhfICsgc2l6ZUltYWdlXyArIGR4XzsKICAgIGF1dG8gcmlnaHRNYXJnaW4gPSBkeF87CiAgICBhdXRvIHRvcE1hcmdpbiA9IDQ7CiAgICBhdXRvIGJvdHRvbU1hcmdpbiA9IDg7CgogICAgUVJlY3QgcmVjdE5hbWUxKHJlY3QubGVmdCgpICsgbGVmdE1hcmdpbiwKICAgICAgICAgICAgICAgICAgICByZWN0LnRvcCgpICsgdG9wTWFyZ2luLAogICAgICAgICAgICAgICAgICAgIHJlY3Qud2lkdGgoKSAtIGxlZnRNYXJnaW4gLSBpbmZvVGV4dFdpZHRoXyAtIGluZm9UZXh0V2lkdGhNb2RpZmllciwKICAgICAgICAgICAgICAgICAgICByZWN0LmhlaWdodCgpIC8gMiAtIDIpOwoKICAgIFFSZWN0IHJlY3ROYW1lMihyZWN0TmFtZTEubGVmdCgpLAogICAgICAgICAgICAgICAgICAgIHJlY3ROYW1lMS50b3AoKSArIHJlY3ROYW1lMS5oZWlnaHQoKSwKICAgICAgICAgICAgICAgICAgICByZWN0TmFtZTEud2lkdGgoKSwKICAgICAgICAgICAgICAgICAgICByZWN0TmFtZTEuaGVpZ2h0KCkgLSBib3R0b21NYXJnaW4pOwoKICAgIFFSZWN0IHJlY3RJbmZvMShyZWN0TmFtZTEubGVmdCgpICsgcmVjdE5hbWUxLndpZHRoKCksCiAgICAgICAgICAgICAgICAgICAgcmVjdC50b3AoKSArIHRvcE1hcmdpbiwKICAgICAgICAgICAgICAgICAgICBpbmZvVGV4dFdpZHRoXyAtIHJpZ2h0TWFyZ2luICsgaW5mb1RleHRXaWR0aE1vZGlmaWVyLAogICAgICAgICAgICAgICAgICAgIHJlY3QuaGVpZ2h0KCkgLyAyIC0gMik7CgogICAgUVJlY3QgcmVjdEluZm8yKHJlY3RJbmZvMS5sZWZ0KCksCiAgICAgICAgICAgICAgICAgICAgcmVjdEluZm8xLnRvcCgpICsgcmVjdEluZm8xLmhlaWdodCgpIC0gaW5mb1RleHQySGVpZ2h0TW9kaWZpZXIsCiAgICAgICAgICAgICAgICAgICAgcmVjdEluZm8xLndpZHRoKCksCiAgICAgICAgICAgICAgICAgICAgcmVjdEluZm8xLmhlaWdodCgpIC0gYm90dG9tTWFyZ2luICsgaW5mb1RleHQySGVpZ2h0TW9kaWZpZXIpOwoKICAgIFFGb250TWV0cmljcyBmb250TWV0cmljcyhmb250KTsKCiAgICAvLyBUaGUgbmFtZSBpcyBkaXNwbGF5ZWQgYXQgdGhlIGF2YXRhcidzIHJpZ2h0CiAgICBRU3RyaW5nIG5hbWVTdHIgPSBpbmRleC5kYXRhKHN0YXRpY19jYXN0PGludD4oU21hcnRMaXN0TW9kZWw6OlJvbGU6OkRpc3BsYXlOYW1lKSkudmFsdWU8UVN0cmluZz4oKTsKICAgIGlmICghbmFtZVN0ci5pc051bGwoKSkgewogICAgICAgIGZvbnQuc2V0SXRhbGljKGZhbHNlKTsKICAgICAgICBmb250LnNldEJvbGQoZmFsc2UpOwogICAgICAgIHBlbi5zZXRDb2xvcihSaW5nVGhlbWU6OmxpZ2h0QmxhY2tfKTsKICAgICAgICBwYWludGVyLT5zZXRQZW4ocGVuKTsKICAgICAgICBwYWludGVyLT5zZXRGb250KGZvbnQpOwogICAgICAgIFFTdHJpbmcgZWxpZGVkTmFtZVN0ciA9IGZvbnRNZXRyaWNzLmVsaWRlZFRleHQobmFtZVN0ciwgUXQ6OkVsaWRlUmlnaHQsIHJlY3ROYW1lMS53aWR0aCgpKTsKICAgICAgICBwYWludGVyLT5kcmF3VGV4dChyZWN0TmFtZTEsIFF0OjpBbGlnblZDZW50ZXIgfCBRdDo6QWxpZ25MZWZ0LCBlbGlkZWROYW1lU3RyKTsKICAgIH0KCiAgICAvLyBEaXNwbGF5IHRoZSBJRCB1bmRlciB0aGUgbmFtZQogICAgUVN0cmluZyBpZFN0ciA9IGluZGV4LmRhdGEoc3RhdGljX2Nhc3Q8aW50PihTbWFydExpc3RNb2RlbDo6Um9sZTo6RGlzcGxheUlEKSkudmFsdWU8UVN0cmluZz4oKTsKICAgIGlmIChpZFN0ciAhPSBuYW1lU3RyICYmICFpZFN0ci5pc051bGwoKSkgewogICAgICAgIGZvbnQuc2V0SXRhbGljKGZhbHNlKTsKICAgICAgICBmb250LnNldEJvbGQoZmFsc2UpOwogICAgICAgIHBlbi5zZXRDb2xvcihSaW5nVGhlbWU6OmdyZXlfKTsKICAgICAgICBwYWludGVyLT5zZXRQZW4ocGVuKTsKICAgICAgICBwYWludGVyLT5zZXRGb250KGZvbnQpOwogICAgICAgIGlkU3RyID0gZm9udE1ldHJpY3MuZWxpZGVkVGV4dChpZFN0ciwgUXQ6OkVsaWRlUmlnaHQsIHJlY3ROYW1lMi53aWR0aCgpKTsKICAgICAgICBwYWludGVyLT5kcmF3VGV4dChyZWN0TmFtZTIsIFF0OjpBbGlnblZDZW50ZXIgfCBRdDo6QWxpZ25MZWZ0LCBpZFN0cik7CiAgICB9CgogICAgLy8gdG9wLXJpZ2h0OiBsYXN0IGludGVyYWN0aW9uIGRhdGUvdGltZQogICAgUVN0cmluZyBsYXN0VXNlZFN0ciA9IGluZGV4LmRhdGEoc3RhdGljX2Nhc3Q8aW50PihTbWFydExpc3RNb2RlbDo6Um9sZTo6TGFzdEludGVyYWN0aW9uRGF0ZSkpLnZhbHVlPFFTdHJpbmc+KCk7CiAgICBpZiAoIWxhc3RVc2VkU3RyLmlzTnVsbCgpKSB7CiAgICAgICAgZm9udC5zZXRJdGFsaWMoZmFsc2UpOwogICAgICAgIGZvbnQuc2V0Qm9sZChmYWxzZSk7CiAgICAgICAgcGVuLnNldENvbG9yKFJpbmdUaGVtZTo6Z3JleV8pOwogICAgICAgIHBhaW50ZXItPnNldFBlbihwZW4pOwogICAgICAgIHBhaW50ZXItPnNldEZvbnQoZm9udCk7CiAgICAgICAgbGFzdFVzZWRTdHIgPSBmb250TWV0cmljcy5lbGlkZWRUZXh0KGxhc3RVc2VkU3RyLCBRdDo6RWxpZGVSaWdodCwgcmVjdEluZm8xLndpZHRoKCkpOwogICAgICAgIHBhaW50ZXItPmRyYXdUZXh0KHJlY3RJbmZvMSwgUXQ6OkFsaWduVkNlbnRlciB8IFF0OjpBbGlnblJpZ2h0LCBsYXN0VXNlZFN0cik7CiAgICB9CgogICAgLy8gYm90dG9tLXJpZ2h0OiBsYXN0IGludGVyYWN0aW9uIHNuaXBwZXQKICAgIFFTdHJpbmcgaW50ZXJhY3Rpb25TdHIgPSBpbmRleC5kYXRhKHN0YXRpY19jYXN0PGludD4oU21hcnRMaXN0TW9kZWw6OlJvbGU6Okxhc3RJbnRlcmFjdGlvbikpLnZhbHVlPFFTdHJpbmc+KCk7CiAgICBpZiAoIWludGVyYWN0aW9uU3RyLmlzTnVsbCgpKSB7CiAgICAgICAgcGFpbnRlci0+c2F2ZSgpOwogICAgICAgIGZvbnQuc2V0V2VpZ2h0KFFGb250OjpFeHRyYUxpZ2h0KTsKICAgICAgICBpbnRlcmFjdGlvblN0ciA9IGludGVyYWN0aW9uU3RyLnNpbXBsaWZpZWQoKTsKICAgICAgICBhdXRvIHR5cGUgPSBVdGlsczo6dG9FbnVtPGxyYzo6YXBpOjppbnRlcmFjdGlvbjo6VHlwZT4oaW5kZXgKICAgICAgICAgICAgLmRhdGEoc3RhdGljX2Nhc3Q8aW50PihTbWFydExpc3RNb2RlbDo6Um9sZTo6TGFzdEludGVyYWN0aW9uVHlwZSkpCiAgICAgICAgICAgIC52YWx1ZTxpbnQ+KCkpOwogICAgICAgIGlmICh0eXBlID09IGxyYzo6YXBpOjppbnRlcmFjdGlvbjo6VHlwZTo6Q0FMTCB8fAogICAgICAgICAgICB0eXBlID09IGxyYzo6YXBpOjppbnRlcmFjdGlvbjo6VHlwZTo6Q09OVEFDVCkgewogICAgICAgICAgICBmb250LnNldEl0YWxpYyhmYWxzZSk7CiAgICAgICAgICAgIGZvbnQuc2V0Qm9sZChmYWxzZSk7CiAgICAgICAgICAgIHBlbi5zZXRDb2xvcihSaW5nVGhlbWU6OmdyZXlfLmRhcmtlcigxNDApKTsKICAgICAgICAgICAgcGFpbnRlci0+c2V0UGVuKHBlbik7CiAgICAgICAgICAgIHBhaW50ZXItPnNldEZvbnQoZm9udCk7CiAgICAgICAgICAgIC8vIHN0cmlwIGVtb2ppcyBpZiBpdCdzIGEgY2FsbC9jb250YWN0IHR5cGUgbWVzc2FnZQogICAgICAgICAgICBWZWN0b3JVSW50IGVtb2ppbGVzczsKICAgICAgICAgICAgZm9yIChhdXRvIHVuaWNvZGUgOiBpbnRlcmFjdGlvblN0ci50b1VjczQoKSkgewogICAgICAgICAgICAgICAgaWYgKCEodW5pY29kZSA+PSAweDFGMDAwICYmIHVuaWNvZGUgPD0gMHgxRkZGRikpIHsKICAgICAgICAgICAgICAgICAgICBlbW9qaWxlc3MucHVzaF9iYWNrKHVuaWNvZGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGludGVyYWN0aW9uU3RyID0gUVN0cmluZzo6ZnJvbVVjczQoJmVtb2ppbGVzcy5hdCgwKSwgZW1vamlsZXNzLnNpemUoKSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgUUZvbnQgZW1vamlNc2dGb250KFFTdHJpbmdMaXRlcmFsKCJTZWdvZSBVSSBFbW9qaSIpKTsKICAgICAgICAgICAgZW1vamlNc2dGb250LnNldEl0YWxpYyhmYWxzZSk7CiAgICAgICAgICAgIGVtb2ppTXNnRm9udC5zZXRCb2xkKGZhbHNlKTsKICAgICAgICAgICAgZW1vamlNc2dGb250LnNldFBvaW50U2l6ZShzY2FsaW5nUmF0aW8gPiAxLjAgPyBmb250U2l6ZV8gLSAyIDogZm9udFNpemVfKTsKICAgICAgICAgICAgcGFpbnRlci0+c2V0T3BhY2l0eSgwLjcpOwogICAgICAgICAgICBwYWludGVyLT5zZXRGb250KGVtb2ppTXNnRm9udCk7CiAgICAgICAgfQogICAgICAgIGludGVyYWN0aW9uU3RyID0gZm9udE1ldHJpY3MuZWxpZGVkVGV4dChpbnRlcmFjdGlvblN0ciwgUXQ6OkVsaWRlUmlnaHQsIHJlY3RJbmZvMi53aWR0aCgpKTsKICAgICAgICBwYWludGVyLT5kcmF3VGV4dChyZWN0SW5mbzIsIFF0OjpBbGlnblZDZW50ZXIgfCBRdDo6QWxpZ25SaWdodCwgaW50ZXJhY3Rpb25TdHIpOwogICAgICAgIHBhaW50ZXItPnJlc3RvcmUoKTsKICAgIH0KfQoKdm9pZApDb252ZXJzYXRpb25JdGVtRGVsZWdhdGU6OnBhaW50UmluZ0ludml0ZUNvbnZlcnNhdGlvbkl0ZW0oUVBhaW50ZXIqIHBhaW50ZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBRU3R5bGVPcHRpb25WaWV3SXRlbSYgb3B0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUVJlY3QmIHJlY3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBRTW9kZWxJbmRleCYgaW5kZXgpIGNvbnN0CnsKICAgIFFGb250IGZvbnQocGFpbnRlci0+Zm9udCgpKTsKICAgIGZvbnQuc2V0UG9pbnRTaXplKGZvbnRTaXplXyk7CiAgICBRUGVuIHBlbihwYWludGVyLT5wZW4oKSk7CiAgICBwYWludGVyLT5zZXRQZW4ocGVuKTsKCiAgICBhdXRvIGxlZnRNYXJnaW4gPSBkeF8gKyBzaXplSW1hZ2VfICsgZHhfOwogICAgYXV0byByaWdodE1hcmdpbiA9IGR4XzsKICAgIGlmIChvcHRpb24uc3RhdGUgJiBRU3R5bGU6OlN0YXRlX01vdXNlT3ZlcikgewogICAgICAgIHJpZ2h0TWFyZ2luID0gaW5mb1RleHRXaWR0aF8gLSBkeF8gKiAyOwogICAgfQogICAgYXV0byB0b3BNYXJnaW4gPSA0OwogICAgYXV0byBib3R0b21NYXJnaW4gPSA4OwoKICAgIFFSZWN0IHJlY3ROYW1lMShyZWN0LmxlZnQoKSArIGxlZnRNYXJnaW4sCiAgICAgICAgcmVjdC50b3AoKSArIHRvcE1hcmdpbiwKICAgICAgICByZWN0LndpZHRoKCkgLSBsZWZ0TWFyZ2luIC0gcmlnaHRNYXJnaW4sCiAgICAgICAgcmVjdC5oZWlnaHQoKSAvIDIgLSAyKTsKCiAgICBRUmVjdCByZWN0TmFtZTIocmVjdE5hbWUxLmxlZnQoKSwKICAgICAgICByZWN0TmFtZTEudG9wKCkgKyByZWN0TmFtZTEuaGVpZ2h0KCksCiAgICAgICAgcmVjdE5hbWUxLndpZHRoKCksCiAgICAgICAgcmVjdE5hbWUxLmhlaWdodCgpIC0gYm90dG9tTWFyZ2luKTsKCiAgICBRRm9udE1ldHJpY3MgZm9udE1ldHJpY3MoZm9udCk7CgogICAgLy8gVGhlIG5hbWUgaXMgZGlzcGxheWVkIGF0IHRoZSBhdmF0YXIncyByaWdodAogICAgUVN0cmluZyBuYW1lU3RyID0gaW5kZXguZGF0YShzdGF0aWNfY2FzdDxpbnQ+KFNtYXJ0TGlzdE1vZGVsOjpSb2xlOjpEaXNwbGF5TmFtZSkpLnZhbHVlPFFTdHJpbmc+KCk7CiAgICBpZiAoIW5hbWVTdHIuaXNOdWxsKCkpIHsKICAgICAgICBmb250LnNldEl0YWxpYyhmYWxzZSk7CiAgICAgICAgZm9udC5zZXRCb2xkKGZhbHNlKTsKICAgICAgICBwZW4uc2V0Q29sb3IoUmluZ1RoZW1lOjpsaWdodEJsYWNrXyk7CiAgICAgICAgcGFpbnRlci0+c2V0UGVuKHBlbik7CiAgICAgICAgcGFpbnRlci0+c2V0Rm9udChmb250KTsKICAgICAgICBRU3RyaW5nIGVsaWRlZE5hbWVTdHIgPSBmb250TWV0cmljcy5lbGlkZWRUZXh0KG5hbWVTdHIsIFF0OjpFbGlkZVJpZ2h0LCByZWN0TmFtZTEud2lkdGgoKSk7CiAgICAgICAgcGFpbnRlci0+ZHJhd1RleHQocmVjdE5hbWUxLCBRdDo6QWxpZ25WQ2VudGVyIHwgUXQ6OkFsaWduTGVmdCwgZWxpZGVkTmFtZVN0cik7CiAgICB9CgogICAgLy8gRGlzcGxheSB0aGUgSUQgdW5kZXIgdGhlIG5hbWUKICAgIFFTdHJpbmcgaWRTdHIgPSBpbmRleC5kYXRhKHN0YXRpY19jYXN0PGludD4oU21hcnRMaXN0TW9kZWw6OlJvbGU6OkRpc3BsYXlJRCkpLnZhbHVlPFFTdHJpbmc+KCk7CiAgICBpZiAoaWRTdHIgIT0gbmFtZVN0ciAmJiAhaWRTdHIuaXNOdWxsKCkpIHsKICAgICAgICBmb250LnNldEl0YWxpYyhmYWxzZSk7CiAgICAgICAgZm9udC5zZXRCb2xkKGZhbHNlKTsKICAgICAgICBwZW4uc2V0Q29sb3IoUmluZ1RoZW1lOjpncmV5Xyk7CiAgICAgICAgcGFpbnRlci0+c2V0UGVuKHBlbik7CiAgICAgICAgcGFpbnRlci0+c2V0Rm9udChmb250KTsKICAgICAgICBpZFN0ciA9IGZvbnRNZXRyaWNzLmVsaWRlZFRleHQoaWRTdHIsIFF0OjpFbGlkZVJpZ2h0LCByZWN0TmFtZTIud2lkdGgoKSk7CiAgICAgICAgcGFpbnRlci0+ZHJhd1RleHQocmVjdE5hbWUyLCBRdDo6QWxpZ25WQ2VudGVyIHwgUXQ6OkFsaWduTGVmdCwgaWRTdHIpOwogICAgfQp9Cgp2b2lkCkNvbnZlcnNhdGlvbkl0ZW1EZWxlZ2F0ZTo6cGFpbnRTSVBDb252ZXJzYXRpb25JdGVtKFFQYWludGVyKiBwYWludGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBRU3R5bGVPcHRpb25WaWV3SXRlbSYgb3B0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBRTW9kZWxJbmRleCYgaW5kZXgpIGNvbnN0CnsKICAgIFFfVU5VU0VEKHBhaW50ZXIpOwogICAgUV9VTlVTRUQob3B0aW9uKTsKICAgIFFfVU5VU0VEKGluZGV4KTsKfQo=