LyoKICogQ29weXJpZ2h0IChjKSAyMDA3IFN1biBNaWNyb3N5c3RlbXMsIEluYy4gIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBTdW4gZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgU3VuIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IFN1biBNaWNyb3N5c3RlbXMsIEluYy4sIDQxNTAgTmV0d29yayBDaXJjbGUsIFNhbnRhIENsYXJhLAogKiBDQSA5NTA1NCBVU0Egb3IgdmlzaXQgd3d3LnN1bi5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvcgogKiBoYXZlIGFueSBxdWVzdGlvbnMuCiAqLwoKI2luY2x1ZGUgImpuaS5oIgojaW5jbHVkZSAiam5pX3V0aWwuaCIKI2luY2x1ZGUgImpsb25nLmgiCiNpbmNsdWRlICJzdW5mb250aWRzLmgiCiNpbmNsdWRlICJzdW5fZm9udF9GcmVldHlwZUZvbnRTY2FsZXIuaCIKCiNpbmNsdWRlPHN0ZGxpYi5oPgojaW5jbHVkZSA8bWF0aC5oPgojaW5jbHVkZSAiZnQyYnVpbGQuaCIKI2luY2x1ZGUgRlRfRlJFRVRZUEVfSAojaW5jbHVkZSBGVF9HTFlQSF9ICiNpbmNsdWRlIEZUX0JCT1hfSAojaW5jbHVkZSBGVF9TSVpFU19ICiNpbmNsdWRlIEZUX09VVExJTkVfSAojaW5jbHVkZSBGVF9TWU5USEVTSVNfSAoKI2luY2x1ZGUgImZvbnRzY2FsZXIuaCIKCiNkZWZpbmUgIGZ0Rml4ZWQxICAoRlRfRml4ZWQpICgxIDw8IDE2KQojZGVmaW5lICBGbG9hdFRvRlRGaXhlZChmKSAoRlRfRml4ZWQpKChmKSAqIChmbG9hdCkoZnRGaXhlZDEpKQojZGVmaW5lICBGVEZpeGVkVG9GbG9hdCh4KSAoKHgpIC8gKGZsb2F0KShmdEZpeGVkMSkpCiNkZWZpbmUgIEZUMjZEb3Q2VG9GbG9hdCh4KSAgKCh4KSAvICgoZmxvYXQpICgxPDw2KSkpCiNkZWZpbmUgIFJPVU5EKHgpICgoaW50KSAoeCswLjUpKQoKdHlwZWRlZiBzdHJ1Y3QgewogICAgLyogSW1wb3J0YW50IG5vdGU6CiAgICAgICAgIEpOSSBmb3JiaWRzIHNoYXJpbmcgc2FtZSBlbnYgYmV0d2VlbiBkaWZmZXJlbnQgdGhyZWFkcy4KICAgICAgICAgV2UgYXJlIHNhZmUsIGJlY2F1c2UgcG9pbnRlciBpcyBvdmVyd3JpdHRlbiBldmVyeSB0aW1lIHdlIGdldCBpbnRvCiAgICAgICAgIEpOSSBjYWxsIChzZWUgc2V0dXBGVENvbnRleHQpLgoKICAgICAgICAgUG9pbnRlciBpcyB1c2VkIGJ5IGZvbnQgZGF0YSByZWFkaW5nIGNhbGxiYWNrcwogICAgICAgICBzdWNoIGFzIFJlYWRUVEZvbnRGaWxlRnVuYy4KCiAgICAgICAgIE5COiBXZSBtYXkgY29uc2lkZXIgc3dpdGNoaW5nIHRvIEpOSV9HZXRFbnYuICovCiAgICBKTklFbnYqIGVudjsKICAgIEZUX0xpYnJhcnkgbGlicmFyeTsKICAgIEZUX0ZhY2UgZmFjZTsKICAgIGpvYmplY3QgZm9udDJEOwogICAgam9iamVjdCBkaXJlY3RCdWZmZXI7CgogICAgdW5zaWduZWQgY2hhciogZm9udERhdGE7CiAgICB1bnNpZ25lZCBmb250RGF0YU9mZnNldDsKICAgIHVuc2lnbmVkIGZvbnREYXRhTGVuZ3RoOwogICAgdW5zaWduZWQgZmlsZVNpemU7CiAgICBUVExheW91dFRhYmxlQ2FjaGUqIGxheW91dFRhYmxlczsKfSBGVFNjYWxlckluZm87Cgp0eXBlZGVmIHN0cnVjdCBGVFNjYWxlckNvbnRleHQgewogICAgRlRfTWF0cml4ICB0cmFuc2Zvcm07ICAgICAvKiBnbHlwaCB0cmFuc2Zvcm0sIGluY2x1ZGluZyBkZXZpY2UgdHJhbnNmb3JtICovCiAgICBqYm9vbGVhbiAgIHVzZVNiaXRzOyAgICAgIC8qIHNiaXQgdXNhZ2UgZW5hYmxlZD8gKi8KICAgIGppbnQgICAgICAgYWFUeXBlOyAgICAgICAgLyogYW50aWFsaWFzaW5nIG1vZGUgKG9mZi9vbi9ncmV5L2xjZCkgKi8KICAgIGppbnQgICAgICAgZm1UeXBlOyAgICAgICAgLyogZnJhY3Rpb25hbCBtZXRyaWNzIC0gb24vb2ZmICovCiAgICBqYm9vbGVhbiAgIGRvQm9sZDsgICAgICAgIC8qIHBlcmZvcm0gYWxnb3JpdGhtaWMgYm9sZGluZz8gKi8KICAgIGpib29sZWFuICAgZG9JdGFsaXplOyAgICAgLyogcGVyZm9ybSBhbGdvcml0aG1pYyBpdGFsaWNpemluZz8gKi8KICAgIGludCAgICAgICAgcmVuZGVyRmxhZ3M7ICAgLyogY29uZmlndXJhdGlvbiBzcGVjaWZpYyB0byBwYXJ0aWN1bGFyIGVuZ2luZSAqLwogICAgaW50ICAgICAgICBwYXRoVHlwZTsKICAgIGludCAgICAgICAgcHRzejsgICAgICAgICAgLyogc2l6ZSBpbiBwb2ludHMgKi8KfSBGVFNjYWxlckNvbnRleHQ7CgojaWZkZWYgREVCVUcKLyogVGhlc2UgYXJlIHJlZmVyZW5jZWQgaW4gdGhlIGZyZWV0eXBlIHNvdXJjZXMgaWYgREVCVUcgbWFjcm8gaXMgZGVmaW5lZC4KICAgVG8gc2ltcGxpZnkgd29yayB3aXRoIGRlYnVnaW5nIHZlcnNpb24gb2YgZnJlZXR5cGUgd2UgZGVmaW5lCiAgIHRoZW0gaGVyZS4gKi8KaW50IHpfdmVyYm9zZTsKdm9pZCB6X2Vycm9yKGNoYXIgKnMpIHt9CiNlbmRpZgoKLyoqKioqKioqKioqKioqKiogRXJyb3IgaGFuZGxpbmcgdXRpbGl0aWVzICoqKioqKioqKioqKioqKioqLwoKc3RhdGljIGptZXRob2RJRCBpbnZhbGlkYXRlU2NhbGVyTUlEOwoKSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTApKYXZhX3N1bl9mb250X0ZyZWV0eXBlRm9udFNjYWxlcl9pbml0SURzKAogICAgICAgIEpOSUVudiAqZW52LCBqb2JqZWN0IHNjYWxlciwgamNsYXNzIEZGU0NsYXNzKSB7CiAgICBpbnZhbGlkYXRlU2NhbGVyTUlEID0KICAgICAgICAoKmVudiktPkdldE1ldGhvZElEKGVudiwgRkZTQ2xhc3MsICJpbnZhbGlkYXRlU2NhbGVyIiwgIigpViIpOwp9CgpzdGF0aWMgdm9pZCBmcmVlTmF0aXZlUmVzb3VyY2VzKEpOSUVudiAqZW52LCBGVFNjYWxlckluZm8qIHNjYWxlckluZm8pIHsKICAgIGlmIChzY2FsZXJJbmZvID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwoKICAgIEZUX0RvbmVfRmFjZShzY2FsZXJJbmZvLT5mYWNlKTsKICAgIEZUX0RvbmVfRnJlZVR5cGUoc2NhbGVySW5mby0+bGlicmFyeSk7CgogICAgaWYgKHNjYWxlckluZm8tPmRpcmVjdEJ1ZmZlciAhPSBOVUxMKSB7CiAgICAgICAgKCplbnYpLT5EZWxldGVHbG9iYWxSZWYoZW52LCBzY2FsZXJJbmZvLT5kaXJlY3RCdWZmZXIpOwogICAgfQoKICAgIGlmIChzY2FsZXJJbmZvLT5mb250RGF0YSAhPSBOVUxMKSB7CiAgICAgICAgZnJlZShzY2FsZXJJbmZvLT5mb250RGF0YSk7CiAgICB9CgogICAgZnJlZShzY2FsZXJJbmZvKTsKfQoKLyogaW52YWxpZGF0ZXMgc3RhdGUgb2YgamF2YSBzY2FsZXIgb2JqZWN0ICovCnN0YXRpYyB2b2lkIGludmFsaWRhdGVKYXZhU2NhbGVyKEpOSUVudiAqZW52LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqb2JqZWN0IHNjYWxlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRlRTY2FsZXJJbmZvKiBzY2FsZXJJbmZvKSB7CiAgICBmcmVlTmF0aXZlUmVzb3VyY2VzKGVudiwgc2NhbGVySW5mbyk7CiAgICAoKmVudiktPkNhbGxWb2lkTWV0aG9kKGVudiwgc2NhbGVyLCBpbnZhbGlkYXRlU2NhbGVyTUlEKTsKfQoKLyoqKioqKioqKioqKioqKioqKiogSS9PIGhhbmRsZXJzICoqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiNkZWZpbmUgRklMRURBVEFDQUNIRVNJWkUgMTAyNAoKLyogTkI6IGlzIGl0IGV2ZXIgY2FsbGVkPyAqLwpzdGF0aWMgdm9pZCBDbG9zZVRURm9udEZpbGVGdW5jKEZUX1N0cmVhbSBzdHJlYW0pIHsKICAgIEZUU2NhbGVySW5mbyAqc2NhbGVySW5mbyA9IChGVFNjYWxlckluZm8gKikgc3RyZWFtLT5wYXRobmFtZS5wb2ludGVyOwogICAgSk5JRW52KiBlbnYgPSBzY2FsZXJJbmZvLT5lbnY7CiAgICBqY2xhc3MgdG1wQ2xhc3MgPSAoKmVudiktPkZpbmRDbGFzcyhlbnYsICJzdW4vZm9udC9UcnVlVHlwZUZvbnQiKTsKICAgIGpmaWVsZElEIHBsYXROYW1lRmllbGQgPQogICAgICAgICAoKmVudiktPkdldEZpZWxkSUQoZW52LCB0bXBDbGFzcywgInBsYXROYW1lIiwgIkxqYXZhL2xhbmcvU3RyaW5nOyIpOwogICAganN0cmluZyBwbGF0TmFtZSA9ICgqZW52KS0+R2V0T2JqZWN0RmllbGQoZW52LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NhbGVySW5mby0+Zm9udDJELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGxhdE5hbWVGaWVsZCk7CiAgICBjb25zdCBjaGFyICpuYW1lID0gSk5VX0dldFN0cmluZ1BsYXRmb3JtQ2hhcnMoZW52LCBwbGF0TmFtZSwgTlVMTCk7CiAgICBKTlVfUmVsZWFzZVN0cmluZ1BsYXRmb3JtQ2hhcnMoZW52LCBwbGF0TmFtZSwgbmFtZSk7Cn0KCnN0YXRpYyB1bnNpZ25lZCBsb25nIFJlYWRUVEZvbnRGaWxlRnVuYyhGVF9TdHJlYW0gc3RyZWFtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgbG9uZyBvZmZzZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBjaGFyKiBkZXN0QnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgbG9uZyBudW1CeXRlcykKewogICAgRlRTY2FsZXJJbmZvICpzY2FsZXJJbmZvID0gKEZUU2NhbGVySW5mbyAqKSBzdHJlYW0tPnBhdGhuYW1lLnBvaW50ZXI7CiAgICBKTklFbnYqIGVudiA9IHNjYWxlckluZm8tPmVudjsKICAgIGpvYmplY3QgYkJ1ZmZlcjsKICAgIGludCBicmVhZCA9IDA7CgogICAgaWYgKG51bUJ5dGVzID09IDApIHJldHVybiAwOwoKICAgIC8qIExhcmdlIHJlYWRzIHdpbGwgYnlwYXNzIHRoZSBjYWNoZSBhbmQgZGF0YSBjb3B5aW5nICovCiAgICBpZiAobnVtQnl0ZXMgPiBGSUxFREFUQUNBQ0hFU0laRSkgewogICAgICAgIGJCdWZmZXIgPSAoKmVudiktPk5ld0RpcmVjdEJ5dGVCdWZmZXIoZW52LCBkZXN0QnVmZmVyLCBudW1CeXRlcyk7CiAgICAgICAgaWYgKGJCdWZmZXIgIT0gTlVMTCkgewogICAgICAgICAgICAvKiBMb29wIHVudGlsIHRoZSByZWFkIHN1Y2NlZWRzIChvciBFT0YpLgogICAgICAgICAgICAgKiBUaGlzIHNob3VsZCBpbXByb3ZlIHJvYnVzdG5lc3MgaW4gdGhlIGV2ZW50IG9mIGEgcHJvYmxlbSBpbgogICAgICAgICAgICAgKiB0aGUgSS9PIHN5c3RlbS4gSWYgd2UgZmluZCB0aGF0IHdlIGV2ZXIgZW5kIHVwIHNwaW5uaW5nIGhlcmUKICAgICAgICAgICAgICogd2UgYXJlIGdvaW5nIHRvIGhhdmUgdG8gZG8gc29tZSBzZXJpb3VzIHdvcmsgdG8gcmVjb3Zlci4KICAgICAgICAgICAgICogSnVzdCByZXR1cm5pbmcgd2l0aG91dCByZWFkaW5nIHRoZSBkYXRhIHdpbGwgY2F1c2UgYSBjcmFzaC4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIHdoaWxlIChicmVhZCA9PSAwKSB7CiAgICAgICAgICAgICAgICBicmVhZCA9ICgqZW52KS0+Q2FsbEludE1ldGhvZChlbnYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2FsZXJJbmZvLT5mb250MkQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdW5Gb250SURzLnR0UmVhZEJsb2NrTUlELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYkJ1ZmZlciwgb2Zmc2V0LCBudW1CeXRlcyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGJyZWFkOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8qIFdlIHByb2JhYmx5IGhpdCBidWcgYnVnIDQ4NDUzNzEuIEZvciByZWFzb25zIHRoYXQKICAgICAgICAgICAgICogYXJlIGN1cnJlbnRseSB1bmNsZWFyLCB0aGUgY2FsbCBzdGFja3MgYWZ0ZXIgdGhlIGluaXRpYWwKICAgICAgICAgICAgICogY3JlYXRlU2NhbGVyIGNhbGwgdGhhdCByZWFkIGxhcmdlIGFtb3VudHMgb2YgZGF0YSBzZWVtIHRvCiAgICAgICAgICAgICAqIGJlIE9LIGFuZCBjYW4gY3JlYXRlIHRoZSBieXRlIGJ1ZmZlciBhYm92ZSwgYnV0IHRoaXMgY29kZQogICAgICAgICAgICAgKiBpcyBoZXJlIGp1c3QgaW4gY2FzZS4KICAgICAgICAgICAgICogNDg0NTM3MSBpcyBmaXhlZCBub3cgc28gSSBkb24ndCBleHBlY3QgdGhpcyBjb2RlIHBhdGggdG8KICAgICAgICAgICAgICogZXZlciBnZXQgY2FsbGVkIGJ1dCBpdHMgaGFybWxlc3MgdG8gbGVhdmUgaXQgaGVyZSBvbiB0aGUKICAgICAgICAgICAgICogc21hbGwgY2hhbmNlIGl0cyBuZWVkZWQuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBqYnl0ZUFycmF5IGJ5dGVBcnJheSA9IChqYnl0ZUFycmF5KQogICAgICAgICAgICAoKmVudiktPkNhbGxPYmplY3RNZXRob2QoZW52LCBzY2FsZXJJbmZvLT5mb250MkQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdW5Gb250SURzLnR0UmVhZEJ5dGVzTUlELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0LCBudW1CeXRlcyk7CiAgICAgICAgICAgICgqZW52KS0+R2V0Qnl0ZUFycmF5UmVnaW9uKGVudiwgYnl0ZUFycmF5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCBudW1CeXRlcywgKGpieXRlKilkZXN0QnVmZmVyKTsKICAgICAgICAgICAgcmV0dXJuIG51bUJ5dGVzOwogICAgICAgIH0KICAgIH0gLyogRG8gd2UgaGF2ZSBhIGNhY2hlIGhpdD8gKi8KICAgICAgZWxzZSBpZiAoc2NhbGVySW5mby0+Zm9udERhdGFPZmZzZXQgPD0gb2Zmc2V0ICYmCiAgICAgICAgc2NhbGVySW5mby0+Zm9udERhdGFPZmZzZXQgKyBzY2FsZXJJbmZvLT5mb250RGF0YUxlbmd0aCA+PQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQgKyBudW1CeXRlcykKICAgIHsKICAgICAgICB1bnNpZ25lZCBjYWNoZU9mZnNldCA9IG9mZnNldCAtIHNjYWxlckluZm8tPmZvbnREYXRhT2Zmc2V0OwoKICAgICAgICBtZW1jcHkoZGVzdEJ1ZmZlciwgc2NhbGVySW5mby0+Zm9udERhdGErKHNpemVfdCljYWNoZU9mZnNldCwgbnVtQnl0ZXMpOwogICAgICAgIHJldHVybiBudW1CeXRlczsKICAgIH0gZWxzZSB7CiAgICAgICAgLyogTXVzdCBmaWxsIHRoZSBjYWNoZSAqLwogICAgICAgIHNjYWxlckluZm8tPmZvbnREYXRhT2Zmc2V0ID0gb2Zmc2V0OwogICAgICAgIHNjYWxlckluZm8tPmZvbnREYXRhTGVuZ3RoID0KICAgICAgICAgICAgICAgICAob2Zmc2V0ICsgRklMRURBVEFDQUNIRVNJWkUgPiBzY2FsZXJJbmZvLT5maWxlU2l6ZSkgPwogICAgICAgICAgICAgICAgIHNjYWxlckluZm8tPmZpbGVTaXplIC0gb2Zmc2V0IDogRklMRURBVEFDQUNIRVNJWkU7CiAgICAgICAgYkJ1ZmZlciA9IHNjYWxlckluZm8tPmRpcmVjdEJ1ZmZlcjsKICAgICAgICAvKiBMb29wIHVudGlsIGFsbCB0aGUgcmVhZCBzdWNjZWVkcyAob3IgRU9GKS4KICAgICAgICAgKiBUaGlzIHNob3VsZCBpbXByb3ZlIHJvYnVzdG5lc3MgaW4gdGhlIGV2ZW50IG9mIGEgcHJvYmxlbSBpbgogICAgICAgICAqIHRoZSBJL08gc3lzdGVtLiBJZiB3ZSBmaW5kIHRoYXQgd2UgZXZlciBlbmQgdXAgc3Bpbm5pbmcgaGVyZQogICAgICAgICAqIHdlIGFyZSBnb2luZyB0byBoYXZlIHRvIGRvIHNvbWUgc2VyaW91cyB3b3JrIHRvIHJlY292ZXIuCiAgICAgICAgICogSnVzdCByZXR1cm5pbmcgd2l0aG91dCByZWFkaW5nIHRoZSBkYXRhIHdpbGwgY2F1c2UgYSBjcmFzaC4KICAgICAgICAgKi8KICAgICAgICB3aGlsZSAoYnJlYWQgPT0gMCkgewogICAgICAgICAgICBicmVhZCA9ICgqZW52KS0+Q2FsbEludE1ldGhvZChlbnYsIHNjYWxlckluZm8tPmZvbnQyRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VuRm9udElEcy50dFJlYWRCbG9ja01JRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYkJ1ZmZlciwgb2Zmc2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2FsZXJJbmZvLT5mb250RGF0YUxlbmd0aCk7CiAgICAgICAgfQoKICAgICAgICBtZW1jcHkoZGVzdEJ1ZmZlciwgc2NhbGVySW5mby0+Zm9udERhdGEsIG51bUJ5dGVzKTsKICAgICAgICByZXR1cm4gbnVtQnl0ZXM7CiAgICB9Cn0KCi8qCiAqIENsYXNzOiAgICAgc3VuX2ZvbnRfRnJlZXR5cGVGb250U2NhbGVyCiAqIE1ldGhvZDogICAgaW5pdE5hdGl2ZVNjYWxlcgogKiBTaWduYXR1cmU6IChMc3VuL2ZvbnQvRm9udDJEO0lJWkkpSgogKi8KSk5JRVhQT1JUIGpsb25nIEpOSUNBTEwKSmF2YV9zdW5fZm9udF9GcmVldHlwZUZvbnRTY2FsZXJfaW5pdE5hdGl2ZVNjYWxlcigKICAgICAgICBKTklFbnYgKmVudiwgam9iamVjdCBzY2FsZXIsIGpvYmplY3QgZm9udDJELCBqaW50IHR5cGUsCiAgICAgICAgamludCBpbmRleEluQ29sbGVjdGlvbiwgamJvb2xlYW4gc3VwcG9ydHNDSkssIGppbnQgZmlsZXNpemUpIHsKICAgIEZUU2NhbGVySW5mbyogc2NhbGVySW5mbyA9IE5VTEw7CiAgICBGVF9TdHJlYW0gZnRzdHJlYW07CiAgICBGVF9PcGVuX0FyZ3MgZnRfb3Blbl9hcmdzOwogICAgaW50IGVycm9yOwogICAgam9iamVjdCBiQnVmZmVyOwogICAgc2NhbGVySW5mbyA9IChGVFNjYWxlckluZm8qKSBjYWxsb2MoMSwgc2l6ZW9mKEZUU2NhbGVySW5mbykpOwoKICAgIGlmIChzY2FsZXJJbmZvID09IE5VTEwpCiAgICAgICAgcmV0dXJuIDA7CgogICAgc2NhbGVySW5mby0+ZW52ID0gZW52OwogICAgc2NhbGVySW5mby0+Zm9udDJEID0gZm9udDJEOwogICAgc2NhbGVySW5mby0+Zm9udERhdGFPZmZzZXQgPSAwOwogICAgc2NhbGVySW5mby0+Zm9udERhdGFMZW5ndGggPSAwOwogICAgc2NhbGVySW5mby0+ZmlsZVNpemUgPSBmaWxlc2l6ZTsKCiAgICAvKgogICAgICAgV2UgY2FuIGNvbnNpZGVyIHNoYXJpbmcgZnJlZXR5cGUgbGlicmFyeSBiZXR3ZWVuIGRpZmZlcmVudAogICAgICAgc2NhbGVycy4gSG93ZXZlciwgRnJlZXR5cGUgZG9jcyBzdWdnZXN0IHRvIHVzZSBkaWZmZXJlbnQgbGlicmFyaWVzCiAgICAgICBmb3IgZGlmZmVyZW50IHRocmVhZHMuIEFsc28sIG91ciBhcmNoaXRlY3R1cmUgaW1wbGllcyB0aGF0IHNpbmdsZQogICAgICAgRm9udFNjYWxlciBvYmplY3QgaXMgc2hhcmVkIGZvciBmb3IgZGlmZmVyZW50IHNpemVzL3RyYW5zZm9ybXMvc3R5bGVzCiAgICAgICBvZiB0aGUgc2FtZSBmb250LgoKICAgICAgIE9uIG90aGVyIGhhbmQgdGhlc2UgbWV0aG9kcyBjYW4gbm90IGJlIGNvbmN1cnJlbnRseSBleGVjdXRlZAogICAgICAgYmVjYXVzZWQgdGhleSBhcmUgInN5bmNocm9uaXplZCIgaW4gamF2YS4KICAgICovCiAgICBlcnJvciA9IEZUX0luaXRfRnJlZVR5cGUoJnNjYWxlckluZm8tPmxpYnJhcnkpOwogICAgaWYgKGVycm9yKSB7CiAgICAgICAgZnJlZShzY2FsZXJJbmZvKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiNkZWZpbmUgVFlQRTFfRlJPTV9KQVZBICAgICAgICAyCgogICAgZXJyb3IgPSAxOyAvKiB0cmlnZ2VycyBtZW1vcnkgZnJlZWluZyB1bmxlc3Mgd2UgY2xlYXIgaXQgKi8KICAgIGlmICh0eXBlID09IFRZUEUxX0ZST01fSkFWQSkgeyAvKiBUWVBFMSAqLwogICAgICAgIHNjYWxlckluZm8tPmZvbnREYXRhID0gKHVuc2lnbmVkIGNoYXIqKSBtYWxsb2MoZmlsZXNpemUpOwogICAgICAgIHNjYWxlckluZm8tPmRpcmVjdEJ1ZmZlciA9IE5VTEw7CiAgICAgICAgc2NhbGVySW5mby0+bGF5b3V0VGFibGVzID0gTlVMTDsKICAgICAgICBzY2FsZXJJbmZvLT5mb250RGF0YUxlbmd0aCA9IGZpbGVzaXplOwoKICAgICAgICBpZiAoc2NhbGVySW5mby0+Zm9udERhdGEgIT0gTlVMTCkgewogICAgICAgICAgICBiQnVmZmVyID0gKCplbnYpLT5OZXdEaXJlY3RCeXRlQnVmZmVyKGVudiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjYWxlckluZm8tPmZvbnREYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NhbGVySW5mby0+Zm9udERhdGFMZW5ndGgpOwogICAgICAgICAgICBpZiAoYkJ1ZmZlciAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAoKmVudiktPkNhbGxPYmplY3RNZXRob2QoZW52LCBmb250MkQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VuRm9udElEcy5yZWFkRmlsZU1JRCwgYkJ1ZmZlcik7CgogICAgICAgICAgICAgICAgZXJyb3IgPSBGVF9OZXdfTWVtb3J5X0ZhY2Uoc2NhbGVySW5mby0+bGlicmFyeSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2FsZXJJbmZvLT5mb250RGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2FsZXJJbmZvLT5mb250RGF0YUxlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmRleEluQ29sbGVjdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmc2NhbGVySW5mby0+ZmFjZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9IGVsc2UgeyAvKiBUcnVldHlwZSAqLwogICAgICAgIHNjYWxlckluZm8tPmZvbnREYXRhID0gKHVuc2lnbmVkIGNoYXIqKSBtYWxsb2MoRklMRURBVEFDQUNIRVNJWkUpOwogICAgICAgIGZ0c3RyZWFtID0gKEZUX1N0cmVhbSkgY2FsbG9jKDEsIHNpemVvZihGVF9TdHJlYW1SZWMpKTsKCiAgICAgICAgaWYgKGZ0c3RyZWFtICE9IE5VTEwgJiYgc2NhbGVySW5mby0+Zm9udERhdGEgIT0gTlVMTCkgewogICAgICAgICAgICBzY2FsZXJJbmZvLT5kaXJlY3RCdWZmZXIgPSAoKmVudiktPk5ld0RpcmVjdEJ5dGVCdWZmZXIoZW52LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NhbGVySW5mby0+Zm9udERhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSUxFREFUQUNBQ0hFU0laRSk7CiAgICAgICAgICAgIGlmIChzY2FsZXJJbmZvLT5kaXJlY3RCdWZmZXIgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgc2NhbGVySW5mby0+ZGlyZWN0QnVmZmVyID0gKCplbnYpLT5OZXdHbG9iYWxSZWYoZW52LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjYWxlckluZm8tPmRpcmVjdEJ1ZmZlcik7CiAgICAgICAgICAgICAgICBmdHN0cmVhbS0+YmFzZSA9IE5VTEw7CiAgICAgICAgICAgICAgICBmdHN0cmVhbS0+c2l6ZSA9IGZpbGVzaXplOwogICAgICAgICAgICAgICAgZnRzdHJlYW0tPnBvcyA9IDA7CiAgICAgICAgICAgICAgICBmdHN0cmVhbS0+cmVhZCA9IChGVF9TdHJlYW1fSW9GdW5jKSBSZWFkVFRGb250RmlsZUZ1bmM7CiAgICAgICAgICAgICAgICBmdHN0cmVhbS0+Y2xvc2UgPSAoRlRfU3RyZWFtX0Nsb3NlRnVuYykgQ2xvc2VUVEZvbnRGaWxlRnVuYzsKICAgICAgICAgICAgICAgIGZ0c3RyZWFtLT5wYXRobmFtZS5wb2ludGVyID0gKHZvaWQgKikgc2NhbGVySW5mbzsKCiAgICAgICAgICAgICAgICBtZW1zZXQoJmZ0X29wZW5fYXJncywgMCwgc2l6ZW9mKEZUX09wZW5fQXJncykpOwogICAgICAgICAgICAgICAgZnRfb3Blbl9hcmdzLmZsYWdzID0gRlRfT1BFTl9TVFJFQU07CiAgICAgICAgICAgICAgICBmdF9vcGVuX2FyZ3Muc3RyZWFtID0gZnRzdHJlYW07CgogICAgICAgICAgICAgICAgZXJyb3IgPSBGVF9PcGVuX0ZhY2Uoc2NhbGVySW5mby0+bGlicmFyeSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZmdF9vcGVuX2FyZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmRleEluQ29sbGVjdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZzY2FsZXJJbmZvLT5mYWNlKTsKICAgICAgICAgICB9CiAgICAgICAgICAgaWYgKGVycm9yIHx8IHNjYWxlckluZm8tPmRpcmVjdEJ1ZmZlciA9PSBOVUxMKSB7CiAgICAgICAgICAgICAgIGZyZWUoZnRzdHJlYW0pOwogICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgaWYgKGVycm9yKSB7CiAgICAgICAgRlRfRG9uZV9GcmVlVHlwZShzY2FsZXJJbmZvLT5saWJyYXJ5KTsKICAgICAgICBpZiAoc2NhbGVySW5mby0+ZGlyZWN0QnVmZmVyICE9IE5VTEwpIHsKICAgICAgICAgICAgKCplbnYpLT5EZWxldGVHbG9iYWxSZWYoZW52LCBzY2FsZXJJbmZvLT5kaXJlY3RCdWZmZXIpOwogICAgICAgIH0KICAgICAgICBpZiAoc2NhbGVySW5mby0+Zm9udERhdGEgIT0gTlVMTCkKICAgICAgICAgICAgZnJlZShzY2FsZXJJbmZvLT5mb250RGF0YSk7CiAgICAgICAgZnJlZShzY2FsZXJJbmZvKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICByZXR1cm4gcHRyX3RvX2psb25nKHNjYWxlckluZm8pOwp9CgpzdGF0aWMgZG91YmxlIGV1Y2xpZGlhbkRpc3RhbmNlKGRvdWJsZSBhLCBkb3VibGUgYikgewogICAgaWYgKGEgPCAwKSBhPS1hOwogICAgaWYgKGIgPCAwKSBiPS1iOwoKICAgIGlmIChhID09IDApIHJldHVybiBiOwogICAgaWYgKGIgPT0gMCkgcmV0dXJuIGE7CgogICAgcmV0dXJuIHNxcnQoYSphK2IqYik7Cn0KCkpOSUVYUE9SVCBqbG9uZyBKTklDQUxMCkphdmFfc3VuX2ZvbnRfRnJlZXR5cGVGb250U2NhbGVyX2NyZWF0ZVNjYWxlckNvbnRleHROYXRpdmUoCiAgICAgICAgSk5JRW52ICplbnYsIGpvYmplY3Qgc2NhbGVyLCBqbG9uZyBwU2NhbGVyLCBqZG91YmxlQXJyYXkgbWF0cml4LAogICAgICAgIGpib29sZWFuIHR0Rm9udCwgamludCBhYSwgamludCBmbSwgamZsb2F0IGJvbGRuZXNzLCBqZmxvYXQgaXRhbGljKSB7CiAgICBkb3VibGUgZG1hdFs0XSwgcHRzejsKICAgIEZUU2NhbGVyQ29udGV4dCAqY29udGV4dCA9CiAgICAgICAgICAgIChGVFNjYWxlckNvbnRleHQqKSBjYWxsb2MoMSwgc2l6ZW9mKEZUU2NhbGVyQ29udGV4dCkpOwogICAgRlRTY2FsZXJJbmZvICpzY2FsZXJJbmZvID0KICAgICAgICAgICAgIChGVFNjYWxlckluZm8qKSBqbG9uZ190b19wdHIocFNjYWxlcik7CgogICAgaWYgKGNvbnRleHQgPT0gTlVMTCkgewogICAgICAgIGludmFsaWRhdGVKYXZhU2NhbGVyKGVudiwgc2NhbGVyLCBOVUxMKTsKICAgICAgICByZXR1cm4gKGpsb25nKSAwOwogICAgfQogICAgKCplbnYpLT5HZXREb3VibGVBcnJheVJlZ2lvbihlbnYsIG1hdHJpeCwgMCwgNCwgZG1hdCk7CiAgICBwdHN6ID0gZXVjbGlkaWFuRGlzdGFuY2UoZG1hdFsyXSwgZG1hdFszXSk7IC8vaS5lLiB5LXNpemUKICAgIGlmIChwdHN6IDwgMS4wKSB7CiAgICAgICAgLy90ZXh0IGNhbiBub3QgYmUgc21hbGxlciB0aGFuIDEgcG9pbnQKICAgICAgICBwdHN6ID0gMS4wOwogICAgfQogICAgY29udGV4dC0+cHRzeiA9ICgoKGludCkgcHRzeikgPDwgNik7CiAgICBjb250ZXh0LT50cmFuc2Zvcm0ueHggPSAgRmxvYXRUb0ZURml4ZWQoKGZsb2F0KWRtYXRbMF0vcHRzeik7CiAgICBjb250ZXh0LT50cmFuc2Zvcm0ueXggPSAtRmxvYXRUb0ZURml4ZWQoKGZsb2F0KWRtYXRbMV0vcHRzeik7CiAgICBjb250ZXh0LT50cmFuc2Zvcm0ueHkgPSAtRmxvYXRUb0ZURml4ZWQoKGZsb2F0KWRtYXRbMl0vcHRzeik7CiAgICBjb250ZXh0LT50cmFuc2Zvcm0ueXkgPSAgRmxvYXRUb0ZURml4ZWQoKGZsb2F0KWRtYXRbM10vcHRzeik7CiAgICBjb250ZXh0LT5hYVR5cGUgPSBhYTsKICAgIGNvbnRleHQtPmZtVHlwZSA9IGZtOwoKICAgIC8qIElmIHVzaW5nIGFsZ29yaXRobWljIHN0eWxpbmcsIHRoZSBiYXNlIHZhbHVlcyBhcmUKICAgICAqIGJvbGRuZXNzID0gMS4wLCBpdGFsaWMgPSAwLjAuCiAgICAgKi8KICAgIGNvbnRleHQtPmRvQm9sZCA9IChib2xkbmVzcyAhPSAxLjApOwogICAgY29udGV4dC0+ZG9JdGFsaXplID0gKGl0YWxpYyAhPSAwKTsKCiAgICByZXR1cm4gcHRyX3RvX2psb25nKGNvbnRleHQpOwp9CgpzdGF0aWMgaW50IHNldHVwRlRDb250ZXh0KEpOSUVudiAqZW52LAogICAgICAgICAgICAgICAgICAgICAgICAgIGpvYmplY3QgZm9udDJELAogICAgICAgICAgICAgICAgICAgICAgICAgIEZUU2NhbGVySW5mbyAqc2NhbGVySW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICBGVFNjYWxlckNvbnRleHQgKmNvbnRleHQpIHsKICAgIGludCBlcnJDb2RlID0gMDsKCiAgICBzY2FsZXJJbmZvLT5lbnYgPSBlbnY7CiAgICBzY2FsZXJJbmZvLT5mb250MkQgPSBmb250MkQ7CgogICAgRlRfU2V0X1RyYW5zZm9ybShzY2FsZXJJbmZvLT5mYWNlLCAmY29udGV4dC0+dHJhbnNmb3JtLCBOVUxMKTsKCiAgICBlcnJDb2RlID0gRlRfU2V0X0NoYXJfU2l6ZShzY2FsZXJJbmZvLT5mYWNlLCAwLCBjb250ZXh0LT5wdHN6LCA3MiwgNzIpOwoKICAgIGlmIChlcnJDb2RlID09IDApIHsKICAgICAgICBlcnJDb2RlID0gRlRfQWN0aXZhdGVfU2l6ZShzY2FsZXJJbmZvLT5mYWNlLT5zaXplKTsKICAgIH0KCiAgICByZXR1cm4gZXJyQ29kZTsKfQoKLyogZnRzeW50aC5jIHVzZXMgKDB4MTAwMDAsIDB4MDYwMDAsIDB4MCwgMHgxMDAwMCkgbWF0cml4IHRvIGdldCBvYmxpcXVlCiAgIG91dGxpbmUuICBUaGVyZWZvcmUgeCBjb29yZGluYXRlIHdpbGwgY2hhbmdlIGJ5IDB4MDYwMDAqeS4KICAgTm90ZSB0aGF0IHkgY29vcmRpbmF0ZSBkb2VzIG5vdCBjaGFuZ2UuICovCiNkZWZpbmUgT0JMSVFVRV9NT0RJRklFUih5KSAgKGNvbnRleHQtPmRvSXRhbGl6ZSA/ICgoeSkqNi8xNikgOiAwKQoKLyoKICogQ2xhc3M6ICAgICBzdW5fZm9udF9GcmVldHlwZUZvbnRTY2FsZXIKICogTWV0aG9kOiAgICBnZXRGb250TWV0cmljc05hdGl2ZQogKiBTaWduYXR1cmU6IChMc3VuL2ZvbnQvRm9udDJEO0opTHN1bi9mb250L1N0cmlrZU1ldHJpY3M7CiAqLwpKTklFWFBPUlQgam9iamVjdCBKTklDQUxMCkphdmFfc3VuX2ZvbnRfRnJlZXR5cGVGb250U2NhbGVyX2dldEZvbnRNZXRyaWNzTmF0aXZlKAogICAgICAgIEpOSUVudiAqZW52LCBqb2JqZWN0IHNjYWxlciwgam9iamVjdCBmb250MkQsCiAgICAgICAgamxvbmcgcFNjYWxlckNvbnRleHQsIGpsb25nIHBTY2FsZXIpIHsKCiAgICBqb2JqZWN0IG1ldHJpY3M7CiAgICBqZmxvYXQgYXgsIGF5LCBkeCwgZHksIGJ4LCBieSwgbHgsIGx5LCBteCwgbXk7CiAgICBqZmxvYXQgZjAgPSAwLjA7CiAgICBGVF9Qb3MgYm1vZGlmaWVyID0gMDsKICAgIEZUU2NhbGVyQ29udGV4dCAqY29udGV4dCA9CiAgICAgICAgKEZUU2NhbGVyQ29udGV4dCopIGpsb25nX3RvX3B0cihwU2NhbGVyQ29udGV4dCk7CiAgICBGVFNjYWxlckluZm8gKnNjYWxlckluZm8gPQogICAgICAgICAgICAgKEZUU2NhbGVySW5mbyopIGpsb25nX3RvX3B0cihwU2NhbGVyKTsKCiAgICBpbnQgZXJyQ29kZTsKCiAgICBpZiAoaXNOdWxsU2NhbGVyQ29udGV4dChjb250ZXh0KSB8fCBzY2FsZXJJbmZvID09IE5VTEwpIHsKICAgICAgICByZXR1cm4gKCplbnYpLT5OZXdPYmplY3QoZW52LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdW5Gb250SURzLnN0cmlrZU1ldHJpY3NDbGFzcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VuRm9udElEcy5zdHJpa2VNZXRyaWNzQ3RyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmMCwgZjAsIGYwLCBmMCwgZjAsIGYwLCBmMCwgZjAsIGYwLCBmMCk7CiAgICB9CgogICAgZXJyQ29kZSA9IHNldHVwRlRDb250ZXh0KGVudiwgZm9udDJELCBzY2FsZXJJbmZvLCBjb250ZXh0KTsKCiAgICBpZiAoZXJyQ29kZSkgewogICAgICAgIG1ldHJpY3MgPSAoKmVudiktPk5ld09iamVjdChlbnYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1bkZvbnRJRHMuc3RyaWtlTWV0cmljc0NsYXNzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdW5Gb250SURzLnN0cmlrZU1ldHJpY3NDdHIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYwLCBmMCwgZjAsIGYwLCBmMCwgZjAsIGYwLCBmMCwgZjAsIGYwKTsKICAgICAgICBpbnZhbGlkYXRlSmF2YVNjYWxlcihlbnYsIHNjYWxlciwgc2NhbGVySW5mbyk7CiAgICAgICAgcmV0dXJuIG1ldHJpY3M7CiAgICB9CgogICAgLyogVGhpcyBpcyB1Z2x5IGFuZCBoYXMgdG8gYmUgcmV3b3JrZWQuCiAgICAgICBGcmVldHlwZSBwcm92aWRlIG1lYW5zIHRvIGFkZCBzdHlsZSB0byBnbHlwaCBidXQKICAgICAgIGl0IHNlZW1zIHRoZXJlIGlzIG5vIHdheSB0byBhZGp1c3QgbWV0cmljcyBhY2NvcmRpbmdseS4KCiAgICAgICBTbywgd2UgaGF2ZSB0byBkbyBhZHVzdCB0aGVtIGV4cGxpY2l0bHkgYW5kIHN0YXkgY29uc2lzdGVudCB3aXRoIHdoYXQKICAgICAgIGZyZWV0eXBlIGRvZXMgdG8gb3V0bGluZXMuICovCgogICAgLyogRm9yIGJvbGRpbmcgZ2x5cGhzIGFyZSBub3QganVzdCB3aWRlbmVkLiBIZWlnaHQgaXMgYWxzbyBjaGFuZ2VkCiAgICAgICAoc2VlIGZ0c3ludGguYykuCgogICAgICAgVE9ETzogSW4gdmVydGljYWwgZGlyZWN0aW9uIHdlIGNvdWxkIGRvIGJldHRlciBqb2IgYW5kIGFkanVzdCBtZXRyaWNzCiAgICAgICBwcm9wb3J0aW9uYWxseSB0byBnbHlvaCBzaGFwZS4gKi8KICAgIGlmIChjb250ZXh0LT5kb0JvbGQpIHsKICAgICAgICBibW9kaWZpZXIgPSBGVF9NdWxGaXgoCiAgICAgICAgICAgICAgICAgICAgICAgc2NhbGVySW5mby0+ZmFjZS0+dW5pdHNfcGVyX0VNLAogICAgICAgICAgICAgICAgICAgICAgIHNjYWxlckluZm8tPmZhY2UtPnNpemUtPm1ldHJpY3MueV9zY2FsZSkvMjQ7CiAgICB9CgoKICAgIC8qKioqIE5vdGU6IG9ubHkgc29tZSBtZXRyaWNzIGFyZSBhZmZlY3RlZCBieSBzdHlsaW5nICoqKi8KCiAgICAvKiBhc2NlbnQgKi8KICAgIGF4ID0gMDsKICAgIGF5ID0gLShqZmxvYXQpIEZUMjZEb3Q2VG9GbG9hdCgKICAgICAgICAgICAgICAgICAgICAgICBzY2FsZXJJbmZvLT5mYWNlLT5zaXplLT5tZXRyaWNzLmFzY2VuZGVyICsKICAgICAgICAgICAgICAgICAgICAgICBibW9kaWZpZXIvMik7CiAgICAvKiBkZXNjZW50ICovCiAgICBkeCA9IDA7CiAgICBkeSA9IC0oamZsb2F0KSBGVDI2RG90NlRvRmxvYXQoCiAgICAgICAgICAgICAgICAgICAgICAgc2NhbGVySW5mby0+ZmFjZS0+c2l6ZS0+bWV0cmljcy5kZXNjZW5kZXIgKwogICAgICAgICAgICAgICAgICAgICAgIGJtb2RpZmllci8yKTsKICAgIC8qIGJhc2VsaW5lICovCiAgICBieCA9IGJ5ID0gMDsKCiAgICAvKiBsZWFkaW5nICovCiAgICBseCA9IDA7CiAgICBseSA9IChqZmxvYXQpIEZUMjZEb3Q2VG9GbG9hdCgKICAgICAgICAgICAgICAgICAgICAgIHNjYWxlckluZm8tPmZhY2UtPnNpemUtPm1ldHJpY3MuaGVpZ2h0ICsKICAgICAgICAgICAgICAgICAgICAgIGJtb2RpZmllcikgKyBheSAtIGR5OwogICAgLyogbWF4IGFkdmFuY2UgKi8KICAgIG14ID0gKGpmbG9hdCkgRlQyNkRvdDZUb0Zsb2F0KAogICAgICAgICAgICAgICAgICAgICBzY2FsZXJJbmZvLT5mYWNlLT5zaXplLT5tZXRyaWNzLm1heF9hZHZhbmNlICsKICAgICAgICAgICAgICAgICAgICAgMipibW9kaWZpZXIgKwogICAgICAgICAgICAgICAgICAgICBPQkxJUVVFX01PRElGSUVSKHNjYWxlckluZm8tPmZhY2UtPnNpemUtPm1ldHJpY3MuaGVpZ2h0KSk7CiAgICBteSA9IDA7CgogICAgbWV0cmljcyA9ICgqZW52KS0+TmV3T2JqZWN0KGVudiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdW5Gb250SURzLnN0cmlrZU1ldHJpY3NDbGFzcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdW5Gb250SURzLnN0cmlrZU1ldHJpY3NDdHIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXgsIGF5LCBkeCwgZHksIGJ4LCBieSwgbHgsIGx5LCBteCwgbXkpOwoKICAgIHJldHVybiBtZXRyaWNzOwp9CgovKgogKiBDbGFzczogICAgIHN1bl9mb250X0ZyZWV0eXBlRm9udFNjYWxlcgogKiBNZXRob2Q6ICAgIGdldEdseXBoQWR2YW5jZU5hdGl2ZQogKiBTaWduYXR1cmU6IChMc3VuL2ZvbnQvRm9udDJEO0pJKUYKICovCkpOSUVYUE9SVCBqZmxvYXQgSk5JQ0FMTApKYXZhX3N1bl9mb250X0ZyZWV0eXBlRm9udFNjYWxlcl9nZXRHbHlwaEFkdmFuY2VOYXRpdmUoCiAgICAgICAgSk5JRW52ICplbnYsIGpvYmplY3Qgc2NhbGVyLCBqb2JqZWN0IGZvbnQyRCwKICAgICAgICBqbG9uZyBwU2NhbGVyQ29udGV4dCwgamxvbmcgcFNjYWxlciwgamludCBnbHlwaENvZGUpIHsKCiAgIC8qIFRoaXMgbWV0aG9kIGlzIHJhcmVseSB1c2VkIGJlY2F1c2UgcmVxdWVzdHMgZm9yIG1ldHJpY3MgYXJlIHVzdWFsbHkKICAgICAgY291cGxlZCB3aXRoIHJlcXVlc3QgZm9yIGJpdG1hcCBhbmQgdG8gbGFyZ2UgZXh0ZW5kIHdvcmsgY2FuIGJlIHJldXNlZAogICAgICAodG8gZmluZCBvdXQgbWV0cmljcyB3ZSBuZWVkIHRvIGhpbnQgZ2x5cGgpLgogICAgICBTbywgd2UgdHlwaWNhbGx5IGdvIHRocm91Z2ggZ2V0R2x5cGhJbWFnZSBjb2RlIHBhdGguCgogICAgICBGb3IgaW5pdGlhbCBmcmVldHlwZSBpbXBsZW1lbnRhdGlvbiB3ZSBkZWxlZ2F0ZQogICAgICBhbGwgd29yayB0byBnZXRHbHlwaEltYWdlIGJ1dCBkcm9wIHJlc3VsdCBpbWFnZS4KICAgICAgVGhpcyBpcyB3YXN0ZSBvZiB3b3JrIHJlbGF0ZWQgdG8gc2NhbiBjb252ZXJzaW9uIGFuZCBjb252ZXJzaW9uIGZyb20KICAgICAgZnJlZXR5cGUgZm9ybWF0IHRvIG91ciBmb3JtYXQgYnV0IGZvciBub3cgdGhpcyBzZWVtcyB0byBiZSBvay4KCiAgICAgIE5COiBpbnZlc3RpZ2F0ZSBwZXJmb3JtYW5jZSBiZW5lZml0cyBvZiByZWZhY3RvcmluZyBjb2RlCiAgICAgIHRvIGF2b2lkIHVubmVjZXNhcnkgd29yayB3aXRoIGJpdG1hcHMuICovCgogICAgR2x5cGhJbmZvICppbmZvOwogICAgamZsb2F0IGFkdmFuY2U7CiAgICBqbG9uZyBpbWFnZTsKCiAgICBpbWFnZSA9IEphdmFfc3VuX2ZvbnRfRnJlZXR5cGVGb250U2NhbGVyX2dldEdseXBoSW1hZ2VOYXRpdmUoCiAgICAgICAgICAgICAgICAgZW52LCBzY2FsZXIsIGZvbnQyRCwgcFNjYWxlckNvbnRleHQsIHBTY2FsZXIsIGdseXBoQ29kZSk7CiAgICBpbmZvID0gKEdseXBoSW5mbyopIGpsb25nX3RvX3B0cihpbWFnZSk7CgogICAgYWR2YW5jZSA9IGluZm8tPmFkdmFuY2VYOwoKICAgIGZyZWUoaW5mbyk7CgogICAgcmV0dXJuIGFkdmFuY2U7Cn0KCi8qCiAqIENsYXNzOiAgICAgc3VuX2ZvbnRfRnJlZXR5cGVGb250U2NhbGVyCiAqIE1ldGhvZDogICAgZ2V0R2x5cGhNZXRyaWNzTmF0aXZlCiAqIFNpZ25hdHVyZTogKExzdW4vZm9udC9Gb250MkQ7SklMamF2YS9hd3QvZ2VvbS9Qb2ludDJEL0Zsb2F0OylWCiAqLwpKTklFWFBPUlQgdm9pZCBKTklDQUxMCkphdmFfc3VuX2ZvbnRfRnJlZXR5cGVGb250U2NhbGVyX2dldEdseXBoTWV0cmljc05hdGl2ZSgKICAgICAgICBKTklFbnYgKmVudiwgam9iamVjdCBzY2FsZXIsIGpvYmplY3QgZm9udDJELCBqbG9uZyBwU2NhbGVyQ29udGV4dCwKICAgICAgICBqbG9uZyBwU2NhbGVyLCBqaW50IGdseXBoQ29kZSwgam9iamVjdCBtZXRyaWNzKSB7CgogICAgIC8qIEFzIGluaXRpYWwgaW1wbGVtZW50YXRpb24gd2UgZGVsZWdhdGUgYWxsIHdvcmsgdG8gZ2V0R2x5cGhJbWFnZQogICAgICAgIGJ1dCBkcm9wIHJlc3VsdCBpbWFnZS4gVGhpcyBpcyBjbGVhcmx5IHdhc3RlIG9mIHJlc29yY2VzLgoKICAgICAgICBUT0RPOiBpbnZlc3RpZ2F0ZSBwZXJmb3JtYW5jZSBiZW5lZml0cyBvZiByZWZhY3RvcmluZyBjb2RlCiAgICAgICAgICAgICAgYnkgYXZvaWRpbmcgYml0bWFwIGdlbmVyYXRpb24gYW5kIGNvbnZlcnNpb24gZnJvbSBGVAogICAgICAgICAgICAgIGJpdG1hcCBmb3JtYXQuICovCiAgICAgR2x5cGhJbmZvICppbmZvOwoKICAgICBqbG9uZyBpbWFnZSA9IEphdmFfc3VuX2ZvbnRfRnJlZXR5cGVGb250U2NhbGVyX2dldEdseXBoSW1hZ2VOYXRpdmUoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVudiwgc2NhbGVyLCBmb250MkQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBTY2FsZXJDb250ZXh0LCBwU2NhbGVyLCBnbHlwaENvZGUpOwogICAgIGluZm8gPSAoR2x5cGhJbmZvKikgamxvbmdfdG9fcHRyKGltYWdlKTsKCiAgICAgKCplbnYpLT5TZXRGbG9hdEZpZWxkKGVudiwgbWV0cmljcywgc3VuRm9udElEcy54RklELCBpbmZvLT5hZHZhbmNlWCk7CiAgICAgKCplbnYpLT5TZXRGbG9hdEZpZWxkKGVudiwgbWV0cmljcywgc3VuRm9udElEcy55RklELCBpbmZvLT5hZHZhbmNlWSk7CgogICAgIGZyZWUoaW5mbyk7Cn0KCgpzdGF0aWMgR2x5cGhJbmZvKiBnZXROdWxsR2x5cGhJbWFnZSgpIHsKICAgIEdseXBoSW5mbyAqZ2x5cGhJbmZvID0gIChHbHlwaEluZm8qKSBjYWxsb2MoMSwgc2l6ZW9mKEdseXBoSW5mbykpOwogICAgcmV0dXJuIGdseXBoSW5mbzsKfQoKc3RhdGljIHZvaWQgQ29weUJXMkdyZXk4KGNvbnN0IHZvaWQqIHNyY0ltYWdlLCBpbnQgc3JjUm93Qnl0ZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkKiBkc3RJbWFnZSwgaW50IGRzdFJvd0J5dGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgaW50IHdpZHRoLCBpbnQgaGVpZ2h0KSB7CiAgICBjb25zdCBVSW50OCogc3JjUm93ID0gKFVJbnQ4KilzcmNJbWFnZTsKICAgIFVJbnQ4KiBkc3RSb3cgPSAoVUludDgqKWRzdEltYWdlOwogICAgaW50IHdob2xlQnl0ZUNvdW50ID0gd2lkdGggPj4gMzsKICAgIGludCByZW1haW5pbmdCaXRzQ291bnQgPSB3aWR0aCAmIDc7CiAgICBpbnQgaSwgajsKCiAgICB3aGlsZSAoaGVpZ2h0LS0pIHsKICAgICAgICBjb25zdCBVSW50OCogc3JjOCA9IHNyY1JvdzsKICAgICAgICBVSW50OCogZHN0Qnl0ZSA9IGRzdFJvdzsKICAgICAgICB1bnNpZ25lZCBzcmNWYWx1ZTsKCiAgICAgICAgc3JjUm93ICs9IHNyY1Jvd0J5dGVzOwogICAgICAgIGRzdFJvdyArPSBkc3RSb3dCeXRlczsKCiAgICAgICAgZm9yIChpID0gMDsgaSA8IHdob2xlQnl0ZUNvdW50OyBpKyspIHsKICAgICAgICAgICAgc3JjVmFsdWUgPSAqc3JjOCsrOwogICAgICAgICAgICBmb3IgKGogPSAwOyBqIDwgODsgaisrKSB7CiAgICAgICAgICAgICAgICAqZHN0Qnl0ZSsrID0gKHNyY1ZhbHVlICYgMHg4MCkgPyAweEZGIDogMDsKICAgICAgICAgICAgICAgIHNyY1ZhbHVlIDw8PSAxOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmIChyZW1haW5pbmdCaXRzQ291bnQpIHsKICAgICAgICAgICAgc3JjVmFsdWUgPSAqc3JjODsKICAgICAgICAgICAgZm9yIChqID0gMDsgaiA8IHJlbWFpbmluZ0JpdHNDb3VudDsgaisrKSB7CiAgICAgICAgICAgICAgICAqZHN0Qnl0ZSsrID0gKHNyY1ZhbHVlICYgMHg4MCkgPyAweEZGIDogMDsKICAgICAgICAgICAgICAgIHNyY1ZhbHVlIDw8PSAxOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQp9CgojZGVmaW5lIEdyZXk0VG9BbHBoYTI1NSh2YWx1ZSkgKCgodmFsdWUpIDw8IDQpICsgKCh2YWx1ZSkgPj4gMykpCgpzdGF0aWMgdm9pZCBDb3B5R3JleTRUb0dyZXk4KGNvbnN0IHZvaWQqIHNyY0ltYWdlLCBpbnQgc3JjUm93Qnl0ZXMsCiAgICAgICAgICAgICAgICB2b2lkKiBkc3RJbWFnZSwgaW50IGRzdFJvd0J5dGVzLCBpbnQgd2lkdGgsIGludCBoZWlnaHQpIHsKICAgICBjb25zdCBVSW50OCogc3JjUm93ID0gKFVJbnQ4Kikgc3JjSW1hZ2U7CiAgICAgVUludDgqIGRzdFJvdyA9IChVSW50OCopIGRzdEltYWdlOwogICAgIGludCBpOwoKICAgICB3aGlsZSAoaGVpZ2h0LS0pIHsKICAgICAgICAgY29uc3QgVUludDgqIHNyYzggPSBzcmNSb3c7CiAgICAgICAgIFVJbnQ4KiBkc3RCeXRlID0gZHN0Um93OwogICAgICAgICB1bnNpZ25lZCBzcmNWYWx1ZTsKCiAgICAgICAgIHNyY1JvdyArPSBzcmNSb3dCeXRlczsKICAgICAgICAgZHN0Um93ICs9IGRzdFJvd0J5dGVzOwoKICAgICAgICAgZm9yIChpID0gMDsgaSA8IHdpZHRoOyBpKyspIHsKICAgICAgICAgICAgIHNyY1ZhbHVlID0gKnNyYzgrKzsKICAgICAgICAgICAgICpkc3RCeXRlKysgPSBHcmV5NFRvQWxwaGEyNTUoc3JjVmFsdWUgJiAweDBmKTsKICAgICAgICAgICAgICpkc3RCeXRlKysgPSBHcmV5NFRvQWxwaGEyNTUoc3JjVmFsdWUgPj4gNCk7CiAgICAgICAgIH0KICAgICB9Cn0KCi8qIFdlIG5lZWQgaXQgYmVjYXVzZSBGVCByb3dzIGFyZSBvZnRlbiBwYWRkZWQgdG8gNCBieXRlIGJvdW5kYXJpZXMKICAgIGFuZCBvdXIgaW50ZXJuYWwgZm9ybWF0IGlzIG5vdCBwYWRkZWQgKi8Kc3RhdGljIHZvaWQgQ29weUZUU3VicGl4ZWxUb1N1YnBpeGVsKGNvbnN0IHZvaWQqIHNyY0ltYWdlLCBpbnQgc3JjUm93Qnl0ZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkKiBkc3RJbWFnZSwgaW50IGRzdFJvd0J5dGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHdpZHRoLCBpbnQgaGVpZ2h0KSB7CiAgICB1bnNpZ25lZCBjaGFyICpzcmNSb3cgPSAodW5zaWduZWQgY2hhciAqKSBzcmNJbWFnZTsKICAgIHVuc2lnbmVkIGNoYXIgKmRzdFJvdyA9ICh1bnNpZ25lZCBjaGFyICopIGRzdEltYWdlOwoKICAgIHdoaWxlIChoZWlnaHQtLSkgewogICAgICAgIG1lbWNweShkc3RSb3csIHNyY1Jvdywgd2lkdGgpOwogICAgICAgIHNyY1JvdyArPSBzcmNSb3dCeXRlczsKICAgICAgICBkc3RSb3cgKz0gZHN0Um93Qnl0ZXM7CiAgICB9Cn0KCi8qIFdlIG5lZWQgaXQgYmVjYXVzZSBGVCByb3dzIGFyZSBvZnRlbiBwYWRkZWQgdG8gNCBieXRlIGJvdW5kYXJpZXMKICAgYW5kIG91ciBpbnRlcm5hbCBmb3JtYXQgaXMgbm90IHBhZGRlZCAqLwpzdGF0aWMgdm9pZCBDb3B5RlRTdWJwaXhlbFZUb1N1YnBpeGVsKGNvbnN0IHZvaWQqIHNyY0ltYWdlLCBpbnQgc3JjUm93Qnl0ZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCogZHN0SW1hZ2UsIGludCBkc3RSb3dCeXRlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgd2lkdGgsIGludCBoZWlnaHQpIHsKICAgIHVuc2lnbmVkIGNoYXIgKnNyY1JvdyA9ICh1bnNpZ25lZCBjaGFyICopIHNyY0ltYWdlLCAqc3JjQnl0ZTsKICAgIHVuc2lnbmVkIGNoYXIgKmRzdFJvdyA9ICh1bnNpZ25lZCBjaGFyICopIGRzdEltYWdlLCAqZHN0Qnl0ZTsKICAgIGludCBpOwoKICAgIHdoaWxlIChoZWlnaHQgPiAwKSB7CiAgICAgICAgc3JjQnl0ZSA9IHNyY1JvdzsKICAgICAgICBkc3RCeXRlID0gZHN0Um93OwogICAgICAgIGZvciAoaSA9IDA7IGkgPCB3aWR0aDsgaSsrKSB7CiAgICAgICAgICAgICpkc3RCeXRlKysgPSAqc3JjQnl0ZTsKICAgICAgICAgICAgKmRzdEJ5dGUrKyA9ICooc3JjQnl0ZSArIHNyY1Jvd0J5dGVzKTsKICAgICAgICAgICAgKmRzdEJ5dGUrKyA9ICooc3JjQnl0ZSArIDIqc3JjUm93Qnl0ZXMpOwogICAgICAgICAgICBzcmNCeXRlKys7CiAgICAgICAgfQogICAgICAgIHNyY1JvdyArPSAzKnNyY1Jvd0J5dGVzOwogICAgICAgIGRzdFJvdyArPSBkc3RSb3dCeXRlczsKICAgICAgICBoZWlnaHQgLT0gMzsKICAgIH0KfQoKCi8qCiAqIENsYXNzOiAgICAgc3VuX2ZvbnRfRnJlZXR5cGVGb250U2NhbGVyCiAqIE1ldGhvZDogICAgZ2V0R2x5cGhJbWFnZU5hdGl2ZQogKiBTaWduYXR1cmU6IChMc3VuL2ZvbnQvRm9udDJEO0pJKUoKICovCkpOSUVYUE9SVCBqbG9uZyBKTklDQUxMCkphdmFfc3VuX2ZvbnRfRnJlZXR5cGVGb250U2NhbGVyX2dldEdseXBoSW1hZ2VOYXRpdmUoCiAgICAgICAgSk5JRW52ICplbnYsIGpvYmplY3Qgc2NhbGVyLCBqb2JqZWN0IGZvbnQyRCwKICAgICAgICBqbG9uZyBwU2NhbGVyQ29udGV4dCwgamxvbmcgcFNjYWxlciwgamludCBnbHlwaENvZGUpIHsKCiAgICBpbnQgZXJyb3IsIGltYWdlU2l6ZTsKICAgIFVJbnQxNiB3aWR0aCwgaGVpZ2h0OwogICAgR2x5cGhJbmZvICpnbHlwaEluZm87CiAgICBpbnQgZ2x5cGhfaW5kZXg7CiAgICBpbnQgcmVuZGVyRmxhZ3MgPSBGVF9MT0FEX1JFTkRFUiwgdGFyZ2V0OwogICAgRlRfR2x5cGhTbG90IGZ0Z2x5cGg7CgogICAgRlRTY2FsZXJDb250ZXh0KiBjb250ZXh0ID0KICAgICAgICAoRlRTY2FsZXJDb250ZXh0KikgamxvbmdfdG9fcHRyKHBTY2FsZXJDb250ZXh0KTsKICAgIEZUU2NhbGVySW5mbyAqc2NhbGVySW5mbyA9CiAgICAgICAgICAgICAoRlRTY2FsZXJJbmZvKikgamxvbmdfdG9fcHRyKHBTY2FsZXIpOwoKICAgIGlmIChpc051bGxTY2FsZXJDb250ZXh0KGNvbnRleHQpIHx8IHNjYWxlckluZm8gPT0gTlVMTCkgewogICAgICAgIHJldHVybiBwdHJfdG9famxvbmcoZ2V0TnVsbEdseXBoSW1hZ2UoKSk7CiAgICB9CgogICAgZXJyb3IgPSBzZXR1cEZUQ29udGV4dChlbnYsIGZvbnQyRCwgc2NhbGVySW5mbywgY29udGV4dCk7CiAgICBpZiAoZXJyb3IpIHsKICAgICAgICBpbnZhbGlkYXRlSmF2YVNjYWxlcihlbnYsIHNjYWxlciwgc2NhbGVySW5mbyk7CiAgICAgICAgcmV0dXJuIHB0cl90b19qbG9uZyhnZXROdWxsR2x5cGhJbWFnZSgpKTsKICAgIH0KCiAgICAvKiBpZiBhbGdvcml0aG1pYyBzdHlsaW5nIGlzIHJlcXVpcmVkIHRoZW4gd2UgZG8gbm90IHJlcXVlc3QgYml0bWFwICovCiAgICBpZiAoY29udGV4dC0+ZG9Cb2xkIHx8IGNvbnRleHQtPmRvSXRhbGl6ZSkgewogICAgICAgIHJlbmRlckZsYWdzID0gIEZUX0xPQURfREVGQVVMVDsKICAgIH0KCiAgICAvKiBOQjogaW4gY2FzZSBvZiBub24gaWRlbnRpdHkgdHJhbnNmb3JtCiAgICAgd2UgbWlnaHQgYWxzbyBwcmVmZXIgdG8gZGlzYWJsZSB0cmFuc2Zvcm0gYmVmb3JlIGhpbnRpbmcsCiAgICAgYW5kIGFwcGx5IGl0IGV4cGxpY2l0bHkgYWZ0ZXIgaGludGluZyBpcyBwZXJmb3JtZWQuCiAgICAgT3Igd2UgY2FuIGRpc2FibGUgaGludGluZy4gKi8KCiAgICAvKiBzZWxlY3QgYXBwcm9wcmlhdGUgaGludGluZyBtb2RlICovCiAgICBpZiAoY29udGV4dC0+YWFUeXBlID09IFRFWFRfQUFfT0ZGKSB7CiAgICAgICAgdGFyZ2V0ID0gRlRfTE9BRF9UQVJHRVRfTU9OTzsKICAgIH0gZWxzZSBpZiAoY29udGV4dC0+YWFUeXBlID09IFRFWFRfQUFfT04pIHsKICAgICAgICB0YXJnZXQgPSBGVF9MT0FEX1RBUkdFVF9OT1JNQUw7CiAgICB9IGVsc2UgaWYgKGNvbnRleHQtPmFhVHlwZSA9PSBURVhUX0FBX0xDRF9IUkdCIHx8CiAgICAgICAgICAgICAgIGNvbnRleHQtPmFhVHlwZSA9PSBURVhUX0FBX0xDRF9IQkdSKSB7CiAgICAgICAgdGFyZ2V0ID0gRlRfTE9BRF9UQVJHRVRfTENEOwogICAgfSBlbHNlIHsKICAgICAgICB0YXJnZXQgPSBGVF9MT0FEX1RBUkdFVF9MQ0RfVjsKICAgIH0KICAgIHJlbmRlckZsYWdzIHw9IHRhcmdldDsKCiAgICBnbHlwaF9pbmRleCA9IEZUX0dldF9DaGFyX0luZGV4KHNjYWxlckluZm8tPmZhY2UsIGdseXBoQ29kZSk7CgogICAgZXJyb3IgPSBGVF9Mb2FkX0dseXBoKHNjYWxlckluZm8tPmZhY2UsIGdseXBoQ29kZSwgcmVuZGVyRmxhZ3MpOwogICAgaWYgKGVycm9yKSB7CiAgICAgICAgLy9kbyBub3QgZGVzdHJveSBzY2FsZXIgeWV0LgogICAgICAgIC8vdGhpcyBjYW4gYmUgcHJvYmxlbSBvZiBwYXJ0aWN1bGFyIGNvbnRleHQgKGUuZy4gd2l0aCBiYWQgdHJhbnNmb3JtKQogICAgICAgIHJldHVybiBwdHJfdG9famxvbmcoZ2V0TnVsbEdseXBoSW1hZ2UoKSk7CiAgICB9CgogICAgZnRnbHlwaCA9IHNjYWxlckluZm8tPmZhY2UtPmdseXBoOwoKICAgIC8qIGFwcGx5IHN0eWxlcyAqLwogICAgaWYgKGNvbnRleHQtPmRvQm9sZCkgeyAvKiBpZiBib2xkIHN0eWxlICovCiAgICAgICAgRlRfR2x5cGhTbG90X0VtYm9sZGVuKGZ0Z2x5cGgpOwogICAgfQogICAgaWYgKGNvbnRleHQtPmRvSXRhbGl6ZSkgeyAvKiBpZiBvYmxpcXVlICovCiAgICAgICAgRlRfR2x5cGhTbG90X09ibGlxdWUoZnRnbHlwaCk7CiAgICB9CgogICAgLyogZ2VuZXJhdGUgYml0bWFwIGlmIGl0IGlzIG5vdCBkb25lIHlldAogICAgIGUuZy4gaWYgYWxnb3JpdGhtaWMgc3R5bGluZyBpcyBwZXJmb3JtZWQgYW5kIHN0eWxlIHdhcyBhZGRlZCB0byBvdXRsaW5lICovCiAgICBpZiAoZnRnbHlwaC0+Zm9ybWF0ID09IEZUX0dMWVBIX0ZPUk1BVF9PVVRMSU5FKSB7CiAgICAgICAgRlRfUmVuZGVyX0dseXBoKGZ0Z2x5cGgsIEZUX0xPQURfVEFSR0VUX01PREUodGFyZ2V0KSk7CiAgICB9CgogICAgd2lkdGggID0gKFVJbnQxNikgZnRnbHlwaC0+Yml0bWFwLndpZHRoOwogICAgaGVpZ2h0ID0gKFVJbnQxNikgZnRnbHlwaC0+Yml0bWFwLnJvd3M7CgogICAgaW1hZ2VTaXplID0gd2lkdGgqaGVpZ2h0OwogICAgZ2x5cGhJbmZvID0gKEdseXBoSW5mbyopIG1hbGxvYyhzaXplb2YoR2x5cGhJbmZvKSArIGltYWdlU2l6ZSk7CiAgICBpZiAoZ2x5cGhJbmZvID09IE5VTEwpIHsKICAgICAgICBnbHlwaEluZm8gPSBnZXROdWxsR2x5cGhJbWFnZSgpOwogICAgICAgIHJldHVybiBwdHJfdG9famxvbmcoZ2x5cGhJbmZvKTsKICAgIH0KICAgIGdseXBoSW5mby0+Y2VsbEluZm8gID0gTlVMTDsKICAgIGdseXBoSW5mby0+cm93Qnl0ZXMgID0gd2lkdGg7CiAgICBnbHlwaEluZm8tPndpZHRoICAgICA9IHdpZHRoOwogICAgZ2x5cGhJbmZvLT5oZWlnaHQgICAgPSBoZWlnaHQ7CiAgICBnbHlwaEluZm8tPnRvcExlZnRYICA9IChmbG9hdCkgIGZ0Z2x5cGgtPmJpdG1hcF9sZWZ0OwogICAgZ2x5cGhJbmZvLT50b3BMZWZ0WSAgPSAoZmxvYXQpIC1mdGdseXBoLT5iaXRtYXBfdG9wOwoKICAgIGlmIChjb250ZXh0LT5hYVR5cGUgPT0gVEVYVF9BQV9MQ0RfSFJHQiB8fAogICAgICAgIGNvbnRleHQtPmFhVHlwZSA9PSBURVhUX0FBX0xDRF9IQkdSKSB7CiAgICAgICAgZ2x5cGhJbmZvLT53aWR0aCA9IHdpZHRoLzM7CiAgICB9IGVsc2UgaWYgKGNvbnRleHQtPmFhVHlwZSA9PSBURVhUX0FBX0xDRF9WUkdCIHx8CiAgICAgICAgICAgICAgIGNvbnRleHQtPmFhVHlwZSA9PSBURVhUX0FBX0xDRF9WQkdSKSB7CiAgICAgICAgZ2x5cGhJbmZvLT5oZWlnaHQgPSBnbHlwaEluZm8tPmhlaWdodC8zOwogICAgfQoKICAgIGlmIChjb250ZXh0LT5mbVR5cGUgPT0gVEVYVF9GTV9PTikgewogICAgICAgIGdseXBoSW5mby0+YWR2YW5jZVggPSBGVDI2RG90NlRvRmxvYXQoZnRnbHlwaC0+YWR2YW5jZS54KTsKICAgICAgICBnbHlwaEluZm8tPmFkdmFuY2VZID0gRlQyNkRvdDZUb0Zsb2F0KC1mdGdseXBoLT5hZHZhbmNlLnkpOwogICAgfSBlbHNlIHsKICAgICAgICBnbHlwaEluZm8tPmFkdmFuY2VYID0KICAgICAgICAgICAoZmxvYXQpIFJPVU5EKEZUMjZEb3Q2VG9GbG9hdChmdGdseXBoLT5hZHZhbmNlLngpKTsKICAgICAgICBnbHlwaEluZm8tPmFkdmFuY2VZID0KICAgICAgICAgICAoZmxvYXQpIFJPVU5EKEZUMjZEb3Q2VG9GbG9hdCgtZnRnbHlwaC0+YWR2YW5jZS55KSk7CiAgICB9CgogICAgaWYgKGltYWdlU2l6ZSA9PSAwKSB7CiAgICAgICAgZ2x5cGhJbmZvLT5pbWFnZSA9IE5VTEw7CiAgICB9IGVsc2UgewogICAgICAgIGdseXBoSW5mby0+aW1hZ2UgPSAodW5zaWduZWQgY2hhciopIGdseXBoSW5mbyArIHNpemVvZihHbHlwaEluZm8pOwogICAgICAgIC8vY29udmVydCByZXN1bHQgdG8gb3V0cHV0IGZvcm1hdAogICAgICAgIC8vb3V0cHV0IGZvcm1hdCBpcyBlaXRoZXIgMyBieXRlcyBwZXIgcGl4ZWwgKGZvciBzdWJwaXhlbCBtb2RlcykKICAgICAgICAvLyBvciAxIGJ5dGUgcGVyIHBpeGVsIGZvciBBQSBhbmQgQiZXCiAgICAgICAgaWYgKGZ0Z2x5cGgtPmJpdG1hcC5waXhlbF9tb2RlID09ICBGVF9QSVhFTF9NT0RFX01PTk8pIHsKICAgICAgICAgICAgLyogY29udmVydCBmcm9tIDggcGl4ZWxzIHBlciBieXRlIHRvIDEgYnl0ZSBwZXIgcGl4ZWwgKi8KICAgICAgICAgICAgQ29weUJXMkdyZXk4KGZ0Z2x5cGgtPmJpdG1hcC5idWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICBmdGdseXBoLT5iaXRtYXAucGl0Y2gsCiAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCAqKSBnbHlwaEluZm8tPmltYWdlLAogICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aCwKICAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodCk7CiAgICAgICAgfSBlbHNlIGlmIChmdGdseXBoLT5iaXRtYXAucGl4ZWxfbW9kZSA9PSAgRlRfUElYRUxfTU9ERV9HUkFZKSB7CiAgICAgICAgICAgIC8qIGJ5dGUgcGVyIHBpeGVsIHRvIGJ5dGUgcGVyIHBpeGVsID0+IGp1c3QgY29weSAqLwogICAgICAgICAgICBtZW1jcHkoZ2x5cGhJbmZvLT5pbWFnZSwgZnRnbHlwaC0+Yml0bWFwLmJ1ZmZlciwgaW1hZ2VTaXplKTsKICAgICAgICB9IGVsc2UgaWYgKGZ0Z2x5cGgtPmJpdG1hcC5waXhlbF9tb2RlID09ICBGVF9QSVhFTF9NT0RFX0dSQVk0KSB7CiAgICAgICAgICAgIC8qIDQgYml0cyBwZXIgcGl4ZWwgdG8gYnl0ZSBwZXIgcGl4ZWwgKi8KICAgICAgICAgICAgQ29weUdyZXk0VG9HcmV5OChmdGdseXBoLT5iaXRtYXAuYnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ0Z2x5cGgtPmJpdG1hcC5waXRjaCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCAqKSBnbHlwaEluZm8tPmltYWdlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpZHRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpZHRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodCk7CiAgICAgICAgfSBlbHNlIGlmIChmdGdseXBoLT5iaXRtYXAucGl4ZWxfbW9kZSA9PSAgRlRfUElYRUxfTU9ERV9MQ0QpIHsKICAgICAgICAgICAgLyogMyBieXRlcyBwZXIgcGl4ZWwgdG8gMyBieXRlcyBwZXIgcGl4ZWwgKi8KICAgICAgICAgICAgQ29weUZUU3VicGl4ZWxUb1N1YnBpeGVsKGZ0Z2x5cGgtPmJpdG1hcC5idWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdGdseXBoLT5iaXRtYXAucGl0Y2gsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCAqKSBnbHlwaEluZm8tPmltYWdlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodCk7CiAgICAgICAgfSBlbHNlIGlmIChmdGdseXBoLT5iaXRtYXAucGl4ZWxfbW9kZSA9PSAgRlRfUElYRUxfTU9ERV9MQ0RfVikgewogICAgICAgICAgICAvKiAzIGJ5dGVzIHBlciBwaXhlbCB0byAzIGJ5dGVzIHBlciBwaXhlbCAqLwogICAgICAgICAgICBDb3B5RlRTdWJwaXhlbFZUb1N1YnBpeGVsKGZ0Z2x5cGgtPmJpdG1hcC5idWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnRnbHlwaC0+Yml0bWFwLnBpdGNoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh2b2lkICopIGdseXBoSW5mby0+aW1hZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGgqMywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQpOwogICAgICAgICAgICBnbHlwaEluZm8tPnJvd0J5dGVzICo9MzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBmcmVlKGdseXBoSW5mbyk7CiAgICAgICAgICAgIGdseXBoSW5mbyA9IGdldE51bGxHbHlwaEltYWdlKCk7CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiBwdHJfdG9famxvbmcoZ2x5cGhJbmZvKTsKfQoKCi8qCiAqIENsYXNzOiAgICAgc3VuX2ZvbnRfRnJlZXR5cGVGb250U2NhbGVyCiAqIE1ldGhvZDogICAgZ2V0TGF5b3V0VGFibGVDYWNoZU5hdGl2ZQogKiBTaWduYXR1cmU6IChKKUoKICovCkpOSUVYUE9SVCBqbG9uZyBKTklDQUxMCkphdmFfc3VuX2ZvbnRfRnJlZXR5cGVGb250U2NhbGVyX2dldExheW91dFRhYmxlQ2FjaGVOYXRpdmUoCiAgICAgICAgSk5JRW52ICplbnYsIGpvYmplY3Qgc2NhbGVyLCBqbG9uZyBwU2NhbGVyKSB7CiAgICBGVFNjYWxlckluZm8gKnNjYWxlckluZm8gPSAoRlRTY2FsZXJJbmZvKikgamxvbmdfdG9fcHRyKHBTY2FsZXIpOwoKICAgIGlmIChzY2FsZXJJbmZvID09IE5VTEwpIHsKICAgICAgICBpbnZhbGlkYXRlSmF2YVNjYWxlcihlbnYsIHNjYWxlciwgc2NhbGVySW5mbyk7CiAgICAgICAgcmV0dXJuIDBMOwogICAgfQoKICAgIC8vIGluaXQgbGF5b3V0IHRhYmxlIGNhY2hlIGluIGZvbnQKICAgIC8vIHdlJ3JlIGFzc3VtaW5nIHRoZSBmb250IGlzIGEgZmlsZSBmb250IGFuZCBtb3Jlb3ZlciBpdCBpcyBUcnVldHlwZSBmb250CiAgICAvLyBvdGhlcndpc2Ugd2Ugc2hvdWxkbid0IGJlIGFibGUgdG8gZ2V0IGhlcmUuLi4KICAgIGlmIChzY2FsZXJJbmZvLT5sYXlvdXRUYWJsZXMgPT0gTlVMTCkgewogICAgICAgIHNjYWxlckluZm8tPmxheW91dFRhYmxlcyA9IG5ld0xheW91dFRhYmxlQ2FjaGUoKTsKICAgIH0KCiAgICByZXR1cm4gcHRyX3RvX2psb25nKHNjYWxlckluZm8tPmxheW91dFRhYmxlcyk7Cn0KCi8qCiAqIENsYXNzOiAgICAgc3VuX2ZvbnRfRnJlZXR5cGVGb250U2NhbGVyCiAqIE1ldGhvZDogICAgZGlzcG9zZU5hdGl2ZVNjYWxlcgogKiBTaWduYXR1cmU6IChKKVYKICovCkpOSUVYUE9SVCB2b2lkIEpOSUNBTEwKSmF2YV9zdW5fZm9udF9GcmVldHlwZUZvbnRTY2FsZXJfZGlzcG9zZU5hdGl2ZVNjYWxlcigKICAgICAgICBKTklFbnYgKmVudiwgam9iamVjdCBzY2FsZXIsIGpsb25nIHBTY2FsZXIpIHsKICAgIEZUU2NhbGVySW5mbyogc2NhbGVySW5mbyA9IChGVFNjYWxlckluZm8gKikgamxvbmdfdG9fcHRyKHBTY2FsZXIpOwoKICAgIGZyZWVOYXRpdmVSZXNvdXJjZXMoZW52LCBzY2FsZXJJbmZvKTsKfQoKLyoKICogQ2xhc3M6ICAgICBzdW5fZm9udF9GcmVldHlwZUZvbnRTY2FsZXIKICogTWV0aG9kOiAgICBnZXROdW1HbHlwaHNOYXRpdmUKICogU2lnbmF0dXJlOiAoKUkKICovCkpOSUVYUE9SVCBqaW50IEpOSUNBTEwKSmF2YV9zdW5fZm9udF9GcmVldHlwZUZvbnRTY2FsZXJfZ2V0TnVtR2x5cGhzTmF0aXZlKAogICAgICAgIEpOSUVudiAqZW52LCBqb2JqZWN0IHNjYWxlciwgamxvbmcgcFNjYWxlcikgewogICAgRlRTY2FsZXJJbmZvKiBzY2FsZXJJbmZvID0gKEZUU2NhbGVySW5mbyAqKSBqbG9uZ190b19wdHIocFNjYWxlcik7CgogICAgaWYgKHNjYWxlckluZm8gPT0gTlVMTCB8fCBzY2FsZXJJbmZvLT5mYWNlID09IE5VTEwpIHsgLyogYmFkL251bGwgc2NhbGVyICovCiAgICAgICAgLyogbnVsbCBzY2FsZXIgY2FuIHJlbmRlciAxIGdseXBoIC0gIm1pc3NpbmcgZ2x5cGgiIHdpdGggY29kZSAwCiAgICAgICAgICAgKGFsbCBnbHlwaCBjb2RlcyByZXF1ZXN0ZWQgYnkgdXNlciBhcmUgbWFwcGVkIHRvIGNvZGUgMCBhdAogICAgICAgICAgIHZhbGlkYXRpb24gc3RlcCkgKi8KICAgICAgICBpbnZhbGlkYXRlSmF2YVNjYWxlcihlbnYsIHNjYWxlciwgc2NhbGVySW5mbyk7CiAgICAgICAgcmV0dXJuIChqaW50KSAxOwogICAgfQoKICAgIHJldHVybiAoamludCkgc2NhbGVySW5mby0+ZmFjZS0+bnVtX2dseXBoczsKfQoKLyoKICogQ2xhc3M6ICAgICBzdW5fZm9udF9GcmVldHlwZUZvbnRTY2FsZXIKICogTWV0aG9kOiAgICBnZXRNaXNzaW5nR2x5cGhDb2RlTmF0aXZlCiAqIFNpZ25hdHVyZTogKClJCiAqLwpKTklFWFBPUlQgamludCBKTklDQUxMCkphdmFfc3VuX2ZvbnRfRnJlZXR5cGVGb250U2NhbGVyX2dldE1pc3NpbmdHbHlwaENvZGVOYXRpdmUoCiAgICAgICAgSk5JRW52ICplbnYsIGpvYmplY3Qgc2NhbGVyLCBqbG9uZyBwU2NhbGVyKSB7CgogICAgLyogSXMgaXQgYWx3YXlzIDAgZm9yIGZyZWV0eXBlPyAqLwogICAgcmV0dXJuIDA7Cn0KCi8qCiAqIENsYXNzOiAgICAgc3VuX2ZvbnRfRnJlZXR5cGVGb250U2NhbGVyCiAqIE1ldGhvZDogICAgZ2V0R2x5cGhDb2RlTmF0aXZlCiAqIFNpZ25hdHVyZTogKEMpSQogKi8KSk5JRVhQT1JUIGppbnQgSk5JQ0FMTApKYXZhX3N1bl9mb250X0ZyZWV0eXBlRm9udFNjYWxlcl9nZXRHbHlwaENvZGVOYXRpdmUoCiAgICAgICAgSk5JRW52ICplbnYsIGpvYmplY3Qgc2NhbGVyLCBqbG9uZyBwU2NhbGVyLCBqY2hhciBjaGFyQ29kZSkgewoKICAgIEZUU2NhbGVySW5mbyogc2NhbGVySW5mbyA9IChGVFNjYWxlckluZm8gKikgamxvbmdfdG9fcHRyKHBTY2FsZXIpOwoKICAgIGlmIChzY2FsZXIgPT0gTlVMTCB8fCBzY2FsZXJJbmZvLT5mYWNlID09IE5VTEwpIHsgLyogYmFkL251bGwgc2NhbGVyICovCiAgICAgICAgaW52YWxpZGF0ZUphdmFTY2FsZXIoZW52LCBzY2FsZXIsIHNjYWxlckluZm8pOwogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIHJldHVybiBGVF9HZXRfQ2hhcl9JbmRleChzY2FsZXJJbmZvLT5mYWNlLCBjaGFyQ29kZSk7Cn0KCgojZGVmaW5lIEZsb2F0VG9GMjZEb3Q2KHgpICgodW5zaWduZWQgaW50KSAoKHgpKjY0KSkKCnN0YXRpYyBGVF9PdXRsaW5lKiBnZXRGVE91dGxpbmUoSk5JRW52KiBlbnYsIGpvYmplY3QgZm9udDJELAogICAgICAgIEZUU2NhbGVyQ29udGV4dCAqY29udGV4dCwgRlRTY2FsZXJJbmZvKiBzY2FsZXJJbmZvLAogICAgICAgIGppbnQgZ2x5cGhDb2RlLCBqZmxvYXQgeHBvcywgamZsb2F0IHlwb3MpIHsKICAgIGludCByZW5kZXJGbGFnczsKICAgIGludCBnbHlwaF9pbmRleDsKICAgIEZUX0Vycm9yIGVycm9yOwogICAgRlRfR2x5cGhTbG90IGZ0Z2x5cGg7CgogICAgaWYgKGdseXBoQ29kZSA+PSBJTlZJU0lCTEVfR0xZUEhTIHx8CiAgICAgICAgICAgIGlzTnVsbFNjYWxlckNvbnRleHQoY29udGV4dCkgfHwgc2NhbGVySW5mbyA9PSBOVUxMKSB7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgZXJyb3IgPSBzZXR1cEZUQ29udGV4dChlbnYsIGZvbnQyRCwgc2NhbGVySW5mbywgY29udGV4dCk7CiAgICBpZiAoZXJyb3IpIHsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICByZW5kZXJGbGFncyA9IEZUX0xPQURfTk9fSElOVElORyB8IEZUX0xPQURfTk9fQklUTUFQOwoKICAgIGdseXBoX2luZGV4ID0gRlRfR2V0X0NoYXJfSW5kZXgoc2NhbGVySW5mby0+ZmFjZSwgZ2x5cGhDb2RlKTsKCiAgICBlcnJvciA9IEZUX0xvYWRfR2x5cGgoc2NhbGVySW5mby0+ZmFjZSwgZ2x5cGhDb2RlLCByZW5kZXJGbGFncyk7CiAgICBpZiAoZXJyb3IpIHsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICBmdGdseXBoID0gc2NhbGVySW5mby0+ZmFjZS0+Z2x5cGg7CgogICAgLyogYXBwbHkgc3R5bGVzICovCiAgICBpZiAoY29udGV4dC0+ZG9Cb2xkKSB7IC8qIGlmIGJvbGQgc3R5bGUgKi8KICAgICAgICBGVF9HbHlwaFNsb3RfRW1ib2xkZW4oZnRnbHlwaCk7CiAgICB9CiAgICBpZiAoY29udGV4dC0+ZG9JdGFsaXplKSB7IC8qIGlmIG9ibGlxdWUgKi8KICAgICAgICBGVF9HbHlwaFNsb3RfT2JsaXF1ZShmdGdseXBoKTsKICAgIH0KCiAgICBGVF9PdXRsaW5lX1RyYW5zbGF0ZSgmZnRnbHlwaC0+b3V0bGluZSwKICAgICAgICAgICAgICAgICAgICAgICAgIEZsb2F0VG9GMjZEb3Q2KHhwb3MpLAogICAgICAgICAgICAgICAgICAgICAgICAgRmxvYXRUb0YyNkRvdDYoeXBvcykpOwoKICAgIHJldHVybiAmZnRnbHlwaC0+b3V0bGluZTsKfQoKI2RlZmluZSBGMjZEb3Q2VG9GbG9hdChuKSAoKChmbG9hdCkobikpLygoZmxvYXQpIDY0KSkKCi8qIFR5cGVzIG9mIEdlbmVyYWxQYXRoIHNlZ21lbnRzLgogICBUT0RPOiBwdWxsIGNvbnN0YW50cyBmcm9tIG90aGVyIHBsYWNlPyAqLwoKI2RlZmluZSBTRUdfVU5LTk9XTiAtMQojZGVmaW5lIFNFR19NT1ZFVE8gICAwCiNkZWZpbmUgU0VHX0xJTkVUTyAgIDEKI2RlZmluZSBTRUdfUVVBRFRPICAgMgojZGVmaW5lIFNFR19DVUJJQ1RPICAzCiNkZWZpbmUgU0VHX0NMT1NFICAgIDQKCiNkZWZpbmUgV0lORF9OT05fWkVSTyAwCiNkZWZpbmUgV0lORF9FVkVOX09ERCAxCgovKiBQbGFjZWhvbGRlciB0byBhY2N1bXVsYXRlIEdlbmVyYWxQYXRoIGRhdGEgKi8KdHlwZWRlZiBzdHJ1Y3QgewogICAgamludCBudW1UeXBlczsKICAgIGppbnQgbnVtQ29vcmRzOwogICAgamludCBsZW5UeXBlczsKICAgIGppbnQgbGVuQ29vcmRzOwogICAgamludCB3cjsKICAgIGpieXRlKiBwb2ludFR5cGVzOwogICAgamZsb2F0KiBwb2ludENvb3JkczsKfSBHUERhdGE7CgovKiByZXR1cm5zIDAgb24gZmFpbHVyZSAqLwpzdGF0aWMgaW50IGFsbG9jYXRlU3BhY2VGb3JHUChHUERhdGEqIGdwZGF0YSwgaW50IG5wb2ludHMsIGludCBuY29udG91cnMpIHsKICAgIGludCBtYXhUeXBlcywgbWF4Q29vcmRzOwoKICAgIC8qIHdlIG1heSBoYXZlIHVwIHRvIE4gaW50ZXJtZWRpYXRlIHBvaW50cyBwZXIgY29udG91cgogICAgICAgKGFuZCBmb3IgZWFjaCBwb2ludCBjYW4gYWN0dWFsbHkgY2F1c2UgbmV3IGN1cnZlIHRvIGJlIGdlbmVyYXRlZCkKICAgICAgIEluIGFkZGl0aW9uIHdlIGNhbiBhbHNvIGhhdmUgMiBleHRyYSBwb2ludCBwZXIgb3V0bGluZS4KICAgICAqLwogICAgbWF4VHlwZXMgID0gMipucG9pbnRzICArIDIqbmNvbnRvdXJzOwogICAgbWF4Q29vcmRzID0gNCoobnBvaW50cyArIDIqbmNvbnRvdXJzKTsgLy93ZSBtYXkgbmVlZCB0byBpbnNlcnQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vdXAgdG8gbi0xIGludGVybWVkaWF0ZSBwb2ludHMKCiAgICAvKiBmaXJzdCB1c2FnZSAtIGFsbG9jYXRlIHNwYWNlIGFuZCBpbnRpYWxpemUgYWxsIGZpZWxkcyAqLwogICAgaWYgKGdwZGF0YS0+cG9pbnRUeXBlcyA9PSBOVUxMIHx8IGdwZGF0YS0+cG9pbnRDb29yZHMgPT0gTlVMTCkgewogICAgICAgIGdwZGF0YS0+bGVuVHlwZXMgID0gbWF4VHlwZXM7CiAgICAgICAgZ3BkYXRhLT5sZW5Db29yZHMgPSBtYXhDb29yZHM7CiAgICAgICAgZ3BkYXRhLT5wb2ludFR5cGVzICA9IChqYnl0ZSopCiAgICAgICAgICAgICBtYWxsb2MoZ3BkYXRhLT5sZW5UeXBlcypzaXplb2YoamJ5dGUpKTsKICAgICAgICBncGRhdGEtPnBvaW50Q29vcmRzID0gKGpmbG9hdCopCiAgICAgICAgICAgICBtYWxsb2MoZ3BkYXRhLT5sZW5Db29yZHMqc2l6ZW9mKGpmbG9hdCkpOwogICAgICAgIGdwZGF0YS0+bnVtVHlwZXMgPSAwOwogICAgICAgIGdwZGF0YS0+bnVtQ29vcmRzID0gMDsKICAgICAgICBncGRhdGEtPndyID0gV0lORF9OT05fWkVSTzsgLyogQnkgZGVmYXVsdCwgb3V0bGluZXMgYXJlIGZpbGxlZAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1c2luZyB0aGUgbm9uLXplcm8gd2luZGluZyBydWxlLiAqLwogICAgfSBlbHNlIHsKICAgICAgICAvKiBkbyB3ZSBoYXZlIGVub3VnaCBzcGFjZT8gKi8KICAgICAgICBpZiAoZ3BkYXRhLT5sZW5UeXBlcyAtIGdwZGF0YS0+bnVtVHlwZXMgPCBtYXhUeXBlcykgewogICAgICAgICAgICBncGRhdGEtPmxlblR5cGVzICArPSBtYXhUeXBlczsKICAgICAgICAgICAgZ3BkYXRhLT5wb2ludFR5cGVzICA9IChqYnl0ZSopCiAgICAgICAgICAgICAgcmVhbGxvYyhncGRhdGEtPnBvaW50VHlwZXMsIGdwZGF0YS0+bGVuVHlwZXMqc2l6ZW9mKGpieXRlKSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoZ3BkYXRhLT5sZW5Db29yZHMgLSBncGRhdGEtPm51bUNvb3JkcyA8IG1heENvb3JkcykgewogICAgICAgICAgICBncGRhdGEtPmxlbkNvb3JkcyArPSBtYXhDb29yZHM7CiAgICAgICAgICAgIGdwZGF0YS0+cG9pbnRDb29yZHMgPSAoamZsb2F0KikKICAgICAgICAgICAgICByZWFsbG9jKGdwZGF0YS0+cG9pbnRDb29yZHMsIGdwZGF0YS0+bGVuQ29vcmRzKnNpemVvZihqZmxvYXQpKTsKICAgICAgICB9CiAgICB9CgogICAgLyogZmFpbHVyZSBpZiBhbnkgb2YgbWFsbG9jcyBmYWlsZWQgKi8KICAgIGlmIChncGRhdGEtPnBvaW50VHlwZXMgPT0gTlVMTCB8fCAgZ3BkYXRhLT5wb2ludENvb3JkcyA9PSBOVUxMKQogICAgICAgIHJldHVybiAwOwogICAgZWxzZQogICAgICAgIHJldHVybiAxOwp9CgpzdGF0aWMgdm9pZCBhZGRUb0dQKEdQRGF0YSogZ3BkYXRhLCBGVF9PdXRsaW5lKm91dGxpbmUpIHsKICAgIGpieXRlIGN1cnJlbnRfdHlwZT1TRUdfVU5LTk9XTjsKICAgIGludCBpLCBqOwogICAgamZsb2F0IHgsIHk7CgogICAgaiA9IDA7CiAgICBmb3IoaT0wOyBpPG91dGxpbmUtPm5fcG9pbnRzOyBpKyspIHsKICAgICAgICB4ID0gIEYyNkRvdDZUb0Zsb2F0KG91dGxpbmUtPnBvaW50c1tpXS54KTsKICAgICAgICB5ID0gLUYyNkRvdDZUb0Zsb2F0KG91dGxpbmUtPnBvaW50c1tpXS55KTsKCiAgICAgICAgaWYgKEZUX0NVUlZFX1RBRyhvdXRsaW5lLT50YWdzW2ldKSA9PSBGVF9DVVJWRV9UQUdfT04pIHsKICAgICAgICAgICAgLyogSWYgYml0IDAgaXMgdW5zZXQsIHRoZSBwb2ludCBpcyAib2ZmIiB0aGUgY3VydmUsCiAgICAgICAgICAgICBpLmUuLCBhIEJlemllciBjb250cm9sIHBvaW50LCB3aGlsZSBpdCBpcyAib24iIHdoZW4gc2V0LiAqLwogICAgICAgICAgICBpZiAoY3VycmVudF90eXBlID09IFNFR19VTktOT1dOKSB7IC8qIHNwZWNpYWwgY2FzZToKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZXJ5IGZpcnN0IHBvaW50ICovCiAgICAgICAgICAgICAgICAvKiBhZGQgc2VnbWVudCAqLwogICAgICAgICAgICAgICAgZ3BkYXRhLT5wb2ludFR5cGVzW2dwZGF0YS0+bnVtVHlwZXMrK10gPSBTRUdfTU9WRVRPOwogICAgICAgICAgICAgICAgY3VycmVudF90eXBlID0gU0VHX0xJTkVUTzsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGdwZGF0YS0+cG9pbnRUeXBlc1tncGRhdGEtPm51bVR5cGVzKytdID0gY3VycmVudF90eXBlOwogICAgICAgICAgICAgICAgY3VycmVudF90eXBlID0gU0VHX0xJTkVUTzsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGlmIChjdXJyZW50X3R5cGUgPT0gU0VHX1VOS05PV04pIHsgLyogc3BlY2lhbCBjYXNlOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZXJ5IGZpcnN0IHBvaW50ICovCiAgICAgICAgICAgICAgICBpZiAoRlRfQ1VSVkVfVEFHKG91dGxpbmUtPnRhZ3NbaSsxXSkgPT0gRlRfQ1VSVkVfVEFHX09OKSB7CiAgICAgICAgICAgICAgICAgICAgLyoganVzdCBza2lwIGZpcnN0IHBvaW50LiBBZGhvYyBoZXVyaXN0aWM/ICovCiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHggPSAoeCArIEYyNkRvdDZUb0Zsb2F0KG91dGxpbmUtPnBvaW50c1tpKzFdLngpKS8yOwogICAgICAgICAgICAgICAgICAgIHkgPSAoeSAtIEYyNkRvdDZUb0Zsb2F0KG91dGxpbmUtPnBvaW50c1tpKzFdLnkpKS8yOwogICAgICAgICAgICAgICAgICAgIGdwZGF0YS0+cG9pbnRUeXBlc1tncGRhdGEtPm51bVR5cGVzKytdID0gU0VHX01PVkVUTzsKICAgICAgICAgICAgICAgICAgICBjdXJyZW50X3R5cGUgPSBTRUdfTElORVRPOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgaWYgKEZUX0NVUlZFX1RBRyhvdXRsaW5lLT50YWdzW2ldKSA9PSBGVF9DVVJWRV9UQUdfQ1VCSUMpIHsKICAgICAgICAgICAgICAgIC8qIEJpdCAxIGlzIG1lYW5pbmdmdWwgZm9yIJFvZmaSIHBvaW50cyBvbmx5LgogICAgICAgICAgICAgICAgICAgSWYgc2V0LCBpdCBpbmRpY2F0ZXMgYSB0aGlyZC1vcmRlciBCZXppZXIgYXJjIGNvbnRyb2wKICAgICAgICAgICAgICAgICAgIHBvaW50OyBhbmQgYSBzZWNvbmQtb3JkZXIgY29udHJvbCBwb2ludCBpZiB1bnNldC4gICovCiAgICAgICAgICAgICAgICBjdXJyZW50X3R5cGUgPSBTRUdfQ1VCSUNUTzsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8qIHR3byBzdWNjZXNzaXZlIGNvbmljICJvZmYiIHBvaW50cyBmb3JjZXMgdGhlIHJhc3Rlcml6ZXIKICAgICAgICAgICAgICAgICAgIHRvIGNyZWF0ZSAoZHVyaW5nIHRoZSBzY2FuLWxpbmUgY29udmVyc2lvbiBwcm9jZXNzCiAgICAgICAgICAgICAgICAgICBleGNsdXNpdmVseSkgYSB2aXJ0dWFsICJvbiIgcG9pbnQgYW1pZHN0IHRoZW0sIGF0IHRoZWlyCiAgICAgICAgICAgICAgICAgICBleGFjdCBtaWRkbGUuIFRoaXMgZ3JlYXRseSBmYWNpbGl0YXRlcyB0aGUgZGVmaW5pdGlvbiBvZgogICAgICAgICAgICAgICAgICAgc3VjY2Vzc2l2ZSBjb25pYyBCZXppZXIgYXJjcy4gIE1vcmVvdmVyLCBpdCBpcyB0aGUgd2F5CiAgICAgICAgICAgICAgICAgICBvdXRsaW5lcyBhcmUgZGVzY3JpYmVkIGluIHRoZSBUcnVlVHlwZSBzcGVjaWZpY2F0aW9uLiAqLwogICAgICAgICAgICAgICAgaWYgKGN1cnJlbnRfdHlwZSA9PSBTRUdfUVVBRFRPKSB7CiAgICAgICAgICAgICAgICAgICAgZ3BkYXRhLT5wb2ludENvb3Jkc1tncGRhdGEtPm51bUNvb3JkcysrXSA9CiAgICAgICAgICAgICAgICAgICAgICAgIEYyNkRvdDZUb0Zsb2F0KG91dGxpbmUtPnBvaW50c1tpXS54ICsKICAgICAgICAgICAgICAgICAgICAgICAgb3V0bGluZS0+cG9pbnRzW2ktMV0ueCkvMjsKICAgICAgICAgICAgICAgICAgICBncGRhdGEtPnBvaW50Q29vcmRzW2dwZGF0YS0+bnVtQ29vcmRzKytdID0KICAgICAgICAgICAgICAgICAgICAgICAgLSBGMjZEb3Q2VG9GbG9hdChvdXRsaW5lLT5wb2ludHNbaV0ueSArCiAgICAgICAgICAgICAgICAgICAgICAgIG91dGxpbmUtPnBvaW50c1tpLTFdLnkpLzI7CiAgICAgICAgICAgICAgICAgICAgZ3BkYXRhLT5wb2ludFR5cGVzW2dwZGF0YS0+bnVtVHlwZXMrK10gPSBTRUdfUVVBRFRPOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgY3VycmVudF90eXBlID0gU0VHX1FVQURUTzsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBncGRhdGEtPnBvaW50Q29vcmRzW2dwZGF0YS0+bnVtQ29vcmRzKytdID0geDsKICAgICAgICBncGRhdGEtPnBvaW50Q29vcmRzW2dwZGF0YS0+bnVtQ29vcmRzKytdID0geTsKICAgICAgICBpZiAob3V0bGluZS0+Y29udG91cnNbal0gPT0gaSkgeyAvL2VuZCBvZiBjb250b3VyCiAgICAgICAgICAgIGludCBzdGFydCA9IGogPiAwID8gb3V0bGluZS0+Y29udG91cnNbai0xXSsxIDogMDsKICAgICAgICAgICAgZ3BkYXRhLT5wb2ludFR5cGVzW2dwZGF0YS0+bnVtVHlwZXMrK10gPSBjdXJyZW50X3R5cGU7CiAgICAgICAgICAgIGlmIChjdXJyZW50X3R5cGUgPT0gU0VHX1FVQURUTyAmJgogICAgICAgICAgICBGVF9DVVJWRV9UQUcob3V0bGluZS0+dGFnc1tzdGFydF0pICE9IEZUX0NVUlZFX1RBR19PTikgewogICAgICAgICAgICAgICAgZ3BkYXRhLT5wb2ludENvb3Jkc1tncGRhdGEtPm51bUNvb3JkcysrXSA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoRjI2RG90NlRvRmxvYXQob3V0bGluZS0+cG9pbnRzW3N0YXJ0XS54KSArIHgpLzI7CiAgICAgICAgICAgICAgICBncGRhdGEtPnBvaW50Q29vcmRzW2dwZGF0YS0+bnVtQ29vcmRzKytdID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICgtRjI2RG90NlRvRmxvYXQob3V0bGluZS0+cG9pbnRzW3N0YXJ0XS55KSArIHkpLzI7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBncGRhdGEtPnBvaW50Q29vcmRzW2dwZGF0YS0+bnVtQ29vcmRzKytdID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIEYyNkRvdDZUb0Zsb2F0KG91dGxpbmUtPnBvaW50c1tzdGFydF0ueCk7CiAgICAgICAgICAgICAgICBncGRhdGEtPnBvaW50Q29vcmRzW2dwZGF0YS0+bnVtQ29vcmRzKytdID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIC1GMjZEb3Q2VG9GbG9hdChvdXRsaW5lLT5wb2ludHNbc3RhcnRdLnkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGdwZGF0YS0+cG9pbnRUeXBlc1tncGRhdGEtPm51bVR5cGVzKytdID0gU0VHX0NMT1NFOwogICAgICAgICAgICBjdXJyZW50X3R5cGUgPSBTRUdfVU5LTk9XTjsKICAgICAgICAgICAgaisrOwogICAgICAgIH0KICAgIH0KCiAgICAvKiBJZiBzZXQgdG8gMSwgdGhlIG91dGxpbmUgd2lsbCBiZSBmaWxsZWQgdXNpbmcgdGhlIGV2ZW4tb2RkIGZpbGwgcnVsZSAqLwogICAgaWYgKG91dGxpbmUtPmZsYWdzICYgRlRfT1VUTElORV9FVkVOX09ERF9GSUxMKSB7CiAgICAgICAgZ3BkYXRhLT53ciA9IFdJTkRfRVZFTl9PREQ7CiAgICB9Cn0KCnN0YXRpYyB2b2lkIGZyZWVHUChHUERhdGEqIGdwZGF0YSkgewogICAgaWYgKGdwZGF0YS0+cG9pbnRDb29yZHMgIT0gTlVMTCkgewogICAgICAgIGZyZWUoZ3BkYXRhLT5wb2ludENvb3Jkcyk7CiAgICAgICAgZ3BkYXRhLT5wb2ludENvb3JkcyA9IE5VTEw7CiAgICAgICAgZ3BkYXRhLT5udW1Db29yZHMgPSAwOwogICAgICAgIGdwZGF0YS0+bGVuQ29vcmRzID0gMDsKICAgIH0KICAgIGlmIChncGRhdGEtPnBvaW50VHlwZXMgIT0gTlVMTCkgewogICAgICAgIGZyZWUoZ3BkYXRhLT5wb2ludFR5cGVzKTsKICAgICAgICBncGRhdGEtPnBvaW50VHlwZXMgPSBOVUxMOwogICAgICAgIGdwZGF0YS0+bnVtVHlwZXMgPSAwOwogICAgICAgIGdwZGF0YS0+bGVuVHlwZXMgPSAwOwogICAgfQp9CgpzdGF0aWMgam9iamVjdCBnZXRHbHlwaEdlbmVyYWxQYXRoKEpOSUVudiogZW52LCBqb2JqZWN0IGZvbnQyRCwKICAgICAgICBGVFNjYWxlckNvbnRleHQgKmNvbnRleHQsIEZUU2NhbGVySW5mbyAqc2NhbGVySW5mbywKICAgICAgICBqaW50IGdseXBoQ29kZSwgamZsb2F0IHhwb3MsIGpmbG9hdCB5cG9zKSB7CgogICAgRlRfT3V0bGluZSogb3V0bGluZTsKICAgIGpvYmplY3QgZ3AgPSBOVUxMOwogICAgamJ5dGVBcnJheSB0eXBlczsKICAgIGpmbG9hdEFycmF5IGNvb3JkczsKICAgIEdQRGF0YSBncGRhdGE7CgogICAgb3V0bGluZSA9IGdldEZUT3V0bGluZShlbnYsIGZvbnQyRCwgY29udGV4dCwgc2NhbGVySW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2x5cGhDb2RlLCB4cG9zLCB5cG9zKTsKCiAgICBpZiAob3V0bGluZSA9PSBOVUxMIHx8IG91dGxpbmUtPm5fcG9pbnRzID09IDApIHsKICAgICAgICByZXR1cm4gZ3A7CiAgICB9CgogICAgZ3BkYXRhLnBvaW50VHlwZXMgID0gTlVMTDsKICAgIGdwZGF0YS5wb2ludENvb3JkcyA9IE5VTEw7CiAgICBpZiAoIWFsbG9jYXRlU3BhY2VGb3JHUCgmZ3BkYXRhLCBvdXRsaW5lLT5uX3BvaW50cywgb3V0bGluZS0+bl9jb250b3VycykpIHsKICAgICAgICByZXR1cm4gZ3A7CiAgICB9CgogICAgYWRkVG9HUCgmZ3BkYXRhLCBvdXRsaW5lKTsKCiAgICB0eXBlcyAgPSAoKmVudiktPk5ld0J5dGVBcnJheShlbnYsIGdwZGF0YS5udW1UeXBlcyk7CiAgICBjb29yZHMgPSAoKmVudiktPk5ld0Zsb2F0QXJyYXkoZW52LCBncGRhdGEubnVtQ29vcmRzKTsKCiAgICBpZiAodHlwZXMgJiYgY29vcmRzKSB7CiAgICAgICAgKCplbnYpLT5TZXRCeXRlQXJyYXlSZWdpb24oZW52LCB0eXBlcywgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncGRhdGEubnVtVHlwZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3BkYXRhLnBvaW50VHlwZXMpOwogICAgICAgICgqZW52KS0+U2V0RmxvYXRBcnJheVJlZ2lvbihlbnYsIGNvb3JkcywgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3BkYXRhLm51bUNvb3JkcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3BkYXRhLnBvaW50Q29vcmRzKTsKICAgICAgICBncCA9ICgqZW52KS0+TmV3T2JqZWN0KGVudiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1bkZvbnRJRHMuZ3BDbGFzcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1bkZvbnRJRHMuZ3BDdHIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncGRhdGEud3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdwZGF0YS5udW1UeXBlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvb3JkcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdwZGF0YS5udW1Db29yZHMpOwogICAgfQoKICAgIGZyZWVHUCgmZ3BkYXRhKTsKCiAgICByZXR1cm4gZ3A7Cn0KCi8qCiAqIENsYXNzOiAgICAgc3VuX2ZvbnRfRnJlZXR5cGVGb250U2NhbGVyCiAqIE1ldGhvZDogICAgZ2V0R2x5cGhPdXRsaW5lTmF0aXZlCiAqIFNpZ25hdHVyZTogKExzdW4vZm9udC9Gb250MkQ7SklGRilMamF2YS9hd3QvZ2VvbS9HZW5lcmFsUGF0aDsKICovCkpOSUVYUE9SVCBqb2JqZWN0IEpOSUNBTEwKSmF2YV9zdW5fZm9udF9GcmVldHlwZUZvbnRTY2FsZXJfZ2V0R2x5cGhPdXRsaW5lTmF0aXZlKAogICAgICBKTklFbnYgKmVudiwgam9iamVjdCBzY2FsZXIsIGpvYmplY3QgZm9udDJELCBqbG9uZyBwU2NhbGVyQ29udGV4dCwKICAgICAgamxvbmcgcFNjYWxlciwgamludCBnbHlwaENvZGUsIGpmbG9hdCB4cG9zLCBqZmxvYXQgeXBvcykgewoKICAgIEZUU2NhbGVyQ29udGV4dCAqY29udGV4dCA9CiAgICAgICAgIChGVFNjYWxlckNvbnRleHQqKSBqbG9uZ190b19wdHIocFNjYWxlckNvbnRleHQpOwogICAgRlRTY2FsZXJJbmZvKiBzY2FsZXJJbmZvID0gKEZUU2NhbGVySW5mbyAqKSBqbG9uZ190b19wdHIocFNjYWxlcik7CgogICAgam9iamVjdCBncCA9IGdldEdseXBoR2VuZXJhbFBhdGgoZW52LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9udDJELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjYWxlckluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnbHlwaENvZGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4cG9zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeXBvcyk7CiAgICBpZiAoZ3AgPT0gTlVMTCkgeyAvKiBjYW4gYmUgbGVnYWwgKi8KICAgICAgICBncCA9ICgqZW52KS0+TmV3T2JqZWN0KGVudiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1bkZvbnRJRHMuZ3BDbGFzcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1bkZvbnRJRHMuZ3BDdHJFbXB0eSk7CiAgICB9CiAgICByZXR1cm4gZ3A7Cn0KCi8qCiAqIENsYXNzOiAgICAgc3VuX2ZvbnRfRnJlZXR5cGVGb250U2NhbGVyCiAqIE1ldGhvZDogICAgZ2V0R2x5cGhPdXRsaW5lQm91bmRzTmF0aXZlCiAqIFNpZ25hdHVyZTogKExzdW4vZm9udC9Gb250MkQ7SkkpTGphdmEvYXd0L2dlb20vUmVjdGFuZ2xlMkQvRmxvYXQ7CiAqLwpKTklFWFBPUlQgam9iamVjdCBKTklDQUxMCkphdmFfc3VuX2ZvbnRfRnJlZXR5cGVGb250U2NhbGVyX2dldEdseXBoT3V0bGluZUJvdW5kc05hdGl2ZSgKICAgICAgICBKTklFbnYgKmVudiwgam9iamVjdCBzY2FsZXIsIGpvYmplY3QgZm9udDJELAogICAgICAgIGpsb25nIHBTY2FsZXJDb250ZXh0LCBqbG9uZyBwU2NhbGVyLCBqaW50IGdseXBoQ29kZSkgewoKICAgIEZUX091dGxpbmUgKm91dGxpbmU7CiAgICBGVF9CQm94IGJib3g7CiAgICBpbnQgZXJyb3I7CiAgICBqb2JqZWN0IGJvdW5kczsKCiAgICBGVFNjYWxlckNvbnRleHQgKmNvbnRleHQgPQogICAgICAgICAoRlRTY2FsZXJDb250ZXh0KikgamxvbmdfdG9fcHRyKHBTY2FsZXJDb250ZXh0KTsKICAgIEZUU2NhbGVySW5mbyogc2NhbGVySW5mbyA9IChGVFNjYWxlckluZm8gKikgamxvbmdfdG9fcHRyKHBTY2FsZXIpOwoKICAgIG91dGxpbmUgPSBnZXRGVE91dGxpbmUoZW52LCBmb250MkQsIGNvbnRleHQsIHNjYWxlckluZm8sIGdseXBoQ29kZSwgMCwgMCk7CiAgICBpZiAob3V0bGluZSA9PSBOVUxMIHx8IG91dGxpbmUtPm5fcG9pbnRzID09IDApIHsKICAgICAgICAvKiBpdCBpcyBsZWdhbCBjYXNlLCBlLmcuIGludmlzaWJsZSBnbHlwaCAqLwogICAgICAgIGJvdW5kcyA9ICgqZW52KS0+TmV3T2JqZWN0KGVudiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VuRm9udElEcy5yZWN0MkRGbG9hdENsYXNzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdW5Gb250SURzLnJlY3QyREZsb2F0Q3RyKTsKICAgICAgICByZXR1cm4gYm91bmRzOwogICAgfQoKICAgIGVycm9yID0gRlRfT3V0bGluZV9HZXRfQkJveChvdXRsaW5lLCAmYmJveCk7CgogICAgLy9jb252ZXJ0IGJib3gKICAgIGlmIChlcnJvciB8fCBiYm94LnhNaW4gPj0gYmJveC54TWF4IHx8IGJib3gueU1pbiA+PSBiYm94LnlNYXgpIHsKICAgICAgICBib3VuZHMgPSAoKmVudiktPk5ld09iamVjdChlbnYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VuRm9udElEcy5yZWN0MkRGbG9hdENsYXNzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1bkZvbnRJRHMucmVjdDJERmxvYXRDdHIpOwogICAgfSBlbHNlIHsKICAgICAgICBib3VuZHMgPSAoKmVudiktPk5ld09iamVjdChlbnYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VuRm9udElEcy5yZWN0MkRGbG9hdENsYXNzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1bkZvbnRJRHMucmVjdDJERmxvYXRDdHI0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEYyNkRvdDZUb0Zsb2F0KGJib3gueE1pbiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRjI2RG90NlRvRmxvYXQoYmJveC55TWF4KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGMjZEb3Q2VG9GbG9hdChiYm94LnhNYXgtYmJveC54TWluKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGMjZEb3Q2VG9GbG9hdChiYm94LnlNYXgtYmJveC55TWluKSk7CiAgICB9CgogICAgcmV0dXJuIGJvdW5kczsKfQoKLyoKICogQ2xhc3M6ICAgICBzdW5fZm9udF9GcmVldHlwZUZvbnRTY2FsZXIKICogTWV0aG9kOiAgICBnZXRHbHlwaFZlY3Rvck91dGxpbmVOYXRpdmUKICogU2lnbmF0dXJlOiAoTHN1bi9mb250L0ZvbnQyRDtKW0lJRkYpTGphdmEvYXd0L2dlb20vR2VuZXJhbFBhdGg7CiAqLwpKTklFWFBPUlQgam9iamVjdApKTklDQUxMCkphdmFfc3VuX2ZvbnRfRnJlZXR5cGVGb250U2NhbGVyX2dldEdseXBoVmVjdG9yT3V0bGluZU5hdGl2ZSgKICAgICAgICBKTklFbnYgKmVudiwgam9iamVjdCBzY2FsZXIsIGpvYmplY3QgZm9udDJELAogICAgICAgIGpsb25nIHBTY2FsZXJDb250ZXh0LCBqbG9uZyBwU2NhbGVyLAogICAgICAgIGppbnRBcnJheSBnbHlwaEFycmF5LCBqaW50IG51bUdseXBocywgamZsb2F0IHhwb3MsIGpmbG9hdCB5cG9zKSB7CgogICAgRlRfT3V0bGluZSogb3V0bGluZTsKICAgIGpvYmplY3QgZ3AgPSBOVUxMOwogICAgamJ5dGVBcnJheSB0eXBlczsKICAgIGpmbG9hdEFycmF5IGNvb3JkczsKICAgIEdQRGF0YSBncGRhdGE7CiAgICBpbnQgaTsKICAgIGppbnQgKmdseXBoczsKCiAgICBGVFNjYWxlckNvbnRleHQgKmNvbnRleHQgPQogICAgICAgICAoRlRTY2FsZXJDb250ZXh0KikgamxvbmdfdG9fcHRyKHBTY2FsZXJDb250ZXh0KTsKICAgIEZUU2NhbGVySW5mbyAqc2NhbGVySW5mbyA9CiAgICAgICAgICAgICAoRlRTY2FsZXJJbmZvKikgamxvbmdfdG9fcHRyKHBTY2FsZXIpOwoKICAgIGdseXBocyA9IChqaW50KikgbWFsbG9jKG51bUdseXBocypzaXplb2YoamludCkpOwogICAgaWYgKGdseXBocyA9PSBOVUxMKSB7CiAgICAgICAgZ3AgPSAoKmVudiktPk5ld09iamVjdChlbnYsIHN1bkZvbnRJRHMuZ3BDbGFzcywgc3VuRm9udElEcy5ncEN0ckVtcHR5KTsKICAgICAgICBpZiAoIWlzTnVsbFNjYWxlckNvbnRleHQoY29udGV4dCkgJiYgc2NhbGVySW5mbyAhPSBOVUxMKSB7CiAgICAgICAgICAgIGludmFsaWRhdGVKYXZhU2NhbGVyKGVudiwgc2NhbGVyLCBzY2FsZXJJbmZvKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGdwOwogICAgfQoKICAgICgqZW52KS0+R2V0SW50QXJyYXlSZWdpb24oZW52LCBnbHlwaEFycmF5LCAwLCBudW1HbHlwaHMsIGdseXBocyk7CgogICAgZm9yIChpPTA7IGk8bnVtR2x5cGhzO2krKykgewogICAgICAgIGlmIChnbHlwaHNbaV0gPj0gSU5WSVNJQkxFX0dMWVBIUykgewogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgb3V0bGluZSA9IGdldEZUT3V0bGluZShlbnYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb250MkQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NhbGVySW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdseXBoc1tpXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhwb3MsIHlwb3MpOwoKICAgICAgICBpZiAob3V0bGluZSA9PSBOVUxMIHx8IG91dGxpbmUtPm5fcG9pbnRzID09IDApIHsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQoKICAgICAgICBncGRhdGEucG9pbnRUeXBlcyAgPSBOVUxMOwogICAgICAgIGdwZGF0YS5wb2ludENvb3JkcyA9IE5VTEw7CiAgICAgICAgaWYgKCFhbGxvY2F0ZVNwYWNlRm9yR1AoJmdwZGF0YSwgb3V0bGluZS0+bl9wb2ludHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3V0bGluZS0+bl9jb250b3VycykpIHsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICBhZGRUb0dQKCZncGRhdGEsIG91dGxpbmUpOwogICAgfQogICAgZnJlZShnbHlwaHMpOwoKICAgIGlmIChncGRhdGEubnVtQ29vcmRzICE9IDApIHsKICAgICAgdHlwZXMgPSAoKmVudiktPk5ld0J5dGVBcnJheShlbnYsIGdwZGF0YS5udW1UeXBlcyk7CiAgICAgIGNvb3JkcyA9ICgqZW52KS0+TmV3RmxvYXRBcnJheShlbnYsIGdwZGF0YS5udW1Db29yZHMpOwoKICAgICAgaWYgKHR5cGVzICYmIGNvb3JkcykgewogICAgICAgICgqZW52KS0+U2V0Qnl0ZUFycmF5UmVnaW9uKGVudiwgdHlwZXMsIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3BkYXRhLm51bVR5cGVzLCBncGRhdGEucG9pbnRUeXBlcyk7CiAgICAgICAgKCplbnYpLT5TZXRGbG9hdEFycmF5UmVnaW9uKGVudiwgY29vcmRzLCAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncGRhdGEubnVtQ29vcmRzLCBncGRhdGEucG9pbnRDb29yZHMpOwoKICAgICAgICBncD0oKmVudiktPk5ld09iamVjdChlbnYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VuRm9udElEcy5ncENsYXNzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1bkZvbnRJRHMuZ3BDdHIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3BkYXRhLndyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdwZGF0YS5udW1UeXBlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb29yZHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3BkYXRhLm51bUNvb3Jkcyk7CiAgICAgICAgcmV0dXJuIGdwOwogICAgICB9CiAgICB9CiAgICByZXR1cm4gKCplbnYpLT5OZXdPYmplY3QoZW52LCBzdW5Gb250SURzLmdwQ2xhc3MsIHN1bkZvbnRJRHMuZ3BDdHJFbXB0eSk7Cn0KCkpOSUVYUE9SVCBqbG9uZyBKTklDQUxMCkphdmFfc3VuX2ZvbnRfRnJlZXR5cGVGb250U2NhbGVyX2dldFVuaXRzUGVyRU1OYXRpdmUoCiAgICAgICAgSk5JRW52ICplbnYsIGpvYmplY3Qgc2NhbGVyLCBqbG9uZyBwU2NhbGVyKSB7CgogICAgRlRTY2FsZXJJbmZvICpzID0gKEZUU2NhbGVySW5mbyogKSBqbG9uZ190b19wdHIocFNjYWxlcik7CgogICAgLyogRnJlZXR5cGUgZG9jIHNheXM6CiAgICAgVGhlIG51bWJlciBvZiBmb250IHVuaXRzIHBlciBFTSBzcXVhcmUgZm9yIHRoaXMgZmFjZS4KICAgICBUaGlzIGlzIHR5cGljYWxseSAyMDQ4IGZvciBUcnVlVHlwZSBmb250cywgYW5kIDEwMDAgZm9yIFR5cGUgMSBmb250cy4KICAgICBPbmx5IHJlbGV2YW50IGZvciBzY2FsYWJsZSBmb3JtYXRzLgogICAgIEhvd2V2ZXIsIGxheW91dCBlbmdpbmUgbWlnaHQgYmUgbm90IHRlc3RlZCB3aXRoIGFueXRoaW5nIGJ1dCAyMDQ4LgoKICAgICBOQjogdGVzdCBpdCEgKi8KICAgIGlmIChzICE9IE5VTEwpIHsKICAgICAgICByZXR1cm4gcy0+ZmFjZS0+dW5pdHNfcGVyX0VNOwogICAgfQogICAgcmV0dXJuIDIwNDg7Cn0KCi8qIFRoaXMgbmF0aXZlIG1ldGhvZCBpcyBjYWxsZWQgYnkgdGhlIE9wZW5UeXBlIGxheW91dCBlbmdpbmUuICovCkpOSUVYUE9SVCBqb2JqZWN0IEpOSUNBTEwKSmF2YV9zdW5fZm9udF9GcmVldHlwZUZvbnRTY2FsZXJfZ2V0R2x5cGhQb2ludE5hdGl2ZSgKICAgICAgICBKTklFbnYgKmVudiwgam9iamVjdCBzY2FsZXIsIGpvYmplY3QgZm9udDJELCBqbG9uZyBwU2NhbGVyQ29udGV4dCwKICAgICAgICBqbG9uZyBwU2NhbGVyLCBqaW50IGdseXBoQ29kZSwgamludCBwb2ludE51bWJlcikgewoKICAgIEZUX091dGxpbmUqIG91dGxpbmU7CiAgICBqb2JqZWN0IHBvaW50ID0gTlVMTDsKICAgIGpmbG9hdCB4PTAsIHk9MDsKICAgIEZUU2NhbGVyQ29udGV4dCAqY29udGV4dCA9CiAgICAgICAgIChGVFNjYWxlckNvbnRleHQqKSBqbG9uZ190b19wdHIocFNjYWxlckNvbnRleHQpOwogICAgRlRTY2FsZXJJbmZvICpzY2FsZXJJbmZvID0gKEZUU2NhbGVySW5mbyopIGpsb25nX3RvX3B0cihwU2NhbGVyKTsKCiAgICBvdXRsaW5lID0gZ2V0RlRPdXRsaW5lKGVudiwgZm9udDJELCBjb250ZXh0LCBzY2FsZXJJbmZvLCBnbHlwaENvZGUsIDAsIDApOwoKICAgIGlmIChvdXRsaW5lICE9IE5VTEwgJiYgb3V0bGluZS0+bl9wb2ludHMgPiBwb2ludE51bWJlcikgewogICAgICAgIHggPSAgRjI2RG90NlRvRmxvYXQob3V0bGluZS0+cG9pbnRzW3BvaW50TnVtYmVyXS54KTsKICAgICAgICB5ID0gLUYyNkRvdDZUb0Zsb2F0KG91dGxpbmUtPnBvaW50c1twb2ludE51bWJlcl0ueSk7CiAgICB9CgogICAgcmV0dXJuICgqZW52KS0+TmV3T2JqZWN0KGVudiwgc3VuRm9udElEcy5wdDJERmxvYXRDbGFzcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdW5Gb250SURzLnB0MkRGbG9hdEN0ciwgeCwgeSk7Cn0K