LyoKICogMkQgU3VyZmFjZSBpbXBsZW1lbnRhdGlvbiB3aXRob3V0IE9wZW5HTAogKgogKiBDb3B5cmlnaHQgMTk5Ny0yMDAwIE1hcmN1cyBNZWlzc25lcgogKiBDb3B5cmlnaHQgMTk5OC0yMDAwIExpb25lbCBVbG1lcgogKiBDb3B5cmlnaHQgMjAwMC0yMDAxIFRyYW5zR2FtaW5nIFRlY2hub2xvZ2llcyBJbmMuCiAqIENvcHlyaWdodCAyMDAyLTIwMDUgSmFzb24gRWRtZWFkZXMKICogQ29weXJpZ2h0IDIwMDItMjAwMyBSYXBoYWVsIEp1bnF1ZWlyYQogKiBDb3B5cmlnaHQgMjAwNCBDaHJpc3RpYW4gQ29zdGEKICogQ29weXJpZ2h0IDIwMDUgT2xpdmVyIFN0aWViZXIKICogQ29weXJpZ2h0IDIwMDYgU3RlZmFuIET2c2luZ2VyCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQQogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKI2luY2x1ZGUgIndpbmUvcG9ydC5oIgojaW5jbHVkZSAid2luZWQzZF9wcml2YXRlLmgiCgojaW5jbHVkZSA8YXNzZXJ0Lmg+CiNpbmNsdWRlIDxzdGRpby5oPgoKLyogVXNlIHRoZSBkM2Rfc3VyZmFjZSBkZWJ1ZyBjaGFubmVsIHRvIGhhdmUgb25lIGNoYW5uZWwgZm9yIGFsbCBzdXJmYWNlcyAqLwpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChkM2Rfc3VyZmFjZSk7CldJTkVfREVDTEFSRV9ERUJVR19DSEFOTkVMKGZwcyk7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogeDExX2NvcHlfdG9fc2NyZWVuCiAqCiAqIEhlbHBlciBmdW5jdGlvbiB0aGF0IGJsdHMgdGhlIGZyb250IGJ1ZmZlciBjb250ZW50cyB0byB0aGUgdGFyZ2V0IHdpbmRvdwogKgogKiBQYXJhbXM6CiAqICBUaGlzOiBTdXJmYWNlIHRvIGNvcHkgZnJvbQogKiAgcmM6IFJlY3RhbmdsZSB0byBjb3B5CiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIHZvaWQKeDExX2NvcHlfdG9fc2NyZWVuKElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMsCiAgICAgICAgICAgICAgICAgICBMUFJFQ1QgcmMpCnsKICAgIGlmKFRoaXMtPnJlc291cmNlLnVzYWdlICYgV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVCkKICAgIHsKICAgICAgICBQT0lOVCBvZmZzZXQgPSB7MCwwfTsKICAgICAgICBIV05EIGhEaXNwbGF5V25kOwogICAgICAgIEhEQyBoRGlzcGxheURDOwogICAgICAgIEhEQyBoU3VyZmFjZURDID0gMDsKICAgICAgICBSRUNUIGRyYXdyZWN0OwogICAgICAgIFRSQUNFKCIoJXApLT4oJXApOiBDb3B5aW5nIHRvIHNjcmVlblxuIiwgVGhpcywgcmMpOwoKICAgICAgICBoU3VyZmFjZURDID0gVGhpcy0+aERDOwoKICAgICAgICBoRGlzcGxheVduZCA9IFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2UtPmRkcmF3X3dpbmRvdzsKICAgICAgICBoRGlzcGxheURDID0gR2V0RENFeChoRGlzcGxheVduZCwgMCwgRENYX0NMSVBTSUJMSU5HU3xEQ1hfQ0FDSEUpOwogICAgICAgIGlmKHJjKQogICAgICAgIHsKICAgICAgICAgICAgVFJBQ0UoIiBjb3B5aW5nIHJlY3QgKCVkLCVkKS0+KCVkLCVkKSwgb2Zmc2V0ICglZCwlZClcbiIsCiAgICAgICAgICAgIHJjLT5sZWZ0LCByYy0+dG9wLCByYy0+cmlnaHQsIHJjLT5ib3R0b20sIG9mZnNldC54LCBvZmZzZXQueSk7CiAgICAgICAgfQoKICAgICAgICAvKiBGcm9udCBidWZmZXIgY29vcmRpbmF0ZXMgYXJlIHNjcmVlbiBjb29yZGluYXRlcy4gTWFwIHRoZW0gdG8gdGhlIGRlc3RpbmF0aW9uCiAgICAgICAgICogd2luZG93IGlmIG5vdCBmdWxsc2NyZWVuZWQKICAgICAgICAgKi8KICAgICAgICBpZighVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZS0+ZGRyYXdfZnVsbHNjcmVlbikgewogICAgICAgICAgICBDbGllbnRUb1NjcmVlbihoRGlzcGxheVduZCwgJm9mZnNldCk7CiAgICAgICAgfQojaWYgMAogICAgICAgIC8qIEZJWE1FOiB0aGlzIGRvZXNuJ3Qgd29yay4uLiBpZiB1c2VycyByZWFsbHkgd2FudCB0byBydW4KICAgICAgICAqIFggaW4gOGJwcCwgdGhlbiB3ZSBuZWVkIHRvIGNhbGwgZGlyZWN0bHkgaW50byBkaXNwbGF5LmRydgogICAgICAgICogKG9yIFdpbmUncyBlcXVpdmFsZW50KSwgYW5kIGZvcmNlIGEgcHJpdmF0ZSBjb2xvcm1hcAogICAgICAgICogd2l0aG91dCBkZWZhdWx0IGVudHJpZXMuICovCiAgICAgICAgaWYgKFRoaXMtPnBhbGV0dGUpIHsKICAgICAgICAgICAgU2VsZWN0UGFsZXR0ZShoRGlzcGxheURDLCBUaGlzLT5wYWxldHRlLT5ocGFsLCBGQUxTRSk7CiAgICAgICAgICAgIFJlYWxpemVQYWxldHRlKGhEaXNwbGF5REMpOyAvKiBzZW5kcyBtZXNzYWdlcyA9PiBkZWFkbG9ja3MgKi8KICAgICAgICB9CiNlbmRpZgogICAgICAgIGRyYXdyZWN0LmxlZnQJPSAwOwogICAgICAgIGRyYXdyZWN0LnJpZ2h0CT0gVGhpcy0+Y3VycmVudERlc2MuV2lkdGg7CiAgICAgICAgZHJhd3JlY3QudG9wCT0gMDsKICAgICAgICBkcmF3cmVjdC5ib3R0b20JPSBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQ7CgojaWYgMAogICAgICAgIC8qIFRPRE86IFN1cHBvcnQgY2xpcHBlcnMgKi8KICAgICAgICBpZiAoVGhpcy0+Y2xpcHBlcikKICAgICAgICB7CiAgICAgICAgICAgIFJFQ1QgeHJjOwogICAgICAgICAgICBIV05EIGh3bmQgPSAoKElXaW5lRDNEQ2xpcHBlckltcGwgKikgVGhpcy0+Y2xpcHBlciktPmhXbmQ7CiAgICAgICAgICAgIGlmIChod25kICYmIEdldENsaWVudFJlY3QoaHduZCwmeHJjKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgT2Zmc2V0UmVjdCgmeHJjLG9mZnNldC54LG9mZnNldC55KTsKICAgICAgICAgICAgICAgIEludGVyc2VjdFJlY3QoJmRyYXdyZWN0LCZkcmF3cmVjdCwmeHJjKTsKICAgICAgICAgICAgfQogICAgICAgIH0KI2VuZGlmCiAgICAgICAgaWYgKHJjKQogICAgICAgIHsKICAgICAgICAgICAgSW50ZXJzZWN0UmVjdCgmZHJhd3JlY3QsJmRyYXdyZWN0LHJjKTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgLyogT25seSB1c2UgdGhpcyBpZiB0aGUgY2FsbGVyIGRpZCBub3QgcGFzcyBhIHJlY3RhbmdsZSwgc2luY2UKICAgICAgICAgICAgICogZHVlIHRvIGRvdWJsZSBsb2NraW5nIHRoaXMgY291bGQgYmUgdGhlIHdyb25nIG9uZSAuLi4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmIChUaGlzLT5sb2NrZWRSZWN0LmxlZnQgIT0gVGhpcy0+bG9ja2VkUmVjdC5yaWdodCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgSW50ZXJzZWN0UmVjdCgmZHJhd3JlY3QsJmRyYXdyZWN0LCZUaGlzLT5sb2NrZWRSZWN0KTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQml0Qmx0KGhEaXNwbGF5REMsCiAgICAgICAgICAgICAgIGRyYXdyZWN0LmxlZnQtb2Zmc2V0LngsIGRyYXdyZWN0LnRvcC1vZmZzZXQueSwKICAgICAgICAgICAgICAgZHJhd3JlY3QucmlnaHQtZHJhd3JlY3QubGVmdCwgZHJhd3JlY3QuYm90dG9tLWRyYXdyZWN0LnRvcCwKICAgICAgICAgICAgICAgaFN1cmZhY2VEQywKICAgICAgICAgICAgICAgZHJhd3JlY3QubGVmdCwgZHJhd3JlY3QudG9wLAogICAgICAgICAgICAgICBTUkNDT1BZKTsKICAgICAgICBSZWxlYXNlREMoaERpc3BsYXlXbmQsIGhEaXNwbGF5REMpOwogICAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSVdpbmVEM0RTdXJmYWNlOjpQcmVMb2FkLCBHREkgdmVyc2lvbgogKgogKiBUaGlzIGNhbGwgaXMgdW5zdXBwb3J0ZWQgb24gR0RJIHN1cmZhY2VzLCBpZiBpdCdzIGNhbGxlZCBzb21ldGhpbmcgd2VudAogKiB3cm9uZyBpbiB0aGUgcGFyZW50IGxpYnJhcnkuIFdyaXRlIGFuIGluZm9ybWF0aXZlIHdhcm5pbmcKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgdm9pZCBXSU5BUEkKSVdpbmVHRElTdXJmYWNlSW1wbF9QcmVMb2FkKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UpCnsKICAgIEVSUigiKCVwKTogUHJlTG9hZCBpcyBub3Qgc3VwcG9ydGVkIG9uIFgxMSBzdXJmYWNlcyFcbiIsIGlmYWNlKTsKICAgIEVSUigiKCVwKTogTW9zdCBsaWtlbHkgdGhlIHBhcmVudCBsaWJyYXJ5IGRpZCBzb21ldGhpbmcgd3JvbmcuXG4iLCBpZmFjZSk7CiAgICBFUlIoIiglcCk6IFBsZWFzZSByZXBvcnQgdG8gd2luZS1kZXZlbFxuIiwgaWZhY2UpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSVdpbmVEM0RTdXJmYWNlOjpMb2NrUmVjdCwgR0RJIHZlcnNpb24KICoKICogTG9ja3MgdGhlIHN1cmZhY2UgYW5kIHJldHVybnMgYSBwb2ludGVyIHRvIHRoZSBzdXJmYWNlIG1lbW9yeQogKgogKiBQYXJhbXM6CiAqICBwTG9ja2VkUmVjdDogQWRkcmVzcyB0byByZXR1cm4gdGhlIGxvY2tpbmcgaW5mbyBhdAogKiAgcFJlY3Q6IFJlY3RhbmdsZSB0byBsb2NrCiAqICBGbGFnczogU29tZSBmbGFncwogKgogKiBSZXR1cm5zOgogKiAgV0lORUQzRF9PSyBvbiBzdWNjZXNzCiAqICBXSU5FRDNERVJSX0lOVkFMSURDQUxMIG9uIGVycm9ycwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJV2luZUdESVN1cmZhY2VJbXBsX0xvY2tSZWN0KElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzRExPQ0tFRF9SRUNUKiBwTG9ja2VkUmVjdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDT05TVCBSRUNUKiBwUmVjdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncykKewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CgogICAgLyogQWxyZWFkeSBsb2NrZWQ/ICovCiAgICBpZihUaGlzLT5GbGFncyAmIFNGTEFHX0xPQ0tFRCkKICAgIHsKICAgICAgICBFUlIoIiglcCkgU3VyZmFjZSBhbHJlYWR5IGxvY2tlZFxuIiwgVGhpcyk7CiAgICAgICAgLyogV2hhdCBzaG91bGQgSSByZXR1cm4gaGVyZT8gKi8KICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICBpZiAoIShUaGlzLT5GbGFncyAmIFNGTEFHX0xPQ0tBQkxFKSkKICAgIHsKICAgICAgICAvKiBUaGlzIGlzIHNvbWUgR0wgc3BlY2lmaWMgdGhpbmcsIHNlZSB0aGUgT3BlbkdMIHZlcnNpb24gb2YKICAgICAgICAgKiB0aGlzIG1ldGhvZCwgYnV0IGNoZWNrIGZvciB0aGUgZmxhZyBhbmQgd3JpdGUgYSB0cmFjZQogICAgICAgICAqLwogICAgICAgIFRSQUNFKCJXYXJuaW5nOiB0cnlpbmcgdG8gbG9jayB1bmxvY2thYmxlIHN1cmZAJXBcbiIsIFRoaXMpOwogICAgfQoKICAgIFRSQUNFKCIoJXApIDogcmVjdEAlcCBmbGFncyglMDh4KSwgb3V0cHV0IGxvY2tlZFJlY3RAJXAsIG1lbW9yeUAlcFxuIiwKICAgICAgICAgIFRoaXMsIHBSZWN0LCBGbGFncywgcExvY2tlZFJlY3QsIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSk7CgogICAgaWYoIVRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSkgewogICAgICAgIEhEQyBoZGM7CiAgICAgICAgSFJFU1VMVCBocjsKICAgICAgICAvKiBUaGlzIGhhcHBlbnMgb24gZ2RpIHN1cmZhY2VzIGlmIHRoZSBhcHBsaWNhdGlvbiBzZXQgYSB1c2VyIHBvaW50ZXIgYW5kIHJlc2V0cyBpdC4KICAgICAgICAgKiBSZWNyZWF0ZSB0aGUgRElCIHNlY3Rpb24KICAgICAgICAgKi8KICAgICAgICBociA9IElXaW5lRDNEU3VyZmFjZV9HZXREQyhpZmFjZSwgJmhkYyk7ICAvKiB3aWxsIHJlY3Vyc2l2ZWx5IGNhbGwgbG9ja3JlY3QsIGRvIG5vdCBzZXQgdGhlIExPQ0tFRCBmbGFnIHRvIHRoaXMgbGluZSAqLwogICAgICAgIGlmKGhyICE9IFdJTkVEM0RfT0spIHJldHVybiBocjsKICAgICAgICBociA9IElXaW5lRDNEU3VyZmFjZV9SZWxlYXNlREMoaWZhY2UsIGhkYyk7CiAgICAgICAgaWYoaHIgIT0gV0lORUQzRF9PSykgcmV0dXJuIGhyOwogICAgfQoKICAgIHBMb2NrZWRSZWN0LT5QaXRjaCA9IElXaW5lRDNEU3VyZmFjZV9HZXRQaXRjaChpZmFjZSk7CgogICAgaWYgKE5VTEwgPT0gcFJlY3QpCiAgICB7CiAgICAgICAgcExvY2tlZFJlY3QtPnBCaXRzID0gVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5OwogICAgICAgIFRoaXMtPmxvY2tlZFJlY3QubGVmdCAgID0gMDsKICAgICAgICBUaGlzLT5sb2NrZWRSZWN0LnRvcCAgICA9IDA7CiAgICAgICAgVGhpcy0+bG9ja2VkUmVjdC5yaWdodCAgPSBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aDsKICAgICAgICBUaGlzLT5sb2NrZWRSZWN0LmJvdHRvbSA9IFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodDsKCiAgICAgICAgVFJBQ0UoIkxvY2tlZCBSZWN0ICglcCkgPSBsICVkLCB0ICVkLCByICVkLCBiICVkXG4iLAogICAgICAgICZUaGlzLT5sb2NrZWRSZWN0LCBUaGlzLT5sb2NrZWRSZWN0LmxlZnQsIFRoaXMtPmxvY2tlZFJlY3QudG9wLAogICAgICAgIFRoaXMtPmxvY2tlZFJlY3QucmlnaHQsIFRoaXMtPmxvY2tlZFJlY3QuYm90dG9tKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBUUkFDRSgiTG9jayBSZWN0ICglcCkgPSBsICVkLCB0ICVkLCByICVkLCBiICVkXG4iLAogICAgICAgICAgICAgIHBSZWN0LCBwUmVjdC0+bGVmdCwgcFJlY3QtPnRvcCwgcFJlY3QtPnJpZ2h0LCBwUmVjdC0+Ym90dG9tKTsKCiAgICAgICAgaWYgKFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDEpCiAgICAgICAgewogICAgICAgICAgICAvKiBEWFQxIGlzIGhhbGYgYnl0ZSBwZXIgcGl4ZWwgKi8KICAgICAgICAgICAgcExvY2tlZFJlY3QtPnBCaXRzID0gVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChwTG9ja2VkUmVjdC0+UGl0Y2ggKiBwUmVjdC0+dG9wKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKHBSZWN0LT5sZWZ0ICogVGhpcy0+Ynl0ZXNQZXJQaXhlbCAvIDIpKTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgcExvY2tlZFJlY3QtPnBCaXRzID0gVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHBMb2NrZWRSZWN0LT5QaXRjaCAqIHBSZWN0LT50b3ApICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHBSZWN0LT5sZWZ0ICogVGhpcy0+Ynl0ZXNQZXJQaXhlbCk7CiAgICAgICAgfQogICAgICAgIFRoaXMtPmxvY2tlZFJlY3QubGVmdCAgID0gcFJlY3QtPmxlZnQ7CiAgICAgICAgVGhpcy0+bG9ja2VkUmVjdC50b3AgICAgPSBwUmVjdC0+dG9wOwogICAgICAgIFRoaXMtPmxvY2tlZFJlY3QucmlnaHQgID0gcFJlY3QtPnJpZ2h0OwogICAgICAgIFRoaXMtPmxvY2tlZFJlY3QuYm90dG9tID0gcFJlY3QtPmJvdHRvbTsKICAgIH0KCiAgICAvKiBObyBkaXJ0aWZ5aW5nIGlzIG5lZWRlZCBmb3IgdGhpcyBzdXJmYWNlIGltcGxlbWVudGF0aW9uICovCiAgICBUUkFDRSgicmV0dXJuaW5nIG1lbW9yeUAlcCwgcGl0Y2goJWQpXG4iLCBwTG9ja2VkUmVjdC0+cEJpdHMsIHBMb2NrZWRSZWN0LT5QaXRjaCk7CgogICAgVGhpcy0+RmxhZ3MgfD0gU0ZMQUdfTE9DS0VEOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJV2luZUQzRFN1cmZhY2U6OlVubG9ja1JlY3QsIEdESSB2ZXJzaW9uCiAqCiAqIFVubG9ja3MgYSBzdXJmYWNlLiBUaGlzIGltcGxlbWVudGF0aW9uIGRvZXNuJ3QgZG8gbXVjaCwgZXhjZXB0IHVwZGF0aW5nCiAqIHRoZSB3aW5kb3cgaWYgdGhlIGZyb250IGJ1ZmZlciBpcyB1bmxvY2tlZAogKgogKiBSZXR1cm5zOgogKiAgV0lORUQzRF9PSyBvbiBzdWNjZXNzCiAqICBXSU5FRDNERVJSX0lOVkFMSURDQUxMIG9uIGZhaWx1cmUKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSVdpbmVHRElTdXJmYWNlSW1wbF9VbmxvY2tSZWN0KElXaW5lRDNEU3VyZmFjZSAqaWZhY2UpCnsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0REZXZpY2VJbXBsICpkZXYgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopIFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2U7CiAgICBUUkFDRSgiKCVwKVxuIiwgVGhpcyk7CgogICAgaWYgKCEoVGhpcy0+RmxhZ3MgJiBTRkxBR19MT0NLRUQpKQogICAgewogICAgICAgIFdBUk4oInRyeWluZyB0byBVbmxvY2sgYW4gdW5sb2NrZWQgc3VyZkAlcFxuIiwgVGhpcyk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgLyogQ2FuIGJlIHVzZWZ1bCBmb3IgZGVidWdnaW5nICovCiNpZiAwCiAgICAgICAgewogICAgICAgICAgICBzdGF0aWMgdW5zaWduZWQgaW50IGdlbiA9IDA7CiAgICAgICAgICAgIGNoYXIgYnVmZmVyWzQwOTZdOwogICAgICAgICAgICArK2dlbjsKICAgICAgICAgICAgaWYgKChnZW4gJSAxMCkgPT0gMCkgewogICAgICAgICAgICAgICAgc25wcmludGYoYnVmZmVyLCBzaXplb2YoYnVmZmVyKSwgIi90bXAvc3VyZmFjZSVwX3R5cGUldV9sZXZlbCV1XyV1LnBwbSIsIFRoaXMsIFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0LCBUaGlzLT5nbERlc2NyaXB0aW9uLmxldmVsLCBnZW4pOwogICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9TYXZlU25hcHNob3QoaWZhY2UsIGJ1ZmZlcik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogZGVidWdnaW5nIGNyYXNoIGNvZGUKICAgICAgICAgICAgaWYgKGdlbiA9PSAyNTApIHsKICAgICAgICAgICAgICB2b2lkKiogdGVzdCA9IE5VTEw7CiAgICAgICAgICAgICAgKnRlc3QgPSAwOwogICAgICAgICAgICB9CiAgICAgICAgICAgICovCiAgICAgICAgfQojZW5kaWYKCiAgICAvKiBVcGRhdGUgdGhlIHNjcmVlbiAqLwogICAgaWYoVGhpcyA9PSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBkZXYtPmRkcmF3X3ByaW1hcnkpCiAgICB7CiAgICAgICAgeDExX2NvcHlfdG9fc2NyZWVuKFRoaXMsICZUaGlzLT5sb2NrZWRSZWN0KTsKICAgIH0KCiAgICBUaGlzLT5GbGFncyAmPSB+U0ZMQUdfTE9DS0VEOwogICAgbWVtc2V0KCZUaGlzLT5sb2NrZWRSZWN0LCAwLCBzaXplb2YoUkVDVCkpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJV2luZUQzRFN1cmZhY2U6OkZsaXAsIEdESSB2ZXJzaW9uCiAqCiAqIEZsaXBzIDIgZmxpcHBpbmcgZW5hYmxlZCBzdXJmYWNlcy4gRGV0ZXJtaW5pbmcgdGhlIDIgdGFyZ2V0cyBpcyBkb25lIGJ5CiAqIHRoZSBwYXJlbnQgbGlicmFyeS4gVGhpcyBpbXBsZW1lbnRhdGlvbiBjaGFuZ2VzIHRoZSBkYXRhIHBvaW50ZXJzIG9mIHRoZQogKiBzdXJmYWNlcyBhbmQgY29waWVzIHRoZSBuZXcgZnJvbnQgYnVmZmVyIGNvbnRlbnQgdG8gdGhlIHNjcmVlbgogKgogKiBQYXJhbXM6CiAqICBvdmVycmlkZTogRmxpcHBpbmcgdGFyZ2V0KGUuZy4gYmFjayBidWZmZXIpCiAqCiAqIFJldHVybnM6CiAqICBXSU5FRDNEX09LIG9uIHN1Y2Nlc3MKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSVdpbmVHRElTdXJmYWNlSW1wbF9GbGlwKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2UgKm92ZXJyaWRlLAogICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MpCnsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBpZmFjZTsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRhcmdldCA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIG92ZXJyaWRlOwogICAgVFJBQ0UoIiglcCktPiglcCwleClcbiIsIFRoaXMsIG92ZXJyaWRlLCBGbGFncyk7CgogICAgVFJBQ0UoIiglcCkgRmxpcHBpbmcgdG8gc3VyZmFjZSAlcFxuIiwgVGhpcywgVGFyZ2V0KTsKCiAgICBpZihUYXJnZXQgPT0gTlVMTCkKICAgIHsKICAgICAgICBFUlIoIiglcCk6IENhbid0IGZsaXAgd2l0aG91dCBhIHRhcmdldFxuIiwgVGhpcyk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgLyogRmxpcCB0aGUgREMgKi8KICAgIHsKICAgICAgICBIREMgdG1wOwogICAgICAgIHRtcCA9IFRoaXMtPmhEQzsKICAgICAgICBUaGlzLT5oREMgPSBUYXJnZXQtPmhEQzsKICAgICAgICBUYXJnZXQtPmhEQyA9IHRtcDsKICAgIH0KCiAgICAvKiBGbGlwIHRoZSBESUJzZWN0aW9uICovCiAgICB7CiAgICAgICAgSEJJVE1BUCB0bXA7CiAgICAgICAgdG1wID0gVGhpcy0+ZGliLkRJQnNlY3Rpb247CiAgICAgICAgVGhpcy0+ZGliLkRJQnNlY3Rpb24gPSBUYXJnZXQtPmRpYi5ESUJzZWN0aW9uOwogICAgICAgIFRhcmdldC0+ZGliLkRJQnNlY3Rpb24gPSB0bXA7CiAgICB9CgogICAgLyogRmxpcCB0aGUgc3VyZmFjZSBkYXRhICovCiAgICB7CiAgICAgICAgdm9pZCogdG1wOwoKICAgICAgICB0bXAgPSBUaGlzLT5kaWIuYml0bWFwX2RhdGE7CiAgICAgICAgVGhpcy0+ZGliLmJpdG1hcF9kYXRhID0gVGFyZ2V0LT5kaWIuYml0bWFwX2RhdGE7CiAgICAgICAgVGFyZ2V0LT5kaWIuYml0bWFwX2RhdGEgPSB0bXA7CgogICAgICAgIHRtcCA9IFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeTsKICAgICAgICBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkgPSBUYXJnZXQtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeTsKICAgICAgICBUYXJnZXQtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSA9IHRtcDsKICAgIH0KCiAgICAvKiBjbGllbnRfbWVtb3J5IHNob3VsZCBub3QgYmUgZGlmZmVyZW50LCBidXQganVzdCBpbiBjYXNlICovCiAgICB7CiAgICAgICAgQk9PTCB0bXA7CiAgICAgICAgdG1wID0gVGhpcy0+ZGliLmNsaWVudF9tZW1vcnk7CiAgICAgICAgVGhpcy0+ZGliLmNsaWVudF9tZW1vcnkgPSBUYXJnZXQtPmRpYi5jbGllbnRfbWVtb3J5OwogICAgICAgIFRhcmdldC0+ZGliLmNsaWVudF9tZW1vcnkgPSB0bXA7CiAgICB9CgogICAgLyogVXNlZnVsIGZvciBkZWJ1Z2dpbmcgKi8KI2lmIDAKICAgICAgICB7CiAgICAgICAgICAgIHN0YXRpYyB1bnNpZ25lZCBpbnQgZ2VuID0gMDsKICAgICAgICAgICAgY2hhciBidWZmZXJbNDA5Nl07CiAgICAgICAgICAgICsrZ2VuOwogICAgICAgICAgICBpZiAoKGdlbiAlIDEwKSA9PSAwKSB7CiAgICAgICAgICAgICAgICBzbnByaW50ZihidWZmZXIsIHNpemVvZihidWZmZXIpLCAiL3RtcC9zdXJmYWNlJXBfdHlwZSV1X2xldmVsJXVfJXUucHBtIiwgVGhpcywgVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQsIFRoaXMtPmdsRGVzY3JpcHRpb24ubGV2ZWwsIGdlbik7CiAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1NhdmVTbmFwc2hvdChpZmFjZSwgYnVmZmVyKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBkZWJ1Z2dpbmcgY3Jhc2ggY29kZQogICAgICAgICAgICBpZiAoZ2VuID09IDI1MCkgewogICAgICAgICAgICAgIHZvaWQqKiB0ZXN0ID0gTlVMTDsKICAgICAgICAgICAgICAqdGVzdCA9IDA7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgKi8KICAgICAgICB9CiNlbmRpZgoKICAgIC8qIFVwZGF0ZSB0aGUgc2NyZWVuICovCiAgICB4MTFfY29weV90b19zY3JlZW4oVGhpcywgTlVMTCk7CgogICAgLyogRlBTIHN1cHBvcnQgKi8KICAgIGlmIChUUkFDRV9PTihmcHMpKQogICAgewogICAgICAgIHN0YXRpYyBsb25nIHByZXZfdGltZSwgZnJhbWVzOwoKICAgICAgICBEV09SRCB0aW1lID0gR2V0VGlja0NvdW50KCk7CiAgICAgICAgZnJhbWVzKys7CiAgICAgICAgLyogZXZlcnkgMS41IHNlY29uZHMgKi8KICAgICAgICBpZiAodGltZSAtIHByZXZfdGltZSA+IDE1MDApIHsKICAgICAgICAgICAgVFJBQ0VfKGZwcykoIkAgYXBwcm94ICUuMmZmcHNcbiIsIDEwMDAuMCpmcmFtZXMvKHRpbWUgLSBwcmV2X3RpbWUpKTsKICAgICAgICAgICAgcHJldl90aW1lID0gdGltZTsKICAgICAgICAgICAgZnJhbWVzID0gMDsKICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfQmx0X0NvbG9yRmlsbAogKgogKiBIZWxwZXIgZnVuY3Rpb24gdGhhdCBmaWxscyBhIG1lbW9yeSBhcmVhIHdpdGggYSBzcGVjaWZpYyBjb2xvcgogKgogKiBQYXJhbXM6CiAqICBidWY6IG1lbW9yeSBhZGRyZXNzIHRvIHN0YXJ0IGZpbGxpbmcgYXQKICogIHdpZHRoLCBoZWlnaHQ6IERpbWVuc2lvbnMgb2YgdGhlIGFyZWEgdG8gZmlsbAogKiAgYnBwOiBCaXQgZGVwdGggb2YgdGhlIHN1cmZhY2UKICogIGxQaXRjaDogcGl0Y2ggb2YgdGhlIHN1cmZhY2UKICogIGNvbG9yOiBDb2xvciB0byBmaWxsIHdpdGgKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVApfQmx0X0NvbG9yRmlsbChCWVRFICpidWYsCiAgICAgICAgICAgICAgIGludCB3aWR0aCwgaW50IGhlaWdodCwKICAgICAgICAgICAgICAgaW50IGJwcCwgTE9ORyBsUGl0Y2gsCiAgICAgICAgICAgICAgIERXT1JEIGNvbG9yKQp7CiAgICBpbnQgeCwgeTsKICAgIExQQllURSBmaXJzdDsKCiAgICAvKiBEbyBmaXJzdCByb3cgKi8KCiNkZWZpbmUgQ09MT1JGSUxMX1JPVyh0eXBlKSBcCnsgXAogICAgdHlwZSAqZCA9ICh0eXBlICopIGJ1ZjsgXAogICAgZm9yICh4ID0gMDsgeCA8IHdpZHRoOyB4KyspIFwKCWRbeF0gPSAodHlwZSkgY29sb3I7IFwKICAgIGJyZWFrOyBcCn0KICAgIHN3aXRjaChicHApCiAgICB7CiAgICAgICAgY2FzZSAxOiBDT0xPUkZJTExfUk9XKEJZVEUpCiAgICAgICAgY2FzZSAyOiBDT0xPUkZJTExfUk9XKFdPUkQpCiAgICAgICAgY2FzZSAzOgogICAgICAgIHsKICAgICAgICAgICAgQllURSAqZCA9IChCWVRFICopIGJ1ZjsKICAgICAgICAgICAgZm9yICh4ID0gMDsgeCA8IHdpZHRoOyB4KyssZCs9MykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZFswXSA9IChjb2xvciAgICApICYgMHhGRjsKICAgICAgICAgICAgICAgIGRbMV0gPSAoY29sb3I+PiA4KSAmIDB4RkY7CiAgICAgICAgICAgICAgICBkWzJdID0gKGNvbG9yPj4xNikgJiAweEZGOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBjYXNlIDQ6IENPTE9SRklMTF9ST1coRFdPUkQpCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgRklYTUUoIkNvbG9yIGZpbGwgbm90IGltcGxlbWVudGVkIGZvciBicHAgJWQhXG4iLCBicHAqOCk7CiAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX05PVEFWQUlMQUJMRTsKICAgIH0KCiN1bmRlZiBDT0xPUkZJTExfUk9XCgogICAgLyogTm93IGNvcHkgZmlyc3Qgcm93ICovCiAgICBmaXJzdCA9IGJ1ZjsKICAgIGZvciAoeSA9IDE7IHkgPCBoZWlnaHQ7IHkrKykKICAgIHsKICAgICAgICBidWYgKz0gbFBpdGNoOwogICAgICAgIG1lbWNweShidWYsIGZpcnN0LCB3aWR0aCAqIGJwcCk7CiAgICB9CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElXaW5lRDNEU3VyZmFjZTo6Qmx0LCBHREkgdmVyc2lvbgogKgogKiBQZXJmb3JtcyBibGl0cyB0byBhIHN1cmZhY2UsIGVpZ2hlciBmcm9tIGEgc291cmNlIG9mIHNvdXJjZS1sZXNzIGJsdHMKICogVGhpcyBpcyB0aGUgbWFpbiBmdW5jdGlvbmFsaXR5IG9mIERpcmVjdERyYXcKICoKICogUGFyYW1zOgogKiAgRGVzdFJlY3Q6IERlc3RpbmF0aW9uIHJlY3RhbmdsZSB0byB3cml0ZSB0bwogKiAgU3JjU3VyZmFjZTogU291cmNlIHN1cmZhY2UsIGNhbiBiZSBOVUxMCiAqICBTcmNSZWN0OiBTb3VyY2UgcmVjdGFuZ2xlCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KSFJFU1VMVCBXSU5BUEkKSVdpbmVHRElTdXJmYWNlSW1wbF9CbHQoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgUkVDVCAqRGVzdFJlY3QsCiAgICAgICAgICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZSAqU3JjU3VyZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgUkVDVCAqU3JjUmVjdCwKICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEREJMVEZYICpEREJsdEZ4LAogICAgICAgICAgICAgICAgICAgICAgICBXSU5FRDNEVEVYVFVSRUZJTFRFUlRZUEUgRmlsdGVyKQp7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgaWZhY2U7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpTcmMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBTcmNTdXJmYWNlOwogICAgUkVDVAkJeGRzdCx4c3JjOwogICAgSFJFU1VMVAkJcmV0ID0gV0lORUQzRF9PSzsKICAgIFdJTkVEM0RMT0NLRURfUkVDVCAgZGxvY2ssIHNsb2NrOwogICAgV0lORUQzREZPUk1BVCAgICAgICBkZm10ID0gV0lORUQzREZNVF9VTktOT1dOLCBzZm10ID0gV0lORUQzREZNVF9VTktOT1dOOwogICAgaW50IGJwcCwgc3JjaGVpZ2h0LCBzcmN3aWR0aCwgZHN0aGVpZ2h0LCBkc3R3aWR0aCwgd2lkdGg7CiAgICBpbnQgeCwgeTsKICAgIGNvbnN0IFBpeGVsRm9ybWF0RGVzYyAqc0VudHJ5LCAqZEVudHJ5OwogICAgTFBCWVRFIGRidWYsIHNidWY7CiAgICBUUkFDRSgiKCVwKS0+KCVwLCVwLCVwLCV4LCVwKVxuIiwgVGhpcywgRGVzdFJlY3QsIFNyYywgU3JjUmVjdCwgRmxhZ3MsIEREQmx0RngpOwoKICAgIGlmIChUUkFDRV9PTihkM2Rfc3VyZmFjZSkpCiAgICB7CiAgICAgICAgaWYgKERlc3RSZWN0KSBUUkFDRSgiXHRkZXN0cmVjdCA6JWR4JWQtJWR4JWRcbiIsCiAgICAgICAgRGVzdFJlY3QtPmxlZnQsIERlc3RSZWN0LT50b3AsIERlc3RSZWN0LT5yaWdodCwgRGVzdFJlY3QtPmJvdHRvbSk7CiAgICAgICAgaWYgKFNyY1JlY3QpIFRSQUNFKCJcdHNyY3JlY3QgIDolZHglZC0lZHglZFxuIiwKICAgICAgICBTcmNSZWN0LT5sZWZ0LCBTcmNSZWN0LT50b3AsIFNyY1JlY3QtPnJpZ2h0LCBTcmNSZWN0LT5ib3R0b20pOwojaWYgMAogICAgICAgIFRSQUNFKCJcdGZsYWdzOiAiKTsKICAgICAgICBERFJBV19kdW1wX0REQkxUKEZsYWdzKTsKICAgICAgICBpZiAoRmxhZ3MgJiBXSU5FRERCTFRfRERGWCkKICAgICAgICB7CiAgICAgICAgICAgIFRSQUNFKCJcdGJsaXRmeDogIik7CiAgICAgICAgICAgIEREUkFXX2R1bXBfRERCTFRGWChEREJsdEZ4LT5kd0RERlgpOwogICAgICAgIH0KI2VuZGlmCiAgICB9CgogICAgaWYgKCAoVGhpcy0+RmxhZ3MgJiBTRkxBR19MT0NLRUQpIHx8ICgoU3JjICE9IE5VTEwpICYmIChTcmMtPkZsYWdzICYgU0ZMQUdfTE9DS0VEKSkpCiAgICB7CiAgICAgICAgV0FSTigiIFN1cmZhY2UgaXMgYnVzeSwgcmV0dXJuaW5nIERERVJSX1NVUkZBQ0VCVVNZXG4iKTsKICAgICAgICByZXR1cm4gV0lORURERVJSX1NVUkZBQ0VCVVNZOwogICAgfQoKICAgIGlmKEZpbHRlciAhPSBXSU5FRDNEVEVYRl9OT05FICYmIEZpbHRlciAhPSBXSU5FRDNEVEVYRl9QT0lOVCkgewogICAgICAgIC8qIENhbiBoYXBwZW4gd2hlbiBkM2Q5IGFwcHMgZG8gYSBTdHJldGNoUmVjdCBjYWxsIHdoaWNoIGlzbid0IGhhbmRsZWQgaW4gZ2wgKi8KICAgICAgICBGSVhNRSgiRmlsdGVycyBub3Qgc3VwcG9ydGVkIGluIHNvZnR3YXJlIGJsaXRcbiIpOwogICAgfQoKICAgIGlmIChTcmMgPT0gVGhpcykKICAgIHsKICAgICAgICBJV2luZUQzRFN1cmZhY2VfTG9ja1JlY3QoaWZhY2UsICZkbG9jaywgTlVMTCwgMCk7CiAgICAgICAgZGZtdCA9IFRoaXMtPnJlc291cmNlLmZvcm1hdDsKICAgICAgICBzbG9jayA9IGRsb2NrOwogICAgICAgIHNmbXQgPSBkZm10OwogICAgICAgIHNFbnRyeSA9IGdldEZvcm1hdERlc2NFbnRyeShzZm10KTsKICAgICAgICBkRW50cnkgPSBzRW50cnk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgaWYgKFNyYykKICAgICAgICB7CiAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9Mb2NrUmVjdChTcmNTdXJmYWNlLCAmc2xvY2ssIE5VTEwsIFdJTkVEM0RMT0NLX1JFQURPTkxZKTsKICAgICAgICAgICAgc2ZtdCA9IFNyYy0+cmVzb3VyY2UuZm9ybWF0OwogICAgICAgIH0KICAgICAgICBzRW50cnkgPSBnZXRGb3JtYXREZXNjRW50cnkoc2ZtdCk7CiAgICAgICAgZGZtdCA9IFRoaXMtPnJlc291cmNlLmZvcm1hdDsKICAgICAgICBkRW50cnkgPSBnZXRGb3JtYXREZXNjRW50cnkoZGZtdCk7CiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0xvY2tSZWN0KGlmYWNlLCAmZGxvY2ssTlVMTCwwKTsKICAgIH0KCiAgICBpZiAoIUREQmx0RnggfHwgIShEREJsdEZ4LT5kd0RERlgpKSBGbGFncyAmPSB+V0lORUREQkxUX0RERlg7CgogICAgaWYgKHNFbnRyeS0+aXNGb3VyY2MgJiYgZEVudHJ5LT5pc0ZvdXJjYykKICAgIHsKICAgICAgICBpZiAoc2ZtdCAhPSBkZm10KQogICAgICAgIHsKICAgICAgICAgICAgRklYTUUoIkZPVVJDQy0+Rk9VUkNDIGNvcHkgb25seSBzdXBwb3J0ZWQgZm9yIHRoZSBzYW1lIHR5cGUgb2Ygc3VyZmFjZVxuIik7CiAgICAgICAgICAgIHJldCA9IFdJTkVEM0RFUlJfV1JPTkdURVhUVVJFRk9STUFUOwogICAgICAgICAgICBnb3RvIHJlbGVhc2U7CiAgICAgICAgfQogICAgICAgIG1lbWNweShkbG9jay5wQml0cywgc2xvY2sucEJpdHMsIFRoaXMtPnJlc291cmNlLnNpemUpOwogICAgICAgIGdvdG8gcmVsZWFzZTsKICAgIH0KCiAgICBpZiAoc0VudHJ5LT5pc0ZvdXJjYyAmJiAhZEVudHJ5LT5pc0ZvdXJjYykKICAgIHsKICAgICAgICBGSVhNRSgiRFhUQyBkZWNvbXByZXNzaW9uIG5vdCBzdXBwb3J0ZWQgcmlnaHQgbm93XG4iKTsKICAgICAgICBnb3RvIHJlbGVhc2U7CiAgICB9CgogICAgaWYgKERlc3RSZWN0KQogICAgewogICAgICAgIG1lbWNweSgmeGRzdCxEZXN0UmVjdCxzaXplb2YoeGRzdCkpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIHhkc3QudG9wCT0gMDsKICAgICAgICB4ZHN0LmJvdHRvbQk9IFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodDsKICAgICAgICB4ZHN0LmxlZnQJPSAwOwogICAgICAgIHhkc3QucmlnaHQJPSBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aDsKICAgIH0KCiAgICBpZiAoU3JjUmVjdCkKICAgIHsKICAgICAgICBtZW1jcHkoJnhzcmMsU3JjUmVjdCxzaXplb2YoeHNyYykpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIGlmIChTcmMpCiAgICAgICAgewogICAgICAgICAgICB4c3JjLnRvcAk9IDA7CiAgICAgICAgICAgIHhzcmMuYm90dG9tCT0gU3JjLT5jdXJyZW50RGVzYy5IZWlnaHQ7CiAgICAgICAgICAgIHhzcmMubGVmdAk9IDA7CiAgICAgICAgICAgIHhzcmMucmlnaHQJPSBTcmMtPmN1cnJlbnREZXNjLldpZHRoOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBtZW1zZXQoJnhzcmMsMCxzaXplb2YoeHNyYykpOwogICAgICAgIH0KICAgIH0KCiAgICAvKiBGaXJzdCBjaGVjayBmb3IgdGhlIHZhbGlkaXR5IG9mIHNvdXJjZSAvIGRlc3RpbmF0aW9uIHJlY3RhbmdsZXMuIFRoaXMgd2FzCiAgICAgIHZlcmlmaWVkIHVzaW5nIGEgdGVzdCBhcHBsaWNhdGlvbiArIGJ5IE1TRE4uCiAgICAqLwogICAgaWYgKChTcmMgIT0gTlVMTCkgJiYKICAgICAgICAoKHhzcmMuYm90dG9tID4gU3JjLT5jdXJyZW50RGVzYy5IZWlnaHQpIHx8ICh4c3JjLmJvdHRvbSA8IDApIHx8CiAgICAgICAgKHhzcmMudG9wICAgICA+IFNyYy0+Y3VycmVudERlc2MuSGVpZ2h0KSB8fCAoeHNyYy50b3AgICAgPCAwKSB8fAogICAgICAgICh4c3JjLmxlZnQgICAgPiBTcmMtPmN1cnJlbnREZXNjLldpZHRoKSAgfHwgKHhzcmMubGVmdCAgIDwgMCkgfHwKICAgICAgICAoeHNyYy5yaWdodCAgID4gU3JjLT5jdXJyZW50RGVzYy5XaWR0aCkgIHx8ICh4c3JjLnJpZ2h0ICA8IDApIHx8CiAgICAgICAgKHhzcmMucmlnaHQgICA8IHhzcmMubGVmdCkgICAgICAgICAgICAgICB8fCAoeHNyYy5ib3R0b20gPCB4c3JjLnRvcCkpKQogICAgewogICAgICAgIFdBUk4oIkFwcGxpY2F0aW9uIGdhdmUgdXMgYmFkIHNvdXJjZSByZWN0YW5nbGUgZm9yIEJsdC5cbiIpOwogICAgICAgIHJldCA9IFdJTkVEREVSUl9JTlZBTElEUkVDVDsKICAgICAgICBnb3RvIHJlbGVhc2U7CiAgICB9CiAgICAvKiBGb3IgdGhlIERlc3RpbmF0aW9uIHJlY3QsIGl0IGNhbiBiZSBvdXQgb2YgYm91bmRzIG9uIHRoZSBjb25kaXRpb24gdGhhdCBhIGNsaXBwZXIKICAgICAgaXMgc2V0IGZvciB0aGUgZ2l2ZW4gc3VyZmFjZS4KICAgICovCiAgICBpZiAoKC8qVGhpcy0+Y2xpcHBlciA9PSBOVUxMKi8gVFJVRSkgJiYKICAgICAgICAoKHhkc3QuYm90dG9tICA+IFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodCkgfHwgKHhkc3QuYm90dG9tIDwgMCkgfHwKICAgICAgICAoeGRzdC50b3AgICAgICA+IFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodCkgfHwgKHhkc3QudG9wICAgIDwgMCkgfHwKICAgICAgICAoeGRzdC5sZWZ0ICAgICA+IFRoaXMtPmN1cnJlbnREZXNjLldpZHRoKSAgfHwgKHhkc3QubGVmdCAgIDwgMCkgfHwKICAgICAgICAoeGRzdC5yaWdodCAgICA+IFRoaXMtPmN1cnJlbnREZXNjLldpZHRoKSAgfHwgKHhkc3QucmlnaHQgIDwgMCkgfHwKICAgICAgICAoeGRzdC5yaWdodCAgICA8IHhkc3QubGVmdCkgICAgICAgICAgICAgICAgfHwgKHhkc3QuYm90dG9tIDwgeGRzdC50b3ApKSkKICAgIHsKICAgICAgICBXQVJOKCJBcHBsaWNhdGlvbiBnYXZlIHVzIGJhZCBkZXN0aW5hdGlvbiByZWN0YW5nbGUgZm9yIEJsdCB3aXRob3V0IGEgY2xpcHBlciBzZXQuXG4iKTsKICAgICAgICByZXQgPSBXSU5FRERFUlJfSU5WQUxJRFJFQ1Q7CiAgICAgICAgZ290byByZWxlYXNlOwogICAgfQoKICAgIC8qIE5vdyBoYW5kbGUgbmVnYXRpdmUgdmFsdWVzIGluIHRoZSByZWN0YW5nbGVzLiBXYXJuaW5nOiBvbmx5IHN1cHBvcnRlZCBmb3Igbm93CiAgICAgIGluIHRoZSAnc2ltcGxlJyBjYXNlcyAoaWUgbm90IGluIGFueSBzdHJldGNoaW5nIC8gcm90YXRpb24gY2FzZXMpLgoKICAgICAgRmlyc3QsIHRoZSBjYXNlIHdoZXJlIG5vdGhpbmcgaXMgdG8gYmUgZG9uZS4KICAgICovCiAgICBpZiAoKCh4ZHN0LmJvdHRvbSA8PSAwKSB8fCAoeGRzdC5yaWdodCA8PSAwKSAgICAgICAgIHx8CiAgICAgICAgICh4ZHN0LnRvcCAgICA+PSAoaW50KSBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQpIHx8CiAgICAgICAgICh4ZHN0LmxlZnQgICA+PSAoaW50KSBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aCkpIHx8CiAgICAgICAgKChTcmMgIT0gTlVMTCkgJiYKICAgICAgICAoKHhzcmMuYm90dG9tIDw9IDApIHx8ICh4c3JjLnJpZ2h0IDw9IDApICAgICB8fAogICAgICAgICAoeHNyYy50b3AgPj0gKGludCkgU3JjLT5jdXJyZW50RGVzYy5IZWlnaHQpIHx8CiAgICAgICAgICh4c3JjLmxlZnQgPj0gKGludCkgU3JjLT5jdXJyZW50RGVzYy5XaWR0aCkpICApKQogICAgewogICAgICAgIFRSQUNFKCJOb3RoaW5nIHRvIGJlIGRvbmUgIVxuIik7CiAgICAgICAgZ290byByZWxlYXNlOwogICAgfQoKICAgIC8qIFRoZSBlYXN5IGNhc2UgOiB0aGUgc291cmNlLWxlc3MgYmxpdHMuLi4uICovCiAgICBpZiAoU3JjID09IE5VTEwpCiAgICB7CiAgICAgICAgUkVDVCBmdWxsX3JlY3Q7CiAgICAgICAgUkVDVCB0ZW1wX3JlY3Q7IC8qIE5vIGlkZWEgaWYgaW50ZXJzZWN0IHJlY3QgY2FuIGJlIHRoZSBzYW1lIGFzIG9uZSBvZiB0aGUgc291cmNlIHJlY3QgKi8KCiAgICAgICAgZnVsbF9yZWN0LmxlZnQgICA9IDA7CiAgICAgICAgZnVsbF9yZWN0LnRvcCAgICA9IDA7CiAgICAgICAgZnVsbF9yZWN0LnJpZ2h0ICA9IFRoaXMtPmN1cnJlbnREZXNjLldpZHRoOwogICAgICAgIGZ1bGxfcmVjdC5ib3R0b20gPSBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQ7CiAgICAgICAgSW50ZXJzZWN0UmVjdCgmdGVtcF9yZWN0LCAmZnVsbF9yZWN0LCAmeGRzdCk7CiAgICAgICAgeGRzdCA9IHRlbXBfcmVjdDsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICAvKiBPbmx5IGhhbmRsZSBjbGlwcGluZyBvbiB0aGUgZGVzdGluYXRpb24gcmVjdGFuZ2xlICovCiAgICAgICAgaW50IGNsaXBfaG9yaXogPSAoeGRzdC5sZWZ0IDwgMCkgfHwgKHhkc3QucmlnaHQgID4gKGludCkgVGhpcy0+Y3VycmVudERlc2MuV2lkdGggKTsKICAgICAgICBpbnQgY2xpcF92ZXJ0ICA9ICh4ZHN0LnRvcCAgPCAwKSB8fCAoeGRzdC5ib3R0b20gPiAoaW50KSBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQpOwogICAgICAgIGlmIChjbGlwX3ZlcnQgfHwgY2xpcF9ob3JpeikKICAgICAgICB7CiAgICAgICAgICAgIC8qIE5vdyBjaGVjayBpZiB0aGlzIGlzIGEgc3BlY2lhbCBjYXNlIG9yIG5vdC4uLiAqLwogICAgICAgICAgICBpZiAoKCgoeGRzdC5ib3R0b20gLSB4ZHN0LnRvcCApICE9ICh4c3JjLmJvdHRvbSAtIHhzcmMudG9wICkpICYmIGNsaXBfdmVydCApIHx8CiAgICAgICAgICAgICAgICAoKCh4ZHN0LnJpZ2h0ICAtIHhkc3QubGVmdCkgIT0gKHhzcmMucmlnaHQgIC0geHNyYy5sZWZ0KSkgJiYgY2xpcF9ob3JpeikgfHwKICAgICAgICAgICAgICAgIChGbGFncyAmIFdJTkVEREJMVF9EREZYKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgV0FSTigiT3V0IG9mIHNjcmVlbiByZWN0YW5nbGUgaW4gc3BlY2lhbCBjYXNlLiBOb3QgaGFuZGxlZCByaWdodCBub3cuXG4iKTsKICAgICAgICAgICAgICAgIGdvdG8gcmVsZWFzZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGNsaXBfaG9yaXopCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh4ZHN0LmxlZnQgPCAwKSB7IHhzcmMubGVmdCAtPSB4ZHN0LmxlZnQ7IHhkc3QubGVmdCA9IDA7IH0KICAgICAgICAgICAgICAgIGlmICh4ZHN0LnJpZ2h0ID4gVGhpcy0+Y3VycmVudERlc2MuV2lkdGgpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgeHNyYy5yaWdodCAtPSAoeGRzdC5yaWdodCAtIChpbnQpIFRoaXMtPmN1cnJlbnREZXNjLldpZHRoKTsKICAgICAgICAgICAgICAgICAgICB4ZHN0LnJpZ2h0ID0gKGludCkgVGhpcy0+Y3VycmVudERlc2MuV2lkdGg7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGNsaXBfdmVydCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHhkc3QudG9wIDwgMCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB4c3JjLnRvcCAtPSB4ZHN0LnRvcDsKICAgICAgICAgICAgICAgICAgICB4ZHN0LnRvcCA9IDA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoeGRzdC5ib3R0b20gPiBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgeHNyYy5ib3R0b20gLT0gKHhkc3QuYm90dG9tIC0gKGludCkgVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0KTsKICAgICAgICAgICAgICAgICAgICB4ZHN0LmJvdHRvbSA9IChpbnQpIFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICAvKiBBbmQgY2hlY2sgaWYgYWZ0ZXIgY2xpcHBpbmcgc29tZXRoaW5nIGlzIHN0aWxsIHRvIGJlIGRvbmUuLi4gKi8KICAgICAgICAgICAgaWYgKCh4ZHN0LmJvdHRvbSA8PSAwKSAgIHx8ICh4ZHN0LnJpZ2h0IDw9IDApICAgICAgIHx8CiAgICAgICAgICAgICAgICAoeGRzdC50b3AgICA+PSAoaW50KSBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQpICB8fAogICAgICAgICAgICAgICAgKHhkc3QubGVmdCAgPj0gKGludCkgVGhpcy0+Y3VycmVudERlc2MuV2lkdGgpICAgfHwKICAgICAgICAgICAgICAgICh4c3JjLmJvdHRvbSA8PSAwKSAgIHx8ICh4c3JjLnJpZ2h0IDw9IDApICAgICAgIHx8CiAgICAgICAgICAgICAgICAoeHNyYy50b3AgPj0gKGludCkgU3JjLT5jdXJyZW50RGVzYy5IZWlnaHQpICAgICB8fAogICAgICAgICAgICAgICAgKHhzcmMubGVmdCA+PSAoaW50KSBTcmMtPmN1cnJlbnREZXNjLldpZHRoKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgVFJBQ0UoIk5vdGhpbmcgdG8gYmUgZG9uZSBhZnRlciBjbGlwcGluZyAhXG4iKTsKICAgICAgICAgICAgICAgIGdvdG8gcmVsZWFzZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBicHAgPSBUaGlzLT5ieXRlc1BlclBpeGVsOwogICAgc3JjaGVpZ2h0ID0geHNyYy5ib3R0b20gLSB4c3JjLnRvcDsKICAgIHNyY3dpZHRoID0geHNyYy5yaWdodCAtIHhzcmMubGVmdDsKICAgIGRzdGhlaWdodCA9IHhkc3QuYm90dG9tIC0geGRzdC50b3A7CiAgICBkc3R3aWR0aCA9IHhkc3QucmlnaHQgLSB4ZHN0LmxlZnQ7CiAgICB3aWR0aCA9ICh4ZHN0LnJpZ2h0IC0geGRzdC5sZWZ0KSAqIGJwcDsKCiAgICBhc3NlcnQod2lkdGggPD0gZGxvY2suUGl0Y2gpOwoKICAgIGRidWYgPSAoQllURSopZGxvY2sucEJpdHMrKHhkc3QudG9wKmRsb2NrLlBpdGNoKSsoeGRzdC5sZWZ0KmJwcCk7CgogICAgaWYgKEZsYWdzICYgV0lORUREQkxUX1dBSVQpCiAgICB7CiAgICAgICAgRmxhZ3MgJj0gfldJTkVEREJMVF9XQUlUOwogICAgfQogICAgaWYgKEZsYWdzICYgV0lORUREQkxUX0FTWU5DKQogICAgewogICAgICAgIHN0YXRpYyBCT09MIGRpc3BsYXllZCA9IEZBTFNFOwogICAgICAgIGlmICghZGlzcGxheWVkKQogICAgICAgICAgICBGSVhNRSgiQ2FuJ3QgaGFuZGxlIFdJTkVEREJMVF9BU1lOQyBmbGFnIHJpZ2h0IG5vdy5cbiIpOwogICAgICAgIGRpc3BsYXllZCA9IFRSVUU7CiAgICAgICAgRmxhZ3MgJj0gfldJTkVEREJMVF9BU1lOQzsKICAgIH0KICAgIGlmIChGbGFncyAmIFdJTkVEREJMVF9ET05PVFdBSVQpCiAgICB7CiAgICAgICAgLyogV0lORUREQkxUX0RPTk9UV0FJVCBhcHBlYXJlZCBpbiBEWDcgKi8KICAgICAgICBzdGF0aWMgQk9PTCBkaXNwbGF5ZWQgPSBGQUxTRTsKICAgICAgICBpZiAoIWRpc3BsYXllZCkKICAgICAgICAgICAgRklYTUUoIkNhbid0IGhhbmRsZSBXSU5FRERCTFRfRE9OT1RXQUlUIGZsYWcgcmlnaHQgbm93LlxuIik7CiAgICAgICAgZGlzcGxheWVkID0gVFJVRTsKICAgICAgICBGbGFncyAmPSB+V0lORUREQkxUX0RPTk9UV0FJVDsKICAgIH0KCiAgICAvKiBGaXJzdCwgYWxsIHRoZSAnc291cmNlLWxlc3MnIGJsaXRzICovCiAgICBpZiAoRmxhZ3MgJiBXSU5FRERCTFRfQ09MT1JGSUxMKQogICAgewogICAgICAgIHJldCA9IF9CbHRfQ29sb3JGaWxsKGRidWYsIGRzdHdpZHRoLCBkc3RoZWlnaHQsIGJwcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRsb2NrLlBpdGNoLCBEREJsdEZ4LT51NS5kd0ZpbGxDb2xvcik7CiAgICAgICAgRmxhZ3MgJj0gfldJTkVEREJMVF9DT0xPUkZJTEw7CiAgICB9CgogICAgaWYgKEZsYWdzICYgV0lORUREQkxUX0RFUFRIRklMTCkKICAgIHsKICAgICAgICBGSVhNRSgiRERCTFRfREVQVEhGSUxMIG5lZWRzIHRvIGJlIGltcGxlbWVudGVkIVxuIik7CiAgICB9CiAgICBpZiAoRmxhZ3MgJiBXSU5FRERCTFRfUk9QKQogICAgewogICAgICAgIC8qIENhdGNoIHNvbWUgZGVnZW5lcmF0ZSBjYXNlcyBoZXJlICovCiAgICAgICAgc3dpdGNoKEREQmx0RngtPmR3Uk9QKQogICAgICAgIHsKICAgICAgICAgICAgY2FzZSBCTEFDS05FU1M6CiAgICAgICAgICAgICAgICByZXQgPSBfQmx0X0NvbG9yRmlsbChkYnVmLGRzdHdpZHRoLGRzdGhlaWdodCxicHAsZGxvY2suUGl0Y2gsMCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAweEFBMDAyOTogLyogTm8tb3AgKi8KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFdISVRFTkVTUzoKICAgICAgICAgICAgICAgIHJldCA9IF9CbHRfQ29sb3JGaWxsKGRidWYsZHN0d2lkdGgsZHN0aGVpZ2h0LGJwcCxkbG9jay5QaXRjaCx+MCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBTUkNDT1BZOiAvKiB3ZWxsLCB3ZSBkbyB0aGF0IGJlbG93ID8gKi8KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgRklYTUUoIlVuc3VwcG9ydGVkIHJhc3RlciBvcDogJTA4eCAgUGF0dGVybjogJXBcbiIsIEREQmx0RngtPmR3Uk9QLCBEREJsdEZ4LT51NS5scEREU1BhdHRlcm4pOwogICAgICAgICAgICAgICAgZ290byBlcnJvcjsKICAgICAgICB9CiAgICAgICAgRmxhZ3MgJj0gfldJTkVEREJMVF9ST1A7CiAgICB9CiAgICBpZiAoRmxhZ3MgJiBXSU5FRERCTFRfRERST1BTKQogICAgewogICAgICAgIEZJWE1FKCJcdERkcmF3IFJhc3RlciBPcHM6ICUwOHggIFBhdHRlcm46ICVwXG4iLCBEREJsdEZ4LT5kd0REUk9QLCBEREJsdEZ4LT51NS5scEREU1BhdHRlcm4pOwogICAgfQogICAgLyogTm93IHRoZSAnd2l0aCBzb3VyY2UnIGJsaXRzICovCiAgICBpZiAoU3JjKQogICAgewogICAgICAgIExQQllURSBzYmFzZTsKICAgICAgICBpbnQgc3gsIHhpbmMsIHN5LCB5aW5jOwoKICAgICAgICBpZiAoIWRzdHdpZHRoIHx8ICFkc3RoZWlnaHQpIC8qIGhtbS4uLiBzdHVwaWQgcHJvZ3JhbSA/ICovCiAgICAgICAgICAgIGdvdG8gcmVsZWFzZTsKICAgICAgICBzYmFzZSA9IChCWVRFKilzbG9jay5wQml0cysoeHNyYy50b3Aqc2xvY2suUGl0Y2gpK3hzcmMubGVmdCpicHA7CiAgICAgICAgeGluYyA9IChzcmN3aWR0aCA8PCAxNikgLyBkc3R3aWR0aDsKICAgICAgICB5aW5jID0gKHNyY2hlaWdodCA8PCAxNikgLyBkc3RoZWlnaHQ7CgogICAgICAgIGlmICghRmxhZ3MpCiAgICAgICAgewogICAgICAgICAgICAvKiBObyBlZmZlY3RzLCB3ZSBjYW4gY2hlYXQgaGVyZSAqLwogICAgICAgICAgICBpZiAoZHN0d2lkdGggPT0gc3Jjd2lkdGgpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChkc3RoZWlnaHQgPT0gc3JjaGVpZ2h0KQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIC8qIE5vIHN0cmV0Y2hpbmcgaW4gZWl0aGVyIGRpcmVjdGlvbi4gVGhpcyBuZWVkcyB0byBiZSBhcwogICAgICAgICAgICAgICAgICAgICogZmFzdCBhcyBwb3NzaWJsZSAqLwogICAgICAgICAgICAgICAgICAgIHNidWYgPSBzYmFzZTsKCiAgICAgICAgICAgICAgICAgICAgLyogY2hlY2sgZm9yIG92ZXJsYXBwaW5nIHN1cmZhY2VzICovCiAgICAgICAgICAgICAgICAgICAgaWYgKFNyY1N1cmZhY2UgIT0gaWZhY2UgfHwgeGRzdC50b3AgPCB4c3JjLnRvcCB8fAogICAgICAgICAgICAgICAgICAgICAgICB4ZHN0LnJpZ2h0IDw9IHhzcmMubGVmdCB8fCB4c3JjLnJpZ2h0IDw9IHhkc3QubGVmdCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIG5vIG92ZXJsYXAsIG9yIGRzdCBhYm92ZSBzcmMsIHNvIGNvcHkgZnJvbSB0b3AgZG93bndhcmRzICovCiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoeSA9IDA7IHkgPCBkc3RoZWlnaHQ7IHkrKykKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVtY3B5KGRidWYsIHNidWYsIHdpZHRoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNidWYgKz0gc2xvY2suUGl0Y2g7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYnVmICs9IGRsb2NrLlBpdGNoOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHhkc3QudG9wID4geHNyYy50b3ApICAvKiBjb3B5IGZyb20gYm90dG9tIHVwd2FyZHMgKi8KICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNidWYgKz0gKHNsb2NrLlBpdGNoKmRzdGhlaWdodCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGRidWYgKz0gKGRsb2NrLlBpdGNoKmRzdGhlaWdodCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoeSA9IDA7IHkgPCBkc3RoZWlnaHQ7IHkrKykKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2J1ZiAtPSBzbG9jay5QaXRjaDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRidWYgLT0gZGxvY2suUGl0Y2g7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZW1jcHkoZGJ1Ziwgc2J1Ziwgd2lkdGgpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UgLyogc3JjIGFuZCBkc3Qgb3ZlcmxhcHBpbmcgb24gdGhlIHNhbWUgbGluZSwgdXNlIG1lbW1vdmUgKi8KICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoeSA9IDA7IHkgPCBkc3RoZWlnaHQ7IHkrKykKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVtbW92ZShkYnVmLCBzYnVmLCB3aWR0aCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzYnVmICs9IHNsb2NrLlBpdGNoOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGJ1ZiArPSBkbG9jay5QaXRjaDsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgLyogU3RyZXRjaGluZyBpbiBZIGRpcmVjdGlvbiBvbmx5ICovCiAgICAgICAgICAgICAgICAgICAgZm9yICh5ID0gc3kgPSAwOyB5IDwgZHN0aGVpZ2h0OyB5KyssIHN5ICs9IHlpbmMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgc2J1ZiA9IHNiYXNlICsgKHN5ID4+IDE2KSAqIHNsb2NrLlBpdGNoOwogICAgICAgICAgICAgICAgICAgICAgICBtZW1jcHkoZGJ1Ziwgc2J1Ziwgd2lkdGgpOwogICAgICAgICAgICAgICAgICAgICAgICBkYnVmICs9IGRsb2NrLlBpdGNoOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8qIFN0cmV0Y2hpbmcgaW4gWCBkaXJlY3Rpb24gKi8KICAgICAgICAgICAgICAgIGludCBsYXN0X3N5ID0gLTE7CiAgICAgICAgICAgICAgICBmb3IgKHkgPSBzeSA9IDA7IHkgPCBkc3RoZWlnaHQ7IHkrKywgc3kgKz0geWluYykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzYnVmID0gc2Jhc2UgKyAoc3kgPj4gMTYpICogc2xvY2suUGl0Y2g7CgogICAgICAgICAgICAgICAgICAgIGlmICgoc3kgPj4gMTYpID09IChsYXN0X3N5ID4+IDE2KSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRoaXMgc291cmNlcm93IGlzIHRoZSBzYW1lIGFzIGxhc3Qgc291cmNlcm93IC0KICAgICAgICAgICAgICAgICAgICAgICAgICogY29weSBhbHJlYWR5IHN0cmV0Y2hlZCByb3cKICAgICAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgICAgIG1lbWNweShkYnVmLCBkYnVmIC0gZGxvY2suUGl0Y2gsIHdpZHRoKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKI2RlZmluZSBTVFJFVENIX1JPVyh0eXBlKSB7IFwKICAgICAgICAgICAgICAgICAgICB0eXBlICpzID0gKHR5cGUgKikgc2J1ZiwgKmQgPSAodHlwZSAqKSBkYnVmOyBcCiAgICAgICAgICAgICAgICAgICAgZm9yICh4ID0gc3ggPSAwOyB4IDwgZHN0d2lkdGg7IHgrKywgc3ggKz0geGluYykgXAogICAgICAgICAgICAgICAgICAgIGRbeF0gPSBzW3N4ID4+IDE2XTsgXAogICAgICAgICAgICAgICAgICAgIGJyZWFrOyB9CgogICAgICAgICAgICAgICAgICAgIHN3aXRjaChicHApCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDE6IFNUUkVUQ0hfUk9XKEJZVEUpCiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMjogU1RSRVRDSF9ST1coV09SRCkKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSA0OiBTVFJFVENIX1JPVyhEV09SRCkKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAzOgogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUEJZVEUgcyxkID0gZGJ1ZjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoeCA9IHN4ID0gMDsgeCA8IGRzdHdpZHRoOyB4KyssIHN4Kz0geGluYykKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBwaXhlbDsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcyA9IHNidWYrMyooc3g+PjE2KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaXhlbCA9IHNbMF18KHNbMV08PDgpfChzWzJdPDwxNik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZFswXSA9IChwaXhlbCAgICApJjB4ZmY7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZFsxXSA9IChwaXhlbD4+IDgpJjB4ZmY7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZFsyXSA9IChwaXhlbD4+MTYpJjB4ZmY7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZCs9MzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICAgICBGSVhNRSgiU3RyZXRjaGVkIGJsaXQgbm90IGltcGxlbWVudGVkIGZvciBicHAgJWQhXG4iLCBicHAqOCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldCA9IFdJTkVEM0RFUlJfTk9UQVZBSUxBQkxFOwogICAgICAgICAgICAgICAgICAgICAgICBnb3RvIGVycm9yOwogICAgICAgICAgICAgICAgICAgIH0KI3VuZGVmIFNUUkVUQ0hfUk9XCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGRidWYgKz0gZGxvY2suUGl0Y2g7CiAgICAgICAgICAgICAgICAgICAgbGFzdF9zeSA9IHN5OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICBMT05HIGRzdHlpbmMgPSBkbG9jay5QaXRjaCwgZHN0eGluYyA9IGJwcDsKICAgICAgICAgIERXT1JEIGtleWxvdyA9IDB4RkZGRkZGRkYsIGtleWhpZ2ggPSAwLCBrZXltYXNrID0gMHhGRkZGRkZGRjsKICAgICAgICAgIERXT1JEIGRlc3RrZXlsb3cgPSAweDAsIGRlc3RrZXloaWdoID0gMHhGRkZGRkZGRiwgZGVzdGtleW1hc2sgPSAweEZGRkZGRkZGOwogICAgICAgICAgaWYgKEZsYWdzICYgKFdJTkVEREJMVF9LRVlTUkMgfCBXSU5FRERCTFRfS0VZREVTVCB8IFdJTkVEREJMVF9LRVlTUkNPVkVSUklERSB8IFdJTkVEREJMVF9LRVlERVNUT1ZFUlJJREUpKQogICAgICAgICAgewogICAgICAgICAgICAgIC8qIFRoZSBjb2xvciBrZXlpbmcgZmxhZ3MgYXJlIGNoZWNrZWQgZm9yIGNvcnJlY3RuZXNzIGluIGRkcmF3ICovCiAgICAgICAgICAgICAgaWYgKEZsYWdzICYgV0lORUREQkxUX0tFWVNSQykKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBrZXlsb3cgID0gU3JjLT5TcmNCbHRDS2V5LmR3Q29sb3JTcGFjZUxvd1ZhbHVlOwogICAgICAgICAgICAgICAga2V5aGlnaCA9IFNyYy0+U3JjQmx0Q0tleS5kd0NvbG9yU3BhY2VIaWdoVmFsdWU7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGVsc2UgIGlmIChGbGFncyAmIFdJTkVEREJMVF9LRVlTUkNPVkVSUklERSkKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBrZXlsb3cgID0gRERCbHRGeC0+ZGRja1NyY0NvbG9ya2V5LmR3Q29sb3JTcGFjZUxvd1ZhbHVlOwogICAgICAgICAgICAgICAga2V5aGlnaCA9IEREQmx0RngtPmRkY2tTcmNDb2xvcmtleS5kd0NvbG9yU3BhY2VIaWdoVmFsdWU7CiAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICBpZiAoRmxhZ3MgJiBXSU5FRERCTFRfS0VZREVTVCkKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvKiBEZXN0aW5hdGlvbiBjb2xvciBrZXlzIGFyZSB0YWtlbiBmcm9tIHRoZSBzb3VyY2Ugc3VyZmFjZSAhICovCiAgICAgICAgICAgICAgICBkZXN0a2V5bG93ICA9IFNyYy0+RGVzdEJsdENLZXkuZHdDb2xvclNwYWNlTG93VmFsdWU7CiAgICAgICAgICAgICAgICBkZXN0a2V5aGlnaCA9IFNyYy0+RGVzdEJsdENLZXkuZHdDb2xvclNwYWNlSGlnaFZhbHVlOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBlbHNlIGlmIChGbGFncyAmIFdJTkVEREJMVF9LRVlERVNUT1ZFUlJJREUpCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZGVzdGtleWxvdyAgPSBEREJsdEZ4LT5kZGNrRGVzdENvbG9ya2V5LmR3Q29sb3JTcGFjZUxvd1ZhbHVlOwogICAgICAgICAgICAgICAgZGVzdGtleWhpZ2ggPSBEREJsdEZ4LT5kZGNrRGVzdENvbG9ya2V5LmR3Q29sb3JTcGFjZUhpZ2hWYWx1ZTsKICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgIGlmKGJwcCA9PSAxKQogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAga2V5bWFzayA9IDB4ZmY7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgIGtleW1hc2sgPSBzRW50cnktPnJlZE1hc2sgICB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzRW50cnktPmdyZWVuTWFzayB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzRW50cnktPmJsdWVNYXNrOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBGbGFncyAmPSB+KFdJTkVEREJMVF9LRVlTUkMgfCBXSU5FRERCTFRfS0VZREVTVCB8IFdJTkVEREJMVF9LRVlTUkNPVkVSUklERSB8IFdJTkVEREJMVF9LRVlERVNUT1ZFUlJJREUpOwogICAgICAgICAgfQoKICAgICAgICAgIGlmIChGbGFncyAmIFdJTkVEREJMVF9EREZYKQogICAgICAgICAgewogICAgICAgICAgICAgIExQQllURSBkVG9wTGVmdCwgZFRvcFJpZ2h0LCBkQm90dG9tTGVmdCwgZEJvdHRvbVJpZ2h0LCB0bXA7CiAgICAgICAgICAgICAgTE9ORyB0bXB4eTsKICAgICAgICAgICAgICBkVG9wTGVmdCAgICAgPSBkYnVmOwogICAgICAgICAgICAgIGRUb3BSaWdodCAgICA9IGRidWYrKChkc3R3aWR0aC0xKSpicHApOwogICAgICAgICAgICAgIGRCb3R0b21MZWZ0ICA9IGRUb3BMZWZ0KygoZHN0aGVpZ2h0LTEpKmRsb2NrLlBpdGNoKTsKICAgICAgICAgICAgICBkQm90dG9tUmlnaHQgPSBkQm90dG9tTGVmdCsoKGRzdHdpZHRoLTEpKmJwcCk7CgogICAgICAgICAgICAgIGlmIChEREJsdEZ4LT5kd0RERlggJiBXSU5FRERCTFRGWF9BUklUSFNUUkVUQ0hZKQogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8qIEkgZG9uJ3QgdGhpbmsgd2UgbmVlZCB0byBkbyBhbnl0aGluZyBhYm91dCB0aGlzIGZsYWcgKi8KICAgICAgICAgICAgICAgIFdBUk4oIkZsYWdzPUREQkxUX0RERlggbm90aGluZyBkb25lIGZvciBXSU5FRERCTFRGWF9BUklUSFNUUkVUQ0hZXG4iKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgaWYgKEREQmx0RngtPmR3RERGWCAmIFdJTkVEREJMVEZYX01JUlJPUkxFRlRSSUdIVCkKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0bXAgICAgICAgICAgPSBkVG9wUmlnaHQ7CiAgICAgICAgICAgICAgICBkVG9wUmlnaHQgICAgPSBkVG9wTGVmdDsKICAgICAgICAgICAgICAgIGRUb3BMZWZ0ICAgICA9IHRtcDsKICAgICAgICAgICAgICAgIHRtcCAgICAgICAgICA9IGRCb3R0b21SaWdodDsKICAgICAgICAgICAgICAgIGRCb3R0b21SaWdodCA9IGRCb3R0b21MZWZ0OwogICAgICAgICAgICAgICAgZEJvdHRvbUxlZnQgID0gdG1wOwogICAgICAgICAgICAgICAgZHN0eGluYyA9IGRzdHhpbmMgKi0xOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBpZiAoRERCbHRGeC0+ZHdEREZYICYgV0lORUREQkxURlhfTUlSUk9SVVBET1dOKQogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRtcCAgICAgICAgICA9IGRUb3BMZWZ0OwogICAgICAgICAgICAgICAgZFRvcExlZnQgICAgID0gZEJvdHRvbUxlZnQ7CiAgICAgICAgICAgICAgICBkQm90dG9tTGVmdCAgPSB0bXA7CiAgICAgICAgICAgICAgICB0bXAgICAgICAgICAgPSBkVG9wUmlnaHQ7CiAgICAgICAgICAgICAgICBkVG9wUmlnaHQgICAgPSBkQm90dG9tUmlnaHQ7CiAgICAgICAgICAgICAgICBkQm90dG9tUmlnaHQgPSB0bXA7CiAgICAgICAgICAgICAgICBkc3R5aW5jID0gZHN0eWluYyAqLTE7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGlmIChEREJsdEZ4LT5kd0RERlggJiBXSU5FRERCTFRGWF9OT1RFQVJJTkcpCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLyogSSBkb24ndCB0aGluayB3ZSBuZWVkIHRvIGRvIGFueXRoaW5nIGFib3V0IHRoaXMgZmxhZyAqLwogICAgICAgICAgICAgICAgV0FSTigiRmxhZ3M9RERCTFRfRERGWCBub3RoaW5nIGRvbmUgZm9yIFdJTkVEREJMVEZYX05PVEVBUklOR1xuIik7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGlmIChEREJsdEZ4LT5kd0RERlggJiBXSU5FRERCTFRGWF9ST1RBVEUxODApCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdG1wICAgICAgICAgID0gZEJvdHRvbVJpZ2h0OwogICAgICAgICAgICAgICAgZEJvdHRvbVJpZ2h0ID0gZFRvcExlZnQ7CiAgICAgICAgICAgICAgICBkVG9wTGVmdCAgICAgPSB0bXA7CiAgICAgICAgICAgICAgICB0bXAgICAgICAgICAgPSBkQm90dG9tTGVmdDsKICAgICAgICAgICAgICAgIGRCb3R0b21MZWZ0ICA9IGRUb3BSaWdodDsKICAgICAgICAgICAgICAgIGRUb3BSaWdodCAgICA9IHRtcDsKICAgICAgICAgICAgICAgIGRzdHhpbmMgPSBkc3R4aW5jICogLTE7CiAgICAgICAgICAgICAgICBkc3R5aW5jID0gZHN0eWluYyAqIC0xOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBpZiAoRERCbHRGeC0+ZHdEREZYICYgV0lORUREQkxURlhfUk9UQVRFMjcwKQogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRtcCAgICAgICAgICA9IGRUb3BMZWZ0OwogICAgICAgICAgICAgICAgZFRvcExlZnQgICAgID0gZEJvdHRvbUxlZnQ7CiAgICAgICAgICAgICAgICBkQm90dG9tTGVmdCAgPSBkQm90dG9tUmlnaHQ7CiAgICAgICAgICAgICAgICBkQm90dG9tUmlnaHQgPSBkVG9wUmlnaHQ7CiAgICAgICAgICAgICAgICBkVG9wUmlnaHQgICAgPSB0bXA7CiAgICAgICAgICAgICAgICB0bXB4eSAgID0gZHN0eGluYzsKICAgICAgICAgICAgICAgIGRzdHhpbmMgPSBkc3R5aW5jOwogICAgICAgICAgICAgICAgZHN0eWluYyA9IHRtcHh5OwogICAgICAgICAgICAgICAgZHN0eGluYyA9IGRzdHhpbmMgKiAtMTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgaWYgKEREQmx0RngtPmR3RERGWCAmIFdJTkVEREJMVEZYX1JPVEFURTkwKQogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRtcCAgICAgICAgICA9IGRUb3BMZWZ0OwogICAgICAgICAgICAgICAgZFRvcExlZnQgICAgID0gZFRvcFJpZ2h0OwogICAgICAgICAgICAgICAgZFRvcFJpZ2h0ICAgID0gZEJvdHRvbVJpZ2h0OwogICAgICAgICAgICAgICAgZEJvdHRvbVJpZ2h0ID0gZEJvdHRvbUxlZnQ7CiAgICAgICAgICAgICAgICBkQm90dG9tTGVmdCAgPSB0bXA7CiAgICAgICAgICAgICAgICB0bXB4eSAgID0gZHN0eGluYzsKICAgICAgICAgICAgICAgIGRzdHhpbmMgPSBkc3R5aW5jOwogICAgICAgICAgICAgICAgZHN0eWluYyA9IHRtcHh5OwogICAgICAgICAgICAgICAgZHN0eWluYyA9IGRzdHlpbmMgKiAtMTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgaWYgKEREQmx0RngtPmR3RERGWCAmIFdJTkVEREJMVEZYX1pCVUZGRVJCQVNFREVTVCkKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvKiBJIGRvbid0IHRoaW5rIHdlIG5lZWQgdG8gZG8gYW55dGhpbmcgYWJvdXQgdGhpcyBmbGFnICovCiAgICAgICAgICAgICAgICBXQVJOKCJGbGFncz1XSU5FRERCTFRfRERGWCBub3RoaW5nIGRvbmUgZm9yIFdJTkVEREJMVEZYX1pCVUZGRVJCQVNFREVTVFxuIik7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGRidWYgPSBkVG9wTGVmdDsKICAgICAgICAgICAgICBGbGFncyAmPSB+KFdJTkVEREJMVF9EREZYKTsKICAgICAgICAgIH0KCiNkZWZpbmUgQ09QWV9DT0xPUktFWV9GWCh0eXBlKSB7IFwKICAgICAgICAgICAgdHlwZSAqcywgKmQgPSAodHlwZSAqKSBkYnVmLCAqZHgsIHRtcDsgXAogICAgICAgICAgICBmb3IgKHkgPSBzeSA9IDA7IHkgPCBkc3RoZWlnaHQ7IHkrKywgc3kgKz0geWluYykgeyBcCiAgICAgICAgICAgICAgcyA9ICh0eXBlKikoc2Jhc2UgKyAoc3kgPj4gMTYpICogc2xvY2suUGl0Y2gpOyBcCiAgICAgICAgICAgICAgZHggPSBkOyBcCiAgICAgICAgICAgICAgZm9yICh4ID0gc3ggPSAwOyB4IDwgZHN0d2lkdGg7IHgrKywgc3ggKz0geGluYykgeyBcCiAgICAgICAgICAgICAgICAgIHRtcCA9IHNbc3ggPj4gMTZdOyBcCiAgICAgICAgICAgICAgICAgIGlmICgoKHRtcCAmIGtleW1hc2spIDwga2V5bG93IHx8ICh0bXAgJiBrZXltYXNrKSA+IGtleWhpZ2gpICYmIFwKICAgICAgICAgICAgICAgICAgICAgICgoZHhbMF0gJiBkZXN0a2V5bWFzaykgPj0gZGVzdGtleWxvdyAmJiAoZHhbMF0gJiBkZXN0a2V5bWFzaykgPD0gZGVzdGtleWhpZ2gpKSB7IFwKICAgICAgICAgICAgICAgICAgICAgICBkeFswXSA9IHRtcDsgXAogICAgICAgICAgICAgICAgICAgICB9IFwKICAgICAgICAgICAgICAgICAgZHggPSAodHlwZSopKCgoTFBCWVRFKWR4KStkc3R4aW5jKTsgXAogICAgICAgICAgICAgIH0gXAogICAgICAgICAgICAgIGQgPSAodHlwZSopKCgoTFBCWVRFKWQpK2RzdHlpbmMpOyBcCiAgICAgICAgICAgIH0gXAogICAgICAgICAgICBicmVhazsgfQoKICAgICAgICAgICAgc3dpdGNoIChicHApIHsKICAgICAgICAgICAgY2FzZSAxOiBDT1BZX0NPTE9SS0VZX0ZYKEJZVEUpCiAgICAgICAgICAgIGNhc2UgMjogQ09QWV9DT0xPUktFWV9GWChXT1JEKQogICAgICAgICAgICBjYXNlIDQ6IENPUFlfQ09MT1JLRVlfRlgoRFdPUkQpCiAgICAgICAgICAgIGNhc2UgMzoKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgTFBCWVRFIHMsZCA9IGRidWYsIGR4OwogICAgICAgICAgICAgICAgZm9yICh5ID0gc3kgPSAwOyB5IDwgZHN0aGVpZ2h0OyB5KyssIHN5ICs9IHlpbmMpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc2J1ZiA9IHNiYXNlICsgKHN5ID4+IDE2KSAqIHNsb2NrLlBpdGNoOwogICAgICAgICAgICAgICAgICAgIGR4ID0gZDsKICAgICAgICAgICAgICAgICAgICBmb3IgKHggPSBzeCA9IDA7IHggPCBkc3R3aWR0aDsgeCsrLCBzeCs9IHhpbmMpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBwaXhlbCwgZHBpeGVsID0gMDsKICAgICAgICAgICAgICAgICAgICAgICAgcyA9IHNidWYrMyooc3g+PjE2KTsKICAgICAgICAgICAgICAgICAgICAgICAgcGl4ZWwgPSBzWzBdfChzWzFdPDw4KXwoc1syXTw8MTYpOwogICAgICAgICAgICAgICAgICAgICAgICBkcGl4ZWwgPSBkeFswXXwoZHhbMV08PDgpfChkeFsyXTw8MTYpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoKChwaXhlbCAmIGtleW1hc2spIDwga2V5bG93IHx8IChwaXhlbCAmIGtleW1hc2spID4ga2V5aGlnaCkgJiYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoZHBpeGVsICYga2V5bWFzaykgPj0gZGVzdGtleWxvdyB8fCAoZHBpeGVsICYga2V5bWFzaykgPD0ga2V5aGlnaCkpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR4WzBdID0gKHBpeGVsICAgICkmMHhmZjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR4WzFdID0gKHBpeGVsPj4gOCkmMHhmZjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR4WzJdID0gKHBpeGVsPj4xNikmMHhmZjsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBkeCs9IGRzdHhpbmM7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGQgKz0gZHN0eWluYzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgRklYTUUoIiVzIGNvbG9yLWtleWVkIGJsaXQgbm90IGltcGxlbWVudGVkIGZvciBicHAgJWQhXG4iLAogICAgICAgICAgICAgICAgICAoRmxhZ3MgJiBXSU5FRERCTFRfS0VZU1JDKSA/ICJTb3VyY2UiIDogIkRlc3RpbmF0aW9uIiwgYnBwKjgpOwogICAgICAgICAgICAgICAgICByZXQgPSBXSU5FRDNERVJSX05PVEFWQUlMQUJMRTsKICAgICAgICAgICAgICAgICAgZ290byBlcnJvcjsKI3VuZGVmIENPUFlfQ09MT1JLRVlfRlgKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCmVycm9yOgogICAgaWYgKEZsYWdzICYmIEZJWE1FX09OKGQzZF9zdXJmYWNlKSkKICAgIHsKICAgICAgICBGSVhNRSgiXHRVbnN1cHBvcnRlZCBmbGFnczogJTA4eFxuIiwgRmxhZ3MpOwogICAgfQoKcmVsZWFzZToKICAgIElXaW5lRDNEU3VyZmFjZV9VbmxvY2tSZWN0KGlmYWNlKTsKICAgIGlmIChTcmNTdXJmYWNlICYmIFNyY1N1cmZhY2UgIT0gaWZhY2UpIElXaW5lRDNEU3VyZmFjZV9VbmxvY2tSZWN0KFNyY1N1cmZhY2UpOwogICAgcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElXaW5lRDNEU3VyZmFjZTo6Qmx0RmFzdCwgR0RJIHZlcnNpb24KICoKICogVGhpcyBpcyB0aGUgc29mdHdhcmUgaW1wbGVtZW50YXRpb24gb2YgQmx0RmFzdCwgYXMgdXNlZCBieSBHREkgc3VyZmFjZXMKICogYW5kIGFzIGEgZmFsbGJhY2sgZm9yIE9wZW5HTCBzdXJmYWNlcy4gVGhpcyBjb2RlIGlzIHRha2VuIGZyb20gdGhlIG9sZAogKiBEaXJlY3REcmF3IGNvZGUsIGFuZCB3YXMgb3JpZ2luYWxseSB3cml0dGVuIGJ5IFRyYW5zR2FtaW5nLgogKgogKiBQYXJhbXM6CiAqICBkc3R4OgogKiAgZHN0eToKICogIFNvdXJjZTogU291cmNlIHN1cmZhY2UgdG8gY29weSBmcm9tCiAqICByc3JjOiBTb3VyY2UgcmVjdGFuZ2xlCiAqICB0cmFuczogU29tZSBGbGFncwogKgogKiBSZXR1cm5zOgogKiAgV0lORUQzRF9PSyBvbiBzdWNjZXNzCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KSFJFU1VMVCBXSU5BUEkKSVdpbmVHRElTdXJmYWNlSW1wbF9CbHRGYXN0KElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBkc3R4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZHN0eSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZSAqU291cmNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVDVCAqcnNyYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIHRyYW5zKQp7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgaWZhY2U7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpTcmMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBTb3VyY2U7CgogICAgaW50ICAgICAgICAgICAgICAgICBicHAsIHcsIGgsIHgsIHk7CiAgICBXSU5FRDNETE9DS0VEX1JFQ1QgIGRsb2NrLHNsb2NrOwogICAgSFJFU1VMVCAgICAgICAgICAgICByZXQgPSBXSU5FRDNEX09LOwogICAgUkVDVCAgICAgICAgICAgICAgICByc3JjMjsKICAgIFJFQ1QgICAgICAgICAgICAgICAgbG9ja19zcmMsIGxvY2tfZHN0LCBsb2NrX3VuaW9uOwogICAgQllURSAgICAgICAgICAgICAgICAqc2J1ZiwgKmRidWY7CiAgICBjb25zdCBQaXhlbEZvcm1hdERlc2MgKnNFbnRyeSwgKmRFbnRyeTsKCiAgICBpZiAoVFJBQ0VfT04oZDNkX3N1cmZhY2UpKQogICAgewogICAgICAgIFRSQUNFKCIoJXApLT4oJWQsJWQsJXAsJXAsJTA4eClcbiIsIFRoaXMsZHN0eCxkc3R5LFNyYyxyc3JjLHRyYW5zKTsKCiAgICAgICAgaWYgKHJzcmMpCiAgICAgICAgewogICAgICAgICAgICBUUkFDRSgiXHRzcmNyZWN0OiAlZHglZC0lZHglZFxuIixyc3JjLT5sZWZ0LHJzcmMtPnRvcCwKICAgICAgICAgICAgICAgICAgcnNyYy0+cmlnaHQscnNyYy0+Ym90dG9tKTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgVFJBQ0UoIiBzcmNyZWN0OiBOVUxMXG4iKTsKICAgICAgICB9CiAgICB9CgogICAgaWYgKChUaGlzLT5GbGFncyAmIFNGTEFHX0xPQ0tFRCkgfHwKICAgICAgICAoKFNyYyAhPSBOVUxMKSAmJiAoU3JjLT5GbGFncyAmIFNGTEFHX0xPQ0tFRCkpKQogICAgewogICAgICAgIFdBUk4oIiBTdXJmYWNlIGlzIGJ1c3ksIHJldHVybmluZyBEREVSUl9TVVJGQUNFQlVTWVxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEREVSUl9TVVJGQUNFQlVTWTsKICAgIH0KCiAgICBpZiAoIXJzcmMpCiAgICB7CiAgICAgICAgV0FSTigicnNyYyBpcyBOVUxMIVxuIik7CiAgICAgICAgcnNyYyA9ICZyc3JjMjsKICAgICAgICByc3JjLT5sZWZ0ID0gMDsKICAgICAgICByc3JjLT50b3AgPSAwOwogICAgICAgIHJzcmMtPnJpZ2h0ID0gU3JjLT5jdXJyZW50RGVzYy5XaWR0aDsKICAgICAgICByc3JjLT5ib3R0b20gPSBTcmMtPmN1cnJlbnREZXNjLkhlaWdodDsKICAgIH0KCiAgICAvKiBDaGVjayBzb3VyY2UgcmVjdCBmb3IgdmFsaWRpdHkuIENvcGllZCBmcm9tIG5vcm1hbCBCbHQuIEZpeGVzIEJhbGR1cidzIEdhdGUuKi8KICAgIGlmICgocnNyYy0+Ym90dG9tID4gU3JjLT5jdXJyZW50RGVzYy5IZWlnaHQpIHx8IChyc3JjLT5ib3R0b20gPCAwKSB8fAogICAgICAgIChyc3JjLT50b3AgICAgPiBTcmMtPmN1cnJlbnREZXNjLkhlaWdodCkgfHwgKHJzcmMtPnRvcCAgICA8IDApIHx8CiAgICAgICAgKHJzcmMtPmxlZnQgICA+IFNyYy0+Y3VycmVudERlc2MuV2lkdGgpICB8fCAocnNyYy0+bGVmdCAgIDwgMCkgfHwKICAgICAgICAocnNyYy0+cmlnaHQgID4gU3JjLT5jdXJyZW50RGVzYy5XaWR0aCkgIHx8IChyc3JjLT5yaWdodCAgPCAwKSB8fAogICAgICAgIChyc3JjLT5yaWdodCAgPCByc3JjLT5sZWZ0KSAgICAgICAgICAgICAgfHwgKHJzcmMtPmJvdHRvbSA8IHJzcmMtPnRvcCkpCiAgICB7CiAgICAgICAgV0FSTigiQXBwbGljYXRpb24gZ2F2ZSB1cyBiYWQgc291cmNlIHJlY3RhbmdsZSBmb3IgQmx0RmFzdC5cbiIpOwogICAgICAgIHJldHVybiBXSU5FRERFUlJfSU5WQUxJRFJFQ1Q7CiAgICB9CgogICAgaCA9IHJzcmMtPmJvdHRvbSAtIHJzcmMtPnRvcDsKICAgIGlmIChoID4gVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0LWRzdHkpIGggPSBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQtZHN0eTsKICAgIGlmIChoID4gU3JjLT5jdXJyZW50RGVzYy5IZWlnaHQtcnNyYy0+dG9wKSBoPVNyYy0+Y3VycmVudERlc2MuSGVpZ2h0LXJzcmMtPnRvcDsKICAgIGlmIChoIDw9IDApIHJldHVybiBXSU5FRERFUlJfSU5WQUxJRFJFQ1Q7CgogICAgdyA9IHJzcmMtPnJpZ2h0IC0gcnNyYy0+bGVmdDsKICAgIGlmICh3ID4gVGhpcy0+Y3VycmVudERlc2MuV2lkdGgtZHN0eCkgdyA9IFRoaXMtPmN1cnJlbnREZXNjLldpZHRoLWRzdHg7CiAgICBpZiAodyA+IFNyYy0+Y3VycmVudERlc2MuV2lkdGgtcnNyYy0+bGVmdCkgdyA9IFNyYy0+Y3VycmVudERlc2MuV2lkdGgtcnNyYy0+bGVmdDsKICAgIGlmICh3IDw9IDApIHJldHVybiBXSU5FRERFUlJfSU5WQUxJRFJFQ1Q7CgogICAgLyogTm93IGNvbXB1dGUgdGhlIGxvY2tpbmcgcmVjdGFuZ2xlLi4uICovCiAgICBsb2NrX3NyYy5sZWZ0ID0gcnNyYy0+bGVmdDsKICAgIGxvY2tfc3JjLnRvcCA9IHJzcmMtPnRvcDsKICAgIGxvY2tfc3JjLnJpZ2h0ID0gbG9ja19zcmMubGVmdCArIHc7CiAgICBsb2NrX3NyYy5ib3R0b20gPSBsb2NrX3NyYy50b3AgKyBoOwoKICAgIGxvY2tfZHN0LmxlZnQgPSBkc3R4OwogICAgbG9ja19kc3QudG9wID0gZHN0eTsKICAgIGxvY2tfZHN0LnJpZ2h0ID0gZHN0eCArIHc7CiAgICBsb2NrX2RzdC5ib3R0b20gPSBkc3R5ICsgaDsKCiAgICBicHAgPSBUaGlzLT5ieXRlc1BlclBpeGVsOwoKICAgIC8qIFdlIG5lZWQgdG8gbG9jayB0aGUgc3VyZmFjZXMsIG9yIHdlIHdvbid0IGdldCByZWZyZXNoZXMgd2hlbiBkb25lLiAqLwogICAgaWYgKFNyYyA9PSBUaGlzKQogICAgewogICAgICAgIGludCBwaXRjaDsKCiAgICAgICAgVW5pb25SZWN0KCZsb2NrX3VuaW9uLCAmbG9ja19zcmMsICZsb2NrX2RzdCk7CgogICAgICAgIC8qIExvY2sgdGhlIHVuaW9uIG9mIHRoZSB0d28gcmVjdGFuZ2xlcyAqLwogICAgICAgIHJldCA9IElXaW5lRDNEU3VyZmFjZV9Mb2NrUmVjdChpZmFjZSwgJmRsb2NrLCAmbG9ja191bmlvbiwgMCk7CiAgICAgICAgaWYocmV0ICE9IFdJTkVEM0RfT0spIGdvdG8gZXJyb3I7CgogICAgICAgIHBpdGNoID0gZGxvY2suUGl0Y2g7CiAgICAgICAgc2xvY2suUGl0Y2ggPSBkbG9jay5QaXRjaDsKCiAgICAgICAgLyogU2luY2Ugc2xvY2sgd2FzIG9yaWdpbmFsbHkgY29waWVkIGZyb20gdGhpcyBzdXJmYWNlJ3MgZGVzY3JpcHRpb24sIHdlIGNhbiBqdXN0IHJldXNlIGl0ICovCiAgICAgICAgYXNzZXJ0KFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSAhPSBOVUxMKTsKICAgICAgICBzYnVmID0gKEJZVEUgKilUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkgKyBsb2NrX3NyYy50b3AgKiBwaXRjaCArIGxvY2tfc3JjLmxlZnQgKiBicHA7CiAgICAgICAgZGJ1ZiA9IChCWVRFICopVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ICsgbG9ja19kc3QudG9wICogcGl0Y2ggKyBsb2NrX2RzdC5sZWZ0ICogYnBwOwogICAgICAgIHNFbnRyeSA9IGdldEZvcm1hdERlc2NFbnRyeShTcmMtPnJlc291cmNlLmZvcm1hdCk7CiAgICAgICAgZEVudHJ5ID0gc0VudHJ5OwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIHJldCA9IElXaW5lRDNEU3VyZmFjZV9Mb2NrUmVjdChTb3VyY2UsICZzbG9jaywgJmxvY2tfc3JjLCBXSU5FRDNETE9DS19SRUFET05MWSk7CiAgICAgICAgaWYocmV0ICE9IFdJTkVEM0RfT0spIGdvdG8gZXJyb3I7CiAgICAgICAgcmV0ID0gSVdpbmVEM0RTdXJmYWNlX0xvY2tSZWN0KGlmYWNlLCAmZGxvY2ssICZsb2NrX2RzdCwgMCk7CiAgICAgICAgaWYocmV0ICE9IFdJTkVEM0RfT0spIGdvdG8gZXJyb3I7CgogICAgICAgIHNidWYgPSBzbG9jay5wQml0czsKICAgICAgICBkYnVmID0gZGxvY2sucEJpdHM7CiAgICAgICAgVFJBQ0UoIkRzdCBpcyBhdCAlcCwgU3JjIGlzIGF0ICVwXG4iLCBkYnVmLCBzYnVmKTsKCiAgICAgICAgc0VudHJ5ID0gZ2V0Rm9ybWF0RGVzY0VudHJ5KFNyYy0+cmVzb3VyY2UuZm9ybWF0KTsKICAgICAgICBkRW50cnkgPSBnZXRGb3JtYXREZXNjRW50cnkoVGhpcy0+cmVzb3VyY2UuZm9ybWF0KTsKICAgIH0KCiAgICAvKiBIYW5kbGUgZmlyc3QgdGhlIEZPVVJDQyBzdXJmYWNlcy4uLiAqLwogICAgaWYgKHNFbnRyeS0+aXNGb3VyY2MgJiYgZEVudHJ5LT5pc0ZvdXJjYykKICAgIHsKICAgICAgICBUUkFDRSgiRm91cmNjIC0+IEZvdXJjYyBjb3B5XG4iKTsKICAgICAgICBpZiAodHJhbnMpCiAgICAgICAgICAgIEZJWE1FKCJ0cmFucyBhcmcgbm90IHN1cHBvcnRlZCB3aGVuIGEgRk9VUkNDIHN1cmZhY2UgaXMgaW52b2x2ZWRcbiIpOwogICAgICAgIGlmIChkc3R4IHx8IGRzdHkpCiAgICAgICAgICAgIEZJWE1FKCJvZmZzZXQgZm9yIGRlc3RpbmF0aW9uIHN1cmZhY2UgaXMgbm90IHN1cHBvcnRlZFxuIik7CiAgICAgICAgaWYgKFNyYy0+cmVzb3VyY2UuZm9ybWF0ICE9IFRoaXMtPnJlc291cmNlLmZvcm1hdCkKICAgICAgICB7CiAgICAgICAgICAgIEZJWE1FKCJGT1VSQ0MtPkZPVVJDQyBjb3B5IG9ubHkgc3VwcG9ydGVkIGZvciB0aGUgc2FtZSB0eXBlIG9mIHN1cmZhY2VcbiIpOwogICAgICAgICAgICByZXQgPSBXSU5FRDNERVJSX1dST05HVEVYVFVSRUZPUk1BVDsKICAgICAgICAgICAgZ290byBlcnJvcjsKICAgICAgICB9CiAgICAgICAgLyogRklYTUU6IFdhdGNoIG91dCB0aGF0IHRoZSBzaXplIGlzIGNvcnJlY3QgZm9yIEZPVVJDQyBzdXJmYWNlcyAqLwogICAgICAgIG1lbWNweShkYnVmLCBzYnVmLCBUaGlzLT5yZXNvdXJjZS5zaXplKTsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQogICAgaWYgKHNFbnRyeS0+aXNGb3VyY2MgJiYgIWRFbnRyeS0+aXNGb3VyY2MpCiAgICB7CiAgICAgICAgLyogVE9ETzogVXNlIHRoZSBsaWJ0eGNfZHh0bi5zbyBzaGFyZWQgbGlicmFyeSB0byBkbwogICAgICAgICAqIHNvZnR3YXJlIGRlY29tcHJlc3Npb24KICAgICAgICAgKi8KICAgICAgICBFUlIoIkRYVEMgZGVjb21wcmVzc2lvbiBub3Qgc3VwcG9ydGVkIGJ5IG5vd1xuIik7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICBpZiAodHJhbnMgJiAoV0lORUREQkxURkFTVF9TUkNDT0xPUktFWSB8IFdJTkVEREJMVEZBU1RfREVTVENPTE9SS0VZKSkKICAgIHsKICAgICAgICBEV09SRCBrZXlsb3csIGtleWhpZ2g7CiAgICAgICAgVFJBQ0UoIkNvbG9yIGtleWVkIGNvcHlcbiIpOwogICAgICAgIGlmICh0cmFucyAmIFdJTkVEREJMVEZBU1RfU1JDQ09MT1JLRVkpCiAgICAgICAgewogICAgICAgICAgICBrZXlsb3cgID0gU3JjLT5TcmNCbHRDS2V5LmR3Q29sb3JTcGFjZUxvd1ZhbHVlOwogICAgICAgICAgICBrZXloaWdoID0gU3JjLT5TcmNCbHRDS2V5LmR3Q29sb3JTcGFjZUhpZ2hWYWx1ZTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgLyogSSdtIG5vdCBzdXJlIGlmIHRoaXMgaXMgY29ycmVjdCAqLwogICAgICAgICAgICBGSVhNRSgiV0lORUREQkxURkFTVF9ERVNUQ09MT1JLRVkgbm90IGZ1bGx5IHN1cHBvcnRlZCB5ZXQuXG4iKTsKICAgICAgICAgICAga2V5bG93ICA9IFRoaXMtPkRlc3RCbHRDS2V5LmR3Q29sb3JTcGFjZUxvd1ZhbHVlOwogICAgICAgICAgICBrZXloaWdoID0gVGhpcy0+RGVzdEJsdENLZXkuZHdDb2xvclNwYWNlSGlnaFZhbHVlOwogICAgICAgIH0KCiNkZWZpbmUgQ09QWUJPWF9DT0xPUktFWSh0eXBlKSB7IFwKICAgICAgICAgICAgdHlwZSAqZCwgKnMsIHRtcDsgXAogICAgICAgICAgICBzID0gKHR5cGUgKikgc2J1ZjsgXAogICAgICAgICAgICBkID0gKHR5cGUgKikgZGJ1ZjsgXAogICAgICAgICAgICBmb3IgKHkgPSAwOyB5IDwgaDsgeSsrKSB7IFwKICAgICAgICAgICAgICAgIGZvciAoeCA9IDA7IHggPCB3OyB4KyspIHsgXAogICAgICAgICAgICAgICAgICAgIHRtcCA9IHNbeF07IFwKICAgICAgICAgICAgICAgICAgICBpZiAodG1wIDwga2V5bG93IHx8IHRtcCA+IGtleWhpZ2gpIGRbeF0gPSB0bXA7IFwKICAgICAgICAgICAgICAgIH0gXAogICAgICAgICAgICAgICAgcyA9ICh0eXBlICopKChCWVRFICopcyArIHNsb2NrLlBpdGNoKTsgXAogICAgICAgICAgICAgICAgZCA9ICh0eXBlICopKChCWVRFICopZCArIGRsb2NrLlBpdGNoKTsgXAogICAgICAgICAgICB9IFwKICAgICAgICAgICAgYnJlYWs7IFwKICAgICAgICB9CgogICAgICAgIHN3aXRjaCAoYnBwKSB7CiAgICAgICAgICAgIGNhc2UgMTogQ09QWUJPWF9DT0xPUktFWShCWVRFKQogICAgICAgICAgICBjYXNlIDI6IENPUFlCT1hfQ09MT1JLRVkoV09SRCkKICAgICAgICAgICAgY2FzZSA0OiBDT1BZQk9YX0NPTE9SS0VZKERXT1JEKQogICAgICAgICAgICBjYXNlIDM6CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEJZVEUgKmQsICpzOwogICAgICAgICAgICAgICAgRFdPUkQgdG1wOwogICAgICAgICAgICAgICAgcyA9IChCWVRFICopIHNidWY7CiAgICAgICAgICAgICAgICBkID0gKEJZVEUgKikgZGJ1ZjsKICAgICAgICAgICAgICAgIGZvciAoeSA9IDA7IHkgPCBoOyB5KyspCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZm9yICh4ID0gMDsgeCA8IHcgKiAzOyB4ICs9IDMpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB0bXAgPSAoRFdPUkQpc1t4XSArICgoRFdPUkQpc1t4ICsgMV0gPDwgOCkgKyAoKERXT1JEKXNbeCArIDJdIDw8IDE2KTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRtcCA8IGtleWxvdyB8fCB0bXAgPiBrZXloaWdoKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkW3ggKyAwXSA9IHNbeCArIDBdOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZFt4ICsgMV0gPSBzW3ggKyAxXTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRbeCArIDJdID0gc1t4ICsgMl07CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcyArPSBzbG9jay5QaXRjaDsKICAgICAgICAgICAgICAgICAgICBkICs9IGRsb2NrLlBpdGNoOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIEZJWE1FKCJTb3VyY2UgY29sb3Iga2V5IGJsaXR0aW5nIG5vdCBzdXBwb3J0ZWQgZm9yIGJwcCAlZFxuIixicHAqOCk7CiAgICAgICAgICAgICAgICByZXQgPSBXSU5FRDNERVJSX05PVEFWQUlMQUJMRTsKICAgICAgICAgICAgICAgIGdvdG8gZXJyb3I7CiAgICAgICAgfQojdW5kZWYgQ09QWUJPWF9DT0xPUktFWQogICAgICAgIFRSQUNFKCJDb3B5IERvbmVcbiIpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIGludCB3aWR0aCA9IHcgKiBicHA7CiAgICAgICAgVFJBQ0UoIk5PIGNvbG9yIGtleSBjb3B5XG4iKTsKICAgICAgICBmb3IgKHkgPSAwOyB5IDwgaDsgeSsrKQogICAgICAgIHsKICAgICAgICAgICAgLyogVGhpcyBpcyBwcmV0dHkgZWFzeSwgYSBsaW5lIGZvciBsaW5lIG1lbWNweSAqLwogICAgICAgICAgICBtZW1jcHkoZGJ1Ziwgc2J1Ziwgd2lkdGgpOwogICAgICAgICAgICBzYnVmICs9IHNsb2NrLlBpdGNoOwogICAgICAgICAgICBkYnVmICs9IGRsb2NrLlBpdGNoOwogICAgICAgIH0KICAgICAgICBUUkFDRSgiQ29weSBkb25lXG4iKTsKICAgIH0KCmVycm9yOgogICAgaWYgKFNyYyA9PSBUaGlzKQogICAgewogICAgICAgIElXaW5lRDNEU3VyZmFjZV9VbmxvY2tSZWN0KGlmYWNlKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBJV2luZUQzRFN1cmZhY2VfVW5sb2NrUmVjdChpZmFjZSk7CiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1VubG9ja1JlY3QoU291cmNlKTsKICAgIH0KCiAgICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSVdpbmVEM0RTdXJmYWNlOjpMb2FkVGV4dHVyZSwgR0RJIHZlcnNpb24KICoKICogVGhpcyBpcyBtdXR1YWxseSB1bnN1cHBvcnRlZCBieSBHREkgc3VyZmFjZXMKICoKICogUmV0dXJuczoKICogIEQzREVSUl9JTlZBTElEQ0FMTAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkhSRVNVTFQgV0lOQVBJCklXaW5lR0RJU3VyZmFjZUltcGxfTG9hZFRleHR1cmUoSVdpbmVEM0RTdXJmYWNlICppZmFjZSkKewogICAgRVJSKCJVbnN1cHBvcnRlZCBvbiBYMTEgc3VyZmFjZXNcbiIpOwogICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJV2luZUQzRFN1cmZhY2U6OlNhdmVTbmFwc2hvdCwgR0RJIHZlcnNpb24KICoKICogVGhpcyBtZXRob2Qgd3JpdGVzIHRoZSBzdXJmYWNlJ3MgY29udGVudHMgdG8gdGhlIGluIHRnYSBmb3JtYXQgdG8gdGhlCiAqIGZpbGUgc3BlY2lmaWVkIGluIGZpbGVuYW1lLgogKgogKiBQYXJhbXM6CiAqICBmaWxlbmFtZTogRmlsZSB0byB3cml0ZSB0bwogKgogKiBSZXR1cm5zOgogKiAgV0lORUQzREVSUl9JTlZBTElEQ0FMTCBpZiB0aGUgZmlsZSBjb3VsZG4ndCBiZSBvcGVuZWQKICogIFdJTkVEM0RfT0sgb24gc3VjY2VzcwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBpbnQgZ2V0X3NoaWZ0KERXT1JEIGNvbG9yX21hc2spIHsKICAgIGludCBzaGlmdCA9IDA7CiAgICB3aGlsZSAoY29sb3JfbWFzayA+IDB4RkYpIHsKICAgICAgICBjb2xvcl9tYXNrID4+PSAxOwogICAgICAgIHNoaWZ0ICs9IDE7CiAgICB9CiAgICB3aGlsZSAoKGNvbG9yX21hc2sgJiAweDgwKSA9PSAwKSB7CiAgICAgICAgY29sb3JfbWFzayA8PD0gMTsKICAgICAgICBzaGlmdCAtPSAxOwogICAgfQogICAgcmV0dXJuIHNoaWZ0Owp9CgoKSFJFU1VMVCBXSU5BUEkKSVdpbmVHRElTdXJmYWNlSW1wbF9TYXZlU25hcHNob3QoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwKY29uc3QgY2hhciogZmlsZW5hbWUpCnsKICAgIEZJTEUqIGYgPSBOVUxMOwogICAgVUlOVCB5ID0gMCwgeCA9IDA7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIHN0YXRpYyBjaGFyICpvdXRwdXQgPSBOVUxMOwogICAgc3RhdGljIGludCBzaXplID0gMDsKICAgIGNvbnN0IFBpeGVsRm9ybWF0RGVzYyAqZm9ybWF0RW50cnkgPSBnZXRGb3JtYXREZXNjRW50cnkoVGhpcy0+cmVzb3VyY2UuZm9ybWF0KTsKCiAgICBpZiAoVGhpcy0+cG93MldpZHRoID4gc2l6ZSkgewogICAgICAgIG91dHB1dCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBUaGlzLT5wb3cyV2lkdGggKiAzKTsKICAgICAgICBzaXplID0gVGhpcy0+cG93MldpZHRoOwogICAgfQoKCiAgICBmID0gZm9wZW4oZmlsZW5hbWUsICJ3KyIpOwogICAgaWYgKE5VTEwgPT0gZikgewogICAgICAgIEVSUigib3BlbmluZyBvZiAlcyBmYWlsZWQgd2l0aFxuIiwgZmlsZW5hbWUpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQogICAgZnByaW50ZihmLCAiUDZcbiVkICVkXG4yNTVcbiIsIFRoaXMtPnBvdzJXaWR0aCwgVGhpcy0+cG93MkhlaWdodCk7CgogICAgaWYgKFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX1A4KSB7CiAgICAgICAgdW5zaWduZWQgY2hhciB0YWJsZVsyNTZdWzNdOwogICAgICAgIGludCBpOwoKICAgICAgICBpZiAoVGhpcy0+cGFsZXR0ZSA9PSBOVUxMKSB7CiAgICAgICAgICAgIGZjbG9zZShmKTsKICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICAgICAgfQogICAgICAgIGZvciAoaSA9IDA7IGkgPCAyNTY7IGkrKykgewogICAgICAgICAgICB0YWJsZVtpXVswXSA9IFRoaXMtPnBhbGV0dGUtPnBhbGVudHNbaV0ucGVSZWQ7CiAgICAgICAgICAgIHRhYmxlW2ldWzFdID0gVGhpcy0+cGFsZXR0ZS0+cGFsZW50c1tpXS5wZUdyZWVuOwogICAgICAgICAgICB0YWJsZVtpXVsyXSA9IFRoaXMtPnBhbGV0dGUtPnBhbGVudHNbaV0ucGVCbHVlOwogICAgICAgIH0KICAgICAgICBmb3IgKHkgPSAwOyB5IDwgVGhpcy0+cG93MkhlaWdodDsgeSsrKSB7CiAgICAgICAgICAgIHVuc2lnbmVkIGNoYXIgKnNyYyA9ICh1bnNpZ25lZCBjaGFyICopIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSArICh5ICogMSAqIElXaW5lRDNEU3VyZmFjZV9HZXRQaXRjaChpZmFjZSkpOwogICAgICAgICAgICBmb3IgKHggPSAwOyB4IDwgVGhpcy0+cG93MldpZHRoOyB4KyspIHsKICAgICAgICAgICAgICAgIHVuc2lnbmVkIGNoYXIgY29sb3IgPSAqc3JjOwogICAgICAgICAgICAgICAgc3JjICs9IDE7CgogICAgICAgICAgICAgICAgb3V0cHV0WzMgKiB4ICsgMF0gPSB0YWJsZVtjb2xvcl1bMF07CiAgICAgICAgICAgICAgICBvdXRwdXRbMyAqIHggKyAxXSA9IHRhYmxlW2NvbG9yXVsxXTsKICAgICAgICAgICAgICAgIG91dHB1dFszICogeCArIDJdID0gdGFibGVbY29sb3JdWzJdOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZ3cml0ZShvdXRwdXQsIDMgKiBUaGlzLT5wb3cyV2lkdGgsIDEsIGYpOwogICAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgICAgaW50IHJlZF9zaGlmdCwgZ3JlZW5fc2hpZnQsIGJsdWVfc2hpZnQsIHBpeF93aWR0aDsKCiAgICAgICAgcGl4X3dpZHRoID0gVGhpcy0+Ynl0ZXNQZXJQaXhlbDsKCiAgICAgICAgcmVkX3NoaWZ0ID0gZ2V0X3NoaWZ0KGZvcm1hdEVudHJ5LT5yZWRNYXNrKTsKICAgICAgICBncmVlbl9zaGlmdCA9IGdldF9zaGlmdChmb3JtYXRFbnRyeS0+Z3JlZW5NYXNrKTsKICAgICAgICBibHVlX3NoaWZ0ID0gZ2V0X3NoaWZ0KGZvcm1hdEVudHJ5LT5ibHVlTWFzayk7CgogICAgICAgIGZvciAoeSA9IDA7IHkgPCBUaGlzLT5wb3cySGVpZ2h0OyB5KyspIHsKICAgICAgICAgICAgdW5zaWduZWQgY2hhciAqc3JjID0gKHVuc2lnbmVkIGNoYXIgKikgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ICsgKHkgKiAxICogSVdpbmVEM0RTdXJmYWNlX0dldFBpdGNoKGlmYWNlKSk7CiAgICAgICAgICAgIGZvciAoeCA9IDA7IHggPCBUaGlzLT5wb3cyV2lkdGg7IHgrKykgewkgICAgCiAgICAgICAgICAgICAgICB1bnNpZ25lZCBpbnQgY29sb3I7CiAgICAgICAgICAgICAgICB1bnNpZ25lZCBpbnQgY29tcDsKICAgICAgICAgICAgICAgIGludCBpOwoKICAgICAgICAgICAgICAgIGNvbG9yID0gMDsKICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBwaXhfd2lkdGg7IGkrKykgewogICAgICAgICAgICAgICAgICAgIGNvbG9yIHw9IHNyY1tpXSA8PCAoOCAqIGkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgc3JjICs9IDEgKiBwaXhfd2lkdGg7CgogICAgICAgICAgICAgICAgY29tcCA9IGNvbG9yICYgZm9ybWF0RW50cnktPnJlZE1hc2s7CiAgICAgICAgICAgICAgICBvdXRwdXRbMyAqIHggKyAwXSA9IHJlZF9zaGlmdCA+IDAgPyBjb21wID4+IHJlZF9zaGlmdCA6IGNvbXAgPDwgLXJlZF9zaGlmdDsKICAgICAgICAgICAgICAgIGNvbXAgPSBjb2xvciAmIGZvcm1hdEVudHJ5LT5ncmVlbk1hc2s7CiAgICAgICAgICAgICAgICBvdXRwdXRbMyAqIHggKyAxXSA9IGdyZWVuX3NoaWZ0ID4gMCA/IGNvbXAgPj4gZ3JlZW5fc2hpZnQgOiBjb21wIDw8IC1ncmVlbl9zaGlmdDsKICAgICAgICAgICAgICAgIGNvbXAgPSBjb2xvciAmIGZvcm1hdEVudHJ5LT5ibHVlTWFzazsKICAgICAgICAgICAgICAgIG91dHB1dFszICogeCArIDJdID0gYmx1ZV9zaGlmdCA+IDAgPyBjb21wID4+IGJsdWVfc2hpZnQgOiBjb21wIDw8IC1ibHVlX3NoaWZ0OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZ3cml0ZShvdXRwdXQsIDMgKiBUaGlzLT5wb3cyV2lkdGgsIDEsIGYpOwogICAgICAgIH0KICAgIH0KICAgIGZjbG9zZShmKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSVdpbmVEM0RTdXJmYWNlOjpQcml2YXRlU2V0dXAsIEdESSB2ZXJzaW9uCiAqCiAqIEluaXRpYWxpemVzIHRoZSBHREkgc3VyZmFjZSwgYWthIGNyZWF0ZXMgdGhlIERJQiBzZWN0aW9uIHdlIHJlbmRlciB0bwogKiBUaGUgRElCIHNlY3Rpb24gY3JlYXRpb24gaXMgZG9uZSBieSBjYWxsaW5nIEdldERDLCB3aGljaCB3aWxsIGNyZWF0ZSB0aGUKICogc2VjdGlvbiBhbmQgcmVsZWFzaW5nIHRoZSBkYyB0byBhbGxvdyB0aGUgYXBwIHRvIHVzZSBpdC4gVGhlIGRpYiBzZWN0aW9uCiAqIHdpbGwgc3RheSB1bnRpbCB0aGUgc3VyZmFjZSBpcyByZWxlYXNlZAogKgogKiBHREkgc3VyZmFjZXMgZG8gbm90IG5lZWQgdG8gYmUgYSBwb3dlciBvZiAyIGluIHNpemUsIHNvIHRoZSBwb3cyIHNpemVzCiAqIGFyZSBzZXQgdG8gdGhlIHJlYWwgc2l6ZXMgdG8gc2F2ZSBtZW1vcnkuIFRoZSBOT05QT1cyIGZsYWcgaXMgdW5zZXQgdG8KICogYXZvaWQgY29uZnVzaW9uIGluIHRoZSBzaGFyZWQgc3VyZmFjZSBjb2RlLgogKgogKiBSZXR1cm5zOgogKiAgV0lORUQzRF9PSyBvbiBzdWNjZXNzCiAqICBUaGUgcmV0dXJuIHZhbHVlcyBvZiBjYWxsZWQgbWV0aG9kcyBvbiBmYWlsdXJlCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KSFJFU1VMVCBXSU5BUEkKSVdpbmVHRElTdXJmYWNlSW1wbF9Qcml2YXRlU2V0dXAoSVdpbmVEM0RTdXJmYWNlICppZmFjZSkKewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIGlmYWNlOwogICAgSFJFU1VMVCBocjsKICAgIEhEQyBoZGM7CiAgICBsb25nIG9sZHNpemUgPSBUaGlzLT5yZXNvdXJjZS5zaXplOwoKICAgIGlmKFRoaXMtPnJlc291cmNlLnVzYWdlICYgV0lORUQzRFVTQUdFX09WRVJMQVkpCiAgICB7CiAgICAgICAgRVJSKCIoJXApIE92ZXJsYXlzIG5vdCB5ZXQgc3VwcG9ydGVkIGJ5IEdESSBzdXJmYWNlc1xuIiwgVGhpcyk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CiAgICAvKiBTeXNtZW0gdGV4dHVyZXMgaGF2ZSBtZW1vcnkgYWxyZWFkeSBhbGxvY2F0ZWQgLQogICAgICogcmVsZWFzZSBpdCwgdGhpcyBhdm9pZHMgYW4gdW5uZWNlc3NhcnkgbWVtY3B5CiAgICAgKi8KICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSk7CiAgICBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkgPSBOVUxMOwoKICAgIC8qIFdlIGRvbid0IG1pbmQgdGhlIG5vbnBvdzIgc3R1ZmYgaW4gR0RJICovCiAgICBUaGlzLT5yZXNvdXJjZS5zaXplID0gSVdpbmVEM0RTdXJmYWNlX0dldFBpdGNoKGlmYWNlKSAqIFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodDsKICAgIFRoaXMtPnBvdzJXaWR0aCA9IFRoaXMtPmN1cnJlbnREZXNjLldpZHRoOwogICAgVGhpcy0+cG93MkhlaWdodCA9IFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodDsKICAgIFRoaXMtPkZsYWdzICY9IH5TRkxBR19OT05QT1cyOwoKICAgIC8qIEFkanVzdCB0aGUgb3BlbmdsIG1lbSBjb3VudGVyICovCiAgICBnbG9iYWxDaGFuZ2VHbFJhbShUaGlzLT5yZXNvdXJjZS5zaXplIC0gb2xkc2l6ZSk7CgogICAgLyogQ2FsbCBHZXREQyB0byBjcmVhdGUgYSBESUIgc2VjdGlvbi4gV2Ugd2lsbCB1c2UgdGhhdAogICAgICogRElCIHNlY3Rpb24gZm9yIHJlbmRlcmluZwogICAgICoKICAgICAqIFJlbGVhc2UgdGhlIERDIGFmdGVyd2FyZHMgdG8gYWxsb3cgdGhlIGFwcCB0byB1c2UgaXQKICAgICAqLwogICAgaHIgPSBJV2luZUQzRFN1cmZhY2VfR2V0REMoaWZhY2UsICZoZGMpOwogICAgaWYoRkFJTEVEKGhyKSkKICAgIHsKICAgICAgICBFUlIoIiglcCkgSVdpbmVEM0RTdXJmYWNlOjpHZXREQyBmYWlsZWQgd2l0aCBociAlMDh4XG4iLCBUaGlzLCBocik7CiAgICAgICAgcmV0dXJuIGhyOwogICAgfQogICAgaHIgPSBJV2luZUQzRFN1cmZhY2VfUmVsZWFzZURDKGlmYWNlLCBoZGMpOwogICAgaWYoRkFJTEVEKGhyKSkKICAgIHsKICAgICAgICBFUlIoIiglcCkgSVdpbmVEM0RTdXJmYWNlOjpSZWxlYXNlREMgZmFpbGVkIHdpdGggaHIgJTA4eFxuIiwgVGhpcywgaHIpOwogICAgICAgIHJldHVybiBocjsKICAgIH0KCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKY29uc3QgSVdpbmVEM0RTdXJmYWNlVnRibCBJV2luZUdESVN1cmZhY2VfVnRibCA9CnsKICAgIC8qIElVbmtub3duICovCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1F1ZXJ5SW50ZXJmYWNlLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9BZGRSZWYsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1JlbGVhc2UsCiAgICAvKiBJV2luZUQzRFJlc291cmNlICovCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0dldFBhcmVudCwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0RGV2aWNlLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9TZXRQcml2YXRlRGF0YSwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0UHJpdmF0ZURhdGEsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0ZyZWVQcml2YXRlRGF0YSwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfU2V0UHJpb3JpdHksCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0dldFByaW9yaXR5LAogICAgSVdpbmVHRElTdXJmYWNlSW1wbF9QcmVMb2FkLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXRUeXBlLAogICAgLyogSVdpbmVEM0RTdXJmYWNlICovCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0dldENvbnRhaW5lciwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0RGVzYywKICAgIElXaW5lR0RJU3VyZmFjZUltcGxfTG9ja1JlY3QsCiAgICBJV2luZUdESVN1cmZhY2VJbXBsX1VubG9ja1JlY3QsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0dldERDLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9SZWxlYXNlREMsCiAgICBJV2luZUdESVN1cmZhY2VJbXBsX0ZsaXAsCiAgICBJV2luZUdESVN1cmZhY2VJbXBsX0JsdCwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0Qmx0U3RhdHVzLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXRGbGlwU3RhdHVzLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9Jc0xvc3QsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1Jlc3RvcmUsCiAgICBJV2luZUdESVN1cmZhY2VJbXBsX0JsdEZhc3QsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0dldFBhbGV0dGUsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1NldFBhbGV0dGUsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1JlYWxpemVQYWxldHRlLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9TZXRDb2xvcktleSwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0UGl0Y2gsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1NldE1lbSwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfU2V0T3ZlcmxheVBvc2l0aW9uLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXRPdmVybGF5UG9zaXRpb24sCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1VwZGF0ZU92ZXJsYXlaT3JkZXIsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1VwZGF0ZU92ZXJsYXksCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1NldENsaXBwZXIsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0dldENsaXBwZXIsCiAgICAvKiBJbnRlcm5hbCB1c2U6ICovCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0FkZERpcnR5UmVjdCwKICAgIElXaW5lR0RJU3VyZmFjZUltcGxfTG9hZFRleHR1cmUsCiAgICBJV2luZUdESVN1cmZhY2VJbXBsX1NhdmVTbmFwc2hvdCwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfU2V0Q29udGFpbmVyLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9TZXRHbFRleHR1cmVEZXNjLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXRHbERlc2MsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0dldERhdGEsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1NldEZvcm1hdCwKICAgIElXaW5lR0RJU3VyZmFjZUltcGxfUHJpdmF0ZVNldHVwCn07Cg==