I2luY2x1ZGUgPENvcHlyaWdodC5oPgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3RQb3J0Q3RybC5jCioKKiBERVNDUklQVElPTjoKKiAgICAgICBBUEkgaW1wbGVtZW50YXRpb24gZm9yIHN3aXRjaCBwb3J0IGNvbnRyb2wuCioKKiBERVBFTkRFTkNJRVM6CioKKiBGSUxFIFJFVklTSU9OIE5VTUJFUjoKKiAgICAgICAkUmV2aXNpb246IDMgJAoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKI2luY2x1ZGUgPG1zQXBpLmg+CiNpbmNsdWRlIDxndEh3Q250bC5oPgojaW5jbHVkZSA8Z3REcnZTd1JlZ3MuaD4KI2luY2x1ZGUgPGd0U2VtLmg+CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdwcnRTZXRGb3JjZUZjCioKKiBERVNDUklQVElPTjoKKiAgICAgICBUaGlzIHJvdXRpbmUgc2V0IHRoZSBmb3JjZSBmbG93IGNvbnRyb2wgc3RhdGUuCioKKiBJTlBVVFM6CiogICAgICAgcG9ydCAgLSB0aGUgbG9naWNhbCBwb3J0IG51bWJlci4KKiAgICAgICBmb3JjZSAtIEdUX1RSVUUgZm9yIGZvcmNlIGZsb3cgY29udHJvbCAgb3IgR1RfRkFMU0Ugb3RoZXJ3aXNlCioKKiBPVVRQVVRTOgoqICAgICAgIE5vbmUuCioKKiBSRVRVUk5TOgoqICAgICAgIEdUX09LICAgLSBvbiBzdWNjZXNzCiogICAgICAgR1RfRkFJTCAtIG9uIGVycm9yCioKKiBDT01NRU5UUzoKKgoqCiogR2FsVGlzOgoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBncHJ0U2V0Rm9yY2VGYwooCiAgICBJTiBHVF9RRF9ERVYgICpkZXYsCiAgICBJTiBHVF9MUE9SVCAgIHBvcnQsCiAgICBJTiBHVF9CT09MICAgIGZvcmNlCikKewogICAgR1RfVTE2ICAgICAgICAgIGRhdGE7CiAgICBHVF9TVEFUVVMgICAgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX1U4ICAgICAgICAgICBod1BvcnQ7ICAgICAgICAgLyogdGhlIHBoeXNpY2FsIHBvcnQgbnVtYmVyICAgICAqLwogICAgR1RfUE9SVF9TVFBfU1RBVEUgIHN0YXRlOwoKICAgIERCR19JTkZPKCgiZ3BydFNldEZvcmNlRmMgQ2FsbGVkLlxuIikpOwoKICAgIC8qIHRyYW5zbGF0ZSBMUE9SVCB0byBoYXJkd2FyZSBwb3J0ICovCiAgICBod1BvcnQgPSBHVF9MUE9SVF8yX1BPUlQocG9ydCk7CgogICAgLyogY2hlY2sgaWYgZGV2aWNlIGFsbG93cyB0byBmb3JjZSBhIGZsb3djb250cm9sIGRpc2FibGVkICovCiAgICBpZiAoSVNfSU5fREVWX0dST1VQKGRldixERVZfRkNfV0lUSF9WQUxVRSkpCiAgICB7CiAgICAgICAgaWYoZm9yY2UpCiAgICAgICAgICAgIGRhdGEgPSAzOwogICAgICAgIGVsc2UKICAgICAgICAgICAgZGF0YSA9IDA7CgogICAgICAgIHJldFZhbCA9IGh3U2V0UG9ydFJlZ0ZpZWxkKGRldixod1BvcnQsIFFEX1JFR19QQ1NfQ09OVFJPTCw2LDIsZGF0YSk7CiAgICAgICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgICAgIHsKICAgICAgICAgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIERCR19JTkZPKCgiT0suXG4iKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXRWYWw7CiAgICB9CgogICAgLyogUG9ydCBzaG91bGQgYmUgZGlzYWJsZWQgYmVmb3JlIFNldCBGb3JjZSBGbG93IENvbnRyb2wgYml0ICovCiAgICByZXRWYWwgPSBnc3RwR2V0UG9ydFN0YXRlKGRldixwb3J0LCAmc3RhdGUpOwogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgewogICAgICAgIERCR19JTkZPKCgiZ3N0cEdldFBvcnRTdGF0ZSBmYWlsZWQuXG4iKSk7CiAgICAgICAgcmV0dXJuIHJldFZhbDsKICAgIH0KCiAgICByZXRWYWwgPSBnc3RwU2V0UG9ydFN0YXRlKGRldixwb3J0LCBHVF9QT1JUX0RJU0FCTEUpOwogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgewogICAgICAgIERCR19JTkZPKCgiZ3N0cFNldFBvcnRTdGF0ZSBmYWlsZWQuXG4iKSk7CiAgICAgICAgcmV0dXJuIHJldFZhbDsKICAgIH0KCiAgICAvKiB0cmFuc2xhdGUgQk9PTCB0byBiaW5hcnkgKi8KICAgIEJPT0xfMl9CSVQoZm9yY2UsIGRhdGEpOwoKICAgIC8qIFNldCB0aGUgZm9yY2UgZmxvdyBjb250cm9sIGJpdC4gICovCiAgICByZXRWYWwgPSBod1NldFBvcnRSZWdGaWVsZChkZXYsaHdQb3J0LCBRRF9SRUdfUE9SVF9DT05UUk9MLDE1LDEsZGF0YSk7CiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJPSy5cbiIpKTsKICAgIH0KCiAgICAvKiBSZXN0b3JlIG9yaWdpbmFsIHN0cCBzdGF0ZS4gKi8KICAgIGlmKGdzdHBTZXRQb3J0U3RhdGUoZGV2LHBvcnQsIHN0YXRlKSAhPSBHVF9PSykKICAgIHsKICAgICAgICBEQkdfSU5GTygoImdzdHBTZXRQb3J0U3RhdGUgZmFpbGVkLlxuIikpOwogICAgICAgIHJldHVybiBHVF9GQUlMOwogICAgfQoKICAgIHJldHVybiByZXRWYWw7Cn0KCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBncHJ0R2V0Rm9yY2VGYwoqCiogREVTQ1JJUFRJT046CiogICAgICAgVGhpcyByb3V0aW5lIGdldCB0aGUgZm9yY2UgZmxvdyBjb250cm9sIHN0YXRlLgoqCiogSU5QVVRTOgoqICAgICAgIHBvcnQgIC0gdGhlIGxvZ2ljYWwgcG9ydCBudW1iZXIuCioKKiBPVVRQVVRTOgoqICAgICAgIGZvcmNlIC0gR1RfVFJVRSBmb3IgZm9yY2UgZmxvdyBjb250cm9sICBvciBHVF9GQUxTRSBvdGhlcndpc2UKKgoqIFJFVFVSTlM6CiogICAgICAgR1RfT0sgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICBHVF9GQUlMIC0gb24gZXJyb3IKKgoqIENPTU1FTlRTOgoqCioKKiBHYWxUaXM6CioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdwcnRHZXRGb3JjZUZjCigKICAgIElOICBHVF9RRF9ERVYgICpkZXYsCiAgICBJTiAgR1RfTFBPUlQgICBwb3J0LAogICAgT1VUIEdUX0JPT0wgICAgKmZvcmNlCikKewogICAgR1RfVTE2ICAgICAgICAgIGRhdGE7CiAgICBHVF9TVEFUVVMgICAgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX1U4ICAgICAgICAgICBod1BvcnQ7ICAgICAgICAgLyogdGhlIHBoeXNpY2FsIHBvcnQgbnVtYmVyICAgICAqLwoKICAgIERCR19JTkZPKCgiZ3BydEdldEZvcmNlRmMgQ2FsbGVkLlxuIikpOwogICAgLyogdHJhbnNsYXRlIExQT1JUIHRvIGhhcmR3YXJlIHBvcnQgKi8KICAgIGh3UG9ydCA9IEdUX0xQT1JUXzJfUE9SVChwb3J0KTsKCiAgICAvKiBjaGVjayBpZiBkZXZpY2UgYWxsb3dzIHRvIGZvcmNlIGEgZmxvd2NvbnRyb2wgZGlzYWJsZWQgKi8KICAgIGlmIChJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9GQ19XSVRIX1ZBTFVFKSkKICAgIHsKICAgICAgICByZXRWYWwgPSBod0dldFBvcnRSZWdGaWVsZChkZXYsaHdQb3J0LCBRRF9SRUdfUENTX0NPTlRST0wsNiwyLCZkYXRhKTsKICAgICAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICAgICAgewogICAgICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgREJHX0lORk8oKCJPSy5cbiIpKTsKICAgICAgICB9CgogICAgICAgIGlmKGRhdGEgJiAweDEpCiAgICAgICAgICAgICpmb3JjZSA9IEdUX1RSVUU7CiAgICAgICAgZWxzZQogICAgICAgICAgICAqZm9yY2UgPSBHVF9GQUxTRTsKCiAgICAgICAgcmV0dXJuIHJldFZhbDsKICAgIH0KCiAgICAvKiBHZXQgdGhlIGZvcmNlIGZsb3cgY29udHJvbCBiaXQuICAqLwogICAgcmV0VmFsID0gaHdHZXRQb3J0UmVnRmllbGQoZGV2LGh3UG9ydCwgUURfUkVHX1BPUlRfQ09OVFJPTCwxNSwxLCZkYXRhKTsKICAgIC8qIHRyYW5zbGF0ZSBiaW5hcnkgdG8gQk9PTCAgKi8KICAgIEJJVF8yX0JPT0woZGF0YSwgKmZvcmNlKTsKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBEQkdfSU5GTygoIk9LLlxuIikpOwogICAgfQoKICAgIHJldHVybiByZXRWYWw7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdwcnRTZXRVc2VDb3JlVGFnCioKKiBERVNDUklQVElPTjoKKiAgICAgICAgVGhpcyByb3V0aW5lIHNldCB0aGUgVXNlQ29yZVRhZyBiaXQgaW4gUG9ydCBDb250cm9sIFJlZ2lzdGVyLgoqICAgICAgICBXaGVuIHRoaXMgYml0IGlzIGNsZWFyZWQgdG8gYSB6ZXJvLCBpbmdyZXNzaW5nIGZyYW1lcyBhcmUgY29uc2lkZXJlZAoqICAgICAgICBUYWdnZWQgaWYgdGhlIDE2LWJpdHMgZm9sbG93aW5nIHRoZSBmcmFtZSdzIFNvdXJjZSBBZGRyZXNzIGlzIDB4ODEwMC4KKiAgICAgICAgV2hlbiB0aGlzIGJpdCBpcyBzZXQgdG8gYSBvbmUsIGluZ3Jlc3NpbmcgZnJhbWVzIGFyZSBjb25zaWRlcmVkIFRhZ2dlZAoqICAgICAgICBpZiB0aGUgMTYtYml0cyBmb2xsb3dpbmcgdGhlIGZyYW1lJ3MgU291cmNlIEFkZHJlc3MgaXMgZXF1YWwgdG8gdGhlCiogICAgICAgIENvcmVUYWcgcmVnaXN0ZXIgdmFsdWUuCioKKiBJTlBVVFM6CiogICAgICAgcG9ydCAgLSB0aGUgbG9naWNhbCBwb3J0IG51bWJlci4KKiAgICAgICBmb3JjZSAtIEdUX1RSVUUgZm9yIGZvcmNlIGZsb3cgY29udHJvbCAgb3IgR1RfRkFMU0Ugb3RoZXJ3aXNlCioKKiBPVVRQVVRTOgoqICAgICAgIE5vbmUuCioKKiBSRVRVUk5TOgoqICAgICAgIEdUX09LICAgLSBvbiBzdWNjZXNzCiogICAgICAgR1RfRkFJTCAtIG9uIGVycm9yCioKKiBDT01NRU5UUzoKKgoqCiogR2FsVGlzOgoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBncHJ0U2V0VXNlQ29yZVRhZwooCiAgICBJTiBHVF9RRF9ERVYgICpkZXYsCiAgICBJTiBHVF9MUE9SVCAgIHBvcnQsCiAgICBJTiBHVF9CT09MICAgIGZvcmNlCikKewogICAgR1RfVTE2ICAgICAgICAgIGRhdGE7CiAgICBHVF9TVEFUVVMgICAgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX1U4ICAgICAgICAgICBod1BvcnQ7ICAgICAgICAgLyogdGhlIHBoeXNpY2FsIHBvcnQgbnVtYmVyICAgICAqLwoKICAgIERCR19JTkZPKCgiZ3BydFNldFVzZUNvcmVUYWcgQ2FsbGVkLlxuIikpOwoKICAgIC8qIHRyYW5zbGF0ZSBMUE9SVCB0byBoYXJkd2FyZSBwb3J0ICovCiAgICBod1BvcnQgPSBHVF9MUE9SVF8yX1BPUlQocG9ydCk7CgogICAgLyogY2hlY2sgaWYgZGV2aWNlIGFsbG93cyB0byBmb3JjZSBhIGZsb3djb250cm9sIGRpc2FibGVkICovCiAgICBpZiAoIUlTX0lOX0RFVl9HUk9VUChkZXYsREVWX0NPUkVfVEFHKSkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX05PVF9TVVBQT1JURUQuXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CgogICAgLyogdHJhbnNsYXRlIEJPT0wgdG8gYmluYXJ5ICovCiAgICBCT09MXzJfQklUKGZvcmNlLCBkYXRhKTsKCiAgICAvKiBTZXQgdGhlIFVzZUNvcmVUYWcgYml0LiAgKi8KICAgIHJldFZhbCA9IGh3U2V0UG9ydFJlZ0ZpZWxkKGRldixod1BvcnQsIFFEX1JFR19QT1JUX0NPTlRST0wsMTUsMSxkYXRhKTsKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBEQkdfSU5GTygoIk9LLlxuIikpOwogICAgfQoKICAgIHJldHVybiByZXRWYWw7Cn0KCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBncHJ0R2V0VXNlQ29yZVRhZwoqCiogREVTQ1JJUFRJT046CiogICAgICAgVGhpcyByb3V0aW5lIGdldCB0aGUgVXNlIENvcmUgVGFnIHN0YXRlLgoqCiogSU5QVVRTOgoqICAgICAgIHBvcnQgIC0gdGhlIGxvZ2ljYWwgcG9ydCBudW1iZXIuCioKKiBPVVRQVVRTOgoqICAgICAgIGZvcmNlIC0gR1RfVFJVRSBmb3IgdXNpbmcgY29yZSB0YWcgcmVnaXN0ZXIgIG9yIEdUX0ZBTFNFIG90aGVyd2lzZQoqCiogUkVUVVJOUzoKKiAgICAgICBHVF9PSyAgIC0gb24gc3VjY2VzcwoqICAgICAgIEdUX0ZBSUwgLSBvbiBlcnJvcgoqCiogQ09NTUVOVFM6CioKKgoqIEdhbFRpczoKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3BydEdldFVzZUNvcmVUYWcKKAogICAgSU4gIEdUX1FEX0RFViAgKmRldiwKICAgIElOICBHVF9MUE9SVCAgIHBvcnQsCiAgICBPVVQgR1RfQk9PTCAgICAqZm9yY2UKKQp7CiAgICBHVF9VMTYgICAgICAgICAgZGF0YTsKICAgIEdUX1NUQVRVUyAgICAgICByZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwogICAgR1RfVTggICAgICAgICAgIGh3UG9ydDsgICAgICAgICAvKiB0aGUgcGh5c2ljYWwgcG9ydCBudW1iZXIgICAgICovCgogICAgREJHX0lORk8oKCJncHJ0R2V0VXNlQ29yZVRhZyBDYWxsZWQuXG4iKSk7CiAgICAvKiB0cmFuc2xhdGUgTFBPUlQgdG8gaGFyZHdhcmUgcG9ydCAqLwogICAgaHdQb3J0ID0gR1RfTFBPUlRfMl9QT1JUKHBvcnQpOwoKICAgIGlmICghSVNfSU5fREVWX0dST1VQKGRldixERVZfQ09SRV9UQUcpKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfTk9UX1NVUFBPUlRFRC5cbiIpKTsKICAgICAgICByZXR1cm4gR1RfTk9UX1NVUFBPUlRFRDsKICAgIH0KCiAgICAvKiBHZXQgdGhlIFVzZUNvcmVUYWcgYml0LiAgKi8KICAgIHJldFZhbCA9IGh3R2V0UG9ydFJlZ0ZpZWxkKGRldixod1BvcnQsIFFEX1JFR19QT1JUX0NPTlRST0wsMTUsMSwmZGF0YSk7CiAgICAvKiB0cmFuc2xhdGUgYmluYXJ5IHRvIEJPT0wgICovCiAgICBCSVRfMl9CT09MKGRhdGEsICpmb3JjZSk7CiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJPSy5cbiIpKTsKICAgIH0KCiAgICByZXR1cm4gcmV0VmFsOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBncHJ0U2V0VHJhaWxlck1vZGUKKgoqIERFU0NSSVBUSU9OOgoqICAgICAgIFRoaXMgcm91dGluZSBzZXQgdGhlIGVncmVzcyB0cmFpbGVyIG1vZGUuCioKKiBJTlBVVFM6CiogICAgICAgcG9ydCAtIHRoZSBsb2dpY2FsIHBvcnQgbnVtYmVyLgoqICAgICAgIG1vZGUgLSBHVF9UUlVFIGZvciBhZGQgdHJhaWxlciBvciBHVF9GQUxTRSBvdGhlcndpc2UKKgoqIE9VVFBVVFM6CiogICAgICAgTm9uZS4KKgoqIFJFVFVSTlM6CiogICAgICAgR1RfT0sgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICBHVF9GQUlMIC0gb24gZXJyb3IKKgoqIENPTU1FTlRTOgoqCioKKiBHYWxUaXM6CioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdwcnRTZXRUcmFpbGVyTW9kZQooCiAgICBJTiBHVF9RRF9ERVYgICpkZXYsCiAgICBJTiBHVF9MUE9SVCAgIHBvcnQsCiAgICBJTiBHVF9CT09MICAgIG1vZGUKKQp7CiAgICBHVF9VMTYgICAgICAgICAgZGF0YTsKICAgIEdUX1NUQVRVUyAgICAgICByZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwogICAgR1RfVTggICAgICAgICAgIGh3UG9ydDsgICAgICAgICAvKiB0aGUgcGh5c2ljYWwgcG9ydCBudW1iZXIgICAgICovCgogICAgREJHX0lORk8oKCJncHJ0U2V0VHJhaWxlck1vZGUgQ2FsbGVkLlxuIikpOwoKICAgIC8qIGNoZWNrIGlmIGRldmljZSBzdXBwb3J0cyB0aGlzIGZlYXR1cmUgKi8KICAgIGlmICghKChJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9UUkFJTEVSKSkgfHwKICAgICAgICAgIChJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9UUkFJTEVSX1A1KSkgfHwKICAgICAgICAgIChJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9UUkFJTEVSX1A0UDUpKSkpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVELlxuIikpOwogICAgICAgIHJldHVybiBHVF9OT1RfU1VQUE9SVEVEOwogICAgfQoKICAgIC8qIHRyYW5zbGF0ZSBCT09MIHRvIGJpbmFyeSAqLwogICAgQk9PTF8yX0JJVChtb2RlLCBkYXRhKTsKICAgIC8qIHRyYW5zbGF0ZSBMUE9SVCB0byBoYXJkd2FyZSBwb3J0ICovCiAgICBod1BvcnQgPSBHVF9MUE9SVF8yX1BPUlQocG9ydCk7CgogICAgaWYoaHdQb3J0IDwgNCkKICAgIHsKICAgICAgICAvKiBjaGVjayBpZiBkZXZpY2Ugc3VwcG9ydHMgdGhpcyBmZWF0dXJlIGZvciB0aGlzIHBvcnQgKi8KICAgICAgICBpZiAoKElTX0lOX0RFVl9HUk9VUChkZXYsREVWX1RSQUlMRVJfUDUpKSB8fAogICAgICAgICAgICAoSVNfSU5fREVWX0dST1VQKGRldixERVZfVFJBSUxFUl9QNFA1KSkpCiAgICAgICAgewogICAgICAgICAgICBEQkdfSU5GTygoIkdUX05PVF9TVVBQT1JURUQuXG4iKSk7CiAgICAgICAgICAgIHJldHVybiBHVF9OT1RfU1VQUE9SVEVEOwogICAgICAgIH0KICAgIH0KICAgIGVsc2UgaWYoaHdQb3J0ID09IDQpCiAgICB7CiAgICAgICAgLyogY2hlY2sgaWYgZGV2aWNlIHN1cHBvcnRzIHRoaXMgZmVhdHVyZSBmb3IgdGhpcyBwb3J0Ki8KICAgICAgICBpZiAoSVNfSU5fREVWX0dST1VQKGRldixERVZfVFJBSUxFUl9QNSkpCiAgICAgICAgewogICAgICAgICAgICBEQkdfSU5GTygoIkdUX05PVF9TVVBQT1JURUQuXG4iKSk7CiAgICAgICAgICAgIHJldHVybiBHVF9OT1RfU1VQUE9SVEVEOwogICAgICAgIH0KICAgIH0KCiAgICAvKiBTZXQgdGhlIHRyYWlsZXIgbW9kZS4gICAgICAgICAgICAqLwogICAgcmV0VmFsID0gaHdTZXRQb3J0UmVnRmllbGQoZGV2LGh3UG9ydCwgUURfUkVHX1BPUlRfQ09OVFJPTCwxNCwxLGRhdGEpOwoKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBEQkdfSU5GTygoIk9LLlxuIikpOwogICAgfQogICAgcmV0dXJuIHJldFZhbDsKfQoKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdwcnRHZXRUcmFpbGVyTW9kZQoqCiogREVTQ1JJUFRJT046CiogICAgICAgVGhpcyByb3V0aW5lIGdldCB0aGUgZWdyZXNzIHRyYWlsZXIgbW9kZS4KKgoqIElOUFVUUzoKKiAgICAgICBwb3J0ICAtIHRoZSBsb2dpY2FsIHBvcnQgbnVtYmVyLgoqCiogT1VUUFVUUzoKKiAgICAgICBtb2RlIC0gR1RfVFJVRSBmb3IgYWRkIHRyYWlsZXIgb3IgR1RfRkFMU0Ugb3RoZXJ3aXNlCioKKiBSRVRVUk5TOgoqICAgICAgIEdUX09LICAgLSBvbiBzdWNjZXNzCiogICAgICAgR1RfRkFJTCAtIG9uIGVycm9yCioKKiBDT01NRU5UUzoKKgoqCiogR2FsVGlzOgoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBncHJ0R2V0VHJhaWxlck1vZGUKKAogICAgSU4gIEdUX1FEX0RFViAgKmRldiwKICAgIElOICBHVF9MUE9SVCAgIHBvcnQsCiAgICBPVVQgR1RfQk9PTCAgICAqbW9kZQopCnsKICAgIEdUX1UxNiAgICAgICAgICBkYXRhOwogICAgR1RfU1RBVFVTICAgICAgIHJldFZhbDsgICAgICAgICAvKiBGdW5jdGlvbnMgcmV0dXJuIHZhbHVlLiAgICAgICovCiAgICBHVF9VOCAgICAgICAgICAgaHdQb3J0OyAgICAgICAgIC8qIHRoZSBwaHlzaWNhbCBwb3J0IG51bWJlciAgICAgKi8KCiAgICBEQkdfSU5GTygoImdwcnRHZXRUcmFpbGVyTW9kZSBDYWxsZWQuXG4iKSk7CgogICAgLyogY2hlY2sgaWYgZGV2aWNlIHN1cHBvcnRzIHRoaXMgZmVhdHVyZSAqLwogICAgaWYgKCEoKElTX0lOX0RFVl9HUk9VUChkZXYsREVWX1RSQUlMRVIpKSB8fAogICAgICAgICAgKElTX0lOX0RFVl9HUk9VUChkZXYsREVWX1RSQUlMRVJfUDUpKSB8fAogICAgICAgICAgKElTX0lOX0RFVl9HUk9VUChkZXYsREVWX1RSQUlMRVJfUDRQNSkpKSkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX05PVF9TVVBQT1JURUQuXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CgogICAgLyogdHJhbnNsYXRlIExQT1JUIHRvIGhhcmR3YXJlIHBvcnQgKi8KICAgIGh3UG9ydCA9IEdUX0xQT1JUXzJfUE9SVChwb3J0KTsKCiAgICBpZihod1BvcnQgPCA0KQogICAgewogICAgICAgIC8qIGNoZWNrIGlmIGRldmljZSBzdXBwb3J0cyB0aGlzIGZlYXR1cmUgZm9yIHRoaXMgcG9ydCAqLwogICAgICAgIGlmICgoSVNfSU5fREVWX0dST1VQKGRldixERVZfVFJBSUxFUl9QNSkpIHx8CiAgICAgICAgICAgIChJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9UUkFJTEVSX1A0UDUpKSkKICAgICAgICB7CiAgICAgICAgICAgIERCR19JTkZPKCgiR1RfTk9UX1NVUFBPUlRFRC5cbiIpKTsKICAgICAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICAgICAgfQogICAgfQogICAgZWxzZSBpZihod1BvcnQgPT0gNCkKICAgIHsKICAgICAgICAvKiBjaGVjayBpZiBkZXZpY2Ugc3VwcG9ydHMgdGhpcyBmZWF0dXJlIGZvciB0aGlzIHBvcnQgKi8KICAgICAgICBpZiAoSVNfSU5fREVWX0dST1VQKGRldixERVZfVFJBSUxFUl9QNSkpCiAgICAgICAgewogICAgICAgICAgICBEQkdfSU5GTygoIkdUX05PVF9TVVBQT1JURUQuXG4iKSk7CiAgICAgICAgICAgIHJldHVybiBHVF9OT1RfU1VQUE9SVEVEOwogICAgICAgIH0KICAgIH0KCiAgICAvKiBHZXQgdGhlIFRyYWlsZXIgbW9kZS4gICAgICAgICAgICAqLwogICAgcmV0VmFsID0gaHdHZXRQb3J0UmVnRmllbGQoZGV2LGh3UG9ydCwgUURfUkVHX1BPUlRfQ09OVFJPTCwxNCwxLCZkYXRhKTsKICAgIC8qIHRyYW5zbGF0ZSBiaW5hcnkgdG8gQk9PTCAgKi8KICAgIEJJVF8yX0JPT0woZGF0YSwgKm1vZGUpOwogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgewogICAgICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIERCR19JTkZPKCgiT0suXG4iKSk7CiAgICB9CgogICAgcmV0dXJuIHJldFZhbDsKfQoKCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBncHJ0U2V0SW5ncmVzc01vZGUKKgoqIERFU0NSSVBUSU9OOgoqICAgICAgIFRoaXMgcm91dGluZSBzZXQgdGhlIGluZ3Jlc3MgbW9kZS4KKgoqIElOUFVUUzoKKiAgICAgICBwb3J0IC0gdGhlIGxvZ2ljYWwgcG9ydCBudW1iZXIuCiogICAgICAgbW9kZSAtIHRoZSBpbmdyZXNzIG1vZGUuCioKKiBPVVRQVVRTOgoqICAgICAgIE5vbmUuCioKKiBSRVRVUk5TOgoqICAgICAgIEdUX09LICAgLSBvbiBzdWNjZXNzCiogICAgICAgR1RfRkFJTCAtIG9uIGVycm9yCiogICAgICAgR1RfTk9UX1NVUFBPUlRFRCAtIGlmIGN1cnJlbnQgZGV2aWNlIGRvZXMgbm90IHN1cHBvcnQgdGhpcyBmZWF0dXJlLgoqCiogQ09NTUVOVFM6CioKKgoqIEdhbFRpczoKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3BydFNldEluZ3Jlc3NNb2RlCigKICAgIElOICBHVF9RRF9ERVYgICAgICAqZGV2LAogICAgSU4gR1RfTFBPUlQgICAgICAgIHBvcnQsCiAgICBJTiBHVF9JTkdSRVNTX01PREUgbW9kZQopCnsKICAgIEdUX1NUQVRVUyAgICAgICByZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwogICAgR1RfVTggICAgICAgICAgIGh3UG9ydDsgICAgICAgICAvKiB0aGUgcGh5c2ljYWwgcG9ydCBudW1iZXIgICAgICovCgogICAgREJHX0lORk8oKCJncHJ0U2V0SW5ncmVzc01vZGUgQ2FsbGVkLlxuIikpOwogICAgLyogdHJhbnNsYXRlIExQT1JUIHRvIGhhcmR3YXJlIHBvcnQgKi8KICAgIGh3UG9ydCA9IEdUX0xQT1JUXzJfUE9SVChwb3J0KTsKCiAgICAvKiBHaWdhYml0IFN3aXRjaCBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgc3RhdHVzLiAqLwogICAgaWYgKElTX0lOX0RFVl9HUk9VUChkZXYsREVWX0dJR0FCSVRfU1dJVENIKSkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX05PVF9TVVBQT1JURURcbiIpKTsKICAgICAgICByZXR1cm4gR1RfTk9UX1NVUFBPUlRFRDsKICAgIH0KCiAgICAvKiBjaGVjayBpZiBkZXZpY2Ugc3VwcG9ydHMgdGhpcyBmZWF0dXJlICovCiAgICBzd2l0Y2ggKG1vZGUpCiAgICB7CiAgICAgICAgY2FzZSAoR1RfVU5NT0RJRllfSU5HUkVTUyk6CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIChHVF9UUkFJTEVSX0lOR1JFU1MpOgogICAgICAgICAgICBpZiAoISgoSVNfSU5fREVWX0dST1VQKGRldixERVZfVFJBSUxFUikpIHx8CiAgICAgICAgICAgICAgICAgIChJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9UUkFJTEVSX1A1KSkgfHwKICAgICAgICAgICAgICAgICAgKElTX0lOX0RFVl9HUk9VUChkZXYsREVWX1RSQUlMRVJfUDRQNSkpKSkKICAgICB7CiAgICAgICAgICAgICAgICBEQkdfSU5GTygoIkdpdmVuIGluZ3Jlc3MgbW9kZSBpcyBub3Qgc3VwcG9ydGVkIGJ5IHRoaXMgZGV2aWNlXG4iKSk7CiAgICAgICAgICAgICAgICByZXR1cm4gR1RfTk9UX1NVUFBPUlRFRDsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSAoR1RfVU5UQUdHRURfSU5HUkVTUyk6CiAgICAgICAgICAgIGlmKCEoSVNfSU5fREVWX0dST1VQKGRldixERVZfVEFHR0lORykpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBEQkdfSU5GTygoIkdpdmVuIGluZ3Jlc3MgbW9kZSBpcyBub3Qgc3VwcG9ydGVkIGJ5IHRoaXMgZGV2aWNlXG4iKSk7CiAgICAgICAgICAgICAgICByZXR1cm4gR1RfTk9UX1NVUFBPUlRFRDsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSAoR1RfQ1BVUE9SVF9JTkdSRVNTKToKICAgICAgICAgICAgaWYoIShJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9JR01QX1NOT09QSU5HKSkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIERCR19JTkZPKCgiR2l2ZW4gaW5ncmVzcyBtb2RlIGlzIG5vdCBzdXBwb3J0ZWQgYnkgdGhpcyBkZXZpY2VcbiIpKTsKICAgICAgICAgICAgICAgIHJldHVybiBHVF9OT1RfU1VQUE9SVEVEOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZihod1BvcnQgIT0gR1RfTFBPUlRfMl9QT1JUKGRldi0+Y3B1UG9ydE51bSkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIERCR19JTkZPKCgiR2l2ZW4gaW5ncmVzcyBtb2RlIGlzIHN1cHBvcnRlZCBieSBDUFUgcG9ydCBvbmx5XG4iKSk7CiAgICAgICAgICAgICAgICByZXR1cm4gR1RfTk9UX1NVUFBPUlRFRDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAgICAgICAgICByZXR1cm4gR1RfRkFJTDsKICAgIH0KCiAgICAvKiBTZXQgdGhlIEluZ3Jlc3MgTW9kZS4gICAgICAgICovCiAgICByZXRWYWwgPSBod1NldFBvcnRSZWdGaWVsZChkZXYsaHdQb3J0LCBRRF9SRUdfUE9SVF9DT05UUk9MLDgsMiwoR1RfVTE2KW1vZGUpOwogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgewogICAgICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIERCR19JTkZPKCgiT0suXG4iKSk7CiAgICB9CgogICAgcmV0dXJuIHJldFZhbDsKfQoKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdwcnRHZXRJbmdyZXNzTW9kZQoqCiogREVTQ1JJUFRJT046CiogICAgICAgVGhpcyByb3V0aW5lIGdldCB0aGUgaW5ncmVzcyBtb2RlLgoqCiogSU5QVVRTOgoqICAgICAgIHBvcnQgIC0gdGhlIGxvZ2ljYWwgcG9ydCBudW1iZXIuCioKKiBPVVRQVVRTOgoqICAgICAgIG1vZGUgLSB0aGUgaW5ncmVzcyBtb2RlLgoqCiogUkVUVVJOUzoKKiAgICAgICBHVF9PSyAgIC0gb24gc3VjY2VzcwoqICAgICAgIEdUX0ZBSUwgLSBvbiBlcnJvcgoqICAgICAgIEdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqCioKKiBHYWxUaXM6CioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdwcnRHZXRJbmdyZXNzTW9kZQooCiAgICBJTiAgR1RfUURfREVWICAgICAgKmRldiwKICAgIElOICBHVF9MUE9SVCAgICAgICAgcG9ydCwKICAgIE9VVCBHVF9JTkdSRVNTX01PREUgKm1vZGUKKQp7CiAgICBHVF9TVEFUVVMgICAgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX1U4ICAgICAgICAgICBod1BvcnQ7ICAgICAgICAgLyogdGhlIHBoeXNpY2FsIHBvcnQgbnVtYmVyICAgICAqLwogICAgR1RfVTE2ICAgICAgICAgIGRhdGE7ICAgICAgICAgICAvKiB0byBrZWVwIHRoZSByZWFkIHZhbHZlICAgICAgICovCgogICAgREJHX0lORk8oKCJncHJ0R2V0SW5ncmVzc01vZGUgQ2FsbGVkLlxuIikpOwoKICAgIC8qIEdpZ2FiaXQgU3dpdGNoIGRvZXMgbm90IHN1cHBvcnQgdGhpcyBzdGF0dXMuICovCiAgICBpZiAoSVNfSU5fREVWX0dST1VQKGRldixERVZfR0lHQUJJVF9TV0lUQ0gpKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfTk9UX1NVUFBPUlRFRFxuIikpOwogICAgICAgIHJldHVybiBHVF9OT1RfU1VQUE9SVEVEOwogICAgfQoKICAgIC8qIHRyYW5zbGF0ZSBMUE9SVCB0byBoYXJkd2FyZSBwb3J0ICovCiAgICBod1BvcnQgPSBHVF9MUE9SVF8yX1BPUlQocG9ydCk7CiAgICAvKiBHZXQgdGhlIEluZ3Jlc3MgTW9kZS4gICAgICAgICAgICAqLwogICAgcmV0VmFsID0gaHdHZXRQb3J0UmVnRmllbGQoZGV2LGh3UG9ydCwgUURfUkVHX1BPUlRfQ09OVFJPTCwgOCwgMiwmZGF0YSk7CiAgICAqbW9kZSA9IGRhdGE7CiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJPSy5cbiIpKTsKICAgIH0KCiAgICByZXR1cm4gcmV0VmFsOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBncHJ0U2V0TWNSYXRlTGltaXQKKgoqIERFU0NSSVBUSU9OOgoqICAgICAgIFRoaXMgcm91dGluZSBzZXQgdGhlIHBvcnQgbXVsdGljYXN0IHJhdGUgbGltaXQuCioKKiBJTlBVVFM6CiogICAgICAgcG9ydCAtIHRoZSBsb2dpY2FsIHBvcnQgbnVtYmVyLgoqICAgICAgIHJhdGUgLSBHVF9UUlVFIHRvIEVuYWJsZSwgR1RfRkFMU0UgZm9yIG90aGVyd2lzZS4KKgoqIE9VVFBVVFM6CiogICAgICAgTm9uZS4KKgoqIFJFVFVSTlM6CiogICAgICAgR1RfT0sgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICBHVF9GQUlMIC0gb24gZXJyb3IKKgoqIENPTU1FTlRTOgoqCioKKiBHYWxUaXM6CioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdwcnRTZXRNY1JhdGVMaW1pdAooCiAgICBJTiAgR1RfUURfREVWICAgKmRldiwKICAgIElOIEdUX0xQT1JUICAgICBwb3J0LAogICAgSU4gR1RfTUNfUkFURSAgIHJhdGUKKQp7CiAgICBHVF9TVEFUVVMgICAgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX1U4ICAgICAgICAgICBod1BvcnQ7ICAgICAgICAgLyogdGhlIHBoeXNpY2FsIHBvcnQgbnVtYmVyICAgICAqLwoKICAgIERCR19JTkZPKCgiZ3BydFNldE1jUmF0ZUxpbWl0IENhbGxlZC5cbiIpKTsKCiAgICAvKiB0cmFuc2xhdGUgTFBPUlQgdG8gaGFyZHdhcmUgcG9ydCAqLwogICAgaHdQb3J0ID0gR1RfTFBPUlRfMl9QT1JUKHBvcnQpOwoKICAgIC8qIHRoaXMgZmVhdHVyZSBvbmx5IGV4aXRzIGluIDYwNTEsIDYwNTIsIGFuZCA2MDEyLiBJdCBpcyByZXBsYWNlIHdpdGgKICAgICAqIFJhdGUgQ290cm9sIFJlZ2lzdGVyIGluIHRoZSBmdXR1cmUgcHJvZHVjdHMsIHN0YXJ0aW5nIGZyb20gY2xpcHBlcnNoaXAKICAgICAqLwogICAgaWYoKHJldFZhbCA9IElTX1ZBTElEX0FQSV9DQUxMKGRldixod1BvcnQsIERFVl9NQ19SQVRFX1BFUkNFTlQpKSAhPSBHVF9PSykKICAgICAgICByZXR1cm4gcmV0VmFsOwoKICAgIC8qIFNldCB0aGUgbXVsdGljYXN0IHJhdGUgbGltaXQuICAgICovCiAgICByZXRWYWwgPSBod1NldFBvcnRSZWdGaWVsZChkZXYsaHdQb3J0LCBRRF9SRUdfUE9SVF9DT05UUk9MLDIsMiwoR1RfVTE2KXJhdGUpOwogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgewogICAgICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIERCR19JTkZPKCgiT0suXG4iKSk7CiAgICB9CgogICAgcmV0dXJuIHJldFZhbDsKfQoKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdwcnRHZXRNY1JhdGVMaW1pdAoqCiogREVTQ1JJUFRJT046CiogICAgICAgVGhpcyByb3V0aW5lIEdldCB0aGUgcG9ydCBtdWx0aWNhc3QgcmF0ZSBsaW1pdC4KKgoqIElOUFVUUzoKKiAgICAgICBwb3J0IC0gdGhlIGxvZ2ljYWwgcG9ydCBudW1iZXIuCioKKiBPVVRQVVRTOgoqICAgICAgIHJhdGUgLSBHVF9UUlVFIHRvIEVuYWJsZSwgR1RfRkFMU0UgZm9yIG90aGVyd2lzZS4KKgoqIFJFVFVSTlM6CiogICAgICAgR1RfT0sgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICBHVF9GQUlMIC0gb24gZXJyb3IKKgoqIENPTU1FTlRTOgoqCioKKiBHYWxUaXM6CioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdwcnRHZXRNY1JhdGVMaW1pdAooCiAgICBJTiAgR1RfUURfREVWICAgKmRldiwKICAgIElOICBHVF9MUE9SVCAgICBwb3J0LAogICAgT1VUIEdUX01DX1JBVEUgICpyYXRlCikKewogICAgR1RfU1RBVFVTICAgICAgIHJldFZhbDsgICAgICAgICAvKiBGdW5jdGlvbnMgcmV0dXJuIHZhbHVlLiAgICAgICovCiAgICBHVF9VOCAgICAgICAgICAgaHdQb3J0OyAgICAgICAgIC8qIHRoZSBwaHlzaWNhbCBwb3J0IG51bWJlciAgICAgKi8KICAgIEdUX1UxNiAgICAgICAgICBkYXRhOyAgICAgICAgICAgLyogdG8ga2VlcCB0aGUgcmVhZCBkYXRhICAgICAgICAqLwoKICAgIERCR19JTkZPKCgiZ3BydEdldE1jUmF0ZUxpbWl0IENhbGxlZC5cbiIpKTsKCiAgICAvKiB0cmFuc2xhdGUgTFBPUlQgdG8gaGFyZHdhcmUgcG9ydCAqLwogICAgaHdQb3J0ID0gR1RfTFBPUlRfMl9QT1JUKHBvcnQpOwoKICAgIC8qIHRoaXMgZmVhdHVyZSBvbmx5IGV4aXRzIGluIDYwNTEsIDYwNTIsIGFuZCA2MDEyLiBJdCBpcyByZXBsYWNlIHdpdGgKICAgICAqIFJhdGUgQ290cm9sIFJlZ2lzdGVyIGluIHRoZSBmdXR1cmUgcHJvZHVjdHMsIHN0YXJ0aW5nIGZyb20gY2xpcHBlcnNoaXAKICAgICAqLwogICAgaWYoKHJldFZhbCA9IElTX1ZBTElEX0FQSV9DQUxMKGRldixod1BvcnQsIERFVl9NQ19SQVRFX1BFUkNFTlQpKSAhPSBHVF9PSykKICAgICAgICByZXR1cm4gcmV0VmFsOwoKICAgIC8qIEdldCB0aGUgbXVsdGljYXN0IHJhdGUgbGltaXQuICAgICovCiAgICByZXRWYWwgPSBod0dldFBvcnRSZWdGaWVsZChkZXYsaHdQb3J0LCBRRF9SRUdfUE9SVF9DT05UUk9MLCAyLCAyLCZkYXRhKTsKICAgICpyYXRlID0gZGF0YTsKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBEQkdfSU5GTygoIk9LLlxuIikpOwogICAgfQogICAgcmV0dXJuIHJldFZhbDsKfQoKCi8qIHRoZSBmb2xsb3dpbmcgdHdvIEFQSXMgYXJlIGFkZGVkIHRvIHN1cHBvcnQgZnVsbHNhaWwgYW5kIGNsaXBwZXJzaGlwICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdwcnRTZXRJR01QU25vb3AKKgoqIERFU0NSSVBUSU9OOgoqICAgICAgICAgVGhpcyByb3V0aW5lIHNldCB0aGUgSUdNUCBTbm9vcC4gV2hlbiBzZXQgdG8gb25lIGFuZCB0aGlzIHBvcnQgcmVjZWl2ZXMKKiAgICAgICAgSUdNUCBmcmFtZSwgdGhlIGZyYW1lIGlzIHN3aXRjaGVkIHRvIHRoZSBDUFUgcG9ydCwgb3ZlcnJpZGluZyBhbGwgb3RoZXIKKiAgICAgICAgc3dpdGNoaW5nIGRlY2lzaW9ucywgd2l0aCBleGNlcHRpb24gZm9yIENQVSdzIFRyYWlsZXIuCiogICAgICAgIENQVSBwb3J0IGlzIGRldGVybWluZWQgYnkgdGhlIEluZ3Jlc3MgTW9kZSBiaXRzLiBBIHBvcnQgaXMgY29uc2lkZXJlZAoqICAgICAgICB0aGUgQ1BVIHBvcnQgaWYgaXRzIEluZ3Jlc3MgTW9kZSBhcmUgZWl0aGVyIEdUX1RSQUlMRVJfSU5HUkVTUyBvcgoqICAgICAgICBHVF9DUFVQT1JUX0lOR1JFU1MuCioKKiBJTlBVVFM6CiogICAgICAgIHBvcnQgLSB0aGUgbG9naWNhbCBwb3J0IG51bWJlci4KKiAgICAgICAgbW9kZSAtIEdUX1RSVUUgZm9yIElHTVAgU25vb3Agb3IgR1RfRkFMU0Ugb3RoZXJ3aXNlCioKKiBPVVRQVVRTOgoqICAgICAgICBOb25lLgoqCiogUkVUVVJOUzoKKiAgICAgICAgR1RfT0sgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICAgR1RfRkFJTCAtIG9uIGVycm9yCioKKiBDT01NRU5UUzoKKgoqIEdhbFRpczoKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3BydFNldElHTVBTbm9vcAooCiAgICBJTiAgR1RfUURfREVWICAgKmRldiwKICAgIElOIEdUX0xQT1JUICAgICBwb3J0LAogICAgSU4gR1RfQk9PTCAgICAgIG1vZGUKKQp7CiAgICBHVF9VMTYgICAgICAgICAgZGF0YTsKICAgIEdUX1NUQVRVUyAgICAgICByZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwogICAgR1RfVTggICAgICAgICAgIGh3UG9ydDsgICAgICAgICAvKiB0aGUgcGh5c2ljYWwgcG9ydCBudW1iZXIgICAgICovCgogICAgREJHX0lORk8oKCJncHJ0U2V0SUdNUFNub29wIENhbGxlZC5cbiIpKTsKCiAgICAvKiB0cmFuc2xhdGUgTFBPUlQgdG8gaGFyZHdhcmUgcG9ydCAqLwogICAgaHdQb3J0ID0gR1RfTFBPUlRfMl9QT1JUKHBvcnQpOwoKICAgIC8qIGNoZWNrIGlmIGRldmljZSBzdXBwb3J0cyB0aGlzIGZlYXR1cmUgKi8KICAgIGlmKChyZXRWYWwgPSBJU19WQUxJRF9BUElfQ0FMTChkZXYsaHdQb3J0LCBERVZfSUdNUF9TTk9PUElORykpICE9IEdUX09LKQogICAgICByZXR1cm4gcmV0VmFsOwoKICAgIC8qIHRyYW5zbGF0ZSBCT09MIHRvIGJpbmFyeSAqLwogICAgQk9PTF8yX0JJVChtb2RlLCBkYXRhKTsKCiAgICAvKiBTZXQgdGhlIElHTVAgU25vb3BpbmcgbW9kZS4gICAgICAgICAgICAqLwogICAgcmV0VmFsID0gaHdTZXRQb3J0UmVnRmllbGQoZGV2LGh3UG9ydCwgUURfUkVHX1BPUlRfQ09OVFJPTCwxMCwxLCBkYXRhKTsKCiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJPSy5cbiIpKTsKICAgIH0KICAgIHJldHVybiByZXRWYWw7Cn0KCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBncHJ0R2V0SUdNUFNub29wCioKKiBERVNDUklQVElPTjoKKiAgICAgICBUaGlzIHJvdXRpbmUgZ2V0IHRoZSBJR01QIFNub29wIG1vZGUuCioKKiBJTlBVVFM6CiogICAgICAgcG9ydCAgLSB0aGUgbG9naWNhbCBwb3J0IG51bWJlci4KKgoqIE9VVFBVVFM6CiogICAgICAgbW9kZSAtIEdUX1RSVUU6IElHTVAgU25vb3AgZW5hYmxlZAoqICAgICAgICAgICBHVF9GQUxTRSBvdGhlcndpc2UKKgoqIFJFVFVSTlM6CiogICAgICAgR1RfT0sgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICBHVF9GQUlMIC0gb24gZXJyb3IKKgoqIENPTU1FTlRTOgoqCiogR2FsVGlzOgoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBncHJ0R2V0SUdNUFNub29wCigKICAgIElOICBHVF9RRF9ERVYgICAqZGV2LAogICAgSU4gIEdUX0xQT1JUICAgIHBvcnQsCiAgICBPVVQgR1RfQk9PTCAgICAgKm1vZGUKKQp7CiAgICBHVF9TVEFUVVMgICAgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX1U4ICAgICAgICAgICBod1BvcnQ7ICAgICAgICAgLyogdGhlIHBoeXNpY2FsIHBvcnQgbnVtYmVyICAgICAqLwogICAgR1RfVTE2ICAgICAgICAgIGRhdGE7ICAgICAgICAgICAvKiB0byBrZWVwIHRoZSByZWFkIHZhbHZlICAgICAgICovCgogICAgREJHX0lORk8oKCJncHJ0R2V0SUdNUFNub29wIENhbGxlZC5cbiIpKTsKCiAgICAvKiB0cmFuc2xhdGUgTFBPUlQgdG8gaGFyZHdhcmUgcG9ydCAqLwogICAgaHdQb3J0ID0gR1RfTFBPUlRfMl9QT1JUKHBvcnQpOwoKICAgIC8qIGNoZWNrIGlmIGRldmljZSBzdXBwb3J0cyB0aGlzIGZlYXR1cmUgKi8KICAgIGlmKChyZXRWYWwgPSBJU19WQUxJRF9BUElfQ0FMTChkZXYsaHdQb3J0LCBERVZfSUdNUF9TTk9PUElORykpICE9IEdUX09LKQogICAgICByZXR1cm4gcmV0VmFsOwoKICAgIC8qIEdldCB0aGUgSW5ncmVzcyBNb2RlLiAgICAgICAgICAgICovCiAgICByZXRWYWwgPSBod0dldFBvcnRSZWdGaWVsZChkZXYsaHdQb3J0LCBRRF9SRUdfUE9SVF9DT05UUk9MLCAxMCwgMSwgJmRhdGEpOwoKICAgIC8qIHRyYW5zbGF0ZSBiaW5hcnkgdG8gQk9PTCAgKi8KICAgIEJJVF8yX0JPT0woZGF0YSwgKm1vZGUpOwogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgewogICAgICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIERCR19JTkZPKCgiT0suXG4iKSk7CiAgICB9CgogICAgcmV0dXJuIHJldFZhbDsKfQoKLyogdGhlIGZvbGxvd2luZyB0d28gQVBJcyBhcmUgYWRkZWQgdG8gc3VwcG9ydCBjbGlwcGVyc2hpcCAqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBncHJ0U2V0SGVhZGVyTW9kZQoqCiogREVTQ1JJUFRJT046CiogICAgICAgVGhpcyByb3V0aW5lIHNldCBpbmdyZXNzIGFuZCBlZ3Jlc3MgaGVhZGVyIG1vZGUgb2YgYSBzd2l0Y2ggcG9ydC4KKgoqIElOUFVUUzoKKiAgICAgICBwb3J0IC0gdGhlIGxvZ2ljYWwgcG9ydCBudW1iZXIuCiogICAgICAgbW9kZSAtIEdUX1RSVUUgZm9yIGhlYWRlciBtb2RlICBvciBHVF9GQUxTRSBvdGhlcndpc2UKKgoqIE9VVFBVVFM6CiogICAgICAgTm9uZS4KKgoqIFJFVFVSTlM6CiogICAgICAgR1RfT0sgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICBHVF9GQUlMIC0gb24gZXJyb3IKKgoqIENPTU1FTlRTOgoqCiogR2FsVGlzOgoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBncHJ0U2V0SGVhZGVyTW9kZQooCiAgICBJTiAgR1RfUURfREVWICAgKmRldiwKICAgIElOIEdUX0xQT1JUICAgICBwb3J0LAogICAgSU4gR1RfQk9PTCAgICAgIG1vZGUKKQp7CiAgICBHVF9VMTYgICAgICAgICAgZGF0YTsKICAgIEdUX1NUQVRVUyAgICAgICByZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwogICAgR1RfVTggICAgICAgICAgIGh3UG9ydDsgICAgICAgICAvKiB0aGUgcGh5c2ljYWwgcG9ydCBudW1iZXIgICAgICovCgogICAgREJHX0lORk8oKCJncHJ0U2V0SGVhZGVyTW9kZSBDYWxsZWQuXG4iKSk7CgogICAgLyogb25seSBkZXZpY2VzIGJleW9uZCBxdWFydGVyZGVjayAoNjA1MikgaGFzIHRoaXMgZmVhdHVyZSAqLwogICAgLyogRnVsbHNhaWwgKERFVl9RRF84OEU2NTAyKSBpcyBhbiBleGNlcHRpb24sIGFuZCBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZSAqLwogICAgaWYoSVNfVkFMSURfQVBJX0NBTEwoZGV2LHBvcnQsIERFVl9IRUFERVJ8REVWX0hFQURFUl9QNXxERVZfSEVBREVSX1A0UDUpICE9IEdUX09LKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfTk9UX1NVUFBPUlRFRC5cbiIpKTsKICAgICAgICByZXR1cm4gR1RfTk9UX1NVUFBPUlRFRDsKICAgIH0KCiAgICAvKiB0cmFuc2xhdGUgQk9PTCB0byBiaW5hcnkgKi8KICAgIEJPT0xfMl9CSVQobW9kZSwgZGF0YSk7CgogICAgLyogdHJhbnNsYXRlIExQT1JUIHRvIGhhcmR3YXJlIHBvcnQgKi8KICAgIGh3UG9ydCA9IEdUX0xQT1JUXzJfUE9SVChwb3J0KTsKCiAgICBpZihod1BvcnQgPCA0KQogICAgewogICAgICAgIGlmICgoSVNfSU5fREVWX0dST1VQKGRldixERVZfVFJBSUxFUl9QNSkpIHx8CiAgICAgICAgICAgIChJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9UUkFJTEVSX1A0UDUpKSkKICAgICAgICB7CiAgICAgICAgICAgIERCR19JTkZPKCgiR1RfTk9UX1NVUFBPUlRFRC5cbiIpKTsKICAgICAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICAgICAgfQogICAgfQogICAgZWxzZSBpZihod1BvcnQgPT0gNCkKICAgIHsKICAgICAgICBpZiAoSVNfSU5fREVWX0dST1VQKGRldixERVZfSEVBREVSX1A1KSkKICAgICAgICB7CiAgICAgICAgICAgIERCR19JTkZPKCgiR1RfTk9UX1NVUFBPUlRFRC5cbiIpKTsKICAgICAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICAgICAgfQogICAgfQoKICAgIC8qIFNldCB0aGUgaGVhZGVyIG1vZGUuICAgICAgICAgICAgKi8KICAgIHJldFZhbCA9IGh3U2V0UG9ydFJlZ0ZpZWxkKGRldixod1BvcnQsIFFEX1JFR19QT1JUX0NPTlRST0wsMTEsMSwgZGF0YSk7CgogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgewogICAgICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIERCR19JTkZPKCgiT0suXG4iKSk7CiAgICB9CiAgICByZXR1cm4gcmV0VmFsOwp9CgoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3BydEdldEhlYWRlck1vZGUKKgoqIERFU0NSSVBUSU9OOgoqICAgICAgIFRoaXMgcm91dGluZSBnZXRzIGluZ3Jlc3MgYW5kIGVncmVzcyBoZWFkZXIgbW9kZSBvZiBhIHN3aXRjaCBwb3J0LgoqCiogSU5QVVRTOgoqICAgICAgIHBvcnQgIC0gdGhlIGxvZ2ljYWwgcG9ydCBudW1iZXIuCioKKiBPVVRQVVRTOgoqICAgICAgIG1vZGUgLSBHVF9UUlVFOiBoZWFkZXIgbW9kZSBlbmFibGVkCiogICAgICAgICAgIEdUX0ZBTFNFIG90aGVyd2lzZQoqCiogUkVUVVJOUzoKKiAgICAgICBHVF9PSyAgIC0gb24gc3VjY2VzcwoqICAgICAgIEdUX0ZBSUwgLSBvbiBlcnJvcgoqCiogQ09NTUVOVFM6CioKKiBHYWxUaXM6CioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdwcnRHZXRIZWFkZXJNb2RlCigKICAgIElOICBHVF9RRF9ERVYgICAqZGV2LAogICAgSU4gIEdUX0xQT1JUICAgIHBvcnQsCiAgICBPVVQgR1RfQk9PTCAgICAgKm1vZGUKKQp7CiAgICBHVF9TVEFUVVMgICAgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX1U4ICAgICAgICAgICBod1BvcnQ7ICAgICAgICAgLyogdGhlIHBoeXNpY2FsIHBvcnQgbnVtYmVyICAgICAqLwogICAgR1RfVTE2ICAgICAgICAgIGRhdGE7ICAgICAgICAgICAvKiB0byBrZWVwIHRoZSByZWFkIHZhbHZlICAgICAgICovCgogICAgREJHX0lORk8oKCJncHJ0R2V0SGVhZGVyTW9kZSBDYWxsZWQuXG4iKSk7CgogICAgLyogb25seSBkZXZpY2VzIGJleW9uZCBxdWFydGVyZGVjayAoNjA1MikgaGFzIHRoaXMgZmVhdHVyZSAqLwogICAgLyogRnVsbHNhaWwgKERFVl9RRF84OEU2MDIpIGlzIGFuIGV4Y2VwdGlvbiwgYW5kIGRvZXMgbm90IHN1cHBvcnQgdGhpcyBmZWF0dXJlICovCiAgICBpZihJU19WQUxJRF9BUElfQ0FMTChkZXYscG9ydCwgREVWX0hFQURFUnxERVZfSEVBREVSX1A1fERFVl9IRUFERVJfUDRQNSkgIT0gR1RfT0spCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVELlxuIikpOwogICAgICAgIHJldHVybiBHVF9OT1RfU1VQUE9SVEVEOwogICAgfQoKICAgIC8qIHRyYW5zbGF0ZSBMUE9SVCB0byBoYXJkd2FyZSBwb3J0ICovCiAgICBod1BvcnQgPSBHVF9MUE9SVF8yX1BPUlQocG9ydCk7CgogICAgaWYoaHdQb3J0IDwgNCkKICAgIHsKICAgICAgICBpZiAoKElTX0lOX0RFVl9HUk9VUChkZXYsREVWX1RSQUlMRVJfUDUpKSB8fAogICAgICAgICAgICAoSVNfSU5fREVWX0dST1VQKGRldixERVZfVFJBSUxFUl9QNFA1KSkpCiAgICAgICAgewogICAgICAgICAgICBEQkdfSU5GTygoIkdUX05PVF9TVVBQT1JURUQuXG4iKSk7CiAgICAgICAgICAgIHJldHVybiBHVF9OT1RfU1VQUE9SVEVEOwogICAgICAgIH0KICAgIH0KICAgIGVsc2UgaWYoaHdQb3J0ID09IDQpCiAgICB7CiAgICAgICAgaWYgKElTX0lOX0RFVl9HUk9VUChkZXYsREVWX0hFQURFUl9QNSkpCiAgICAgICAgewogICAgICAgICAgICBEQkdfSU5GTygoIkdUX05PVF9TVVBQT1JURUQuXG4iKSk7CiAgICAgICAgICAgIHJldHVybiBHVF9OT1RfU1VQUE9SVEVEOwogICAgICAgIH0KICAgIH0KCiAgICAvKiBHZXQgdGhlIEhlYWRlciBNb2RlLiAgICAgICAgICAgICovCiAgICByZXRWYWwgPSBod0dldFBvcnRSZWdGaWVsZChkZXYsaHdQb3J0LCBRRF9SRUdfUE9SVF9DT05UUk9MLCAxMSwgMSwgJmRhdGEpOwoKICAgIC8qIHRyYW5zbGF0ZSBiaW5hcnkgdG8gQk9PTCAgKi8KICAgIEJJVF8yX0JPT0woZGF0YSwgKm1vZGUpOwogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgewogICAgICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIERCR19JTkZPKCgiT0suXG4iKSk7CiAgICB9CgogICAgcmV0dXJuIHJldFZhbDsKfQoKLyogdGhlIGZvbGxvd2luZyBmb3VyIEFQSXMgYXJlIGFkZGVkIHRvIHN1cHBvcnQgT2N0YW5lICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdwcnRTZXRQcm90ZWN0ZWRNb2RlCioKKiBERVNDUklQVElPTjoKKiAgICAgICBUaGlzIHJvdXRpbmUgc2V0IHByb3RlY3RlZCBtb2RlIG9mIGEgc3dpdGNoIHBvcnQuCiogICAgICAgIFdoZW4gdGhpcyBtb2RlIGlzIHNldCB0byBHVF9UUlVFLCBmcmFtZXMgYXJlIGFsbG93ZWQgdG8gZWdyZXNzIHBvcnQKKiAgICAgICAgZGVmaW5lZCBieSB0aGUgODAyLjFRIFZMQU4gbWVtYmVyc2hpcCBmb3IgdGhlIGZyYW1lJ3MgVklEICdBTkQnCiogICAgICAgIGJ5IHRoZSBwb3J0J3MgVkxBTlRhYmxlIGlmIDgwMi4xUSBpcyBlbmFibGVkIG9uIHRoZSBwb3J0LiBCb3RoIG11c3QKKiAgICAgICAgYWxsb3cgdGhlIGZyYW1lIHRvIEVncmVzcy4KKgoqIElOUFVUUzoKKiAgICAgICBwb3J0IC0gdGhlIGxvZ2ljYWwgcG9ydCBudW1iZXIuCiogICAgICAgbW9kZSAtIEdUX1RSVUUgZm9yIHByb3RlY3RlZCBtb2RlIG9yIEdUX0ZBTFNFIG90aGVyd2lzZQoqCiogT1VUUFVUUzoKKiAgICAgICBOb25lLgoqCiogUkVUVVJOUzoKKiAgICAgICBHVF9PSyAgIC0gb24gc3VjY2VzcwoqICAgICAgIEdUX0ZBSUwgLSBvbiBlcnJvcgoqCiogQ09NTUVOVFM6CioKKiBHYWxUaXM6CioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdwcnRTZXRQcm90ZWN0ZWRNb2RlCigKICAgIElOICBHVF9RRF9ERVYgICAqZGV2LAogICAgSU4gR1RfTFBPUlQgICAgIHBvcnQsCiAgICBJTiBHVF9CT09MICAgICAgbW9kZQopCnsKICAgIEdUX1UxNiAgICAgICAgICBkYXRhOwogICAgR1RfU1RBVFVTICAgICAgIHJldFZhbDsgICAgICAgICAvKiBGdW5jdGlvbnMgcmV0dXJuIHZhbHVlLiAgICAgICovCiAgICBHVF9VOCAgICAgICAgICAgaHdQb3J0OyAgICAgICAgIC8qIHRoZSBwaHlzaWNhbCBwb3J0IG51bWJlciAgICAgKi8KCiAgICBEQkdfSU5GTygoImdwcnRTZXRQcm90ZWN0ZWRNb2RlIENhbGxlZC5cbiIpKTsKCiAgICAvKiBDaGVjayBpZiB0aGlzIGZlYXR1cmUgaXMgc3VwcG9ydGVkICovCiAgICBpZihJU19WQUxJRF9BUElfQ0FMTChkZXYscG9ydCwgREVWX1BPUlRfU0VDVVJJVFkpICE9IEdUX09LKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfTk9UX1NVUFBPUlRFRC5cbiIpKTsKICAgICAgICByZXR1cm4gR1RfTk9UX1NVUFBPUlRFRDsKICAgIH0KCiAgICBpZiAoSVNfSU5fREVWX0dST1VQKGRldixERVZfQ1JPU1NfQ0hJUF9WTEFOKSkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX05PVF9TVVBQT1JURURcbiIpKTsKICAgICAgICByZXR1cm4gR1RfTk9UX1NVUFBPUlRFRDsKICAgIH0KCiAgICAvKiB0cmFuc2xhdGUgQk9PTCB0byBiaW5hcnkgKi8KICAgIEJPT0xfMl9CSVQobW9kZSwgZGF0YSk7CgogICAgLyogdHJhbnNsYXRlIExQT1JUIHRvIGhhcmR3YXJlIHBvcnQgKi8KICAgIGh3UG9ydCA9IEdUX0xQT1JUXzJfUE9SVChwb3J0KTsKCiAgICAvKiBTZXQgdGhlIHByb3RlY3RlZCBtb2RlLiAgICAgICAgICAgICovCiAgICByZXRWYWwgPSBod1NldFBvcnRSZWdGaWVsZChkZXYsaHdQb3J0LCBRRF9SRUdfUE9SVF9DT05UUk9MLDMsMSwgZGF0YSk7CgogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgewogICAgICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIERCR19JTkZPKCgiT0suXG4iKSk7CiAgICB9CiAgICByZXR1cm4gcmV0VmFsOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdwcnRHZXRQcm90ZWN0ZWRNb2RlCioKKiBERVNDUklQVElPTjoKKiAgICAgICBUaGlzIHJvdXRpbmUgZ2V0cyBwcm90ZWN0ZWQgbW9kZSBvZiBhIHN3aXRjaCBwb3J0LgoqICAgICAgICBXaGVuIHRoaXMgbW9kZSBpcyBzZXQgdG8gR1RfVFJVRSwgZnJhbWVzIGFyZSBhbGxvd2VkIHRvIGVncmVzcyBwb3J0CiogICAgICAgIGRlZmluZWQgYnkgdGhlIDgwMi4xUSBWTEFOIG1lbWJlcnNoaXAgZm9yIHRoZSBmcmFtZSdzIFZJRCAnQU5EJwoqICAgICAgICBieSB0aGUgcG9ydCdzIFZMQU5UYWJsZSBpZiA4MDIuMVEgaXMgZW5hYmxlZCBvbiB0aGUgcG9ydC4gQm90aCBtdXN0CiogICAgICAgIGFsbG93IHRoZSBmcmFtZSB0byBFZ3Jlc3MuCioKKiBJTlBVVFM6CiogICAgICAgcG9ydCAgLSB0aGUgbG9naWNhbCBwb3J0IG51bWJlci4KKgoqIE9VVFBVVFM6CiogICAgICAgbW9kZSAtIEdUX1RSVUU6IGhlYWRlciBtb2RlIGVuYWJsZWQKKiAgICAgICAgICAgR1RfRkFMU0Ugb3RoZXJ3aXNlCioKKiBSRVRVUk5TOgoqICAgICAgIEdUX09LICAgLSBvbiBzdWNjZXNzCiogICAgICAgR1RfRkFJTCAtIG9uIGVycm9yCioKKiBDT01NRU5UUzoKKgoqIEdhbFRpczoKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3BydEdldFByb3RlY3RlZE1vZGUKKAogICAgSU4gIEdUX1FEX0RFViAgICpkZXYsCiAgICBJTiAgR1RfTFBPUlQgICAgcG9ydCwKICAgIE9VVCBHVF9CT09MICAgICAqbW9kZQopCnsKICAgIEdUX1NUQVRVUyAgICAgICByZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwogICAgR1RfVTggICAgICAgICAgIGh3UG9ydDsgICAgICAgICAvKiB0aGUgcGh5c2ljYWwgcG9ydCBudW1iZXIgICAgICovCiAgICBHVF9VMTYgICAgICAgICAgZGF0YTsgICAgICAgICAgIC8qIHRvIGtlZXAgdGhlIHJlYWQgdmFsdmUgICAgICAgKi8KCiAgICBEQkdfSU5GTygoImdwcnRHZXRQcm90ZWN0ZWRNb2RlIENhbGxlZC5cbiIpKTsKCiAgICBpZihJU19WQUxJRF9BUElfQ0FMTChkZXYscG9ydCwgREVWX1BPUlRfU0VDVVJJVFkpICE9IEdUX09LKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfTk9UX1NVUFBPUlRFRC5cbiIpKTsKICAgICAgICByZXR1cm4gR1RfTk9UX1NVUFBPUlRFRDsKICAgIH0KCiAgICBpZiAoSVNfSU5fREVWX0dST1VQKGRldixERVZfQ1JPU1NfQ0hJUF9WTEFOKSkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX05PVF9TVVBQT1JURURcbiIpKTsKICAgICAgICByZXR1cm4gR1RfTk9UX1NVUFBPUlRFRDsKICAgIH0KCiAgICAvKiB0cmFuc2xhdGUgTFBPUlQgdG8gaGFyZHdhcmUgcG9ydCAqLwogICAgaHdQb3J0ID0gR1RfTFBPUlRfMl9QT1JUKHBvcnQpOwoKICAgIC8qIEdldCB0aGUgcHJvdGVjdGVkIE1vZGUuICAgICAgICAgICAgKi8KICAgIHJldFZhbCA9IGh3R2V0UG9ydFJlZ0ZpZWxkKGRldixod1BvcnQsIFFEX1JFR19QT1JUX0NPTlRST0wsIDMsIDEsICZkYXRhKTsKCiAgICAvKiB0cmFuc2xhdGUgYmluYXJ5IHRvIEJPT0wgICovCiAgICBCSVRfMl9CT09MKGRhdGEsICptb2RlKTsKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBEQkdfSU5GTygoIk9LLlxuIikpOwogICAgfQoKICAgIHJldHVybiByZXRWYWw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3BydFNldEZvcndhcmRVbmtub3duCioKKiBERVNDUklQVElPTjoKKiAgICAgICBUaGlzIHJvdXRpbmUgc2V0IEZvcndhcmQgVW5rbm93biBtb2RlIG9mIGEgc3dpdGNoIHBvcnQuCiogICAgICAgIFdoZW4gdGhpcyBtb2RlIGlzIHNldCB0byBHVF9UUlVFLCBub3JtYWwgc3dpdGNoIG9wZXJhdGlvbiBvY2N1cnMuCiogICAgICAgIFdoZW4gdGhpcyBtb2RlIGlzIHNldCB0byBHVF9GQUxTRSwgdW5pY2FzdCBmcmFtZSB3aXRoIHVua25vd24gREEgYWRkcmVzc2VzCiogICAgICAgIHdpbGwgbm90IGVncmVzcyBvdXQgdGhpcyBwb3J0LgoqCiogSU5QVVRTOgoqICAgICAgIHBvcnQgLSB0aGUgbG9naWNhbCBwb3J0IG51bWJlci4KKiAgICAgICBtb2RlIC0gR1RfVFJVRSBmb3IgcHJvdGVjdGVkIG1vZGUgb3IgR1RfRkFMU0Ugb3RoZXJ3aXNlCioKKiBPVVRQVVRTOgoqICAgICAgIE5vbmUuCioKKiBSRVRVUk5TOgoqICAgICAgIEdUX09LICAgLSBvbiBzdWNjZXNzCiogICAgICAgR1RfRkFJTCAtIG9uIGVycm9yCioKKiBDT01NRU5UUzoKKgoqIEdhbFRpczoKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3BydFNldEZvcndhcmRVbmtub3duCigKICAgIElOICBHVF9RRF9ERVYgICAqZGV2LAogICAgSU4gR1RfTFBPUlQgICAgIHBvcnQsCiAgICBJTiBHVF9CT09MICAgICAgbW9kZQopCnsKICAgIEdUX1UxNiAgICAgICAgICBkYXRhOwogICAgR1RfU1RBVFVTICAgICAgIHJldFZhbDsgICAgICAgICAvKiBGdW5jdGlvbnMgcmV0dXJuIHZhbHVlLiAgICAgICovCiAgICBHVF9VOCAgICAgICAgICAgaHdQb3J0OyAgICAgICAgIC8qIHRoZSBwaHlzaWNhbCBwb3J0IG51bWJlciAgICAgKi8KCiAgICBEQkdfSU5GTygoImdwcnRTZXRGb3J3YXJkVW5rbm93biBDYWxsZWQuXG4iKSk7CgogICAgaWYoSVNfVkFMSURfQVBJX0NBTEwoZGV2LHBvcnQsIERFVl9QT1JUX1NFQ1VSSVRZfERFVl9FR1JFU1NfRkxPT0QpICE9IEdUX09LKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfTk9UX1NVUFBPUlRFRC5cbiIpKTsKICAgICAgICByZXR1cm4gR1RfTk9UX1NVUFBPUlRFRDsKICAgIH0KCiAgICAvKiB0cmFuc2xhdGUgQk9PTCB0byBiaW5hcnkgKi8KICAgIEJPT0xfMl9CSVQobW9kZSwgZGF0YSk7CgogICAgLyogdHJhbnNsYXRlIExQT1JUIHRvIGhhcmR3YXJlIHBvcnQgKi8KICAgIGh3UG9ydCA9IEdUX0xQT1JUXzJfUE9SVChwb3J0KTsKCiAgICAvKiBTZXQgdGhlIGZvcndhcmQgdW5rbm93biBtb2RlLiAgICAgICAgICAgICovCiAgICByZXRWYWwgPSBod1NldFBvcnRSZWdGaWVsZChkZXYsaHdQb3J0LCBRRF9SRUdfUE9SVF9DT05UUk9MLDIsMSwgZGF0YSk7CgogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgewogICAgICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIERCR19JTkZPKCgiT0suXG4iKSk7CiAgICB9CiAgICByZXR1cm4gcmV0VmFsOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdwcnRHZXRGb3J3YXJkVW5rbm93bgoqCiogREVTQ1JJUFRJT046CiogICAgICAgVGhpcyByb3V0aW5lIGdldHMgRm9yd2FyZCBVbmtub3duIG1vZGUgb2YgYSBzd2l0Y2ggcG9ydC4KKiAgICAgICAgV2hlbiB0aGlzIG1vZGUgaXMgc2V0IHRvIEdUX1RSVUUsIG5vcm1hbCBzd2l0Y2ggb3BlcmF0aW9uIG9jY3Vycy4KKiAgICAgICAgV2hlbiB0aGlzIG1vZGUgaXMgc2V0IHRvIEdUX0ZBTFNFLCB1bmljYXN0IGZyYW1lIHdpdGggdW5rbm93biBEQSBhZGRyZXNzZXMKKiAgICAgICAgd2lsbCBub3QgZWdyZXNzIG91dCB0aGlzIHBvcnQuCioKKiBJTlBVVFM6CiogICAgICAgcG9ydCAgLSB0aGUgbG9naWNhbCBwb3J0IG51bWJlci4KKgoqIE9VVFBVVFM6CiogICAgICAgbW9kZSAtIEdUX1RSVUU6IGhlYWRlciBtb2RlIGVuYWJsZWQKKiAgICAgICAgICAgR1RfRkFMU0Ugb3RoZXJ3aXNlCioKKiBSRVRVUk5TOgoqICAgICAgIEdUX09LICAgLSBvbiBzdWNjZXNzCiogICAgICAgR1RfRkFJTCAtIG9uIGVycm9yCioKKiBDT01NRU5UUzoKKgoqIEdhbFRpczoKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3BydEdldEZvcndhcmRVbmtub3duCigKICAgIElOICBHVF9RRF9ERVYgICAqZGV2LAogICAgSU4gIEdUX0xQT1JUICAgIHBvcnQsCiAgICBPVVQgR1RfQk9PTCAgICAgKm1vZGUKKQp7CiAgICBHVF9TVEFUVVMgICAgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX1U4ICAgICAgICAgICBod1BvcnQ7ICAgICAgICAgLyogdGhlIHBoeXNpY2FsIHBvcnQgbnVtYmVyICAgICAqLwogICAgR1RfVTE2ICAgICAgICAgIGRhdGE7ICAgICAgICAgICAvKiB0byBrZWVwIHRoZSByZWFkIHZhbHZlICAgICAgICovCgogICAgREJHX0lORk8oKCJncHJ0R2V0Rm9yd2FyZFVua25vd24gQ2FsbGVkLlxuIikpOwoKICAgIGlmKElTX1ZBTElEX0FQSV9DQUxMKGRldixwb3J0LCBERVZfUE9SVF9TRUNVUklUWXxERVZfRUdSRVNTX0ZMT09EKSAhPSBHVF9PSykKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX05PVF9TVVBQT1JURUQuXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CgogICAgLyogdHJhbnNsYXRlIExQT1JUIHRvIGhhcmR3YXJlIHBvcnQgKi8KICAgIGh3UG9ydCA9IEdUX0xQT1JUXzJfUE9SVChwb3J0KTsKCiAgICAvKiBHZXQgdGhlIGZvcndhcmQgdW5rbm93biBNb2RlLiAgICAgICAgICAgICovCiAgICByZXRWYWwgPSBod0dldFBvcnRSZWdGaWVsZChkZXYsaHdQb3J0LCBRRF9SRUdfUE9SVF9DT05UUk9MLCAyLCAxLCAmZGF0YSk7CgogICAgLyogdHJhbnNsYXRlIGJpbmFyeSB0byBCT09MICAqLwogICAgQklUXzJfQk9PTChkYXRhLCAqbW9kZSk7CiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJPSy5cbiIpKTsKICAgIH0KCiAgICByZXR1cm4gcmV0VmFsOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBncHJ0U2V0RHJvcE9uTG9jawoqCiogREVTQ1JJUFRJT046CiogICAgICAgIFRoaXMgcm91dGluZSBzZXQgdGhlIERyb3Agb24gTG9jay4gV2hlbiBzZXQgdG8gb25lLCBJbmdyZXNzIGZyYW1lcyB3aWxsCiogICAgICAgIGJlIGRpc2NhcmRlZCBpZiB0aGVpciBTQSBmaWVsZCBpcyBub3QgaW4gdGhlIEFUVSdzIGFkZHJlc3MgZGF0YWJhc2UuCioKKiBJTlBVVFM6CiogICAgICAgIHBvcnQgLSB0aGUgbG9naWNhbCBwb3J0IG51bWJlci4KKiAgICAgICAgbW9kZSAtIEdUX1RSVUUgZm9yIFVua25vd24gU0EgZHJvcCBvciBHVF9GQUxTRSBvdGhlcndpc2UKKgoqIE9VVFBVVFM6CiogICAgICAgIE5vbmUuCioKKiBSRVRVUk5TOgoqICAgICAgICBHVF9PSyAgIC0gb24gc3VjY2VzcwoqICAgICAgICBHVF9GQUlMIC0gb24gZXJyb3IKKiAgICAgICAgR1RfTk9UX1NVUFBPUlRFRCAtIGlmIGN1cnJlbnQgZGV2aWNlIGRvZXMgbm90IHN1cHBvcnQgdGhpcyBmZWF0dXJlLgoqCiogQ09NTUVOVFM6CioKKiBHYWxUaXM6CioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdwcnRTZXREcm9wT25Mb2NrCigKICAgIElOIEdUX1FEX0RFViAgICAqZGV2LAogICAgSU4gR1RfTFBPUlQgICAgICAgIHBvcnQsCiAgICBJTiBHVF9CT09MICAgICAgICBtb2RlCikKewogICAgR1RfVTE2ICAgICAgICAgIGRhdGE7CiAgICBHVF9TVEFUVVMgICAgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX1U4ICAgICAgICAgICBod1BvcnQ7ICAgICAgICAgLyogdGhlIHBoeXNpY2FsIHBvcnQgbnVtYmVyICAgICAqLwoKICAgIERCR19JTkZPKCgiZ3BydFNldERyb3BPbkxvY2sgQ2FsbGVkLlxuIikpOwoKICAgIC8qIHRyYW5zbGF0ZSBMUE9SVCB0byBoYXJkd2FyZSBwb3J0ICovCiAgICBod1BvcnQgPSBHVF9MUE9SVF8yX1BPUlQocG9ydCk7CgogICAgLyogT25seSBHaWdhYml0IFN3aXRjaCBzdXBwb3J0cyB0aGlzIHN0YXR1cy4gKi8KICAgIGlmICghSVNfSU5fREVWX0dST1VQKGRldixERVZfQ0FTQ0FERV9QT1JUKSkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX05PVF9TVVBQT1JURURcbiIpKTsKICAgICAgICByZXR1cm4gR1RfTk9UX1NVUFBPUlRFRDsKICAgIH0KCiAgICAvKiB0cmFuc2xhdGUgQk9PTCB0byBiaW5hcnkgKi8KICAgIEJPT0xfMl9CSVQobW9kZSwgZGF0YSk7CgogICAgLyogU2V0IHRoZSBEcm9wT25Mb2NrIG1vZGUuICAgICAgICAgICAgKi8KICAgIHJldFZhbCA9IGh3U2V0UG9ydFJlZ0ZpZWxkKGRldixod1BvcnQsIFFEX1JFR19QT1JUX0NPTlRST0wsMTQsMSxkYXRhKTsKCiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJPSy5cbiIpKTsKICAgIH0KICAgIHJldHVybiByZXRWYWw7Cn0KCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBncHJ0R2V0RHJvcE9uTG9jawoqCiogREVTQ1JJUFRJT046CiogICAgICAgIFRoaXMgcm91dGluZSBnZXRzIERyb3BPbkxvY2sgbW9kZS4KKgoqIElOUFVUUzoKKiAgICAgICAgcG9ydCAgLSB0aGUgbG9naWNhbCBwb3J0IG51bWJlci4KKgoqIE9VVFBVVFM6CiogICAgICAgIG1vZGUgLSBHVF9UUlVFOiBEcm9wT25Mb2NrIGVuYWJsZWQsCiogICAgICAgICAgICAgICAgIEdUX0ZBTFNFIG90aGVyd2lzZQoqCiogUkVUVVJOUzoKKiAgICAgICAgR1RfT0sgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICAgR1RfRkFJTCAtIG9uIGVycm9yCiogICAgICAgIEdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqCiogR2FsVGlzOgoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBncHJ0R2V0RHJvcE9uTG9jawooCiAgICBJTiAgR1RfUURfREVWICAgICpkZXYsCiAgICBJTiAgR1RfTFBPUlQgICAgcG9ydCwKICAgIE9VVCBHVF9CT09MICAgICAgICAqbW9kZQopCnsKICAgIEdUX1NUQVRVUyAgICAgICByZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwogICAgR1RfVTggICAgICAgICAgIGh3UG9ydDsgICAgICAgICAvKiB0aGUgcGh5c2ljYWwgcG9ydCBudW1iZXIgICAgICovCiAgICBHVF9VMTYgICAgICAgICAgZGF0YTsgICAgICAgICAgIC8qIHRvIGtlZXAgdGhlIHJlYWQgdmFsdmUgICAgICAgKi8KCiAgICBEQkdfSU5GTygoImdwcnRHZXREcm9wT25Mb2NrIENhbGxlZC5cbiIpKTsKCiAgICAvKiB0cmFuc2xhdGUgTFBPUlQgdG8gaGFyZHdhcmUgcG9ydCAqLwogICAgaHdQb3J0ID0gR1RfTFBPUlRfMl9QT1JUKHBvcnQpOwoKICAgIC8qIE9ubHkgR2lnYWJpdCBTd2l0Y2ggc3VwcG9ydHMgdGhpcyBzdGF0dXMuICovCiAgICBpZiAoIUlTX0lOX0RFVl9HUk9VUChkZXYsREVWX0NBU0NBREVfUE9SVCkpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CgogICAgLyogR2V0IHRoZSBEcm9wT25Mb2NrIE1vZGUuICAgICAgICAgICAgKi8KICAgIHJldFZhbCA9IGh3R2V0UG9ydFJlZ0ZpZWxkKGRldixod1BvcnQsIFFEX1JFR19QT1JUX0NPTlRST0wsIDE0LCAxLCAmZGF0YSk7CgogICAgLyogdHJhbnNsYXRlIGJpbmFyeSB0byBCT09MICAqLwogICAgQklUXzJfQk9PTChkYXRhLCAqbW9kZSk7CiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJPSy5cbiIpKTsKICAgIH0KCiAgICByZXR1cm4gcmV0VmFsOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdwcnRTZXREb3VibGVUYWcKKgoqIERFU0NSSVBUSU9OOgoqICAgICAgICBUaGlzIHJvdXRpbmUgc2V0IHRoZSBJbmdyZXNzIERvdWJsZSBUYWcgTW9kZS4gV2hlbiBzZXQgdG8gb25lLAoqICAgICAgICBpbmdyZXNzaW5nIGZyYW1lcyBhcmUgZXhhbWluZWQgdG8gc2VlIGlmIHRoZXkgY29udGFpbiBhbiA4MDIuM2FjIHRhZy4KKiAgICAgICAgSWYgdGhleSBkbywgdGhlIHRhZyBpcyByZW1vdmVkIGFuZCB0aGVuIHRoZSBmcmFtZSBpcyBwcm9jZXNzZWQgZnJvbQoqICAgICAgICB0aGVyZSAoaS5lLiwgcmVtb3ZlZCB0YWcgaXMgaWdub3JlZCkuIEVzc2VudGlhbGx5LCB1bnRhZ2dlZCBmcmFtZXMKKiAgICAgICAgcmVtYWluIHVudGFnZ2VkLCBzaW5nbGUgdGFnZ2VkIGZyYW1lcyBiZWNvbWUgdW50YWdnZWQgYW5kIGRvdWJsZSB0YWdnZWQKKiAgICAgICAgZnJhbWVzIGJlY29tZSBzaW5nbGUgdGFnZ2VkLgoqCiogSU5QVVRTOgoqICAgICAgICBwb3J0IC0gdGhlIGxvZ2ljYWwgcG9ydCBudW1iZXIuCiogICAgICAgIG1vZGUgLSBHVF9UUlVFIGZvciBEb3VsYmVUYWcgbW9kZSBvciBHVF9GQUxTRSBvdGhlcndpc2UKKgoqIE9VVFBVVFM6CiogICAgICAgIE5vbmUuCioKKiBSRVRVUk5TOgoqICAgICAgICBHVF9PSyAgIC0gb24gc3VjY2VzcwoqICAgICAgICBHVF9GQUlMIC0gb24gZXJyb3IKKiAgICAgICAgR1RfTk9UX1NVUFBPUlRFRCAtIGlmIGN1cnJlbnQgZGV2aWNlIGRvZXMgbm90IHN1cHBvcnQgdGhpcyBmZWF0dXJlLgoqCiogQ09NTUVOVFM6CioKKiBHYWxUaXM6CioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdwcnRTZXREb3VibGVUYWcKKAogICAgSU4gR1RfUURfREVWICAgICpkZXYsCiAgICBJTiBHVF9MUE9SVCAgICAgICAgcG9ydCwKICAgIElOIEdUX0JPT0wgICAgICAgIG1vZGUKKQp7CiAgICBHVF9VMTYgICAgICAgICAgZGF0YTsKICAgIEdUX1NUQVRVUyAgICAgICByZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwogICAgR1RfVTggICAgICAgICAgIGh3UG9ydDsgICAgICAgICAvKiB0aGUgcGh5c2ljYWwgcG9ydCBudW1iZXIgICAgICovCgogICAgREJHX0lORk8oKCJncHJ0U2V0RG91YmxlVGFnIENhbGxlZC5cbiIpKTsKCiAgICAvKiB0cmFuc2xhdGUgTFBPUlQgdG8gaGFyZHdhcmUgcG9ydCAqLwogICAgaHdQb3J0ID0gR1RfTFBPUlRfMl9QT1JUKHBvcnQpOwoKICAgIC8qIE9ubHkgR2lnYWJpdCBTd2l0Y2ggc3VwcG9ydHMgdGhpcyBzdGF0dXMuICovCiAgICBpZiAoIUlTX0lOX0RFVl9HUk9VUChkZXYsREVWX0lOR1JFU1NfRE9VQkxFX1RBR0dJTkcpKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfTk9UX1NVUFBPUlRFRFxuIikpOwogICAgICAgIHJldHVybiBHVF9OT1RfU1VQUE9SVEVEOwogICAgfQoKICAgIC8qIHRyYW5zbGF0ZSBCT09MIHRvIGJpbmFyeSAqLwogICAgQk9PTF8yX0JJVChtb2RlLCBkYXRhKTsKCiAgICAvKiBTZXQgdGhlIERvdWJsZVRhZyBtb2RlLiAgICAgICAgICAgICovCiAgICByZXRWYWwgPSBod1NldFBvcnRSZWdGaWVsZChkZXYsaHdQb3J0LCBRRF9SRUdfUE9SVF9DT05UUk9MLDksMSxkYXRhKTsKCiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJPSy5cbiIpKTsKICAgIH0KICAgIHJldHVybiByZXRWYWw7Cn0KCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBncHJ0R2V0RG91YmxlVGFnCioKKiBERVNDUklQVElPTjoKKiAgICAgICAgVGhpcyByb3V0aW5lIGdldHMgRG91YmxlVGFnIG1vZGUuCioKKiBJTlBVVFM6CiogICAgICAgIHBvcnQgIC0gdGhlIGxvZ2ljYWwgcG9ydCBudW1iZXIuCioKKiBPVVRQVVRTOgoqICAgICAgICBtb2RlIC0gR1RfVFJVRTogRG91YmxlVGFnIGVuYWJsZWQsCiogICAgICAgICAgICAgICAgIEdUX0ZBTFNFIG90aGVyd2lzZQoqCiogUkVUVVJOUzoKKiAgICAgICAgR1RfT0sgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICAgR1RfRkFJTCAtIG9uIGVycm9yCiogICAgICAgIEdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqCiogR2FsVGlzOgoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBncHJ0R2V0RG91YmxlVGFnCigKICAgIElOICBHVF9RRF9ERVYgICAgKmRldiwKICAgIElOICBHVF9MUE9SVCAgICBwb3J0LAogICAgT1VUIEdUX0JPT0wgICAgICAgICptb2RlCikKewogICAgR1RfU1RBVFVTICAgICAgIHJldFZhbDsgICAgICAgICAvKiBGdW5jdGlvbnMgcmV0dXJuIHZhbHVlLiAgICAgICovCiAgICBHVF9VOCAgICAgICAgICAgaHdQb3J0OyAgICAgICAgIC8qIHRoZSBwaHlzaWNhbCBwb3J0IG51bWJlciAgICAgKi8KICAgIEdUX1UxNiAgICAgICAgICBkYXRhOyAgICAgICAgICAgLyogdG8ga2VlcCB0aGUgcmVhZCB2YWx2ZSAgICAgICAqLwoKICAgIERCR19JTkZPKCgiZ3BydEdldERvdWJsZVRhZyBDYWxsZWQuXG4iKSk7CgogICAgLyogdHJhbnNsYXRlIExQT1JUIHRvIGhhcmR3YXJlIHBvcnQgKi8KICAgIGh3UG9ydCA9IEdUX0xQT1JUXzJfUE9SVChwb3J0KTsKCiAgICAvKiBPbmx5IEdpZ2FiaXQgU3dpdGNoIHN1cHBvcnRzIHRoaXMgc3RhdHVzLiAqLwogICAgaWYgKCFJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9JTkdSRVNTX0RPVUJMRV9UQUdHSU5HKSkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX05PVF9TVVBQT1JURURcbiIpKTsKICAgICAgICByZXR1cm4gR1RfTk9UX1NVUFBPUlRFRDsKICAgIH0KCiAgICAvKiBHZXQgdGhlIERvdWJsZVRhZyBNb2RlLiAgICAgICAgICAgICovCiAgICByZXRWYWwgPSBod0dldFBvcnRSZWdGaWVsZChkZXYsaHdQb3J0LCBRRF9SRUdfUE9SVF9DT05UUk9MLCA5LCAxLCAmZGF0YSk7CgogICAgLyogdHJhbnNsYXRlIGJpbmFyeSB0byBCT09MICAqLwogICAgQklUXzJfQk9PTChkYXRhLCAqbW9kZSk7CiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJPSy5cbiIpKTsKICAgIH0KCiAgICByZXR1cm4gcmV0VmFsOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBncHJ0U2V0SW50ZXJzd2l0Y2hQb3J0CioKKiBERVNDUklQVElPTjoKKiAgICAgICAgVGhpcyByb3V0aW5lIHNldCBJbnRlcnN3aXRjaCBQb3J0LiBXaGVuIHNldCB0byBvbmUsCiogICAgICAgIGl0IGluZGljYXRlcyB0aGlzIHBvcnQgaXMgYSBpbnRlcnN3aXRjaCBwb3J0IHVzZWQgdG8gY29tbXVuaWNhdGVkIHdpdGgKKiAgICAgICAgQ1BVIG9yIHRvIGNhc2NhZGUgd2l0aCBhbm90aGVyIHN3aXRjaCBkZXZpY2UuCioKKiBJTlBVVFM6CiogICAgICAgIHBvcnQgLSB0aGUgbG9naWNhbCBwb3J0IG51bWJlci4KKiAgICAgICAgbW9kZSAtIEdUX1RSVUUgZm9yIEludGVyc3dpdGNoIHBvcnQgb3IgR1RfRkFMU0Ugb3RoZXJ3aXNlCioKKiBPVVRQVVRTOgoqICAgICAgICBOb25lLgoqCiogUkVUVVJOUzoKKiAgICAgICAgR1RfT0sgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICAgR1RfRkFJTCAtIG9uIGVycm9yCiogICAgICAgIEdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqCiogR2FsVGlzOgoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBncHJ0U2V0SW50ZXJzd2l0Y2hQb3J0CigKICAgIElOIEdUX1FEX0RFViAgICAqZGV2LAogICAgSU4gR1RfTFBPUlQgICAgICAgIHBvcnQsCiAgICBJTiBHVF9CT09MICAgICAgICBtb2RlCikKewogICAgR1RfVTE2ICAgICAgICAgIGRhdGE7CiAgICBHVF9TVEFUVVMgICAgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX1U4ICAgICAgICAgICBod1BvcnQ7ICAgICAgICAgLyogdGhlIHBoeXNpY2FsIHBvcnQgbnVtYmVyICAgICAqLwoKICAgIERCR19JTkZPKCgiZ3BydFNldEludGVyc3dpdGNoUG9ydCBDYWxsZWQuXG4iKSk7CgogICAgLyogdHJhbnNsYXRlIExQT1JUIHRvIGhhcmR3YXJlIHBvcnQgKi8KICAgIGh3UG9ydCA9IEdUX0xQT1JUXzJfUE9SVChwb3J0KTsKCiAgICAvKiBPbmx5IEdpZ2FiaXQgU3dpdGNoIHN1cHBvcnRzIHRoaXMgc3RhdHVzLiAqLwogICAgaWYgKCFJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9DQVNDQURFX1BPUlQpKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfTk9UX1NVUFBPUlRFRFxuIikpOwogICAgICAgIHJldHVybiBHVF9OT1RfU1VQUE9SVEVEOwogICAgfQoKICAgIC8qIHRyYW5zbGF0ZSBCT09MIHRvIGJpbmFyeSAqLwogICAgQk9PTF8yX0JJVChtb2RlLCBkYXRhKTsKCiAgICAvKiBTZXQgdGhlIEludGVyc3dpdGNoUG9ydC4gICAgICAgICAgICAqLwogICAgcmV0VmFsID0gaHdTZXRQb3J0UmVnRmllbGQoZGV2LGh3UG9ydCwgUURfUkVHX1BPUlRfQ09OVFJPTCw4LDEsZGF0YSk7CgogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgewogICAgICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIERCR19JTkZPKCgiT0suXG4iKSk7CiAgICB9CiAgICByZXR1cm4gcmV0VmFsOwp9CgoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3BydEdldEludGVyc3dpdGhQb3J0CioKKiBERVNDUklQVElPTjoKKiAgICAgICAgVGhpcyByb3V0aW5lIGdldHMgSW50ZXJzd2l0Y2hQb3J0LgoqCiogSU5QVVRTOgoqICAgICAgICBwb3J0ICAtIHRoZSBsb2dpY2FsIHBvcnQgbnVtYmVyLgoqCiogT1VUUFVUUzoKKiAgICAgICAgbW9kZSAtIEdUX1RSVUU6IFRoaXMgcG9ydCBpcyBpbnRlcnN3aXRjaCBwb3J0LAoqICAgICAgICAgICAgICAgICBHVF9GQUxTRSBvdGhlcndpc2UKKgoqIFJFVFVSTlM6CiogICAgICAgIEdUX09LICAgLSBvbiBzdWNjZXNzCiogICAgICAgIEdUX0ZBSUwgLSBvbiBlcnJvcgoqICAgICAgICBHVF9OT1RfU1VQUE9SVEVEIC0gaWYgY3VycmVudCBkZXZpY2UgZG9lcyBub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCioKKiBDT01NRU5UUzoKKgoqIEdhbFRpczoKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3BydEdldEludGVyc3dpdGNoUG9ydAooCiAgICBJTiAgR1RfUURfREVWICAgICpkZXYsCiAgICBJTiAgR1RfTFBPUlQgICAgcG9ydCwKICAgIE9VVCBHVF9CT09MICAgICAgICAqbW9kZQopCnsKICAgIEdUX1NUQVRVUyAgICAgICByZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwogICAgR1RfVTggICAgICAgICAgIGh3UG9ydDsgICAgICAgICAvKiB0aGUgcGh5c2ljYWwgcG9ydCBudW1iZXIgICAgICovCiAgICBHVF9VMTYgICAgICAgICAgZGF0YTsgICAgICAgICAgIC8qIHRvIGtlZXAgdGhlIHJlYWQgdmFsdmUgICAgICAgKi8KCiAgICBEQkdfSU5GTygoImdwcnRHZXRJbnRlcnN3aXRjaFBvcnQgQ2FsbGVkLlxuIikpOwoKICAgIC8qIHRyYW5zbGF0ZSBMUE9SVCB0byBoYXJkd2FyZSBwb3J0ICovCiAgICBod1BvcnQgPSBHVF9MUE9SVF8yX1BPUlQocG9ydCk7CgogICAgLyogT25seSBHaWdhYml0IFN3aXRjaCBzdXBwb3J0cyB0aGlzIHN0YXR1cy4gKi8KICAgIGlmICghSVNfSU5fREVWX0dST1VQKGRldixERVZfQ0FTQ0FERV9QT1JUKSkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX05PVF9TVVBQT1JURURcbiIpKTsKICAgICAgICByZXR1cm4gR1RfTk9UX1NVUFBPUlRFRDsKICAgIH0KCiAgICAvKiBHZXQgdGhlIEludGVyc3dpdGNoUG9ydCBNb2RlLiAgICAgICAgICAgICovCiAgICByZXRWYWwgPSBod0dldFBvcnRSZWdGaWVsZChkZXYsaHdQb3J0LCBRRF9SRUdfUE9SVF9DT05UUk9MLCA4LCAxLCAmZGF0YSk7CgogICAgLyogdHJhbnNsYXRlIGJpbmFyeSB0byBCT09MICAqLwogICAgQklUXzJfQk9PTChkYXRhLCAqbW9kZSk7CiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJPSy5cbiIpKTsKICAgIH0KCiAgICByZXR1cm4gcmV0VmFsOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdwcnRTZXRMZWFybkRpc2FibGUKKgoqIERFU0NSSVBUSU9OOgoqICAgICAgICBUaGlzIHJvdXRpbmUgZW5hYmxlcy9kaXNhYmxlcyBhdXRvbWF0aWMgbGVhcm5pbmcgb2YgbmV3IHNvdXJjZSBNQUMKKiAgICAgICAgYWRkcmVzc2VzIG9uIHRoZSBnaXZlbiBwb3J0IGluZ3Jlc3MKKgoqIElOUFVUUzoKKiAgICAgICAgcG9ydCAtIHRoZSBsb2dpY2FsIHBvcnQgbnVtYmVyLgoqICAgICAgICBtb2RlIC0gR1RfVFJVRSBmb3IgZGlzYWJsZSBvciBHVF9GQUxTRSBvdGhlcndpc2UKKgoqIE9VVFBVVFM6CiogICAgICAgIE5vbmUuCioKKiBSRVRVUk5TOgoqICAgICAgICBHVF9PSyAgIC0gb24gc3VjY2VzcwoqICAgICAgICBHVF9GQUlMIC0gb24gZXJyb3IKKiAgICAgICAgR1RfTk9UX1NVUFBPUlRFRCAtIGlmIGN1cnJlbnQgZGV2aWNlIGRvZXMgbm90IHN1cHBvcnQgdGhpcyBmZWF0dXJlLgoqCiogQ09NTUVOVFM6CioKKiBHYWxUaXM6CioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdwcnRTZXRMZWFybkRpc2FibGUKKAogICAgSU4gR1RfUURfREVWICAgICpkZXYsCiAgICBJTiBHVF9MUE9SVCAgICAgICAgcG9ydCwKICAgIElOIEdUX0JPT0wgICAgICAgIG1vZGUKKQp7CiAgICBHVF9VMTYgICAgICAgICAgZGF0YTsKICAgIEdUX1NUQVRVUyAgICAgICByZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwogICAgR1RfVTggICAgICAgICAgIGh3UG9ydDsgICAgICAgICAvKiB0aGUgcGh5c2ljYWwgcG9ydCBudW1iZXIgICAgICovCgogICAgREJHX0lORk8oKCJncHJ0U2V0TGVhcm5EaXNhYmxlIENhbGxlZC5cbiIpKTsKCiAgICAvKiB0cmFuc2xhdGUgTFBPUlQgdG8gaGFyZHdhcmUgcG9ydCAqLwogICAgaHdQb3J0ID0gR1RfTFBPUlRfMl9QT1JUKHBvcnQpOwoKICAgIC8qIE9ubHkgR2lnYWJpdCBTd2l0Y2ggc3VwcG9ydHMgdGhpcyBzdGF0dXMuICovCiAgICBpZiAoIUlTX0lOX0RFVl9HUk9VUChkZXYsREVWX0dJR0FCSVRfU1dJVENIKSkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX05PVF9TVVBQT1JURURcbiIpKTsKICAgICAgICByZXR1cm4gR1RfTk9UX1NVUFBPUlRFRDsKICAgIH0KCiAgICAvKiB0cmFuc2xhdGUgQk9PTCB0byBiaW5hcnkgKi8KICAgIEJPT0xfMl9CSVQobW9kZSwgZGF0YSk7CgogICAgLyogU2V0IHRoZSBMZWFybkRpc2FibGUgbW9kZS4gICAgICAgICAgICAqLwogICAgcmV0VmFsID0gaHdTZXRQb3J0UmVnRmllbGQoZGV2LGh3UG9ydCwgUURfUkVHX1BPUlRfVkxBTl9NQVAsMTEsMSxkYXRhKTsKCiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJPSy5cbiIpKTsKICAgIH0KICAgIHJldHVybiByZXRWYWw7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdwcnRHZXRMZWFybkRpc2FibGUKKgoqIERFU0NSSVBUSU9OOgoqICAgICAgICBUaGlzIHJvdXRpbmUgZ2V0cyBMZWFybkRpc2FibGUgc2V0dXAKKgoqIElOUFVUUzoKKiAgICAgICAgcG9ydCAgLSB0aGUgbG9naWNhbCBwb3J0IG51bWJlci4KKgoqIE9VVFBVVFM6CiogICAgICAgIG1vZGUgLSBHVF9UUlVFOiBMZWFybmluZyBkaXNhYmxlZCBvbiB0aGUgZ2l2ZW4gcG9ydCBpbmdyZXNzIGZyYW1lcywKKiAgICAgICAgICAgICAgICAgR1RfRkFMU0Ugb3RoZXJ3aXNlCioKKiBSRVRVUk5TOgoqICAgICAgICBHVF9PSyAgIC0gb24gc3VjY2VzcwoqICAgICAgICBHVF9GQUlMIC0gb24gZXJyb3IKKiAgICAgICAgR1RfTk9UX1NVUFBPUlRFRCAtIGlmIGN1cnJlbnQgZGV2aWNlIGRvZXMgbm90IHN1cHBvcnQgdGhpcyBmZWF0dXJlLgoqCiogQ09NTUVOVFM6CioKKiBHYWxUaXM6CioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdwcnRHZXRMZWFybkRpc2FibGUKKAogICAgSU4gIEdUX1FEX0RFViAgICAqZGV2LAogICAgSU4gIEdUX0xQT1JUICAgIHBvcnQsCiAgICBPVVQgR1RfQk9PTCAgICAgICAgKm1vZGUKKQp7CiAgICBHVF9TVEFUVVMgICAgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX1U4ICAgICAgICAgICBod1BvcnQ7ICAgICAgICAgLyogdGhlIHBoeXNpY2FsIHBvcnQgbnVtYmVyICAgICAqLwogICAgR1RfVTE2ICAgICAgICAgIGRhdGE7ICAgICAgICAgICAvKiB0byBrZWVwIHRoZSByZWFkIHZhbHZlICAgICAgICovCgogICAgREJHX0lORk8oKCJncHJ0R2V0TGVhcm5EaXNhYmxlIENhbGxlZC5cbiIpKTsKCiAgICAvKiB0cmFuc2xhdGUgTFBPUlQgdG8gaGFyZHdhcmUgcG9ydCAqLwogICAgaHdQb3J0ID0gR1RfTFBPUlRfMl9QT1JUKHBvcnQpOwoKICAgIC8qIE9ubHkgR2lnYWJpdCBTd2l0Y2ggc3VwcG9ydHMgdGhpcyBzdGF0dXMuICovCiAgICBpZiAoIUlTX0lOX0RFVl9HUk9VUChkZXYsREVWX0dJR0FCSVRfU1dJVENIKSkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX05PVF9TVVBQT1JURURcbiIpKTsKICAgICAgICByZXR1cm4gR1RfTk9UX1NVUFBPUlRFRDsKICAgIH0KCiAgICAvKiBHZXQgdGhlIExlYXJuRGlzYWJsZSBNb2RlLiAgICAgICAgICAgICovCiAgICByZXRWYWwgPSBod0dldFBvcnRSZWdGaWVsZChkZXYsaHdQb3J0LCBRRF9SRUdfUE9SVF9WTEFOX01BUCwgMTEsIDEsICZkYXRhKTsKCiAgICAvKiB0cmFuc2xhdGUgYmluYXJ5IHRvIEJPT0wgICovCiAgICBCSVRfMl9CT09MKGRhdGEsICptb2RlKTsKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBEQkdfSU5GTygoIk9LLlxuIikpOwogICAgfQoKICAgIHJldHVybiByZXRWYWw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3BydFNldElnbm9yZUZDUwoqCiogREVTQ1JJUFRJT046CiogICAgICAgIFRoaXMgcm91dGluZSBzZXRzIEZDUyBJZ25vcmUgbW9kZS4gV2hlbiB0aGlzIGJpdCBpcyBzZXQgdG8gYSBvbmUsCiogICAgICAgIHRoZSBsYXN0IGZvdXIgYnl0ZXMgb2YgZnJhbWVzIHJlY2VpdmVkIG9uIHRoaXMgcG9ydCBhcmUgb3ZlcndyaXR0ZW4gd2l0aAoqICAgICAgICBhIGdvb2QgQ1JDIGFuZCB0aGUgZnJhbWVzIHdpbGwgYmUgYWNjZXB0ZWQgYnkgdGhlIHN3aXRjaC4KKgoqIElOUFVUUzoKKiAgICAgICAgcG9ydCAtIHRoZSBsb2dpY2FsIHBvcnQgbnVtYmVyLgoqICAgICAgICBtb2RlIC0gR1RfVFJVRSBmb3IgaWdub3JlIEZDUyBvciBHVF9GQUxTRSBvdGhlcndpc2UKKgoqIE9VVFBVVFM6CiogICAgICAgIE5vbmUuCioKKiBSRVRVUk5TOgoqICAgICAgICBHVF9PSyAgIC0gb24gc3VjY2VzcwoqICAgICAgICBHVF9GQUlMIC0gb24gZXJyb3IKKiAgICAgICAgR1RfTk9UX1NVUFBPUlRFRCAtIGlmIGN1cnJlbnQgZGV2aWNlIGRvZXMgbm90IHN1cHBvcnQgdGhpcyBmZWF0dXJlLgoqCiogQ09NTUVOVFM6CioKKiBHYWxUaXM6CioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdwcnRTZXRJZ25vcmVGQ1MKKAogICAgSU4gR1RfUURfREVWICAgICpkZXYsCiAgICBJTiBHVF9MUE9SVCAgICAgICAgcG9ydCwKICAgIElOIEdUX0JPT0wgICAgICAgICBtb2RlCikKewogICAgR1RfVTE2ICAgICAgICAgIGRhdGE7CiAgICBHVF9TVEFUVVMgICAgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX1U4ICAgICAgICAgICBod1BvcnQ7ICAgICAgICAgLyogdGhlIHBoeXNpY2FsIHBvcnQgbnVtYmVyICAgICAqLwoKICAgIERCR19JTkZPKCgiZ3BydFNldElnbm9yZUZDUyBDYWxsZWQuXG4iKSk7CgogICAgLyogdHJhbnNsYXRlIExQT1JUIHRvIGhhcmR3YXJlIHBvcnQgKi8KICAgIGh3UG9ydCA9IEdUX0xQT1JUXzJfUE9SVChwb3J0KTsKCiAgICAvKiBPbmx5IEdpZ2FiaXQgU3dpdGNoIHN1cHBvcnRzIHRoaXMgc3RhdHVzLiAqLwogICAgaWYgKCEoSVNfSU5fREVWX0dST1VQKGRldiwgREVWX0lHTk9SRV9GQ1MpKSkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX05PVF9TVVBQT1JURURcbiIpKTsKICAgICAgICByZXR1cm4gR1RfTk9UX1NVUFBPUlRFRDsKICAgIH0KCiAgICAvKiB0cmFuc2xhdGUgQk9PTCB0byBiaW5hcnkgKi8KICAgIEJPT0xfMl9CSVQobW9kZSwgZGF0YSk7CgogICAgLyogU2V0IHRoZSBJZ25vcmVGQ1MgbW9kZS4gICAgICAgICAgICAqLwogICAgaWYgKChJU19JTl9ERVZfR1JPVVAoZGV2LERFVl84OEU2MDkzX0ZBTUlMWSkpIHx8CiAgICAgICAgKElTX0lOX0RFVl9HUk9VUChkZXYsREVWX0VOSEFOQ0VEX0ZFX1NXSVRDSCkpIHx8CiAgICAgICAgKElTX0lOX0RFVl9HUk9VUChkZXYsREVWX0ZFX0FWQl9GQU1JTFkpKSkKICAgIHsKICAgICAgICByZXRWYWwgPSBod1NldFBvcnRSZWdGaWVsZChkZXYsaHdQb3J0LFFEX1JFR19QT1JUX0NPTlRST0wyLDE1LDEsZGF0YSApOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIHJldFZhbCA9IGh3U2V0UG9ydFJlZ0ZpZWxkKGRldixod1BvcnQsIFFEX1JFR19QT1JUX1ZMQU5fTUFQLDEwLDEsZGF0YSk7CiAgICB9CgogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgewogICAgICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIERCR19JTkZPKCgiT0suXG4iKSk7CiAgICB9CiAgICByZXR1cm4gcmV0VmFsOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBncHJ0R2V0SWdub3JlRkNTCioKKiBERVNDUklQVElPTjoKKiAgICAgICAgVGhpcyByb3V0aW5lIGdldHMgSWdub3JlIEZDUyBzZXR1cAoqCiogSU5QVVRTOgoqICAgICAgICBwb3J0ICAtIHRoZSBsb2dpY2FsIHBvcnQgbnVtYmVyLgoqCiogT1VUUFVUUzoKKiAgICAgICAgbW9kZSAtIEdUX1RSVUU6IElnbm9yZSBGQ1Mgb24gdGhlIGdpdmVuIHBvcnQncyBpbmdyZXNzIGZyYW1lcywKKiAgICAgICAgICAgICAgICAgR1RfRkFMU0Ugb3RoZXJ3aXNlCioKKiBSRVRVUk5TOgoqICAgICAgICBHVF9PSyAgIC0gb24gc3VjY2VzcwoqICAgICAgICBHVF9GQUlMIC0gb24gZXJyb3IKKiAgICAgICAgR1RfTk9UX1NVUFBPUlRFRCAtIGlmIGN1cnJlbnQgZGV2aWNlIGRvZXMgbm90IHN1cHBvcnQgdGhpcyBmZWF0dXJlLgoqCiogQ09NTUVOVFM6CioKKiBHYWxUaXM6CioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdwcnRHZXRJZ25vcmVGQ1MKKAogICAgSU4gIEdUX1FEX0RFViAgICAqZGV2LAogICAgSU4gIEdUX0xQT1JUICAgIHBvcnQsCiAgICBPVVQgR1RfQk9PTCAgICAgICAgKm1vZGUKKQp7CiAgICBHVF9TVEFUVVMgICAgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX1U4ICAgICAgICAgICBod1BvcnQ7ICAgICAgICAgLyogdGhlIHBoeXNpY2FsIHBvcnQgbnVtYmVyICAgICAqLwogICAgR1RfVTE2ICAgICAgICAgIGRhdGE7ICAgICAgICAgICAvKiB0byBrZWVwIHRoZSByZWFkIHZhbHZlICAgICAgICovCgogICAgREJHX0lORk8oKCJncHJ0R2V0SWdub3JlRkNTIENhbGxlZC5cbiIpKTsKCiAgICAvKiB0cmFuc2xhdGUgTFBPUlQgdG8gaGFyZHdhcmUgcG9ydCAqLwogICAgaHdQb3J0ID0gR1RfTFBPUlRfMl9QT1JUKHBvcnQpOwoKICAgIC8qIE9ubHkgR2lnYWJpdCBTd2l0Y2ggc3VwcG9ydHMgdGhpcyBzdGF0dXMuICovCiAgICBpZiAoIShJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9JR05PUkVfRkNTKSkpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CgogICAgLyogR2V0IHRoZSBJZ25vcmVGQ1MgTW9kZS4gICAgICAgICAgICAqLwogICAgaWYgKChJU19JTl9ERVZfR1JPVVAoZGV2LERFVl84OEU2MDkzX0ZBTUlMWSkpIHx8CiAgICAgICAgKElTX0lOX0RFVl9HUk9VUChkZXYsREVWX0VOSEFOQ0VEX0ZFX1NXSVRDSCkgfHwKICAgICAgICAoSVNfSU5fREVWX0dST1VQKGRldixERVZfRkVfQVZCX0ZBTUlMWSkpKSkKICAgIHsKICAgICAgICByZXRWYWwgPSBod0dldFBvcnRSZWdGaWVsZChkZXYsaHdQb3J0LFFEX1JFR19QT1JUX0NPTlRST0wyLDE1LDEsJmRhdGEgKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICByZXRWYWwgPSBod0dldFBvcnRSZWdGaWVsZChkZXYsaHdQb3J0LCBRRF9SRUdfUE9SVF9WTEFOX01BUCwgMTAsIDEsICZkYXRhKTsKICAgIH0KCiAgICAvKiB0cmFuc2xhdGUgYmluYXJ5IHRvIEJPT0wgICovCiAgICBCSVRfMl9CT09MKGRhdGEsICptb2RlKTsKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBEQkdfSU5GTygoIk9LLlxuIikpOwogICAgfQoKICAgIHJldHVybiByZXRWYWw7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdwcnRTZXRWVFVQcmlPdmVycmlkZQoqCiogREVTQ1JJUFRJT046CiogICAgICAgIFZUVSBQcmlvcml0eSBPdmVycmlkZS4gVGhlIGZvbGxvd2luZyBtb2RlcyBhcmUgc3VwcG9ydGVkOgoqICAgICAgICAgICAgUFJJX09WRVJSSURFX05PTkUgLQoqICAgICAgICAgICAgICAgIE5vcm1hbCBmcmFtZSBwcmlvcml0eSBwcm9jZXNzaW5nIG9jY3Vycy4KKiAgICAgICAgICAgIFBSSV9PVkVSUklERV9GUkFNRV9RVUVVRSAtCiogICAgICAgICAgICAgICAgQm90aCBmcmFtZSBhbmQgcXVldWUgb3ZlcnJpZGVzIHRha2UgcGxhY2Ugb24gdGhlIGZyYW1lLgoqICAgICAgICAgICAgUFJJX09WRVJSSURFX0ZSQU1FIC0KKiAgICAgICAgICAgICAgICBQcmlvcml0eSBhc3NpZ25lZCB0byB0aGUgZnJhbWUncyBWSUQgKGluIHRoZSBWVFUgdGFibGUpIGlzIHVzZWQKKiAgICAgICAgICAgICAgICB0byBvdmVyd2l0ZSB0aGUgZnJhbWUncyBGUHJpIChmcmFtZSBwcmlvcml0eSkuCiogICAgICAgICAgICAgICAgSWYgdGhlIGZyYW1lIGVncmVzc2VzIHRhZ2dlZCwgdGhlIHByaW9yaXR5IGluIHRoZSBmcmFtZSB3aWxsIGJlCiogICAgICAgICAgICAgICAgdGhpcyBuZXcgcHJpb3JpdHkgdmFsdWUuCiogICAgICAgICAgICBQUklfT1ZFUlJJREVfUVVFVUUgLQoqICAgICAgICAgICAgICAgIFByaW9yaXR5IGFzc2lnbmVkIHRvIHRoZSBmcmFtZSdzIFZJRCAoaW4gdGhlIFZUVSB0YWJsZSkgaXMgdXNlZAoqICAgICAgICAgICAgICAgIHRvIG92ZXJ3aXRlIHRoZSBmcmFtZSdzIFFQcmkgKHF1ZXVlIHByaW9yaXR5KS4KKiAgICAgICAgICAgICAgICBRUHJpIGlzIHVzZWQgaW50ZXJuYWxseSB0byBtYXAgdGhlIGZyYW1lIHRvIG9uZSBvZiB0aGUgZWdyZXNzCiogICAgICAgICAgICAgICAgcXVldWVzIGluc2lkZSB0aGUgc3dpdGNoLgoqCiogSU5QVVRTOgoqICAgICAgICBwb3J0IC0gdGhlIGxvZ2ljYWwgcG9ydCBudW1iZXIuCiogICAgICAgIG1vZGUgLSBHVF9QUklfT1ZFUlJJREUgdHlwZQoqCiogT1VUUFVUUzoKKiAgICAgICAgTm9uZS4KKgoqIFJFVFVSTlM6CiogICAgICAgIEdUX09LICAgLSBvbiBzdWNjZXNzCiogICAgICAgIEdUX0ZBSUwgLSBvbiBlcnJvcgoqICAgICAgICBHVF9CQURfUEFSQU0gLSBpZiBtb2RlIGlzIGludmFsaWQKKiAgICAgICAgR1RfTk9UX1NVUFBPUlRFRCAtIGlmIGN1cnJlbnQgZGV2aWNlIGRvZXMgbm90IHN1cHBvcnQgdGhpcyBmZWF0dXJlLgoqCiogQ09NTUVOVFM6CiogICAgICAgIFBSSV9PVkVSUklERV9GUkFNRSBhbmQgUFJJX09WRVJSSURFX1FVRVVFIG1vZGVzIGFyZSBzdXBwb3J0ZWQgb25seSBvbgoqICAgICAgICBjZXJ0YWluIHN3aXRjaCBkZXZpY2UuIFBsZWFzZSByZWZlciB0byB0aGUgZGV2aWNlIGRhdGFzaGVldC4KKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3BydFNldFZUVVByaU92ZXJyaWRlCigKICAgIElOIEdUX1FEX0RFViAgICAqZGV2LAogICAgSU4gR1RfTFBPUlQgICAgICAgIHBvcnQsCiAgICBJTiBHVF9QUklfT1ZFUlJJREUgICAgICAgIG1vZGUKKQp7CiAgICBHVF9VMTYgICAgICAgICAgZGF0YTsKICAgIEdUX1NUQVRVUyAgICAgICByZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwogICAgR1RfVTggICAgICAgICAgIGh3UG9ydDsgICAgICAgICAvKiB0aGUgcGh5c2ljYWwgcG9ydCBudW1iZXIgICAgICovCgogICAgREJHX0lORk8oKCJncHJ0U2V0VlRVUHJpT3ZlcnJpZGUgQ2FsbGVkLlxuIikpOwoKICAgIC8qIHRyYW5zbGF0ZSBMUE9SVCB0byBoYXJkd2FyZSBwb3J0ICovCiAgICBod1BvcnQgPSBHVF9MUE9SVF8yX1BPUlQocG9ydCk7CgogICAgaWYgKCFJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9QUklPUklUWV9PVkVSUklERSkpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CgogICAgc3dpdGNoIChtb2RlKQogICAgewogICAgICAgIGNhc2UgUFJJX09WRVJSSURFX05PTkU6CiAgICAgICAgICAgIGRhdGEgPSAwOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFBSSV9PVkVSUklERV9GUkFNRV9RVUVVRToKICAgICAgICAgICAgaWYgKElTX0lOX0RFVl9HUk9VUChkZXYsREVWX0VYVF9QUklPUklUWV9PVkVSUklERSkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGRhdGEgPSAzOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZGF0YSA9IDE7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBQUklfT1ZFUlJJREVfRlJBTUU6CiAgICAgICAgICAgIGlmICghSVNfSU5fREVWX0dST1VQKGRldixERVZfRVhUX1BSSU9SSVRZX09WRVJSSURFKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgREJHX0lORk8oKCJCYWQgUGFyYW1ldGVyXG4iKSk7CiAgICAgICAgICAgICAgICByZXR1cm4gR1RfQkFEX1BBUkFNOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGRhdGEgPSAxOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFBSSV9PVkVSUklERV9RVUVVRToKICAgICAgICAgICAgaWYgKCFJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9FWFRfUFJJT1JJVFlfT1ZFUlJJREUpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBEQkdfSU5GTygoIkJhZCBQYXJhbWV0ZXJcbiIpKTsKICAgICAgICAgICAgICAgIHJldHVybiBHVF9CQURfUEFSQU07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZGF0YSA9IDI7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIERCR19JTkZPKCgiQmFkIFBhcmFtZXRlclxuIikpOwogICAgICAgICAgICByZXR1cm4gR1RfQkFEX1BBUkFNOwogICAgfQoKICAgIC8qIFNldCB0aGUgVlRVUHJpIE92ZXJyaWRlIG1vZGUuICAgICAgICAgICAgKi8KICAgIGlmIChJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9FWFRfUFJJT1JJVFlfT1ZFUlJJREUpKQogICAgewogICAgICAgIHJldFZhbCA9IGh3U2V0UG9ydFJlZ0ZpZWxkKGRldixod1BvcnQsIFFEX1JFR19QUklfT1ZFUlJJREUsMTAsMixkYXRhKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICByZXRWYWwgPSBod1NldFBvcnRSZWdGaWVsZChkZXYsaHdQb3J0LCBRRF9SRUdfUE9SVF9DT05UUk9MMiwxNCwxLGRhdGEpOwogICAgfQoKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBEQkdfSU5GTygoIk9LLlxuIikpOwogICAgfQogICAgcmV0dXJuIHJldFZhbDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3BydEdldFZUVVByaU92ZXJyaWRlCioKKiBERVNDUklQVElPTjoKKiAgICAgICAgVlRVIFByaW9yaXR5IE92ZXJyaWRlLiBUaGUgZm9sbG93aW5nIG1vZGVzIGFyZSBzdXBwb3J0ZWQ6CiogICAgICAgICAgICBQUklfT1ZFUlJJREVfTk9ORSAtCiogICAgICAgICAgICAgICAgTm9ybWFsIGZyYW1lIHByaW9yaXR5IHByb2Nlc3Npbmcgb2NjdXJzLgoqICAgICAgICAgICAgUFJJX09WRVJSSURFX0ZSQU1FX1FVRVVFIC0KKiAgICAgICAgICAgICAgICBCb3RoIGZyYW1lIGFuZCBxdWV1ZSBvdmVycmlkZXMgdGFrZSBwbGFjZSBvbiB0aGUgZnJhbWUuCiogICAgICAgICAgICBQUklfT1ZFUlJJREVfRlJBTUUgLQoqICAgICAgICAgICAgICAgIFByaW9yaXR5IGFzc2lnbmVkIHRvIHRoZSBmcmFtZSdzIFZJRCAoaW4gdGhlIFZUVSB0YWJsZSkgaXMgdXNlZAoqICAgICAgICAgICAgICAgIHRvIG92ZXJ3aXRlIHRoZSBmcmFtZSdzIEZQcmkgKGZyYW1lIHByaW9yaXR5KS4KKiAgICAgICAgICAgICAgICBJZiB0aGUgZnJhbWUgZWdyZXNzZXMgdGFnZ2VkLCB0aGUgcHJpb3JpdHkgaW4gdGhlIGZyYW1lIHdpbGwgYmUKKiAgICAgICAgICAgICAgICB0aGlzIG5ldyBwcmlvcml0eSB2YWx1ZS4KKiAgICAgICAgICAgIFBSSV9PVkVSUklERV9RVUVVRSAtCiogICAgICAgICAgICAgICAgUHJpb3JpdHkgYXNzaWduZWQgdG8gdGhlIGZyYW1lJ3MgVklEIChpbiB0aGUgVlRVIHRhYmxlKSBpcyB1c2VkCiogICAgICAgICAgICAgICAgdG8gb3ZlcndpdGUgdGhlIGZyYW1lJ3MgUVByaSAocXVldWUgcHJpb3JpdHkpLgoqICAgICAgICAgICAgICAgIFFQcmkgaXMgdXNlZCBpbnRlcm5hbGx5IHRvIG1hcCB0aGUgZnJhbWUgdG8gb25lIG9mIHRoZSBlZ3Jlc3MKKiAgICAgICAgICAgICAgICBxdWV1ZXMgaW5zaWRlIHRoZSBzd2l0Y2guCioKKiBJTlBVVFM6CiogICAgICAgIHBvcnQgIC0gdGhlIGxvZ2ljYWwgcG9ydCBudW1iZXIuCioKKiBPVVRQVVRTOgoqICAgICAgICBtb2RlIC0gR1RfUFJJX09WRVJSSURFIHR5cGUKKgoqIFJFVFVSTlM6CiogICAgICAgIEdUX09LICAgLSBvbiBzdWNjZXNzCiogICAgICAgIEdUX0ZBSUwgLSBvbiBlcnJvcgoqICAgICAgICBHVF9OT1RfU1VQUE9SVEVEIC0gaWYgY3VycmVudCBkZXZpY2UgZG9lcyBub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCioKKiBDT01NRU5UUzoKKiAgICAgICAgUFJJX09WRVJSSURFX0ZSQU1FIGFuZCBQUklfT1ZFUlJJREVfUVVFVUUgbW9kZXMgYXJlIHN1cHBvcnRlZCBvbmx5IG9uCiogICAgICAgIGNlcnRhaW4gc3dpdGNoIGRldmljZS4gUGxlYXNlIHJlZmVyIHRvIHRoZSBkZXZpY2UgZGF0YXNoZWV0LgoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBncHJ0R2V0VlRVUHJpT3ZlcnJpZGUKKAogICAgSU4gIEdUX1FEX0RFViAgICAqZGV2LAogICAgSU4gIEdUX0xQT1JUICAgIHBvcnQsCiAgICBPVVQgR1RfUFJJX09WRVJSSURFICAgICAgICAqbW9kZQopCnsKICAgIEdUX1NUQVRVUyAgICAgICByZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwogICAgR1RfVTggICAgICAgICAgIGh3UG9ydDsgICAgICAgICAvKiB0aGUgcGh5c2ljYWwgcG9ydCBudW1iZXIgICAgICovCiAgICBHVF9VMTYgICAgICAgICAgZGF0YTsgICAgICAgICAgIC8qIHRvIGtlZXAgdGhlIHJlYWQgdmFsdmUgICAgICAgKi8KCiAgICBEQkdfSU5GTygoImdwcnRHZXRWVFVQcmlPdmVycmlkZSBDYWxsZWQuXG4iKSk7CgogICAgLyogdHJhbnNsYXRlIExQT1JUIHRvIGhhcmR3YXJlIHBvcnQgKi8KICAgIGh3UG9ydCA9IEdUX0xQT1JUXzJfUE9SVChwb3J0KTsKCiAgICBpZiAoIUlTX0lOX0RFVl9HUk9VUChkZXYsREVWX1BSSU9SSVRZX09WRVJSSURFKSkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX05PVF9TVVBQT1JURURcbiIpKTsKICAgICAgICByZXR1cm4gR1RfTk9UX1NVUFBPUlRFRDsKICAgIH0KCiAgICAvKiBHZXQgdGhlIFZUVVByaU92ZXJyaWRlIE1vZGUuICAgICAgICAgICAgKi8KICAgIGlmIChJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9FWFRfUFJJT1JJVFlfT1ZFUlJJREUpKQogICAgewogICAgICAgIHJldFZhbCA9IGh3R2V0UG9ydFJlZ0ZpZWxkKGRldixod1BvcnQsIFFEX1JFR19QUklfT1ZFUlJJREUsMTAsMiwmZGF0YSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgcmV0VmFsID0gaHdHZXRQb3J0UmVnRmllbGQoZGV2LGh3UG9ydCwgUURfUkVHX1BPUlRfQ09OVFJPTDIsIDE0LCAxLCAmZGF0YSk7CiAgICAgICAgaWYoZGF0YSA9PSAxKQogICAgICAgICAgICBkYXRhID0gMzsKICAgIH0KCiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICAgICAgcmV0dXJuIHJldFZhbDsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBEQkdfSU5GTygoIk9LLlxuIikpOwogICAgfQoKICAgIHN3aXRjaCAoZGF0YSkKICAgIHsKICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICptb2RlID0gUFJJX09WRVJSSURFX05PTkU7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMzoKICAgICAgICAgICAgKm1vZGUgPSBQUklfT1ZFUlJJREVfRlJBTUVfUVVFVUU7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMToKICAgICAgICAgICAgKm1vZGUgPSBQUklfT1ZFUlJJREVfRlJBTUU7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMjoKICAgICAgICAgICAgKm1vZGUgPSBQUklfT1ZFUlJJREVfUVVFVUU7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIERCR19JTkZPKCgiQmFkIFBhcmFtZXRlclxuIikpOwogICAgICAgICAgICByZXR1cm4gR1RfQkFEX1BBUkFNOwogICAgfQoKICAgIHJldHVybiBHVF9PSzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3BydFNldFNBUHJpT3ZlcnJpZGUKKgoqIERFU0NSSVBUSU9OOgoqICAgICAgICBTQSBQcmlvcml0eSBPdmVycmlkZS4gVGhlIGZvbGxvd2luZyBtb2RlIGlzIHN1cHBvcnRlZDoKKiAgICAgICAgICAgIFBSSV9PVkVSUklERV9OT05FIC0KKiAgICAgICAgICAgICAgICBOb3JtYWwgZnJhbWUgcHJpb3JpdHkgcHJvY2Vzc2luZyBvY2N1cnMuCiogICAgICAgICAgICBQUklfT1ZFUlJJREVfRlJBTUVfUVVFVUUgLQoqICAgICAgICAgICAgICAgIEJvdGggZnJhbWUgYW5kIHF1ZXVlIG92ZXJyaWRlcyB0YWtlIHBsYWNlIG9uIHRoZSBmcmFtZS4KKiAgICAgICAgICAgIFBSSV9PVkVSUklERV9GUkFNRSAtCiogICAgICAgICAgICAgICAgUHJpb3JpdHkgYXNzaWduZWQgdG8gdGhlIGZyYW1lJ3MgU0EgKGluIHRoZSBBVFUgdGFibGUpIGlzIHVzZWQKKiAgICAgICAgICAgICAgICB0byBvdmVyd2l0ZSB0aGUgZnJhbWUncyBGUHJpIChmcmFtZSBwcmlvcml0eSkuCiogICAgICAgICAgICAgICAgSWYgdGhlIGZyYW1lIGVncmVzc2VzIHRhZ2dlZCwgdGhlIHByaW9yaXR5IGluIHRoZSBmcmFtZSB3aWxsIGJlCiogICAgICAgICAgICAgICAgdGhpcyBuZXcgcHJpb3JpdHkgdmFsdWUuCiogICAgICAgICAgICBQUklfT1ZFUlJJREVfUVVFVUUgLQoqICAgICAgICAgICAgICAgIFByaW9yaXR5IGFzc2lnbmVkIHRvIHRoZSBmcmFtZSdzIFNBIChpbiB0aGUgQVRVIHRhYmxlKSBpcyB1c2VkCiogICAgICAgICAgICAgICAgdG8gb3ZlcndpdGUgdGhlIGZyYW1lJ3MgUVByaSAocXVldWUgcHJpb3JpdHkpLgoqICAgICAgICAgICAgICAgIFFQcmkgaXMgdXNlZCBpbnRlcm5hbGx5IHRvIG1hcCB0aGUgZnJhbWUgdG8gb25lIG9mIHRoZSBlZ3Jlc3MKKiAgICAgICAgICAgICAgICBxdWV1ZXMgaW5zaWRlIHRoZSBzd2l0Y2guCioKKiBJTlBVVFM6CiogICAgICAgIHBvcnQgLSB0aGUgbG9naWNhbCBwb3J0IG51bWJlci4KKiAgICAgICAgbW9kZSAtIEdUX1BSSV9PVkVSUklERSB0eXBlCioKKiBPVVRQVVRTOgoqICAgICAgICBOb25lLgoqCiogUkVUVVJOUzoKKiAgICAgICAgR1RfT0sgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICAgR1RfRkFJTCAtIG9uIGVycm9yCiogICAgICAgIEdUX0JBRF9QQVJBTSAtIGlmIG1vZGUgaXMgaW52YWxpZAoqICAgICAgICBHVF9OT1RfU1VQUE9SVEVEIC0gaWYgY3VycmVudCBkZXZpY2UgZG9lcyBub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCioKKiBDT01NRU5UUzoKKiAgICAgICAgUFJJX09WRVJSSURFX0ZSQU1FIGFuZCBQUklfT1ZFUlJJREVfUVVFVUUgbW9kZXMgYXJlIHN1cHBvcnRlZCBvbmx5IG9uCiogICAgICAgIGNlcnRhaW4gc3dpdGNoIGRldmljZS4gUGxlYXNlIHJlZmVyIHRvIHRoZSBkZXZpY2UgZGF0YXNoZWV0LgoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBncHJ0U2V0U0FQcmlPdmVycmlkZQooCiAgICBJTiBHVF9RRF9ERVYgICAgKmRldiwKICAgIElOIEdUX0xQT1JUICAgICAgICBwb3J0LAogICAgSU4gR1RfQk9PTCAgICAgICAgbW9kZQopCnsKICAgIEdUX1UxNiAgICAgICAgICBkYXRhOwogICAgR1RfU1RBVFVTICAgICAgIHJldFZhbDsgICAgICAgICAvKiBGdW5jdGlvbnMgcmV0dXJuIHZhbHVlLiAgICAgICovCiAgICBHVF9VOCAgICAgICAgICAgaHdQb3J0OyAgICAgICAgIC8qIHRoZSBwaHlzaWNhbCBwb3J0IG51bWJlciAgICAgKi8KCiAgICBEQkdfSU5GTygoImdwcnRTZXRTQVByaU92ZXJyaWRlIENhbGxlZC5cbiIpKTsKCiAgICAvKiB0cmFuc2xhdGUgTFBPUlQgdG8gaGFyZHdhcmUgcG9ydCAqLwogICAgaHdQb3J0ID0gR1RfTFBPUlRfMl9QT1JUKHBvcnQpOwoKICAgIGlmICghSVNfSU5fREVWX0dST1VQKGRldixERVZfUFJJT1JJVFlfT1ZFUlJJREUpKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfTk9UX1NVUFBPUlRFRFxuIikpOwogICAgICAgIHJldHVybiBHVF9OT1RfU1VQUE9SVEVEOwogICAgfQoKICAgIHN3aXRjaCAobW9kZSkKICAgIHsKICAgICAgICBjYXNlIFBSSV9PVkVSUklERV9OT05FOgogICAgICAgICAgICBkYXRhID0gMDsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBQUklfT1ZFUlJJREVfRlJBTUVfUVVFVUU6CiAgICAgICAgICAgIGlmIChJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9FWFRfUFJJT1JJVFlfT1ZFUlJJREUpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBkYXRhID0gMzsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGRhdGEgPSAxOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgUFJJX09WRVJSSURFX0ZSQU1FOgogICAgICAgICAgICBpZiAoIUlTX0lOX0RFVl9HUk9VUChkZXYsREVWX0VYVF9QUklPUklUWV9PVkVSUklERSkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIERCR19JTkZPKCgiQmFkIFBhcmFtZXRlclxuIikpOwogICAgICAgICAgICAgICAgcmV0dXJuIEdUX0JBRF9QQVJBTTsKICAgICAgICAgICAgfQogICAgICAgICAgICBkYXRhID0gMTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBQUklfT1ZFUlJJREVfUVVFVUU6CiAgICAgICAgICAgIGlmICghSVNfSU5fREVWX0dST1VQKGRldixERVZfRVhUX1BSSU9SSVRZX09WRVJSSURFKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgREJHX0lORk8oKCJCYWQgUGFyYW1ldGVyXG4iKSk7CiAgICAgICAgICAgICAgICByZXR1cm4gR1RfQkFEX1BBUkFNOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGRhdGEgPSAyOwogICAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBEQkdfSU5GTygoIkJhZCBQYXJhbWV0ZXJcbiIpKTsKICAgICAgICAgICAgcmV0dXJuIEdUX0JBRF9QQVJBTTsKICAgIH0KCiAgICAvKiBTZXQgdGhlIFNBUHJpT3ZlcnJpZGUgbW9kZS4gICAgICAgICAgICAqLwogICAgaWYgKElTX0lOX0RFVl9HUk9VUChkZXYsREVWX0VYVF9QUklPUklUWV9PVkVSUklERSkpCiAgICB7CiAgICAgICAgcmV0VmFsID0gaHdTZXRQb3J0UmVnRmllbGQoZGV2LGh3UG9ydCwgUURfUkVHX1BSSV9PVkVSUklERSwxMiwyLGRhdGEpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIHJldFZhbCA9IGh3U2V0UG9ydFJlZ0ZpZWxkKGRldixod1BvcnQsIFFEX1JFR19QT1JUX0NPTlRST0wyLDEzLDEsZGF0YSk7CiAgICB9CgogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgewogICAgICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIERCR19JTkZPKCgiT0suXG4iKSk7CiAgICB9CiAgICByZXR1cm4gcmV0VmFsOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBncHJ0R2V0U0FQcmlPdmVycmlkZQoqCiogREVTQ1JJUFRJT046CiogICAgICAgIFNBIFByaW9yaXR5IE92ZXJyaWRlLiBUaGUgZm9sbG93aW5nIG1vZGUgaXMgc3VwcG9ydGVkOgoqICAgICAgICAgICAgUFJJX09WRVJSSURFX05PTkUgLQoqICAgICAgICAgICAgICAgIE5vcm1hbCBmcmFtZSBwcmlvcml0eSBwcm9jZXNzaW5nIG9jY3Vycy4KKiAgICAgICAgICAgIFBSSV9PVkVSUklERV9GUkFNRV9RVUVVRSAtCiogICAgICAgICAgICAgICAgQm90aCBmcmFtZSBhbmQgcXVldWUgb3ZlcnJpZGVzIHRha2UgcGxhY2Ugb24gdGhlIGZyYW1lLgoqICAgICAgICAgICAgUFJJX09WRVJSSURFX0ZSQU1FIC0KKiAgICAgICAgICAgICAgICBQcmlvcml0eSBhc3NpZ25lZCB0byB0aGUgZnJhbWUncyBTQSAoaW4gdGhlIEFUVSB0YWJsZSkgaXMgdXNlZAoqICAgICAgICAgICAgICAgIHRvIG92ZXJ3aXRlIHRoZSBmcmFtZSdzIEZQcmkgKGZyYW1lIHByaW9yaXR5KS4KKiAgICAgICAgICAgICAgICBJZiB0aGUgZnJhbWUgZWdyZXNzZXMgdGFnZ2VkLCB0aGUgcHJpb3JpdHkgaW4gdGhlIGZyYW1lIHdpbGwgYmUKKiAgICAgICAgICAgICAgICB0aGlzIG5ldyBwcmlvcml0eSB2YWx1ZS4KKiAgICAgICAgICAgIFBSSV9PVkVSUklERV9RVUVVRSAtCiogICAgICAgICAgICAgICAgUHJpb3JpdHkgYXNzaWduZWQgdG8gdGhlIGZyYW1lJ3MgU0EgKGluIHRoZSBBVFUgdGFibGUpIGlzIHVzZWQKKiAgICAgICAgICAgICAgICB0byBvdmVyd2l0ZSB0aGUgZnJhbWUncyBRUHJpIChxdWV1ZSBwcmlvcml0eSkuCiogICAgICAgICAgICAgICAgUVByaSBpcyB1c2VkIGludGVybmFsbHkgdG8gbWFwIHRoZSBmcmFtZSB0byBvbmUgb2YgdGhlIGVncmVzcwoqICAgICAgICAgICAgICAgIHF1ZXVlcyBpbnNpZGUgdGhlIHN3aXRjaC4KKgoqIElOUFVUUzoKKiAgICAgICAgcG9ydCAgLSB0aGUgbG9naWNhbCBwb3J0IG51bWJlci4KKgoqIE9VVFBVVFM6CiogICAgICAgIG1vZGUgLSBHVF9QUklfT1ZFUlJJREUgdHlwZQoqCiogUkVUVVJOUzoKKiAgICAgICAgR1RfT0sgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICAgR1RfRkFJTCAtIG9uIGVycm9yCiogICAgICAgIEdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqICAgICAgICBQUklfT1ZFUlJJREVfRlJBTUUgYW5kIFBSSV9PVkVSUklERV9RVUVVRSBtb2RlcyBhcmUgc3VwcG9ydGVkIG9ubHkgb24KKiAgICAgICAgY2VydGFpbiBzd2l0Y2ggZGV2aWNlLiBQbGVhc2UgcmVmZXIgdG8gdGhlIGRldmljZSBkYXRhc2hlZXQuCioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdwcnRHZXRTQVByaU92ZXJyaWRlCigKICAgIElOICBHVF9RRF9ERVYgICAgKmRldiwKICAgIElOICBHVF9MUE9SVCAgICAgcG9ydCwKICAgIE9VVCBHVF9QUklfT1ZFUlJJREUgICAgICAgICptb2RlCikKewogICAgR1RfU1RBVFVTICAgICAgIHJldFZhbDsgICAgICAgICAvKiBGdW5jdGlvbnMgcmV0dXJuIHZhbHVlLiAgICAgICovCiAgICBHVF9VOCAgICAgICAgICAgaHdQb3J0OyAgICAgICAgIC8qIHRoZSBwaHlzaWNhbCBwb3J0IG51bWJlciAgICAgKi8KICAgIEdUX1UxNiAgICAgICAgICBkYXRhOyAgICAgICAgICAgLyogdG8ga2VlcCB0aGUgcmVhZCB2YWx2ZSAgICAgICAqLwoKICAgIERCR19JTkZPKCgiZ3BydEdldFNBUHJpT3ZlcnJpZGUgQ2FsbGVkLlxuIikpOwoKICAgIC8qIHRyYW5zbGF0ZSBMUE9SVCB0byBoYXJkd2FyZSBwb3J0ICovCiAgICBod1BvcnQgPSBHVF9MUE9SVF8yX1BPUlQocG9ydCk7CgogICAgaWYgKCFJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9QUklPUklUWV9PVkVSUklERSkpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CgogICAgLyogR2V0IHRoZSBTQVByaU92ZXJyaWRlIE1vZGUuICAgICAgICAgICAgKi8KICAgIGlmIChJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9FWFRfUFJJT1JJVFlfT1ZFUlJJREUpKQogICAgewogICAgICAgIHJldFZhbCA9IGh3R2V0UG9ydFJlZ0ZpZWxkKGRldixod1BvcnQsIFFEX1JFR19QUklfT1ZFUlJJREUsMTIsMiwmZGF0YSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgcmV0VmFsID0gaHdHZXRQb3J0UmVnRmllbGQoZGV2LGh3UG9ydCwgUURfUkVHX1BPUlRfQ09OVFJPTDIsIDEzLCAxLCAmZGF0YSk7CiAgICAgICAgaWYoZGF0YSA9PSAxKQogICAgICAgICAgICBkYXRhID0gMzsKICAgIH0KCiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICAgICAgcmV0dXJuIHJldFZhbDsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBEQkdfSU5GTygoIk9LLlxuIikpOwogICAgfQoKICAgIHN3aXRjaCAoZGF0YSkKICAgIHsKICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICptb2RlID0gUFJJX09WRVJSSURFX05PTkU7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMzoKICAgICAgICAgICAgKm1vZGUgPSBQUklfT1ZFUlJJREVfRlJBTUVfUVVFVUU7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMToKICAgICAgICAgICAgKm1vZGUgPSBQUklfT1ZFUlJJREVfRlJBTUU7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMjoKICAgICAgICAgICAgKm1vZGUgPSBQUklfT1ZFUlJJREVfUVVFVUU7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIERCR19JTkZPKCgiQmFkIFBhcmFtZXRlclxuIikpOwogICAgICAgICAgICByZXR1cm4gR1RfQkFEX1BBUkFNOwogICAgfQoKICAgIHJldHVybiBHVF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBncHJ0U2V0REFQcmlPdmVycmlkZQoqCiogREVTQ1JJUFRJT046CiogICAgICAgIERBIFByaW9yaXR5IE92ZXJyaWRlLiBUaGUgZm9sbG93aW5nIG1vZGUgaXMgc3VwcG9ydGVkOgoqICAgICAgICAgICAgUFJJX09WRVJSSURFX05PTkUgLQoqICAgICAgICAgICAgICAgIE5vcm1hbCBmcmFtZSBwcmlvcml0eSBwcm9jZXNzaW5nIG9jY3Vycy4KKiAgICAgICAgICAgIFBSSV9PVkVSUklERV9GUkFNRSAtCiogICAgICAgICAgICAgICAgUHJpb3JpdHkgYXNzaWduZWQgdG8gdGhlIGZyYW1lJ3MgREEgKGluIHRoZSBBVFUgdGFibGUpIGlzIHVzZWQKKiAgICAgICAgICAgICAgICB0byBvdmVyd2l0ZSB0aGUgZnJhbWUncyBGUHJpIChmcmFtZSBwcmlvcml0eSkuCiogICAgICAgICAgICAgICAgSWYgdGhlIGZyYW1lIGVncmVzc2VzIHRhZ2dlZCwgdGhlIHByaW9yaXR5IGluIHRoZSBmcmFtZSB3aWxsIGJlCiogICAgICAgICAgICAgICAgdGhpcyBuZXcgcHJpb3JpdHkgdmFsdWUuCiogICAgICAgICAgICBQUklfT1ZFUlJJREVfUVVFVUUgLQoqICAgICAgICAgICAgICAgIFByaW9yaXR5IGFzc2lnbmVkIHRvIHRoZSBmcmFtZSdzIERBIChpbiB0aGUgQVRVIHRhYmxlKSBpcyB1c2VkCiogICAgICAgICAgICAgICAgdG8gb3ZlcndpdGUgdGhlIGZyYW1lJ3MgUVByaSAocXVldWUgcHJpb3JpdHkpLgoqICAgICAgICAgICAgICAgIFFQcmkgaXMgdXNlZCBpbnRlcm5hbGx5IHRvIG1hcCB0aGUgZnJhbWUgdG8gb25lIG9mIHRoZSBlZ3Jlc3MKKiAgICAgICAgICAgICAgICBxdWV1ZXMgaW5zaWRlIHRoZSBzd2l0Y2guCiogICAgICAgICAgICBQUklfT1ZFUlJJREVfRlJBTUVfUVVFVUUgLQoqICAgICAgICAgICAgICAgIEJvdGggZnJhbWUgYW5kIHF1ZXVlIG92ZXJyaWRlcyB0YWtlIHBsYWNlIG9uIHRoZSBmcmFtZS4KKgoqIElOUFVUUzoKKiAgICAgICAgcG9ydCAtIHRoZSBsb2dpY2FsIHBvcnQgbnVtYmVyLgoqICAgICAgICBtb2RlIC0gR1RfUFJJX09WRVJSSURFIHR5cGUKKgoqIE9VVFBVVFM6CiogICAgICAgIE5vbmUuCioKKiBSRVRVUk5TOgoqICAgICAgICBHVF9PSyAgIC0gb24gc3VjY2VzcwoqICAgICAgICBHVF9GQUlMIC0gb24gZXJyb3IKKiAgICAgICAgR1RfQkFEX1BBUkFNIC0gaWYgbW9kZSBpcyBpbnZhbGlkCiogICAgICAgIEdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqICAgICAgICBQUklfT1ZFUlJJREVfRlJBTUUgYW5kIFBSSV9PVkVSUklERV9RVUVVRSBtb2RlcyBhcmUgc3VwcG9ydGVkIG9ubHkgb24KKiAgICAgICAgY2VydGFpbiBzd2l0Y2ggZGV2aWNlLiBQbGVhc2UgcmVmZXIgdG8gdGhlIGRldmljZSBkYXRhc2hlZXQuCioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdwcnRTZXREQVByaU92ZXJyaWRlCigKICAgIElOIEdUX1FEX0RFViAgICAqZGV2LAogICAgSU4gR1RfTFBPUlQgICAgIHBvcnQsCiAgICBJTiBHVF9QUklfT1ZFUlJJREUgICAgICAgIG1vZGUKKQp7CiAgICBHVF9VMTYgICAgICAgICAgZGF0YTsKICAgIEdUX1NUQVRVUyAgICAgICByZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwogICAgR1RfVTggICAgICAgICAgIGh3UG9ydDsgICAgICAgICAvKiB0aGUgcGh5c2ljYWwgcG9ydCBudW1iZXIgICAgICovCgogICAgREJHX0lORk8oKCJncHJ0U2V0REFQcmlPdmVycmlkZSBDYWxsZWQuXG4iKSk7CgogICAgLyogdHJhbnNsYXRlIExQT1JUIHRvIGhhcmR3YXJlIHBvcnQgKi8KICAgIGh3UG9ydCA9IEdUX0xQT1JUXzJfUE9SVChwb3J0KTsKCiAgICBpZiAoIUlTX0lOX0RFVl9HUk9VUChkZXYsREVWX1BSSU9SSVRZX09WRVJSSURFKSkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX05PVF9TVVBQT1JURURcbiIpKTsKICAgICAgICByZXR1cm4gR1RfTk9UX1NVUFBPUlRFRDsKICAgIH0KCiAgICBzd2l0Y2ggKG1vZGUpCiAgICB7CiAgICAgICAgY2FzZSBQUklfT1ZFUlJJREVfTk9ORToKICAgICAgICAgICAgZGF0YSA9IDA7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgUFJJX09WRVJSSURFX0ZSQU1FX1FVRVVFOgogICAgICAgICAgICBpZiAoSVNfSU5fREVWX0dST1VQKGRldixERVZfRVhUX1BSSU9SSVRZX09WRVJSSURFKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZGF0YSA9IDM7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBkYXRhID0gMTsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFBSSV9PVkVSUklERV9GUkFNRToKICAgICAgICAgICAgaWYgKCFJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9FWFRfUFJJT1JJVFlfT1ZFUlJJREUpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBEQkdfSU5GTygoIkJhZCBQYXJhbWV0ZXJcbiIpKTsKICAgICAgICAgICAgICAgIHJldHVybiBHVF9CQURfUEFSQU07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZGF0YSA9IDE7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgUFJJX09WRVJSSURFX1FVRVVFOgogICAgICAgICAgICBpZiAoIUlTX0lOX0RFVl9HUk9VUChkZXYsREVWX0VYVF9QUklPUklUWV9PVkVSUklERSkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIERCR19JTkZPKCgiQmFkIFBhcmFtZXRlclxuIikpOwogICAgICAgICAgICAgICAgcmV0dXJuIEdUX0JBRF9QQVJBTTsKICAgICAgICAgICAgfQogICAgICAgICAgICBkYXRhID0gMjsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgREJHX0lORk8oKCJCYWQgUGFyYW1ldGVyXG4iKSk7CiAgICAgICAgICAgIHJldHVybiBHVF9CQURfUEFSQU07CiAgICB9CgogICAgLyogU2V0IHRoZSBEQVByaU92ZXJyaWRlIG1vZGUuICAgICAgICAgICAgKi8KICAgIGlmIChJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9FWFRfUFJJT1JJVFlfT1ZFUlJJREUpKQogICAgewogICAgICAgIHJldFZhbCA9IGh3U2V0UG9ydFJlZ0ZpZWxkKGRldixod1BvcnQsIFFEX1JFR19QUklfT1ZFUlJJREUsMTQsMixkYXRhKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICByZXRWYWwgPSBod1NldFBvcnRSZWdGaWVsZChkZXYsaHdQb3J0LCBRRF9SRUdfUE9SVF9DT05UUk9MMiwxMiwxLGRhdGEpOwogICAgfQoKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBEQkdfSU5GTygoIk9LLlxuIikpOwogICAgfQogICAgcmV0dXJuIHJldFZhbDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3BydEdldERBUHJpT3ZlcnJpZGUKKgoqIERFU0NSSVBUSU9OOgoqICAgICAgICBEQSBQcmlvcml0eSBPdmVycmlkZS4gVGhlIGZvbGxvd2luZyBtb2RlIGlzIHN1cHBvcnRlZDoKKiAgICAgICAgICAgIFBSSV9PVkVSUklERV9OT05FIC0KKiAgICAgICAgICAgICAgICBOb3JtYWwgZnJhbWUgcHJpb3JpdHkgcHJvY2Vzc2luZyBvY2N1cnMuCiogICAgICAgICAgICBQUklfT1ZFUlJJREVfRlJBTUUgLQoqICAgICAgICAgICAgICAgIFByaW9yaXR5IGFzc2lnbmVkIHRvIHRoZSBmcmFtZSdzIERBIChpbiB0aGUgQVRVIHRhYmxlKSBpcyB1c2VkCiogICAgICAgICAgICAgICAgdG8gb3ZlcndpdGUgdGhlIGZyYW1lJ3MgRlByaSAoZnJhbWUgcHJpb3JpdHkpLgoqICAgICAgICAgICAgICAgIElmIHRoZSBmcmFtZSBlZ3Jlc3NlcyB0YWdnZWQsIHRoZSBwcmlvcml0eSBpbiB0aGUgZnJhbWUgd2lsbCBiZQoqICAgICAgICAgICAgICAgIHRoaXMgbmV3IHByaW9yaXR5IHZhbHVlLgoqICAgICAgICAgICAgUFJJX09WRVJSSURFX1FVRVVFIC0KKiAgICAgICAgICAgICAgICBQcmlvcml0eSBhc3NpZ25lZCB0byB0aGUgZnJhbWUncyBEQSAoaW4gdGhlIEFUVSB0YWJsZSkgaXMgdXNlZAoqICAgICAgICAgICAgICAgIHRvIG92ZXJ3aXRlIHRoZSBmcmFtZSdzIFFQcmkgKHF1ZXVlIHByaW9yaXR5KS4KKiAgICAgICAgICAgICAgICBRUHJpIGlzIHVzZWQgaW50ZXJuYWxseSB0byBtYXAgdGhlIGZyYW1lIHRvIG9uZSBvZiB0aGUgZWdyZXNzCiogICAgICAgICAgICAgICAgcXVldWVzIGluc2lkZSB0aGUgc3dpdGNoLgoqICAgICAgICAgICAgUFJJX09WRVJSSURFX0ZSQU1FX1FVRVVFIC0KKiAgICAgICAgICAgICAgICBCb3RoIGZyYW1lIGFuZCBxdWV1ZSBvdmVycmlkZXMgdGFrZSBwbGFjZSBvbiB0aGUgZnJhbWUuCioKKiBJTlBVVFM6CiogICAgICAgIHBvcnQgIC0gdGhlIGxvZ2ljYWwgcG9ydCBudW1iZXIuCioKKiBPVVRQVVRTOgoqICAgICAgICBtb2RlIC0gR1RfUFJJX09WRVJSSURFIHR5cGUKKgoqIFJFVFVSTlM6CiogICAgICAgIEdUX09LICAgLSBvbiBzdWNjZXNzCiogICAgICAgIEdUX0ZBSUwgLSBvbiBlcnJvcgoqICAgICAgICBHVF9OT1RfU1VQUE9SVEVEIC0gaWYgY3VycmVudCBkZXZpY2UgZG9lcyBub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCioKKiBDT01NRU5UUzoKKiAgICAgICAgUFJJX09WRVJSSURFX0ZSQU1FIGFuZCBQUklfT1ZFUlJJREVfUVVFVUUgbW9kZXMgYXJlIHN1cHBvcnRlZCBvbmx5IG9uCiogICAgICAgIGNlcnRhaW4gc3dpdGNoIGRldmljZS4gUGxlYXNlIHJlZmVyIHRvIHRoZSBkZXZpY2UgZGF0YXNoZWV0LgoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBncHJ0R2V0REFQcmlPdmVycmlkZQooCiAgICBJTiAgR1RfUURfREVWICAgICpkZXYsCiAgICBJTiAgR1RfTFBPUlQgICAgIHBvcnQsCiAgICBPVVQgR1RfUFJJX09WRVJSSURFICAgICAgICAqbW9kZQopCnsKICAgIEdUX1NUQVRVUyAgICAgICByZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwogICAgR1RfVTggICAgICAgICAgIGh3UG9ydDsgICAgICAgICAvKiB0aGUgcGh5c2ljYWwgcG9ydCBudW1iZXIgICAgICovCiAgICBHVF9VMTYgICAgICAgICAgZGF0YTsgICAgICAgICAgIC8qIHRvIGtlZXAgdGhlIHJlYWQgdmFsdmUgICAgICAgKi8KCiAgICBEQkdfSU5GTygoImdwcnRHZXREQVByaU92ZXJyaWRlIENhbGxlZC5cbiIpKTsKCiAgICAvKiB0cmFuc2xhdGUgTFBPUlQgdG8gaGFyZHdhcmUgcG9ydCAqLwogICAgaHdQb3J0ID0gR1RfTFBPUlRfMl9QT1JUKHBvcnQpOwoKICAgIGlmICghSVNfSU5fREVWX0dST1VQKGRldixERVZfUFJJT1JJVFlfT1ZFUlJJREUpKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfTk9UX1NVUFBPUlRFRFxuIikpOwogICAgICAgIHJldHVybiBHVF9OT1RfU1VQUE9SVEVEOwogICAgfQoKICAgIC8qIEdldCB0aGUgREFQcmlPdmVycmlkZSBNb2RlLiAgICAgICAgICAgICovCiAgICBpZiAoSVNfSU5fREVWX0dST1VQKGRldixERVZfRVhUX1BSSU9SSVRZX09WRVJSSURFKSkKICAgIHsKICAgICAgICByZXRWYWwgPSBod0dldFBvcnRSZWdGaWVsZChkZXYsaHdQb3J0LCBRRF9SRUdfUFJJX09WRVJSSURFLDE0LDIsJmRhdGEpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIHJldFZhbCA9IGh3R2V0UG9ydFJlZ0ZpZWxkKGRldixod1BvcnQsIFFEX1JFR19QT1JUX0NPTlRST0wyLCAxMiwgMSwgJmRhdGEpOwogICAgICAgIGlmKGRhdGEgPT0gMSkKICAgICAgICAgICAgZGF0YSA9IDM7CiAgICB9CgogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgewogICAgICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAgICAgIHJldHVybiByZXRWYWw7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJPSy5cbiIpKTsKICAgIH0KCiAgICBzd2l0Y2ggKGRhdGEpCiAgICB7CiAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAqbW9kZSA9IFBSSV9PVkVSUklERV9OT05FOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDM6CiAgICAgICAgICAgICptb2RlID0gUFJJX09WRVJSSURFX0ZSQU1FX1FVRVVFOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDE6CiAgICAgICAgICAgICptb2RlID0gUFJJX09WRVJSSURFX0ZSQU1FOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDI6CiAgICAgICAgICAgICptb2RlID0gUFJJX09WRVJSSURFX1FVRVVFOwogICAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBEQkdfSU5GTygoIkJhZCBQYXJhbWV0ZXJcbiIpKTsKICAgICAgICAgICAgcmV0dXJuIEdUX0JBRF9QQVJBTTsKICAgIH0KCiAgICByZXR1cm4gR1RfT0s7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdwcnRTZXRDUFVQb3J0CioKKiBERVNDUklQVElPTjoKKiAgICAgICAgVGhpcyByb3V0aW5lIHNldHMgQ1BVIFBvcnQgbnVtYmVyLiBXaGVuIFNub29waW5nIGlzIGVuYWJsZWQgb24gdGhpcyBwb3J0CiogICAgICAgIG9yIHdoZW4gdGhpcyBwb3J0IGlzIGNvbmZpZ3VyZWQgYXMgYW4gSW50ZXJzd2l0Y2ggUG9ydCBhbmQgaXQgcmVjZWl2ZXMgYQoqICAgICAgICBUb19DUFUgZnJhbWUsIHRoZSBzd2l0Y2ggbmVlZHMgdG8ga25vdyB3aGF0IHBvcnQgb24gdGhpcyBkZXZpY2UgdGhlIGZyYW1lCiogICAgICAgIHNob3VsZCBlZ3Jlc3MuCioKKiBJTlBVVFM6CiogICAgICAgIHBvcnQgLSB0aGUgbG9naWNhbCBwb3J0IG51bWJlci4KKiAgICAgICAgY3B1UG9ydCAtIENQVSBQb3J0IG51bWJlciBvciBpbnRlcnN3aXRjaCBwb3J0IHdoZXJlIENQVSBQb3J0IGlzIGNvbm5lY3RlZAoqCiogT1VUUFVUUzoKKiAgICAgICAgTm9uZS4KKgoqIFJFVFVSTlM6CiogICAgICAgIEdUX09LICAgLSBvbiBzdWNjZXNzCiogICAgICAgIEdUX0ZBSUwgLSBvbiBlcnJvcgoqICAgICAgICBHVF9OT1RfU1VQUE9SVEVEIC0gaWYgY3VycmVudCBkZXZpY2UgZG9lcyBub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCioKKiBDT01NRU5UUzoKKgoqIEdhbFRpczoKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3BydFNldENQVVBvcnQKKAogICAgSU4gR1RfUURfREVWICAgICpkZXYsCiAgICBJTiBHVF9MUE9SVCAgICAgcG9ydCwKICAgIElOIEdUX0xQT1JUICAgICBjcHVQb3J0CikKewogICAgR1RfVTE2ICAgICAgICAgIGRhdGE7CiAgICBHVF9TVEFUVVMgICAgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX1U4ICAgICAgICAgICBod1BvcnQ7ICAgICAgICAgLyogdGhlIHBoeXNpY2FsIHBvcnQgbnVtYmVyICAgICAqLwoKICAgIERCR19JTkZPKCgiZ3BydFNldENQVVBvcnQgQ2FsbGVkLlxuIikpOwoKICAgIC8qIHRyYW5zbGF0ZSBMUE9SVCB0byBoYXJkd2FyZSBwb3J0ICovCiAgICBod1BvcnQgPSBHVF9MUE9SVF8yX1BPUlQocG9ydCk7CiAgICBkYXRhID0gKEdUX1UxNilHVF9MUE9SVF8yX1BPUlQoY3B1UG9ydCk7CgogICAgLyogT25seSBHaWdhYml0IFN3aXRjaCBzdXBwb3J0cyB0aGlzIHN0YXR1cy4gKi8KICAgIGlmICghSVNfSU5fREVWX0dST1VQKGRldixERVZfQ1BVX0RFU1RfUEVSX1BPUlQpKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfTk9UX1NVUFBPUlRFRFxuIikpOwogICAgICAgIHJldHVybiBHVF9OT1RfU1VQUE9SVEVEOwogICAgfQoKICAgIC8qIFNldCB0aGUgQ1BVIFBvcnQuICAgICAgICAgICAgKi8KICAgIHJldFZhbCA9IGh3U2V0UG9ydFJlZ0ZpZWxkKGRldixod1BvcnQsIFFEX1JFR19QT1JUX0NPTlRST0wyLDAsNCxkYXRhKTsKCiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJPSy5cbiIpKTsKICAgIH0KICAgIHJldHVybiByZXRWYWw7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdwcnRHZXRDUFVQb3J0CioKKiBERVNDUklQVElPTjoKKiAgICAgICAgVGhpcyByb3V0aW5lIGdldHMgQ1BVIExvZ2ljYWwgUG9ydAoqCiogSU5QVVRTOgoqICAgICAgICBwb3J0ICAtIHRoZSBsb2dpY2FsIHBvcnQgbnVtYmVyLgoqCiogT1VUUFVUUzoKKiAgICAgICAgY3B1UG9ydCAtIENQVSBQb3J0J3MgbG9naWNhbCBudW1iZXIKKgoqIFJFVFVSTlM6CiogICAgICAgIEdUX09LICAgLSBvbiBzdWNjZXNzCiogICAgICAgIEdUX0ZBSUwgLSBvbiBlcnJvcgoqICAgICAgICBHVF9OT1RfU1VQUE9SVEVEIC0gaWYgY3VycmVudCBkZXZpY2UgZG9lcyBub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCioKKiBDT01NRU5UUzoKKgoqIEdhbFRpczoKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3BydEdldENQVVBvcnQKKAogICAgSU4gIEdUX1FEX0RFViAgICAqZGV2LAogICAgSU4gIEdUX0xQT1JUICAgICBwb3J0LAogICAgT1VUIEdUX0xQT1JUICAgICAqY3B1TFBvcnQKKQp7CiAgICBHVF9TVEFUVVMgICAgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX1U4ICAgICAgICAgICBod1BvcnQ7ICAgICAgICAgLyogdGhlIHBoeXNpY2FsIHBvcnQgbnVtYmVyICAgICAqLwogICAgR1RfVTE2ICAgICAgICAgIGRhdGE7ICAgICAgICAgICAvKiB0byBrZWVwIHRoZSByZWFkIHZhbHZlICAgICAgICovCgogICAgREJHX0lORk8oKCJncHJ0R2V0Q1BVUG9ydCBDYWxsZWQuXG4iKSk7CgogICAgLyogdHJhbnNsYXRlIExQT1JUIHRvIGhhcmR3YXJlIHBvcnQgKi8KICAgIGh3UG9ydCA9IEdUX0xQT1JUXzJfUE9SVChwb3J0KTsKCiAgICAvKiBPbmx5IEdpZ2FiaXQgU3dpdGNoIHN1cHBvcnRzIHRoaXMgc3RhdHVzLiAqLwogICAgaWYgKCFJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9DUFVfREVTVF9QRVJfUE9SVCkpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CgogICAgLyogR2V0IHRoZSBDUFVQb3J0LiAgICAgICAgICAgICovCiAgICByZXRWYWwgPSBod0dldFBvcnRSZWdGaWVsZChkZXYsaHdQb3J0LCBRRF9SRUdfUE9SVF9DT05UUk9MMiwgMCwgNCwgJmRhdGEpOwoKICAgICpjcHVMUG9ydCA9IEdUX1BPUlRfMl9MUE9SVCgoR1RfVTgpZGF0YSk7CgogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgewogICAgICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIERCR19JTkZPKCgiT0suXG4iKSk7CiAgICB9CgogICAgcmV0dXJuIHJldFZhbDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3BydFNldExvY2tlZFBvcnQKKgoqIERFU0NSSVBUSU9OOgoqICAgICAgICBUaGlzIHJvdXRpbmUgc2V0cyBMb2NrZWRQb3J0LiBXaGVuIGl0J3Mgc2V0IHRvIG9uZSwgQ1BVIGRpcmVjdGVkCiogICAgICAgIGxlYXJuaW5nIGZvciA4MDIuMXggTUFDIGF1dGhlbnRpY2F0aW9uIGlzIGVuYWJsZWQgb24gdGhpcyBwb3J0LiBJbiB0aGlzCiogICAgICAgIG1vZGUsIGFuIEFUVSBNaXNzIFZpb2xhdGlvbiBpbnRlcnJ1cHQgd2lsbCBvY2N1ciB3aGVuIGEgbmV3IFNBIGFkZHJlc3MKKiAgICAgICAgaXMgcmVjZWl2ZWQgaW4gYSBmcmFtZSBvbiB0aGlzIHBvcnQuIEF1dG9tYXRpY2FsbHkgU0EgbGVhcm5pbmcgYW5kCiogICAgICAgIHJlZnJlc2hpbmcgaXMgZGlzYWJsZWQgaW4gdGhpcyBtb2RlLgoqCiogSU5QVVRTOgoqICAgICAgICBwb3J0IC0gdGhlIGxvZ2ljYWwgcG9ydCBudW1iZXIuCiogICAgICAgIG1vZGUgLSBHVF9UUlVFIGZvciBMb2NrZWQgUG9ydCwgR1RfRkFMU0Ugb3RoZXJ3aXNlCioKKiBPVVRQVVRTOgoqICAgICAgICBOb25lLgoqCiogUkVUVVJOUzoKKiAgICAgICAgR1RfT0sgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICAgR1RfRkFJTCAtIG9uIGVycm9yCiogICAgICAgIEdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqCiogR2FsVGlzOgoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBncHJ0U2V0TG9ja2VkUG9ydAooCiAgICBJTiBHVF9RRF9ERVYgICAgKmRldiwKICAgIElOIEdUX0xQT1JUICAgICBwb3J0LAogICAgSU4gR1RfQk9PTCAgICAgICAgbW9kZQopCnsKICAgIEdUX1UxNiAgICAgICAgICBkYXRhOwogICAgR1RfU1RBVFVTICAgICAgIHJldFZhbDsgICAgICAgICAvKiBGdW5jdGlvbnMgcmV0dXJuIHZhbHVlLiAgICAgICovCiAgICBHVF9VOCAgICAgICAgICAgaHdQb3J0OyAgICAgICAgIC8qIHRoZSBwaHlzaWNhbCBwb3J0IG51bWJlciAgICAgKi8KCiAgICBEQkdfSU5GTygoImdwcnRTZXRMb2NrZWRQb3J0IENhbGxlZC5cbiIpKTsKCiAgICAvKiB0cmFuc2xhdGUgTFBPUlQgdG8gaGFyZHdhcmUgcG9ydCAqLwogICAgaHdQb3J0ID0gR1RfTFBPUlRfMl9QT1JUKHBvcnQpOwoKICAgIC8qIE9ubHkgR2lnYWJpdCBTd2l0Y2ggc3VwcG9ydHMgdGhpcyBzdGF0dXMuICovCiAgICBpZiAoIShJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9MT0NLRURfUE9SVCkpICkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX05PVF9TVVBQT1JURURcbiIpKTsKICAgICAgICByZXR1cm4gR1RfTk9UX1NVUFBPUlRFRDsKICAgIH0KCiAgICAvKiB0cmFuc2xhdGUgQk9PTCB0byBiaW5hcnkgKi8KICAgIEJPT0xfMl9CSVQobW9kZSwgZGF0YSk7CgogICAgLyogU2V0IExvY2tlZCBQb3J0LiAgICAgICAgICAgICovCiAgICByZXRWYWwgPSBod1NldFBvcnRSZWdGaWVsZChkZXYsaHdQb3J0LCBRRF9SRUdfUE9SVF9BU1NPQ0lBVElPTiwgMTMsIDEsIGRhdGEpOwoKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBEQkdfSU5GTygoIk9LLlxuIikpOwogICAgfQogICAgcmV0dXJuIHJldFZhbDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3BydEdldExvY2tlZFBvcnQKKgoqIERFU0NSSVBUSU9OOgoqICAgICAgICBUaGlzIHJvdXRpbmUgZ2V0cyBMb2NrZWQgUG9ydCBtb2RlIGZvciB0aGUgZ2l2ZW4gcG9ydAoqCiogSU5QVVRTOgoqICAgICAgICBwb3J0ICAtIHRoZSBsb2dpY2FsIHBvcnQgbnVtYmVyLgoqCiogT1VUUFVUUzoKKiAgICAgICAgbW9kZSAgLSBHVF9UUlVFIGlmIExvY2tlZFBvcnQsIEdUX0ZBTFNFIG90aGVyd2lzZQoqCiogUkVUVVJOUzoKKiAgICAgICAgR1RfT0sgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICAgR1RfRkFJTCAtIG9uIGVycm9yCiogICAgICAgIEdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqCiogR2FsVGlzOgoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBncHJ0R2V0TG9ja2VkUG9ydAooCiAgICBJTiAgR1RfUURfREVWICAgICpkZXYsCiAgICBJTiAgR1RfTFBPUlQgICAgcG9ydCwKICAgIE9VVCBHVF9CT09MICAgICAgKm1vZGUKKQp7CiAgICBHVF9TVEFUVVMgICAgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX1U4ICAgICAgICAgICBod1BvcnQ7ICAgICAgICAgLyogdGhlIHBoeXNpY2FsIHBvcnQgbnVtYmVyICAgICAqLwogICAgR1RfVTE2ICAgICAgICAgIGRhdGE7ICAgICAgICAgICAvKiB0byBrZWVwIHRoZSByZWFkIHZhbHZlICAgICAgICovCgogICAgREJHX0lORk8oKCJncHJ0R2V0TG9ja2VkUG9ydCBDYWxsZWQuXG4iKSk7CgogICAgLyogdHJhbnNsYXRlIExQT1JUIHRvIGhhcmR3YXJlIHBvcnQgKi8KICAgIGh3UG9ydCA9IEdUX0xQT1JUXzJfUE9SVChwb3J0KTsKCiAgICAvKiBPbmx5IEdpZ2FiaXQgU3dpdGNoIHN1cHBvcnRzIHRoaXMgc3RhdHVzLiAqLwogICAgaWYgKCEoSVNfSU5fREVWX0dST1VQKGRldixERVZfTE9DS0VEX1BPUlQpKSApCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CgogICAgLyogR2V0IHRoZSBMb2NrZWRQb3J0LiAqLwogICAgcmV0VmFsID0gaHdHZXRQb3J0UmVnRmllbGQoZGV2LGh3UG9ydCwgUURfUkVHX1BPUlRfQVNTT0NJQVRJT04sIDEzLCAxLCAmZGF0YSk7CgogICAgQklUXzJfQk9PTChkYXRhLCAqbW9kZSk7CgogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgewogICAgICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIERCR19JTkZPKCgiT0suXG4iKSk7CiAgICB9CgogICAgcmV0dXJuIHJldFZhbDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3BydFNldElnbm9yZVdyb25nRGF0YQoqCiogREVTQ1JJUFRJT046CiogICAgICAgIFRoaXMgcm91dGluZSBzZXRzIElnbm9yZSBXcm9uZyBEYXRhLiBJZiB0aGUgZnJhbWUncyBTQSBhZGRyZXNzIGlzIGZvdW5kCiogICAgICAgIGluIHRoZSBkYXRhYmFzZSBhbmQgaWYgdGhlIGVudHJ5IGlzICdzdGF0aWMnIG9yIGlmIHRoZSBwb3J0IGlzICdsb2NrZWQnCiogICAgICAgIHRoZSBzb3VyY2UgcG9ydCdzIGJpdCBpcyBjaGVja2VkIHRvIGluc3VyZSB0aGUgU0EgaGFzIGJlZW4gYXNzaWduZWQgdG8KKiAgICAgICAgdGhpcyBwb3J0LiBJZiB0aGUgU0EgaXMgTk9UIGFzc2lnbmVkIHRvIHRoaXMgcG9ydCwgaXQgaXMgY29uc2lkZXJlZCBhbgoqICAgICAgICBBVFUgTWVtYmVyIFZpb2xhdGlvbi4gSWYgdGhlIElnbm9yZVdyb25nRGF0YSBpcyBzZXQgdG8gR1RfRkFMU0UsIGFuIEFUVQoqICAgICAgICBNZW1iZXIgVmlvbGF0aW9uIGludGVycnVwdCB3aWxsIGJlIGdlbmVyYXRlZC4gSWYgaXQncyBzZXQgdG8gR1RfVFJVRSwKKiAgICAgICAgdGhlIEFUVSBNZW1iZXIgVmlvbGF0aW9uIGVycm9yIHdpbGwgYmUgbWFza2VkIGFuZCBpZ25vcmVkLgoqCiogSU5QVVRTOgoqICAgICAgICBwb3J0IC0gdGhlIGxvZ2ljYWwgcG9ydCBudW1iZXIuCiogICAgICAgIG1vZGUgLSBHVF9UUlVFIGZvciBJZ25vcmVXcm9uZ0RhdGEsIEdUX0ZBTFNFIG90aGVyd2lzZQoqCiogT1VUUFVUUzoKKiAgICAgICAgTm9uZS4KKgoqIFJFVFVSTlM6CiogICAgICAgIEdUX09LICAgLSBvbiBzdWNjZXNzCiogICAgICAgIEdUX0ZBSUwgLSBvbiBlcnJvcgoqICAgICAgICBHVF9OT1RfU1VQUE9SVEVEIC0gaWYgY3VycmVudCBkZXZpY2UgZG9lcyBub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCioKKiBDT01NRU5UUzoKKgoqIEdhbFRpczoKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3BydFNldElnbm9yZVdyb25nRGF0YQooCiAgICBJTiBHVF9RRF9ERVYgICAgKmRldiwKICAgIElOIEdUX0xQT1JUICAgICBwb3J0LAogICAgSU4gR1RfQk9PTCAgICAgICAgbW9kZQopCnsKICAgIEdUX1UxNiAgICAgICAgICBkYXRhOwogICAgR1RfU1RBVFVTICAgICAgIHJldFZhbDsgICAgICAgICAvKiBGdW5jdGlvbnMgcmV0dXJuIHZhbHVlLiAgICAgICovCiAgICBHVF9VOCAgICAgICAgICAgaHdQb3J0OyAgICAgICAgIC8qIHRoZSBwaHlzaWNhbCBwb3J0IG51bWJlciAgICAgKi8KCiAgICBEQkdfSU5GTygoImdwcnRTZXRJZ25vcmVXcm9uZ0RhdGEgQ2FsbGVkLlxuIikpOwoKICAgIC8qIHRyYW5zbGF0ZSBMUE9SVCB0byBoYXJkd2FyZSBwb3J0ICovCiAgICBod1BvcnQgPSBHVF9MUE9SVF8yX1BPUlQocG9ydCk7CgogICAgLyogT25seSBHaWdhYml0IFN3aXRjaCBzdXBwb3J0cyB0aGlzIHN0YXR1cy4gKi8KICAgIGlmICghKElTX0lOX0RFVl9HUk9VUChkZXYsREVWX0lHTk9SRV9XUk9OR19EQVQpKSkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX05PVF9TVVBQT1JURURcbiIpKTsKICAgICAgICByZXR1cm4gR1RfTk9UX1NVUFBPUlRFRDsKICAgIH0KCiAgICAvKiB0cmFuc2xhdGUgQk9PTCB0byBiaW5hcnkgKi8KICAgIEJPT0xfMl9CSVQobW9kZSwgZGF0YSk7CgogICAgLyogU2V0IElnbm9yZVdyb25nRGF0YS4gICAgICAgICAgICAqLwogICAgcmV0VmFsID0gaHdTZXRQb3J0UmVnRmllbGQoZGV2LGh3UG9ydCwgUURfUkVHX1BPUlRfQVNTT0NJQVRJT04sIDEyLCAxLCBkYXRhKTsKCiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJPSy5cbiIpKTsKICAgIH0KICAgIHJldHVybiByZXRWYWw7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdwcnRHZXRJZ25vcmVXcm9uZ0RhdGEKKgoqIERFU0NSSVBUSU9OOgoqICAgICAgICBUaGlzIHJvdXRpbmUgZ2V0cyBJZ25vcmUgV3JvbmcgRGF0YSBtb2RlIGZvciB0aGUgZ2l2ZW4gcG9ydAoqCiogSU5QVVRTOgoqICAgICAgICBwb3J0ICAtIHRoZSBsb2dpY2FsIHBvcnQgbnVtYmVyLgoqCiogT1VUUFVUUzoKKiAgICAgICAgbW9kZSAgLSBHVF9UUlVFIGlmIElnbm9yZVdyb25nRGF0YSwgR1RfRkFMU0Ugb3RoZXJ3aXNlCioKKiBSRVRVUk5TOgoqICAgICAgICBHVF9PSyAgIC0gb24gc3VjY2VzcwoqICAgICAgICBHVF9GQUlMIC0gb24gZXJyb3IKKiAgICAgICAgR1RfTk9UX1NVUFBPUlRFRCAtIGlmIGN1cnJlbnQgZGV2aWNlIGRvZXMgbm90IHN1cHBvcnQgdGhpcyBmZWF0dXJlLgoqCiogQ09NTUVOVFM6CioKKiBHYWxUaXM6CioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdwcnRHZXRJZ25vcmVXcm9uZ0RhdGEKKAogICAgSU4gIEdUX1FEX0RFViAgICAqZGV2LAogICAgSU4gIEdUX0xQT1JUICAgIHBvcnQsCiAgICBPVVQgR1RfQk9PTCAgICAgKm1vZGUKKQp7CiAgICBHVF9TVEFUVVMgICAgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX1U4ICAgICAgICAgICBod1BvcnQ7ICAgICAgICAgLyogdGhlIHBoeXNpY2FsIHBvcnQgbnVtYmVyICAgICAqLwogICAgR1RfVTE2ICAgICAgICAgIGRhdGE7ICAgICAgICAgICAvKiB0byBrZWVwIHRoZSByZWFkIHZhbHZlICAgICAgICovCgogICAgREJHX0lORk8oKCJncHJ0R2V0SWdub3JlV3JvbmdEYXRhIENhbGxlZC5cbiIpKTsKCiAgICAvKiB0cmFuc2xhdGUgTFBPUlQgdG8gaGFyZHdhcmUgcG9ydCAqLwogICAgaHdQb3J0ID0gR1RfTFBPUlRfMl9QT1JUKHBvcnQpOwoKICAgIC8qIE9ubHkgR2lnYWJpdCBTd2l0Y2ggc3VwcG9ydHMgdGhpcyBzdGF0dXMuICovCiAgICBpZiAoIShJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9JR05PUkVfV1JPTkdfREFUKSkpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CgogICAgLyogR2V0IHRoZSBJZ25vcmVXcm9uZ0RhdGEuICovCiAgICByZXRWYWwgPSBod0dldFBvcnRSZWdGaWVsZChkZXYsaHdQb3J0LCBRRF9SRUdfUE9SVF9BU1NPQ0lBVElPTiwgMTIsIDEsICZkYXRhKTsKCiAgICBCSVRfMl9CT09MKGRhdGEsICptb2RlKTsKCiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJPSy5cbiIpKTsKICAgIH0KCiAgICByZXR1cm4gcmV0VmFsOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBncHJ0U2V0RGlzY2FyZFRhZ2dlZAoqCiogREVTQ1JJUFRJT046CiogICAgICAgIFdoZW4gdGhpcyBiaXQgaXMgc2V0IHRvIGEgb25lLCBhbGwgbm9uLU1HTVQgZnJhbWVzIHRoYXQgYXJlIHByb2Nlc3NlZCBhcwoqICAgICAgICBUYWdnZWQgd2lsbCBiZSBkaXNjYXJkZWQgYXMgdGhleSBlbnRlciB0aGlzIHN3aXRjaCBwb3J0LiBQcmlvcml0eSBvbmx5CiogICAgICAgIHRhZ2dlZCBmcmFtZXMgKHdpdGggYSBWSUQgb2YgMHgwMDApIGFyZSBjb25zaWRlcmVkIHRhZ2dlZC4KKgoqIElOUFVUUzoKKiAgICAgICAgcG9ydCAtIHRoZSBsb2dpY2FsIHBvcnQgbnVtYmVyLgoqICAgICAgICBtb2RlIC0gR1RfVFJVRSB0byBkaXNjYXJkIHRhZ2dlZCBmcmFtZSwgR1RfRkFMU0Ugb3RoZXJ3aXNlCioKKiBPVVRQVVRTOgoqICAgICAgICBOb25lLgoqCiogUkVUVVJOUzoKKiAgICAgICAgR1RfT0sgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICAgR1RfRkFJTCAtIG9uIGVycm9yCiogICAgICAgIEdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqCiogR2FsVGlzOgoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBncHJ0U2V0RGlzY2FyZFRhZ2dlZAooCiAgICBJTiBHVF9RRF9ERVYgICAgKmRldiwKICAgIElOIEdUX0xQT1JUICAgICBwb3J0LAogICAgSU4gR1RfQk9PTCAgICAgICAgbW9kZQopCnsKICAgIEdUX1UxNiAgICAgICAgICBkYXRhOwogICAgR1RfU1RBVFVTICAgICAgIHJldFZhbDsgICAgICAgICAvKiBGdW5jdGlvbnMgcmV0dXJuIHZhbHVlLiAgICAgICovCiAgICBHVF9VOCAgICAgICAgICAgaHdQb3J0OyAgICAgICAgIC8qIHRoZSBwaHlzaWNhbCBwb3J0IG51bWJlciAgICAgKi8KCiAgICBEQkdfSU5GTygoImdwcnRTZXREaXNjYXJkVGFnZ2VkIENhbGxlZC5cbiIpKTsKCiAgICAvKiB0cmFuc2xhdGUgTFBPUlQgdG8gaGFyZHdhcmUgcG9ydCAqLwogICAgaHdQb3J0ID0gR1RfTFBPUlRfMl9QT1JUKHBvcnQpOwoKICAgIC8qIGNoZWNrIGlmIHRoZSBnaXZlbiBTd2l0Y2ggc3VwcG9ydHMgdGhpcyBmZWF0dXJlLiAqLwogICAgaWYgKCEoSVNfSU5fREVWX0dST1VQKGRldixERVZfRElTQ0FSRF9UQUdHRUQpKSApCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CgogICAgLyogdHJhbnNsYXRlIEJPT0wgdG8gYmluYXJ5ICovCiAgICBCT09MXzJfQklUKG1vZGUsIGRhdGEpOwoKICAgIC8qIFNldCBEaXNjYXJkVGFnZ2VkLiAqLwogICAgcmV0VmFsID0gaHdTZXRQb3J0UmVnRmllbGQoZGV2LGh3UG9ydCwgUURfUkVHX1BPUlRfQ09OVFJPTDIsIDksIDEsIGRhdGEpOwoKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBEQkdfSU5GTygoIk9LLlxuIikpOwogICAgfQogICAgcmV0dXJuIHJldFZhbDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3BydEdldERpc2NhcmRUYWdnZWQKKgoqIERFU0NSSVBUSU9OOgoqICAgICAgICBUaGlzIHJvdXRpbmUgZ2V0cyBEaXNjYXJkVGFnZ2VkIGJpdCBmb3IgdGhlIGdpdmVuIHBvcnQKKgoqIElOUFVUUzoKKiAgICAgICAgcG9ydCAgLSB0aGUgbG9naWNhbCBwb3J0IG51bWJlci4KKgoqIE9VVFBVVFM6CiogICAgICAgIG1vZGUgIC0gR1RfVFJVRSBpZiBEaXNjYXJkVGFnZ2VkIGJpdCBpcyBzZXQsIEdUX0ZBTFNFIG90aGVyd2lzZQoqCiogUkVUVVJOUzoKKiAgICAgICAgR1RfT0sgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICAgR1RfRkFJTCAtIG9uIGVycm9yCiogICAgICAgIEdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqCiogR2FsVGlzOgoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBncHJ0R2V0RGlzY2FyZFRhZ2dlZAooCiAgICBJTiAgR1RfUURfREVWICAgICpkZXYsCiAgICBJTiAgR1RfTFBPUlQgICAgcG9ydCwKICAgIE9VVCBHVF9CT09MICAgICAqbW9kZQopCnsKICAgIEdUX1NUQVRVUyAgICAgICByZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwogICAgR1RfVTggICAgICAgICAgIGh3UG9ydDsgICAgICAgICAvKiB0aGUgcGh5c2ljYWwgcG9ydCBudW1iZXIgICAgICovCiAgICBHVF9VMTYgICAgICAgICAgZGF0YTsgICAgICAgICAgIC8qIHRvIGtlZXAgdGhlIHJlYWQgdmFsdmUgICAgICAgKi8KCiAgICBEQkdfSU5GTygoImdwcnRHZXREaXNjYXJkVGFnZ2VkIENhbGxlZC5cbiIpKTsKCiAgICAvKiB0cmFuc2xhdGUgTFBPUlQgdG8gaGFyZHdhcmUgcG9ydCAqLwogICAgaHdQb3J0ID0gR1RfTFBPUlRfMl9QT1JUKHBvcnQpOwoKICAgIC8qIGNoZWNrIGlmIHRoZSBnaXZlbiBTd2l0Y2ggc3VwcG9ydHMgdGhpcyBmZWF0dXJlLiAqLwogICAgaWYgKCEoSVNfSU5fREVWX0dST1VQKGRldixERVZfRElTQ0FSRF9UQUdHRUQpKSApCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CgogICAgLyogR2V0IHRoZSBEaXNjYXJkVGFnZ2VkLiAqLwogICAgcmV0VmFsID0gaHdHZXRQb3J0UmVnRmllbGQoZGV2LGh3UG9ydCwgUURfUkVHX1BPUlRfQ09OVFJPTDIsIDksIDEsICZkYXRhKTsKCiAgICBCSVRfMl9CT09MKGRhdGEsICptb2RlKTsKCiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJPSy5cbiIpKTsKICAgIH0KCiAgICByZXR1cm4gcmV0VmFsOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBncHJ0U2V0RGlzY2FyZFVudGFnZ2VkCioKKiBERVNDUklQVElPTjoKKiAgICAgICAgV2hlbiB0aGlzIGJpdCBpcyBzZXQgdG8gYSBvbmUsIGFsbCBub24tTUdNVCBmcmFtZXMgdGhhdCBhcmUgcHJvY2Vzc2VkIGFzCiogICAgICAgIFVudGFnZ2VkIHdpbGwgYmUgZGlzY2FyZGVkIGFzIHRoZXkgZW50ZXIgdGhpcyBzd2l0Y2ggcG9ydC4gUHJpb3JpdHkgb25seQoqICAgICAgICB0YWdnZWQgZnJhbWVzICh3aXRoIGEgVklEIG9mIDB4MDAwKSBhcmUgY29uc2lkZXJlZCB0YWdnZWQuCioKKiBJTlBVVFM6CiogICAgICAgIHBvcnQgLSB0aGUgbG9naWNhbCBwb3J0IG51bWJlci4KKiAgICAgICAgbW9kZSAtIEdUX1RSVUUgdG8gZGlzY2FyZCB1bnRhZ2dlZCBmcmFtZSwgR1RfRkFMU0Ugb3RoZXJ3aXNlCioKKiBPVVRQVVRTOgoqICAgICAgICBOb25lLgoqCiogUkVUVVJOUzoKKiAgICAgICAgR1RfT0sgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICAgR1RfRkFJTCAtIG9uIGVycm9yCiogICAgICAgIEdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqCiogR2FsVGlzOgoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBncHJ0U2V0RGlzY2FyZFVudGFnZ2VkCigKICAgIElOIEdUX1FEX0RFViAgICAqZGV2LAogICAgSU4gR1RfTFBPUlQgICAgIHBvcnQsCiAgICBJTiBHVF9CT09MICAgICAgICBtb2RlCikKewogICAgR1RfVTE2ICAgICAgICAgIGRhdGE7CiAgICBHVF9TVEFUVVMgICAgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX1U4ICAgICAgICAgICBod1BvcnQ7ICAgICAgICAgLyogdGhlIHBoeXNpY2FsIHBvcnQgbnVtYmVyICAgICAqLwoKICAgIERCR19JTkZPKCgiZ3BydFNldERpc2NhcmRVbnRhZ2dlZCBDYWxsZWQuXG4iKSk7CgogICAgLyogdHJhbnNsYXRlIExQT1JUIHRvIGhhcmR3YXJlIHBvcnQgKi8KICAgIGh3UG9ydCA9IEdUX0xQT1JUXzJfUE9SVChwb3J0KTsKCiAgICAvKiBjaGVjayBpZiB0aGUgZ2l2ZW4gU3dpdGNoIHN1cHBvcnRzIHRoaXMgZmVhdHVyZS4gKi8KICAgIGlmICghKElTX0lOX0RFVl9HUk9VUChkZXYsREVWX0RJU0NBUkRfVEFHR0VEKSkgKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfTk9UX1NVUFBPUlRFRFxuIikpOwogICAgICAgIHJldHVybiBHVF9OT1RfU1VQUE9SVEVEOwogICAgfQoKICAgIC8qIHRyYW5zbGF0ZSBCT09MIHRvIGJpbmFyeSAqLwogICAgQk9PTF8yX0JJVChtb2RlLCBkYXRhKTsKCiAgICAvKiBTZXQgRGlzY2FyZFVuVGFnZ2VkLiAqLwogICAgcmV0VmFsID0gaHdTZXRQb3J0UmVnRmllbGQoZGV2LGh3UG9ydCwgUURfUkVHX1BPUlRfQ09OVFJPTDIsIDgsIDEsIGRhdGEpOwoKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBEQkdfSU5GTygoIk9LLlxuIikpOwogICAgfQogICAgcmV0dXJuIHJldFZhbDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3BydEdldERpc2NhcmRVbnRhZ2dlZAoqCiogREVTQ1JJUFRJT046CiogICAgICAgIFRoaXMgcm91dGluZSBnZXRzIERpc2NhcmRVbnRhZ2dlZCBiaXQgZm9yIHRoZSBnaXZlbiBwb3J0CioKKiBJTlBVVFM6CiogICAgICAgIHBvcnQgIC0gdGhlIGxvZ2ljYWwgcG9ydCBudW1iZXIuCioKKiBPVVRQVVRTOgoqICAgICAgICBtb2RlICAtIEdUX1RSVUUgaWYgRGlzY2FyZFVudGFnZ2VkIGJpdCBpcyBzZXQsIEdUX0ZBTFNFIG90aGVyd2lzZQoqCiogUkVUVVJOUzoKKiAgICAgICAgR1RfT0sgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICAgR1RfRkFJTCAtIG9uIGVycm9yCiogICAgICAgIEdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqCiogR2FsVGlzOgoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBncHJ0R2V0RGlzY2FyZFVudGFnZ2VkCigKICAgIElOICBHVF9RRF9ERVYgICAgKmRldiwKICAgIElOICBHVF9MUE9SVCAgICBwb3J0LAogICAgT1VUIEdUX0JPT0wgICAgICptb2RlCikKewogICAgR1RfU1RBVFVTICAgICAgIHJldFZhbDsgICAgICAgICAvKiBGdW5jdGlvbnMgcmV0dXJuIHZhbHVlLiAgICAgICovCiAgICBHVF9VOCAgICAgICAgICAgaHdQb3J0OyAgICAgICAgIC8qIHRoZSBwaHlzaWNhbCBwb3J0IG51bWJlciAgICAgKi8KICAgIEdUX1UxNiAgICAgICAgICBkYXRhOyAgICAgICAgICAgLyogdG8ga2VlcCB0aGUgcmVhZCB2YWx2ZSAgICAgICAqLwoKICAgIERCR19JTkZPKCgiZ3BydEdldERpc2NhcmRVblRhZ2dlZCBDYWxsZWQuXG4iKSk7CgogICAgLyogdHJhbnNsYXRlIExQT1JUIHRvIGhhcmR3YXJlIHBvcnQgKi8KICAgIGh3UG9ydCA9IEdUX0xQT1JUXzJfUE9SVChwb3J0KTsKCiAgICAvKiBjaGVjayBpZiB0aGUgZ2l2ZW4gU3dpdGNoIHN1cHBvcnRzIHRoaXMgZmVhdHVyZS4gKi8KICAgIGlmICghKElTX0lOX0RFVl9HUk9VUChkZXYsREVWX0RJU0NBUkRfVEFHR0VEKSkgKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfTk9UX1NVUFBPUlRFRFxuIikpOwogICAgICAgIHJldHVybiBHVF9OT1RfU1VQUE9SVEVEOwogICAgfQoKICAgIC8qIEdldCB0aGUgRGlzY2FyZFVuVGFnZ2VkLiAqLwogICAgcmV0VmFsID0gaHdHZXRQb3J0UmVnRmllbGQoZGV2LGh3UG9ydCwgUURfUkVHX1BPUlRfQ09OVFJPTDIsIDgsIDEsICZkYXRhKTsKCiAgICBCSVRfMl9CT09MKGRhdGEsICptb2RlKTsKCiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJPSy5cbiIpKTsKICAgIH0KCiAgICByZXR1cm4gcmV0VmFsOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdwcnRTZXRNYXBEQQoqCiogREVTQ1JJUFRJT046CiogICAgICAgIFdoZW4gdGhpcyBiaXQgaXMgc2V0IHRvIGEgb25lLCBub3JtYWwgc3dpdGNoIG9wZXJhdGlvbiB3aWxsIG9jY3VyIHdoZXJlIGEKKiAgICAgICAgZnJhbWUncyBEQSBhZGRyZXNzIGlzIHVzZWQgdG8gZGlyZWN0IHRoZSBmcmFtZSBvdXQgdGhlIGNvcnJlY3QgcG9ydC4KKiAgICAgICAgV2hlbiB0aGlzIGJlIGlzIGNsZWFyZWQgdG8gYSB6ZXJvLCB0aGUgZnJhbWUgd2lsbCBiZSBzZW50IG91dCB0aGUgcG9ydChzKQoqICAgICAgICBkZWZpbmVkIGJ5IEZvcndhcmRVbmtub3duIGJpdHMgb3IgdGhlIERlZmF1bHRGb3J3YXJkIGJpdHMgZXZlbiBpZiB0aGUgREEKKiAgICAgICAgaXMgb3VuZCBpbiB0aGUgYWRkcmVzcyBkYXRhYmFzZS4KKgoqIElOUFVUUzoKKiAgICAgICAgcG9ydCAtIHRoZSBsb2dpY2FsIHBvcnQgbnVtYmVyLgoqICAgICAgICBtb2RlIC0gR1RfVFJVRSB0byB1c2UgTWFwREEsIEdUX0ZBTFNFIG90aGVyd2lzZQoqCiogT1VUUFVUUzoKKiAgICAgICAgTm9uZS4KKgoqIFJFVFVSTlM6CiogICAgICAgIEdUX09LICAgLSBvbiBzdWNjZXNzCiogICAgICAgIEdUX0ZBSUwgLSBvbiBlcnJvcgoqICAgICAgICBHVF9OT1RfU1VQUE9SVEVEIC0gaWYgY3VycmVudCBkZXZpY2UgZG9lcyBub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCioKKiBDT01NRU5UUzoKKgoqIEdhbFRpczoKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3BydFNldE1hcERBCigKICAgIElOIEdUX1FEX0RFViAgICAqZGV2LAogICAgSU4gR1RfTFBPUlQgICAgIHBvcnQsCiAgICBJTiBHVF9CT09MICAgICAgICBtb2RlCikKewogICAgR1RfVTE2ICAgICAgICAgIGRhdGE7CiAgICBHVF9TVEFUVVMgICAgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX1U4ICAgICAgICAgICBod1BvcnQ7ICAgICAgICAgLyogdGhlIHBoeXNpY2FsIHBvcnQgbnVtYmVyICAgICAqLwoKICAgIERCR19JTkZPKCgiZ3BydFNldE1hcERBIENhbGxlZC5cbiIpKTsKCiAgICAvKiB0cmFuc2xhdGUgTFBPUlQgdG8gaGFyZHdhcmUgcG9ydCAqLwogICAgaHdQb3J0ID0gR1RfTFBPUlRfMl9QT1JUKHBvcnQpOwoKICAgIC8qIGNoZWNrIGlmIHRoZSBnaXZlbiBTd2l0Y2ggc3VwcG9ydHMgdGhpcyBmZWF0dXJlLiAqLwogICAgaWYgKCEoSVNfSU5fREVWX0dST1VQKGRldixERVZfTUFQX0RBKSkpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CgogICAgLyogdHJhbnNsYXRlIEJPT0wgdG8gYmluYXJ5ICovCiAgICBCT09MXzJfQklUKG1vZGUsIGRhdGEpOwoKICAgIC8qIFNldCBNYXBEQS4gKi8KICAgIHJldFZhbCA9IGh3U2V0UG9ydFJlZ0ZpZWxkKGRldixod1BvcnQsIFFEX1JFR19QT1JUX0NPTlRST0wyLCA3LCAxLCBkYXRhKTsKCiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJPSy5cbiIpKTsKICAgIH0KICAgIHJldHVybiByZXRWYWw7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdwcnRHZXRNYXBEQQoqCiogREVTQ1JJUFRJT046CiogICAgICAgIFRoaXMgcm91dGluZSBnZXRzIE1hcERBIGJpdCBmb3IgdGhlIGdpdmVuIHBvcnQKKgoqIElOUFVUUzoKKiAgICAgICAgcG9ydCAgLSB0aGUgbG9naWNhbCBwb3J0IG51bWJlci4KKgoqIE9VVFBVVFM6CiogICAgICAgIG1vZGUgIC0gR1RfVFJVRSBpZiBNYXBEQSBiaXQgaXMgc2V0LCBHVF9GQUxTRSBvdGhlcndpc2UKKgoqIFJFVFVSTlM6CiogICAgICAgIEdUX09LICAgLSBvbiBzdWNjZXNzCiogICAgICAgIEdUX0ZBSUwgLSBvbiBlcnJvcgoqICAgICAgICBHVF9OT1RfU1VQUE9SVEVEIC0gaWYgY3VycmVudCBkZXZpY2UgZG9lcyBub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCioKKiBDT01NRU5UUzoKKgoqIEdhbFRpczoKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3BydEdldE1hcERBCigKICAgIElOICBHVF9RRF9ERVYgICAgKmRldiwKICAgIElOICBHVF9MUE9SVCAgICBwb3J0LAogICAgT1VUIEdUX0JPT0wgICAgICptb2RlCikKewogICAgR1RfU1RBVFVTICAgICAgIHJldFZhbDsgICAgICAgICAvKiBGdW5jdGlvbnMgcmV0dXJuIHZhbHVlLiAgICAgICovCiAgICBHVF9VOCAgICAgICAgICAgaHdQb3J0OyAgICAgICAgIC8qIHRoZSBwaHlzaWNhbCBwb3J0IG51bWJlciAgICAgKi8KICAgIEdUX1UxNiAgICAgICAgICBkYXRhOyAgICAgICAgICAgLyogdG8ga2VlcCB0aGUgcmVhZCB2YWx2ZSAgICAgICAqLwoKICAgIERCR19JTkZPKCgiZ3BydEdldE1hcERBIENhbGxlZC5cbiIpKTsKCiAgICAvKiB0cmFuc2xhdGUgTFBPUlQgdG8gaGFyZHdhcmUgcG9ydCAqLwogICAgaHdQb3J0ID0gR1RfTFBPUlRfMl9QT1JUKHBvcnQpOwoKICAgIC8qIGNoZWNrIGlmIHRoZSBnaXZlbiBTd2l0Y2ggc3VwcG9ydHMgdGhpcyBmZWF0dXJlLiAqLwogICAgaWYgKCEoSVNfSU5fREVWX0dST1VQKGRldixERVZfTUFQX0RBKSkpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CgogICAgLyogR2V0IHRoZSBNYXBEQS4gKi8KICAgIHJldFZhbCA9IGh3R2V0UG9ydFJlZ0ZpZWxkKGRldixod1BvcnQsIFFEX1JFR19QT1JUX0NPTlRST0wyLCA3LCAxLCAmZGF0YSk7CgogICAgQklUXzJfQk9PTChkYXRhLCAqbW9kZSk7CgogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgewogICAgICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIERCR19JTkZPKCgiT0suXG4iKSk7CiAgICB9CgogICAgcmV0dXJuIHJldFZhbDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3BydFNldERlZmF1bHRGb3J3YXJkCioKKiBERVNDUklQVElPTjoKKiAgICAgICAgV2hlbiB0aGlzIGJpdCBpcyBzZXQgdG8gYSBvbmUsIG5vcm1hbCBzd2l0Y2ggb3BlcmF0aW9uIHdpbGwgb2NjdXJzIGFuZAoqICAgICAgICBtdWx0aWNhc3QgZnJhbWVzIHdpdGggdW5rbm93biBEQSBhZGRyZXNzZXMgYXJlIGFsbG93ZWQgdG8gZWdyZXNzIG91dCB0aGlzCiogICAgICAgIHBvcnQgKGFzc3VtaW5nIHRoZSBWTEFOIHNldHRpbmdzIGFsbG93IHRoZSBmcmFtZSB0byBlZ3Jlc3MgdGhpcyBwb3J0IHRvbykuCiogICAgICAgIFdoZW4gdGhpcyBiaXQgaXMgY2xlYXJlZCB0byBhIHplcm8sIG11bHRpY2FzdCBmcmFtZXMgd2l0aCB1bmtub3duIERBCiogICAgICAgIGFkZHJlc3NlcyB3aWxsIG5vdCBlZ3Jlc3Mgb3V0IHRoaXMgcG9ydC4KKgoqIElOUFVUUzoKKiAgICAgICAgcG9ydCAtIHRoZSBsb2dpY2FsIHBvcnQgbnVtYmVyLgoqICAgICAgICBtb2RlIC0gR1RfVFJVRSB0byB1c2UgRGVmYXVsdEZvcndhcmQsIEdUX0ZBTFNFIG90aGVyd2lzZQoqCiogT1VUUFVUUzoKKiAgICAgICAgTm9uZS4KKgoqIFJFVFVSTlM6CiogICAgICAgIEdUX09LICAgLSBvbiBzdWNjZXNzCiogICAgICAgIEdUX0ZBSUwgLSBvbiBlcnJvcgoqICAgICAgICBHVF9OT1RfU1VQUE9SVEVEIC0gaWYgY3VycmVudCBkZXZpY2UgZG9lcyBub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCioKKiBDT01NRU5UUzoKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3BydFNldERlZmF1bHRGb3J3YXJkCigKICAgIElOIEdUX1FEX0RFViAgICAqZGV2LAogICAgSU4gR1RfTFBPUlQgICAgIHBvcnQsCiAgICBJTiBHVF9CT09MICAgICAgICBtb2RlCikKewogICAgR1RfVTE2ICAgICAgICAgIGRhdGE7CiAgICBHVF9TVEFUVVMgICAgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX1U4ICAgICAgICAgICBod1BvcnQ7ICAgICAgICAgLyogdGhlIHBoeXNpY2FsIHBvcnQgbnVtYmVyICAgICAqLwoKICAgIERCR19JTkZPKCgiZ3BydFNldERlZmF1bHRGb3J3YXJkIENhbGxlZC5cbiIpKTsKCiAgICAvKiB0cmFuc2xhdGUgTFBPUlQgdG8gaGFyZHdhcmUgcG9ydCAqLwogICAgaHdQb3J0ID0gR1RfTFBPUlRfMl9QT1JUKHBvcnQpOwoKICAgIC8qIGNoZWNrIGlmIHRoZSBnaXZlbiBTd2l0Y2ggc3VwcG9ydHMgdGhpcyBmZWF0dXJlLiAqLwogICAgaWYgKCFJU19JTl9ERVZfR1JPVVAoZGV2LERFVl84OEU2MDkzX0ZBTUlMWSkpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CgogICAgLyogdHJhbnNsYXRlIEJPT0wgdG8gYmluYXJ5ICovCiAgICBCT09MXzJfQklUKG1vZGUsIGRhdGEpOwoKICAgIC8qIFNldCBEZWZhdWx0Rm9yd2FyZC4gKi8KICAgIGlmICghSVNfSU5fREVWX0dST1VQKGRldixERVZfRUdSRVNTX0ZMT09EKSkKICAgIHsKICAgICAgICByZXRWYWwgPSBod1NldFBvcnRSZWdGaWVsZChkZXYsaHdQb3J0LCBRRF9SRUdfUE9SVF9DT05UUk9MMiwgNiwgMSwgZGF0YSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgcmV0VmFsID0gaHdTZXRQb3J0UmVnRmllbGQoZGV2LGh3UG9ydCwgUURfUkVHX1BPUlRfQ09OVFJPTCwgMywgMSwgZGF0YSk7CiAgICB9CgogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgewogICAgICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIERCR19JTkZPKCgiT0suXG4iKSk7CiAgICB9CiAgICByZXR1cm4gcmV0VmFsOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBncHJ0R2V0RGVmYXVsdEZvcndhcmQKKgoqIERFU0NSSVBUSU9OOgoqICAgICAgICBUaGlzIHJvdXRpbmUgZ2V0cyBEZWZhdWx0Rm9yd2FyZCBiaXQgZm9yIHRoZSBnaXZlbiBwb3J0CioKKiBJTlBVVFM6CiogICAgICAgIHBvcnQgIC0gdGhlIGxvZ2ljYWwgcG9ydCBudW1iZXIuCioKKiBPVVRQVVRTOgoqICAgICAgICBtb2RlICAtIEdUX1RSVUUgaWYgRGVmYXVsdEZvcndhcmQgYml0IGlzIHNldCwgR1RfRkFMU0Ugb3RoZXJ3aXNlCioKKiBSRVRVUk5TOgoqICAgICAgICBHVF9PSyAgIC0gb24gc3VjY2VzcwoqICAgICAgICBHVF9GQUlMIC0gb24gZXJyb3IKKiAgICAgICAgR1RfTk9UX1NVUFBPUlRFRCAtIGlmIGN1cnJlbnQgZGV2aWNlIGRvZXMgbm90IHN1cHBvcnQgdGhpcyBmZWF0dXJlLgoqCiogQ09NTUVOVFM6CioKKiBHYWxUaXM6CioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdwcnRHZXREZWZhdWx0Rm9yd2FyZAooCiAgICBJTiAgR1RfUURfREVWICAgICpkZXYsCiAgICBJTiAgR1RfTFBPUlQgICAgcG9ydCwKICAgIE9VVCBHVF9CT09MICAgICAqbW9kZQopCnsKICAgIEdUX1NUQVRVUyAgICAgICByZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwogICAgR1RfVTggICAgICAgICAgIGh3UG9ydDsgICAgICAgICAvKiB0aGUgcGh5c2ljYWwgcG9ydCBudW1iZXIgICAgICovCiAgICBHVF9VMTYgICAgICAgICAgZGF0YTsgICAgICAgICAgIC8qIHRvIGtlZXAgdGhlIHJlYWQgdmFsdmUgICAgICAgKi8KCiAgICBEQkdfSU5GTygoImdwcnRHZXREZWZhdWx0Rm9yd2FyZCBDYWxsZWQuXG4iKSk7CgogICAgLyogdHJhbnNsYXRlIExQT1JUIHRvIGhhcmR3YXJlIHBvcnQgKi8KICAgIGh3UG9ydCA9IEdUX0xQT1JUXzJfUE9SVChwb3J0KTsKCiAgICAvKiBjaGVjayBpZiB0aGUgZ2l2ZW4gU3dpdGNoIHN1cHBvcnRzIHRoaXMgZmVhdHVyZS4gKi8KICAgIGlmICghSVNfSU5fREVWX0dST1VQKGRldixERVZfODhFNjA5M19GQU1JTFkpKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfTk9UX1NVUFBPUlRFRFxuIikpOwogICAgICAgIHJldHVybiBHVF9OT1RfU1VQUE9SVEVEOwogICAgfQoKICAgIC8qIEdldCB0aGUgRGVmYXVsdEZvcndhcmQuICovCiAgICBpZiAoIUlTX0lOX0RFVl9HUk9VUChkZXYsREVWX0VHUkVTU19GTE9PRCkpCiAgICB7CiAgICAgICAgcmV0VmFsID0gaHdHZXRQb3J0UmVnRmllbGQoZGV2LGh3UG9ydCwgUURfUkVHX1BPUlRfQ09OVFJPTDIsIDYsIDEsICZkYXRhKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICByZXRWYWwgPSBod0dldFBvcnRSZWdGaWVsZChkZXYsaHdQb3J0LCBRRF9SRUdfUE9SVF9DT05UUk9MLCAzLCAxLCAmZGF0YSk7CiAgICB9CgogICAgQklUXzJfQk9PTChkYXRhLCAqbW9kZSk7CgogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgewogICAgICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIERCR19JTkZPKCgiT0suXG4iKSk7CiAgICB9CgogICAgcmV0dXJuIHJldFZhbDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBncHJ0U2V0RWdyZXNzTW9uaXRvclNvdXJjZQoqCiogREVTQ1JJUFRJT046CiogICAgICAgIFdoZW4gdGhpcyBiZSBpcyBjbGVhcmVkIHRvIGEgemVybywgbm9ybWFsIG5ldHdvcmsgc3dpdGNoaW5nIG9jY3Vycy4KKiAgICAgICAgV2hlbiB0aGlzIGJpdCBpcyBzZXQgdG8gYSBvbmUsIGFueSBmcmFtZSB0aGF0IGVncmVzc2VzIG91dCB0aGlzIHBvcnQgd2lsbAoqICAgICAgICBhbHNvIGJlIHNlbnQgdG8gdGhlIEVncmVzc01vbml0b3JEZXN0IFBvcnQKKgoqIElOUFVUUzoKKiAgICAgICAgcG9ydCAtIHRoZSBsb2dpY2FsIHBvcnQgbnVtYmVyLgoqICAgICAgICBtb2RlIC0gR1RfVFJVRSB0byBzZXQgRWdyZXNzTW9uaXRvclNvdXJjZSwgR1RfRkFMU0Ugb3RoZXJ3aXNlCioKKiBPVVRQVVRTOgoqICAgICAgICBOb25lLgoqCiogUkVUVVJOUzoKKiAgICAgICAgR1RfT0sgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICAgR1RfRkFJTCAtIG9uIGVycm9yCiogICAgICAgIEdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqCiogR2FsVGlzOgoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBncHJ0U2V0RWdyZXNzTW9uaXRvclNvdXJjZQooCiAgICBJTiBHVF9RRF9ERVYgICAgKmRldiwKICAgIElOIEdUX0xQT1JUICAgICBwb3J0LAogICAgSU4gR1RfQk9PTCAgICAgICAgbW9kZQopCnsKICAgIEdUX1UxNiAgICAgICAgICBkYXRhOwogICAgR1RfU1RBVFVTICAgICAgIHJldFZhbDsgICAgICAgICAvKiBGdW5jdGlvbnMgcmV0dXJuIHZhbHVlLiAgICAgICovCiAgICBHVF9VOCAgICAgICAgICAgaHdQb3J0OyAgICAgICAgIC8qIHRoZSBwaHlzaWNhbCBwb3J0IG51bWJlciAgICAgKi8KCiAgICBEQkdfSU5GTygoImdwcnRTZXRFZ3Jlc3NNb25pdG9yU291cmNlIENhbGxlZC5cbiIpKTsKCiAgICAvKiB0cmFuc2xhdGUgTFBPUlQgdG8gaGFyZHdhcmUgcG9ydCAqLwogICAgaHdQb3J0ID0gR1RfTFBPUlRfMl9QT1JUKHBvcnQpOwoKICAgIC8qIGNoZWNrIGlmIHRoZSBnaXZlbiBTd2l0Y2ggc3VwcG9ydHMgdGhpcyBmZWF0dXJlLiAqLwogICAgaWYgKCFJU19JTl9ERVZfR1JPVVAoZGV2LERFVl84OEU2MDkzX0ZBTUlMWSkpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CgogICAgLyogdHJhbnNsYXRlIEJPT0wgdG8gYmluYXJ5ICovCiAgICBCT09MXzJfQklUKG1vZGUsIGRhdGEpOwoKICAgIC8qIFNldCBFZ3Jlc3NNb25pdG9yU291cmNlLiAqLwogICAgcmV0VmFsID0gaHdTZXRQb3J0UmVnRmllbGQoZGV2LGh3UG9ydCwgUURfUkVHX1BPUlRfQ09OVFJPTDIsIDUsIDEsIGRhdGEpOwoKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBEQkdfSU5GTygoIk9LLlxuIikpOwogICAgfQogICAgcmV0dXJuIHJldFZhbDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3BydEdldEVncmVzc01vbml0b3JTb3VyY2UKKgoqIERFU0NSSVBUSU9OOgoqICAgICAgICBUaGlzIHJvdXRpbmUgZ2V0cyBFZ3Jlc3NNb25pdG9yU291cmNlIGJpdCBmb3IgdGhlIGdpdmVuIHBvcnQKKgoqIElOUFVUUzoKKiAgICAgICAgcG9ydCAgLSB0aGUgbG9naWNhbCBwb3J0IG51bWJlci4KKgoqIE9VVFBVVFM6CiogICAgICAgIG1vZGUgIC0gR1RfVFJVRSBpZiBFZ3Jlc3NNb25pdG9yU291cmNlIGJpdCBpcyBzZXQsIEdUX0ZBTFNFIG90aGVyd2lzZQoqCiogUkVUVVJOUzoKKiAgICAgICAgR1RfT0sgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICAgR1RfRkFJTCAtIG9uIGVycm9yCiogICAgICAgIEdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqCiogR2FsVGlzOgoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBncHJ0R2V0RWdyZXNzTW9uaXRvclNvdXJjZQooCiAgICBJTiAgR1RfUURfREVWICAgICpkZXYsCiAgICBJTiAgR1RfTFBPUlQgICAgcG9ydCwKICAgIE9VVCBHVF9CT09MICAgICAqbW9kZQopCnsKICAgIEdUX1NUQVRVUyAgICAgICByZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwogICAgR1RfVTggICAgICAgICAgIGh3UG9ydDsgICAgICAgICAvKiB0aGUgcGh5c2ljYWwgcG9ydCBudW1iZXIgICAgICovCiAgICBHVF9VMTYgICAgICAgICAgZGF0YTsgICAgICAgICAgIC8qIHRvIGtlZXAgdGhlIHJlYWQgdmFsdmUgICAgICAgKi8KCiAgICBEQkdfSU5GTygoImdwcnRHZXRFZ3Jlc3NNb25pdG9yU291cmNlIENhbGxlZC5cbiIpKTsKCiAgICAvKiB0cmFuc2xhdGUgTFBPUlQgdG8gaGFyZHdhcmUgcG9ydCAqLwogICAgaHdQb3J0ID0gR1RfTFBPUlRfMl9QT1JUKHBvcnQpOwoKICAgIC8qIGNoZWNrIGlmIHRoZSBnaXZlbiBTd2l0Y2ggc3VwcG9ydHMgdGhpcyBmZWF0dXJlLiAqLwogICAgaWYgKCFJU19JTl9ERVZfR1JPVVAoZGV2LERFVl84OEU2MDkzX0ZBTUlMWSkpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CgogICAgLyogR2V0IHRoZSBFZ3Jlc3NNb25pdG9yU291cmNlLiAqLwogICAgcmV0VmFsID0gaHdHZXRQb3J0UmVnRmllbGQoZGV2LGh3UG9ydCwgUURfUkVHX1BPUlRfQ09OVFJPTDIsIDUsIDEsICZkYXRhKTsKCiAgICBCSVRfMl9CT09MKGRhdGEsICptb2RlKTsKCiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJPSy5cbiIpKTsKICAgIH0KCiAgICByZXR1cm4gcmV0VmFsOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBncHJ0U2V0SW5ncmVzc01vbml0b3JTb3VyY2UKKgoqIERFU0NSSVBUSU9OOgoqICAgICAgICBXaGVuIHRoaXMgYmUgaXMgY2xlYXJlZCB0byBhIHplcm8sIG5vcm1hbCBuZXR3b3JrIHN3aXRjaGluZyBvY2N1cnMuCiogICAgICAgIFdoZW4gdGhpcyBiaXQgaXMgc2V0IHRvIGEgb25lLCBhbnkgZnJhbWUgdGhhdCBlZ3Jlc3NlcyBvdXQgdGhpcyBwb3J0IHdpbGwKKiAgICAgICAgYWxzbyBiZSBzZW50IHRvIHRoZSBFZ3Jlc3NNb25pdG9yRGVzdCBQb3J0CioKKiBJTlBVVFM6CiogICAgICAgIHBvcnQgLSB0aGUgbG9naWNhbCBwb3J0IG51bWJlci4KKiAgICAgICAgbW9kZSAtIEdUX1RSVUUgdG8gc2V0IEVncmVzc01vbml0b3JTb3VyY2UsIEdUX0ZBTFNFIG90aGVyd2lzZQoqCiogT1VUUFVUUzoKKiAgICAgICAgTm9uZS4KKgoqIFJFVFVSTlM6CiogICAgICAgIEdUX09LICAgLSBvbiBzdWNjZXNzCiogICAgICAgIEdUX0ZBSUwgLSBvbiBlcnJvcgoqICAgICAgICBHVF9OT1RfU1VQUE9SVEVEIC0gaWYgY3VycmVudCBkZXZpY2UgZG9lcyBub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCioKKiBDT01NRU5UUzoKKgoqIEdhbFRpczoKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3BydFNldEluZ3Jlc3NNb25pdG9yU291cmNlCigKICAgIElOIEdUX1FEX0RFViAgICAqZGV2LAogICAgSU4gR1RfTFBPUlQgICAgIHBvcnQsCiAgICBJTiBHVF9CT09MICAgICAgICBtb2RlCikKewogICAgR1RfVTE2ICAgICAgICAgIGRhdGE7CiAgICBHVF9TVEFUVVMgICAgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX1U4ICAgICAgICAgICBod1BvcnQ7ICAgICAgICAgLyogdGhlIHBoeXNpY2FsIHBvcnQgbnVtYmVyICAgICAqLwoKICAgIERCR19JTkZPKCgiZ3BydFNldEluZ3Jlc3NNb25pdG9yU291cmNlIENhbGxlZC5cbiIpKTsKCiAgICAvKiB0cmFuc2xhdGUgTFBPUlQgdG8gaGFyZHdhcmUgcG9ydCAqLwogICAgaHdQb3J0ID0gR1RfTFBPUlRfMl9QT1JUKHBvcnQpOwoKICAgIC8qIGNoZWNrIGlmIHRoZSBnaXZlbiBTd2l0Y2ggc3VwcG9ydHMgdGhpcyBmZWF0dXJlLiAqLwogICAgaWYgKCFJU19JTl9ERVZfR1JPVVAoZGV2LERFVl84OEU2MDkzX0ZBTUlMWSkpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CgogICAgLyogdHJhbnNsYXRlIEJPT0wgdG8gYmluYXJ5ICovCiAgICBCT09MXzJfQklUKG1vZGUsIGRhdGEpOwoKICAgIC8qIFNldCBJbmdyZXNzTW9uaXRvclNvdXJjZS4gKi8KICAgIHJldFZhbCA9IGh3U2V0UG9ydFJlZ0ZpZWxkKGRldixod1BvcnQsIFFEX1JFR19QT1JUX0NPTlRST0wyLCA0LCAxLCBkYXRhKTsKCiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJPSy5cbiIpKTsKICAgIH0KICAgIHJldHVybiByZXRWYWw7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdwcnRHZXRJbmdyZXNzTW9uaXRvclNvdXJjZQoqCiogREVTQ1JJUFRJT046CiogICAgICAgIFRoaXMgcm91dGluZSBnZXRzIEluZ3Jlc3NNb25pdG9yU291cmNlIGJpdCBmb3IgdGhlIGdpdmVuIHBvcnQKKgoqIElOUFVUUzoKKiAgICAgICAgcG9ydCAgLSB0aGUgbG9naWNhbCBwb3J0IG51bWJlci4KKgoqIE9VVFBVVFM6CiogICAgICAgIG1vZGUgIC0gR1RfVFJVRSBpZiBJbmdyZXNzTW9uaXRvclNvdXJjZSBiaXQgaXMgc2V0LCBHVF9GQUxTRSBvdGhlcndpc2UKKgoqIFJFVFVSTlM6CiogICAgICAgIEdUX09LICAgLSBvbiBzdWNjZXNzCiogICAgICAgIEdUX0ZBSUwgLSBvbiBlcnJvcgoqICAgICAgICBHVF9OT1RfU1VQUE9SVEVEIC0gaWYgY3VycmVudCBkZXZpY2UgZG9lcyBub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCioKKiBDT01NRU5UUzoKKgoqIEdhbFRpczoKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3BydEdldEluZ3Jlc3NNb25pdG9yU291cmNlCigKICAgIElOICBHVF9RRF9ERVYgICAgKmRldiwKICAgIElOICBHVF9MUE9SVCAgICBwb3J0LAogICAgT1VUIEdUX0JPT0wgICAgICptb2RlCikKewogICAgR1RfU1RBVFVTICAgICAgIHJldFZhbDsgICAgICAgICAvKiBGdW5jdGlvbnMgcmV0dXJuIHZhbHVlLiAgICAgICovCiAgICBHVF9VOCAgICAgICAgICAgaHdQb3J0OyAgICAgICAgIC8qIHRoZSBwaHlzaWNhbCBwb3J0IG51bWJlciAgICAgKi8KICAgIEdUX1UxNiAgICAgICAgICBkYXRhOyAgICAgICAgICAgLyogdG8ga2VlcCB0aGUgcmVhZCB2YWx2ZSAgICAgICAqLwoKICAgIERCR19JTkZPKCgiZ3BydEdldEluZ3Jlc3NNb25pdG9yU291cmNlIENhbGxlZC5cbiIpKTsKCiAgICAvKiB0cmFuc2xhdGUgTFBPUlQgdG8gaGFyZHdhcmUgcG9ydCAqLwogICAgaHdQb3J0ID0gR1RfTFBPUlRfMl9QT1JUKHBvcnQpOwoKICAgIC8qIGNoZWNrIGlmIHRoZSBnaXZlbiBTd2l0Y2ggc3VwcG9ydHMgdGhpcyBmZWF0dXJlLiAqLwogICAgaWYgKCFJU19JTl9ERVZfR1JPVVAoZGV2LERFVl84OEU2MDkzX0ZBTUlMWSkpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CgogICAgLyogR2V0IHRoZSBJbmdyZXNzTW9uaXRvclNvdXJjZS4gKi8KICAgIHJldFZhbCA9IGh3R2V0UG9ydFJlZ0ZpZWxkKGRldixod1BvcnQsIFFEX1JFR19QT1JUX0NPTlRST0wyLCA0LCAxLCAmZGF0YSk7CgogICAgQklUXzJfQk9PTChkYXRhLCAqbW9kZSk7CgogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgewogICAgICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIERCR19JTkZPKCgiT0suXG4iKSk7CiAgICB9CgogICAgcmV0dXJuIHJldFZhbDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3BydFNldE1lc3NhZ2VQb3J0CioKKiBERVNDUklQVElPTjoKKiAgICAgICAgV2hlbiB0aGUgTGVhcm4yQWxsIGJpdCBpcyBzZXQgdG8gb25lLCBsZWFybmluZyBtZXNzYWdlIGZyYW1lcyBhcmUKKiAgICAgICAgZ2VuZXJhdGVkLiBUaGVzZSBmcmFtZXMgd2lsbCBiZSBzZW50IG91dCBhbGwgcG9ydHMgd2hvc2UgTWVzc2FnZSBQb3J0IGlzCiogICAgICAgIHNldCB0byBvbmUuCiogICAgICAgICBJZiB0aGlzIGZlYXR1cmUgaXMgdXNlZCwgaXQgaXMgcmVjb21tZW5kZWQgdGhhdCBhbGwgTWFydmVsbCBUYWcgcG9ydHMsCiogICAgICAgIGV4Y2VwdCBmb3IgdGhlIENQVSdzIHBvcnQsIGhhdmUgdGhlaXIgTWVzc2FnZVBvcnQgYml0IHNldCB0byBvbmUuCiogICAgICAgIFBvcnRzIHRoYXQgYXJlIG5vdCBNYXJ2ZWxsIFRhZyBwb3J0cyBzaG91bGQgbm90IGhhdmUgdGhlaXIgTWVzc2FnZSBQb3J0CiogICAgICAgIGJpdCBzZXQgdG8gb25lLgoqCioKKiBJTlBVVFM6CiogICAgICAgIHBvcnQgLSB0aGUgbG9naWNhbCBwb3J0IG51bWJlci4KKiAgICAgICAgbW9kZSAtIEdUX1RSVUUgdG8gbWFrZSB0aGlzIHBvcnQgYSBNZXNzYWdlIFBvcnQuIEdUX0ZBTFNFLCBvdGhlcndpc2UuCioKKiBPVVRQVVRTOgoqICAgICAgICBOb25lLgoqCiogUkVUVVJOUzoKKiAgICAgICAgR1RfT0sgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICAgR1RfRkFJTCAtIG9uIGVycm9yCiogICAgICAgIEdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBncHJ0U2V0TWVzc2FnZVBvcnQKKAogICAgSU4gR1RfUURfREVWICAgICpkZXYsCiAgICBJTiBHVF9MUE9SVCAgICAgcG9ydCwKICAgIElOIEdUX0JPT0wgICAgICAgIG1vZGUKKQp7CiAgICBHVF9VMTYgICAgICAgICAgZGF0YTsKICAgIEdUX1NUQVRVUyAgICAgICByZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwogICAgR1RfVTggICAgICAgICAgIGh3UG9ydDsgICAgICAgICAvKiB0aGUgcGh5c2ljYWwgcG9ydCBudW1iZXIgICAgICovCgogICAgREJHX0lORk8oKCJncHJ0U2V0TWVzc2FnZVBvcnQgQ2FsbGVkLlxuIikpOwoKICAgIC8qIHRyYW5zbGF0ZSBMUE9SVCB0byBoYXJkd2FyZSBwb3J0ICovCiAgICBod1BvcnQgPSBHVF9MUE9SVF8yX1BPUlQocG9ydCk7CgogICAgLyogY2hlY2sgaWYgdGhlIGdpdmVuIFN3aXRjaCBzdXBwb3J0cyB0aGlzIGZlYXR1cmUuICovCiAgICBpZiAoIUlTX0lOX0RFVl9HUk9VUChkZXYsREVWX1RSVU5LKSkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX05PVF9TVVBQT1JURURcbiIpKTsKICAgICAgICByZXR1cm4gR1RfTk9UX1NVUFBPUlRFRDsKICAgIH0KCiAgICAvKiB0cmFuc2xhdGUgQk9PTCB0byBiaW5hcnkgKi8KICAgIEJPT0xfMl9CSVQobW9kZSwgZGF0YSk7CgogICAgLyogU2V0IEluZ3Jlc3NNb25pdG9yU291cmNlLiAqLwogICAgcmV0VmFsID0gaHdTZXRQb3J0UmVnRmllbGQoZGV2LGh3UG9ydCwgUURfUkVHX1BPUlRfQ09OVFJPTDEsIDE1LCAxLCBkYXRhKTsKCiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJPSy5cbiIpKTsKICAgIH0KICAgIHJldHVybiByZXRWYWw7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdwcnRHZXRNZXNzYWdlUG9ydAoqCiogREVTQ1JJUFRJT046CiogICAgICAgIFdoZW4gdGhlIExlYXJuMkFsbCBiaXQgaXMgc2V0IHRvIG9uZSwgbGVhcm5pbmcgbWVzc2FnZSBmcmFtZXMgYXJlCiogICAgICAgIGdlbmVyYXRlZC4gVGhlc2UgZnJhbWVzIHdpbGwgYmUgc2VudCBvdXQgYWxsIHBvcnRzIHdob3NlIE1lc3NhZ2UgUG9ydCBpcwoqICAgICAgICBzZXQgdG8gb25lLgoqICAgICAgICAgSWYgdGhpcyBmZWF0dXJlIGlzIHVzZWQsIGl0IGlzIHJlY29tbWVuZGVkIHRoYXQgYWxsIE1hcnZlbGwgVGFnIHBvcnRzLAoqICAgICAgICBleGNlcHQgZm9yIHRoZSBDUFUncyBwb3J0LCBoYXZlIHRoZWlyIE1lc3NhZ2VQb3J0IGJpdCBzZXQgdG8gb25lLgoqICAgICAgICBQb3J0cyB0aGF0IGFyZSBub3QgTWFydmVsbCBUYWcgcG9ydHMgc2hvdWxkIG5vdCBoYXZlIHRoZWlyIE1lc3NhZ2UgUG9ydAoqICAgICAgICBiaXQgc2V0IHRvIG9uZS4KKgoqCiogSU5QVVRTOgoqICAgICAgICBwb3J0IC0gdGhlIGxvZ2ljYWwgcG9ydCBudW1iZXIuCioKKiBPVVRQVVRTOgoqICAgICAgICBtb2RlIC0gR1RfVFJVRSB0byBtYWtlIHRoaXMgcG9ydCBhIE1lc3NhZ2UgUG9ydC4gR1RfRkFMU0UsIG90aGVyd2lzZS4KKgoqIFJFVFVSTlM6CiogICAgICAgIEdUX09LICAgLSBvbiBzdWNjZXNzCiogICAgICAgIEdUX0ZBSUwgLSBvbiBlcnJvcgoqICAgICAgICBHVF9OT1RfU1VQUE9SVEVEIC0gaWYgY3VycmVudCBkZXZpY2UgZG9lcyBub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCioKKiBDT01NRU5UUzoKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3BydEdldE1lc3NhZ2VQb3J0CigKICAgIElOICBHVF9RRF9ERVYgICAgKmRldiwKICAgIElOICBHVF9MUE9SVCAgICBwb3J0LAogICAgT1VUIEdUX0JPT0wgICAgICptb2RlCikKewogICAgR1RfU1RBVFVTICAgICAgIHJldFZhbDsgICAgICAgICAvKiBGdW5jdGlvbnMgcmV0dXJuIHZhbHVlLiAgICAgICovCiAgICBHVF9VOCAgICAgICAgICAgaHdQb3J0OyAgICAgICAgIC8qIHRoZSBwaHlzaWNhbCBwb3J0IG51bWJlciAgICAgKi8KICAgIEdUX1UxNiAgICAgICAgICBkYXRhOyAgICAgICAgICAgLyogdG8ga2VlcCB0aGUgcmVhZCB2YWx2ZSAgICAgICAqLwoKICAgIERCR19JTkZPKCgiZ3BydEdldE1lc3NhZ2VQb3J0IENhbGxlZC5cbiIpKTsKCiAgICAvKiB0cmFuc2xhdGUgTFBPUlQgdG8gaGFyZHdhcmUgcG9ydCAqLwogICAgaHdQb3J0ID0gR1RfTFBPUlRfMl9QT1JUKHBvcnQpOwoKICAgIC8qIGNoZWNrIGlmIHRoZSBnaXZlbiBTd2l0Y2ggc3VwcG9ydHMgdGhpcyBmZWF0dXJlLiAqLwogICAgaWYgKCFJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9UUlVOSykpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CgogICAgLyogR2V0IHRoZSBJbmdyZXNzTW9uaXRvclNvdXJjZS4gKi8KICAgIHJldFZhbCA9IGh3R2V0UG9ydFJlZ0ZpZWxkKGRldixod1BvcnQsIFFEX1JFR19QT1JUX0NPTlRST0wxLCAxNSwgMSwgJmRhdGEpOwoKICAgIEJJVF8yX0JPT0woZGF0YSwgKm1vZGUpOwoKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBEQkdfSU5GTygoIk9LLlxuIikpOwogICAgfQoKICAgIHJldHVybiByZXRWYWw7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdwcnRTZXRUcnVua1BvcnQKKgoqIERFU0NSSVBUSU9OOgoqICAgICAgICBUaGlzIGZ1bmN0aW9uIGVuYWJsZXMvZGlzYWJsZXMgYW5kIHNldHMgdGhlIHRydW5rIElELgoqCiogSU5QVVRTOgoqICAgICAgICBwb3J0IC0gdGhlIGxvZ2ljYWwgcG9ydCBudW1iZXIuCiogICAgICAgIGVuIC0gR1RfVFJVRSB0byBtYWtlIHRoZSBwb3J0IGJlIGEgbWVtYmVyIG9mIGEgdHJ1bmsgd2l0aCB0aGUgZ2l2ZW4gdHJ1bmtJZC4KKiAgICAgICAgICAgICBHVF9GQUxTRSwgb3RoZXJ3aXNlLgoqICAgICAgICB0cnVua0lkIC0gdmFsaWQgSUQgaXMgMCB+IDE1LgoqCiogT1VUUFVUUzoKKiAgICAgICAgTm9uZS4KKgoqIFJFVFVSTlM6CiogICAgICAgIEdUX09LICAgLSBvbiBzdWNjZXNzCiogICAgICAgIEdUX0ZBSUwgLSBvbiBlcnJvcgoqICAgICAgICBHVF9CQURfUEFSQU0gLSBpZiB0cnVua0lkIGlzIG5laXRoZXIgdmFsaWQgbm9yIElOVkFMSURfVFJVTktfSUQKKiAgICAgICAgR1RfTk9UX1NVUFBPUlRFRCAtIGlmIGN1cnJlbnQgZGV2aWNlIGRvZXMgbm90IHN1cHBvcnQgdGhpcyBmZWF0dXJlLgoqCiogQ09NTUVOVFM6CioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdwcnRTZXRUcnVua1BvcnQKKAogICAgSU4gR1RfUURfREVWICAgICpkZXYsCiAgICBJTiBHVF9MUE9SVCAgICAgcG9ydCwKICAgIElOIEdUX0JPT0wgICAgICAgICBlbiwKICAgIElOIEdUX1UzMiAgICAgICAgdHJ1bmtJZAopCnsKICAgIEdUX1UxNiAgICAgICAgICBkYXRhOwogICAgR1RfU1RBVFVTICAgICAgIHJldFZhbDsgICAgICAgICAvKiBGdW5jdGlvbnMgcmV0dXJuIHZhbHVlLiAgICAgICovCiAgICBHVF9VOCAgICAgICAgICAgaHdQb3J0OyAgICAgICAgIC8qIHRoZSBwaHlzaWNhbCBwb3J0IG51bWJlciAgICAgKi8KCiAgICBEQkdfSU5GTygoImdwcnRTZXRUcnVua1BvcnQgQ2FsbGVkLlxuIikpOwoKICAgIC8qIHRyYW5zbGF0ZSBMUE9SVCB0byBoYXJkd2FyZSBwb3J0ICovCiAgICBod1BvcnQgPSBHVF9MUE9SVF8yX1BPUlQocG9ydCk7CgogICAgLyogY2hlY2sgaWYgdGhlIGdpdmVuIFN3aXRjaCBzdXBwb3J0cyB0aGlzIGZlYXR1cmUuICovCiAgICBpZiAoIUlTX0lOX0RFVl9HUk9VUChkZXYsREVWX1RSVU5LKSkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX05PVF9TVVBQT1JURURcbiIpKTsKICAgICAgICByZXR1cm4gR1RfTk9UX1NVUFBPUlRFRDsKICAgIH0KCiAgICAvKiB0cmFuc2xhdGUgQk9PTCB0byBiaW5hcnkgKi8KICAgIEJPT0xfMl9CSVQoZW4sIGRhdGEpOwoKICAgIGlmKGVuID09IEdUX1RSVUUpCiAgICB7CiAgICAgICAgLyogbmVlZCB0byBlbmFibGUgdHJ1bmsuIHNvIGNoZWNrIHRoZSB0cnVua0lkICovCiAgICAgICAgaWYgKCFJU19UUlVOS19JRF9WQUxJRChkZXYsIHRydW5rSWQpKQogICAgICAgIHsKICAgICAgICAgICAgREJHX0lORk8oKCJHVF9CQURfUEFSQU1cbiIpKTsKICAgICAgICAgICAgcmV0dXJuIEdUX0JBRF9QQVJBTTsKICAgICAgICB9CgogICAgICAgIC8qIFNldCBUcnVua0lkLiAqLwogICAgICAgIGlmIChJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9UUlVOS19ORVdfSURfTE9DQVRJT04pKQogICAgICAgIHsKICAgICAgICAgICAgcmV0VmFsID0gaHdTZXRQb3J0UmVnRmllbGQoZGV2LGh3UG9ydCwgUURfUkVHX1BPUlRfQ09OVFJPTDEsIDgsIDQsIChHVF9VMTYpdHJ1bmtJZCk7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIHJldFZhbCA9IGh3U2V0UG9ydFJlZ0ZpZWxkKGRldixod1BvcnQsIFFEX1JFR19QT1JUX0NPTlRST0wxLCA0LCA0LCAoR1RfVTE2KXRydW5rSWQpOwogICAgICAgIH0KCiAgICAgICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgICAgIHsKICAgICAgICAgICAgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICAgICAgICAgIHJldHVybiByZXRWYWw7CiAgICAgICAgfQoKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICAvKgogICAgICAgICAgIE5lZWQgdG8gcmVzZXQgdHJ1bmtJZCBmb3IgODhFNjA5NSByZXYwLgogICAgICAgICovCiAgICAgICAgaWYgKElTX0lOX0RFVl9HUk9VUChkZXYsREVWX05FV19GRUFUVVJFX0lOX1JFVikgJiYKICAgICAgICAgICAgKChHVF9ERVZJQ0VfUkVWKWRldi0+cmV2aXNpb24gPCBHVF9SRVZfMSkpCiAgICAgICAgewogICAgICAgICAgICB0cnVua0lkID0gMDsKCiAgICAgICAgICAgIC8qIFNldCBUcnVua0lkLiAqLwogICAgICAgICAgICByZXRWYWwgPSBod1NldFBvcnRSZWdGaWVsZChkZXYsaHdQb3J0LCBRRF9SRUdfUE9SVF9DT05UUk9MMSwgNCwgNCwgKEdUX1UxNil0cnVua0lkKTsKICAgICAgICAgICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgICAgICAgICAgICAgIHJldHVybiByZXRWYWw7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyogU2V0IFRydW5rUG9ydCBiaXQuICovCiAgICByZXRWYWwgPSBod1NldFBvcnRSZWdGaWVsZChkZXYsaHdQb3J0LCBRRF9SRUdfUE9SVF9DT05UUk9MMSwgMTQsIDEsIGRhdGEpOwoKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBEQkdfSU5GTygoIk9LLlxuIikpOwogICAgfQogICAgcmV0dXJuIHJldFZhbDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBncHJ0R2V0VHJ1bmtQb3J0CioKKiBERVNDUklQVElPTjoKKiAgICAgICAgVGhpcyBmdW5jdGlvbiByZXR1cm5zIHRydW5rIHN0YXRlIG9mIHRoZSBwb3J0LgoqICAgICAgICBXaGVuIHRydW5rIGlzIGRpc2FibGVkLCB0cnVua0lkIGZpZWxkIHdvbid0IGhhdmUgdmFsaWQgdmFsdWUuCioKKiBJTlBVVFM6CiogICAgICAgIHBvcnQgLSB0aGUgbG9naWNhbCBwb3J0IG51bWJlci4KKgoqIE9VVFBVVFM6CiogICAgICAgIGVuIC0gR1RfVFJVRSwgaWYgdGhlIHBvcnQgaXMgYSBtZW1iZXIgb2YgYSB0cnVuaywKKiAgICAgICAgICAgICBHVF9GQUxTRSwgb3RoZXJ3aXNlLgoqICAgICAgICB0cnVua0lkIC0gMCB+IDE1LCB2YWxpZCBvbmx5IGlmIGVuIGlzIEdUX1RSVUUKKgoqIFJFVFVSTlM6CiogICAgICAgIEdUX09LICAgLSBvbiBzdWNjZXNzCiogICAgICAgIEdUX0ZBSUwgLSBvbiBlcnJvcgoqICAgICAgICBHVF9OT1RfU1VQUE9SVEVEIC0gaWYgY3VycmVudCBkZXZpY2UgZG9lcyBub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCioKKiBDT01NRU5UUzoKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3BydEdldFRydW5rUG9ydAooCiAgICBJTiBHVF9RRF9ERVYgICAgKmRldiwKICAgIElOIEdUX0xQT1JUICAgICBwb3J0LAogICAgT1VUIEdUX0JPT0wgICAgICplbiwKICAgIE9VVCBHVF9VMzIgICAgICAgICp0cnVua0lkCikKewogICAgR1RfVTE2ICAgICAgICAgIGRhdGE7CiAgICBHVF9TVEFUVVMgICAgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX1U4ICAgICAgICAgICBod1BvcnQ7ICAgICAgICAgLyogdGhlIHBoeXNpY2FsIHBvcnQgbnVtYmVyICAgICAqLwoKICAgIERCR19JTkZPKCgiZ3BydEdldFRydW5rUG9ydCBDYWxsZWQuXG4iKSk7CgogICAgLyogdHJhbnNsYXRlIExQT1JUIHRvIGhhcmR3YXJlIHBvcnQgKi8KICAgIGh3UG9ydCA9IEdUX0xQT1JUXzJfUE9SVChwb3J0KTsKCiAgICAvKiBjaGVjayBpZiB0aGUgZ2l2ZW4gU3dpdGNoIHN1cHBvcnRzIHRoaXMgZmVhdHVyZS4gKi8KICAgIGlmICghSVNfSU5fREVWX0dST1VQKGRldixERVZfVFJVTkspKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfTk9UX1NVUFBPUlRFRFxuIikpOwogICAgICAgIHJldHVybiBHVF9OT1RfU1VQUE9SVEVEOwogICAgfQoKICAgIGRhdGEgPSAwOwoKICAgIHJldFZhbCA9IGh3R2V0UG9ydFJlZ0ZpZWxkKGRldixod1BvcnQsIFFEX1JFR19QT1JUX0NPTlRST0wxLCAxNCwgMSwgJmRhdGEpOwoKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgICAgICByZXR1cm4gcmV0VmFsOwogICAgfQoKICAgIEJJVF8yX0JPT0woZGF0YSwgKmVuKTsKCiAgICBpZiAoSVNfSU5fREVWX0dST1VQKGRldixERVZfVFJVTktfTkVXX0lEX0xPQ0FUSU9OKSkKICAgIHsKICAgICAgICByZXRWYWwgPSBod0dldFBvcnRSZWdGaWVsZChkZXYsaHdQb3J0LCBRRF9SRUdfUE9SVF9DT05UUk9MMSwgOCwgNCwgJmRhdGEpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIHJldFZhbCA9IGh3R2V0UG9ydFJlZ0ZpZWxkKGRldixod1BvcnQsIFFEX1JFR19QT1JUX0NPTlRST0wxLCA0LCA0LCAmZGF0YSk7CiAgICB9CgogICAgKnRydW5rSWQgPSAoR1RfVTMyKWRhdGE7CgoKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBEQkdfSU5GTygoIk9LLlxuIikpOwogICAgfQogICAgcmV0dXJuIHJldFZhbDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3BydEdldERpc2NhcmRCQ2FzdE1vZGUKKgoqIERFU0NSSVBUSU9OOgoqICAgICAgIFRoaXMgcm91dGluZSBnZXRzIHRoZSBEaXNjYXJkIEJyb2FkY2FzdCBNb2RlLiBJZiB0aGUgbW9kZSBpcyBlbmFibGVkLAoqICAgICAgICBhbGwgdGhlIGJyb2FkY2FzdCBmcmFtZXMgdG8gdGhlIGdpdmVuIHBvcnQgd2lsbCBiZSBkaXNjYXJkZWQuCioKKiBJTlBVVFM6CiogICAgICAgcG9ydCAtIGxvZ2ljYWwgcG9ydCBudW1iZXIKKgoqIE9VVFBVVFM6CiogICAgICAgIGVuIC0gR1RfVFJVRSwgaWYgZW5hYmxlZCwKKiAgICAgICAgICAgICBHVF9GQUxTRSwgb3RoZXJ3aXNlLgoqCiogUkVUVVJOUzoKKiAgICAgICBHVF9PSyAgICAgICAgICAgLSBvbiBzdWNjZXNzCiogICAgICAgR1RfRkFJTCAgICAgICAgIC0gb24gZXJyb3IKKiAgICAgICAgR1RfTk9UX1NVUFBPUlRFRCAtIGlmIGN1cnJlbnQgZGV2aWNlIGRvZXMgbm90IHN1cHBvcnQgdGhpcyBmZWF0dXJlLgoqCiogQ09NTUVOVFM6CiogICAgICAgTm9uZS4KKgoqIEdhbFRpczoKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3BydEdldERpc2NhcmRCQ2FzdE1vZGUKKAogICAgSU4gIEdUX1FEX0RFViAgICAqZGV2LAogICAgSU4gIEdUX0xQT1JUICAgICBwb3J0LAogICAgT1VUIEdUX0JPT0wgICAgICAqZW4KKQp7CiAgICBHVF9VMTYgICAgICAgICAgZGF0YTsKICAgIEdUX1NUQVRVUyAgICAgICByZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwogICAgR1RfVTggICAgICAgICAgIGh3UG9ydDsgICAgICAgICAvKiB0aGUgcGh5c2ljYWwgcG9ydCBudW1iZXIgICAgICovCgogICAgREJHX0lORk8oKCJncHJ0R2V0RGlzY2FyZEJDYXN0TW9kZSBDYWxsZWQuXG4iKSk7CgogICAgLyogdHJhbnNsYXRlIExQT1JUIHRvIGhhcmR3YXJlIHBvcnQgKi8KICAgIGh3UG9ydCA9IEdUX0xQT1JUXzJfUE9SVChwb3J0KTsKCiAgICAvKiBjaGVjayBpZiB0aGUgZ2l2ZW4gU3dpdGNoIHN1cHBvcnRzIHRoaXMgZmVhdHVyZS4gKi8KICAgIGlmICghSVNfSU5fREVWX0dST1VQKGRldixERVZfRFJPUF9CQ0FTVCkpCiAgICB7CiAgICAgICAgaWYgKCFJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9ORVdfRkVBVFVSRV9JTl9SRVYpIHx8CiAgICAgICAgICAgICgoR1RfREVWSUNFX1JFVilkZXYtPnJldmlzaW9uIDwgR1RfUkVWXzEpKQogICAgICAgIHsKICAgICAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CiAgICAgICAgICAgIHJldHVybiBHVF9OT1RfU1VQUE9SVEVEOwogICAgICAgIH0KICAgIH0KCiAgICBkYXRhID0gMDsKCiAgICByZXRWYWwgPSBod0dldFBvcnRSZWdGaWVsZChkZXYsaHdQb3J0LCAweDE1LCA2LCAxLCAmZGF0YSk7CgogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgewogICAgICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAgICAgIHJldHVybiByZXRWYWw7CiAgICB9CgogICAgQklUXzJfQk9PTChkYXRhLCAqZW4pOwoKICAgIHJldHVybiBHVF9PSzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3BydFNldERpc2NhcmRCQ2FzdE1vZGUKKgoqIERFU0NSSVBUSU9OOgoqICAgICAgIFRoaXMgcm91dGluZSBzZXRzIHRoZSBEaXNjYXJkIEJyb2FkY2FzdCBtb2RlLgoqICAgICAgICBJZiB0aGUgbW9kZSBpcyBlbmFibGVkLCBhbGwgdGhlIGJyb2FkY2FzdCBmcmFtZXMgdG8gdGhlIGdpdmVuIHBvcnQgd2lsbAoqICAgICAgICBiZSBkaXNjYXJkZWQuCioKKiBJTlBVVFM6CiogICAgICAgcG9ydCAtIGxvZ2ljYWwgcG9ydCBudW1iZXIKKiAgICAgICAgZW4gLSBHVF9UUlVFLCB0byBlbmFibGUgdGhlIG1vZGUsCiogICAgICAgICAgICAgR1RfRkFMU0UsIG90aGVyd2lzZS4KKgoqIE9VVFBVVFM6CiogICAgICAgIE5vbmUKKgoqIFJFVFVSTlM6CiogICAgICAgR1RfT0sgICAgICAgICAgIC0gb24gc3VjY2VzcwoqICAgICAgIEdUX0ZBSUwgICAgICAgICAtIG9uIGVycm9yCiogICAgICAgIEdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqICAgICAgIE5vbmUuCioKKiBHYWxUaXM6CioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdwcnRTZXREaXNjYXJkQkNhc3RNb2RlCigKICAgIElOICBHVF9RRF9ERVYgICAgKmRldiwKICAgIElOICBHVF9MUE9SVCAgICAgcG9ydCwKICAgIElOICBHVF9CT09MICAgICAgZW4KKQp7CiAgICBHVF9VMTYgICAgICAgICAgZGF0YTsgICAgICAgICAgIC8qIFVzZWQgdG8gcG9sbCB0aGUgZGF0YSAqLwogICAgR1RfU1RBVFVTICAgICAgIHJldFZhbDsgICAgICAgICAvKiBGdW5jdGlvbnMgcmV0dXJuIHZhbHVlLiAgICAgICovCiAgICBHVF9VOCAgICAgICAgICAgaHdQb3J0OyAgICAgICAgIC8qIHRoZSBwaHlzaWNhbCBwb3J0IG51bWJlciAgICAgKi8KCiAgICBEQkdfSU5GTygoImdwcnRTZXREaXNjYXJkQkNhc3RNb2RlIENhbGxlZC5cbiIpKTsKCiAgICAvKiB0cmFuc2xhdGUgTFBPUlQgdG8gaGFyZHdhcmUgcG9ydCAqLwogICAgaHdQb3J0ID0gR1RfTFBPUlRfMl9QT1JUKHBvcnQpOwoKICAgIC8qIGNoZWNrIGlmIHRoZSBnaXZlbiBTd2l0Y2ggc3VwcG9ydHMgdGhpcyBmZWF0dXJlLiAqLwogICAgaWYgKCFJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9EUk9QX0JDQVNUKSkKICAgIHsKICAgICAgICBpZiAoIUlTX0lOX0RFVl9HUk9VUChkZXYsREVWX05FV19GRUFUVVJFX0lOX1JFVikgfHwKICAgICAgICAgICAgKChHVF9ERVZJQ0VfUkVWKWRldi0+cmV2aXNpb24gPCBHVF9SRVZfMSkpCiAgICAgICAgewogICAgICAgICAgICBEQkdfSU5GTygoIkdUX05PVF9TVVBQT1JURURcbiIpKTsKICAgICAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICAgICAgfQogICAgfQoKICAgIC8qIHRyYW5zbGF0ZSBCT09MIHRvIGJpbmFyeSAqLwogICAgQk9PTF8yX0JJVChlbiwgZGF0YSk7CgogICAgcmV0VmFsID0gaHdTZXRQb3J0UmVnRmllbGQoZGV2LGh3UG9ydCwgMHgxNSwgNiwgMSwgZGF0YSk7CgogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgewogICAgICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAgICAgIHJldHVybiByZXRWYWw7CiAgICB9CgogICAgcmV0dXJuIEdUX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdwcnRHZXRGQ09uUmF0ZUxpbWl0TW9kZQoqCiogREVTQ1JJUFRJT046CiogICAgICAgVGhpcyByb3V0aW5lIHJldHVybnMgbW9kZSB0aGF0IHRlbGxzIGlmIGluZ3Jlc3MgcmF0ZSBsaW1pdGluZyB1c2VzIEZsb3cKKiAgICAgICAgQ29udHJvbC4gV2hlbiB0aGlzIG1vZGUgaXMgZW5hYmxlZCBhbmQgdGhlIHBvcnQgcmVjZWl2ZXMgZnJhbWVzIG92ZXIgdGhlCiogICAgICAgIGxpbWl0LCBJbmdyZXNzIFJhdGUgTGltaXRpbmcgd2lsbCBiZSBwZXJmb3JtZWQgYnkgc3RhbGxpbmcgdGhlCiogICAgICAgIGxpbmsgcGFydG5lciB1c2luZyBmbG93IGNvbnRyb2wsIGluc3RlYWQgb2YgZGlzY2FyZGluZyBmcmFtZXMuCioKKiBJTlBVVFM6CiogICAgICAgcG9ydCAtIGxvZ2ljYWwgcG9ydCBudW1iZXIKKgoqIE9VVFBVVFM6CiogICAgICAgIGVuIC0gR1RfVFJVRSwgaWYgdGhlIG1vZGUgaXMgZW5hYmxlZCwKKiAgICAgICAgICAgICBHVF9GQUxTRSwgb3RoZXJ3aXNlLgoqCiogUkVUVVJOUzoKKiAgICAgICBHVF9PSyAgICAgICAgICAgLSBvbiBzdWNjZXNzCiogICAgICAgR1RfRkFJTCAgICAgICAgIC0gb24gZXJyb3IKKiAgICAgICAgR1RfTk9UX1NVUFBPUlRFRCAtIGlmIGN1cnJlbnQgZGV2aWNlIGRvZXMgbm90IHN1cHBvcnQgdGhpcyBmZWF0dXJlLgoqCiogQ09NTUVOVFM6CiogICAgICAgIEluIG9yZGVyIGZvciB0aGlzIG1vZGUgdG8gd29yaywgRmxvdyBDb250cm9sIGFuZCBSYXRlIExpbWl0aW5nCiogICAgICAgIHNob3VsZCBiZSBjb25maWd1cmVkIHByb3Blcmx5LgoqCiogR2FsVGlzOgoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBncHJ0R2V0RkNPblJhdGVMaW1pdE1vZGUKKAogICAgSU4gIEdUX1FEX0RFViAgICAqZGV2LAogICAgSU4gIEdUX0xQT1JUICAgICBwb3J0LAogICAgT1VUIEdUX0JPT0wgICAgICAqZW4KKQp7CiAgICBHVF9VMTYgICAgICAgICAgZGF0YTsKICAgIEdUX1NUQVRVUyAgICAgICByZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwogICAgR1RfVTggICAgICAgICAgIGh3UG9ydDsgICAgICAgICAvKiB0aGUgcGh5c2ljYWwgcG9ydCBudW1iZXIgICAgICovCgogICAgREJHX0lORk8oKCJncHJ0R2V0RkNPblJhdGVMaW1pdE1vZGUgQ2FsbGVkLlxuIikpOwoKICAgIC8qIHRyYW5zbGF0ZSBMUE9SVCB0byBoYXJkd2FyZSBwb3J0ICovCiAgICBod1BvcnQgPSBHVF9MUE9SVF8yX1BPUlQocG9ydCk7CgogICAgLyogY2hlY2sgaWYgdGhlIGdpdmVuIFN3aXRjaCBzdXBwb3J0cyB0aGlzIGZlYXR1cmUuICovCiAgICBpZiAoIUlTX0lOX0RFVl9HUk9VUChkZXYsREVWX0JVUlNUX1JBVEUpKQogICAgewogICAgICAgICAgICBEQkdfSU5GTygoIkdUX05PVF9TVVBQT1JURURcbiIpKTsKICAgICAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CgogICAgZGF0YSA9IDA7CgogICAgcmV0VmFsID0gaHdHZXRQb3J0UmVnRmllbGQoZGV2LGh3UG9ydCwgMHgxNSwgNCwgMiwgJmRhdGEpOwoKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgICAgICByZXR1cm4gcmV0VmFsOwogICAgfQoKICAgIGlmIChkYXRhID09IDB4MykKICAgICAgICAqZW4gPSBHVF9UUlVFOwogICAgZWxzZQogICAgICAgICplbiA9IEdUX0ZBTFNFOwoKICAgIHJldHVybiBHVF9PSzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3BydFNldEZDT25SYXRlTGltaXRNb2RlCioKKiBERVNDUklQVElPTjoKKiAgICAgICBUaGlzIHJvdXRpbmUgc2V0cyB0aGUgbW9kZSB0aGF0IHRlbGxzIGlmIGluZ3Jlc3MgcmF0ZSBsaW1pdGluZyB1c2VzIEZsb3cKKiAgICAgICAgQ29udHJvbC4gV2hlbiB0aGlzIG1vZGUgaXMgZW5hYmxlZCBhbmQgdGhlIHBvcnQgcmVjZWl2ZXMgZnJhbWVzIG92ZXIgdGhlCiogICAgICAgIGxpbWl0LCBJbmdyZXNzIFJhdGUgTGltaXRpbmcgd2lsbCBiZSBwZXJmb3JtZWQgYnkgc3RhbGxpbmcgdGhlCiogICAgICAgIGxpbmsgcGFydG5lciB1c2luZyBmbG93IGNvbnRyb2wsIGluc3RlYWQgb2YgZGlzY2FyZGluZyBmcmFtZXMuCioKKiBJTlBVVFM6CiogICAgICAgcG9ydCAtIGxvZ2ljYWwgcG9ydCBudW1iZXIKKiAgICAgICAgZW4gLSBHVF9UUlVFLCB0byBlbmFibGUgdGhlIG1vZGUsCiogICAgICAgICAgICAgR1RfRkFMU0UsIG90aGVyd2lzZS4KKgoqIE9VVFBVVFM6CiogICAgICAgIE5vbmUKKgoqIFJFVFVSTlM6CiogICAgICAgR1RfT0sgICAgICAgICAgIC0gb24gc3VjY2VzcwoqICAgICAgIEdUX0ZBSUwgICAgICAgICAtIG9uIGVycm9yCiogICAgICAgIEdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqICAgICAgIFRoaXMgcm91dGluZSB3b24ndCBjb25maWd1cmUgRmxvdyBDb250cm9sIG9yIFJhdGUgTGltaXRpbmcuCiogICAgICAgIEluIG9yZGVyIGZvciB0aGlzIG1vZGUgdG8gd29yaywgRmxvdyBDb250cm9sIGFuZCBSYXRlIExpbWl0aW5nCiogICAgICAgIHNob3VsZCBiZSBjb25maWd1cmVkIHByb3Blcmx5LgoqCiogR2FsVGlzOgoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBncHJ0U2V0RkNPblJhdGVMaW1pdE1vZGUKKAogICAgSU4gIEdUX1FEX0RFViAgICAqZGV2LAogICAgSU4gIEdUX0xQT1JUICAgICBwb3J0LAogICAgSU4gIEdUX0JPT0wgICAgICBlbgopCnsKICAgIEdUX1UxNiAgICAgICAgICBkYXRhOwogICAgR1RfU1RBVFVTICAgICAgIHJldFZhbDsgICAgICAgICAvKiBGdW5jdGlvbnMgcmV0dXJuIHZhbHVlLiAgICAgICovCiAgICBHVF9VOCAgICAgICAgICAgaHdQb3J0OyAgICAgICAgIC8qIHRoZSBwaHlzaWNhbCBwb3J0IG51bWJlciAgICAgKi8KCiAgICBEQkdfSU5GTygoImdwcnRTZXRGQ09uUmF0ZUxpbWl0TW9kZSBDYWxsZWQuXG4iKSk7CgogICAgLyogdHJhbnNsYXRlIExQT1JUIHRvIGhhcmR3YXJlIHBvcnQgKi8KICAgIGh3UG9ydCA9IEdUX0xQT1JUXzJfUE9SVChwb3J0KTsKCiAgICAvKiBjaGVjayBpZiB0aGUgZ2l2ZW4gU3dpdGNoIHN1cHBvcnRzIHRoaXMgZmVhdHVyZS4gKi8KICAgIGlmICghSVNfSU5fREVWX0dST1VQKGRldixERVZfQlVSU1RfUkFURSkpCiAgICB7CiAgICAgICAgICAgIERCR19JTkZPKCgiR1RfTk9UX1NVUFBPUlRFRFxuIikpOwogICAgICAgICAgICByZXR1cm4gR1RfTk9UX1NVUFBPUlRFRDsKICAgIH0KCiAgICAvKiB0cmFuc2xhdGUgQk9PTCB0byBiaW5hcnkgKi8KICAgIGlmIChlbikKICAgICAgICBkYXRhID0gMHgzOwogICAgZWxzZQogICAgICAgIGRhdGEgPSAwOwoKICAgIHJldFZhbCA9IGh3U2V0UG9ydFJlZ0ZpZWxkKGRldixod1BvcnQsIDB4MTUsIDQsIDIsIGRhdGEpOwoKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgICAgICByZXR1cm4gcmV0VmFsOwogICAgfQoKICAgIHJldHVybiBHVF9PSzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3BydFNldFNBRmlsdGVyaW5nCioKKiBERVNDUklQVElPTjoKKiAgICAgICAgVGhpcyByb3V0aW5lIHNldCB0aGUgU291cmNlIEFkZHJlc3MoU0EpIGZpdGVyaW5nIG1ldGhvZC4KKiAgICAgICAgICAgIEdUX1NBX0ZJTFRFUklOR19ESVNBQkxFIDoKKiAgICAgICAgICAgICAgICBubyBmcmFtZSB3aWxsIGJlIGZpbHRlcmVkLgoqICAgICAgICAgICAgR1RfU0FfRFJPUF9PTl9MT0NLIDoKKiAgICAgICAgICAgICAgICBkaXNjYXJkIGlmIFNBIGZpZWxkIGlzIG5vdCBpbiB0aGUgQVRVJ3MgYWRkcmVzcyBkYXRhYmFzZS4KKiAgICAgICAgICAgIEdUX1NBX0RST1BfT05fVU5MT0NLIDoKKiAgICAgICAgICAgICAgICBkaXNjYXJkIGlmIFNBIGZpZWxkIGlzIGluIHRoZSBBVFUncyBhZGRyZXNzIGRhdGFiYXNlIGFzIFN0YXRpYwoqICAgICAgICAgICAgICAgIGVudHJ5IHdpdGggYSBQb3J0VmVjIG9mIGFsbCB6ZXJvcy4KKiAgICAgICAgICAgIEdUX1NBX0RST1BfVE9fQ1BVIDoKKiAgICAgICAgICAgICAgICBJbmdyZXNzaW5nIGZyYW1lcyB3aWxsIGJlIG1hcHBlZCB0byB0aGUgQ1BVIFBvcnQgaWYgdGhlaXIgU0EKKiAgICAgICAgICAgICAgICBmaWVsZCBpcyBpbiB0aGUgQVRVJ3MgYWRkcmVzcyBkYXRhYmFzZSBhcyBTdGF0aWMgZW50cnkgd2l0aCBhCiogICAgICAgICAgICAgICAgUG9ydFZlYyBvZiBhbGwgemVyb3MuIE90aGVyd2lzZSwgdGhlIGZyYW1lcyB3aWxsIGJlIGRpc2NhcmRlZAoqICAgICAgICAgICAgICAgIGlmIHRoZWlyIFNBIGZpZWxkIGlzIG5vdCBpbiB0aGUgQVRVJ3MgYWRkcmVzcyBkYXRhYmFzZSBvciBpZiB0aGlzCiogICAgICAgICAgICAgICAgcG9ydCdzIGJpdCBpcyBub3Qgc2V0IGluIHRoZSBQb3J0VmVjIGJpdHMgZm9yIHRoZSBmcmFtZSdzIFNBLgoqCiogSU5QVVRTOgoqICAgICAgIHBvcnQgLSB0aGUgbG9naWNhbCBwb3J0IG51bWJlci4KKiAgICAgICBtb2RlIC0gR1RfU0FfRklMVEVSSU5HIHN0cnVjdHVyZQoqCiogT1VUUFVUUzoKKiAgICAgICBOb25lLgoqCiogUkVUVVJOUzoKKiAgICAgICBHVF9PSyAgIC0gb24gc3VjY2VzcwoqICAgICAgIEdUX0ZBSUwgLSBvbiBlcnJvcgoqCiogQ09NTUVOVFM6CioKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3BydFNldFNBRmlsdGVyaW5nCigKICAgIElOIEdUX1FEX0RFViAgKmRldiwKICAgIElOIEdUX0xQT1JUICAgcG9ydCwKICAgIElOIEdUX1NBX0ZJTFRFUklORyAgICBtb2RlCikKewogICAgR1RfU1RBVFVTICAgICAgIHJldFZhbDsgICAgICAgICAvKiBGdW5jdGlvbnMgcmV0dXJuIHZhbHVlLiAgICAgICovCiAgICBHVF9VOCAgICAgICAgICAgaHdQb3J0OyAgICAgICAgIC8qIHRoZSBwaHlzaWNhbCBwb3J0IG51bWJlciAgICAgKi8KICAgIEdUX1UxNiAgICAgICAgICAgIGRhdGE7CgogICAgREJHX0lORk8oKCJncHJ0U2V0U0FGaWx0ZXJpbmcgQ2FsbGVkLlxuIikpOwoKICAgIC8qIHRyYW5zbGF0ZSBMUE9SVCB0byBoYXJkd2FyZSBwb3J0ICovCiAgICBod1BvcnQgPSBHVF9MUE9SVF8yX1BPUlQocG9ydCk7CgogICAgLyogY2hlY2sgaWYgZGV2aWNlIGFsbG93cyB0byBmb3JjZSBhIGZsb3djb250cm9sIGRpc2FibGVkICovCiAgICBpZiAoIUlTX0lOX0RFVl9HUk9VUChkZXYsREVWX1NBX0ZJTFRFUklORykpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVELlxuIikpOwogICAgICAgIHJldHVybiBHVF9OT1RfU1VQUE9SVEVEOwogICAgfQoKICAgIGRhdGEgPSAoR1RfVTE2KSBtb2RlOwoKICAgIC8qIFNldCB0aGUgU0EgRmlsdGVyaW5nIGJpdHMuICAqLwogICAgcmV0VmFsID0gaHdTZXRQb3J0UmVnRmllbGQoZGV2LGh3UG9ydCwgUURfUkVHX1BPUlRfQ09OVFJPTCwxNCwyLGRhdGEpOwogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgewogICAgICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIERCR19JTkZPKCgiT0suXG4iKSk7CiAgICB9CgogICAgcmV0dXJuIHJldFZhbDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3BydEdldFNBRmlsdGVyaW5nCioKKiBERVNDUklQVElPTjoKKiAgICAgICAgVGhpcyByb3V0aW5lIGdldHMgdGhlIFNvdXJjZSBBZGRyZXNzKFNBKSBmaXRlcmluZyBtZXRob2QuCiogICAgICAgICAgICBHVF9TQV9GSUxURVJJTkdfRElTQUJMRSA6CiogICAgICAgICAgICAgICAgbm8gZnJhbWUgd2lsbCBiZSBmaWx0ZXJlZC4KKiAgICAgICAgICAgIEdUX1NBX0RST1BfT05fTE9DSyA6CiogICAgICAgICAgICAgICAgZGlzY2FyZCBpZiBTQSBmaWVsZCBpcyBub3QgaW4gdGhlIEFUVSdzIGFkZHJlc3MgZGF0YWJhc2UuCiogICAgICAgICAgICBHVF9TQV9EUk9QX09OX1VOTE9DSyA6CiogICAgICAgICAgICAgICAgZGlzY2FyZCBpZiBTQSBmaWVsZCBpcyBpbiB0aGUgQVRVJ3MgYWRkcmVzcyBkYXRhYmFzZSBhcyBTdGF0aWMKKiAgICAgICAgICAgICAgICBlbnRyeSB3aXRoIGEgUG9ydFZlYyBvZiBhbGwgemVyb3MuCiogICAgICAgICAgICBHVF9TQV9EUk9QX1RPX0NQVSA6CiogICAgICAgICAgICAgICAgSW5ncmVzc2luZyBmcmFtZXMgd2lsbCBiZSBtYXBwZWQgdG8gdGhlIENQVSBQb3J0IGlmIHRoZWlyIFNBCiogICAgICAgICAgICAgICAgZmllbGQgaXMgaW4gdGhlIEFUVSdzIGFkZHJlc3MgZGF0YWJhc2UgYXMgU3RhdGljIGVudHJ5IHdpdGggYQoqICAgICAgICAgICAgICAgIFBvcnRWZWMgb2YgYWxsIHplcm9zLiBPdGhlcndpc2UsIHRoZSBmcmFtZXMgd2lsbCBiZSBkaXNjYXJkZWQKKiAgICAgICAgICAgICAgICBpZiB0aGVpciBTQSBmaWVsZCBpcyBub3QgaW4gdGhlIEFUVSdzIGFkZHJlc3MgZGF0YWJhc2Ugb3IgaWYgdGhpcwoqICAgICAgICAgICAgICAgIHBvcnQncyBiaXQgaXMgbm90IHNldCBpbiB0aGUgUG9ydFZlYyBiaXRzIGZvciB0aGUgZnJhbWUncyBTQS4KKgoqIElOUFVUUzoKKiAgICAgICBwb3J0IC0gdGhlIGxvZ2ljYWwgcG9ydCBudW1iZXIuCioKKiBPVVRQVVRTOgoqICAgICAgIG1vZGUgLSBHVF9TQV9GSUxURVJJTkcgc3RydWN0dXJlCioKKiBSRVRVUk5TOgoqICAgICAgIEdUX09LICAgLSBvbiBzdWNjZXNzCiogICAgICAgR1RfRkFJTCAtIG9uIGVycm9yCioKKiBDT01NRU5UUzoKKgoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBncHJ0R2V0U0FGaWx0ZXJpbmcKKAogICAgSU4gIEdUX1FEX0RFViAgKmRldiwKICAgIElOICBHVF9MUE9SVCAgIHBvcnQsCiAgICBPVVQgR1RfU0FfRklMVEVSSU5HICAgICptb2RlCikKewogICAgR1RfU1RBVFVTICAgICAgIHJldFZhbDsgICAgICAgICAvKiBGdW5jdGlvbnMgcmV0dXJuIHZhbHVlLiAgICAgICovCiAgICBHVF9VOCAgICAgICAgICAgaHdQb3J0OyAgICAgICAgIC8qIHRoZSBwaHlzaWNhbCBwb3J0IG51bWJlciAgICAgKi8KICAgIEdUX1UxNiAgICAgICAgICAgIGRhdGE7CgogICAgREJHX0lORk8oKCJncHJ0U2V0U0FGaWx0ZXJpbmcgQ2FsbGVkLlxuIikpOwoKICAgIC8qIHRyYW5zbGF0ZSBMUE9SVCB0byBoYXJkd2FyZSBwb3J0ICovCiAgICBod1BvcnQgPSBHVF9MUE9SVF8yX1BPUlQocG9ydCk7CgogICAgLyogY2hlY2sgaWYgZGV2aWNlIGFsbG93cyB0byBmb3JjZSBhIGZsb3djb250cm9sIGRpc2FibGVkICovCiAgICBpZiAoIUlTX0lOX0RFVl9HUk9VUChkZXYsREVWX1NBX0ZJTFRFUklORykpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVELlxuIikpOwogICAgICAgIHJldHVybiBHVF9OT1RfU1VQUE9SVEVEOwogICAgfQoKICAgIC8qIEdldCB0aGUgU0EgRmlsdGVyaW5nIGJpdHMuICAqLwogICAgcmV0VmFsID0gaHdHZXRQb3J0UmVnRmllbGQoZGV2LGh3UG9ydCwgUURfUkVHX1BPUlRfQ09OVFJPTCwxNCwyLCZkYXRhKTsKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBEQkdfSU5GTygoIk9LLlxuIikpOwogICAgfQoKICAgICptb2RlID0gKEdUX1NBX0ZJTFRFUklORylkYXRhOwoKICAgIHJldHVybiByZXRWYWw7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdwcnRTZXRBUlB0b0NQVQoqCiogREVTQ1JJUFRJT046CiogICAgICAgIFdoZW4gQVJQdG9DUFUgKG9yIEFSUCBNaXJyb3IpIGlzIHNldCB0byBHVF9UUlVFLCBBUlAgZnJhbWVzIGFyZSBtaXJyb3JlZAoqICAgICAgICB0byB0aGUgQ1BVIHBvcnQuCioKKiBJTlBVVFM6CiogICAgICAgcG9ydCAtIHRoZSBsb2dpY2FsIHBvcnQgbnVtYmVyLgoqICAgICAgIG1vZGUgLSBHVF9UUlVFLCB0byBtYXAgQVJQIGZyYW1lcyB0byBDUFUgUG9ydCwKKiAgICAgICAgICAgICAgIEdUX0ZBTFNFLCBvdGhlcndpc2UuCioKKiBPVVRQVVRTOgoqICAgICAgIE5vbmUuCioKKiBSRVRVUk5TOgoqICAgICAgIEdUX09LICAgLSBvbiBzdWNjZXNzCiogICAgICAgR1RfRkFJTCAtIG9uIGVycm9yCioKKiBDT01NRU5UUzoKKgoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBncHJ0U2V0QVJQdG9DUFUKKAogICAgSU4gR1RfUURfREVWICAqZGV2LAogICAgSU4gR1RfTFBPUlQgICBwb3J0LAogICAgSU4gR1RfQk9PTCAgICBtb2RlCikKewogICAgR1RfVTE2ICAgICAgICAgICAgZGF0YTsKICAgIEdUX1NUQVRVUyAgICAgICByZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwogICAgR1RfVTggICAgICAgICAgIGh3UG9ydDsgICAgICAgICAvKiB0aGUgcGh5c2ljYWwgcG9ydCBudW1iZXIgICAgICovCgogICAgREJHX0lORk8oKCJncHJ0U2V0QVJQdG9DUFUgQ2FsbGVkLlxuIikpOwoKICAgIC8qIHRyYW5zbGF0ZSBMUE9SVCB0byBoYXJkd2FyZSBwb3J0ICovCiAgICBod1BvcnQgPSBHVF9MUE9SVF8yX1BPUlQocG9ydCk7CgogICAgLyogY2hlY2sgaWYgZGV2aWNlIGFsbG93cyB0byBmb3JjZSBhIGZsb3djb250cm9sIGRpc2FibGVkICovCiAgICBpZiAoIUlTX0lOX0RFVl9HUk9VUChkZXYsREVWX0FSUF9UT19DUFUpKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfTk9UX1NVUFBPUlRFRC5cbiIpKTsKICAgICAgICByZXR1cm4gR1RfTk9UX1NVUFBPUlRFRDsKICAgIH0KCiAgICAvKiB0cmFuc2xhdGUgQk9PTCB0byBiaW5hcnkgKi8KICAgIEJPT0xfMl9CSVQobW9kZSwgZGF0YSk7CgogICAgLyogU2V0IHRoZSBBUlB0b0NQVSBiaXRzLiAgKi8KICAgIGlmIChJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9GQVNURVRIX1NXSVRDSCkpCiAgICAgICAgcmV0VmFsID0gaHdTZXRQb3J0UmVnRmllbGQoZGV2LGh3UG9ydCwgUURfUkVHX1BPUlRfQ09OVFJPTCw4LDEsZGF0YSk7CiAgICBlbHNlCiAgICAgICAgcmV0VmFsID0gaHdTZXRQb3J0UmVnRmllbGQoZGV2LGh3UG9ydCwgUURfUkVHX1BPUlRfQ09OVFJPTDIsNiwxLGRhdGEpOwogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgewogICAgICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIERCR19JTkZPKCgiT0suXG4iKSk7CiAgICB9CgogICAgcmV0dXJuIHJldFZhbDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3BydEdldEFSUHRvQ1BVCioKKiBERVNDUklQVElPTjoKKiAgICAgICAgV2hlbiBBUlB0b0NQVSAob3IgQVJQIE1pcnJvcikgaXMgc2V0IHRvIEdUX1RSVUUsIEFSUCBmcmFtZXMgYXJlIG1pcnJvcmVkCiogICAgICAgIHRvIHRoZSBDUFUgcG9ydC4KKgoqIElOUFVUUzoKKiAgICAgICBwb3J0IC0gdGhlIGxvZ2ljYWwgcG9ydCBudW1iZXIuCioKKiBPVVRQVVRTOgoqICAgICAgIG1vZGUgLSBHVF9UUlVFLCB0byBtYXAgQVJQIGZyYW1lcyB0byBDUFUgUG9ydCwKKiAgICAgICAgICAgICAgIEdUX0ZBTFNFLCBvdGhlcndpc2UuCioKKiBSRVRVUk5TOgoqICAgICAgIEdUX09LICAgLSBvbiBzdWNjZXNzCiogICAgICAgR1RfRkFJTCAtIG9uIGVycm9yCioKKiBDT01NRU5UUzoKKgoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBncHJ0R2V0QVJQdG9DUFUKKAogICAgSU4gIEdUX1FEX0RFViAgKmRldiwKICAgIElOICBHVF9MUE9SVCAgIHBvcnQsCiAgICBPVVQgR1RfQk9PTCAgICAqbW9kZQopCnsKICAgIEdUX1UxNiAgICAgICAgICAgIGRhdGE7CiAgICBHVF9TVEFUVVMgICAgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX1U4ICAgICAgICAgICBod1BvcnQ7ICAgICAgICAgLyogdGhlIHBoeXNpY2FsIHBvcnQgbnVtYmVyICAgICAqLwoKICAgIERCR19JTkZPKCgiZ3BydEdldEFSUHRvQ1BVIENhbGxlZC5cbiIpKTsKCiAgICAvKiB0cmFuc2xhdGUgTFBPUlQgdG8gaGFyZHdhcmUgcG9ydCAqLwogICAgaHdQb3J0ID0gR1RfTFBPUlRfMl9QT1JUKHBvcnQpOwoKICAgIC8qIGNoZWNrIGlmIGRldmljZSBzdXBwb3J0cyB0aGUgZmVhdHVyZSAqLwogICAgaWYgKCFJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9BUlBfVE9fQ1BVKSkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX05PVF9TVVBQT1JURUQuXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CgogICAgLyogR2V0IHRoZSBBUlB0b0NQVSBiaXRzLiAgKi8KICAgIGlmIChJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9GQVNURVRIX1NXSVRDSCkpCiAgICAgICAgcmV0VmFsID0gaHdHZXRQb3J0UmVnRmllbGQoZGV2LGh3UG9ydCwgUURfUkVHX1BPUlRfQ09OVFJPTCw4LDEsJmRhdGEpOwogICAgZWxzZQogICAgICAgIHJldFZhbCA9IGh3R2V0UG9ydFJlZ0ZpZWxkKGRldixod1BvcnQsIFFEX1JFR19QT1JUX0NPTlRST0wyLDYsMSwmZGF0YSk7CiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJPSy5cbiIpKTsKICAgIH0KCiAgICBCSVRfMl9CT09MKGRhdGEsICptb2RlKTsKCiAgICByZXR1cm4gcmV0VmFsOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBnc3lzU2V0TGVhcm4yQWxsCioKKiBERVNDUklQVElPTjoKKiAgICAgICBlbmFibGUgdGhlIExlYXJuIHRvIEFsbCBkZXZpY2VzIGluIGEgU3dpdGNoLCB0aGlzIG11c3QgYmUgZW5hYmxlZCBmb3IKKiAgICAgICBoYXJkd2FyZSBsZWFybiBsaW1pdGluZyBpcyBlbmFibGVkIG9uIGFueSBwb3J0IG9uIGFueSBkZXZpY2UKKgoqIElOUFVUUzoKKiAgICAgICAgZW4gLSBHVF9UUlVFIGlmIExlYXJuMkFsbCBpcyBzZXQuIEdUX0ZBTFNFLCBvdGhlcndpc2UuCioKKiBPVVRQVVRTOgoqICAgICAgICBOb25lLgoqCiogUkVUVVJOUzoKKiAgICAgICAgR1RfT0sgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICAgR1RfRkFJTCAtIG9uIGVycm9yCiogICAgICAgIEdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqICAgICAgICBOb25lLgoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBnc3lzU2V0TGVhcm4yQWxsCigKICAgIElOIEdUX1FEX0RFViAgICAqZGV2LAogICAgSU4gR1RfQk9PTCAgICAgICAgZW4KKQp7CiAgICBHVF9TVEFUVVMgICAgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX1UxNiAgICAgICAgICAgIGRhdGE7CgogICAgREJHX0lORk8oKCJnc3lzU2V0TGVhcm4yQWxsIENhbGxlZC5cbiIpKTsKCiAgICBCT09MXzJfQklUKGVuLCBkYXRhKTsKCiAgICAvKiBTZXQgcmVsYXRlZCBiaXQgKi8KICAgIHJldFZhbCA9IGh3U2V0R2xvYmFsUmVnRmllbGQoZGV2LFFEX1JFR19BR0VUSU1FX0xBX0NPTlRST0wsMywxLCBkYXRhKTsKCiAgICBpZiAocmV0VmFsICE9IEdUX09LKQogICAgewogICAgICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAgICAgIHJldHVybiByZXRWYWw7CiAgICB9CgogICAgREJHX0lORk8oKCJPSy5cbiIpKTsKICAgIHJldHVybiBHVF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBnc3lzR2V0TGVhcm4yQWxsCioKKiBERVNDUklQVElPTjoKKiAgICAgICByZXR1cm5zIHRoZSBzdGF0ZSBvZiBMZWFybiB0byBBbGwgZGV2aWNlcyBpbiBhIFN3aXRjaCBmbGFnCioKKiBJTlBVVFM6CiogICAgICAgIE5vbmUuCioKKiBPVVRQVVRTOgoqICAgICAgICBlbiAtIEdUX1RSVUUgaWYgTGVhcm4yQWxsIGlzIHNldC4gR1RfRkFMU0UsIG90aGVyd2lzZS4KKgoqIFJFVFVSTlM6CiogICAgICAgIEdUX09LICAgLSBvbiBzdWNjZXNzCiogICAgICAgIEdUX0ZBSUwgLSBvbiBlcnJvcgoqICAgICAgICBHVF9OT1RfU1VQUE9SVEVEIC0gaWYgY3VycmVudCBkZXZpY2UgZG9lcyBub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCioKKiBDT01NRU5UUzoKKiAgICAgICAgTm9uZS4KKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3N5c0dldExlYXJuMkFsbAooCiAgICBJTiBHVF9RRF9ERVYgICAgKmRldiwKICAgIElOIEdUX0JPT0wgICAgICAgKmVuCikKewogICAgR1RfU1RBVFVTICAgICAgIHJldFZhbDsgICAgICAgICAvKiBGdW5jdGlvbnMgcmV0dXJuIHZhbHVlLiAgICAgICovCiAgICBHVF9VMTYgICAgICAgICAgICBkYXRhOwoKICAgIERCR19JTkZPKCgiZ3N5c0dldExlYXJuMkFsbCBDYWxsZWQuXG4iKSk7CgogICAgLyogU2V0IHJlbGF0ZWQgYml0ICovCiAgICByZXRWYWwgPSBod0dldEdsb2JhbFJlZ0ZpZWxkKGRldiwgUURfUkVHX0FHRVRJTUVfTEFfQ09OVFJPTCwgMywgMSwgJmRhdGEpOwoKICAgIGlmIChyZXRWYWwgIT0gR1RfT0spCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICAgICAgcmV0dXJuIHJldFZhbDsKICAgIH0KCiAgICBCSVRfMl9CT09MKGRhdGEsICplbik7CgogICAgREJHX0lORk8oKCJPSy5cbiIpKTsKICAgIHJldHVybiBHVF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBncHJ0U2V0RWdyZXNzRmxvb2QKKgoqIERFU0NSSVBUSU9OOgoqICAgICAgIFRoaXMgcm91dGluZSBzZXQgRWdyZXNzIEZsb29kaW5nIE1vZGUuCiogICAgICAgIEZyYW1lcyB3aXRoIHVua25vd24gREEgKERlc3RpbmF0aW9uIEFkZHJlc3MgdGhhdCBpcyBub3QgaW4gQVRVIGRhdGFiYXNlKQoqICAgICAgICBnZW5lcmFsbHkgZmxvb2Qgb3V0IGFsbCB0aGUgcG9ydHMuIFRoaXMgbW9kZSBjYW4gYmUgdXNlZCB0byBwcmV2ZW50CiogICAgICAgIHRob3NlIGZyYW1lcyBmcm9tIGVncmVzc2luZyB0aGlzIHBvcnQgYXMgZm9sbG93czoKKiAgICAgICAgICAgIEdUX0JMT0NLX0VHUkVTU19VTktOT1dOCiogICAgICAgICAgICAgICAgZG8gbm90IGVncmVzcyBmcmFtZSB3aXRoIHVua25vd24gREEgKGJvdGggdW5pY2FzdCBhbmQgbXVsdGljYXN0KQoqICAgICAgICAgICAgR1RfQkxPQ0tfRUdSRVNTX1VOS05PV05fTVVMVElDQVNUCiogICAgICAgICAgICAgICAgZG8gbm90IGVncmVzcyBmcmFtZSB3aXRoIHVua25vd24gbXVsdGljYXN0IERBCiogICAgICAgICAgICBHVF9CTE9DS19FR1JFU1NfVU5LTk9XTl9VTklDQVNUCiogICAgICAgICAgICAgICAgZG8gbm90IGVncmVzcyBmcmFtZSB3aXRoIHVua25vd24gdW5pY2FzdCBEQQoqICAgICAgICAgICAgR1RfQkxPQ0tfRUdSRVNTX05PTkUKKiAgICAgICAgICAgICAgICBlZ3Jlc3MgYWxsIGZyYW1lcyB3aXRoIHVua25vd24gREEKKgoqIElOUFVUUzoKKiAgICAgICBwb3J0IC0gdGhlIGxvZ2ljYWwgcG9ydCBudW1iZXIuCiogICAgICAgbW9kZSAtIEdUX0VHUkVTU19GTE9PRCB0eXBlCioKKiBPVVRQVVRTOgoqICAgICAgIE5vbmUuCioKKiBSRVRVUk5TOgoqICAgICAgIEdUX09LICAgLSBvbiBzdWNjZXNzCiogICAgICAgR1RfRkFJTCAtIG9uIGVycm9yCioKKiBDT01NRU5UUzoKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3BydFNldEVncmVzc0Zsb29kCigKICAgIElOICBHVF9RRF9ERVYgICAqZGV2LAogICAgSU4gIEdUX0xQT1JUICAgICBwb3J0LAogICAgSU4gIEdUX0VHUkVTU19GTE9PRCAgICAgIG1vZGUKKQp7CiAgICBHVF9TVEFUVVMgICAgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX1U4ICAgICAgICAgICBod1BvcnQ7ICAgICAgICAgLyogdGhlIHBoeXNpY2FsIHBvcnQgbnVtYmVyICAgICAqLwogICAgR1RfVTE2ICAgICAgICAgICAgZGF0YTsKCiAgICBEQkdfSU5GTygoImdwcnRTZXRFZ3Jlc3NGbG9vZCBDYWxsZWQuXG4iKSk7CgogICAgLyogY2hlY2sgaWYgZGV2aWNlIHN1cHBvcnRzIHRoZSBmZWF0dXJlICovCiAgICBpZiAoIUlTX0lOX0RFVl9HUk9VUChkZXYsREVWX0VHUkVTU19GTE9PRCkpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVELlxuIikpOwogICAgICAgIHJldHVybiBHVF9OT1RfU1VQUE9SVEVEOwogICAgfQoKICAgIC8qIHRyYW5zbGF0ZSBMUE9SVCB0byBoYXJkd2FyZSBwb3J0ICovCiAgICBod1BvcnQgPSBHVF9MUE9SVF8yX1BPUlQocG9ydCk7CgogICAgZGF0YSA9IChHVF9VMTYpIG1vZGU7CgogICAgLyogU2V0IHRoZSBFZ3Jlc3MgRmxvb2QgbW9kZS4gICAgICAgICAgICAqLwogICAgcmV0VmFsID0gaHdTZXRQb3J0UmVnRmllbGQoZGV2LGh3UG9ydCwgUURfUkVHX1BPUlRfQ09OVFJPTCwyLDIsZGF0YSk7CgogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgewogICAgICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIERCR19JTkZPKCgiT0suXG4iKSk7CiAgICB9CiAgICByZXR1cm4gcmV0VmFsOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdwcnRHZXRFZ3Jlc3NGbG9vZAoqCiogREVTQ1JJUFRJT046CiogICAgICAgVGhpcyByb3V0aW5lIGdldHMgRWdyZXNzIEZsb29kaW5nIE1vZGUuCiogICAgICAgIEZyYW1lcyB3aXRoIHVua25vd24gREEgKERlc3RpbmF0aW9uIEFkZHJlc3MgdGhhdCBpcyBub3QgaW4gQVRVIGRhdGFiYXNlKQoqICAgICAgICBnZW5lcmFsbHkgZmxvb2Qgb3V0IGFsbCB0aGUgcG9ydHMuIFRoaXMgbW9kZSBjYW4gYmUgdXNlZCB0byBwcmV2ZW50CiogICAgICAgIHRob3NlIGZyYW1lcyBmcm9tIGVncmVzc2luZyB0aGlzIHBvcnQgYXMgZm9sbG93czoKKiAgICAgICAgICAgIEdUX0JMT0NLX0VHUkVTU19VTktOT1dOCiogICAgICAgICAgICAgICAgZG8gbm90IGVncmVzcyBmcmFtZSB3aXRoIHVua25vd24gREEgKGJvdGggdW5pY2FzdCBhbmQgbXVsdGljYXN0KQoqICAgICAgICAgICAgR1RfQkxPQ0tfRUdSRVNTX1VOS05PV05fTVVMVElDQVNUCiogICAgICAgICAgICAgICAgZG8gbm90IGVncmVzcyBmcmFtZSB3aXRoIHVua25vd24gbXVsdGljYXN0IERBCiogICAgICAgICAgICBHVF9CTE9DS19FR1JFU1NfVU5LTk9XTl9VTklDQVNUCiogICAgICAgICAgICAgICAgZG8gbm90IGVncmVzcyBmcmFtZSB3aXRoIHVua25vd24gdW5pY2FzdCBEQQoqICAgICAgICAgICAgR1RfQkxPQ0tfRUdSRVNTX05PTkUKKiAgICAgICAgICAgICAgICBlZ3Jlc3MgYWxsIGZyYW1lcyB3aXRoIHVua25vd24gREEKKgoqIElOUFVUUzoKKiAgICAgICBwb3J0IC0gdGhlIGxvZ2ljYWwgcG9ydCBudW1iZXIuCioKKiBPVVRQVVRTOgoqICAgICAgIG1vZGUgLSBHVF9FR1JFU1NfRkxPT0QgdHlwZQoqCiogUkVUVVJOUzoKKiAgICAgICBHVF9PSyAgIC0gb24gc3VjY2VzcwoqICAgICAgIEdUX0ZBSUwgLSBvbiBlcnJvcgoqCiogQ09NTUVOVFM6CioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdwcnRHZXRFZ3Jlc3NGbG9vZAooCiAgICBJTiAgR1RfUURfREVWICAgKmRldiwKICAgIElOICBHVF9MUE9SVCAgICAgcG9ydCwKICAgIE9VVCBHVF9FR1JFU1NfRkxPT0QgICAgICAqbW9kZQopCnsKICAgIEdUX1UxNiAgICAgICAgICBkYXRhOwogICAgR1RfU1RBVFVTICAgICAgIHJldFZhbDsgICAgICAgICAvKiBGdW5jdGlvbnMgcmV0dXJuIHZhbHVlLiAgICAgICovCiAgICBHVF9VOCAgICAgICAgICAgaHdQb3J0OyAgICAgICAgIC8qIHRoZSBwaHlzaWNhbCBwb3J0IG51bWJlciAgICAgKi8KCiAgICBEQkdfSU5GTygoImdwcnRHZXRFZ3Jlc3NGbG9vZCBDYWxsZWQuXG4iKSk7CgogICAgLyogY2hlY2sgaWYgZGV2aWNlIHN1cHBvcnRzIHRoZSBmZWF0dXJlICovCiAgICBpZiAoIUlTX0lOX0RFVl9HUk9VUChkZXYsREVWX0VHUkVTU19GTE9PRCkpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVELlxuIikpOwogICAgICAgIHJldHVybiBHVF9OT1RfU1VQUE9SVEVEOwogICAgfQoKICAgIC8qIHRyYW5zbGF0ZSBMUE9SVCB0byBoYXJkd2FyZSBwb3J0ICovCiAgICBod1BvcnQgPSBHVF9MUE9SVF8yX1BPUlQocG9ydCk7CgogICAgLyogZ2V0IHRoZSBFZ3Jlc3MgRmxvb2QgbW9kZS4gICAgICAgICAgICAqLwogICAgcmV0VmFsID0gaHdHZXRQb3J0UmVnRmllbGQoZGV2LGh3UG9ydCwgUURfUkVHX1BPUlRfQ09OVFJPTCwyLDIsJmRhdGEpOwoKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBEQkdfSU5GTygoIk9LLlxuIikpOwogICAgfQoKICAgICptb2RlID0gKEdUX0VHUkVTU19GTE9PRCkgZGF0YTsKCiAgICByZXR1cm4gcmV0VmFsOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBncHJ0U2V0UG9ydFNjaGVkCioKKiBERVNDUklQVElPTjoKKiAgICAgICAgVGhpcyByb3V0aW5lIHNldHMgUG9ydCBTY2hlZHVsaW5nIE1vZGUuCiogICAgICAgIFdoZW4gdXNlUG9ydFNjaGVkIGlzIGVuYWJsaWVkLCB0aGlzIG1vZGUgaXMgdXNlZCB0byBzZWxlY3QgdGhlIFF1ZXVlCiogICAgICAgIGNvbnRyb2xsZXIncyBzY2hlZHVsaW5nIG9uIHRoZSBwb3J0IGFzIGZvbGxvd3M6CiogICAgICAgICAgICBHVF9QT1JUX1NDSEVEX1dFSUdIVEVEX1JSQiAtIHVzZSA4LDQsMiwxIHdlaWdodGVkIGZhaXIgc2NoZWR1bGluZwoqICAgICAgICAgICAgR1RfUE9SVF9TQ0hFRF9TVFJJQ1RfUFJJIC0gdXNlIGEgc3RyaWN0IHByaW9yaXR5IHNjaGVtZQoqCiogSU5QVVRTOgoqICAgICAgICBwb3J0IC0gdGhlIGxvZ2ljYWwgcG9ydCBudW1iZXIKKiAgICAgICAgbW9kZSAtIEdUX1BPUlRfU0NIRURfTU9ERSBlbnVtIHR5cGUKKgoqIE9VVFBVVFM6CiogICAgICAgIE5vbmUuCioKKiBSRVRVUk5TOgoqICAgICAgICBHVF9PSyAgIC0gb24gc3VjY2VzcwoqICAgICAgICBHVF9GQUlMIC0gb24gZXJyb3IKKiAgICAgICAgR1RfTk9UX1NVUFBPUlRFRCAtIGlmIGN1cnJlbnQgZGV2aWNlIGRvZXMgbm90IHN1cHBvcnQgdGhpcyBmZWF0dXJlLgoqCiogQ09NTUVOVFM6CioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdwcnRTZXRQb3J0U2NoZWQKKAogICAgSU4gIEdUX1FEX0RFViAgICAqZGV2LAogICAgSU4gIEdUX0xQT1JUICAgIHBvcnQsCiAgICBJTiAgR1RfUE9SVF9TQ0hFRF9NT0RFICAgICAgICBtb2RlCikKewogICAgR1RfVTE2ICAgICAgICAgIGRhdGE7CiAgICBHVF9TVEFUVVMgICAgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX1U4ICAgICAgICAgICBod1BvcnQ7ICAgICAgICAgLyogdGhlIHBoeXNpY2FsIHBvcnQgbnVtYmVyICAgICAqLwoKICAgIERCR19JTkZPKCgiZ3BydFNldFBvcnRTY2hlZCBDYWxsZWQuXG4iKSk7CgogICAgLyogdHJhbnNsYXRlIExQT1JUIHRvIGhhcmR3YXJlIHBvcnQgKi8KICAgIGh3UG9ydCA9IEdUX0xQT1JUXzJfUE9SVChwb3J0KTsKCiAgICBpZiAoISgoSVNfSU5fREVWX0dST1VQKGRldixERVZfUE9SVF9TQ0hFRFVMRSkpIHx8CiAgICAgICAgKElTX0lOX0RFVl9HUk9VUChkZXYsREVWX1BPUlRfTUlYRURfU0NIRURVTEUpKSkpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CgogICAgaWYgKElTX0lOX0RFVl9HUk9VUChkZXYsREVWX1BPUlRfTUlYRURfU0NIRURVTEUpKQogICAgewogICAgICAgIHN3aXRjaChtb2RlKQogICAgICAgIHsKICAgICAgICAgICAgY2FzZSBHVF9QT1JUX1NDSEVEX1dFSUdIVEVEX1JSQjoKICAgICAgICAgICAgICAgIGRhdGEgPSAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgR1RfUE9SVF9TQ0hFRF9TVFJJQ1RfUFJJOgogICAgICAgICAgICAgICAgZGF0YSA9IDM7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBHVF9QT1JUX1NDSEVEX1NUUklDVF9QUkkzOgogICAgICAgICAgICAgICAgZGF0YSA9IDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBHVF9QT1JUX1NDSEVEX1NUUklDVF9QUkkyXzM6CiAgICAgICAgICAgICAgICBkYXRhID0gMjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgcmV0dXJuIEdUX0JBRF9QQVJBTTsKICAgICAgICB9CgogICAgICAgIHJldFZhbCA9IGh3U2V0UG9ydFJlZ0ZpZWxkKGRldixod1BvcnQsIFFEX1JFR19SQVRFX0NUUkwsIDEyLDIsZGF0YSk7CgogICAgICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgICAgICB7CiAgICAgICAgICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBEQkdfSU5GTygoIk9LLlxuIikpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmV0VmFsOwoKICAgIH0KCgogICAgZGF0YSA9IG1vZGU7CgogICAgLyogU2V0IHRoZSBncHJ0U2V0UG9ydFNjaGVkIG1vZGUuICAgICAgICAgICAgKi8KICAgIHJldFZhbCA9IGh3U2V0UG9ydFJlZ0ZpZWxkKGRldixod1BvcnQsIFFEX1JFR19QT1JUX0FTU09DSUFUSU9OLDE0LDEsZGF0YSk7CgogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgewogICAgICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIERCR19JTkZPKCgiT0suXG4iKSk7CiAgICB9CiAgICByZXR1cm4gcmV0VmFsOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdwcnRHZXRQb3J0U2NoZWQKKgoqIERFU0NSSVBUSU9OOgoqICAgICAgICBUaGlzIHJvdXRpbmUgZ2V0cyBQb3J0IFNjaGVkdWxpbmcgTW9kZS4KKiAgICAgICAgV2hlbiB1c2VQb3J0U2NoZWQgaXMgZW5hYmxpZWQsIHRoaXMgbW9kZSBpcyB1c2VkIHRvIHNlbGVjdCB0aGUgUXVldWUKKiAgICAgICAgY29udHJvbGxlcidzIHNjaGVkdWxpbmcgb24gdGhlIHBvcnQgYXMgZm9sbG93czoKKiAgICAgICAgICAgIEdUX1BPUlRfU0NIRURfV0VJR0hURURfUlJCIC0gdXNlIDgsNCwyLDEgd2VpZ2h0ZWQgZmFpciBzY2hlZHVsaW5nCiogICAgICAgICAgICBHVF9QT1JUX1NDSEVEX1NUUklDVF9QUkkgLSB1c2UgYSBzdHJpY3QgcHJpb3JpdHkgc2NoZW1lCioKKiBJTlBVVFM6CiogICAgICAgIHBvcnQgLSB0aGUgbG9naWNhbCBwb3J0IG51bWJlcgoqCiogT1VUUFVUUzoKKiAgICAgICAgbW9kZSAtIEdUX1BPUlRfU0NIRURfTU9ERSBlbnVtIHR5cGUKKgoqIFJFVFVSTlM6CiogICAgICAgIEdUX09LICAgLSBvbiBzdWNjZXNzCiogICAgICAgIEdUX0ZBSUwgLSBvbiBlcnJvcgoqICAgICAgICBHVF9OT1RfU1VQUE9SVEVEIC0gaWYgY3VycmVudCBkZXZpY2UgZG9lcyBub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCioKKiBDT01NRU5UUzoKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3BydEdldFBvcnRTY2hlZAooCiAgICBJTiAgR1RfUURfREVWICAgICpkZXYsCiAgICBJTiAgR1RfTFBPUlQgICAgcG9ydCwKICAgIE9VVCBHVF9QT1JUX1NDSEVEX01PREUgICAgICAgICptb2RlCikKewogICAgR1RfVTE2ICAgICAgICAgIGRhdGE7CiAgICBHVF9TVEFUVVMgICAgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX1U4ICAgICAgICAgICBod1BvcnQ7ICAgICAgICAgLyogdGhlIHBoeXNpY2FsIHBvcnQgbnVtYmVyICAgICAqLwoKICAgIERCR19JTkZPKCgiZ3BydEdldFBvcnRTY2hlZCBDYWxsZWQuXG4iKSk7CgogICAgLyogdHJhbnNsYXRlIExQT1JUIHRvIGhhcmR3YXJlIHBvcnQgKi8KICAgIGh3UG9ydCA9IEdUX0xQT1JUXzJfUE9SVChwb3J0KTsKCiAgICBpZiAoISgoSVNfSU5fREVWX0dST1VQKGRldixERVZfUE9SVF9TQ0hFRFVMRSkpIHx8CiAgICAgICAgKElTX0lOX0RFVl9HUk9VUChkZXYsREVWX1BPUlRfTUlYRURfU0NIRURVTEUpKSkpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CgogICAgaWYgKElTX0lOX0RFVl9HUk9VUChkZXYsREVWX1BPUlRfTUlYRURfU0NIRURVTEUpKQogICAgewogICAgICAgIHJldFZhbCA9IGh3R2V0UG9ydFJlZ0ZpZWxkKGRldixod1BvcnQsIFFEX1JFR19SQVRFX0NUUkwsIDEyLDIsJmRhdGEpOwogICAgICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgICAgICB7CiAgICAgICAgICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAgICAgICAgICByZXR1cm4gcmV0VmFsOwogICAgICAgIH0KCiAgICAgICAgc3dpdGNoKGRhdGEpCiAgICAgICAgewogICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICAqbW9kZSA9IEdUX1BPUlRfU0NIRURfV0VJR0hURURfUlJCOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgICAgICptb2RlID0gR1RfUE9SVF9TQ0hFRF9TVFJJQ1RfUFJJMzsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIDI6CiAgICAgICAgICAgICAgICAqbW9kZSA9IEdUX1BPUlRfU0NIRURfU1RSSUNUX1BSSTJfMzsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIDM6CiAgICAgICAgICAgICAgICAqbW9kZSA9IEdUX1BPUlRfU0NIRURfU1RSSUNUX1BSSTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgcmV0dXJuIEdUX0JBRF9QQVJBTTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBHVF9PSzsKCiAgICB9CgogICAgLyogR2V0IHRoZSBncHJ0R2V0UG9ydFNjaGVkIG1vZGUuICAgICAgICAgICAgKi8KICAgIHJldFZhbCA9IGh3R2V0UG9ydFJlZ0ZpZWxkKGRldixod1BvcnQsIFFEX1JFR19QT1JUX0FTU09DSUFUSU9OLDE0LDEsJmRhdGEpOwoKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBEQkdfSU5GTygoIk9LLlxuIikpOwogICAgfQoKICAgICptb2RlID0gKEdUX1BPUlRfU0NIRURfTU9ERSlkYXRhOwoKICAgIHJldHVybiByZXRWYWw7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdwcnRTZXRQcm92aWRlclRhZwoqCiogREVTQ1JJUFRJT046CiogICAgICAgIFRoaXMgcm91dGluZSBzZXRzIFByb3ZpZGVyIFRhZyB3aGljaCBpbmRpY2F0ZXMgdGhlIHByb3ZpZGVyIHRhZyAoRXRoZXIKKiAgICAgICAgVHlwZSkgdmFsdWUgdGhhdCBuZWVkcyB0byBiZSBtYXRjaGVkIHRvIGluIGluZ3Jlc3MgdG8gZGV0ZXJtaW5lIGlmIGEKKiAgICAgICAgZnJhbWUgaXMgUHJvdmlkZXIgdGFnZ2VkIG9yIG5vdC4KKgoqIElOUFVUUzoKKiAgICAgICAgcG9ydCAtIHRoZSBsb2dpY2FsIHBvcnQgbnVtYmVyCiogICAgICAgIHRhZyAgLSBQcm92aWRlciBUYWcgKEV0aGVyIFR5cGUpCioKKiBPVVRQVVRTOgoqICAgICAgICBOb25lLgoqCiogUkVUVVJOUzoKKiAgICAgICAgR1RfT0sgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICAgR1RfRkFJTCAtIG9uIGVycm9yCiogICAgICAgIEdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBncHJ0U2V0UHJvdmlkZXJUYWcKKAogICAgSU4gIEdUX1FEX0RFViAgICAqZGV2LAogICAgSU4gIEdUX0xQT1JUICAgIHBvcnQsCiAgICBJTiAgR1RfVTE2ICAgICAgICB0YWcKKQp7CiAgICBHVF9TVEFUVVMgICAgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX1U4ICAgICAgICAgICBod1BvcnQ7ICAgICAgICAgLyogdGhlIHBoeXNpY2FsIHBvcnQgbnVtYmVyICAgICAqLwoKICAgIERCR19JTkZPKCgiZ3BydFNldFByb3ZpZGVyVGFnIENhbGxlZC5cbiIpKTsKCiAgICAvKiB0cmFuc2xhdGUgTFBPUlQgdG8gaGFyZHdhcmUgcG9ydCAqLwogICAgaHdQb3J0ID0gR1RfTFBPUlRfMl9QT1JUKHBvcnQpOwoKICAgIGlmICghSVNfSU5fREVWX0dST1VQKGRldixERVZfUFJPVklERVJfVEFHKSkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX05PVF9TVVBQT1JURURcbiIpKTsKICAgICAgICByZXR1cm4gR1RfTk9UX1NVUFBPUlRFRDsKICAgIH0KCiAgICAvKiBTZXQgUHJvdmlkZXIgVGFnLiAgICAgICAgICAgICovCiAgICByZXRWYWwgPSBod1NldFBvcnRSZWdGaWVsZChkZXYsaHdQb3J0LCBRRF9SRUdfUFJPVklERVJfVEFHLCAwLCAxNiwgdGFnKTsKCiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJPSy5cbiIpKTsKICAgIH0KICAgIHJldHVybiByZXRWYWw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3BydEdldFByb3ZpZGVyVGFnCioKKiBERVNDUklQVElPTjoKKiAgICAgICAgVGhpcyByb3V0aW5lIGdldHMgUHJvdmlkZXIgVGFnIHdoaWNoIGluZGljYXRlcyB0aGUgcHJvdmlkZXIgdGFnIChFdGhlcgoqICAgICAgICBUeXBlKSB2YWx1ZSB0aGF0IG5lZWRzIHRvIGJlIG1hdGNoZWQgdG8gaW4gaW5ncmVzcyB0byBkZXRlcm1pbmUgaWYgYQoqICAgICAgICBmcmFtZSBpcyBQcm92aWRlciB0YWdnZWQgb3Igbm90LgoqCiogSU5QVVRTOgoqICAgICAgICBwb3J0IC0gdGhlIGxvZ2ljYWwgcG9ydCBudW1iZXIKKgoqIE9VVFBVVFM6CiogICAgICAgIHRhZyAgLSBQcm92aWRlciBUYWcgKEV0aGVyIFR5cGUpCioKKiBSRVRVUk5TOgoqICAgICAgICBHVF9PSyAgIC0gb24gc3VjY2VzcwoqICAgICAgICBHVF9GQUlMIC0gb24gZXJyb3IKKiAgICAgICAgR1RfTk9UX1NVUFBPUlRFRCAtIGlmIGN1cnJlbnQgZGV2aWNlIGRvZXMgbm90IHN1cHBvcnQgdGhpcyBmZWF0dXJlLgoqCiogQ09NTUVOVFM6CioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdwcnRHZXRQcm92aWRlclRhZwooCiAgICBJTiAgR1RfUURfREVWICAgICpkZXYsCiAgICBJTiAgR1RfTFBPUlQgICAgcG9ydCwKICAgIE9VVCBHVF9VMTYgICAgICAgICp0YWcKKQp7CiAgICBHVF9TVEFUVVMgICAgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX1U4ICAgICAgICAgICBod1BvcnQ7ICAgICAgICAgLyogdGhlIHBoeXNpY2FsIHBvcnQgbnVtYmVyICAgICAqLwoKICAgIERCR19JTkZPKCgiZ3BydEdldFByb3ZpZGVyVGFnIENhbGxlZC5cbiIpKTsKCiAgICAvKiB0cmFuc2xhdGUgTFBPUlQgdG8gaGFyZHdhcmUgcG9ydCAqLwogICAgaHdQb3J0ID0gR1RfTFBPUlRfMl9QT1JUKHBvcnQpOwoKICAgIGlmICghSVNfSU5fREVWX0dST1VQKGRldixERVZfUFJPVklERVJfVEFHKSkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX05PVF9TVVBQT1JURURcbiIpKTsKICAgICAgICByZXR1cm4gR1RfTk9UX1NVUFBPUlRFRDsKICAgIH0KCiAgICAvKiBHZXQgUHJvdmlkZXIgVGFnLiAgICAgICAgICAgICovCiAgICByZXRWYWwgPSBod0dldFBvcnRSZWdGaWVsZChkZXYsaHdQb3J0LCBRRF9SRUdfUFJPVklERVJfVEFHLCAwLCAxNiwgdGFnKTsKCiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJPSy5cbiIpKTsKICAgIH0KICAgIHJldHVybiByZXRWYWw7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdwcnRTZXRQYXVzZUxpbWl0T3V0CioKKiBERVNDUklQVElPTjoKKiAgICAgICAgTGltaXQgdGhlIG51bWJlciBvZiBjb250aW51b3VzIFBhdXNlIHJlZnJlc2ggZnJhbWVzIHRoYXQgY2FuIGJlIHRyYW5zbWl0dGVkCiogICAgICAgIGZyb20gdGhpcyBwb3J0LiBXaGVuIGZ1bGwgZHVwbGV4IEZsb3cgQ29udHJvbCBpcyBlbmFibGVkIG9uIHRoaXMgcG9ydCwKKiAgICAgICAgdGhlc2UgYml0cyBhcmUgdXNlZCB0byBsaW1pdCB0aGUgbnVtYmVyIG9mIFBhdXNlIHJlZnJlc2ggZnJhbWVzIHRoYXQgY2FuCiogICAgICAgIGJlIGdlbmVyYXRlZCBmcm9tIHRoaXMgcG9ydCB0byBrZWVwIHRoaXMgcG9ydCdzIGxpbmsgcGFydG5lciBmcm9tIHNlbmRpbmcKKiAgICAgICAgYW55IGRhdGEuCiogICAgICAgIFNldHRpbmcgdGhpcyB2YWx1ZSB0byAwIHdpbGwgYWxsb3cgY29udGludW91cyBQYXVzZSBmcmFtZSByZWZyZXNoZXMgdG8KKiAgICAgICAgZWdyZXNzIHRoaXMgcG9ydCBhcyBsb25nIGFzIHRoaXMgcG9ydCByZW1haW5zIGNvbmdlc3RlZC4KKiAgICAgICAgU2V0dGluZyB0aGlzIHZhbHVlIHRvIDEgd2lsbCBhbGxvdyAxIFBhdXNlIGZyYW1lIHRvIGVncmVzcyBmcm9tIHRoaXMgcG9ydAoqICAgICAgICBmb3IgZWFjaCBjb25nZXN0aW9uIHNpdHVhdGlvbi4KKiAgICAgICAgU2V0dGluZyB0aGlzIHZhbHVlIHRvIDIgd2lsbCBhbGxvdyAyIFBhdXNlIGZyYW1lcyB0byBlZ3Jlc3MgZnJvbSB0aGlzIHBvcnQKKiAgICAgICAgZm9yIGVhY2ggY29uZ2VzdGlvbiBzaXR1YXRpb24sIGV0Yy4KKgoqIElOUFVUUzoKKiAgICAgICAgcG9ydCAtIHRoZSBsb2dpY2FsIHBvcnQgbnVtYmVyCiogICAgICAgIGxpbWl0IC0gdGhlIG1heCBudW1iZXIgb2YgUGF1c2UgcmVmcmVzaCBmcmFtZXMgZm9yIGVhY2ggY29uZ2VzdGlvbiBzaXR1YXRpb24KKiAgICAgICAgICAgICAgICAoIDAgfiAweEZGKQoqCiogT1VUUFVUUzoKKiAgICAgICAgTm9uZS4KKgoqIFJFVFVSTlM6CiogICAgICAgIEdUX09LICAgLSBvbiBzdWNjZXNzCiogICAgICAgIEdUX0ZBSUwgLSBvbiBlcnJvcgoqICAgICAgICBHVF9CQURfUEFSQU0gLSBpZiBsaW1pdCA+IDB4RkYKKiAgICAgICAgR1RfTk9UX1NVUFBPUlRFRCAtIGlmIGN1cnJlbnQgZGV2aWNlIGRvZXMgbm90IHN1cHBvcnQgdGhpcyBmZWF0dXJlLgoqCiogQ09NTUVOVFM6CioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdwcnRTZXRQYXVzZUxpbWl0T3V0CigKICAgIElOICBHVF9RRF9ERVYgICAgKmRldiwKICAgIElOICBHVF9MUE9SVCAgICBwb3J0LAogICAgSU4gIEdUX1UxNiAgICAgICAgbGltaXQKKQp7CiAgICBHVF9TVEFUVVMgICAgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX1U4ICAgICAgICAgICBod1BvcnQ7ICAgICAgICAgLyogdGhlIHBoeXNpY2FsIHBvcnQgbnVtYmVyICAgICAqLwoKICAgIERCR19JTkZPKCgiZ3BydFNldFBhdXNlTGltaXRPdXQgQ2FsbGVkLlxuIikpOwoKICAgIC8qIHRyYW5zbGF0ZSBMUE9SVCB0byBoYXJkd2FyZSBwb3J0ICovCiAgICBod1BvcnQgPSBHVF9MUE9SVF8yX1BPUlQocG9ydCk7CgogICAgaWYgKCFJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9QQVVTRV9MSU1JVCkpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CgogICAgaWYgKGxpbWl0ID4gMHhGRikKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkJhZCBQYXJhbWV0ZXJcbiIpKTsKICAgICAgICByZXR1cm4gR1RfQkFEX1BBUkFNOwogICAgfQoKICAgIC8qIFNldCBQYXVzZSBMaW1pdC4gICovCiAgICByZXRWYWwgPSBod1NldFBvcnRSZWdGaWVsZChkZXYsaHdQb3J0LCBRRF9SRUdfTElNSVRfUEFVU0VfQ09OVFJPTCwgOCwgOCwgbGltaXQpOwoKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBEQkdfSU5GTygoIk9LLlxuIikpOwogICAgfQogICAgcmV0dXJuIHJldFZhbDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBncHJ0R2V0UGF1c2VMaW1pdE91dAoqCiogREVTQ1JJUFRJT046CiogICAgICAgIExpbWl0IHRoZSBudW1iZXIgb2YgY29udGludW91cyBQYXVzZSByZWZyZXNoIGZyYW1lcyB0aGF0IGNhbiBiZSB0cmFuc21pdHRlZAoqICAgICAgICBmcm9tIHRoaXMgcG9ydC4gV2hlbiBmdWxsIGR1cGxleCBGbG93IENvbnRyb2wgaXMgZW5hYmxlZCBvbiB0aGlzIHBvcnQsCiogICAgICAgIHRoZXNlIGJpdHMgYXJlIHVzZWQgdG8gbGltaXQgdGhlIG51bWJlciBvZiBQYXVzZSByZWZyZXNoIGZyYW1lcyB0aGF0IGNhbgoqICAgICAgICBiZSBnZW5lcmF0ZWQgZnJvbSB0aGlzIHBvcnQgdG8ga2VlcCB0aGlzIHBvcnQncyBsaW5rIHBhcnRuZXIgZnJvbSBzZW5kaW5nCiogICAgICAgIGFueSBkYXRhLgoqICAgICAgICBTZXR0aW5nIHRoaXMgdmFsdWUgdG8gMCB3aWxsIGFsbG93IGNvbnRpbnVvdXMgUGF1c2UgZnJhbWUgcmVmcmVzaGVzIHRvCiogICAgICAgIGVncmVzcyB0aGlzIHBvcnQgYXMgbG9uZyBhcyB0aGlzIHBvcnQgcmVtYWlucyBjb25nZXN0ZWQuCiogICAgICAgIFNldHRpbmcgdGhpcyB2YWx1ZSB0byAxIHdpbGwgYWxsb3cgMSBQYXVzZSBmcmFtZSB0byBlZ3Jlc3MgZnJvbSB0aGlzIHBvcnQKKiAgICAgICAgZm9yIGVhY2ggY29uZ2VzdGlvbiBzaXR1YXRpb24uCiogICAgICAgIFNldHRpbmcgdGhpcyB2YWx1ZSB0byAyIHdpbGwgYWxsb3cgMiBQYXVzZSBmcmFtZXMgdG8gZWdyZXNzIGZyb20gdGhpcyBwb3J0CiogICAgICAgIGZvciBlYWNoIGNvbmdlc3Rpb24gc2l0dWF0aW9uLCBldGMuCioKKiBJTlBVVFM6CiogICAgICAgIHBvcnQgLSB0aGUgbG9naWNhbCBwb3J0IG51bWJlcgoqCiogT1VUUFVUUzoKKiAgICAgICAgbGltaXQgLSB0aGUgbWF4IG51bWJlciBvZiBQYXVzZSByZWZyZXNoIGZyYW1lcyBmb3IgZWFjaCBjb25nZXN0aW9uIHNpdHVhdGlvbgoqICAgICAgICAgICAgICAgICggMCB+IDB4RkYpCioKKiBSRVRVUk5TOgoqICAgICAgICBHVF9PSyAgIC0gb24gc3VjY2VzcwoqICAgICAgICBHVF9GQUlMIC0gb24gZXJyb3IKKiAgICAgICAgR1RfTk9UX1NVUFBPUlRFRCAtIGlmIGN1cnJlbnQgZGV2aWNlIGRvZXMgbm90IHN1cHBvcnQgdGhpcyBmZWF0dXJlLgoqCiogQ09NTUVOVFM6CioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdwcnRHZXRQYXVzZUxpbWl0T3V0CigKICAgIElOICBHVF9RRF9ERVYgICAgKmRldiwKICAgIElOICBHVF9MUE9SVCAgICBwb3J0LAogICAgT1VUIEdUX1UxNiAgICAgICAgKmxpbWl0CikKewogICAgR1RfU1RBVFVTICAgICAgIHJldFZhbDsgICAgICAgICAvKiBGdW5jdGlvbnMgcmV0dXJuIHZhbHVlLiAgICAgICovCiAgICBHVF9VOCAgICAgICAgICAgaHdQb3J0OyAgICAgICAgIC8qIHRoZSBwaHlzaWNhbCBwb3J0IG51bWJlciAgICAgKi8KCiAgICBEQkdfSU5GTygoImdwcnRHZXRQYXVzZUxpbWl0T3V0IENhbGxlZC5cbiIpKTsKCiAgICAvKiB0cmFuc2xhdGUgTFBPUlQgdG8gaGFyZHdhcmUgcG9ydCAqLwogICAgaHdQb3J0ID0gR1RfTFBPUlRfMl9QT1JUKHBvcnQpOwoKICAgIGlmICghSVNfSU5fREVWX0dST1VQKGRldixERVZfUEFVU0VfTElNSVQpKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfTk9UX1NVUFBPUlRFRFxuIikpOwogICAgICAgIHJldHVybiBHVF9OT1RfU1VQUE9SVEVEOwogICAgfQoKICAgIC8qIEdldCBQYXVzZSBMaW1pdC4gICovCiAgICByZXRWYWwgPSBod0dldFBvcnRSZWdGaWVsZChkZXYsaHdQb3J0LCBRRF9SRUdfTElNSVRfUEFVU0VfQ09OVFJPTCwgOCwgOCwgbGltaXQpOwoKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBEQkdfSU5GTygoIk9LLlxuIikpOwogICAgfQogICAgcmV0dXJuIHJldFZhbDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3BydFNldFBhdXNlTGltaXRJbgoqCiogREVTQ1JJUFRJT046CiogICAgICAgIExpbWl0IHRoZSBudW1iZXIgb2YgY29udGludW91cyBQYXVzZSByZWZyZXNoIGZyYW1lcyB0aGF0IGNhbiBiZSByZWNlaXZlZAoqICAgICAgICBvbiB0aGlzIHBvcnQuIFdoZW4gYSBwb3J0IGhhcyBmbG93IENvbnRyb2wgZW5hYmxlZCwgdGhpcyB2YWx1ZSBjYW4gYmUKKiAgICAgICAgdXNlZCB0byBsaW1pdCBob3cgbG9uZyB0aGlzIHBvcnQgY2FuIGJlIFBhdXNlZCBvZmYgdG8gcHJldmVudCBhIHBvcnQgc3RhbGwKKiAgICAgICAgdGhyb3VnaCBqYW1taW5nLgoqICAgICAgICBXaGVuIHRoaXMgdmFsdWUgaXMgaW4gdGhlIHJhbmdlIG9mIDB4MDEgdG8gMHhGRiwgYW5kIGEgZnJhbWUgaXMgcmVhZHkgdG8KKiAgICAgICAgYmUgdHJhbnNtaXR0ZWQgb3V0IHRoaXMgcG9ydCwgYnV0IGl0IGNhbm5vdCBiZSB0cmFuc21pdHRlZCBkdWUgdG8gdGhlIHBvcnQKKiAgICAgICAgYmVpbmcgamFtbWVkLCB0aGlzIGxpbWl0IG1lY2hhbmlzbSBzdGFydHMuIFRoZSBsaW1pdCBtZWNoYW5pc20gc3RhcnRzCiogICAgICAgIGNvdW50aW5nIG5ldyBQYXVzZSByZWZyZXNoIGZyYW1lcyBvciBjb3VudHMgb2YgMTYgY29uc2VjdXRpdmUgY29sbGlzaW9ucy4KKiAgICAgICAgSWYgdGhlIGNvdW50ZXIgcmVhY2hlcyB0aGUgdmFsdWUgc2V0IHRocm91Z2ggdGhpcyBBUEksIHRoZSBmb2xsb3dpbmcgZXZlbnQKKiAgICAgICAgd2lsbCBvY2N1cjoKKiAgICAgICAgICAgIDEpIFBvcnQncyBGb3JjZUZDIGlzIGVuYWJsZWQsCiogICAgICAgICAgICAyKSBQb3J0J3MgRkNWYWx1ZSBpcyBjbGVhcmVkIHRvIGEgemVybywgYW5kCiogICAgICAgICAgICAzKSBKYW0gTGltaXQgSW50ZXJydXB0IGlzIGFzc2VydGVkLgoqICAgICAgICBUaGlzIGVmZmVjdGl2ZWx5IGRpc2FibGVzIEZsb3cgQ29udHJvbCBvbiB0aGUgcG9ydCBvbmNlIHRoZSBQYXVzZSB0aW1lcgoqICAgICAgICBleHBpcmVzLiBJZiBhIGZyYW1lIGdldHMgdHJhbnNtaXR0ZWQgb3V0IHRoaXMgcG9ydCBiZWZvcmUgdGhlIGNvdW50ZXIKKiAgICAgICAgcmVhY2hlcyB0aGlzIGxpbWl0LCB0aGVuIHRoaXMgbGltaXQgbWVjaGFuaXNtIGNvdW50ZXIgcmVzZXRzIGJhY2sgdG8gemVyby4KKgoqICAgICAgICBTZXR0aW5nIHRoaXMgdmFsdWUgdG8gMCB3aWxsIGFsbG93IGNvbnRpbnVvdXMgamFtbWluZyB0byBiZSByZWNlaXZlZCBvbgoqICAgICAgICB0aGlzIHBvcnQgd2l0aG91dCB0aGUgUG9ydCdzIEZvcmNlRkMgYW5kIEZDVmFsdWUgZ2V0dGluZyBtb2RpZmllZC4KKgoqICAgICAgICBUaGUgbW9kaWZpY2F0aW9uIG9mIFBvcnQncyBGb3JjZUZDIGFuZCBGQ1ZhbHVlIGlzIHRoZSBvbmx5IGluZGljYXRpb24gdGhhdAoqICAgICAgICB0aGUgbGltaXQgd2FzIHJlYWNoZWQgb24gdGhpcyBwb3J0LgoqCiogSU5QVVRTOgoqICAgICAgICBwb3J0IC0gdGhlIGxvZ2ljYWwgcG9ydCBudW1iZXIKKiAgICAgICAgbGltaXQgLSB0aGUgbWF4IG51bWJlciBvZiBjb250aW51b3VzIFBhdXNlIHJlZnJlc2ggZnJhbWVzIGZvciBlYWNoIHRyYXNtaXRpb24KKiAgICAgICAgICAgICAgICAoIDAgfiAweEZGKQoqCiogT1VUUFVUUzoKKiAgICAgICAgTm9uZS4KKgoqIFJFVFVSTlM6CiogICAgICAgIEdUX09LICAgLSBvbiBzdWNjZXNzCiogICAgICAgIEdUX0ZBSUwgLSBvbiBlcnJvcgoqICAgICAgICBHVF9CQURfUEFSQU0gLSBpZiBsaW1pdCA+IDB4RkYKKiAgICAgICAgR1RfTk9UX1NVUFBPUlRFRCAtIGlmIGN1cnJlbnQgZGV2aWNlIGRvZXMgbm90IHN1cHBvcnQgdGhpcyBmZWF0dXJlLgoqCiogQ09NTUVOVFM6CioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdwcnRTZXRQYXVzZUxpbWl0SW4KKAogICAgSU4gIEdUX1FEX0RFViAgICAqZGV2LAogICAgSU4gIEdUX0xQT1JUICAgIHBvcnQsCiAgICBJTiAgR1RfVTE2ICAgICAgICBsaW1pdAopCnsKICAgIEdUX1NUQVRVUyAgICAgICByZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwogICAgR1RfVTggICAgICAgICAgIGh3UG9ydDsgICAgICAgICAvKiB0aGUgcGh5c2ljYWwgcG9ydCBudW1iZXIgICAgICovCgogICAgREJHX0lORk8oKCJncHJ0U2V0UGF1c2VMaW1pdEluIENhbGxlZC5cbiIpKTsKCiAgICAvKiB0cmFuc2xhdGUgTFBPUlQgdG8gaGFyZHdhcmUgcG9ydCAqLwogICAgaHdQb3J0ID0gR1RfTFBPUlRfMl9QT1JUKHBvcnQpOwoKICAgIGlmICghSVNfSU5fREVWX0dST1VQKGRldixERVZfUEFVU0VfTElNSVQpKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfTk9UX1NVUFBPUlRFRFxuIikpOwogICAgICAgIHJldHVybiBHVF9OT1RfU1VQUE9SVEVEOwogICAgfQoKICAgIGlmIChsaW1pdCA+IDB4RkYpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJCYWQgUGFyYW1ldGVyXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX0JBRF9QQVJBTTsKICAgIH0KCiAgICAvKiBTZXQgUGF1c2UgTGltaXQuICAqLwogICAgcmV0VmFsID0gaHdTZXRQb3J0UmVnRmllbGQoZGV2LGh3UG9ydCwgUURfUkVHX0xJTUlUX1BBVVNFX0NPTlRST0wsIDAsIDgsIGxpbWl0KTsKCiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJPSy5cbiIpKTsKICAgIH0KICAgIHJldHVybiByZXRWYWw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3BydEdldFBhdXNlTGltaXRJbgoqCiogREVTQ1JJUFRJT046CiogICAgICAgIExpbWl0IHRoZSBudW1iZXIgb2YgY29udGludW91cyBQYXVzZSByZWZyZXNoIGZyYW1lcyB0aGF0IGNhbiBiZSByZWNlaXZlZAoqICAgICAgICBvbiB0aGlzIHBvcnQuIFdoZW4gYSBwb3J0IGhhcyBmbG93IENvbnRyb2wgZW5hYmxlZCwgdGhpcyB2YWx1ZSBjYW4gYmUKKiAgICAgICAgdXNlZCB0byBsaW1pdCBob3cgbG9uZyB0aGlzIHBvcnQgY2FuIGJlIFBhdXNlZCBvZmYgdG8gcHJldmVudCBhIHBvcnQgc3RhbGwKKiAgICAgICAgdGhyb3VnaCBqYW1taW5nLgoqICAgICAgICBXaGVuIHRoaXMgdmFsdWUgaXMgaW4gdGhlIHJhbmdlIG9mIDB4MDEgdG8gMHhGRiwgYW5kIGEgZnJhbWUgaXMgcmVhZHkgdG8KKiAgICAgICAgYmUgdHJhbnNtaXR0ZWQgb3V0IHRoaXMgcG9ydCwgYnV0IGl0IGNhbm5vdCBiZSB0cmFuc21pdHRlZCBkdWUgdG8gdGhlIHBvcnQKKiAgICAgICAgYmVpbmcgamFtbWVkLCB0aGlzIGxpbWl0IG1lY2hhbmlzbSBzdGFydHMuIFRoZSBsaW1pdCBtZWNoYW5pc20gc3RhcnRzCiogICAgICAgIGNvdW50aW5nIG5ldyBQYXVzZSByZWZyZXNoIGZyYW1lcyBvciBjb3VudHMgb2YgMTYgY29uc2VjdXRpdmUgY29sbGlzaW9ucy4KKiAgICAgICAgSWYgdGhlIGNvdW50ZXIgcmVhY2hlcyB0aGUgdmFsdWUgc2V0IHRocm91Z2ggdGhpcyBBUEksIHRoZSBmb2xsb3dpbmcgZXZlbnQKKiAgICAgICAgd2lsbCBvY2N1cjoKKiAgICAgICAgICAgIDEpIFBvcnQncyBGb3JjZUZDIGlzIGVuYWJsZWQsCiogICAgICAgICAgICAyKSBQb3J0J3MgRkNWYWx1ZSBpcyBjbGVhcmVkIHRvIGEgemVybywgYW5kCiogICAgICAgICAgICAzKSBKYW0gTGltaXQgSW50ZXJydXB0IGlzIGFzc2VydGVkLgoqICAgICAgICBUaGlzIGVmZmVjdGl2ZWx5IGRpc2FibGVzIEZsb3cgQ29udHJvbCBvbiB0aGUgcG9ydCBvbmNlIHRoZSBQYXVzZSB0aW1lcgoqICAgICAgICBleHBpcmVzLiBJZiBhIGZyYW1lIGdldHMgdHJhbnNtaXR0ZWQgb3V0IHRoaXMgcG9ydCBiZWZvcmUgdGhlIGNvdW50ZXIKKiAgICAgICAgcmVhY2hlcyB0aGlzIGxpbWl0LCB0aGVuIHRoaXMgbGltaXQgbWVjaGFuaXNtIGNvdW50ZXIgcmVzZXRzIGJhY2sgdG8gemVyby4KKgoqICAgICAgICBTZXR0aW5nIHRoaXMgdmFsdWUgdG8gMCB3aWxsIGFsbG93IGNvbnRpbnVvdXMgamFtbWluZyB0byBiZSByZWNlaXZlZCBvbgoqICAgICAgICB0aGlzIHBvcnQgd2l0aG91dCB0aGUgUG9ydCdzIEZvcmNlRkMgYW5kIEZDVmFsdWUgZ2V0dGluZyBtb2RpZmllZC4KKgoqICAgICAgICBUaGUgbW9kaWZpY2F0aW9uIG9mIFBvcnQncyBGb3JjZUZDIGFuZCBGQ1ZhbHVlIGlzIHRoZSBvbmx5IGluZGljYXRpb24gdGhhdAoqICAgICAgICB0aGUgbGltaXQgd2FzIHJlYWNoZWQgb24gdGhpcyBwb3J0LgoqCiogSU5QVVRTOgoqICAgICAgICBwb3J0IC0gdGhlIGxvZ2ljYWwgcG9ydCBudW1iZXIKKgoqIE9VVFBVVFM6CiogICAgICAgIGxpbWl0IC0gdGhlIG1heCBudW1iZXIgb2YgY29udGludW91cyBQYXVzZSByZWZyZXNoIGZyYW1lcyBmb3IgZWFjaCB0cmFzbWl0aW9uCiogICAgICAgICAgICAgICAgKCAwIH4gMHhGRikKKgoqIFJFVFVSTlM6CiogICAgICAgIEdUX09LICAgLSBvbiBzdWNjZXNzCiogICAgICAgIEdUX0ZBSUwgLSBvbiBlcnJvcgoqICAgICAgICBHVF9OT1RfU1VQUE9SVEVEIC0gaWYgY3VycmVudCBkZXZpY2UgZG9lcyBub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCioKKiBDT01NRU5UUzoKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3BydEdldFBhdXNlTGltaXRJbgooCiAgICBJTiAgR1RfUURfREVWICAgICpkZXYsCiAgICBJTiAgR1RfTFBPUlQgICAgcG9ydCwKICAgIE9VVCBHVF9VMTYgICAgICAgICpsaW1pdAopCnsKICAgIEdUX1NUQVRVUyAgICAgICByZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwogICAgR1RfVTggICAgICAgICAgIGh3UG9ydDsgICAgICAgICAvKiB0aGUgcGh5c2ljYWwgcG9ydCBudW1iZXIgICAgICovCgogICAgREJHX0lORk8oKCJncHJ0R2V0UGF1c2VMaW1pdEluIENhbGxlZC5cbiIpKTsKCiAgICAvKiB0cmFuc2xhdGUgTFBPUlQgdG8gaGFyZHdhcmUgcG9ydCAqLwogICAgaHdQb3J0ID0gR1RfTFBPUlRfMl9QT1JUKHBvcnQpOwoKICAgIGlmICghSVNfSU5fREVWX0dST1VQKGRldixERVZfUEFVU0VfTElNSVQpKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfTk9UX1NVUFBPUlRFRFxuIikpOwogICAgICAgIHJldHVybiBHVF9OT1RfU1VQUE9SVEVEOwogICAgfQoKICAgIC8qIEdldCBQYXVzZSBMaW1pdC4gICovCiAgICByZXRWYWwgPSBod0dldFBvcnRSZWdGaWVsZChkZXYsaHdQb3J0LCBRRF9SRUdfTElNSVRfUEFVU0VfQ09OVFJPTCwgMCwgOCwgbGltaXQpOwoKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBEQkdfSU5GTygoIk9LLlxuIikpOwogICAgfQogICAgcmV0dXJuIHJldFZhbDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3BydFNldEZyYW1lTW9kZQoqCiogREVTQ1JJUFRJT046CiogICAgICAgIEZybWFlIE1vZGUgaXMgdXNlZCB0byBkZWZpbmUgdGhlIGV4cGVjdGVkIEluZ3Jlc3MgYW5kIHRoZSBnZW5lcmF0ZWQgRWdyZXNzCiogICAgICAgIHRhZ2dpbmcgZnJhbWUgZm9ybWF0IGZvciB0aGlzIHBvcnQgYXMgZm9sbG93czoKKiAgICAgICAgICAgIEdUX0ZSQU1FX01PREVfTk9STUFMIC0KKiAgICAgICAgICAgICAgICBOb3JtYWwgTmV0d29yayBtb2RlIHVzZXMgaW5kdXN0cnkgc3RhbmRhcmQgSUVFRSA4MDIuM2FjIFRhZ2dlZCBvcgoqICAgICAgICAgICAgICAgIFVudGFnZ2VkIGZyYW1lcy4gVGFnZ2VkIGZyYW1lcyB1c2UgYW4gRXRoZXIgVHlwZSBvZiAweDgxMDAuCiogICAgICAgICAgICBHVF9GUkFNRV9NT0RFX0RTQSAtCiogICAgICAgICAgICAgICAgRFNBIG1vZGUgdXNlcyBhIE1hcnZlbGwgZGVmaW5lZCB0YWdnZWQgZnJhbWUgZm9ybWF0IGZvcgoqICAgICAgICAgICAgICAgIENoaXAtdG8tQ2hpcCBhbmQgQ2hpcC10by1DUFUgY29ubmVjdGlvbnMuCiogICAgICAgICAgICBHVF9GUkFNRV9NT0RFX1BST1ZJREVSIC0KKiAgICAgICAgICAgICAgICBQcm92aWRlciBtb2RlIHVzZXMgdXNlciBkZWZpbmFibGUgRXRoZXIgVHlwZXMgcGVyIHBvcnQKKiAgICAgICAgICAgICAgICAoc2VlIGdwcnRTZXRQb3J0RVR5cGUvZ3BydEdldFBvcnRFVHlwZSBBUEkpLgoqICAgICAgICAgICAgR1RfRlJBTUVfTU9ERV9FVEhFUl9UWVBFX0RTQSAtCiogICAgICAgICAgICAgICAgRXRoZXIgVHlwZSBEU0EgbW9kZSB1c2VzIHN0YW5kYXJkIE1hcnZlbGwgRFNBIFRhZ2dlZCBmcmFtZSBpbmZvCiogICAgICAgICAgICAgICAgZmxvd2luZyBhIHVzZXIgZGVmaW5hYmxlIEV0aGVyIFR5cGUuIFRoaXMgbW9kZSBhbGxvd3MgdGhlIG1peHR1cmUKKiAgICAgICAgICAgICAgICBvZiBOb3JtYWwgTmV0d29yayBmcmFtZXMgd2l0aCBEU0EgVGFnZ2VkIGZyYW1lcyBhbmQgaXMgdXNlZnVsIHRvCiogICAgICAgICAgICAgICAgYmUgdXNlZCBvbiBwb3J0cyB0aGF0IGNvbm5lY3QgdG8gYSBDUFUuCioKKiBJTlBVVFM6CiogICAgICAgIHBvcnQgLSB0aGUgbG9naWNhbCBwb3J0IG51bWJlcgoqICAgICAgICBtb2RlIC0gR1RfRlJBTUVfTU9ERSB0eXBlCioKKiBPVVRQVVRTOgoqICAgICAgICBOb25lLgoqCiogUkVUVVJOUzoKKiAgICAgICAgR1RfT0sgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICAgR1RfRkFJTCAtIG9uIGVycm9yCiogICAgICAgIEdUX0JBRF9QQVJBTSAtIGlmIG1vZGUgaXMgdW5rbm93bgoqICAgICAgICBHVF9OT1RfU1VQUE9SVEVEIC0gaWYgY3VycmVudCBkZXZpY2UgZG9lcyBub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCioKKiBDT01NRU5UUzoKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3BydFNldEZyYW1lTW9kZQooCiAgICBJTiAgR1RfUURfREVWICAgICpkZXYsCiAgICBJTiAgR1RfTFBPUlQgICAgcG9ydCwKICAgIElOICBHVF9GUkFNRV9NT0RFICAgIG1vZGUKKQp7CiAgICBHVF9TVEFUVVMgICAgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX1U4ICAgICAgICAgICBod1BvcnQ7ICAgICAgICAgLyogdGhlIHBoeXNpY2FsIHBvcnQgbnVtYmVyICAgICAqLwoKICAgIERCR19JTkZPKCgiZ3BydFNldEZyYW1lTW9kZSBDYWxsZWQuXG4iKSk7CgogICAgLyogdHJhbnNsYXRlIExQT1JUIHRvIGhhcmR3YXJlIHBvcnQgKi8KICAgIGh3UG9ydCA9IEdUX0xQT1JUXzJfUE9SVChwb3J0KTsKCiAgICBpZiAoIUlTX0lOX0RFVl9HUk9VUChkZXYsREVWX0ZSQU1FX01PREUpKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfTk9UX1NVUFBPUlRFRFxuIikpOwogICAgICAgIHJldHVybiBHVF9OT1RfU1VQUE9SVEVEOwogICAgfQoKICAgIHN3aXRjaCAobW9kZSkKICAgIHsKICAgICAgICBjYXNlIEdUX0ZSQU1FX01PREVfTk9STUFMOgogICAgICAgIGNhc2UgR1RfRlJBTUVfTU9ERV9EU0E6CiAgICAgICAgY2FzZSBHVF9GUkFNRV9NT0RFX1BST1ZJREVSOgogICAgICAgIGNhc2UgR1RfRlJBTUVfTU9ERV9FVEhFUl9UWVBFX0RTQToKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgREJHX0lORk8oKCJCYWQgUGFyYW1ldGVyXG4iKSk7CiAgICAgICAgICAgIHJldHVybiBHVF9CQURfUEFSQU07CiAgICB9CgogICAgLyogU2V0IEZyYW1lIE1vZGUuICAqLwogICAgcmV0VmFsID0gaHdTZXRQb3J0UmVnRmllbGQoZGV2LGh3UG9ydCwgUURfUkVHX1BPUlRfQ09OVFJPTCwgOCwgMiwgKEdUX1UxNiltb2RlKTsKCiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJPSy5cbiIpKTsKICAgIH0KICAgIHJldHVybiByZXRWYWw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3BydEdldEZyYW1lTW9kZQoqCiogREVTQ1JJUFRJT046CiogICAgICAgIEZybWFlIE1vZGUgaXMgdXNlZCB0byBkZWZpbmUgdGhlIGV4cGVjdGVkIEluZ3Jlc3MgYW5kIHRoZSBnZW5lcmF0ZWQgRWdyZXNzCiogICAgICAgIHRhZ2dpbmcgZnJhbWUgZm9ybWF0IGZvciB0aGlzIHBvcnQgYXMgZm9sbG93czoKKiAgICAgICAgICAgIEdUX0ZSQU1FX01PREVfTk9STUFMIC0KKiAgICAgICAgICAgICAgICBOb3JtYWwgTmV0d29yayBtb2RlIHVzZXMgaW5kdXN0cnkgc3RhbmRhcmQgSUVFRSA4MDIuM2FjIFRhZ2dlZCBvcgoqICAgICAgICAgICAgICAgIFVudGFnZ2VkIGZyYW1lcy4gVGFnZ2VkIGZyYW1lcyB1c2UgYW4gRXRoZXIgVHlwZSBvZiAweDgxMDAuCiogICAgICAgICAgICBHVF9GUkFNRV9NT0RFX0RTQSAtCiogICAgICAgICAgICAgICAgRFNBIG1vZGUgdXNlcyBhIE1hcnZlbGwgZGVmaW5lZCB0YWdnZWQgZnJhbWUgZm9ybWF0IGZvcgoqICAgICAgICAgICAgICAgIENoaXAtdG8tQ2hpcCBhbmQgQ2hpcC10by1DUFUgY29ubmVjdGlvbnMuCiogICAgICAgICAgICBHVF9GUkFNRV9NT0RFX1BST1ZJREVSIC0KKiAgICAgICAgICAgICAgICBQcm92aWRlciBtb2RlIHVzZXMgdXNlciBkZWZpbmFibGUgRXRoZXIgVHlwZXMgcGVyIHBvcnQKKiAgICAgICAgICAgICAgICAoc2VlIGdwcnRTZXRQb3J0RVR5cGUvZ3BydEdldFBvcnRFVHlwZSBBUEkpLgoqICAgICAgICAgICAgR1RfRlJBTUVfTU9ERV9FVEhFUl9UWVBFX0RTQSAtCiogICAgICAgICAgICAgICAgRXRoZXIgVHlwZSBEU0EgbW9kZSB1c2VzIHN0YW5kYXJkIE1hcnZlbGwgRFNBIFRhZ2dlZCBmcmFtZSBpbmZvCiogICAgICAgICAgICAgICAgZmxvd2luZyBhIHVzZXIgZGVmaW5hYmxlIEV0aGVyIFR5cGUuIFRoaXMgbW9kZSBhbGxvd3MgdGhlIG1peHR1cmUKKiAgICAgICAgICAgICAgICBvZiBOb3JtYWwgTmV0d29yayBmcmFtZXMgd2l0aCBEU0EgVGFnZ2VkIGZyYW1lcyBhbmQgaXMgdXNlZnVsIHRvCiogICAgICAgICAgICAgICAgYmUgdXNlZCBvbiBwb3J0cyB0aGF0IGNvbm5lY3QgdG8gYSBDUFUuCioKKiBJTlBVVFM6CiogICAgICAgIHBvcnQgLSB0aGUgbG9naWNhbCBwb3J0IG51bWJlcgoqCiogT1VUUFVUUzoKKiAgICAgICAgbW9kZSAtIEdUX0ZSQU1FX01PREUgdHlwZQoqCiogUkVUVVJOUzoKKiAgICAgICAgR1RfT0sgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICAgR1RfRkFJTCAtIG9uIGVycm9yCiogICAgICAgIEdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBncHJ0R2V0RnJhbWVNb2RlCigKICAgIElOICBHVF9RRF9ERVYgICAgKmRldiwKICAgIElOICBHVF9MUE9SVCAgICBwb3J0LAogICAgT1VUIEdUX0ZSQU1FX01PREUgICAgKm1vZGUKKQp7CiAgICBHVF9TVEFUVVMgICAgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX1U4ICAgICAgICAgICBod1BvcnQ7ICAgICAgICAgLyogdGhlIHBoeXNpY2FsIHBvcnQgbnVtYmVyICAgICAqLwogICAgR1RfVTE2ICAgICAgICAgIGRhdGE7ICAgICAgICAgICAvKiB0byBrZWVwIHRoZSByZWFkIHZhbHZlICAgICAgICovCgogICAgREJHX0lORk8oKCJncHJ0R2V0RnJhbWVNb2RlIENhbGxlZC5cbiIpKTsKCiAgICAvKiB0cmFuc2xhdGUgTFBPUlQgdG8gaGFyZHdhcmUgcG9ydCAqLwogICAgaHdQb3J0ID0gR1RfTFBPUlRfMl9QT1JUKHBvcnQpOwoKICAgIGlmICghSVNfSU5fREVWX0dST1VQKGRldixERVZfRlJBTUVfTU9ERSkpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CgogICAgLyogR2V0IFBhdXNlIExpbWl0LiAgKi8KICAgIHJldFZhbCA9IGh3R2V0UG9ydFJlZ0ZpZWxkKGRldixod1BvcnQsIFFEX1JFR19QT1JUX0NPTlRST0wsIDgsIDIsICZkYXRhKTsKICAgICptb2RlID0gZGF0YTsKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBEQkdfSU5GTygoIk9LLlxuIikpOwogICAgfQogICAgcmV0dXJuIHJldFZhbDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3BydFNldEhvbGRBdDEKKgoqIERFU0NSSVBUSU9OOgoqICAgICAgICBIb2xkIEFnaW5nIEFUVSBFbnRyaWVzIGF0IGFuIEVudHJ5IFN0YXRlIHZhbHVlIG9mIDEuIFdoZW4gdGhpcyBmZWF0dXJlCiogICAgICAgIGlzIHNldCB0byBHVF9UUlVFLCBBVFUgZW50cmllcyBhc3NvY2lhdGVkIHdpdGggdGhpcyBwb3J0IHdpbGwgYWdlIGRvd24KKiAgICAgICAgdG8gYW4gRW50cnkgU3RhdGUgb2YgMHgxLCBidXQgd2lsbCBub3QgZ28gdG8gMHgwICgweDAgd291bGQgcHVyZ2UgdGhlCiogICAgICAgIGVudHJ5KQoqCiogSU5QVVRTOgoqICAgICAgICBwb3J0IC0gdGhlIGxvZ2ljYWwgcG9ydCBudW1iZXIuCiogICAgICAgIG1vZGUgLSBHVF9UUlVFIHRvIGhvbGQgYWdpbmcgQVRVIGVudHJ5IHdpdGggRW50cnkgU3RhdGUgb2YgMSwKKiAgICAgICAgICAgICAgIEdUX0ZBTFNFIG90aGVyd2lzZQoqCiogT1VUUFVUUzoKKiAgICAgICAgTm9uZS4KKgoqIFJFVFVSTlM6CiogICAgICAgIEdUX09LICAgLSBvbiBzdWNjZXNzCiogICAgICAgIEdUX0ZBSUwgLSBvbiBlcnJvcgoqICAgICAgICBHVF9OT1RfU1VQUE9SVEVEIC0gaWYgY3VycmVudCBkZXZpY2UgZG9lcyBub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCioKKiBDT01NRU5UUzoKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3BydFNldEhvbGRBdDEKKAogICAgSU4gR1RfUURfREVWICAgICpkZXYsCiAgICBJTiBHVF9MUE9SVCAgICAgcG9ydCwKICAgIElOIEdUX0JPT0wgICAgICAgIG1vZGUKKQp7CiAgICBHVF9VMTYgICAgICAgICAgZGF0YTsKICAgIEdUX1NUQVRVUyAgICAgICByZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwogICAgR1RfVTggICAgICAgICAgIGh3UG9ydDsgICAgICAgICAvKiB0aGUgcGh5c2ljYWwgcG9ydCBudW1iZXIgICAgICovCgogICAgREJHX0lORk8oKCJncHJ0U2V0SG9sZEF0MSBDYWxsZWQuXG4iKSk7CgogICAgLyogdHJhbnNsYXRlIExQT1JUIHRvIGhhcmR3YXJlIHBvcnQgKi8KICAgIGh3UG9ydCA9IEdUX0xQT1JUXzJfUE9SVChwb3J0KTsKCiAgICAvKiBjaGVjayBpZiBkZXZpY2UgYWxsb3dzIHRvIGZvcmNlIGEgZmxvd2NvbnRyb2wgZGlzYWJsZWQgKi8KICAgIGlmICghSVNfSU5fREVWX0dST1VQKGRldixERVZfQUdFX0hPTEQpKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfTk9UX1NVUFBPUlRFRFxuIikpOwogICAgICAgIHJldHVybiBHVF9OT1RfU1VQUE9SVEVEOwogICAgfQoKICAgIC8qIHRyYW5zbGF0ZSBCT09MIHRvIGJpbmFyeSAqLwogICAgQk9PTF8yX0JJVChtb2RlLCBkYXRhKTsKCiAgICAvKiBTZXQgSG9sZEF0MSAqLwogICAgcmV0VmFsID0gaHdTZXRQb3J0UmVnRmllbGQoZGV2LGh3UG9ydCwgUURfUkVHX1BPUlRfQVNTT0NJQVRJT04sIDE1LCAxLCBkYXRhKTsKCiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJPSy5cbiIpKTsKICAgIH0KICAgIHJldHVybiByZXRWYWw7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdwcnRHZXRIb2xkQXQxCioKKiBERVNDUklQVElPTjoKKiAgICAgICAgSG9sZCBBZ2luZyBBVFUgRW50cmllcyBhdCBhbiBFbnRyeSBTdGF0ZSB2YWx1ZSBvZiAxLiBXaGVuIHRoaXMgZmVhdHVyZQoqICAgICAgICBpcyBzZXQgdG8gR1RfVFJVRSwgQVRVIGVudHJpZXMgYXNzb2NpYXRlZCB3aXRoIHRoaXMgcG9ydCB3aWxsIGFnZSBkb3duCiogICAgICAgIHRvIGFuIEVudHJ5IFN0YXRlIG9mIDB4MSwgYnV0IHdpbGwgbm90IGdvIHRvIDB4MCAoMHgwIHdvdWxkIHB1cmdlIHRoZQoqICAgICAgICBlbnRyeSkKKgoqIElOUFVUUzoKKiAgICAgICAgcG9ydCAgLSB0aGUgbG9naWNhbCBwb3J0IG51bWJlci4KKgoqIE9VVFBVVFM6CiogICAgICAgIG1vZGUgLSBHVF9UUlVFIHRvIGhvbGQgYWdpbmcgQVRVIGVudHJ5IHdpdGggRW50cnkgU3RhdGUgb2YgMSwKKiAgICAgICAgICAgICAgIEdUX0ZBTFNFIG90aGVyd2lzZQoqCiogUkVUVVJOUzoKKiAgICAgICAgR1RfT0sgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICAgR1RfRkFJTCAtIG9uIGVycm9yCiogICAgICAgIEdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBncHJ0R2V0SG9sZEF0MQooCiAgICBJTiAgR1RfUURfREVWICAgICpkZXYsCiAgICBJTiAgR1RfTFBPUlQgICAgcG9ydCwKICAgIE9VVCBHVF9CT09MICAgICAgKm1vZGUKKQp7CiAgICBHVF9TVEFUVVMgICAgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX1U4ICAgICAgICAgICBod1BvcnQ7ICAgICAgICAgLyogdGhlIHBoeXNpY2FsIHBvcnQgbnVtYmVyICAgICAqLwogICAgR1RfVTE2ICAgICAgICAgIGRhdGE7ICAgICAgICAgICAvKiB0byBrZWVwIHRoZSByZWFkIHZhbHZlICAgICAgICovCgogICAgREJHX0lORk8oKCJncHJ0R2V0SG9sZEF0MSBDYWxsZWQuXG4iKSk7CgogICAgLyogdHJhbnNsYXRlIExQT1JUIHRvIGhhcmR3YXJlIHBvcnQgKi8KICAgIGh3UG9ydCA9IEdUX0xQT1JUXzJfUE9SVChwb3J0KTsKCiAgICAvKiBjaGVjayBpZiBkZXZpY2UgYWxsb3dzIHRvIGZvcmNlIGEgZmxvd2NvbnRyb2wgZGlzYWJsZWQgKi8KICAgIGlmICghSVNfSU5fREVWX0dST1VQKGRldixERVZfQUdFX0hPTEQpKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfTk9UX1NVUFBPUlRFRFxuIikpOwogICAgICAgIHJldHVybiBHVF9OT1RfU1VQUE9SVEVEOwogICAgfQoKICAgIC8qIEdldCBIb2xkQXQxICovCiAgICByZXRWYWwgPSBod0dldFBvcnRSZWdGaWVsZChkZXYsaHdQb3J0LCBRRF9SRUdfUE9SVF9BU1NPQ0lBVElPTiwgMTUsIDEsICZkYXRhKTsKCiAgICBCSVRfMl9CT09MKGRhdGEsICptb2RlKTsKCiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJPSy5cbiIpKTsKICAgIH0KCiAgICByZXR1cm4gcmV0VmFsOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBncHJ0U2V0SW50T25BZ2VPdXQKKgoqIERFU0NSSVBUSU9OOgoqICAgICAgICBJbnRlcnJ1cHQgb24gQWdlIE91dC4gV2hlbiBhZ2luZyBpcyBlbmFibGVkLCBhbGwgbm9uLXN0YXRpYyBhZGRyZXNzCiogICAgICAgIGVudHJpZXMgaW4gdGhlIEFUVSdzIGFkZHJlc3MgZGF0YWJhc2UgYXJlIHBlcmlvZGljYWxseSBhZ2VkLgoqICAgICAgICBXaGVuIHRoaXMgZmVhdHVyZSBpcyBzZXQgdG8gR1RfVFJVRSBhbmQgYW4gZW50cnkgYXNzb2NpYXRlZCB3aXRoIHRoaXMKKiAgICAgICAgcG9ydCBpcyBhZ2VkIG91dCwgYW4gQWdlT3V0VmlvbGF0aW9uIHdpbGwgYmUgY2FwdHVyZWQgZm9yIHRoYXQgZW50cnkuCioKKiBJTlBVVFM6CiogICAgICAgIHBvcnQgLSB0aGUgbG9naWNhbCBwb3J0IG51bWJlci4KKiAgICAgICAgbW9kZSAtIEdUX1RSVUUgdG8gZW5hYmxlIEFnZU91dFZpbG9hdGlvbiBpbnRlcnJ1cHQKKiAgICAgICAgICAgICAgIEdUX0ZBTFNFIG90aGVyd2lzZQoqCiogT1VUUFVUUzoKKiAgICAgICAgTm9uZS4KKgoqIFJFVFVSTlM6CiogICAgICAgIEdUX09LICAgLSBvbiBzdWNjZXNzCiogICAgICAgIEdUX0ZBSUwgLSBvbiBlcnJvcgoqICAgICAgICBHVF9OT1RfU1VQUE9SVEVEIC0gaWYgY3VycmVudCBkZXZpY2UgZG9lcyBub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCioKKiBDT01NRU5UUzoKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3BydFNldEludE9uQWdlT3V0CigKICAgIElOIEdUX1FEX0RFViAgICAqZGV2LAogICAgSU4gR1RfTFBPUlQgICAgIHBvcnQsCiAgICBJTiBHVF9CT09MICAgICAgICBtb2RlCikKewogICAgR1RfVTE2ICAgICAgICAgIGRhdGE7CiAgICBHVF9TVEFUVVMgICAgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX1U4ICAgICAgICAgICBod1BvcnQ7ICAgICAgICAgLyogdGhlIHBoeXNpY2FsIHBvcnQgbnVtYmVyICAgICAqLwoKICAgIERCR19JTkZPKCgiZ3BydFNldEludE9uQWdlT3V0IENhbGxlZC5cbiIpKTsKCiAgICAvKiB0cmFuc2xhdGUgTFBPUlQgdG8gaGFyZHdhcmUgcG9ydCAqLwogICAgaHdQb3J0ID0gR1RfTFBPUlRfMl9QT1JUKHBvcnQpOwoKICAgIC8qIGNoZWNrIGlmIGRldmljZSBhbGxvd3MgdG8gZm9yY2UgYSBmbG93Y29udHJvbCBkaXNhYmxlZCAqLwogICAgaWYgKCFJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9BR0VfT1VUX0lOVCkpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CgogICAgLyogdHJhbnNsYXRlIEJPT0wgdG8gYmluYXJ5ICovCiAgICBCT09MXzJfQklUKG1vZGUsIGRhdGEpOwoKICAgIC8qIFNldCBBZ2UgT3V0IEludGVycnVwdCBFbmFibGUgTW9kZS4gKi8KICAgIHJldFZhbCA9IGh3U2V0UG9ydFJlZ0ZpZWxkKGRldixod1BvcnQsIFFEX1JFR19QT1JUX0FTU09DSUFUSU9OLCAxNCwgMSwgZGF0YSk7CgogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgewogICAgICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIERCR19JTkZPKCgiT0suXG4iKSk7CiAgICB9CiAgICByZXR1cm4gcmV0VmFsOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBncHJ0R2V0SW50T25BZ2VPdXQKKgoqIERFU0NSSVBUSU9OOgoqICAgICAgICBJbnRlcnJ1cHQgb24gQWdlIE91dC4gV2hlbiBhZ2luZyBpcyBlbmFibGVkLCBhbGwgbm9uLXN0YXRpYyBhZGRyZXNzCiogICAgICAgIGVudHJpZXMgaW4gdGhlIEFUVSdzIGFkZHJlc3MgZGF0YWJhc2UgYXJlIHBlcmlvZGljYWxseSBhZ2VkLgoqICAgICAgICBXaGVuIHRoaXMgZmVhdHVyZSBpcyBzZXQgdG8gR1RfVFJVRSBhbmQgYW4gZW50cnkgYXNzb2NpYXRlZCB3aXRoIHRoaXMKKiAgICAgICAgcG9ydCBpcyBhZ2VkIG91dCwgYW4gQWdlT3V0VmlvbGF0aW9uIHdpbGwgYmUgY2FwdHVyZWQgZm9yIHRoYXQgZW50cnkuCioKKiBJTlBVVFM6CiogICAgICAgIHBvcnQgIC0gdGhlIGxvZ2ljYWwgcG9ydCBudW1iZXIuCioKKiBPVVRQVVRTOgoqICAgICAgICBtb2RlIC0gR1RfVFJVRSB0byBlbmFibGUgQWdlT3V0Vmlsb2F0aW9uIGludGVycnVwdAoqICAgICAgICAgICAgICAgR1RfRkFMU0Ugb3RoZXJ3aXNlCioKKiBSRVRVUk5TOgoqICAgICAgICBHVF9PSyAgIC0gb24gc3VjY2VzcwoqICAgICAgICBHVF9GQUlMIC0gb24gZXJyb3IKKiAgICAgICAgR1RfTk9UX1NVUFBPUlRFRCAtIGlmIGN1cnJlbnQgZGV2aWNlIGRvZXMgbm90IHN1cHBvcnQgdGhpcyBmZWF0dXJlLgoqCiogQ09NTUVOVFM6CioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdwcnRHZXRJbnRPbkFnZU91dAooCiAgICBJTiAgR1RfUURfREVWICAgICpkZXYsCiAgICBJTiAgR1RfTFBPUlQgICAgcG9ydCwKICAgIE9VVCBHVF9CT09MICAgICAgKm1vZGUKKQp7CiAgICBHVF9TVEFUVVMgICAgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX1U4ICAgICAgICAgICBod1BvcnQ7ICAgICAgICAgLyogdGhlIHBoeXNpY2FsIHBvcnQgbnVtYmVyICAgICAqLwogICAgR1RfVTE2ICAgICAgICAgIGRhdGE7ICAgICAgICAgICAvKiB0byBrZWVwIHRoZSByZWFkIHZhbHZlICAgICAgICovCgogICAgREJHX0lORk8oKCJncHJ0R2V0SW50T25BZ2VPdXQgQ2FsbGVkLlxuIikpOwoKICAgIC8qIHRyYW5zbGF0ZSBMUE9SVCB0byBoYXJkd2FyZSBwb3J0ICovCiAgICBod1BvcnQgPSBHVF9MUE9SVF8yX1BPUlQocG9ydCk7CgogICAgLyogY2hlY2sgaWYgZGV2aWNlIGFsbG93cyB0byBmb3JjZSBhIGZsb3djb250cm9sIGRpc2FibGVkICovCiAgICBpZiAoIUlTX0lOX0RFVl9HUk9VUChkZXYsREVWX0FHRV9PVVRfSU5UKSkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX05PVF9TVVBQT1JURURcbiIpKTsKICAgICAgICByZXR1cm4gR1RfTk9UX1NVUFBPUlRFRDsKICAgIH0KCiAgICAvKiBHZXQgSW50T25BZ2VPdXQgKi8KICAgIHJldFZhbCA9IGh3R2V0UG9ydFJlZ0ZpZWxkKGRldixod1BvcnQsIFFEX1JFR19QT1JUX0FTU09DSUFUSU9OLCAxNCwgMSwgJmRhdGEpOwoKICAgIEJJVF8yX0JPT0woZGF0YSwgKm1vZGUpOwoKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBEQkdfSU5GTygoIk9LLlxuIikpOwogICAgfQoKICAgIHJldHVybiByZXRWYWw7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdwcnRTZXRSZWZyZXNoTG9ja2VkCioKKiBERVNDUklQVElPTjoKKiAgICAgICAgQXV0byBSZWZyZXNoIGtub3duIGFkZHJlc3NlcyB3aGVuIHBvcnQgaXMgTG9ja2VkLiBBbHJlYWR5IGtub3duIGFkZHJlc3NlcwoqICAgICAgICB3aWxsIGJlIGF1dG8gcmVmcmVzaGVkIHdoZW4gdGhpcyBmZWF0dXJlIGlzIGVuYWJsZWQuIFdoZW4gdGhpcyBmZWF0dXJlCiogICAgICAgIGlzIGRpc2FibGVkLCBhdXRvIHJlZnJlc2hpbmcgd2lsbCBub3Qgb2NjdXIgb24gTG9ja2VkIHBvcnRzLgoqCiogSU5QVVRTOgoqICAgICAgICBwb3J0IC0gdGhlIGxvZ2ljYWwgcG9ydCBudW1iZXIuCiogICAgICAgIG1vZGUgLSBHVF9UUlVFIHRvIGVuYWJsZSBBdXRvIFJlZnJlc2gga25vd24gYWRkcmVzc2VzIG9uIGxvY2tlZCBwb3J0CiogICAgICAgICAgICAgICBHVF9GQUxTRSBvdGhlcndpc2UKKgoqIE9VVFBVVFM6CiogICAgICAgIE5vbmUuCioKKiBSRVRVUk5TOgoqICAgICAgICBHVF9PSyAgIC0gb24gc3VjY2VzcwoqICAgICAgICBHVF9GQUlMIC0gb24gZXJyb3IKKiAgICAgICAgR1RfTk9UX1NVUFBPUlRFRCAtIGlmIGN1cnJlbnQgZGV2aWNlIGRvZXMgbm90IHN1cHBvcnQgdGhpcyBmZWF0dXJlLgoqCiogQ09NTUVOVFM6CioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdwcnRTZXRSZWZyZXNoTG9ja2VkCigKICAgIElOIEdUX1FEX0RFViAgICAqZGV2LAogICAgSU4gR1RfTFBPUlQgICAgIHBvcnQsCiAgICBJTiBHVF9CT09MICAgICAgICBtb2RlCikKewogICAgR1RfVTE2ICAgICAgICAgIGRhdGE7CiAgICBHVF9TVEFUVVMgICAgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX1U4ICAgICAgICAgICBod1BvcnQ7ICAgICAgICAgLyogdGhlIHBoeXNpY2FsIHBvcnQgbnVtYmVyICAgICAqLwoKICAgIERCR19JTkZPKCgiZ3BydFNldFJlZnJlc2hMb2NrZWQgQ2FsbGVkLlxuIikpOwoKICAgIC8qIHRyYW5zbGF0ZSBMUE9SVCB0byBoYXJkd2FyZSBwb3J0ICovCiAgICBod1BvcnQgPSBHVF9MUE9SVF8yX1BPUlQocG9ydCk7CgogICAgLyogY2hlY2sgaWYgZGV2aWNlIGFsbG93cyB0byBmb3JjZSBhIGZsb3djb250cm9sIGRpc2FibGVkICovCiAgICBpZiAoIUlTX0lOX0RFVl9HUk9VUChkZXYsREVWX0FVVE9fUkVGUkVTSF9MT0NLRUQpKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfTk9UX1NVUFBPUlRFRFxuIikpOwogICAgICAgIHJldHVybiBHVF9OT1RfU1VQUE9SVEVEOwogICAgfQoKICAgIC8qIHRyYW5zbGF0ZSBCT09MIHRvIGJpbmFyeSAqLwogICAgQk9PTF8yX0JJVChtb2RlLCBkYXRhKTsKCiAgICAvKiBTZXQgUmVmcmVzaExvY2tlZCAqLwogICAgcmV0VmFsID0gaHdTZXRQb3J0UmVnRmllbGQoZGV2LGh3UG9ydCwgUURfUkVHX1BPUlRfQVNTT0NJQVRJT04sIDExLCAxLCBkYXRhKTsKCiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJPSy5cbiIpKTsKICAgIH0KICAgIHJldHVybiByZXRWYWw7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdwcnRHZXRSZWZyZXNoTG9ja2VkCioKKiBERVNDUklQVElPTjoKKiAgICAgICAgQXV0byBSZWZyZXNoIGtub3duIGFkZHJlc3NlcyB3aGVuIHBvcnQgaXMgTG9ja2VkLiBBbHJlYWR5IGtub3duIGFkZHJlc3NlcwoqICAgICAgICB3aWxsIGJlIGF1dG8gcmVmcmVzaGVkIHdoZW4gdGhpcyBmZWF0dXJlIGlzIGVuYWJsZWQuIFdoZW4gdGhpcyBmZWF0dXJlCiogICAgICAgIGlzIGRpc2FibGVkLCBhdXRvIHJlZnJlc2hpbmcgd2lsbCBub3Qgb2NjdXIgb24gTG9ja2VkIHBvcnRzLgoqCiogSU5QVVRTOgoqICAgICAgICBwb3J0ICAtIHRoZSBsb2dpY2FsIHBvcnQgbnVtYmVyLgoqCiogT1VUUFVUUzoKKiAgICAgICAgbW9kZSAtIEdUX1RSVUUgdG8gZW5hYmxlIEF1dG8gUmVmcmVzaCBrbm93biBhZGRyZXNzZXMgb24gbG9ja2VkIHBvcnQKKiAgICAgICAgICAgICAgIEdUX0ZBTFNFIG90aGVyd2lzZQoqCiogUkVUVVJOUzoKKiAgICAgICAgR1RfT0sgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICAgR1RfRkFJTCAtIG9uIGVycm9yCiogICAgICAgIEdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBncHJ0R2V0UmVmcmVzaExvY2tlZAooCiAgICBJTiAgR1RfUURfREVWICAgICpkZXYsCiAgICBJTiAgR1RfTFBPUlQgICAgcG9ydCwKICAgIE9VVCBHVF9CT09MICAgICAgKm1vZGUKKQp7CiAgICBHVF9TVEFUVVMgICAgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX1U4ICAgICAgICAgICBod1BvcnQ7ICAgICAgICAgLyogdGhlIHBoeXNpY2FsIHBvcnQgbnVtYmVyICAgICAqLwogICAgR1RfVTE2ICAgICAgICAgIGRhdGE7ICAgICAgICAgICAvKiB0byBrZWVwIHRoZSByZWFkIHZhbHZlICAgICAgICovCgogICAgREJHX0lORk8oKCJncHJ0R2V0UmVmcmVzaExvY2tlZCBDYWxsZWQuXG4iKSk7CgogICAgLyogdHJhbnNsYXRlIExQT1JUIHRvIGhhcmR3YXJlIHBvcnQgKi8KICAgIGh3UG9ydCA9IEdUX0xQT1JUXzJfUE9SVChwb3J0KTsKCiAgICAvKiBjaGVjayBpZiBkZXZpY2UgYWxsb3dzIHRvIGZvcmNlIGEgZmxvd2NvbnRyb2wgZGlzYWJsZWQgKi8KICAgIGlmICghSVNfSU5fREVWX0dST1VQKGRldixERVZfQVVUT19SRUZSRVNIX0xPQ0tFRCkpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CgogICAgLyogR2V0IFJlZnJlc2hMb2NrZWQgKi8KICAgIHJldFZhbCA9IGh3R2V0UG9ydFJlZ0ZpZWxkKGRldixod1BvcnQsIFFEX1JFR19QT1JUX0FTU09DSUFUSU9OLCAxMSwgMSwgJmRhdGEpOwoKICAgIEJJVF8yX0JPT0woZGF0YSwgKm1vZGUpOwoKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBEQkdfSU5GTygoIk9LLlxuIikpOwogICAgfQoKICAgIHJldHVybiByZXRWYWw7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdwcnRTZXRQb3J0RVR5cGUKKgoqIERFU0NSSVBUSU9OOgoqICAgICAgICBUaGlzIHJvdXRpbmUgc2V0cyB0aGUgcG9ydCdzIHNwZWNpYWwgRXRoZXIgVHlwZS4gVGhpcyBFdGhlciBUeXBlIGlzIHVzZWQKKiAgICAgICAgZm9yIFBvbGljeSAoc2VlIGdwcnRTZXRQb2xpY3kgQVBJKSBhbmQgRnJhbWVNb2RlIChzZWUgZ3BydFNldEZyYW1lTW9kZSBBUEkpLgoqCiogSU5QVVRTOgoqICAgICAgICBwb3J0ICAtIHRoZSBsb2dpY2FsIHBvcnQgbnVtYmVyCiogICAgICAgIGV0eXBlIC0gcG9ydCdzIHNwZWNpYWwgZXRoZXIgdHlwZQoqCiogT1VUUFVUUzoKKiAgICAgICAgTm9uZS4KKgoqIFJFVFVSTlM6CiogICAgICAgIEdUX09LICAgLSBvbiBzdWNjZXNzCiogICAgICAgIEdUX0ZBSUwgLSBvbiBlcnJvcgoqICAgICAgICBHVF9OT1RfU1VQUE9SVEVEIC0gaWYgY3VycmVudCBkZXZpY2UgZG9lcyBub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCioKKiBDT01NRU5UUzoKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3BydFNldFBvcnRFVHlwZQooCiAgICBJTiBHVF9RRF9ERVYgICAgKmRldiwKICAgIElOIEdUX0xQT1JUICAgICAgICBwb3J0LAogICAgSU4gR1RfRVRZUEUgICAgICAgIGV0eXBlCikKewogICAgR1RfVTE2ICAgICAgICAgIGRhdGE7CiAgICBHVF9TVEFUVVMgICAgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX1U4ICAgICAgICAgICBod1BvcnQ7ICAgICAgICAgLyogdGhlIHBoeXNpY2FsIHBvcnQgbnVtYmVyICAgICAqLwoKICAgIERCR19JTkZPKCgiZ3BydFNldFBvcnRFVHlwZSBDYWxsZWQuXG4iKSk7CgogICAgLyogdHJhbnNsYXRlIExQT1JUIHRvIGhhcmR3YXJlIHBvcnQgKi8KICAgIGh3UG9ydCA9IEdUX0xQT1JUXzJfUE9SVChwb3J0KTsKCiAgICBpZiAoIUlTX0lOX0RFVl9HUk9VUChkZXYsREVWX1BPUlRfRVRZUEUpKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfTk9UX1NVUFBPUlRFRFxuIikpOwogICAgICAgIHJldHVybiBHVF9OT1RfU1VQUE9SVEVEOwogICAgfQoKICAgIGRhdGEgPSAoR1RfVTE2KWV0eXBlOwoKICAgIC8qIFNldCB0aGUgRXRoZXJUeXBlLiAgICAgICAgICAgICovCiAgICByZXRWYWwgPSBod1dyaXRlUG9ydFJlZyhkZXYsaHdQb3J0LCBRRF9SRUdfUE9SVF9FVEhfVFlQRSxkYXRhKTsKCiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJPSy5cbiIpKTsKICAgIH0KICAgIHJldHVybiByZXRWYWw7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdwcnRHZXRQb3J0RVR5cGUKKgoqIERFU0NSSVBUSU9OOgoqICAgICAgICBUaGlzIHJvdXRpbmUgcmV0cmlldmVzIHRoZSBwb3J0J3Mgc3BlY2lhbCBFdGhlciBUeXBlLiBUaGlzIEV0aGVyIFR5cGUgaXMgdXNlZAoqICAgICAgICBmb3IgUG9saWN5IChzZWUgZ3BydFNldFBvbGljeSBBUEkpIGFuZCBGcmFtZU1vZGUgKHNlZSBncHJ0U2V0RnJhbWVNb2RlIEFQSSkuCioKKiBJTlBVVFM6CiogICAgICAgIHBvcnQgIC0gdGhlIGxvZ2ljYWwgcG9ydCBudW1iZXIKKgoqIE9VVFBVVFM6CiogICAgICAgIGV0eXBlIC0gcG9ydCdzIHNwZWNpYWwgZXRoZXIgdHlwZQoqCiogUkVUVVJOUzoKKiAgICAgICAgR1RfT0sgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICAgR1RfRkFJTCAtIG9uIGVycm9yCiogICAgICAgIEdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBncHJ0R2V0UG9ydEVUeXBlCigKICAgIElOICBHVF9RRF9ERVYgICAgKmRldiwKICAgIElOICBHVF9MUE9SVCAgICBwb3J0LAogICAgT1VUIEdUX0VUWVBFICAgICpldHlwZQopCnsKICAgIEdUX1UxNiAgICAgICAgICBkYXRhOwogICAgR1RfU1RBVFVTICAgICAgIHJldFZhbDsgICAgICAgICAvKiBGdW5jdGlvbnMgcmV0dXJuIHZhbHVlLiAgICAgICovCiAgICBHVF9VOCAgICAgICAgICAgaHdQb3J0OyAgICAgICAgIC8qIHRoZSBwaHlzaWNhbCBwb3J0IG51bWJlciAgICAgKi8KCiAgICBEQkdfSU5GTygoImdwcnRHZXRQb3J0RVR5cGUgQ2FsbGVkLlxuIikpOwoKICAgIC8qIHRyYW5zbGF0ZSBMUE9SVCB0byBoYXJkd2FyZSBwb3J0ICovCiAgICBod1BvcnQgPSBHVF9MUE9SVF8yX1BPUlQocG9ydCk7CgogICAgaWYgKCFJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9QT1JUX0VUWVBFKSkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX05PVF9TVVBQT1JURURcbiIpKTsKICAgICAgICByZXR1cm4gR1RfTk9UX1NVUFBPUlRFRDsKICAgIH0KCiAgICAvKiBHZXQgdGhlIEV0aGVyVHlwZS4gICAgICAgICAgICAqLwogICAgcmV0VmFsID0gaHdSZWFkUG9ydFJlZyhkZXYsaHdQb3J0LCBRRF9SRUdfUE9SVF9FVEhfVFlQRSwmZGF0YSk7CgogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgewogICAgICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIERCR19JTkZPKCgiT0suXG4iKSk7CiAgICB9CgogICAgKmV0eXBlID0gKEdUX0VUWVBFKSBkYXRhOwoKICAgIHJldHVybiByZXRWYWw7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdzeXNTZXRKdW1ib01vZGUKKgoqIERFU0NSSVBUSU9OOgoqICAgICAgIFRoaXMgcm91dGluZSBTZXQgdGhlIG1heCBmcmFtZSBzaXplIGFsbG93ZWQgdG8gYmUgcmVjZWl2ZWQgYW5kIHRyYW5zbWl0dGVkCiogICAgICAgIGZyb20gb3IgdG8gYSBnaXZlbiBwb3J0LgoqCiogSU5QVVRTOgoqICAgICAgICBwb3J0IC0gdGhlIGxvZ2ljYWwgcG9ydCBudW1iZXIKKiAgICAgICBtb2RlIC0gR1RfSlVNQk9fTU9ERSAoMTUyMiwgMjA0OCwgb3IgMTAyNDApCioKKiBPVVRQVVRTOgoqICAgICAgIE5vbmUuCioKKiBSRVRVUk5TOgoqICAgICAgIEdUX09LICAgLSBvbiBzdWNjZXNzCiogICAgICAgR1RfRkFJTCAtIG9uIGVycm9yCiogICAgICAgIEdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBnc3lzU2V0SnVtYm9Nb2RlCigKICAgIElOICBHVF9RRF9ERVYgICAgKmRldiwKICAgIElOICBHVF9MUE9SVCAgICBwb3J0LAogICAgSU4gIEdUX0pVTUJPX01PREUgICBtb2RlCikKewogICAgR1RfU1RBVFVTICAgICAgIHJldFZhbDsgICAgICAgICAvKiBGdW5jdGlvbnMgcmV0dXJuIHZhbHVlLiAgICAgICovCiAgICBHVF9VOCAgICAgICAgICAgaHdQb3J0OyAgICAgICAgIC8qIHRoZSBwaHlzaWNhbCBwb3J0IG51bWJlciAgICAgKi8KCiAgICBEQkdfSU5GTygoImdzeXNTZXRKdW1ib01vZGUgQ2FsbGVkLlxuIikpOwoKICAgIGlmIChtb2RlID4gR1RfSlVNQk9fTU9ERV8xMDI0MCkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkJhZCBQYXJhbWV0ZXJcbiIpKTsKICAgICAgICByZXR1cm4gR1RfQkFEX1BBUkFNOwogICAgfQoKICAgIGlmICghSVNfSU5fREVWX0dST1VQKGRldixERVZfSlVNQk9fTU9ERSkpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CgogICAgLyogdHJhbnNsYXRlIExQT1JUIHRvIGhhcmR3YXJlIHBvcnQgKi8KICAgIGh3UG9ydCA9IEdUX0xQT1JUXzJfUE9SVChwb3J0KTsKCiAgICAvKiBTZXQgdGhlIEp1bWJvIEZyYW0gU2l6ZSBiaXQuICAgICAgICAgICAgICAgKi8KICAgIHJldFZhbCA9IGh3U2V0UG9ydFJlZ0ZpZWxkKGRldixod1BvcnQsUURfUkVHX1BPUlRfQ09OVFJPTDIsMTIsMiwoR1RfVTE2KW1vZGUpOwogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgewogICAgICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAgICAgIHJldHVybiByZXRWYWw7CiAgICB9CgogICAgREJHX0lORk8oKCJPSy5cbiIpKTsKICAgIHJldHVybiBHVF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBnc3lzR2V0SnVtYm9Nb2RlCioKKiBERVNDUklQVElPTjoKKiAgICAgICBUaGlzIHJvdXRpbmUgZ2V0cyB0aGUgbWF4IGZyYW1lIHNpemUgYWxsb3dlZCB0byBiZSByZWNlaXZlZCBhbmQgdHJhbnNtaXR0ZWQKKiAgICAgICAgZnJvbSBvciB0byBhIGdpdmVuIHBvcnQuCioKKiBJTlBVVFM6CiogICAgICAgIHBvcnQgIC0gdGhlIGxvZ2ljYWwgcG9ydCBudW1iZXIuCioKKiBPVVRQVVRTOgoqICAgICAgIG1vZGUgLSBHVF9KVU1CT19NT0RFICgxNTIyLCAyMDQ4LCBvciAxMDI0MCkKKgoqIFJFVFVSTlM6CiogICAgICAgIEdUX09LICAgLSBvbiBzdWNjZXNzCiogICAgICAgIEdUX0ZBSUwgLSBvbiBlcnJvcgoqICAgICAgICBHVF9OT1RfU1VQUE9SVEVEIC0gaWYgY3VycmVudCBkZXZpY2UgZG9lcyBub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCioKKiBDT01NRU5UUzoKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3N5c0dldEp1bWJvTW9kZQooCiAgICBJTiAgR1RfUURfREVWICAgICpkZXYsCiAgICBJTiAgR1RfTFBPUlQgICAgcG9ydCwKICAgIE9VVCBHVF9KVU1CT19NT0RFICAgKm1vZGUKKQp7CiAgICBHVF9TVEFUVVMgICAgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX1U4ICAgICAgICAgICBod1BvcnQ7ICAgICAgICAgLyogdGhlIHBoeXNpY2FsIHBvcnQgbnVtYmVyICAgICAqLwogICAgR1RfVTE2ICAgICAgICAgIGRhdGE7ICAgICAgICAgICAvKiB0byBrZWVwIHRoZSByZWFkIHZhbHZlICAgICAgICovCgogICAgREJHX0lORk8oKCJnc3lzR2V0SnVtYm9Nb2RlIENhbGxlZC5cbiIpKTsKCiAgICBpZiAoIUlTX0lOX0RFVl9HUk9VUChkZXYsREVWX0pVTUJPX01PREUpKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfTk9UX1NVUFBPUlRFRFxuIikpOwogICAgICAgIHJldHVybiBHVF9OT1RfU1VQUE9SVEVEOwogICAgfQoKICAgIC8qIHRyYW5zbGF0ZSBMUE9SVCB0byBoYXJkd2FyZSBwb3J0ICovCiAgICBod1BvcnQgPSBHVF9MUE9SVF8yX1BPUlQocG9ydCk7CgogICAgLyogR2V0IEp1bWJvIEZyYW1lIE1vZGUuICAgICAgICAgICAgKi8KICAgIHJldFZhbCA9IGh3R2V0UG9ydFJlZ0ZpZWxkKGRldixod1BvcnQsUURfUkVHX1BPUlRfQ09OVFJPTDIsMTIsMiwmZGF0YSApOwoKICAgICptb2RlID0gKEdUX0pVTUJPX01PREUpZGF0YTsKCiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJPSy5cbiIpKTsKICAgIH0KCiAgICByZXR1cm4gcmV0VmFsOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBncHJ0R2V0MjAwQmFzZQoqCiogREVTQ1JJUFRJT046CiogICAgICAgIDIwMCBCYXNlIG1vZGUuIFRoaXMgYml0IGNhbiBiZSB1c2VkIHRvIGNoYW5nZSB0aGUgcG9ydCdzIFB4X0dUWENMSwoqICAgICAgICBmcmVxdWVuY3kgdG8gNTBNSHogdG8gc3VwcG9ydCAyMDAgQkFTRSBtb2RlIGFzIGZvbGxvd3M6CiogICAgICAgIDAgPSAyNU1IeiBQeF9HVFhDTEsKKiAgICAgICAgMSA9IDUwTUh6IFB4X0dUWENMSwoqCiogSU5QVVRTOgoqICAgICAgICBwb3J0IC0gdGhlIGxvZ2ljYWwgcG9ydCBudW1iZXIuCioKKiBPVVRQVVRTOgoqICAgICAgICBtb2RlIC0gMCBmb3IgMTAwTWJwcywgMSBmb3IgMjAwTWJwcwoqCiogUkVUVVJOUzoKKiAgICAgICAgR1RfT0sgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICAgR1RfRkFJTCAtIG9uIGVycm9yCiogICAgICAgIEdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqICAgICAgICBDX01vZGUgc2hvdWxkIGJlIHNldCB0byAweDIgaW4gb3JkZXIgZm9yIHRoaXMgQVBJIHRvIHdvcmsKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3BydEdldDIwMEJhc2UKKAogICAgSU4gIEdUX1FEX0RFViAgICAqZGV2LAogICAgSU4gIEdUX0xQT1JUICAgICBwb3J0LAogICAgT1VUIEdUX1UzMiAgICAgICptb2RlCikKewogICAgR1RfU1RBVFVTICAgICAgIHJldFZhbDsgICAgICAgICAvKiBGdW5jdGlvbnMgcmV0dXJuIHZhbHVlLiAgICAgICovCiAgICBHVF9VOCAgICAgICAgICAgaHdQb3J0OyAgICAgICAgIC8qIHRoZSBwaHlzaWNhbCBwb3J0IG51bWJlciAgICAgKi8KICAgIEdUX1UxNiAgICAgICAgZGF0YTsKCiAgICBEQkdfSU5GTygoImdwcnRHZXQyMDBCYXNlIENhbGxlZC5cbiIpKTsKCiAgICBpZiAoIUlTX0lOX0RFVl9HUk9VUChkZXYsREVWXzIwMEJBU0VfQ0ZHKSkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX05PVF9TVVBQT1JURURcbiIpKTsKICAgICAgICByZXR1cm4gR1RfTk9UX1NVUFBPUlRFRDsKICAgIH0KCiAgICAvKiB0cmFuc2xhdGUgTFBPUlQgdG8gaGFyZHdhcmUgcG9ydCAqLwogICAgaHdQb3J0ID0gR1RfTFBPUlRfMl9QT1JUKHBvcnQpOwoKICAgIGlmIChod1BvcnQgPCAoZGV2LT5tYXhQb3J0cyAtIDIpKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfTk9UX1NVUFBPUlRFRFxuIikpOwogICAgICAgIHJldHVybiBHVF9OT1RfU1VQUE9SVEVEOwogICAgfQoKICAgIC8qIEdldCB0aGUgaGlnaCBlcnJvciByYXRlIGJpdC4gICovCiAgICByZXRWYWwgPSBod0dldFBvcnRSZWdGaWVsZChkZXYsaHdQb3J0LCBRRF9SRUdfUE9SVF9TVEFUVVMsNiwxLCAmZGF0YSk7CgogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgewogICAgICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIERCR19JTkZPKCgiT0suXG4iKSk7CiAgICB9CgogICAgKm1vZGUgPSBkYXRhOwoKICAgIC8qIHJldHVybiAqLwogICAgcmV0dXJuIHJldFZhbDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBncHJ0U2V0MjAwQmFzZQoqCiogREVTQ1JJUFRJT046CiogICAgICAgIDIwMCBCYXNlIG1vZGUuIFRoaXMgYml0IGNhbiBiZSB1c2VkIHRvIGNoYW5nZSB0aGUgcG9ydCdzIFB4X0dUWENMSwoqICAgICAgICBmcmVxdWVuY3kgdG8gNTBNSHogdG8gc3VwcG9ydCAyMDAgQkFTRSBtb2RlIGFzIGZvbGxvd3M6CiogICAgICAgIDAgPSAyNU1IeiBQeF9HVFhDTEsKKiAgICAgICAgMSA9IDUwTUh6IFB4X0dUWENMSwoqCiogSU5QVVRTOgoqICAgICAgICBwb3J0IC0gdGhlIGxvZ2ljYWwgcG9ydCBudW1iZXIuCiogICAgICAgIG1vZGUgLSAwIGZvciAxMDBNYnBzLCAxIGZvciAyMDBNYnBzCioKKiBPVVRQVVRTOgoqICAgICAgICBOb25lCioKKiBSRVRVUk5TOgoqICAgICAgICBHVF9PSyAgIC0gb24gc3VjY2VzcwoqICAgICAgICBHVF9GQUlMIC0gb24gZXJyb3IKKiAgICAgICAgR1RfTk9UX1NVUFBPUlRFRCAtIGlmIGN1cnJlbnQgZGV2aWNlIGRvZXMgbm90IHN1cHBvcnQgdGhpcyBmZWF0dXJlLgoqCiogQ09NTUVOVFM6CiogICAgICAgIENfTW9kZSBzaG91bGQgYmUgc2V0IHRvIDB4MiBpbiBvcmRlciBmb3IgdGhpcyBBUEkgdG8gd29yawoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBncHJ0U2V0MjAwQmFzZQooCiAgICBJTiAgR1RfUURfREVWICAgICpkZXYsCiAgICBJTiAgR1RfTFBPUlQgICAgIHBvcnQsCiAgICBJTiAgR1RfVTMyICAgICAgbW9kZQopCnsKICAgIEdUX1NUQVRVUyAgICAgICByZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwogICAgR1RfVTggICAgICAgICAgIGh3UG9ydDsgICAgICAgICAvKiB0aGUgcGh5c2ljYWwgcG9ydCBudW1iZXIgICAgICovCgogICAgREJHX0lORk8oKCJncHJ0U2V0MjAwQmFzZSBDYWxsZWQuXG4iKSk7CgogICAgaWYgKCFJU19JTl9ERVZfR1JPVVAoZGV2LERFVl8yMDBCQVNFX0NGRykpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CgogICAgLyogdHJhbnNsYXRlIExQT1JUIHRvIGhhcmR3YXJlIHBvcnQgKi8KICAgIGh3UG9ydCA9IEdUX0xQT1JUXzJfUE9SVChwb3J0KTsKCiAgICBpZiAoaHdQb3J0IDwgKGRldi0+bWF4UG9ydHMgLSAyKSkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX05PVF9TVVBQT1JURURcbiIpKTsKICAgICAgICByZXR1cm4gR1RfQkFEX1BBUkFNOwogICAgfQoKCS8qIEdldCB0aGUgaGlnaCBlcnJvciByYXRlIGJpdC4gICovCglyZXRWYWwgPSBod1NldFBvcnRSZWdGaWVsZChkZXYsIGh3UG9ydCwgUURfUkVHX1BDU19DT05UUk9MLCAxMiwgMSwgKEdUX1UxNiltb2RlICYgMHgxKTsKCiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJPSy5cbiIpKTsKICAgIH0KCiAgICAvKiByZXR1cm4gKi8KICAgIHJldHVybiByZXRWYWw7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdwcnRHZXRTd2l0Y2hSZWcKKgoqIERFU0NSSVBUSU9OOgoqICAgICAgIFRoaXMgcm91dGluZSByZWFkcyBTd2l0Y2ggUG9ydCBSZWdpc3RlcnMuCioKKiBJTlBVVFM6CiogICAgICAgcG9ydCAgICAtIGxvZ2ljYWwgcG9ydCBudW1iZXIKKiAgICAgICByZWdBZGRyIC0gVGhlIHJlZ2lzdGVyJ3MgYWRkcmVzcy4KKgoqIE9VVFBVVFM6CiogICAgICAgZGF0YSAgICAtIFRoZSByZWFkIHJlZ2lzdGVyJ3MgZGF0YS4KKgoqIFJFVFVSTlM6CiogICAgICAgR1RfT0sgICAgICAgICAgIC0gb24gc3VjY2VzcwoqICAgICAgIEdUX0ZBSUwgICAgICAgICAtIG9uIGVycm9yCioKKiBDT01NRU5UUzoKKiAgICAgICBOb25lLgoqCiogR2FsVGlzOgoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBncHJ0R2V0U3dpdGNoUmVnCigKICAgIElOICBHVF9RRF9ERVYgICAgKmRldiwKICAgIElOICBHVF9MUE9SVCAgICAgcG9ydCwKICAgIElOICBHVF9VMzIgICAgICAgICByZWdBZGRyLAogICAgT1VUIEdUX1UxNiAgICAgICAgICpkYXRhCikKewogICAgR1RfVTE2ICAgICAgICAgIHUxNkRhdGE7ICAgICAgICAgICAvKiBUaGUgcmVnaXN0ZXIncyByZWFkIGRhdGEuICAgICovCiAgICBHVF9VOCAgICAgICAgICAgaHdQb3J0OyAgICAgICAgIC8qIHRoZSBwaHlzaWNhbCBwb3J0IG51bWJlciAgICAgKi8KCiAgICBEQkdfSU5GTygoImdwcnRHZXRTd2l0Y2hSZWcgQ2FsbGVkLlxuIikpOwoKICAgIGh3UG9ydCA9IEdUX0xQT1JUXzJfUE9SVChwb3J0KTsKCiAgICAvKiBHZXQgUGh5IFJlZ2lzdGVyLiAqLwogICAgaWYoaHdSZWFkUG9ydFJlZyhkZXYsaHdQb3J0LChHVF9VOClyZWdBZGRyLCZ1MTZEYXRhKSAhPSBHVF9PSykKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgICAgICByZXR1cm4gR1RfRkFJTDsKICAgIH0KCiAgICAqZGF0YSA9IHUxNkRhdGE7CgogICAgcmV0dXJuIEdUX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdwcnRTZXRTd2l0Y2hSZWcKKgoqIERFU0NSSVBUSU9OOgoqICAgICAgIFRoaXMgcm91dGluZSB3cml0ZXMgU3dpdGNoIFBvcnQgUmVnaXN0ZXJzLgoqCiogSU5QVVRTOgoqICAgICAgIHBvcnQgICAgLSBsb2dpY2FsIHBvcnQgbnVtYmVyCiogICAgICAgcmVnQWRkciAtIFRoZSByZWdpc3RlcidzIGFkZHJlc3MuCioKKiBPVVRQVVRTOgoqICAgICAgIGRhdGEgICAgLSBUaGUgcmVhZCByZWdpc3RlcidzIGRhdGEuCioKKiBSRVRVUk5TOgoqICAgICAgIEdUX09LICAgICAgICAgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICBHVF9GQUlMICAgICAgICAgLSBvbiBlcnJvcgoqCiogQ09NTUVOVFM6CiogICAgICAgTm9uZS4KKgoqIEdhbFRpczoKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3BydFNldFN3aXRjaFJlZwooCiAgICBJTiAgR1RfUURfREVWICAgICAgICAqZGV2LAogICAgSU4gIEdUX0xQT1JUICAgICAgICBwb3J0LAogICAgSU4gIEdUX1UzMiAgICAgICAgICAgIHJlZ0FkZHIsCiAgICBJTiAgR1RfVTE2ICAgICAgICAgICAgZGF0YQopCnsKICAgIEdUX1U4ICAgICAgICAgICBod1BvcnQ7ICAgICAgICAgLyogdGhlIHBoeXNpY2FsIHBvcnQgbnVtYmVyICAgICAqLwoKICAgIERCR19JTkZPKCgiZ3BydFNldFN3aXRjaFJlZyBDYWxsZWQuXG4iKSk7CgogICAgaHdQb3J0ID0gR1RfTFBPUlRfMl9QT1JUKHBvcnQpOwoKICAgIC8qIEdldCB0aGUgU2NoZWR1bGluZyBiaXQuICAgICAgICAgICAgICAqLwogICAgaWYoaHdXcml0ZVBvcnRSZWcoZGV2LGh3UG9ydCwoR1RfVTgpcmVnQWRkcixkYXRhKSAhPSBHVF9PSykKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgICAgICByZXR1cm4gR1RfRkFJTDsKICAgIH0KCiAgICByZXR1cm4gR1RfT0s7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdwcnRHZXRHbG9iYWxSZWcKKgoqIERFU0NSSVBUSU9OOgoqICAgICAgIFRoaXMgcm91dGluZSByZWFkcyBTd2l0Y2ggR2xvYmFsIFJlZ2lzdGVycy4KKgoqIElOUFVUUzoKKiAgICAgICByZWdBZGRyIC0gVGhlIHJlZ2lzdGVyJ3MgYWRkcmVzcy4KKgoqIE9VVFBVVFM6CiogICAgICAgZGF0YSAgICAtIFRoZSByZWFkIHJlZ2lzdGVyJ3MgZGF0YS4KKgoqIFJFVFVSTlM6CiogICAgICAgR1RfT0sgICAgICAgICAgIC0gb24gc3VjY2VzcwoqICAgICAgIEdUX0ZBSUwgICAgICAgICAtIG9uIGVycm9yCioKKiBDT01NRU5UUzoKKiAgICAgICBOb25lLgoqCiogR2FsVGlzOgoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBncHJ0R2V0R2xvYmFsUmVnCigKICAgIElOICBHVF9RRF9ERVYgICAgKmRldiwKICAgIElOICBHVF9VMzIgICAgICAgICByZWdBZGRyLAogICAgT1VUIEdUX1UxNiAgICAgICAgICpkYXRhCikKewogICAgR1RfVTE2ICAgICAgICAgIHUxNkRhdGE7ICAgICAgICAgICAvKiBUaGUgcmVnaXN0ZXIncyByZWFkIGRhdGEuICAgICovCgogICAgREJHX0lORk8oKCJncHJ0R2V0R2xvYmFsUmVnIENhbGxlZC5cbiIpKTsKCiAgICAvKiBHZXQgUGh5IFJlZ2lzdGVyLiAqLwogICAgaWYoaHdSZWFkR2xvYmFsUmVnKGRldiwoR1RfVTgpcmVnQWRkciwmdTE2RGF0YSkgIT0gR1RfT0spCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX0ZBSUw7CiAgICB9CgogICAgKmRhdGEgPSB1MTZEYXRhOwoKICAgIHJldHVybiBHVF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBncHJ0U2V0R2xvYmFsUmVnCioKKiBERVNDUklQVElPTjoKKiAgICAgICBUaGlzIHJvdXRpbmUgd3JpdGVzIFN3aXRjaCBHbG9iYWwgUmVnaXN0ZXJzLgoqCiogSU5QVVRTOgoqICAgICAgIHJlZ0FkZHIgLSBUaGUgcmVnaXN0ZXIncyBhZGRyZXNzLgoqCiogT1VUUFVUUzoKKiAgICAgICBkYXRhICAgIC0gVGhlIHJlYWQgcmVnaXN0ZXIncyBkYXRhLgoqCiogUkVUVVJOUzoKKiAgICAgICBHVF9PSyAgICAgICAgICAgLSBvbiBzdWNjZXNzCiogICAgICAgR1RfRkFJTCAgICAgICAgIC0gb24gZXJyb3IKKgoqIENPTU1FTlRTOgoqICAgICAgIE5vbmUuCioKKiBHYWxUaXM6CioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdwcnRTZXRHbG9iYWxSZWcKKAogICAgSU4gIEdUX1FEX0RFViAgICAgICAgKmRldiwKICAgIElOICBHVF9VMzIgICAgICAgICAgICByZWdBZGRyLAogICAgSU4gIEdUX1UxNiAgICAgICAgICAgIGRhdGEKKQp7CiAgICBEQkdfSU5GTygoImdwcnRTZXRHbG9iYWxSZWcgQ2FsbGVkLlxuIikpOwoKICAgIC8qIEdldCB0aGUgU2NoZWR1bGluZyBiaXQuICAgICAgICAgICAgICAqLwogICAgaWYoaHdXcml0ZUdsb2JhbFJlZyhkZXYsKEdUX1U4KXJlZ0FkZHIsZGF0YSkgIT0gR1RfT0spCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX0ZBSUw7CiAgICB9CgogICAgcmV0dXJuIEdUX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdwcnRHZXRHbG9iYWwyUmVnCioKKiBERVNDUklQVElPTjoKKiAgICAgICBUaGlzIHJvdXRpbmUgcmVhZHMgU3dpdGNoIEdsb2JhbCAyIFJlZ2lzdGVycy4KKgoqIElOUFVUUzoKKiAgICAgICByZWdBZGRyIC0gVGhlIHJlZ2lzdGVyJ3MgYWRkcmVzcy4KKgoqIE9VVFBVVFM6CiogICAgICAgZGF0YSAgICAtIFRoZSByZWFkIHJlZ2lzdGVyJ3MgZGF0YS4KKgoqIFJFVFVSTlM6CiogICAgICAgR1RfT0sgICAgICAgICAgIC0gb24gc3VjY2VzcwoqICAgICAgIEdUX0ZBSUwgICAgICAgICAtIG9uIGVycm9yCioKKiBDT01NRU5UUzoKKiAgICAgICBOb25lLgoqCiogR2FsVGlzOgoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBncHJ0R2V0R2xvYmFsMlJlZwooCiAgICBJTiAgR1RfUURfREVWICAgICpkZXYsCiAgICBJTiAgR1RfVTMyICAgICAgICAgcmVnQWRkciwKICAgIE9VVCBHVF9VMTYgICAgICAgICAqZGF0YQopCnsKICAgIEdUX1UxNiAgICAgICAgICB1MTZEYXRhOyAgICAgICAgICAgLyogVGhlIHJlZ2lzdGVyJ3MgcmVhZCBkYXRhLiAgICAqLwoKICAgIERCR19JTkZPKCgiZ3BydEdldEdsb2JhbDJSZWcgQ2FsbGVkLlxuIikpOwoKICAgIC8qIEdldCBQaHkgUmVnaXN0ZXIuICovCiAgICBpZihod1JlYWRHbG9iYWwyUmVnKGRldiwoR1RfVTgpcmVnQWRkciwmdTE2RGF0YSkgIT0gR1RfT0spCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX0ZBSUw7CiAgICB9CgogICAgKmRhdGEgPSB1MTZEYXRhOwoKICAgIHJldHVybiBHVF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBncHJ0U2V0R2xvYmFsMlJlZwoqCiogREVTQ1JJUFRJT046CiogICAgICAgVGhpcyByb3V0aW5lIHdyaXRlcyBTd2l0Y2ggR2xvYmFsMiBSZWdpc3RlcnMuCioKKiBJTlBVVFM6CiogICAgICAgcmVnQWRkciAtIFRoZSByZWdpc3RlcidzIGFkZHJlc3MuCioKKiBPVVRQVVRTOgoqICAgICAgIGRhdGEgICAgLSBUaGUgcmVhZCByZWdpc3RlcidzIGRhdGEuCioKKiBSRVRVUk5TOgoqICAgICAgIEdUX09LICAgICAgICAgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICBHVF9GQUlMICAgICAgICAgLSBvbiBlcnJvcgoqCiogQ09NTUVOVFM6CiogICAgICAgTm9uZS4KKgoqIEdhbFRpczoKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3BydFNldEdsb2JhbDJSZWcKKAogICAgSU4gIEdUX1FEX0RFViAgICAgICAgKmRldiwKICAgIElOICBHVF9VMzIgICAgICAgICAgICByZWdBZGRyLAogICAgSU4gIEdUX1UxNiAgICAgICAgICAgIGRhdGEKKQp7CiAgICBEQkdfSU5GTygoImdwcnRTZXRHbG9iYWwyUmVnIENhbGxlZC5cbiIpKTsKCiAgICAvKiBHZXQgdGhlIFNjaGVkdWxpbmcgYml0LiAgICAgICAgICAgICAgKi8KICAgIGlmKGh3V3JpdGVHbG9iYWwyUmVnKGRldiwoR1RfVTgpcmVnQWRkcixkYXRhKSAhPSBHVF9PSykKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgICAgICByZXR1cm4gR1RfRkFJTDsKICAgIH0KCiAgICByZXR1cm4gR1RfT0s7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBncHJ0R2V0R2xvYmFsM1JlZwoqCiogREVTQ1JJUFRJT046CiogICAgICAgVGhpcyByb3V0aW5lIHJlYWRzIFN3aXRjaCBHbG9iYWwgMyBSZWdpc3RlcnMuCioKKiBJTlBVVFM6CiogICAgICAgcmVnQWRkciAtIFRoZSByZWdpc3RlcidzIGFkZHJlc3MuCioKKiBPVVRQVVRTOgoqICAgICAgIGRhdGEgICAgLSBUaGUgcmVhZCByZWdpc3RlcidzIGRhdGEuCioKKiBSRVRVUk5TOgoqICAgICAgIEdUX09LICAgICAgICAgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICBHVF9GQUlMICAgICAgICAgLSBvbiBlcnJvcgoqCiogQ09NTUVOVFM6CiogICAgICAgTm9uZS4KKgoqIEdhbFRpczoKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3BydEdldEdsb2JhbDNSZWcKKAogICAgSU4gIEdUX1FEX0RFViAgICAqZGV2LAogICAgSU4gIEdUX1UzMiAgICAgICAgIHJlZ0FkZHIsCiAgICBPVVQgR1RfVTE2ICAgICAgICAgKmRhdGEKKQp7CiAgICBHVF9VMTYgICAgICAgICAgdTE2RGF0YTsgICAgICAgICAgIC8qIFRoZSByZWdpc3RlcidzIHJlYWQgZGF0YS4gICAgKi8KCiAgICBEQkdfSU5GTygoImdwcnRHZXRHbG9iYWwzUmVnIENhbGxlZC5cbiIpKTsKCiAgICAvKiBHZXQgUGh5IFJlZ2lzdGVyLiAqLwogICAgaWYoaHdSZWFkR2xvYmFsM1JlZyhkZXYsKEdUX1U4KXJlZ0FkZHIsJnUxNkRhdGEpICE9IEdUX09LKQogICAgewogICAgICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAgICAgIHJldHVybiBHVF9GQUlMOwogICAgfQoKICAgICpkYXRhID0gdTE2RGF0YTsKCiAgICByZXR1cm4gR1RfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3BydFNldEdsb2JhbDNSZWcKKgoqIERFU0NSSVBUSU9OOgoqICAgICAgIFRoaXMgcm91dGluZSB3cml0ZXMgU3dpdGNoIEdsb2JhbDMgUmVnaXN0ZXJzLgoqCiogSU5QVVRTOgoqICAgICAgIHJlZ0FkZHIgLSBUaGUgcmVnaXN0ZXIncyBhZGRyZXNzLgoqCiogT1VUUFVUUzoKKiAgICAgICBkYXRhICAgIC0gVGhlIHJlYWQgcmVnaXN0ZXIncyBkYXRhLgoqCiogUkVUVVJOUzoKKiAgICAgICBHVF9PSyAgICAgICAgICAgLSBvbiBzdWNjZXNzCiogICAgICAgR1RfRkFJTCAgICAgICAgIC0gb24gZXJyb3IKKgoqIENPTU1FTlRTOgoqICAgICAgIE5vbmUuCioKKiBHYWxUaXM6CioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdwcnRTZXRHbG9iYWwzUmVnCigKICAgIElOICBHVF9RRF9ERVYgICAgICAgICpkZXYsCiAgICBJTiAgR1RfVTMyICAgICAgICAgICAgcmVnQWRkciwKICAgIElOICBHVF9VMTYgICAgICAgICAgICBkYXRhCikKewogICAgREJHX0lORk8oKCJncHJ0U2V0R2xvYmFsM1JlZyBDYWxsZWQuXG4iKSk7CgogICAgLyogR2V0IHRoZSBTY2hlZHVsaW5nIGJpdC4gICAgICAgICAgICAgICovCiAgICBpZihod1dyaXRlR2xvYmFsM1JlZyhkZXYsKEdUX1U4KXJlZ0FkZHIsZGF0YSkgIT0gR1RfT0spCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX0ZBSUw7CiAgICB9CgogICAgcmV0dXJuIEdUX09LOwp9CgovKiBOZXcgZnVuY3Rpb25zIGluIDg4RTYzMjAgb3IgbGF0ZXIgKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBncHJ0U2V0UXVldWVDdHJsCioKKiBERVNDUklQVElPTjoKKiAgICAgICAgU2V0IHBvcnQgcXVldWUgY29udHJvbCBkYXRhIHRvIHRoZSBQb3J0IFF1ZXVlIENvbnRyb2wgcmVnaXN0ZXIuCiogICAgICAgIFRoZSByZWdpc3RlcnMgb2YgUG9ydCBRdWV1ZSBjb250cm9sIGFyZS4KKiAgICAgICAgIEhhcmQgUXVldWUgTGltaXRzIHJlZ2lzdGVyIHNwYWNlCiogICAgICAgICBSZXNlcnZlZCBmb3IgZnV0dXJlIEhhcmQgUXVldWUgTGltaXRzIHVzZQoqCiogSU5QVVRTOgoqICAgICAgICBwb3J0ICAtIGxvZ2ljYWwgcG9ydCBudW1iZXIKKiAgICAgICAgcG9pbnQgLSBQb2ludGVyIHRvIHRoZSBQb3J0IFF1ZXVlIENvbnRyb2wgcmVnaXN0ZXIuCiogICAgICAgIGRhdGEgIC0gUG9ydCBRdWV1ZSBDb250cm9sIGRhdGEgd3JpdHRlbiB0byB0aGUgcmVnaXN0ZXIKKiAgICAgICAgICAgICAgICBwb2ludGVkIHRvIGJ5IHRoZSBwb2ludCBhYm92ZS4KKgoqIE9VVFBVVFM6CiogICAgICAgIE5vbmUuCioKKiBSRVRVUk5TOgoqICAgICAgICBHVF9PSyAgICAgIC0gb24gc3VjY2VzcwoqICAgICAgICBHVF9GQUlMICAgIC0gb24gZXJyb3IKKiAgICAgICAgR1RfQkFEX1BBUkFNIC0gaWYgaW5wdXQgcGFyYW1ldGVycyBhcmUgYmV5b25kIHJhbmdlLgoqICAgICAgICBHVF9OT1RfU1VQUE9SVEVEIC0gaWYgY3VycmVudCBkZXZpY2UgZG9lcyBub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCioKKiBDT01NRU5UUzoKKiAgICAgICAgTm9uZQoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBncHJ0U2V0UXVldWVDdHJsCigKICAgIElOICBHVF9RRF9ERVYgICAgICAgICpkZXYsCiAgICBJTiAgR1RfTFBPUlQgICAgICAgICBwb3J0LAogICAgSU4gIEdUX1UzMiAgICAgICAgICAgcG9pbnQsCiAgICBJTiAgR1RfVTggICAgICAgICAgICBkYXRhCikKewogICAgR1RfU1RBVFVTICAgIHJldFZhbDsgICAgICAgICAvKiBGdW5jdGlvbnMgcmV0dXJuIHZhbHVlLiAgICAgICovCiAgICBJTiAgR1RfVTE2ICAgICAgICAgICAgdG1wRGF0YTsKICAgIEdUX1U4ICAgICAgICAgICBod1BvcnQ7ICAgICAgICAgLyogdGhlIHBoeXNpY2FsIHBvcnQgbnVtYmVyICAgICAqLwoKICAgIGlmICghSVNfSU5fREVWX0dST1VQKGRldixERVZfUVVFVUVfQ09OVFJPTCkpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CiAgICAvKiB0cmFuc2xhdGUgTFBPUlQgdG8gaGFyZHdhcmUgcG9ydCAqLwogICAgaHdQb3J0ID0gR1RfTFBPUlRfMl9QT1JUKHBvcnQpOwoKICAgIGlmIChod1BvcnQgPCAoZGV2LT5tYXhQb3J0cyAtIDIpKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfTk9UX1NVUFBPUlRFRFxuIikpOwogICAgICAgIHJldHVybiBHVF9CQURfUEFSQU07CiAgICB9CgogICAgaWYgKHBvaW50ID4gMHg4MCkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX0JBRF9QQVJBTVxuIikpOwogICAgICAgIHJldHVybiBHVF9CQURfUEFSQU07CiAgICB9CgogICAgaWYgKGRhdGEgJjB4ZmZmZmZmMDApCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9CQURfUEFSQU1cbiIpKTsKICAgICAgICByZXR1cm4gR1RfQkFEX1BBUkFNOwogICAgfQoKICAgIGd0U2VtVGFrZShkZXYsZGV2LT50YmxSZWdzU2VtLE9TX1dBSVRfRk9SRVZFUik7CgoKICAgIC8qIFdhaXQgdW50aWwgdGhlIFBvcnQgUXVldWUgQ29udHJvbCBpcyByZWFkeS4gKi8KI2lmZGVmIEdUX1JNR01UX0FDQ0VTUwogICAgewogICAgICBIV19ERVZfUkVHX0FDQ0VTUyByZWdBY2Nlc3M7CgogICAgICByZWdBY2Nlc3MuZW50cmllcyA9IDE7CgogICAgICByZWdBY2Nlc3MucndfcmVnX2xpc3RbMF0uY21kID0gSFdfUkVHX1dBSVRfVElMTF8wOwogICAgICByZWdBY2Nlc3MucndfcmVnX2xpc3RbMF0uYWRkciA9IENBTENfU01JX0RFVl9BRERSKGRldiwgMCwgUE9SVF9BQ0NFU1MpOwogICAgICByZWdBY2Nlc3MucndfcmVnX2xpc3RbMF0ucmVnID0gMHgxZDsKICAgICAgcmVnQWNjZXNzLnJ3X3JlZ19saXN0WzBdLmRhdGEgPSAxNTsKICAgICAgcmV0VmFsID0gaHdBY2Nlc3NNdWx0aVJlZ3MoZGV2LCAmcmVnQWNjZXNzKTsKICAgICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgICB7CiAgICAgICAgZ3RTZW1HaXZlKGRldixkZXYtPnZ0dVJlZ3NTZW0pOwogICAgICAgIHJldHVybiByZXRWYWw7CiAgICAgIH0KICAgIH0KI2Vsc2UKICAgICAgIHRtcERhdGEgPSAxOwogICAgd2hpbGUodG1wRGF0YSA9PSAxKQogICAgICAgewogICAgICAgIHJldFZhbCA9IGh3R2V0UG9ydFJlZ0ZpZWxkKGRldixod1BvcnQsIDB4MWQsMTUsMSwmdG1wRGF0YSk7CiAgICAgICAgICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgICAgICAgIHsKICAgICAgICAgICAgZ3RTZW1HaXZlKGRldixkZXYtPnRibFJlZ3NTZW0pOwogICAgICAgICAgICAgICByZXR1cm4gcmV0VmFsOwogICAgICAgICAgIH0KICAgIH0KI2VuZGlmCgogICAgdG1wRGF0YSA9ICAoR1RfVTE2KSgoMSA8PCAxNSkgfCAocG9pbnQgPDwgOCkgfCBkYXRhKTsKCiAgICByZXRWYWwgPSBod1dyaXRlUG9ydFJlZyhkZXYsaHdQb3J0LCAweDFkLCB0bXBEYXRhKTsKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgICAgIHsKICAgICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgICAgICAgICBndFNlbUdpdmUoZGV2LGRldi0+dGJsUmVnc1NlbSk7CiAgICAgICAgICAgcmV0dXJuIHJldFZhbDsKICAgIH0KCiAgICBndFNlbUdpdmUoZGV2LGRldi0+dGJsUmVnc1NlbSk7CgogICAgICAgcmV0dXJuIHJldFZhbDsKCn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdwcnRHZXRRdWV1ZUN0cmwKKgoqIERFU0NSSVBUSU9OOgoqICAgICAgICBHZXQgcG9ydCBxdWV1ZSBjb250cm9sIGRhdGEgZnJvbSB0aGUgUG9ydCBRdWV1ZSBDb250cm9sIHJlZ2lzdGVyLgoqICAgICAgICBUaGUgcmVnaXN0ZXJzIG9mIFBvcnQgUXVldWUgY29udHJvbCBhcmUuCiogICAgICAgICBIYXJkIFF1ZXVlIExpbWl0cyByZWdpc3RlciBzcGFjZQoqICAgICAgICAgUmVzZXJ2ZWQgZm9yIGZ1dHVyZSBIYXJkIFF1ZXVlIExpbWl0cyB1c2UKKgoqIElOUFVUUzoKKiAgICAgICAgcG9ydCAgLSBsb2dpY2FsIHBvcnQgbnVtYmVyCiogICAgICAgIHBvaW50IC0gUG9pbnRlciB0byB0aGUgUG9ydCBRdWV1ZSBDb250cm9sIHJlZ2lzdGVyLgoqCiogT1VUUFVUUzoKKiAgICAgICAgZGF0YSAgLSBQb3J0IFF1ZXVlIENvbnRyb2wgZGF0YSB3cml0dGVuIHRvIHRoZSByZWdpc3RlcgoqICAgICAgICAgICAgICAgIHBvaW50ZWQgdG8gYnkgdGhlIHBvaW50IGFib3ZlLgoqCiogUkVUVVJOUzoKKiAgICAgICAgR1RfT0sgICAgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICAgR1RfRkFJTCAgICAtIG9uIGVycm9yCiogICAgICAgIEdUX0JBRF9QQVJBTSAtIGlmIGlucHV0IHBhcmFtZXRlcnMgYXJlIGJleW9uZCByYW5nZS4KKiAgICAgICAgR1RfTk9UX1NVUFBPUlRFRCAtIGlmIGN1cnJlbnQgZGV2aWNlIGRvZXMgbm90IHN1cHBvcnQgdGhpcyBmZWF0dXJlLgoqCiogQ09NTUVOVFM6CiogICAgICAgIE5vbmUKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3BydEdldFF1ZXVlQ3RybAooCiAgICBJTiAgR1RfUURfREVWICAgICAgICAqZGV2LAogICAgSU4gIEdUX0xQT1JUICAgICAgICAgcG9ydCwKICAgIElOICBHVF9VMzIgICAgICAgICAgIHBvaW50LAogICAgT1VUIEdUX1U4ICAgICAgICAgICAgKmRhdGEKKQp7CiAgICBHVF9TVEFUVVMgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIE9VVCAgR1RfVTE2ICAgICAgICAgICAgdG1wRGF0YTsKICAgIEdUX1U4ICAgICAgICAgICBod1BvcnQ7ICAgICAgICAgLyogdGhlIHBoeXNpY2FsIHBvcnQgbnVtYmVyICAgICAqLwoKICAgIGlmICghSVNfSU5fREVWX0dST1VQKGRldixERVZfUVVFVUVfQ09OVFJPTCkpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CiAgICAvKiB0cmFuc2xhdGUgTFBPUlQgdG8gaGFyZHdhcmUgcG9ydCAqLwogICAgaHdQb3J0ID0gR1RfTFBPUlRfMl9QT1JUKHBvcnQpOwoKICAgIGlmIChod1BvcnQgPCAoZGV2LT5tYXhQb3J0cyAtIDIpKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfTk9UX1NVUFBPUlRFRFxuIikpOwogICAgICAgIHJldHVybiBHVF9CQURfUEFSQU07CiAgICB9CgogICAgaWYgKHBvaW50ID4gMHg4MCkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX0JBRF9QQVJBTVxuIikpOwogICAgICAgIHJldHVybiBHVF9CQURfUEFSQU07CiAgICB9CgogICAgZ3RTZW1UYWtlKGRldixkZXYtPnRibFJlZ3NTZW0sT1NfV0FJVF9GT1JFVkVSKTsKCiAgICAvKiBXYWl0IHVudGlsIHRoZSBQb3J0IFF1ZXVlIENvbnRyb2wgaXMgcmVhZHkuICovCgogICAgZG8gewogICAgICAgIHJldFZhbCA9IGh3R2V0UG9ydFJlZ0ZpZWxkKGRldixod1BvcnQsIDB4MWQsMTUsMSwmdG1wRGF0YSk7CiAgICAgICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgICAgICAgIHsKICAgICAgICAgICAgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICAgICAgICAgIGd0U2VtR2l2ZShkZXYsZGV2LT50YmxSZWdzU2VtKTsKICAgICAgICAgICAgICAgcmV0dXJuIHJldFZhbDsKICAgICAgICB9CiAgICB9IHdoaWxlICh0bXBEYXRhJjB4ODAwMCk7CgogICAgKmRhdGEgPSB0bXBEYXRhJjB4ZmY7CgogICAgZ3RTZW1HaXZlKGRldixkZXYtPnRibFJlZ3NTZW0pOwoKCiAgICByZXR1cm4gcmV0VmFsOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdwcnRHZXREZWJ1Z0NvdW50ZXIKKgoqIERFU0NSSVBUSU9OOgoqICAgICAgICBHZXQgUG9ydCBEZWJ1ZyBDb3VudGVyLCBiYWQgY291bnRlciBhbmQgZ29vZCBjb3VudGVyLgoqCiogSU5QVVRTOgoqICAgICAgICBwb3J0ICAtIGxvZ2ljYWwgcG9ydCBudW1iZXIKKgoqIE9VVFBVVFM6CiogICAgICAgIGJhZENvdW50ZXIgIC0gV2hlbiBDdHJNb2RlIGlzIGNsZWFyZWQgdG8gYSB6ZXJvIChHbG9iYWwgMSBvZmZzZXQgMHgxQykgdGhpcwoqICBjb3VudGVyIGluY3JlbWVudHMgZWFjaCB0aW1lIGEgZnJhbWUgZW50ZXJzIHRoaXMgcG9ydCB0aGF0IHdhcyBhbiBlcnJvciBvbiB0aGUKKiAgd2lyZS4gSXQgZG9lcyBub3QgbWF0dGVyIGlmIHRoZSBmcmFtZZJzIENSQyBpcyBmaXhlZCBieSBGb3JjZUdvb2RGQ1MgKFBvcnQKKiAgb2Zmc2V0IDB4MDgpIGJlaW5nIHNldCB0byBhIG9uZSwgdGhpcyBjb3VudGVyIHdpbGwgc3RpbGwgaW5jcmVtZW50LiBBIENSQyBlcnJvcgoqICBmcmFtZSBpcyBvbmUgdGhhdCBpcyA2NCBieXRlcyB0byBNYXhGcmFtZVNpemUgKEdsb2JhbCAxLCBvZmZzZXQgMHgwNCkgd2l0aCBhCiogIGJhZCBDUkMgKGluY2x1ZGluZyBhbGlnbm1lbnQgZXJyb3JzIGJ1dCBub3QgZHJpYmJsZXMpLiBGcmFnbWVudHMgYW5kCiogIHByb3Blcmx5IGZvcm1lZCBmcmFtZXMgYXJlIG5vdCBjb3VudGVkLiBUaGUgUnhCYWRGcmFtZXMgY291bnRlciBjb3VudHMKKiAgZnJhbWVzIHRoYXQgYXJlIGNvdW50ZWQgaW4gdGhlIE1JQiBjb3VudGVycyBhcyBJblVuZGVyc2l6ZSwgSW5PdmVyc2l6ZSwKKiAgSW5KYWJiZXIsIEluUnhFcnIgYW5kIEluRkNTRXJyLgoqICBXaGVuIEN0ck1vZGUgaXMgc2V0IHRvIGEgb25lIHRoaXMgY291bnRlciBpbmNyZW1lbnRzIGVhY2ggdGltZSBhIHRyYW5zbWl0CiogIGNvbGxpc2lvbiBvY2N1cnMgb24gdGhpcyBwb3J0LgoqICAgICAgICBnb29kQ291bnRlciAgLSBXaGVuIEN0ck1vZGUgaXMgY2xlYXJlZCB0byBhIHplcm8gKEdsb2JhbCAxIG9mZnNldCAweDFDKSB0aGlzCiogIGNvdW50ZXIgaW5jcmVtZW50cyBlYWNoIHRpbWUgYSBmcmFtZSBlbnRlcnMgdGhpcyBwb3J0IHRoYXQgd2FzIG5vdCBhbiBlcnJvcgoqICBmcmFtZSBvbiB0aGUgd2lyZS4gSXQgZG9lcyBub3QgbWF0dGVyIGlmIHRoZSBmcmFtZSB3YXMgZmlsdGVyZWQgb3IgZGlzY2FyZGVkLAoqICBvbmx5IHRoYXQgdGhlIGZyYW1lIHdhcyByZWNlaXZlZCBhcyBnb29kIG9uIHRoZSB3aXJlIChpLmUuLCBpdHMgd2lyZSBzaXplIGlzIGluIHRoZQoqICByYW5nZSBvZiA2NCBieXRlcyB0byBNYXhGcmFtZVNpemUgKEdsb2JhbCAxLCBvZmZzZXQgMHgwNCkgYW5kIGl0cyBDUkMgd2FzCiogIGdvb2QuIFRoZSBSeEdvb2RGcmFtZXMgY291bnRlciBjb3VudHMgZnJhbWVzIHRoYXQgYXJlIG5vdCBjb3VudGVkCiogIGFib3ZlIGFzIGxvbmcgYXMgdGhleSBhcmUgbm90IGJlaW5nIGNvdW50ZWQgaW4gdGhlIE1JQiBjb3VudGVycyBhcwoqICBJbkZyYWdtZW50cy4KKiAgV2hlbiBDdHJNb2RlIGlzIHNldCB0byBhIG9uZSB0aGlzIGNvdW50ZXIgaW5jcmVtZW50cyBlYWNoIHRpbWUgYSBmcmFtZSBpcwoqICB0cmFuc21pdHRlZCBvdXQgdGhpcyBwb3J0LgoqCiogUkVUVVJOUzoKKiAgICAgICAgR1RfT0sgICAgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICAgR1RfRkFJTCAgICAtIG9uIGVycm9yCiogICAgICAgIEdUX0JBRF9QQVJBTSAtIGlmIGlucHV0IHBhcmFtZXRlcnMgYXJlIGJleW9uZCByYW5nZS4KKiAgICAgICAgR1RfTk9UX1NVUFBPUlRFRCAtIGlmIGN1cnJlbnQgZGV2aWNlIGRvZXMgbm90IHN1cHBvcnQgdGhpcyBmZWF0dXJlLgoqCiogQ09NTUVOVFM6CiogICAgICAgIE5vbmUKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3BydEdldERlYnVnQ291bnRlcgooCiAgICBJTiAgR1RfUURfREVWICAgICAgICAqZGV2LAogICAgSU4gIEdUX0xQT1JUICAgICAgICAgcG9ydCwKICAgIE9VVCAgR1RfVTggICAgICAgICAgICAqYmFkQ291bnRlciwKICAgIE9VVCAgR1RfVTggICAgICAgICAgICAqZ29vZENvdW50ZXIKKQp7CiAgICBHVF9TVEFUVVMgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIE9VVCAgR1RfVTE2ICAgICAgICAgICAgdG1wRGF0YTsKICAgIEdUX1U4ICAgICAgICAgICBod1BvcnQ7ICAgICAgICAgLyogdGhlIHBoeXNpY2FsIHBvcnQgbnVtYmVyICAgICAqLwoKICAgIGlmICghSVNfSU5fREVWX0dST1VQKGRldixERVZfREVCVUdfQ09VTlRFUikpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CiAgICAvKiB0cmFuc2xhdGUgTFBPUlQgdG8gaGFyZHdhcmUgcG9ydCAqLwogICAgaHdQb3J0ID0gR1RfTFBPUlRfMl9QT1JUKHBvcnQpOwoKICAgIGlmIChod1BvcnQgPCAoZGV2LT5tYXhQb3J0cyAtIDIpKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfTk9UX1NVUFBPUlRFRFxuIikpOwogICAgICAgIHJldHVybiBHVF9CQURfUEFSQU07CiAgICB9CgogICAgcmV0VmFsID0gaHdSZWFkUG9ydFJlZyhkZXYsaHdQb3J0LCAweDFlLCAmdG1wRGF0YSk7CiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICB7CiAgICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAgICByZXR1cm4gcmV0VmFsOwogICAgfQoKICAgICpnb29kQ291bnRlciA9IHRtcERhdGEmMHhmZjsKICAgICpiYWRDb3VudGVyID0gKHRtcERhdGE+PjgpJjB4ZmY7CgogICAgcmV0dXJuIHJldFZhbDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3BydFNldEN1dFRocm91Z2gKKgoqIERFU0NSSVBUSU9OOgoqICAgICAgICBTZXQgcG9ydCBDdXQgVGhyb3VnaCBjb25maWd1cmF0aW9uLgoqCiogSU5QVVRTOgoqICAgICAgICBwb3J0ICAtIGxvZ2ljYWwgcG9ydCBudW1iZXIKKiAgICAgICAgY3V0VGhydSAtIEN1dCB0aHJvdWdoIGNvbmZpZ3VyYXRpb24uCiogICAgICAgICAgICAgICAgICAgIGVuYWJsZVNlbGVjdDsgICAgIFBvcnQgRW5hYmxlIFNlbGVjdC4KKiAgICAgICAgICAgICAgICAgICAgZW5hYmxlOyAgICAgICAgICAgQ3V0IFRocm91Z2ggZW5hYmxlLgoqICAgICAgICAgICAgICAgICAgICBjdXRUaHJ1UXVldWU7ICAgICBDdXQgVGhyb3VnaCBRdWV1ZXMuCioKKiBPVVRQVVRTOgoqICAgICAgICBOb25lLgoqCiogUkVUVVJOUzoKKiAgICAgICAgR1RfT0sgICAgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICAgR1RfRkFJTCAgICAtIG9uIGVycm9yCiogICAgICAgIEdUX0JBRF9QQVJBTSAtIGlmIGlucHV0IHBhcmFtZXRlcnMgYXJlIGJleW9uZCByYW5nZS4KKiAgICAgICAgR1RfTk9UX1NVUFBPUlRFRCAtIGlmIGN1cnJlbnQgZGV2aWNlIGRvZXMgbm90IHN1cHBvcnQgdGhpcyBmZWF0dXJlLgoqCiogQ09NTUVOVFM6CiogICAgICAgIE5vbmUKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3BydFNldEN1dFRocm91Z2gKKAogICAgSU4gIEdUX1FEX0RFViAgICAgICAgKmRldiwKICAgIElOICBHVF9MUE9SVCAgICAgICAgIHBvcnQsCiAgICBJTiAgR1RfQ1VUX1RIUk9VR0ggICAqY3V0VGhydQopCnsKICAgIEdUX1NUQVRVUyAgICByZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwogICAgT1VUICBHVF9VMTYgICAgICAgICAgICB0bXBEYXRhOwogICAgR1RfVTggICAgICAgICAgIGh3UG9ydDsgICAgICAgICAvKiB0aGUgcGh5c2ljYWwgcG9ydCBudW1iZXIgICAgICovCgogICAgaWYgKCFJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9DVVRfVEhST1VHSCkpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CiAgICAvKiB0cmFuc2xhdGUgTFBPUlQgdG8gaGFyZHdhcmUgcG9ydCAqLwogICAgaHdQb3J0ID0gR1RfTFBPUlRfMl9QT1JUKHBvcnQpOwoKICAgIGlmIChod1BvcnQgPCAoZGV2LT5tYXhQb3J0cyAtIDIpKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfTk9UX1NVUFBPUlRFRFxuIikpOwogICAgICAgIHJldHVybiBHVF9CQURfUEFSQU07CiAgICB9CgogICAgdG1wRGF0YSA9IChjdXRUaHJ1LT5lbmFibGVTZWxlY3Q8PDEyKXwoY3V0VGhydS0+ZW5hYmxlPDw4KXxjdXRUaHJ1LT5jdXRUaHJ1UXVldWU7CiAgICByZXRWYWwgPSBod1dyaXRlUG9ydFJlZyhkZXYsaHdQb3J0LCAweDFmLCB0bXBEYXRhKTsKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgIHsKICAgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICAgIHJldHVybiByZXRWYWw7CiAgICB9CgoKICAgIHJldHVybiByZXRWYWw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3BydEdldEN1dFRocm91Z2gKKgoqIERFU0NSSVBUSU9OOgoqICAgICAgICBHZXQgcG9ydCBDdXQgVGhyb3VnaCBjb25maWd1cmF0aW9uLgoqCiogSU5QVVRTOgoqICAgICAgICBwb3J0ICAtIGxvZ2ljYWwgcG9ydCBudW1iZXIKKgoqIE9VVFBVVFM6CiogICAgICAgIGN1dFRocnUgLSBDdXQgdGhyb3VnaCBjb25maWd1cmF0aW9uLgoqICAgICAgICAgICAgICAgICAgICBlbmFibGVTZWxlY3Q7ICAgICBQb3J0IEVuYWJsZSBTZWxlY3QuCiogICAgICAgICAgICAgICAgICAgIGVuYWJsZTsgICAgICAgICAgIEN1dCBUaHJvdWdoIGVuYWJsZS4KKiAgICAgICAgICAgICAgICAgICAgY3V0VGhydVF1ZXVlOyAgICAgQ3V0IFRocm91Z2ggUXVldWVzLgoqCiogUkVUVVJOUzoKKiAgICAgICAgR1RfT0sgICAgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICAgR1RfRkFJTCAgICAtIG9uIGVycm9yCiogICAgICAgIEdUX0JBRF9QQVJBTSAtIGlmIGlucHV0IHBhcmFtZXRlcnMgYXJlIGJleW9uZCByYW5nZS4KKiAgICAgICAgR1RfTk9UX1NVUFBPUlRFRCAtIGlmIGN1cnJlbnQgZGV2aWNlIGRvZXMgbm90IHN1cHBvcnQgdGhpcyBmZWF0dXJlLgoqCiogQ09NTUVOVFM6CiogICAgICAgIE5vbmUKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3BydEdldEN1dFRocm91Z2gKKAogICAgSU4gIEdUX1FEX0RFViAgICAgICAgKmRldiwKICAgIElOICBHVF9MUE9SVCAgICAgICAgIHBvcnQsCiAgICBPVVQgR1RfQ1VUX1RIUk9VR0ggICAqY3V0VGhydQopCnsKICAgIEdUX1NUQVRVUyAgICByZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwogICAgT1VUICBHVF9VMTYgICAgICAgICAgICB0bXBEYXRhOwogICAgR1RfVTggICAgICAgICAgIGh3UG9ydDsgICAgICAgICAvKiB0aGUgcGh5c2ljYWwgcG9ydCBudW1iZXIgICAgICovCgogICAgaWYgKCFJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9DVVRfVEhST1VHSCkpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CiAgICAvKiB0cmFuc2xhdGUgTFBPUlQgdG8gaGFyZHdhcmUgcG9ydCAqLwogICAgaHdQb3J0ID0gR1RfTFBPUlRfMl9QT1JUKHBvcnQpOwoKICAgIGlmIChod1BvcnQgPCAoZGV2LT5tYXhQb3J0cyAtIDIpKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfTk9UX1NVUFBPUlRFRFxuIikpOwogICAgICAgIHJldHVybiBHVF9CQURfUEFSQU07CiAgICB9CgogICAgcmV0VmFsID0gaHdSZWFkUG9ydFJlZyhkZXYsaHdQb3J0LCAweDFmLCAmdG1wRGF0YSk7CiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICB7CiAgICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAgICByZXR1cm4gcmV0VmFsOwogICAgfQoKICAgIGN1dFRocnUtPmVuYWJsZVNlbGVjdCA9ICh0bXBEYXRhPj4xMikmMHhmOwogICAgY3V0VGhydS0+ZW5hYmxlID0gKHRtcERhdGEmMHgxMDApPzE6MDsKICAgIGN1dFRocnUtPmN1dFRocnVRdWV1ZSA9dG1wRGF0YSYweGZmOwoKICAgIHJldHVybiByZXRWYWw7Cn0K