LyoKICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKLy8gVGhpcyBmaWxlIGlzIGF2YWlsYWJsZSB1bmRlciBhbmQgZ292ZXJuZWQgYnkgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwovLyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KLy8gSG93ZXZlciwgdGhlIGZvbGxvd2luZyBub3RpY2UgYWNjb21wYW5pZWQgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhpcwovLyBmaWxlOgovLwovLwovLyAgTGl0dGxlIGNtcwovLyAgQ29weXJpZ2h0IChDKSAxOTk4LTIwMDcgTWFydGkgTWFyaWEKLy8KLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nCi8vIGEgY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSAiU29mdHdhcmUiKSwKLy8gdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbgovLyB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwKLy8gYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlCi8vIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6Ci8vCi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluCi8vIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLgovLwovLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwKLy8gRVhQUkVTUyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPCi8vIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5ECi8vIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUKLy8gTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTgovLyBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04KLy8gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuCgoKI2luY2x1ZGUgImxjbXMuaCIKCgovLyBWaXJ0dWFsIChidWlsdC1pbikgcHJvZmlsZXMKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCgovLyBUaGlzIGZ1bmN0aW9uIGNyZWF0ZXMgYSBwcm9maWxlIGJhc2VkIG9uIFdoaXRlIHBvaW50LCBwcmltYXJpZXMgYW5kCi8vIHRyYW5zZmVyIGZ1bmN0aW9ucy4KCgpjbXNIUFJPRklMRSBMQ01TRVhQT1JUIGNtc0NyZWF0ZVJHQlByb2ZpbGUoTFBjbXNDSUV4eVkgV2hpdGVQb2ludCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUGNtc0NJRXh5WVRSSVBMRSBQcmltYXJpZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBHQU1NQVRBQkxFIFRyYW5zZmVyRnVuY3Rpb25bM10pCnsKICAgICAgIGNtc0hQUk9GSUxFIGhJQ0M7CiAgICAgICBjbXNDSUVYWVogdG1wOwogICAgICAgTUFUMyBNQ29sb3JhbnRzOwogICAgICAgY21zQ0lFWFlaVFJJUExFIENvbG9yYW50czsKICAgICAgIGNtc0NJRXh5WSBNYXhXaGl0ZTsKCgogICAgICAgaElDQyA9IF9jbXNDcmVhdGVQcm9maWxlUGxhY2Vob2xkZXIoKTsKICAgICAgIGlmICghaElDQykgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNhbid0IGFsbG9jYXRlCiAgICAgICAgICAgIHJldHVybiBOVUxMOwoKCiAgICAgICBjbXNTZXREZXZpY2VDbGFzcyhoSUNDLCAgICAgIGljU2lnRGlzcGxheUNsYXNzKTsKICAgICAgIGNtc1NldENvbG9yU3BhY2UoaElDQywgICAgICAgaWNTaWdSZ2JEYXRhKTsKICAgICAgIGNtc1NldFBDUyhoSUNDLCAgICAgICAgICAgICAgaWNTaWdYWVpEYXRhKTsKICAgICAgIGNtc1NldFJlbmRlcmluZ0ludGVudChoSUNDLCAgSU5URU5UX1BFUkNFUFRVQUwpOwoKCiAgICAgICAvLyBJbXBsZW1lbnQgcHJvZmlsZSB1c2luZyBmb2xsb3dpbmcgdGFnczoKICAgICAgIC8vCiAgICAgICAvLyAgMSBpY1NpZ1Byb2ZpbGVEZXNjcmlwdGlvblRhZwogICAgICAgLy8gIDIgaWNTaWdNZWRpYVdoaXRlUG9pbnRUYWcKICAgICAgIC8vICAzIGljU2lnUmVkQ29sb3JhbnRUYWcKICAgICAgIC8vICA0IGljU2lnR3JlZW5Db2xvcmFudFRhZwogICAgICAgLy8gIDUgaWNTaWdCbHVlQ29sb3JhbnRUYWcKICAgICAgIC8vICA2IGljU2lnUmVkVFJDVGFnCiAgICAgICAvLyAgNyBpY1NpZ0dyZWVuVFJDVGFnCiAgICAgICAvLyAgOCBpY1NpZ0JsdWVUUkNUYWcKCiAgICAgICAvLyBUaGlzIGNvbmZvcm1zIGEgc3RhbmRhcmQgUkdCIERpc3BsYXlQcm9maWxlIGFzIHNheXMgSUNDLCBhbmQgdGhlbiBJIGFkZAoKICAgICAgIC8vIDkgaWNTaWdDaHJvbWF0aWNpdHlUYWcKCiAgICAgICAvLyBBcyBhZGRlbmR1bSBJSQoKCiAgICAgICAvLyBGaWxsLWluIHRoZSB0YWdzCgogICAgICAgY21zQWRkVGFnKGhJQ0MsIGljU2lnRGV2aWNlTWZnRGVzY1RhZywgICAgICAgKExQVk9JRCkgIihsY21zIGludGVybmFsKSIpOwogICAgICAgY21zQWRkVGFnKGhJQ0MsIGljU2lnUHJvZmlsZURlc2NyaXB0aW9uVGFnLCAgKExQVk9JRCkgImxjbXMgUkdCIHZpcnR1YWwgcHJvZmlsZSIpOwogICAgICAgY21zQWRkVGFnKGhJQ0MsIGljU2lnRGV2aWNlTW9kZWxEZXNjVGFnLCAgICAgKExQVk9JRCkgInJnYiBidWlsdC1pbiIpOwoKCiAgICAgICBpZiAoV2hpdGVQb2ludCkgewoKICAgICAgIGNtc3h5WTJYWVooJnRtcCwgV2hpdGVQb2ludCk7CiAgICAgICBjbXNBZGRUYWcoaElDQywgaWNTaWdNZWRpYVdoaXRlUG9pbnRUYWcsIChMUFZPSUQpICZ0bXApOwogICAgICAgfQoKICAgICAgIGlmIChXaGl0ZVBvaW50ICYmIFByaW1hcmllcykgewoKICAgICAgICBNYXhXaGl0ZS54ID0gIFdoaXRlUG9pbnQgLT4geDsKICAgICAgICBNYXhXaGl0ZS55ID0gIFdoaXRlUG9pbnQgLT4geTsKICAgICAgICBNYXhXaGl0ZS5ZID0gIDEuMDsKCiAgICAgICBpZiAoIWNtc0J1aWxkUkdCMlhZWnRyYW5zZmVyTWF0cml4KCZNQ29sb3JhbnRzLCAmTWF4V2hpdGUsIFByaW1hcmllcykpCiAgICAgICB7CiAgICAgICAgICAgICAgY21zQ2xvc2VQcm9maWxlKGhJQ0MpOwogICAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgfQoKICAgICAgIGNtc0FkYXB0TWF0cml4VG9ENTAoJk1Db2xvcmFudHMsICZNYXhXaGl0ZSk7CgogICAgICAgQ29sb3JhbnRzLlJlZC5YID0gTUNvbG9yYW50cy52WzBdLm5bMF07CiAgICAgICBDb2xvcmFudHMuUmVkLlkgPSBNQ29sb3JhbnRzLnZbMV0ublswXTsKICAgICAgIENvbG9yYW50cy5SZWQuWiA9IE1Db2xvcmFudHMudlsyXS5uWzBdOwoKICAgICAgIENvbG9yYW50cy5HcmVlbi5YID0gTUNvbG9yYW50cy52WzBdLm5bMV07CiAgICAgICBDb2xvcmFudHMuR3JlZW4uWSA9IE1Db2xvcmFudHMudlsxXS5uWzFdOwogICAgICAgQ29sb3JhbnRzLkdyZWVuLlogPSBNQ29sb3JhbnRzLnZbMl0ublsxXTsKCiAgICAgICBDb2xvcmFudHMuQmx1ZS5YID0gTUNvbG9yYW50cy52WzBdLm5bMl07CiAgICAgICBDb2xvcmFudHMuQmx1ZS5ZID0gTUNvbG9yYW50cy52WzFdLm5bMl07CiAgICAgICBDb2xvcmFudHMuQmx1ZS5aID0gTUNvbG9yYW50cy52WzJdLm5bMl07CgogICAgICAgY21zQWRkVGFnKGhJQ0MsIGljU2lnUmVkQ29sb3JhbnRUYWcsICAgKExQVk9JRCkgJkNvbG9yYW50cy5SZWQpOwogICAgICAgY21zQWRkVGFnKGhJQ0MsIGljU2lnQmx1ZUNvbG9yYW50VGFnLCAgKExQVk9JRCkgJkNvbG9yYW50cy5CbHVlKTsKICAgICAgIGNtc0FkZFRhZyhoSUNDLCBpY1NpZ0dyZWVuQ29sb3JhbnRUYWcsIChMUFZPSUQpICZDb2xvcmFudHMuR3JlZW4pOwogICAgICAgfQoKCiAgICAgICBpZiAoVHJhbnNmZXJGdW5jdGlvbikgewoKICAgICAgIC8vIEluIGNhc2Ugb2YgZ2FtbWEsIHdlIG11c3QgZHVwJyB0aGUgdGFibGUgcG9pbnRlcgoKICAgICAgICBjbXNBZGRUYWcoaElDQywgaWNTaWdSZWRUUkNUYWcsICAgKExQVk9JRCkgVHJhbnNmZXJGdW5jdGlvblswXSk7CiAgICAgICAgY21zQWRkVGFnKGhJQ0MsIGljU2lnR3JlZW5UUkNUYWcsIChMUFZPSUQpIFRyYW5zZmVyRnVuY3Rpb25bMV0pOwogICAgICAgIGNtc0FkZFRhZyhoSUNDLCBpY1NpZ0JsdWVUUkNUYWcsICAoTFBWT0lEKSBUcmFuc2ZlckZ1bmN0aW9uWzJdKTsKICAgICAgIH0KCiAgICAgICBpZiAoUHJpbWFyaWVzKSB7CiAgICAgICAgICAgIGNtc0FkZFRhZyhoSUNDLCBpY1NpZ0Nocm9tYXRpY2l0eVRhZywgKExQVk9JRCkgUHJpbWFyaWVzKTsKICAgICAgIH0KCiAgICAgICByZXR1cm4gaElDQzsKfQoKCgovLyBUaGlzIGZ1bmN0aW9uIGNyZWF0ZXMgYSBwcm9maWxlIGJhc2VkIG9uIFdoaXRlIHBvaW50IGFuZCB0cmFuc2ZlciBmdW5jdGlvbi4KCmNtc0hQUk9GSUxFICAgTENNU0VYUE9SVCBjbXNDcmVhdGVHcmF5UHJvZmlsZShMUGNtc0NJRXh5WSBXaGl0ZVBvaW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBHQU1NQVRBQkxFIFRyYW5zZmVyRnVuY3Rpb24pCnsKICAgICAgIGNtc0hQUk9GSUxFIGhJQ0M7CiAgICAgICBjbXNDSUVYWVogdG1wOwoKCiAgICAgICBoSUNDID0gX2Ntc0NyZWF0ZVByb2ZpbGVQbGFjZWhvbGRlcigpOwogICAgICAgaWYgKCFoSUNDKSAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY2FuJ3QgYWxsb2NhdGUKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CgoKICAgICAgIGNtc1NldERldmljZUNsYXNzKGhJQ0MsICAgICAgaWNTaWdEaXNwbGF5Q2xhc3MpOwogICAgICAgY21zU2V0Q29sb3JTcGFjZShoSUNDLCAgICAgICBpY1NpZ0dyYXlEYXRhKTsKICAgICAgIGNtc1NldFBDUyhoSUNDLCAgICAgICAgICAgICAgaWNTaWdYWVpEYXRhKTsKICAgICAgIGNtc1NldFJlbmRlcmluZ0ludGVudChoSUNDLCAgSU5URU5UX1BFUkNFUFRVQUwpOwoKCgogICAgICAgLy8gSW1wbGVtZW50IHByb2ZpbGUgdXNpbmcgZm9sbG93aW5nIHRhZ3M6CiAgICAgICAvLwogICAgICAgLy8gIDEgaWNTaWdQcm9maWxlRGVzY3JpcHRpb25UYWcKICAgICAgIC8vICAyIGljU2lnTWVkaWFXaGl0ZVBvaW50VGFnCiAgICAgICAvLyAgNiBpY1NpZ0dyYXlUUkNUYWcKCiAgICAgICAvLyBUaGlzIGNvbmZvcm1zIGEgc3RhbmRhcmQgR3JheSBEaXNwbGF5UHJvZmlsZQoKICAgICAgIC8vIEZpbGwtaW4gdGhlIHRhZ3MKCgogICAgICAgY21zQWRkVGFnKGhJQ0MsIGljU2lnRGV2aWNlTWZnRGVzY1RhZywgICAgICAgKExQVk9JRCkgIihsY21zIGludGVybmFsKSIpOwogICAgICAgY21zQWRkVGFnKGhJQ0MsIGljU2lnUHJvZmlsZURlc2NyaXB0aW9uVGFnLCAgKExQVk9JRCkgImxjbXMgZ3JheSB2aXJ0dWFsIHByb2ZpbGUiKTsKICAgICAgIGNtc0FkZFRhZyhoSUNDLCBpY1NpZ0RldmljZU1vZGVsRGVzY1RhZywgICAgIChMUFZPSUQpICJncmF5IGJ1aWx0LWluIik7CgoKICAgICAgIGlmIChXaGl0ZVBvaW50KSB7CgogICAgICAgY21zeHlZMlhZWigmdG1wLCBXaGl0ZVBvaW50KTsKICAgICAgIGNtc0FkZFRhZyhoSUNDLCBpY1NpZ01lZGlhV2hpdGVQb2ludFRhZywgKExQVk9JRCkgJnRtcCk7CiAgICAgICB9CgoKICAgICAgIGlmIChUcmFuc2ZlckZ1bmN0aW9uKSB7CgogICAgICAgLy8gSW4gY2FzZSBvZiBnYW1tYSwgd2UgbXVzdCBkdXAnIHRoZSB0YWJsZSBwb2ludGVyCgogICAgICAgY21zQWRkVGFnKGhJQ0MsIGljU2lnR3JheVRSQ1RhZywgKExQVk9JRCkgVHJhbnNmZXJGdW5jdGlvbik7CiAgICAgICB9CgogICAgICAgcmV0dXJuIGhJQ0M7Cgp9CgoKc3RhdGljCmludCBJc1BDUyhpY0NvbG9yU3BhY2VTaWduYXR1cmUgQ29sb3JTcGFjZSkKewogICAgcmV0dXJuIChDb2xvclNwYWNlID09IGljU2lnWFlaRGF0YSB8fAogICAgICAgICAgICBDb2xvclNwYWNlID09IGljU2lnTGFiRGF0YSk7Cn0KCnN0YXRpYwp2b2lkIEZpeENvbG9yU3BhY2VzKGNtc0hQUk9GSUxFIGhQcm9maWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpY0NvbG9yU3BhY2VTaWduYXR1cmUgQ29sb3JTcGFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWNDb2xvclNwYWNlU2lnbmF0dXJlIFBDUywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZHdGbGFncykKewoKICAgIGlmIChkd0ZsYWdzICYgY21zRkxBR1NfR1VFU1NERVZJQ0VDTEFTUykgewoKICAgICAgICAgICAgaWYgKElzUENTKENvbG9yU3BhY2UpICYmIElzUENTKFBDUykpIHsKCiAgICAgICAgICAgICAgICAgICAgY21zU2V0RGV2aWNlQ2xhc3MoaFByb2ZpbGUsICAgICAgaWNTaWdBYnN0cmFjdENsYXNzKTsKICAgICAgICAgICAgICAgICAgICBjbXNTZXRDb2xvclNwYWNlKGhQcm9maWxlLCAgICAgICBDb2xvclNwYWNlKTsKICAgICAgICAgICAgICAgICAgICBjbXNTZXRQQ1MoaFByb2ZpbGUsICAgICAgICAgICAgICBQQ1MpOwogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKElzUENTKENvbG9yU3BhY2UpICYmICFJc1BDUyhQQ1MpKSB7CgogICAgICAgICAgICAgICAgICAgIGNtc1NldERldmljZUNsYXNzKGhQcm9maWxlLCBpY1NpZ091dHB1dENsYXNzKTsKICAgICAgICAgICAgICAgICAgICBjbXNTZXRQQ1MoaFByb2ZpbGUsICAgICAgICAgQ29sb3JTcGFjZSk7CiAgICAgICAgICAgICAgICAgICAgY21zU2V0Q29sb3JTcGFjZShoUHJvZmlsZSwgIFBDUyk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoSXNQQ1MoUENTKSAmJiAhSXNQQ1MoQ29sb3JTcGFjZSkpIHsKCiAgICAgICAgICAgICAgICAgICBjbXNTZXREZXZpY2VDbGFzcyhoUHJvZmlsZSwgIGljU2lnSW5wdXRDbGFzcyk7CiAgICAgICAgICAgICAgICAgICBjbXNTZXRDb2xvclNwYWNlKGhQcm9maWxlLCAgIENvbG9yU3BhY2UpOwogICAgICAgICAgICAgICAgICAgY21zU2V0UENTKGhQcm9maWxlLCAgICAgICAgICBQQ1MpOwogICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICB9CgogICAgY21zU2V0RGV2aWNlQ2xhc3MoaFByb2ZpbGUsICAgICAgaWNTaWdMaW5rQ2xhc3MpOwogICAgY21zU2V0Q29sb3JTcGFjZShoUHJvZmlsZSwgICAgICAgQ29sb3JTcGFjZSk7CiAgICBjbXNTZXRQQ1MoaFByb2ZpbGUsICAgICAgICAgICAgICBQQ1MpOwoKfQoKCnN0YXRpYwpjbXNIUFJPRklMRSBDcmVhdGVOYW1lZENvbG9yRGV2aWNlbGluayhjbXNIVFJBTlNGT1JNIHhmb3JtKQp7CiAgICBfTFBjbXNUUkFOU0ZPUk0gdiA9IChfTFBjbXNUUkFOU0ZPUk0pIHhmb3JtOwogICAgY21zSFBST0ZJTEUgaElDQzsKICAgIGNtc0NJRVhZWiBXaGl0ZVBvaW50OwogICAgaW50IGksIG5Db2xvcnM7CiAgICBzaXplX3QgU2l6ZTsKICAgIExQY21zTkFNRURDT0xPUkxJU1QgbmMyOwoKCiAgICBoSUNDID0gX2Ntc0NyZWF0ZVByb2ZpbGVQbGFjZWhvbGRlcigpOwogICAgaWYgKGhJQ0MgPT0gTlVMTCkgcmV0dXJuIE5VTEw7CgogICAgY21zU2V0UmVuZGVyaW5nSW50ZW50KGhJQ0MsIHYgLT4gSW50ZW50KTsKICAgIGNtc1NldERldmljZUNsYXNzKGhJQ0MsIGljU2lnTmFtZWRDb2xvckNsYXNzKTsKICAgIGNtc1NldENvbG9yU3BhY2UoaElDQywgdiAtPkV4aXRDb2xvclNwYWNlKTsKICAgIGNtc1NldFBDUyhoSUNDLCBjbXNHZXRQQ1ModiAtPklucHV0UHJvZmlsZSkpOwogICAgY21zVGFrZU1lZGlhV2hpdGVQb2ludCgmV2hpdGVQb2ludCwgdiAtPklucHV0UHJvZmlsZSk7CgogICAgY21zQWRkVGFnKGhJQ0MsIGljU2lnTWVkaWFXaGl0ZVBvaW50VGFnLCAgJldoaXRlUG9pbnQpOwogICAgY21zQWRkVGFnKGhJQ0MsIGljU2lnRGV2aWNlTWZnRGVzY1RhZywgICAgICAgKExQVk9JRCkgIkxpdHRsZUNNUyIpOwogICAgY21zQWRkVGFnKGhJQ0MsIGljU2lnUHJvZmlsZURlc2NyaXB0aW9uVGFnLCAgKExQVk9JRCkgIk5hbWVkIGNvbG9yIERldmljZSBsaW5rIik7CiAgICBjbXNBZGRUYWcoaElDQywgaWNTaWdEZXZpY2VNb2RlbERlc2NUYWcsICAgICAoTFBWT0lEKSAiTmFtZWQgY29sb3IgRGV2aWNlIGxpbmsiKTsKCgogICAgbkNvbG9ycyA9IGNtc05hbWVkQ29sb3JDb3VudCh4Zm9ybSk7CiAgICBuYzIgICAgID0gY21zQWxsb2NOYW1lZENvbG9yTGlzdChuQ29sb3JzKTsKCiAgICBTaXplID0gc2l6ZW9mKGNtc05BTUVEQ09MT1JMSVNUKSArIChzaXplb2YoY21zTkFNRURDT0xPUikgKiAobkNvbG9ycy0xKSk7CgogICAgQ29weU1lbW9yeShuYzIsIHYtPk5hbWVkQ29sb3JMaXN0LCBTaXplKTsKICAgIG5jMiAtPkNvbG9yYW50Q291bnQgPSBfY21zQ2hhbm5lbHNPZih2IC0+RXhpdENvbG9yU3BhY2UpOwoKICAgIGZvciAoaT0wOyBpIDwgbkNvbG9yczsgaSsrKSB7CiAgICAgICAgY21zRG9UcmFuc2Zvcm0oeGZvcm0sICZpLCBuYzIgLT5MaXN0W2ldLkRldmljZUNvbG9yYW50LCAxKTsKICAgIH0KCiAgICBjbXNBZGRUYWcoaElDQywgaWNTaWdOYW1lZENvbG9yMlRhZywgKHZvaWQqKSBuYzIpOwogICAgY21zRnJlZU5hbWVkQ29sb3JMaXN0KG5jMik7CgogICAgcmV0dXJuIGhJQ0M7Cn0KCgovLyBEb2VzIGNvbnZlcnQgYSB0cmFuc2Zvcm0gaW50byBhIGRldmljZSBsaW5rIHByb2ZpbGUKCmNtc0hQUk9GSUxFIExDTVNFWFBPUlQgY21zVHJhbnNmb3JtMkRldmljZUxpbmsoY21zSFRSQU5TRk9STSBoVHJhbnNmb3JtLCBEV09SRCBkd0ZsYWdzKQp7CiAgICBjbXNIUFJPRklMRSBoSUNDOwogICAgX0xQY21zVFJBTlNGT1JNIHYgPSAoX0xQY21zVFJBTlNGT1JNKSBoVHJhbnNmb3JtOwogICAgTFBMVVQgTHV0OwogICAgTENNU0JPT0wgTXVzdEZyZWVMVVQ7CiAgICBMUGNtc05BTUVEQ09MT1JMSVNUIElucHV0Q29sb3JhbnQgPSBOVUxMOwogICAgTFBjbXNOQU1FRENPTE9STElTVCBPdXRwdXRDb2xvcmFudCA9IE5VTEw7CgoKICAgIC8vIENoZWNrIGlmIGlzIGEgbmFtZWQgY29sb3IgdHJhbnNmb3JtCgogICAgaWYgKGNtc0dldERldmljZUNsYXNzKHYgLT5JbnB1dFByb2ZpbGUpID09IGljU2lnTmFtZWRDb2xvckNsYXNzKSB7CgogICAgICAgIHJldHVybiBDcmVhdGVOYW1lZENvbG9yRGV2aWNlbGluayhoVHJhbnNmb3JtKTsKCiAgICB9CgogICAgaWYgKHYgLT5EZXZpY2VMaW5rKSB7CgogICAgICAgIEx1dCA9IHYgLT4gRGV2aWNlTGluazsKICAgICAgICBNdXN0RnJlZUxVVCA9IEZBTFNFOwogICAgfQogICAgZWxzZSB7CgogICAgICAgIEx1dCA9IF9jbXNQcmVjYWxjdWxhdGVEZXZpY2VMaW5rKGhUcmFuc2Zvcm0sIGR3RmxhZ3MpOwogICAgICAgIGlmICghTHV0KSByZXR1cm4gTlVMTDsKICAgICAgICBNdXN0RnJlZUxVVCA9IFRSVUU7CiAgICB9CgogICAgaElDQyA9IF9jbXNDcmVhdGVQcm9maWxlUGxhY2Vob2xkZXIoKTsKICAgIGlmICghaElDQykgeyAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY2FuJ3QgYWxsb2NhdGUKCiAgICAgICAgaWYgKE11c3RGcmVlTFVUKSBjbXNGcmVlTFVUKEx1dCk7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgoKICAgIEZpeENvbG9yU3BhY2VzKGhJQ0MsIHYgLT4gRW50cnlDb2xvclNwYWNlLCB2IC0+IEV4aXRDb2xvclNwYWNlLCBkd0ZsYWdzKTsKCiAgICBjbXNTZXRSZW5kZXJpbmdJbnRlbnQoaElDQywgIHYgLT4gSW50ZW50KTsKCiAgICAvLyBJbXBsZW1lbnQgZGV2aWNlbGluayBwcm9maWxlIHVzaW5nIGZvbGxvd2luZyB0YWdzOgogICAgLy8KICAgIC8vICAxIGljU2lnUHJvZmlsZURlc2NyaXB0aW9uVGFnCiAgICAvLyAgMiBpY1NpZ01lZGlhV2hpdGVQb2ludFRhZwogICAgLy8gIDMgaWNTaWdBVG9CMFRhZwoKCiAgICBjbXNBZGRUYWcoaElDQywgaWNTaWdEZXZpY2VNZmdEZXNjVGFnLCAgICAgICAoTFBWT0lEKSAiTGl0dGxlQ01TIik7CiAgICBjbXNBZGRUYWcoaElDQywgaWNTaWdQcm9maWxlRGVzY3JpcHRpb25UYWcsICAoTFBWT0lEKSAiRGV2aWNlIGxpbmsiKTsKICAgIGNtc0FkZFRhZyhoSUNDLCBpY1NpZ0RldmljZU1vZGVsRGVzY1RhZywgICAgIChMUFZPSUQpICJEZXZpY2UgbGluayIpOwoKCiAgICBjbXNBZGRUYWcoaElDQywgaWNTaWdNZWRpYVdoaXRlUG9pbnRUYWcsICAoTFBWT0lEKSBjbXNENTBfWFlaKCkpOwoKICAgIGlmIChjbXNHZXREZXZpY2VDbGFzcyhoSUNDKSA9PSBpY1NpZ091dHB1dENsYXNzKSB7CgogICAgICAgIGNtc0FkZFRhZyhoSUNDLCBpY1NpZ0JUb0EwVGFnLCAoTFBWT0lEKSBMdXQpOwogICAgfQogICAgZWxzZQogICAgICAgIGNtc0FkZFRhZyhoSUNDLCBpY1NpZ0FUb0IwVGFnLCAoTFBWT0lEKSBMdXQpOwoKCgogICAgLy8gVHJ5IHRvIHJlYWQgaW5wdXQgYW5kIG91dHB1dCBjb2xvcmFudCB0YWJsZQogICAgaWYgKGNtc0lzVGFnKHYgLT5JbnB1dFByb2ZpbGUsIGljU2lnQ29sb3JhbnRUYWJsZVRhZykpIHsKCiAgICAgICAgLy8gSW5wdXQgdGFibGUgY2FuIG9ubHkgY29tZSBpbiB0aGlzIHdheS4KICAgICAgICBJbnB1dENvbG9yYW50ID0gY21zUmVhZENvbG9yYW50VGFibGUodiAtPklucHV0UHJvZmlsZSwgaWNTaWdDb2xvcmFudFRhYmxlVGFnKTsKICAgIH0KCiAgICAvLyBPdXRwdXQgaXMgYSBsaXR0bGUgYml0IG1vcmUgY29tcGxleC4KICAgIGlmIChjbXNHZXREZXZpY2VDbGFzcyh2IC0+T3V0cHV0UHJvZmlsZSkgPT0gaWNTaWdMaW5rQ2xhc3MpIHsKCiAgICAgICAgLy8gVGhpcyB0YWcgbWF5IGV4aXN0IG9ubHkgb24gZGV2aWNlbGluayBwcm9maWxlcy4KICAgICAgICBpZiAoY21zSXNUYWcodiAtPk91dHB1dFByb2ZpbGUsIGljU2lnQ29sb3JhbnRUYWJsZU91dFRhZykpIHsKCiAgICAgICAgICAgIE91dHB1dENvbG9yYW50ID0gY21zUmVhZENvbG9yYW50VGFibGUodiAtPk91dHB1dFByb2ZpbGUsIGljU2lnQ29sb3JhbnRUYWJsZU91dFRhZyk7CiAgICAgICAgfQoKICAgIH0gZWxzZSB7CgogICAgICAgIGlmIChjbXNJc1RhZyh2IC0+T3V0cHV0UHJvZmlsZSwgaWNTaWdDb2xvcmFudFRhYmxlVGFnKSkgewoKICAgICAgICAgICAgT3V0cHV0Q29sb3JhbnQgPSBjbXNSZWFkQ29sb3JhbnRUYWJsZSh2IC0+T3V0cHV0UHJvZmlsZSwgaWNTaWdDb2xvcmFudFRhYmxlVGFnKTsKICAgICAgICB9CiAgICB9CgogICAgaWYgKElucHV0Q29sb3JhbnQpCiAgICAgICAgICAgY21zQWRkVGFnKGhJQ0MsIGljU2lnQ29sb3JhbnRUYWJsZVRhZywgSW5wdXRDb2xvcmFudCk7CgogICAgaWYgKE91dHB1dENvbG9yYW50KQogICAgICAgICAgIGNtc0FkZFRhZyhoSUNDLCBpY1NpZ0NvbG9yYW50VGFibGVPdXRUYWcsIE91dHB1dENvbG9yYW50KTsKCgoKICAgIGlmIChNdXN0RnJlZUxVVCkgY21zRnJlZUxVVChMdXQpOwogICAgaWYgKElucHV0Q29sb3JhbnQpIGNtc0ZyZWVOYW1lZENvbG9yTGlzdChJbnB1dENvbG9yYW50KTsKICAgIGlmIChPdXRwdXRDb2xvcmFudCkgY21zRnJlZU5hbWVkQ29sb3JMaXN0KE91dHB1dENvbG9yYW50KTsKCiAgICByZXR1cm4gaElDQzsKCn0KCgovLyBUaGlzIGlzIGEgZGV2aWNlbGluayBvcGVyYXRpbmcgaW4gdGhlIHRhcmdldCBjb2xvcnNwYWNlIHdpdGggYXMgbWFueSB0cmFuc2ZlcgovLyBmdW5jdGlvbnMgYXMgY29tcG9uZW50cwoKY21zSFBST0ZJTEUgTENNU0VYUE9SVCBjbXNDcmVhdGVMaW5lYXJpemF0aW9uRGV2aWNlTGluayhpY0NvbG9yU3BhY2VTaWduYXR1cmUgQ29sb3JTcGFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUEdBTU1BVEFCTEUgVHJhbnNmZXJGdW5jdGlvbnNbXSkKewogICAgICAgY21zSFBST0ZJTEUgaElDQzsKICAgICAgIExQTFVUIEx1dDsKCgogICAgICAgaElDQyA9IF9jbXNDcmVhdGVQcm9maWxlUGxhY2Vob2xkZXIoKTsKICAgICAgIGlmICghaElDQykgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNhbid0IGFsbG9jYXRlCiAgICAgICAgICAgIHJldHVybiBOVUxMOwoKCiAgICAgICBjbXNTZXREZXZpY2VDbGFzcyhoSUNDLCAgICAgIGljU2lnTGlua0NsYXNzKTsKICAgICAgIGNtc1NldENvbG9yU3BhY2UoaElDQywgICAgICAgQ29sb3JTcGFjZSk7CiAgICAgICBjbXNTZXRQQ1MoaElDQywgICAgICAgICAgICAgIENvbG9yU3BhY2UpOwogICAgICAgY21zU2V0UmVuZGVyaW5nSW50ZW50KGhJQ0MsICBJTlRFTlRfUEVSQ0VQVFVBTCk7CgoKICAgICAgIC8vIENyZWF0ZXMgYSBMVVQgd2l0aCBwcmVsaW5lYXJpemF0aW9uIHN0ZXAgb25seQogICAgICAgTHV0ID0gY21zQWxsb2NMVVQoKTsKICAgICAgIGlmIChMdXQgPT0gTlVMTCkgcmV0dXJuIE5VTEw7CgogICAgICAgLy8gU2V0IHVwIGNoYW5uZWxzCiAgICAgICBMdXQgLT5JbnB1dENoYW4gPSBMdXQgLT5PdXRwdXRDaGFuID0gX2Ntc0NoYW5uZWxzT2YoQ29sb3JTcGFjZSk7CgogICAgICAgLy8gQ29weSB0YWJsZXMgdG8gTFVUCiAgICAgICBjbXNBbGxvY0xpbmVhclRhYmxlKEx1dCwgVHJhbnNmZXJGdW5jdGlvbnMsIDEpOwoKICAgICAgIC8vIENyZWF0ZSB0YWdzCiAgICAgICBjbXNBZGRUYWcoaElDQywgaWNTaWdEZXZpY2VNZmdEZXNjVGFnLCAgICAgICAoTFBWT0lEKSAiKGxjbXMgaW50ZXJuYWwpIik7CiAgICAgICBjbXNBZGRUYWcoaElDQywgaWNTaWdQcm9maWxlRGVzY3JpcHRpb25UYWcsICAoTFBWT0lEKSAibGNtcyBsaW5lYXJpemF0aW9uIGRldmljZSBsaW5rIik7CiAgICAgICBjbXNBZGRUYWcoaElDQywgaWNTaWdEZXZpY2VNb2RlbERlc2NUYWcsICAgICAoTFBWT0lEKSAibGluZWFyaXphdGlvbiBidWlsdC1pbiIpOwoKICAgICAgIGNtc0FkZFRhZyhoSUNDLCBpY1NpZ01lZGlhV2hpdGVQb2ludFRhZywgKExQVk9JRCkgY21zRDUwX1hZWigpKTsKICAgICAgIGNtc0FkZFRhZyhoSUNDLCBpY1NpZ0FUb0IwVGFnLCAoTFBWT0lEKSBMdXQpOwoKICAgICAgIC8vIExVVCBpcyBhbHJlYWR5IG9uIHZpcnR1YWwgcHJvZmlsZQogICAgICAgY21zRnJlZUxVVChMdXQpOwoKICAgICAgIC8vIE9rLCBkb25lCiAgICAgICByZXR1cm4gaElDQzsKfQoKCi8vIEluay1saW1pdGluZyBhbGdvcml0aG0KLy8KLy8gIFN1bSA9IEMgKyBNICsgWSArIEsKLy8gIElmIFN1bSA+IElua0xpbWl0Ci8vICAgICAgICBSYXRpbz0gMSAtIChTdW0gLSBJbmtMaW1pdCkgLyAoQyArIE0gKyBZKQovLyAgICAgICAgaWYgUmF0aW8gPDAKLy8gICAgICAgICAgICAgIFJhdGlvPTAKLy8gICAgICAgIGVuZGlmCi8vICAgICBFbHNlCi8vICAgICAgICAgUmF0aW89MQovLyAgICAgZW5kaWYKLy8KLy8gICAgIEMgPSBSYXRpbyAqIEMKLy8gICAgIE0gPSBSYXRpbyAqIE0KLy8gICAgIFkgPSBSYXRpbyAqIFkKLy8gICAgIEs6IERvZXMgbm90IGNoYW5nZQoKc3RhdGljCmludCBJbmtMaW1pdGluZ1NhbXBsZXIocmVnaXN0ZXIgV09SRCBJbltdLCByZWdpc3RlciBXT1JEIE91dFtdLCByZWdpc3RlciBMUFZPSUQgQ2FyZ28pCnsKICAgICAgICBkb3VibGUgSW5rTGltaXQgPSAqKGRvdWJsZSAqKSBDYXJnbzsKICAgICAgICBkb3VibGUgU3VtQ01ZLCBTdW1DTVlLLCBSYXRpbzsKCiAgICAgICAgSW5rTGltaXQgPSAoSW5rTGltaXQgKiA2NTUuMzUpOwoKICAgICAgICBTdW1DTVkgICA9IEluWzBdICArIEluWzFdICsgSW5bMl07CiAgICAgICAgU3VtQ01ZSyAgPSBTdW1DTVkgKyBJblszXTsKCiAgICAgICAgaWYgKFN1bUNNWUsgPiBJbmtMaW1pdCkgewoKICAgICAgICAgICAgICAgIFJhdGlvID0gMSAtICgoU3VtQ01ZSyAtIElua0xpbWl0KSAvIFN1bUNNWSk7CiAgICAgICAgICAgICAgICBpZiAoUmF0aW8gPCAwKQogICAgICAgICAgICAgICAgICAgICAgICBSYXRpbyA9IDA7CiAgICAgICAgfQogICAgICAgIGVsc2UgUmF0aW8gPSAxOwoKICAgICAgICBPdXRbMF0gPSAoV09SRCkgZmxvb3IoSW5bMF0gKiBSYXRpbyArIDAuNSk7ICAgICAvLyBDCiAgICAgICAgT3V0WzFdID0gKFdPUkQpIGZsb29yKEluWzFdICogUmF0aW8gKyAwLjUpOyAgICAgLy8gTQogICAgICAgIE91dFsyXSA9IChXT1JEKSBmbG9vcihJblsyXSAqIFJhdGlvICsgMC41KTsgICAgIC8vIFkKCiAgICAgICAgT3V0WzNdID0gSW5bM107ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSyAodW50b3VjaGVkKQoKICAgICAgICByZXR1cm4gVFJVRTsKfQoKLy8gVGhpcyBpcyBhIGRldmljZWxpbmsgb3BlcmF0aW5nIGluIENNWUsgZm9yIGluay1saW1pdGluZwoKY21zSFBST0ZJTEUgTENNU0VYUE9SVCBjbXNDcmVhdGVJbmtMaW1pdGluZ0RldmljZUxpbmsoaWNDb2xvclNwYWNlU2lnbmF0dXJlIENvbG9yU3BhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG91YmxlIExpbWl0KQp7CiAgICAgICBjbXNIUFJPRklMRSBoSUNDOwogICAgICAgTFBMVVQgTHV0OwoKICAgICAgIGlmIChDb2xvclNwYWNlICE9IGljU2lnQ215a0RhdGEpIHsKICAgICAgICAgICAgY21zU2lnbmFsRXJyb3IoTENNU19FUlJDX0FCT1JURUQsICJJbmtMaW1pdGluZzogT25seSBDTVlLIGN1cnJlbnRseSBzdXBwb3J0ZWQiKTsKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICB9CgogICAgICAgaWYgKExpbWl0IDwgMC4wIHx8IExpbWl0ID4gNDAwKSB7CgogICAgICAgICAgIGNtc1NpZ25hbEVycm9yKExDTVNfRVJSQ19XQVJOSU5HLCAiSW5rTGltaXRpbmc6IExpbWl0IHNob3VsZCBiZSBiZXR3ZWVuIDAuLjQwMCIpOwogICAgICAgICAgIGlmIChMaW1pdCA8IDApIExpbWl0ID0gMDsKICAgICAgICAgICBpZiAoTGltaXQgPiA0MDApIExpbWl0ID0gNDAwOwoKICAgICAgIH0KCiAgICAgIGhJQ0MgPSBfY21zQ3JlYXRlUHJvZmlsZVBsYWNlaG9sZGVyKCk7CiAgICAgICBpZiAoIWhJQ0MpICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjYW4ndCBhbGxvY2F0ZQogICAgICAgICAgICByZXR1cm4gTlVMTDsKCgogICAgICAgY21zU2V0RGV2aWNlQ2xhc3MoaElDQywgICAgICBpY1NpZ0xpbmtDbGFzcyk7CiAgICAgICBjbXNTZXRDb2xvclNwYWNlKGhJQ0MsICAgICAgIENvbG9yU3BhY2UpOwogICAgICAgY21zU2V0UENTKGhJQ0MsICAgICAgICAgICAgICBDb2xvclNwYWNlKTsKICAgICAgIGNtc1NldFJlbmRlcmluZ0ludGVudChoSUNDLCAgSU5URU5UX1BFUkNFUFRVQUwpOwoKCiAgICAgICAvLyBDcmVhdGVzIGEgTFVUIHdpdGggM0QgZ3JpZCBvbmx5CiAgICAgICBMdXQgPSBjbXNBbGxvY0xVVCgpOwogICAgICAgaWYgKEx1dCA9PSBOVUxMKSB7CiAgICAgICAgICAgY21zQ2xvc2VQcm9maWxlKGhJQ0MpOwogICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgICAgIH0KCgogICAgICAgY21zQWxsb2MzREdyaWQoTHV0LCAxNywgX2Ntc0NoYW5uZWxzT2YoQ29sb3JTcGFjZSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfY21zQ2hhbm5lbHNPZihDb2xvclNwYWNlKSk7CgogICAgICAgaWYgKCFjbXNTYW1wbGUzREdyaWQoTHV0LCBJbmtMaW1pdGluZ1NhbXBsZXIsIChMUFZPSUQpICZMaW1pdCwgMCkpIHsKCiAgICAgICAgICAgICAgICAvLyBTaG91bGRuJ3QgcmVhY2ggaGVyZQogICAgICAgICAgICAgICAgY21zRnJlZUxVVChMdXQpOwogICAgICAgICAgICAgICAgY21zQ2xvc2VQcm9maWxlKGhJQ0MpOwogICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICB9CgogICAgICAgLy8gQ3JlYXRlIHRhZ3MKCiAgICAgICBjbXNBZGRUYWcoaElDQywgaWNTaWdEZXZpY2VNZmdEZXNjVGFnLCAgICAgIChMUFZPSUQpICIobGNtcyBpbnRlcm5hbCkiKTsKICAgICAgIGNtc0FkZFRhZyhoSUNDLCBpY1NpZ1Byb2ZpbGVEZXNjcmlwdGlvblRhZywgKExQVk9JRCkgImxjbXMgaW5rIGxpbWl0aW5nIGRldmljZSBsaW5rIik7CiAgICAgICBjbXNBZGRUYWcoaElDQywgaWNTaWdEZXZpY2VNb2RlbERlc2NUYWcsICAgIChMUFZPSUQpICJpbmsgbGltaXRpbmcgYnVpbHQtaW4iKTsKCiAgICAgICBjbXNBZGRUYWcoaElDQywgaWNTaWdNZWRpYVdoaXRlUG9pbnRUYWcsIChMUFZPSUQpIGNtc0Q1MF9YWVooKSk7CgogICAgICAgY21zQWRkVGFnKGhJQ0MsIGljU2lnQVRvQjBUYWcsIChMUFZPSUQpIEx1dCk7CgogICAgICAgLy8gTFVUIGlzIGFscmVhZHkgb24gdmlydHVhbCBwcm9maWxlCiAgICAgICBjbXNGcmVlTFVUKEx1dCk7CgogICAgICAgLy8gT2ssIGRvbmUKICAgICAgIHJldHVybiBoSUNDOwp9CgoKCnN0YXRpYwpMUExVVCBDcmVhdGUzeDNFbXB0eUxVVCh2b2lkKQp7CiAgICAgICAgTFBMVVQgQVRvQjAgPSBjbXNBbGxvY0xVVCgpOwogICAgICAgIGlmIChBVG9CMCA9PSBOVUxMKSByZXR1cm4gTlVMTDsKCiAgICAgICAgQVRvQjAgLT4gSW5wdXRDaGFuID0gQVRvQjAgLT4gT3V0cHV0Q2hhbiA9IDM7CiAgICAgICAgcmV0dXJuIEFUb0IwOwp9CgoKCi8vIENyZWF0ZXMgYSBmYWtlIExhYiBpZGVudGl0eS4KY21zSFBST0ZJTEUgTENNU0VYUE9SVCBjbXNDcmVhdGVMYWJQcm9maWxlKExQY21zQ0lFeHlZIFdoaXRlUG9pbnQpCnsKICAgICAgICBjbXNIUFJPRklMRSBoUHJvZmlsZTsKICAgICAgICBMUExVVCBMdXQ7CgogICAgICAgIGhQcm9maWxlID0gY21zQ3JlYXRlUkdCUHJvZmlsZShXaGl0ZVBvaW50ID09IE5VTEwgPyBjbXNENTBfeHlZKCkgOiBXaGl0ZVBvaW50LCBOVUxMLCBOVUxMKTsKICAgICAgICBpZiAoaFByb2ZpbGUgPT0gTlVMTCkgcmV0dXJuIE5VTEw7CgogICAgICAgIGNtc1NldERldmljZUNsYXNzKGhQcm9maWxlLCBpY1NpZ0Fic3RyYWN0Q2xhc3MpOwogICAgICAgIGNtc1NldENvbG9yU3BhY2UoaFByb2ZpbGUsICBpY1NpZ0xhYkRhdGEpOwogICAgICAgIGNtc1NldFBDUyhoUHJvZmlsZSwgICAgICAgICBpY1NpZ0xhYkRhdGEpOwoKICAgICAgICBjbXNBZGRUYWcoaFByb2ZpbGUsIGljU2lnRGV2aWNlTWZnRGVzY1RhZywgICAgIChMUFZPSUQpICIobGNtcyBpbnRlcm5hbCkiKTsKICAgICAgICBjbXNBZGRUYWcoaFByb2ZpbGUsIGljU2lnUHJvZmlsZURlc2NyaXB0aW9uVGFnLCAoTFBWT0lEKSAibGNtcyBMYWIgaWRlbnRpdHkiKTsKICAgICAgICBjbXNBZGRUYWcoaFByb2ZpbGUsIGljU2lnRGV2aWNlTW9kZWxEZXNjVGFnLCAgICAoTFBWT0lEKSAiTGFiIGJ1aWx0LWluIik7CgoKICAgICAgIC8vIEFuIGVtcHR5IExVVHMgaXMgYWxsIHdlIG5lZWQKICAgICAgIEx1dCA9IENyZWF0ZTN4M0VtcHR5TFVUKCk7CiAgICAgICBpZiAoTHV0ID09IE5VTEwpIHsKICAgICAgICAgICBjbXNDbG9zZVByb2ZpbGUoaFByb2ZpbGUpOwogICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgICAgIH0KCiAgICAgICBjbXNBZGRUYWcoaFByb2ZpbGUsIGljU2lnQVRvQjBUYWcsICAgIChMUFZPSUQpIEx1dCk7CiAgICAgICBjbXNBZGRUYWcoaFByb2ZpbGUsIGljU2lnQlRvQTBUYWcsICAgIChMUFZPSUQpIEx1dCk7CgogICAgICAgY21zRnJlZUxVVChMdXQpOwoKICAgICAgIHJldHVybiBoUHJvZmlsZTsKfQoKCi8vIENyZWF0ZXMgYSBmYWtlIExhYiBpZGVudGl0eS4KY21zSFBST0ZJTEUgTENNU0VYUE9SVCBjbXNDcmVhdGVMYWI0UHJvZmlsZShMUGNtc0NJRXh5WSBXaGl0ZVBvaW50KQp7CiAgICAgICAgY21zSFBST0ZJTEUgaFByb2ZpbGU7CiAgICAgICAgTFBMVVQgTHV0OwoKICAgICAgICBoUHJvZmlsZSA9IGNtc0NyZWF0ZVJHQlByb2ZpbGUoV2hpdGVQb2ludCA9PSBOVUxMID8gY21zRDUwX3h5WSgpIDogV2hpdGVQb2ludCwgTlVMTCwgTlVMTCk7CiAgICAgICAgaWYgKGhQcm9maWxlID09IE5VTEwpIHJldHVybiBOVUxMOwoKICAgICAgICBjbXNTZXRQcm9maWxlSUNDdmVyc2lvbihoUHJvZmlsZSwgMHg0MDAwMDAwKTsKCiAgICAgICAgY21zU2V0RGV2aWNlQ2xhc3MoaFByb2ZpbGUsIGljU2lnQWJzdHJhY3RDbGFzcyk7CiAgICAgICAgY21zU2V0Q29sb3JTcGFjZShoUHJvZmlsZSwgIGljU2lnTGFiRGF0YSk7CiAgICAgICAgY21zU2V0UENTKGhQcm9maWxlLCAgICAgICAgIGljU2lnTGFiRGF0YSk7CgogICAgICAgIGNtc0FkZFRhZyhoUHJvZmlsZSwgaWNTaWdEZXZpY2VNZmdEZXNjVGFnLCAgICAgKExQVk9JRCkgIihsY21zIGludGVybmFsKSIpOwogICAgICAgIGNtc0FkZFRhZyhoUHJvZmlsZSwgaWNTaWdQcm9maWxlRGVzY3JpcHRpb25UYWcsIChMUFZPSUQpICJsY21zIExhYiBpZGVudGl0eSB2NCIpOwogICAgICAgIGNtc0FkZFRhZyhoUHJvZmlsZSwgaWNTaWdEZXZpY2VNb2RlbERlc2NUYWcsICAgIChMUFZPSUQpICJMYWIgdjQgYnVpbHQtaW4iKTsKCgogICAgICAgLy8gQW4gZW1wdHkgTFVUcyBpcyBhbGwgd2UgbmVlZAogICAgICAgTHV0ID0gQ3JlYXRlM3gzRW1wdHlMVVQoKTsKICAgICAgIGlmIChMdXQgPT0gTlVMTCkgewogICAgICAgICAgIGNtc0Nsb3NlUHJvZmlsZShoUHJvZmlsZSk7CiAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgICAgfQoKICAgICAgIEx1dCAtPiB3RmxhZ3MgfD0gTFVUX1Y0X0lOUFVUX0VNVUxBVEVfVjI7CiAgICAgICBjbXNBZGRUYWcoaFByb2ZpbGUsIGljU2lnQVRvQjBUYWcsICAgIChMUFZPSUQpIEx1dCk7CgogICAgICAgTHV0IC0+IHdGbGFncyB8PSBMVVRfVjRfT1VUUFVUX0VNVUxBVEVfVjI7CiAgICAgICBjbXNBZGRUYWcoaFByb2ZpbGUsIGljU2lnQlRvQTBUYWcsICAgIChMUFZPSUQpIEx1dCk7CgogICAgICAgY21zRnJlZUxVVChMdXQpOwoKICAgICAgIHJldHVybiBoUHJvZmlsZTsKfQoKCgovLyBDcmVhdGVzIGEgZmFrZSBYWVogaWRlbnRpdHkKY21zSFBST0ZJTEUgTENNU0VYUE9SVCBjbXNDcmVhdGVYWVpQcm9maWxlKHZvaWQpCnsKICAgICAgICBjbXNIUFJPRklMRSBoUHJvZmlsZTsKICAgICAgICBMUExVVCBMdXQ7CgogICAgICAgIGhQcm9maWxlID0gY21zQ3JlYXRlUkdCUHJvZmlsZShjbXNENTBfeHlZKCksIE5VTEwsIE5VTEwpOwogICAgICAgIGlmIChoUHJvZmlsZSA9PSBOVUxMKSByZXR1cm4gTlVMTDsKCiAgICAgICAgY21zU2V0RGV2aWNlQ2xhc3MoaFByb2ZpbGUsIGljU2lnQWJzdHJhY3RDbGFzcyk7CiAgICAgICAgY21zU2V0Q29sb3JTcGFjZShoUHJvZmlsZSwgaWNTaWdYWVpEYXRhKTsKICAgICAgICBjbXNTZXRQQ1MoaFByb2ZpbGUsICBpY1NpZ1hZWkRhdGEpOwoKICAgICAgICBjbXNBZGRUYWcoaFByb2ZpbGUsIGljU2lnRGV2aWNlTWZnRGVzY1RhZywgICAgICAoTFBWT0lEKSAiKGxjbXMgaW50ZXJuYWwpIik7CiAgICAgICAgY21zQWRkVGFnKGhQcm9maWxlLCBpY1NpZ1Byb2ZpbGVEZXNjcmlwdGlvblRhZywgKExQVk9JRCkgImxjbXMgWFlaIGlkZW50aXR5Iik7CiAgICAgICAgY21zQWRkVGFnKGhQcm9maWxlLCBpY1NpZ0RldmljZU1vZGVsRGVzY1RhZywgICAgKExQVk9JRCkgICJYWVogYnVpbHQtaW4iKTsKCiAgICAgICAvLyBBbiBlbXB0eSBMVVRzIGlzIGFsbCB3ZSBuZWVkCiAgICAgICBMdXQgPSBDcmVhdGUzeDNFbXB0eUxVVCgpOwogICAgICAgaWYgKEx1dCA9PSBOVUxMKSB7CiAgICAgICAgICAgY21zQ2xvc2VQcm9maWxlKGhQcm9maWxlKTsKICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICAgICB9CgogICAgICAgY21zQWRkVGFnKGhQcm9maWxlLCBpY1NpZ0FUb0IwVGFnLCAgICAoTFBWT0lEKSBMdXQpOwogICAgICAgY21zQWRkVGFnKGhQcm9maWxlLCBpY1NpZ0JUb0EwVGFnLCAgICAoTFBWT0lEKSBMdXQpOwogICAgICAgY21zQWRkVGFnKGhQcm9maWxlLCBpY1NpZ1ByZXZpZXcwVGFnLCAoTFBWT0lEKSBMdXQpOwoKICAgICAgIGNtc0ZyZWVMVVQoTHV0KTsKICAgICAgIHJldHVybiBoUHJvZmlsZTsKfQoKCgovKgoKSWYgIFKSc1JHQixHknNSR0IsIEKSc1JHQiA8IDAuMDQwNDUKCiAgICBSID0gIFKSc1JHQiAvIDEyLjkyCiAgICBHID0gIEeSc1JHQiAvIDEyLjkyCiAgICBCID0gIEKSc1JHQiAvIDEyLjkyCgoKCmVsc2UgaWYgIFKSc1JHQixHknNSR0IsIEKSc1JHQiA+PSAwLjA0MDQ1CgogICAgUiA9ICgoUpJzUkdCICsgMC4wNTUpIC8gMS4wNTUpXjIuNAogICAgRyA9ICgoR5JzUkdCICsgMC4wNTUpIC8gMS4wNTUpXjIuNAogICAgQiA9ICgoQpJzUkdCICsgMC4wNTUpIC8gMS4wNTUpXjIuNAoKICAqLwoKc3RhdGljCkxQR0FNTUFUQUJMRSBCdWlsZF9zUkdCR2FtbWEodm9pZCkKewogICAgZG91YmxlIFBhcmFtZXRlcnNbNV07CgogICAgUGFyYW1ldGVyc1swXSA9IDIuNDsKICAgIFBhcmFtZXRlcnNbMV0gPSAxLiAvIDEuMDU1OwogICAgUGFyYW1ldGVyc1syXSA9IDAuMDU1IC8gMS4wNTU7CiAgICBQYXJhbWV0ZXJzWzNdID0gMS4gLyAxMi45MjsKICAgIFBhcmFtZXRlcnNbNF0gPSAwLjA0MDQ1OyAgICAvLyBkCgogICAgcmV0dXJuIGNtc0J1aWxkUGFyYW1ldHJpY0dhbW1hKDEwMjQsIDQsIFBhcmFtZXRlcnMpOwp9CgovLyBDcmVhdGUgdGhlIElDQyB2aXJ0dWFsIHByb2ZpbGUgZm9yIHNSR0Igc3BhY2UKY21zSFBST0ZJTEUgTENNU0VYUE9SVCBjbXNDcmVhdGVfc1JHQlByb2ZpbGUodm9pZCkKewogICAgICAgY21zQ0lFeHlZICAgICAgIEQ2NTsKICAgICAgIGNtc0NJRXh5WVRSSVBMRSBSZWM3MDlQcmltYXJpZXMgPSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgezAuNjQwMCwgMC4zMzAwLCAxLjB9LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHswLjMwMDAsIDAuNjAwMCwgMS4wfSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7MC4xNTAwLCAwLjA2MDAsIDEuMH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9OwogICAgICAgTFBHQU1NQVRBQkxFIEdhbW1hMjJbM107CiAgICAgICBjbXNIUFJPRklMRSAgaHNSR0I7CgogICAgICAgY21zV2hpdGVQb2ludEZyb21UZW1wKDY1MDQsICZENjUpOwogICAgICAgR2FtbWEyMlswXSA9IEdhbW1hMjJbMV0gPSBHYW1tYTIyWzJdID0gQnVpbGRfc1JHQkdhbW1hKCk7CgogICAgICAgaHNSR0IgPSBjbXNDcmVhdGVSR0JQcm9maWxlKCZENjUsICZSZWM3MDlQcmltYXJpZXMsIEdhbW1hMjIpOwogICAgICAgY21zRnJlZUdhbW1hKEdhbW1hMjJbMF0pOwogICAgICAgaWYgKGhzUkdCID09IE5VTEwpIHJldHVybiBOVUxMOwoKCiAgICAgICBjbXNBZGRUYWcoaHNSR0IsIGljU2lnRGV2aWNlTWZnRGVzY1RhZywgICAgICAoTFBWT0lEKSAiKGxjbXMgaW50ZXJuYWwpIik7CiAgICAgICBjbXNBZGRUYWcoaHNSR0IsIGljU2lnRGV2aWNlTW9kZWxEZXNjVGFnLCAgICAoTFBWT0lEKSAic1JHQiBidWlsdC1pbiIpOwogICAgICAgY21zQWRkVGFnKGhzUkdCLCBpY1NpZ1Byb2ZpbGVEZXNjcmlwdGlvblRhZywgKExQVk9JRCkgInNSR0IgYnVpbHQtaW4iKTsKCiAgICAgICByZXR1cm4gaHNSR0I7Cn0KCgoKdHlwZWRlZiBzdHJ1Y3QgewogICAgICAgICAgICAgICAgZG91YmxlIEJyaWdodG5lc3M7CiAgICAgICAgICAgICAgICBkb3VibGUgQ29udHJhc3Q7CiAgICAgICAgICAgICAgICBkb3VibGUgSHVlOwogICAgICAgICAgICAgICAgZG91YmxlIFNhdHVyYXRpb247CiAgICAgICAgICAgICAgICBjbXNDSUVYWVogV1BzcmMsIFdQZGVzdDsKCn0gQkNIU1dBREpVU1RTLCAqTFBCQ0hTV0FESlVTVFM7CgoKc3RhdGljCmludCBiY2hzd1NhbXBsZXIocmVnaXN0ZXIgV09SRCBJbltdLCByZWdpc3RlciBXT1JEIE91dFtdLCByZWdpc3RlciBMUFZPSUQgQ2FyZ28pCnsKICAgIGNtc0NJRUxhYiBMYWJJbiwgTGFiT3V0OwogICAgY21zQ0lFTENoIExDaEluLCBMQ2hPdXQ7CiAgICBjbXNDSUVYWVogWFlaOwogICAgTFBCQ0hTV0FESlVTVFMgYmNoc3cgPSAoTFBCQ0hTV0FESlVTVFMpIENhcmdvOwoKCiAgICBjbXNMYWJFbmNvZGVkMkZsb2F0KCZMYWJJbiwgSW4pOwoKCiAgICBjbXNMYWIyTENoKCZMQ2hJbiwgJkxhYkluKTsKCiAgICAvLyBEbyBzb21lIGFkanVzdHMgb24gTENoCgogICAgTENoT3V0LkwgPSBMQ2hJbi5MICogYmNoc3cgLT5Db250cmFzdCArIGJjaHN3IC0+QnJpZ2h0bmVzczsKICAgIExDaE91dC5DID0gTENoSW4uQyArIGJjaHN3IC0+IFNhdHVyYXRpb247CiAgICBMQ2hPdXQuaCA9IExDaEluLmggKyBiY2hzdyAtPiBIdWU7CgoKICAgIGNtc0xDaDJMYWIoJkxhYk91dCwgJkxDaE91dCk7CgogICAgLy8gTW92ZSB3aGl0ZSBwb2ludCBpbiBMYWIKCiAgICBjbXNMYWIyWFlaKCZiY2hzdyAtPldQc3JjLCAgJlhZWiwgJkxhYk91dCk7CiAgICBjbXNYWVoyTGFiKCZiY2hzdyAtPldQZGVzdCwgJkxhYk91dCwgJlhZWik7CgogICAgLy8gQmFjayB0byBlbmNvZGVkCgogICAgY21zRmxvYXQyTGFiRW5jb2RlZChPdXQsICZMYWJPdXQpOwoKICAgIHJldHVybiBUUlVFOwp9CgoKLy8gQ3JlYXRlcyBhbiBhYnN0cmFjdCBwcm9maWxlIG9wZXJhdGluZyBpbiBMYWIgc3BhY2UgZm9yIEJyaWdodG5lc3MsCi8vIGNvbnRyYXN0LCBTYXR1cmF0aW9uIGFuZCB3aGl0ZSBwb2ludCBkaXNwbGFjZW1lbnQKCmNtc0hQUk9GSUxFIExDTVNFWFBPUlQgY21zQ3JlYXRlQkNIU1dhYnN0cmFjdFByb2ZpbGUoaW50IG5MVVRQb2ludHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG91YmxlIEJyaWdodCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb3VibGUgQ29udHJhc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG91YmxlIEh1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb3VibGUgU2F0dXJhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgVGVtcFNyYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgVGVtcERlc3QpCnsKICAgICBjbXNIUFJPRklMRSBoSUNDOwogICAgIExQTFVUIEx1dDsKICAgICBCQ0hTV0FESlVTVFMgYmNoc3c7CiAgICAgY21zQ0lFeHlZIFdoaXRlUG50OwoKICAgICBiY2hzdy5CcmlnaHRuZXNzID0gQnJpZ2h0OwogICAgIGJjaHN3LkNvbnRyYXN0ICAgPSBDb250cmFzdDsKICAgICBiY2hzdy5IdWUgICAgICAgID0gSHVlOwogICAgIGJjaHN3LlNhdHVyYXRpb24gPSBTYXR1cmF0aW9uOwoKICAgICBjbXNXaGl0ZVBvaW50RnJvbVRlbXAoVGVtcFNyYywgICZXaGl0ZVBudCk7CiAgICAgY21zeHlZMlhZWigmYmNoc3cuV1BzcmMsICZXaGl0ZVBudCk7CgogICAgIGNtc1doaXRlUG9pbnRGcm9tVGVtcChUZW1wRGVzdCwgJldoaXRlUG50KTsKICAgICBjbXN4eVkyWFlaKCZiY2hzdy5XUGRlc3QsICZXaGl0ZVBudCk7CgogICAgICBoSUNDID0gX2Ntc0NyZWF0ZVByb2ZpbGVQbGFjZWhvbGRlcigpOwogICAgICAgaWYgKCFoSUNDKSAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY2FuJ3QgYWxsb2NhdGUKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CgoKICAgICAgIGNtc1NldERldmljZUNsYXNzKGhJQ0MsICAgICAgaWNTaWdBYnN0cmFjdENsYXNzKTsKICAgICAgIGNtc1NldENvbG9yU3BhY2UoaElDQywgICAgICAgaWNTaWdMYWJEYXRhKTsKICAgICAgIGNtc1NldFBDUyhoSUNDLCAgICAgICAgICAgICAgaWNTaWdMYWJEYXRhKTsKCiAgICAgICBjbXNTZXRSZW5kZXJpbmdJbnRlbnQoaElDQywgIElOVEVOVF9QRVJDRVBUVUFMKTsKCgogICAgICAgLy8gQ3JlYXRlcyBhIExVVCB3aXRoIDNEIGdyaWQgb25seQogICAgICAgTHV0ID0gY21zQWxsb2NMVVQoKTsKICAgICAgIGlmIChMdXQgPT0gTlVMTCkgewogICAgICAgICAgIGNtc0Nsb3NlUHJvZmlsZShoSUNDKTsKICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICAgICB9CgogICAgICAgY21zQWxsb2MzREdyaWQoTHV0LCBuTFVUUG9pbnRzLCAzLCAzKTsKCiAgICAgICBpZiAoIWNtc1NhbXBsZTNER3JpZChMdXQsIGJjaHN3U2FtcGxlciwgKExQVk9JRCkgJmJjaHN3LCAwKSkgewoKICAgICAgICAgICAgICAgIC8vIFNob3VsZG4ndCByZWFjaCBoZXJlCiAgICAgICAgICAgICAgICBjbXNGcmVlTFVUKEx1dCk7CiAgICAgICAgICAgICAgICBjbXNDbG9zZVByb2ZpbGUoaElDQyk7CiAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgIH0KCiAgICAgICAvLyBDcmVhdGUgdGFncwoKICAgICAgIGNtc0FkZFRhZyhoSUNDLCBpY1NpZ0RldmljZU1mZ0Rlc2NUYWcsICAgICAgKExQVk9JRCkgIihsY21zIGludGVybmFsKSIpOwogICAgICAgY21zQWRkVGFnKGhJQ0MsIGljU2lnUHJvZmlsZURlc2NyaXB0aW9uVGFnLCAoTFBWT0lEKSAibGNtcyBCQ0hTVyBhYnN0cmFjdCBwcm9maWxlIik7CiAgICAgICBjbXNBZGRUYWcoaElDQywgaWNTaWdEZXZpY2VNb2RlbERlc2NUYWcsICAgIChMUFZPSUQpICJCQ0hTVyBidWlsdC1pbiIpOwoKICAgICAgIGNtc0FkZFRhZyhoSUNDLCBpY1NpZ01lZGlhV2hpdGVQb2ludFRhZywgKExQVk9JRCkgY21zRDUwX1hZWigpKTsKCiAgICAgICBjbXNBZGRUYWcoaElDQywgaWNTaWdBVG9CMFRhZywgKExQVk9JRCkgTHV0KTsKCiAgICAgICAvLyBMVVQgaXMgYWxyZWFkeSBvbiB2aXJ0dWFsIHByb2ZpbGUKICAgICAgIGNtc0ZyZWVMVVQoTHV0KTsKCiAgICAgICAvLyBPaywgZG9uZQogICAgICAgcmV0dXJuIGhJQ0M7Cgp9CgoKLy8gQ3JlYXRlcyBhIGZha2UgTlVMTCBwcm9maWxlLiBUaGlzIHByb2ZpbGUgcmV0dXJuIDEgY2hhbm5lbCBhcyBhbHdheXMgMC4KLy8gSXMgdXNlZnVsIG9ubHkgZm9yIGdhbXV0IGNoZWNraW5nIHRyaWNrcwoKY21zSFBST0ZJTEUgTENNU0VYUE9SVCBjbXNDcmVhdGVOVUxMUHJvZmlsZSh2b2lkKQp7CiAgICAgICAgY21zSFBST0ZJTEUgaFByb2ZpbGU7CiAgICAgICAgTFBMVVQgTHV0OwogICAgICAgIExQR0FNTUFUQUJMRSBFbXB0eVRhYjsKCiAgICAgICAgaFByb2ZpbGUgPSBfY21zQ3JlYXRlUHJvZmlsZVBsYWNlaG9sZGVyKCk7CiAgICAgICAgaWYgKCFoUHJvZmlsZSkgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNhbid0IGFsbG9jYXRlCiAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKCiAgICAgICAgY21zU2V0RGV2aWNlQ2xhc3MoaFByb2ZpbGUsIGljU2lnT3V0cHV0Q2xhc3MpOwogICAgICAgIGNtc1NldENvbG9yU3BhY2UoaFByb2ZpbGUsICBpY1NpZ0dyYXlEYXRhKTsKICAgICAgICBjbXNTZXRQQ1MoaFByb2ZpbGUsICAgICAgICAgaWNTaWdMYWJEYXRhKTsKCgogICAgICAgLy8gQW4gZW1wdHkgTFVUcyBpcyBhbGwgd2UgbmVlZAogICAgICAgTHV0ID0gY21zQWxsb2NMVVQoKTsKICAgICAgIGlmIChMdXQgPT0gTlVMTCkgewogICAgICAgICAgIGNtc0Nsb3NlUHJvZmlsZShoUHJvZmlsZSk7CiAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgICAgfQoKICAgICAgIEx1dCAtPiBJbnB1dENoYW4gPSAzOwogICAgICAgTHV0IC0+IE91dHB1dENoYW4gPSAxOwoKICAgICAgIEVtcHR5VGFiID0gY21zQWxsb2NHYW1tYSgyKTsKICAgICAgIEVtcHR5VGFiIC0+R2FtbWFUYWJsZVswXSA9IDA7CiAgICAgICBFbXB0eVRhYiAtPkdhbW1hVGFibGVbMV0gPSAwOwoKICAgICAgIGNtc0FsbG9jTGluZWFyVGFibGUoTHV0LCAmRW1wdHlUYWIsIDIpOwoKICAgICAgIGNtc0FkZFRhZyhoUHJvZmlsZSwgaWNTaWdCVG9BMFRhZywgKExQVk9JRCkgTHV0KTsKCiAgICAgICBjbXNGcmVlTFVUKEx1dCk7CiAgICAgICBjbXNGcmVlR2FtbWEoRW1wdHlUYWIpOwoKICAgICAgIHJldHVybiBoUHJvZmlsZTsKfQo=