LyoKICogMkQgU3VyZmFjZSBpbXBsZW1lbnRhdGlvbiB3aXRob3V0IE9wZW5HTAogKgogKiBDb3B5cmlnaHQgMTk5Ny0yMDAwIE1hcmN1cyBNZWlzc25lcgogKiBDb3B5cmlnaHQgMTk5OC0yMDAwIExpb25lbCBVbG1lcgogKiBDb3B5cmlnaHQgMjAwMC0yMDAxIFRyYW5zR2FtaW5nIFRlY2hub2xvZ2llcyBJbmMuCiAqIENvcHlyaWdodCAyMDAyLTIwMDUgSmFzb24gRWRtZWFkZXMKICogQ29weXJpZ2h0IDIwMDItMjAwMyBSYXBoYWVsIEp1bnF1ZWlyYQogKiBDb3B5cmlnaHQgMjAwNCBDaHJpc3RpYW4gQ29zdGEKICogQ29weXJpZ2h0IDIwMDUgT2xpdmVyIFN0aWViZXIKICogQ29weXJpZ2h0IDIwMDYgU3RlZmFuIET2c2luZ2VyCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQQogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKI2luY2x1ZGUgIndpbmUvcG9ydC5oIgojaW5jbHVkZSAid2luZWQzZF9wcml2YXRlLmgiCgojaW5jbHVkZSA8YXNzZXJ0Lmg+CiNpbmNsdWRlIDxzdGRpby5oPgoKLyogVXNlIHRoZSBkM2Rfc3VyZmFjZSBkZWJ1ZyBjaGFubmVsIHRvIGhhdmUgb25lIGNoYW5uZWwgZm9yIGFsbCBzdXJmYWNlcyAqLwpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChkM2Rfc3VyZmFjZSk7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogeDExX2NvcHlfdG9fc2NyZWVuCiAqCiAqIEhlbHBlciBmdW5jdGlvbiB0aGF0IGJsdHMgdGhlIGZyb250IGJ1ZmZlciBjb250ZW50cyB0byB0aGUgdGFyZ2V0IHdpbmRvdwogKgogKiBQYXJhbXM6CiAqICBUaGlzOiBTdXJmYWNlIHRvIGNvcHkgZnJvbQogKiAgcmM6IFJlY3RhbmdsZSB0byBjb3B5CiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIHZvaWQKeDExX2NvcHlfdG9fc2NyZWVuKElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMsCiAgICAgICAgICAgICAgICAgICBMUFJFQ1QgcmMpCnsKICAgIGlmKFRoaXMtPnJlc291cmNlLnVzYWdlICYgV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVCkKICAgIHsKICAgICAgICBQT0lOVCBvZmZzZXQgPSB7MCwwfTsKICAgICAgICBIV05EIGhEaXNwbGF5V25kOwogICAgICAgIEhEQyBoRGlzcGxheURDOwogICAgICAgIEhEQyBoU3VyZmFjZURDID0gMDsKICAgICAgICBSRUNUIGRyYXdyZWN0OwogICAgICAgIFRSQUNFKCIoJXApLT4oJXApOiBDb3B5aW5nIHRvIHNjcmVlblxuIiwgVGhpcywgcmMpOwoKICAgICAgICBoU3VyZmFjZURDID0gVGhpcy0+aERDOwoKICAgICAgICBoRGlzcGxheVduZCA9IFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2UtPmRkcmF3X3dpbmRvdzsKICAgICAgICBoRGlzcGxheURDID0gR2V0RENFeChoRGlzcGxheVduZCwgMCwgRENYX0NMSVBTSUJMSU5HU3xEQ1hfQ0FDSEUpOwogICAgICAgIGlmKHJjKQogICAgICAgIHsKICAgICAgICAgICAgVFJBQ0UoIiBjb3B5aW5nIHJlY3QgKCVsZCwlbGQpLT4oJWxkLCVsZCksIG9mZnNldCAoJWxkLCVsZClcbiIsCiAgICAgICAgICAgIHJjLT5sZWZ0LCByYy0+dG9wLCByYy0+cmlnaHQsIHJjLT5ib3R0b20sIG9mZnNldC54LCBvZmZzZXQueSk7CiAgICAgICAgfQojaWYgMAogICAgICAgIC8qIEZJWE1FOiB0aGlzIGRvZXNuJ3Qgd29yay4uLiBpZiB1c2VycyByZWFsbHkgd2FudCB0byBydW4KICAgICAgICAqIFggaW4gOGJwcCwgdGhlbiB3ZSBuZWVkIHRvIGNhbGwgZGlyZWN0bHkgaW50byBkaXNwbGF5LmRydgogICAgICAgICogKG9yIFdpbmUncyBlcXVpdmFsZW50KSwgYW5kIGZvcmNlIGEgcHJpdmF0ZSBjb2xvcm1hcAogICAgICAgICogd2l0aG91dCBkZWZhdWx0IGVudHJpZXMuICovCiAgICAgICAgaWYgKFRoaXMtPnBhbGV0dGUpIHsKICAgICAgICAgICAgU2VsZWN0UGFsZXR0ZShoRGlzcGxheURDLCBUaGlzLT5wYWxldHRlLT5ocGFsLCBGQUxTRSk7CiAgICAgICAgICAgIFJlYWxpemVQYWxldHRlKGhEaXNwbGF5REMpOyAvKiBzZW5kcyBtZXNzYWdlcyA9PiBkZWFkbG9ja3MgKi8KICAgICAgICB9CiNlbmRpZgogICAgICAgIGRyYXdyZWN0LmxlZnQJPSAwOwogICAgICAgIGRyYXdyZWN0LnJpZ2h0CT0gVGhpcy0+Y3VycmVudERlc2MuV2lkdGg7CiAgICAgICAgZHJhd3JlY3QudG9wCT0gMDsKICAgICAgICBkcmF3cmVjdC5ib3R0b20JPSBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQ7CgojaWYgMAogICAgICAgIC8qIFRPRE86IFN1cHBvcnQgY2xpcHBlcnMgKi8KICAgICAgICBpZiAoVGhpcy0+Y2xpcHBlcikKICAgICAgICB7CiAgICAgICAgICAgIFJFQ1QgeHJjOwogICAgICAgICAgICBIV05EIGh3bmQgPSBUaGlzLT5jbGlwcGVyLT5oV25kOwogICAgICAgICAgICBpZiAoaHduZCAmJiBHZXRDbGllbnRSZWN0KGh3bmQsJnhyYykpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIE9mZnNldFJlY3QoJnhyYyxvZmZzZXQueCxvZmZzZXQueSk7CiAgICAgICAgICAgICAgICBJbnRlcnNlY3RSZWN0KCZkcmF3cmVjdCwmZHJhd3JlY3QsJnhyYyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiNlbmRpZgogICAgICAgIGlmIChyYykKICAgICAgICB7CiAgICAgICAgICAgIEludGVyc2VjdFJlY3QoJmRyYXdyZWN0LCZkcmF3cmVjdCxyYyk7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIC8qIE9ubHkgdXNlIHRoaXMgaWYgdGhlIGNhbGxlciBkaWQgbm90IHBhc3MgYSByZWN0YW5nbGUsIHNpbmNlCiAgICAgICAgICAgICAqIGR1ZSB0byBkb3VibGUgbG9ja2luZyB0aGlzIGNvdWxkIGJlIHRoZSB3cm9uZyBvbmUgLi4uCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAoVGhpcy0+bG9ja2VkUmVjdC5sZWZ0ICE9IFRoaXMtPmxvY2tlZFJlY3QucmlnaHQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEludGVyc2VjdFJlY3QoJmRyYXdyZWN0LCZkcmF3cmVjdCwmVGhpcy0+bG9ja2VkUmVjdCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEJpdEJsdChoRGlzcGxheURDLAogICAgICAgICAgICAgICBkcmF3cmVjdC5sZWZ0LW9mZnNldC54LCBkcmF3cmVjdC50b3Atb2Zmc2V0LnksCiAgICAgICAgICAgICAgIGRyYXdyZWN0LnJpZ2h0LWRyYXdyZWN0LmxlZnQsIGRyYXdyZWN0LmJvdHRvbS1kcmF3cmVjdC50b3AsCiAgICAgICAgICAgICAgIGhTdXJmYWNlREMsCiAgICAgICAgICAgICAgIGRyYXdyZWN0LmxlZnQsIGRyYXdyZWN0LnRvcCwKICAgICAgICAgICAgICAgU1JDQ09QWSk7CiAgICAgICAgUmVsZWFzZURDKGhEaXNwbGF5V25kLCBoRGlzcGxheURDKTsKICAgIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElXaW5lRDNEU3VyZmFjZTo6UHJlTG9hZCwgR0RJIHZlcnNpb24KICoKICogVGhpcyBjYWxsIGlzIHVuc3VwcG9ydGVkIG9uIEdESSBzdXJmYWNlcywgaWYgaXQncyBjYWxsZWQgc29tZXRoaW5nIHdlbnQKICogd3JvbmcgaW4gdGhlIHBhcmVudCBsaWJyYXJ5LiBXcml0ZSBhbiBpbmZvcm1hdGl2ZSB3YXJuaW5nCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIHZvaWQgV0lOQVBJCklXaW5lR0RJU3VyZmFjZUltcGxfUHJlTG9hZChJV2luZUQzRFN1cmZhY2UgKmlmYWNlKQp7CiAgICBFUlIoIiglcCk6IFByZUxvYWQgaXMgbm90IHN1cHBvcnRlZCBvbiBYMTEgc3VyZmFjZXMhXG4iLCBpZmFjZSk7CiAgICBFUlIoIiglcCk6IE1vc3QgbGlrZWx5IHRoZSBwYXJlbnQgbGlicmFyeSBkaWQgc29tZXRoaW5nIHdyb25nLlxuIiwgaWZhY2UpOwogICAgRVJSKCIoJXApOiBQbGVhc2UgcmVwb3J0IHRvIHdpbmUtZGV2ZWxcbiIsIGlmYWNlKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElXaW5lRDNEU3VyZmFjZTo6TG9ja1JlY3QsIEdESSB2ZXJzaW9uCiAqCiAqIExvY2tzIHRoZSBzdXJmYWNlIGFuZCByZXR1cm5zIGEgcG9pbnRlciB0byB0aGUgc3VyZmFjZSBtZW1vcnkKICoKICogUGFyYW1zOgogKiAgcExvY2tlZFJlY3Q6IEFkZHJlc3MgdG8gcmV0dXJuIHRoZSBsb2NraW5nIGluZm8gYXQKICogIHBSZWN0OiBSZWN0YW5nbGUgdG8gbG9jawogKiAgRmxhZ3M6IFNvbWUgZmxhZ3MKICoKICogUmV0dXJuczoKICogIFdJTkVEM0RfT0sgb24gc3VjY2VzcwogKiAgV0lORUQzREVSUl9JTlZBTElEQ0FMTCBvbiBlcnJvcnMKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSVdpbmVHRElTdXJmYWNlSW1wbF9Mb2NrUmVjdChJV2luZUQzRFN1cmZhY2UgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RMT0NLRURfUkVDVCogcExvY2tlZFJlY3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ09OU1QgUkVDVCogcFJlY3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MpCnsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwoKICAgIC8qIEFscmVhZHkgbG9ja2VkPyAqLwogICAgaWYoVGhpcy0+RmxhZ3MgJiBTRkxBR19MT0NLRUQpCiAgICB7CiAgICAgICAgRVJSKCIoJXApIFN1cmZhY2UgYWxyZWFkeSBsb2NrZWRcbiIsIFRoaXMpOwogICAgICAgIC8qIFdoYXQgc2hvdWxkIEkgcmV0dXJuIGhlcmU/ICovCiAgICAgICAgcmV0dXJuIEQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICBpZiAoIShUaGlzLT5GbGFncyAmIFNGTEFHX0xPQ0tBQkxFKSkKICAgIHsKICAgICAgICAvKiBUaGlzIGlzIHNvbWUgR0wgc3BlY2lmaWMgdGhpbmcsIHNlZSB0aGUgT3BlbkdMIHZlcnNpb24gb2YKICAgICAgICAgKiB0aGlzIG1ldGhvZCwgYnV0IGNoZWNrIGZvciB0aGUgZmxhZyBhbmQgd3JpdGUgYSB0cmFjZQogICAgICAgICAqLwogICAgICAgIFRSQUNFKCJXYXJuaW5nOiB0cnlpbmcgdG8gbG9jayB1bmxvY2thYmxlIHN1cmZAJXBcbiIsIFRoaXMpOwogICAgfQoKICAgIFRSQUNFKCIoJXApIDogcmVjdEAlcCBmbGFncyglMDhseCksIG91dHB1dCBsb2NrZWRSZWN0QCVwLCBtZW1vcnlAJXBcbiIsCiAgICAgICAgICBUaGlzLCBwUmVjdCwgRmxhZ3MsIHBMb2NrZWRSZWN0LCBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkpOwoKICAgIHBMb2NrZWRSZWN0LT5QaXRjaCA9IElXaW5lRDNEU3VyZmFjZV9HZXRQaXRjaChpZmFjZSk7CgogICAgaWYgKE5VTEwgPT0gcFJlY3QpCiAgICB7CiAgICAgICAgcExvY2tlZFJlY3QtPnBCaXRzID0gVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5OwogICAgICAgIFRoaXMtPmxvY2tlZFJlY3QubGVmdCAgID0gMDsKICAgICAgICBUaGlzLT5sb2NrZWRSZWN0LnRvcCAgICA9IDA7CiAgICAgICAgVGhpcy0+bG9ja2VkUmVjdC5yaWdodCAgPSBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aDsKICAgICAgICBUaGlzLT5sb2NrZWRSZWN0LmJvdHRvbSA9IFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodDsKCiAgICAgICAgVFJBQ0UoIkxvY2tlZCBSZWN0ICglcCkgPSBsICVsZCwgdCAlbGQsIHIgJWxkLCBiICVsZFxuIiwKICAgICAgICAmVGhpcy0+bG9ja2VkUmVjdCwgVGhpcy0+bG9ja2VkUmVjdC5sZWZ0LCBUaGlzLT5sb2NrZWRSZWN0LnRvcCwKICAgICAgICBUaGlzLT5sb2NrZWRSZWN0LnJpZ2h0LCBUaGlzLT5sb2NrZWRSZWN0LmJvdHRvbSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgVFJBQ0UoIkxvY2sgUmVjdCAoJXApID0gbCAlbGQsIHQgJWxkLCByICVsZCwgYiAlbGRcbiIsCiAgICAgICAgICAgICAgcFJlY3QsIHBSZWN0LT5sZWZ0LCBwUmVjdC0+dG9wLCBwUmVjdC0+cmlnaHQsIHBSZWN0LT5ib3R0b20pOwoKICAgICAgICBpZiAoKHBSZWN0LT50b3AgPCAwKSB8fAogICAgICAgICAgICAgKHBSZWN0LT5sZWZ0IDwgMCkgfHwKICAgICAgICAgICAgIChwUmVjdC0+bGVmdCA+PSBwUmVjdC0+cmlnaHQpIHx8CiAgICAgICAgICAgICAocFJlY3QtPnRvcCA+PSBwUmVjdC0+Ym90dG9tKSB8fAogICAgICAgICAgICAgKHBSZWN0LT5yaWdodCA+IFRoaXMtPmN1cnJlbnREZXNjLldpZHRoKSB8fAogICAgICAgICAgICAgKHBSZWN0LT5ib3R0b20gPiBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQpKQogICAgICAgIHsKICAgICAgICAgICAgV0FSTigiIEludmFsaWQgdmFsdWVzIGluIHBSZWN0ICEhIVxuIik7CiAgICAgICAgICAgIHJldHVybiBEM0RFUlJfSU5WQUxJRENBTEw7CiAgICAgICAgfQoKICAgICAgICBpZiAoVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMSkKICAgICAgICB7CiAgICAgICAgICAgIC8qIERYVDEgaXMgaGFsZiBieXRlIHBlciBwaXhlbCAqLwogICAgICAgICAgICBwTG9ja2VkUmVjdC0+cEJpdHMgPSBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHBMb2NrZWRSZWN0LT5QaXRjaCAqIHBSZWN0LT50b3ApICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgocFJlY3QtPmxlZnQgKiBUaGlzLT5ieXRlc1BlclBpeGVsIC8gMikpOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBwTG9ja2VkUmVjdC0+cEJpdHMgPSBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAocExvY2tlZFJlY3QtPlBpdGNoICogcFJlY3QtPnRvcCkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAocFJlY3QtPmxlZnQgKiBUaGlzLT5ieXRlc1BlclBpeGVsKTsKICAgICAgICB9CiAgICAgICAgVGhpcy0+bG9ja2VkUmVjdC5sZWZ0ICAgPSBwUmVjdC0+bGVmdDsKICAgICAgICBUaGlzLT5sb2NrZWRSZWN0LnRvcCAgICA9IHBSZWN0LT50b3A7CiAgICAgICAgVGhpcy0+bG9ja2VkUmVjdC5yaWdodCAgPSBwUmVjdC0+cmlnaHQ7CiAgICAgICAgVGhpcy0+bG9ja2VkUmVjdC5ib3R0b20gPSBwUmVjdC0+Ym90dG9tOwogICAgfQoKICAgIC8qIE5vIGRpcnRpZnlpbmcgaXMgbmVlZGVkIGZvciB0aGlzIHN1cmZhY2UgaW1wbGVtZW50YXRpb24gKi8KICAgIFRSQUNFKCJyZXR1cm5pbmcgbWVtb3J5QCVwLCBwaXRjaCglZClcbiIsIHBMb2NrZWRSZWN0LT5wQml0cywgcExvY2tlZFJlY3QtPlBpdGNoKTsKCiAgICBUaGlzLT5GbGFncyB8PSBTRkxBR19MT0NLRUQ7CiAgICByZXR1cm4gRDNEX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSVdpbmVEM0RTdXJmYWNlOjpVbmxvY2tSZWN0LCBHREkgdmVyc2lvbgogKgogKiBVbmxvY2tzIGEgc3VyZmFjZS4gVGhpcyBpbXBsZW1lbnRhdGlvbiBkb2Vzbid0IGRvIG11Y2gsIGV4Y2VwdCB1cGRhdGluZwogKiB0aGUgd2luZG93IGlmIHRoZSBmcm9udCBidWZmZXIgaXMgdW5sb2NrZWQKICoKICogUmV0dXJuczoKICogIFdJTkVEM0RfT0sgb24gc3VjY2VzcwogKiAgV0lORUQzREVSUl9JTlZBTElEQ0FMTCBvbiBmYWlsdXJlCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklXaW5lR0RJU3VyZmFjZUltcGxfVW5sb2NrUmVjdChJV2luZUQzRFN1cmZhY2UgKmlmYWNlKQp7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqZGV2ID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKSBUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlOwogICAgVFJBQ0UoIiglcClcbiIsIFRoaXMpOwoKICAgIGlmICghKFRoaXMtPkZsYWdzICYgU0ZMQUdfTE9DS0VEKSkKICAgIHsKICAgICAgICBXQVJOKCJ0cnlpbmcgdG8gVW5sb2NrIGFuIHVubG9ja2VkIHN1cmZAJXBcbiIsIFRoaXMpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIC8qIENhbiBiZSB1c2VmdWwgZm9yIGRlYnVnZ2luZyAqLwojaWYgMAogICAgICAgIHsKICAgICAgICAgICAgc3RhdGljIHVuc2lnbmVkIGludCBnZW4gPSAwOwogICAgICAgICAgICBjaGFyIGJ1ZmZlcls0MDk2XTsKICAgICAgICAgICAgKytnZW47CiAgICAgICAgICAgIGlmICgoZ2VuICUgMTApID09IDApIHsKICAgICAgICAgICAgICAgIHNucHJpbnRmKGJ1ZmZlciwgc2l6ZW9mKGJ1ZmZlciksICIvdG1wL3N1cmZhY2UlcF90eXBlJXVfbGV2ZWwldV8ldS5wcG0iLCBUaGlzLCBUaGlzLT5nbERlc2NyaXB0aW9uLnRhcmdldCwgVGhpcy0+Z2xEZXNjcmlwdGlvbi5sZXZlbCwgZ2VuKTsKICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZUltcGxfU2F2ZVNuYXBzaG90KGlmYWNlLCBidWZmZXIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIGRlYnVnZ2luZyBjcmFzaCBjb2RlCiAgICAgICAgICAgIGlmIChnZW4gPT0gMjUwKSB7CiAgICAgICAgICAgICAgdm9pZCoqIHRlc3QgPSBOVUxMOwogICAgICAgICAgICAgICp0ZXN0ID0gMDsKICAgICAgICAgICAgfQogICAgICAgICAgICAqLwogICAgICAgIH0KI2VuZGlmCgogICAgLyogVXBkYXRlIHRoZSBzY3JlZW4gKi8KICAgIGlmKFRoaXMgPT0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgZGV2LT5kZHJhd19wcmltYXJ5KQogICAgewogICAgICAgIHgxMV9jb3B5X3RvX3NjcmVlbihUaGlzLCAmVGhpcy0+bG9ja2VkUmVjdCk7CiAgICB9CgogICAgVGhpcy0+RmxhZ3MgJj0gflNGTEFHX0xPQ0tFRDsKICAgIG1lbXNldCgmVGhpcy0+bG9ja2VkUmVjdCwgMCwgc2l6ZW9mKFJFQ1QpKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSVdpbmVEM0RTdXJmYWNlOjpGbGlwLCBHREkgdmVyc2lvbgogKgogKiBGbGlwcyAyIGZsaXBwaW5nIGVuYWJsZWQgc3VyZmFjZXMuIERldGVybWluaW5nIHRoZSAyIHRhcmdldHMgaXMgZG9uZSBieQogKiB0aGUgcGFyZW50IGxpYnJhcnkuIFRoaXMgaW1wbGVtZW50YXRpb24gY2hhbmdlcyB0aGUgZGF0YSBwb2ludGVycyBvZiB0aGUKICogc3VyZmFjZXMgYW5kIGNvcGllcyB0aGUgbmV3IGZyb250IGJ1ZmZlciBjb250ZW50IHRvIHRoZSBzY3JlZW4KICoKICogUGFyYW1zOgogKiAgb3ZlcnJpZGU6IEZsaXBwaW5nIHRhcmdldChlLmcuIGJhY2sgYnVmZmVyKQogKgogKiBSZXR1cm5zOgogKiAgV0lORUQzRF9PSyBvbiBzdWNjZXNzCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklXaW5lR0RJU3VyZmFjZUltcGxfRmxpcChJV2luZUQzRFN1cmZhY2UgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlICpvdmVycmlkZSwKICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzKQp7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgaWZhY2U7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUYXJnZXQgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBvdmVycmlkZTsKICAgIFRSQUNFKCIoJXApLT4oJXAsJWx4KVxuIiwgVGhpcywgb3ZlcnJpZGUsIEZsYWdzKTsKCiAgICBUUkFDRSgiKCVwKSBGbGlwcGluZyB0byBzdXJmYWNlICVwXG4iLCBUaGlzLCBUYXJnZXQpOwoKICAgIGlmKFRhcmdldCA9PSBOVUxMKQogICAgewogICAgICAgIEVSUigiKCVwKTogQ2FuJ3QgZmxpcCB3aXRob3V0IGEgdGFyZ2V0XG4iLCBUaGlzKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICAvKiBGbGlwIHRoZSBEQyAqLwogICAgewogICAgICAgIEhEQyB0bXA7CiAgICAgICAgdG1wID0gVGhpcy0+aERDOwogICAgICAgIFRoaXMtPmhEQyA9IFRhcmdldC0+aERDOwogICAgICAgIFRhcmdldC0+aERDID0gdG1wOwogICAgfQoKICAgIC8qIEZsaXAgdGhlIERJQnNlY3Rpb24gKi8KICAgIHsKICAgICAgICBIQklUTUFQIHRtcDsKICAgICAgICB0bXAgPSBUaGlzLT5kaWIuRElCc2VjdGlvbjsKICAgICAgICBUaGlzLT5kaWIuRElCc2VjdGlvbiA9IFRhcmdldC0+ZGliLkRJQnNlY3Rpb247CiAgICAgICAgVGFyZ2V0LT5kaWIuRElCc2VjdGlvbiA9IHRtcDsKICAgIH0KCiAgICAvKiBGbGlwIHRoZSBzdXJmYWNlIGRhdGEgKi8KICAgIHsKICAgICAgICB2b2lkKiB0bXA7CgogICAgICAgIHRtcCA9IFRoaXMtPmRpYi5iaXRtYXBfZGF0YTsKICAgICAgICBUaGlzLT5kaWIuYml0bWFwX2RhdGEgPSBUYXJnZXQtPmRpYi5iaXRtYXBfZGF0YTsKICAgICAgICBUYXJnZXQtPmRpYi5iaXRtYXBfZGF0YSA9IHRtcDsKCiAgICAgICAgdG1wID0gVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5OwogICAgICAgIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSA9IFRhcmdldC0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5OwogICAgICAgIFRhcmdldC0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ID0gdG1wOwogICAgfQoKICAgIC8qIGNsaWVudF9tZW1vcnkgc2hvdWxkIG5vdCBiZSBkaWZmZXJlbnQsIGJ1dCBqdXN0IGluIGNhc2UgKi8KICAgIHsKICAgICAgICBCT09MIHRtcDsKICAgICAgICB0bXAgPSBUaGlzLT5kaWIuY2xpZW50X21lbW9yeTsKICAgICAgICBUaGlzLT5kaWIuY2xpZW50X21lbW9yeSA9IFRhcmdldC0+ZGliLmNsaWVudF9tZW1vcnk7CiAgICAgICAgVGFyZ2V0LT5kaWIuY2xpZW50X21lbW9yeSA9IHRtcDsKICAgIH0KCiAgICAvKiBVc2VmdWwgZm9yIGRlYnVnZ2luZyAqLwojaWYgMAogICAgICAgIHsKICAgICAgICAgICAgc3RhdGljIHVuc2lnbmVkIGludCBnZW4gPSAwOwogICAgICAgICAgICBjaGFyIGJ1ZmZlcls0MDk2XTsKICAgICAgICAgICAgKytnZW47CiAgICAgICAgICAgIGlmICgoZ2VuICUgMTApID09IDApIHsKICAgICAgICAgICAgICAgIHNucHJpbnRmKGJ1ZmZlciwgc2l6ZW9mKGJ1ZmZlciksICIvdG1wL3N1cmZhY2UlcF90eXBlJXVfbGV2ZWwldV8ldS5wcG0iLCBUaGlzLCBUaGlzLT5nbERlc2NyaXB0aW9uLnRhcmdldCwgVGhpcy0+Z2xEZXNjcmlwdGlvbi5sZXZlbCwgZ2VuKTsKICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZUltcGxfU2F2ZVNuYXBzaG90KGlmYWNlLCBidWZmZXIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIGRlYnVnZ2luZyBjcmFzaCBjb2RlCiAgICAgICAgICAgIGlmIChnZW4gPT0gMjUwKSB7CiAgICAgICAgICAgICAgdm9pZCoqIHRlc3QgPSBOVUxMOwogICAgICAgICAgICAgICp0ZXN0ID0gMDsKICAgICAgICAgICAgfQogICAgICAgICAgICAqLwogICAgICAgIH0KI2VuZGlmCgogICAgLyogVXBkYXRlIHRoZSBzY3JlZW4gKi8KICAgIHgxMV9jb3B5X3RvX3NjcmVlbihUaGlzLCBOVUxMKTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF9CbHRfQ29sb3JGaWxsCiAqCiAqIEhlbHBlciBmdW5jdGlvbiB0aGF0IGZpbGxzIGEgbWVtb3J5IGFyZWEgd2l0aCBhIHNwZWNpZmljIGNvbG9yCiAqCiAqIFBhcmFtczoKICogIGJ1ZjogbWVtb3J5IGFkZHJlc3MgdG8gc3RhcnQgZmlsbGluZyBhdAogKiAgd2lkdGgsIGhlaWdodDogRGltZW5zaW9ucyBvZiB0aGUgYXJlYSB0byBmaWxsCiAqICBicHA6IEJpdCBkZXB0aCBvZiB0aGUgc3VyZmFjZQogKiAgbFBpdGNoOiBwaXRjaCBvZiB0aGUgc3VyZmFjZQogKiAgY29sb3I6IENvbG9yIHRvIGZpbGwgd2l0aAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUCl9CbHRfQ29sb3JGaWxsKEJZVEUgKmJ1ZiwKICAgICAgICAgICAgICAgaW50IHdpZHRoLCBpbnQgaGVpZ2h0LAogICAgICAgICAgICAgICBpbnQgYnBwLCBMT05HIGxQaXRjaCwKICAgICAgICAgICAgICAgRFdPUkQgY29sb3IpCnsKICAgIGludCB4LCB5OwogICAgTFBCWVRFIGZpcnN0OwoKICAgIC8qIERvIGZpcnN0IHJvdyAqLwoKI2RlZmluZSBDT0xPUkZJTExfUk9XKHR5cGUpIFwKeyBcCiAgICB0eXBlICpkID0gKHR5cGUgKikgYnVmOyBcCiAgICBmb3IgKHggPSAwOyB4IDwgd2lkdGg7IHgrKykgXAoJZFt4XSA9ICh0eXBlKSBjb2xvcjsgXAogICAgYnJlYWs7IFwKfQogICAgc3dpdGNoKGJwcCkKICAgIHsKICAgICAgICBjYXNlIDE6IENPTE9SRklMTF9ST1coQllURSkKICAgICAgICBjYXNlIDI6IENPTE9SRklMTF9ST1coV09SRCkKICAgICAgICBjYXNlIDM6CiAgICAgICAgewogICAgICAgICAgICBCWVRFICpkID0gKEJZVEUgKikgYnVmOwogICAgICAgICAgICBmb3IgKHggPSAwOyB4IDwgd2lkdGg7IHgrKyxkKz0zKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBkWzBdID0gKGNvbG9yICAgICkgJiAweEZGOwogICAgICAgICAgICAgICAgZFsxXSA9IChjb2xvcj4+IDgpICYgMHhGRjsKICAgICAgICAgICAgICAgIGRbMl0gPSAoY29sb3I+PjE2KSAmIDB4RkY7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGNhc2UgNDogQ09MT1JGSUxMX1JPVyhEV09SRCkKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBGSVhNRSgiQ29sb3IgZmlsbCBub3QgaW1wbGVtZW50ZWQgZm9yIGJwcCAlZCFcbiIsIGJwcCo4KTsKICAgICAgICAgICAgcmV0dXJuIERERVJSX1VOU1VQUE9SVEVEOwogICAgfQoKI3VuZGVmIENPTE9SRklMTF9ST1cKCiAgICAvKiBOb3cgY29weSBmaXJzdCByb3cgKi8KICAgIGZpcnN0ID0gYnVmOwogICAgZm9yICh5ID0gMTsgeSA8IGhlaWdodDsgeSsrKQogICAgewogICAgICAgIGJ1ZiArPSBsUGl0Y2g7CiAgICAgICAgbWVtY3B5KGJ1ZiwgZmlyc3QsIHdpZHRoICogYnBwKTsKICAgIH0KICAgIHJldHVybiBERF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElXaW5lRDNEU3VyZmFjZTo6Qmx0LCBHREkgdmVyc2lvbgogKgogKiBQZXJmb3JtcyBibGl0cyB0byBhIHN1cmZhY2UsIGVpZ2hlciBmcm9tIGEgc291cmNlIG9mIHNvdXJjZS1sZXNzIGJsdHMKICogVGhpcyBpcyB0aGUgbWFpbiBmdW5jdGlvbmFsaXR5IG9mIERpcmVjdERyYXcKICoKICogUGFyYW1zOgogKiAgRGVzdFJlY3Q6IERlc3RpbmF0aW9uIHJlY3RhbmdsZSB0byB3cml0ZSB0bwogKiAgU3JjU3VyZmFjZTogU291cmNlIHN1cmZhY2UsIGNhbiBiZSBOVUxMCiAqICBTcmNSZWN0OiBTb3VyY2UgcmVjdGFuZ2xlCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KSFJFU1VMVCBXSU5BUEkKSVdpbmVHRElTdXJmYWNlSW1wbF9CbHQoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgUkVDVCAqRGVzdFJlY3QsCiAgICAgICAgICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZSAqU3JjU3VyZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgUkVDVCAqU3JjUmVjdCwKICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgIEREQkxURlggKkREQmx0RngpCnsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBpZmFjZTsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlNyYyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIFNyY1N1cmZhY2U7CiAgICBSRUNUCQl4ZHN0LHhzcmM7CiAgICBIUkVTVUxUCQlyZXQgPSBERF9PSzsKICAgIFdJTkVEM0RMT0NLRURfUkVDVCAgZGxvY2ssIHNsb2NrOwogICAgV0lORUQzREZPUk1BVCAgICAgICBkZm10ID0gV0lORUQzREZNVF9VTktOT1dOLCBzZm10ID0gV0lORUQzREZNVF9VTktOT1dOOwogICAgaW50IGJwcCwgc3JjaGVpZ2h0LCBzcmN3aWR0aCwgZHN0aGVpZ2h0LCBkc3R3aWR0aCwgd2lkdGg7CiAgICBpbnQgeCwgeTsKICAgIGNvbnN0IFBpeGVsRm9ybWF0RGVzYyAqc0VudHJ5LCAqZEVudHJ5OwogICAgTFBCWVRFIGRidWYsIHNidWY7CiAgICBUUkFDRSgiKCVwKS0+KCVwLCVwLCVwLCVseCwlcClcbiIsIFRoaXMsIERlc3RSZWN0LCBTcmMsIFNyY1JlY3QsIEZsYWdzLCBEREJsdEZ4KTsKCiAgICBpZiAoVFJBQ0VfT04oZDNkX3N1cmZhY2UpKQogICAgewogICAgICAgIGlmIChEZXN0UmVjdCkgVFJBQ0UoIlx0ZGVzdHJlY3QgOiVsZHglbGQtJWxkeCVsZFxuIiwKICAgICAgICBEZXN0UmVjdC0+bGVmdCwgRGVzdFJlY3QtPnRvcCwgRGVzdFJlY3QtPnJpZ2h0LCBEZXN0UmVjdC0+Ym90dG9tKTsKICAgICAgICBpZiAoU3JjUmVjdCkgVFJBQ0UoIlx0c3JjcmVjdCAgOiVsZHglbGQtJWxkeCVsZFxuIiwKICAgICAgICBTcmNSZWN0LT5sZWZ0LCBTcmNSZWN0LT50b3AsIFNyY1JlY3QtPnJpZ2h0LCBTcmNSZWN0LT5ib3R0b20pOwojaWYgMAogICAgICAgIFRSQUNFKCJcdGZsYWdzOiAiKTsKICAgICAgICBERFJBV19kdW1wX0REQkxUKEZsYWdzKTsKICAgICAgICBpZiAoRmxhZ3MgJiBEREJMVF9EREZYKQogICAgICAgIHsKICAgICAgICAgICAgVFJBQ0UoIlx0YmxpdGZ4OiAiKTsKICAgICAgICAgICAgRERSQVdfZHVtcF9EREJMVEZYKEREQmx0RngtPmR3RERGWCk7CiAgICAgICAgfQojZW5kaWYKICAgIH0KCiAgICBpZiAoIChUaGlzLT5GbGFncyAmIFNGTEFHX0xPQ0tFRCkgfHwgKChTcmMgIT0gTlVMTCkgJiYgKFNyYy0+RmxhZ3MgJiBTRkxBR19MT0NLRUQpKSkKICAgIHsKICAgICAgICBXQVJOKCIgU3VyZmFjZSBpcyBidXN5LCByZXR1cm5pbmcgRERFUlJfU1VSRkFDRUJVU1lcbiIpOwogICAgICAgIHJldHVybiBEREVSUl9TVVJGQUNFQlVTWTsKICAgIH0KCiAgICBpZiAoU3JjID09IFRoaXMpCiAgICB7CiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0xvY2tSZWN0KGlmYWNlLCAmZGxvY2ssIE5VTEwsIDApOwogICAgICAgIGRmbXQgPSBUaGlzLT5yZXNvdXJjZS5mb3JtYXQ7CiAgICAgICAgc2xvY2sgPSBkbG9jazsKICAgICAgICBzZm10ID0gZGZtdDsKICAgICAgICBzRW50cnkgPSBnZXRGb3JtYXREZXNjRW50cnkoc2ZtdCk7CiAgICAgICAgZEVudHJ5ID0gc0VudHJ5OwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIGlmIChTcmMpCiAgICAgICAgewogICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfTG9ja1JlY3QoU3JjU3VyZmFjZSwgJnNsb2NrLCBOVUxMLCBEM0RMT0NLX1JFQURPTkxZKTsKICAgICAgICAgICAgc2ZtdCA9IFNyYy0+cmVzb3VyY2UuZm9ybWF0OwogICAgICAgIH0KICAgICAgICBzRW50cnkgPSBnZXRGb3JtYXREZXNjRW50cnkoc2ZtdCk7CiAgICAgICAgZGZtdCA9IFRoaXMtPnJlc291cmNlLmZvcm1hdDsKICAgICAgICBkRW50cnkgPSBnZXRGb3JtYXREZXNjRW50cnkoZGZtdCk7CiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0xvY2tSZWN0KGlmYWNlLCAmZGxvY2ssTlVMTCwwKTsKICAgIH0KCiAgICBpZiAoIUREQmx0RnggfHwgIShEREJsdEZ4LT5kd0RERlgpKSBGbGFncyAmPSB+RERCTFRfRERGWDsKCiAgICBpZiAoc0VudHJ5LT5pc0ZvdXJjYyAmJiBkRW50cnktPmlzRm91cmNjKQogICAgewogICAgICAgIGlmIChzZm10ICE9IGRmbXQpCiAgICAgICAgewogICAgICAgICAgICBGSVhNRSgiRk9VUkNDLT5GT1VSQ0MgY29weSBvbmx5IHN1cHBvcnRlZCBmb3IgdGhlIHNhbWUgdHlwZSBvZiBzdXJmYWNlXG4iKTsKICAgICAgICAgICAgcmV0ID0gRERFUlJfSU5WQUxJRFBJWEVMRk9STUFUOwogICAgICAgICAgICBnb3RvIHJlbGVhc2U7CiAgICAgICAgfQogICAgICAgIFRSQUNFKCJGb3VyY2MtPkZvdXJjYyBjb3B5KVxuIik7CiAgICAgICAgbWVtY3B5KGRsb2NrLnBCaXRzLCBzbG9jay5wQml0cywgVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0ICogZGxvY2suUGl0Y2gpOwogICAgICAgIGdvdG8gcmVsZWFzZTsKICAgIH0KCiAgICBpZiAoc0VudHJ5LT5pc0ZvdXJjYyAmJiAhZEVudHJ5LT5pc0ZvdXJjYykKICAgIHsKICAgICAgICBGSVhNRSgiRFhUQyBkZWNvbXByZXNzaW9uIG5vdCBzdXBwb3J0ZWQgcmlnaHQgbm93XG4iKTsKICAgICAgICBnb3RvIHJlbGVhc2U7CiAgICB9CgogICAgaWYgKERlc3RSZWN0KQogICAgewogICAgICAgIG1lbWNweSgmeGRzdCxEZXN0UmVjdCxzaXplb2YoeGRzdCkpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIHhkc3QudG9wCT0gMDsKICAgICAgICB4ZHN0LmJvdHRvbQk9IFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodDsKICAgICAgICB4ZHN0LmxlZnQJPSAwOwogICAgICAgIHhkc3QucmlnaHQJPSBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aDsKICAgIH0KCiAgICBpZiAoU3JjUmVjdCkKICAgIHsKICAgICAgICBtZW1jcHkoJnhzcmMsU3JjUmVjdCxzaXplb2YoeHNyYykpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIGlmIChTcmMpCiAgICAgICAgewogICAgICAgICAgICB4c3JjLnRvcAk9IDA7CiAgICAgICAgICAgIHhzcmMuYm90dG9tCT0gU3JjLT5jdXJyZW50RGVzYy5IZWlnaHQ7CiAgICAgICAgICAgIHhzcmMubGVmdAk9IDA7CiAgICAgICAgICAgIHhzcmMucmlnaHQJPSBTcmMtPmN1cnJlbnREZXNjLldpZHRoOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBtZW1zZXQoJnhzcmMsMCxzaXplb2YoeHNyYykpOwogICAgICAgIH0KICAgIH0KCiAgICAvKiBGaXJzdCBjaGVjayBmb3IgdGhlIHZhbGlkaXR5IG9mIHNvdXJjZSAvIGRlc3RpbmF0aW9uIHJlY3RhbmdsZXMuIFRoaXMgd2FzCiAgICAgIHZlcmlmaWVkIHVzaW5nIGEgdGVzdCBhcHBsaWNhdGlvbiArIGJ5IE1TRE4uCiAgICAqLwogICAgaWYgKChTcmMgIT0gTlVMTCkgJiYKICAgICAgICAoKHhzcmMuYm90dG9tID4gU3JjLT5jdXJyZW50RGVzYy5IZWlnaHQpIHx8ICh4c3JjLmJvdHRvbSA8IDApIHx8CiAgICAgICAgKHhzcmMudG9wICAgICA+IFNyYy0+Y3VycmVudERlc2MuSGVpZ2h0KSB8fCAoeHNyYy50b3AgICAgPCAwKSB8fAogICAgICAgICh4c3JjLmxlZnQgICAgPiBTcmMtPmN1cnJlbnREZXNjLldpZHRoKSAgfHwgKHhzcmMubGVmdCAgIDwgMCkgfHwKICAgICAgICAoeHNyYy5yaWdodCAgID4gU3JjLT5jdXJyZW50RGVzYy5XaWR0aCkgIHx8ICh4c3JjLnJpZ2h0ICA8IDApIHx8CiAgICAgICAgKHhzcmMucmlnaHQgICA8IHhzcmMubGVmdCkgICAgICAgICAgICAgICB8fCAoeHNyYy5ib3R0b20gPCB4c3JjLnRvcCkpKQogICAgewogICAgICAgIFdBUk4oIkFwcGxpY2F0aW9uIGdhdmUgdXMgYmFkIHNvdXJjZSByZWN0YW5nbGUgZm9yIEJsdC5cbiIpOwogICAgICAgIHJldCA9IERERVJSX0lOVkFMSURSRUNUOwogICAgICAgIGdvdG8gcmVsZWFzZTsKICAgIH0KICAgIC8qIEZvciB0aGUgRGVzdGluYXRpb24gcmVjdCwgaXQgY2FuIGJlIG91dCBvZiBib3VuZHMgb24gdGhlIGNvbmRpdGlvbiB0aGF0IGEgY2xpcHBlcgogICAgICBpcyBzZXQgZm9yIHRoZSBnaXZlbiBzdXJmYWNlLgogICAgKi8KICAgIGlmICgoLypUaGlzLT5jbGlwcGVyID09IE5VTEwqLyBUUlVFKSAmJgogICAgICAgICgoeGRzdC5ib3R0b20gID4gVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0KSB8fCAoeGRzdC5ib3R0b20gPCAwKSB8fAogICAgICAgICh4ZHN0LnRvcCAgICAgID4gVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0KSB8fCAoeGRzdC50b3AgICAgPCAwKSB8fAogICAgICAgICh4ZHN0LmxlZnQgICAgID4gVGhpcy0+Y3VycmVudERlc2MuV2lkdGgpICB8fCAoeGRzdC5sZWZ0ICAgPCAwKSB8fAogICAgICAgICh4ZHN0LnJpZ2h0ICAgID4gVGhpcy0+Y3VycmVudERlc2MuV2lkdGgpICB8fCAoeGRzdC5yaWdodCAgPCAwKSB8fAogICAgICAgICh4ZHN0LnJpZ2h0ICAgIDwgeGRzdC5sZWZ0KSAgICAgICAgICAgICAgICB8fCAoeGRzdC5ib3R0b20gPCB4ZHN0LnRvcCkpKQogICAgewogICAgICAgIFdBUk4oIkFwcGxpY2F0aW9uIGdhdmUgdXMgYmFkIGRlc3RpbmF0aW9uIHJlY3RhbmdsZSBmb3IgQmx0IHdpdGhvdXQgYSBjbGlwcGVyIHNldC5cbiIpOwogICAgICAgIHJldCA9IERERVJSX0lOVkFMSURSRUNUOwogICAgICAgIGdvdG8gcmVsZWFzZTsKICAgIH0KCiAgICAvKiBOb3cgaGFuZGxlIG5lZ2F0aXZlIHZhbHVlcyBpbiB0aGUgcmVjdGFuZ2xlcy4gV2FybmluZzogb25seSBzdXBwb3J0ZWQgZm9yIG5vdwogICAgICBpbiB0aGUgJ3NpbXBsZScgY2FzZXMgKGllIG5vdCBpbiBhbnkgc3RyZXRjaGluZyAvIHJvdGF0aW9uIGNhc2VzKS4KCiAgICAgIEZpcnN0LCB0aGUgY2FzZSB3aGVyZSBub3RoaW5nIGlzIHRvIGJlIGRvbmUuCiAgICAqLwogICAgaWYgKCgoeGRzdC5ib3R0b20gPD0gMCkgfHwgKHhkc3QucmlnaHQgPD0gMCkgICAgICAgICB8fAogICAgICAgICAoeGRzdC50b3AgICAgPj0gKGludCkgVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0KSB8fAogICAgICAgICAoeGRzdC5sZWZ0ICAgPj0gKGludCkgVGhpcy0+Y3VycmVudERlc2MuV2lkdGgpKSB8fAogICAgICAgICgoU3JjICE9IE5VTEwpICYmCiAgICAgICAgKCh4c3JjLmJvdHRvbSA8PSAwKSB8fCAoeHNyYy5yaWdodCA8PSAwKSAgICAgfHwKICAgICAgICAgKHhzcmMudG9wID49IChpbnQpIFNyYy0+Y3VycmVudERlc2MuSGVpZ2h0KSB8fAogICAgICAgICAoeHNyYy5sZWZ0ID49IChpbnQpIFNyYy0+Y3VycmVudERlc2MuV2lkdGgpKSAgKSkKICAgIHsKICAgICAgICBUUkFDRSgiTm90aGluZyB0byBiZSBkb25lICFcbiIpOwogICAgICAgIGdvdG8gcmVsZWFzZTsKICAgIH0KCiAgICAvKiBUaGUgZWFzeSBjYXNlIDogdGhlIHNvdXJjZS1sZXNzIGJsaXRzLi4uLiAqLwogICAgaWYgKFNyYyA9PSBOVUxMKQogICAgewogICAgICAgIFJFQ1QgZnVsbF9yZWN0OwogICAgICAgIFJFQ1QgdGVtcF9yZWN0OyAvKiBObyBpZGVhIGlmIGludGVyc2VjdCByZWN0IGNhbiBiZSB0aGUgc2FtZSBhcyBvbmUgb2YgdGhlIHNvdXJjZSByZWN0ICovCgogICAgICAgIGZ1bGxfcmVjdC5sZWZ0ICAgPSAwOwogICAgICAgIGZ1bGxfcmVjdC50b3AgICAgPSAwOwogICAgICAgIGZ1bGxfcmVjdC5yaWdodCAgPSBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aDsKICAgICAgICBmdWxsX3JlY3QuYm90dG9tID0gVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0OwogICAgICAgIEludGVyc2VjdFJlY3QoJnRlbXBfcmVjdCwgJmZ1bGxfcmVjdCwgJnhkc3QpOwogICAgICAgIHhkc3QgPSB0ZW1wX3JlY3Q7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgLyogT25seSBoYW5kbGUgY2xpcHBpbmcgb24gdGhlIGRlc3RpbmF0aW9uIHJlY3RhbmdsZSAqLwogICAgICAgIGludCBjbGlwX2hvcml6ID0gKHhkc3QubGVmdCA8IDApIHx8ICh4ZHN0LnJpZ2h0ICA+IChpbnQpIFRoaXMtPmN1cnJlbnREZXNjLldpZHRoICk7CiAgICAgICAgaW50IGNsaXBfdmVydCAgPSAoeGRzdC50b3AgIDwgMCkgfHwgKHhkc3QuYm90dG9tID4gKGludCkgVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0KTsKICAgICAgICBpZiAoY2xpcF92ZXJ0IHx8IGNsaXBfaG9yaXopCiAgICAgICAgewogICAgICAgICAgICAvKiBOb3cgY2hlY2sgaWYgdGhpcyBpcyBhIHNwZWNpYWwgY2FzZSBvciBub3QuLi4gKi8KICAgICAgICAgICAgaWYgKCgoKHhkc3QuYm90dG9tIC0geGRzdC50b3AgKSAhPSAoeHNyYy5ib3R0b20gLSB4c3JjLnRvcCApKSAmJiBjbGlwX3ZlcnQgKSB8fAogICAgICAgICAgICAgICAgKCgoeGRzdC5yaWdodCAgLSB4ZHN0LmxlZnQpICE9ICh4c3JjLnJpZ2h0ICAtIHhzcmMubGVmdCkpICYmIGNsaXBfaG9yaXopIHx8CiAgICAgICAgICAgICAgICAoRmxhZ3MgJiBEREJMVF9EREZYKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgV0FSTigiT3V0IG9mIHNjcmVlbiByZWN0YW5nbGUgaW4gc3BlY2lhbCBjYXNlLiBOb3QgaGFuZGxlZCByaWdodCBub3cuXG4iKTsKICAgICAgICAgICAgICAgIGdvdG8gcmVsZWFzZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGNsaXBfaG9yaXopCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh4ZHN0LmxlZnQgPCAwKSB7IHhzcmMubGVmdCAtPSB4ZHN0LmxlZnQ7IHhkc3QubGVmdCA9IDA7IH0KICAgICAgICAgICAgICAgIGlmICh4ZHN0LnJpZ2h0ID4gVGhpcy0+Y3VycmVudERlc2MuV2lkdGgpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgeHNyYy5yaWdodCAtPSAoeGRzdC5yaWdodCAtIChpbnQpIFRoaXMtPmN1cnJlbnREZXNjLldpZHRoKTsKICAgICAgICAgICAgICAgICAgICB4ZHN0LnJpZ2h0ID0gKGludCkgVGhpcy0+Y3VycmVudERlc2MuV2lkdGg7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGNsaXBfdmVydCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHhkc3QudG9wIDwgMCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB4c3JjLnRvcCAtPSB4ZHN0LnRvcDsKICAgICAgICAgICAgICAgICAgICB4ZHN0LnRvcCA9IDA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoeGRzdC5ib3R0b20gPiBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgeHNyYy5ib3R0b20gLT0gKHhkc3QuYm90dG9tIC0gKGludCkgVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0KTsKICAgICAgICAgICAgICAgICAgICB4ZHN0LmJvdHRvbSA9IChpbnQpIFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICAvKiBBbmQgY2hlY2sgaWYgYWZ0ZXIgY2xpcHBpbmcgc29tZXRoaW5nIGlzIHN0aWxsIHRvIGJlIGRvbmUuLi4gKi8KICAgICAgICAgICAgaWYgKCh4ZHN0LmJvdHRvbSA8PSAwKSAgIHx8ICh4ZHN0LnJpZ2h0IDw9IDApICAgICAgIHx8CiAgICAgICAgICAgICAgICAoeGRzdC50b3AgICA+PSAoaW50KSBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQpICB8fAogICAgICAgICAgICAgICAgKHhkc3QubGVmdCAgPj0gKGludCkgVGhpcy0+Y3VycmVudERlc2MuV2lkdGgpICAgfHwKICAgICAgICAgICAgICAgICh4c3JjLmJvdHRvbSA8PSAwKSAgIHx8ICh4c3JjLnJpZ2h0IDw9IDApICAgICAgIHx8CiAgICAgICAgICAgICAgICAoeHNyYy50b3AgPj0gKGludCkgU3JjLT5jdXJyZW50RGVzYy5IZWlnaHQpICAgICB8fAogICAgICAgICAgICAgICAgKHhzcmMubGVmdCA+PSAoaW50KSBTcmMtPmN1cnJlbnREZXNjLldpZHRoKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgVFJBQ0UoIk5vdGhpbmcgdG8gYmUgZG9uZSBhZnRlciBjbGlwcGluZyAhXG4iKTsKICAgICAgICAgICAgICAgIGdvdG8gcmVsZWFzZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBicHAgPSBUaGlzLT5ieXRlc1BlclBpeGVsOwogICAgc3JjaGVpZ2h0ID0geHNyYy5ib3R0b20gLSB4c3JjLnRvcDsKICAgIHNyY3dpZHRoID0geHNyYy5yaWdodCAtIHhzcmMubGVmdDsKICAgIGRzdGhlaWdodCA9IHhkc3QuYm90dG9tIC0geGRzdC50b3A7CiAgICBkc3R3aWR0aCA9IHhkc3QucmlnaHQgLSB4ZHN0LmxlZnQ7CiAgICB3aWR0aCA9ICh4ZHN0LnJpZ2h0IC0geGRzdC5sZWZ0KSAqIGJwcDsKCiAgICBhc3NlcnQod2lkdGggPD0gZGxvY2suUGl0Y2gpOwoKICAgIGRidWYgPSAoQllURSopZGxvY2sucEJpdHMrKHhkc3QudG9wKmRsb2NrLlBpdGNoKSsoeGRzdC5sZWZ0KmJwcCk7CgogICAgaWYgKEZsYWdzICYgRERCTFRfV0FJVCkKICAgIHsKICAgICAgICBzdGF0aWMgQk9PTCBkaXNwbGF5ZWQgPSBGQUxTRTsKICAgICAgICBpZiAoIWRpc3BsYXllZCkKICAgICAgICAgICAgRklYTUUoIkNhbid0IGhhbmRsZSBEREJMVF9XQUlUIGZsYWcgcmlnaHQgbm93LlxuIik7CiAgICAgICAgZGlzcGxheWVkID0gVFJVRTsKICAgICAgICBGbGFncyAmPSB+RERCTFRfV0FJVDsKICAgIH0KICAgIGlmIChGbGFncyAmIEREQkxUX0FTWU5DKQogICAgewogICAgICAgIHN0YXRpYyBCT09MIGRpc3BsYXllZCA9IEZBTFNFOwogICAgICAgIGlmICghZGlzcGxheWVkKQogICAgICAgICAgICBGSVhNRSgiQ2FuJ3QgaGFuZGxlIEREQkxUX0FTWU5DIGZsYWcgcmlnaHQgbm93LlxuIik7CiAgICAgICAgZGlzcGxheWVkID0gVFJVRTsKICAgICAgICBGbGFncyAmPSB+RERCTFRfQVNZTkM7CiAgICB9CiAgICBpZiAoRmxhZ3MgJiBEREJMVF9ET05PVFdBSVQpCiAgICB7CiAgICAgICAgLyogRERCTFRfRE9OT1RXQUlUIGFwcGVhcmVkIGluIERYNyAqLwogICAgICAgIHN0YXRpYyBCT09MIGRpc3BsYXllZCA9IEZBTFNFOwogICAgICAgIGlmICghZGlzcGxheWVkKQogICAgICAgICAgICBGSVhNRSgiQ2FuJ3QgaGFuZGxlIEREQkxUX0RPTk9UV0FJVCBmbGFnIHJpZ2h0IG5vdy5cbiIpOwogICAgICAgIGRpc3BsYXllZCA9IFRSVUU7CiAgICAgICAgRmxhZ3MgJj0gfkREQkxUX0RPTk9UV0FJVDsKICAgIH0KCiAgICAvKiBGaXJzdCwgYWxsIHRoZSAnc291cmNlLWxlc3MnIGJsaXRzICovCiAgICBpZiAoRmxhZ3MgJiBEREJMVF9DT0xPUkZJTEwpCiAgICB7CiAgICAgICAgcmV0ID0gX0JsdF9Db2xvckZpbGwoZGJ1ZiwgZHN0d2lkdGgsIGRzdGhlaWdodCwgYnBwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGxvY2suUGl0Y2gsIEREQmx0RngtPnU1LmR3RmlsbENvbG9yKTsKICAgICAgICBGbGFncyAmPSB+RERCTFRfQ09MT1JGSUxMOwogICAgfQoKICAgIGlmIChGbGFncyAmIEREQkxUX0RFUFRIRklMTCkKICAgIHsKICAgICAgICBGSVhNRSgiRERCTFRfREVQVEhGSUxMIG5lZWRzIHRvIGJlIGltcGxlbWVudGVkIVxuIik7CiAgICB9CiAgICBpZiAoRmxhZ3MgJiBEREJMVF9ST1ApCiAgICB7CiAgICAgICAgLyogQ2F0Y2ggc29tZSBkZWdlbmVyYXRlIGNhc2VzIGhlcmUgKi8KICAgICAgICBzd2l0Y2goRERCbHRGeC0+ZHdST1ApCiAgICAgICAgewogICAgICAgICAgICBjYXNlIEJMQUNLTkVTUzoKICAgICAgICAgICAgICAgIHJldCA9IF9CbHRfQ29sb3JGaWxsKGRidWYsZHN0d2lkdGgsZHN0aGVpZ2h0LGJwcCxkbG9jay5QaXRjaCwwKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIDB4QUEwMDI5OiAvKiBOby1vcCAqLwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgV0hJVEVORVNTOgogICAgICAgICAgICAgICAgcmV0ID0gX0JsdF9Db2xvckZpbGwoZGJ1Zixkc3R3aWR0aCxkc3RoZWlnaHQsYnBwLGRsb2NrLlBpdGNoLH4wKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFNSQ0NPUFk6IC8qIHdlbGwsIHdlIGRvIHRoYXQgYmVsb3cgPyAqLwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICBGSVhNRSgiVW5zdXBwb3J0ZWQgcmFzdGVyIG9wOiAlMDhseCAgUGF0dGVybjogJXBcbiIsIEREQmx0RngtPmR3Uk9QLCBEREJsdEZ4LT51NS5scEREU1BhdHRlcm4pOwogICAgICAgICAgICAgICAgZ290byBlcnJvcjsKICAgICAgICB9CiAgICAgICAgRmxhZ3MgJj0gfkREQkxUX1JPUDsKICAgIH0KICAgIGlmIChGbGFncyAmIEREQkxUX0REUk9QUykKICAgIHsKICAgICAgICBGSVhNRSgiXHREZHJhdyBSYXN0ZXIgT3BzOiAlMDhseCAgUGF0dGVybjogJXBcbiIsIEREQmx0RngtPmR3RERST1AsIEREQmx0RngtPnU1LmxwRERTUGF0dGVybik7CiAgICB9CiAgICAvKiBOb3cgdGhlICd3aXRoIHNvdXJjZScgYmxpdHMgKi8KICAgIGlmIChTcmMpCiAgICB7CiAgICAgICAgTFBCWVRFIHNiYXNlOwogICAgICAgIGludCBzeCwgeGluYywgc3ksIHlpbmM7CgogICAgICAgIGlmICghZHN0d2lkdGggfHwgIWRzdGhlaWdodCkgLyogaG1tLi4uIHN0dXBpZCBwcm9ncmFtID8gKi8KICAgICAgICAgICAgZ290byByZWxlYXNlOwogICAgICAgIHNiYXNlID0gKEJZVEUqKXNsb2NrLnBCaXRzKyh4c3JjLnRvcCpzbG9jay5QaXRjaCkreHNyYy5sZWZ0KmJwcDsKICAgICAgICB4aW5jID0gKHNyY3dpZHRoIDw8IDE2KSAvIGRzdHdpZHRoOwogICAgICAgIHlpbmMgPSAoc3JjaGVpZ2h0IDw8IDE2KSAvIGRzdGhlaWdodDsKCiAgICAgICAgaWYgKCFGbGFncykKICAgICAgICB7CiAgICAgICAgICAgIC8qIE5vIGVmZmVjdHMsIHdlIGNhbiBjaGVhdCBoZXJlICovCiAgICAgICAgICAgIGlmIChkc3R3aWR0aCA9PSBzcmN3aWR0aCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKGRzdGhlaWdodCA9PSBzcmNoZWlnaHQpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgLyogTm8gc3RyZXRjaGluZyBpbiBlaXRoZXIgZGlyZWN0aW9uLiBUaGlzIG5lZWRzIHRvIGJlIGFzCiAgICAgICAgICAgICAgICAgICAgKiBmYXN0IGFzIHBvc3NpYmxlICovCiAgICAgICAgICAgICAgICAgICAgc2J1ZiA9IHNiYXNlOwoKICAgICAgICAgICAgICAgICAgICAvKiBjaGVjayBmb3Igb3ZlcmxhcHBpbmcgc3VyZmFjZXMgKi8KICAgICAgICAgICAgICAgICAgICBpZiAoU3JjU3VyZmFjZSAhPSBpZmFjZSB8fCB4ZHN0LnRvcCA8IHhzcmMudG9wIHx8CiAgICAgICAgICAgICAgICAgICAgICAgIHhkc3QucmlnaHQgPD0geHNyYy5sZWZ0IHx8IHhzcmMucmlnaHQgPD0geGRzdC5sZWZ0KQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgLyogbm8gb3ZlcmxhcCwgb3IgZHN0IGFib3ZlIHNyYywgc28gY29weSBmcm9tIHRvcCBkb3dud2FyZHMgKi8KICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh5ID0gMDsgeSA8IGRzdGhlaWdodDsgeSsrKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZW1jcHkoZGJ1Ziwgc2J1Ziwgd2lkdGgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2J1ZiArPSBzbG9jay5QaXRjaDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRidWYgKz0gZGxvY2suUGl0Y2g7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoeGRzdC50b3AgPiB4c3JjLnRvcCkgIC8qIGNvcHkgZnJvbSBib3R0b20gdXB3YXJkcyAqLwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgc2J1ZiArPSAoc2xvY2suUGl0Y2gqZHN0aGVpZ2h0KTsKICAgICAgICAgICAgICAgICAgICAgICAgZGJ1ZiArPSAoZGxvY2suUGl0Y2gqZHN0aGVpZ2h0KTsKICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh5ID0gMDsgeSA8IGRzdGhlaWdodDsgeSsrKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzYnVmIC09IHNsb2NrLlBpdGNoOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGJ1ZiAtPSBkbG9jay5QaXRjaDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lbWNweShkYnVmLCBzYnVmLCB3aWR0aCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSAvKiBzcmMgYW5kIGRzdCBvdmVybGFwcGluZyBvbiB0aGUgc2FtZSBsaW5lLCB1c2UgbWVtbW92ZSAqLwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh5ID0gMDsgeSA8IGRzdGhlaWdodDsgeSsrKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZW1tb3ZlKGRidWYsIHNidWYsIHdpZHRoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNidWYgKz0gc2xvY2suUGl0Y2g7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYnVmICs9IGRsb2NrLlBpdGNoOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAvKiBTdHJldGNoaW5nIGluIFkgZGlyZWN0aW9uIG9ubHkgKi8KICAgICAgICAgICAgICAgICAgICBmb3IgKHkgPSBzeSA9IDA7IHkgPCBkc3RoZWlnaHQ7IHkrKywgc3kgKz0geWluYykgewogICAgICAgICAgICAgICAgICAgICAgICBzYnVmID0gc2Jhc2UgKyAoc3kgPj4gMTYpICogc2xvY2suUGl0Y2g7CiAgICAgICAgICAgICAgICAgICAgICAgIG1lbWNweShkYnVmLCBzYnVmLCB3aWR0aCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGRidWYgKz0gZGxvY2suUGl0Y2g7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLyogU3RyZXRjaGluZyBpbiBYIGRpcmVjdGlvbiAqLwogICAgICAgICAgICAgICAgaW50IGxhc3Rfc3kgPSAtMTsKICAgICAgICAgICAgICAgIGZvciAoeSA9IHN5ID0gMDsgeSA8IGRzdGhlaWdodDsgeSsrLCBzeSArPSB5aW5jKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHNidWYgPSBzYmFzZSArIChzeSA+PiAxNikgKiBzbG9jay5QaXRjaDsKCiAgICAgICAgICAgICAgICAgICAgaWYgKChzeSA+PiAxNikgPT0gKGxhc3Rfc3kgPj4gMTYpKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgLyogdGhpcyBzb3VyY2Vyb3cgaXMgdGhlIHNhbWUgYXMgbGFzdCBzb3VyY2Vyb3cgLQogICAgICAgICAgICAgICAgICAgICAgICAgKiBjb3B5IGFscmVhZHkgc3RyZXRjaGVkIHJvdwogICAgICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICAgICAgbWVtY3B5KGRidWYsIGRidWYgLSBkbG9jay5QaXRjaCwgd2lkdGgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewojZGVmaW5lIFNUUkVUQ0hfUk9XKHR5cGUpIHsgXAogICAgICAgICAgICAgICAgICAgIHR5cGUgKnMgPSAodHlwZSAqKSBzYnVmLCAqZCA9ICh0eXBlICopIGRidWY7IFwKICAgICAgICAgICAgICAgICAgICBmb3IgKHggPSBzeCA9IDA7IHggPCBkc3R3aWR0aDsgeCsrLCBzeCArPSB4aW5jKSBcCiAgICAgICAgICAgICAgICAgICAgZFt4XSA9IHNbc3ggPj4gMTZdOyBcCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7IH0KCiAgICAgICAgICAgICAgICAgICAgc3dpdGNoKGJwcCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTogU1RSRVRDSF9ST1coQllURSkKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAyOiBTVFJFVENIX1JPVyhXT1JEKQogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDQ6IFNUUkVUQ0hfUk9XKERXT1JEKQogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDM6CiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQllURSBzLGQgPSBkYnVmOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh4ID0gc3ggPSAwOyB4IDwgZHN0d2lkdGg7IHgrKywgc3grPSB4aW5jKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIHBpeGVsOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzID0gc2J1ZiszKihzeD4+MTYpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpeGVsID0gc1swXXwoc1sxXTw8OCl8KHNbMl08PDE2KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkWzBdID0gKHBpeGVsICAgICkmMHhmZjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkWzFdID0gKHBpeGVsPj4gOCkmMHhmZjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkWzJdID0gKHBpeGVsPj4xNikmMHhmZjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkKz0zOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgIEZJWE1FKCJTdHJldGNoZWQgYmxpdCBub3QgaW1wbGVtZW50ZWQgZm9yIGJwcCAlZCFcbiIsIGJwcCo4KTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0ID0gRERFUlJfVU5TVVBQT1JURUQ7CiAgICAgICAgICAgICAgICAgICAgICAgIGdvdG8gZXJyb3I7CiAgICAgICAgICAgICAgICAgICAgfQojdW5kZWYgU1RSRVRDSF9ST1cKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZGJ1ZiArPSBkbG9jay5QaXRjaDsKICAgICAgICAgICAgICAgICAgICBsYXN0X3N5ID0gc3k7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgIExPTkcgZHN0eWluYyA9IGRsb2NrLlBpdGNoLCBkc3R4aW5jID0gYnBwOwogICAgICAgICAgRFdPUkQga2V5bG93ID0gMHhGRkZGRkZGRiwga2V5aGlnaCA9IDAsIGtleW1hc2sgPSAweEZGRkZGRkZGOwogICAgICAgICAgaWYgKEZsYWdzICYgKEREQkxUX0tFWVNSQyB8IEREQkxUX0tFWURFU1QgfCBEREJMVF9LRVlTUkNPVkVSUklERSB8IEREQkxUX0tFWURFU1RPVkVSUklERSkpCiAgICAgICAgICB7CgogICAgICAgICAgICAgIGlmIChGbGFncyAmIEREQkxUX0tFWVNSQykKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBrZXlsb3cgID0gU3JjLT5TcmNCbHRDS2V5LmR3Q29sb3JTcGFjZUxvd1ZhbHVlOwogICAgICAgICAgICAgICAga2V5aGlnaCA9IFNyYy0+U3JjQmx0Q0tleS5kd0NvbG9yU3BhY2VIaWdoVmFsdWU7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGVsc2UgaWYgKEZsYWdzICYgRERCTFRfS0VZREVTVCkKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBrZXlsb3cgID0gVGhpcy0+RGVzdEJsdENLZXkuZHdDb2xvclNwYWNlTG93VmFsdWU7CiAgICAgICAgICAgICAgICBrZXloaWdoID0gVGhpcy0+RGVzdEJsdENLZXkuZHdDb2xvclNwYWNlSGlnaFZhbHVlOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBlbHNlIGlmIChGbGFncyAmIEREQkxUX0tFWVNSQ09WRVJSSURFKQogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGtleWxvdyAgPSBEREJsdEZ4LT5kZGNrU3JjQ29sb3JrZXkuZHdDb2xvclNwYWNlTG93VmFsdWU7CiAgICAgICAgICAgICAgICBrZXloaWdoID0gRERCbHRGeC0+ZGRja1NyY0NvbG9ya2V5LmR3Q29sb3JTcGFjZUhpZ2hWYWx1ZTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGtleWxvdyAgPSBEREJsdEZ4LT5kZGNrRGVzdENvbG9ya2V5LmR3Q29sb3JTcGFjZUxvd1ZhbHVlOwogICAgICAgICAgICAgICAga2V5aGlnaCA9IEREQmx0RngtPmRkY2tEZXN0Q29sb3JrZXkuZHdDb2xvclNwYWNlSGlnaFZhbHVlOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBpZihicHAgPT0gMSkKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgIGtleW1hc2sgPSAweGZmOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICBrZXltYXNrID0gc0VudHJ5LT5yZWRNYXNrICAgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgc0VudHJ5LT5ncmVlbk1hc2sgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgc0VudHJ5LT5ibHVlTWFzazsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgRmxhZ3MgJj0gfihEREJMVF9LRVlTUkMgfCBEREJMVF9LRVlERVNUIHwgRERCTFRfS0VZU1JDT1ZFUlJJREUgfCBEREJMVF9LRVlERVNUT1ZFUlJJREUpOwogICAgICAgICAgfQoKICAgICAgICAgIGlmIChGbGFncyAmIEREQkxUX0RERlgpCiAgICAgICAgICB7CiAgICAgICAgICAgICAgTFBCWVRFIGRUb3BMZWZ0LCBkVG9wUmlnaHQsIGRCb3R0b21MZWZ0LCBkQm90dG9tUmlnaHQsIHRtcDsKICAgICAgICAgICAgICBMT05HIHRtcHh5OwogICAgICAgICAgICAgIGRUb3BMZWZ0ICAgICA9IGRidWY7CiAgICAgICAgICAgICAgZFRvcFJpZ2h0ICAgID0gZGJ1ZisoKGRzdHdpZHRoLTEpKmJwcCk7CiAgICAgICAgICAgICAgZEJvdHRvbUxlZnQgID0gZFRvcExlZnQrKChkc3RoZWlnaHQtMSkqZGxvY2suUGl0Y2gpOwogICAgICAgICAgICAgIGRCb3R0b21SaWdodCA9IGRCb3R0b21MZWZ0KygoZHN0d2lkdGgtMSkqYnBwKTsKCiAgICAgICAgICAgICAgaWYgKEREQmx0RngtPmR3RERGWCAmIEREQkxURlhfQVJJVEhTVFJFVENIWSkKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvKiBJIGRvbid0IHRoaW5rIHdlIG5lZWQgdG8gZG8gYW55dGhpbmcgYWJvdXQgdGhpcyBmbGFnICovCiAgICAgICAgICAgICAgICBXQVJOKCJGbGFncz1EREJMVF9EREZYIG5vdGhpbmcgZG9uZSBmb3IgRERCTFRGWF9BUklUSFNUUkVUQ0hZXG4iKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgaWYgKEREQmx0RngtPmR3RERGWCAmIEREQkxURlhfTUlSUk9STEVGVFJJR0hUKQogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRtcCAgICAgICAgICA9IGRUb3BSaWdodDsKICAgICAgICAgICAgICAgIGRUb3BSaWdodCAgICA9IGRUb3BMZWZ0OwogICAgICAgICAgICAgICAgZFRvcExlZnQgICAgID0gdG1wOwogICAgICAgICAgICAgICAgdG1wICAgICAgICAgID0gZEJvdHRvbVJpZ2h0OwogICAgICAgICAgICAgICAgZEJvdHRvbVJpZ2h0ID0gZEJvdHRvbUxlZnQ7CiAgICAgICAgICAgICAgICBkQm90dG9tTGVmdCAgPSB0bXA7CiAgICAgICAgICAgICAgICBkc3R4aW5jID0gZHN0eGluYyAqLTE7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGlmIChEREJsdEZ4LT5kd0RERlggJiBEREJMVEZYX01JUlJPUlVQRE9XTikKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0bXAgICAgICAgICAgPSBkVG9wTGVmdDsKICAgICAgICAgICAgICAgIGRUb3BMZWZ0ICAgICA9IGRCb3R0b21MZWZ0OwogICAgICAgICAgICAgICAgZEJvdHRvbUxlZnQgID0gdG1wOwogICAgICAgICAgICAgICAgdG1wICAgICAgICAgID0gZFRvcFJpZ2h0OwogICAgICAgICAgICAgICAgZFRvcFJpZ2h0ICAgID0gZEJvdHRvbVJpZ2h0OwogICAgICAgICAgICAgICAgZEJvdHRvbVJpZ2h0ID0gdG1wOwogICAgICAgICAgICAgICAgZHN0eWluYyA9IGRzdHlpbmMgKi0xOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBpZiAoRERCbHRGeC0+ZHdEREZYICYgRERCTFRGWF9OT1RFQVJJTkcpCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLyogSSBkb24ndCB0aGluayB3ZSBuZWVkIHRvIGRvIGFueXRoaW5nIGFib3V0IHRoaXMgZmxhZyAqLwogICAgICAgICAgICAgICAgV0FSTigiRmxhZ3M9RERCTFRfRERGWCBub3RoaW5nIGRvbmUgZm9yIEREQkxURlhfTk9URUFSSU5HXG4iKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgaWYgKEREQmx0RngtPmR3RERGWCAmIEREQkxURlhfUk9UQVRFMTgwKQogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRtcCAgICAgICAgICA9IGRCb3R0b21SaWdodDsKICAgICAgICAgICAgICAgIGRCb3R0b21SaWdodCA9IGRUb3BMZWZ0OwogICAgICAgICAgICAgICAgZFRvcExlZnQgICAgID0gdG1wOwogICAgICAgICAgICAgICAgdG1wICAgICAgICAgID0gZEJvdHRvbUxlZnQ7CiAgICAgICAgICAgICAgICBkQm90dG9tTGVmdCAgPSBkVG9wUmlnaHQ7CiAgICAgICAgICAgICAgICBkVG9wUmlnaHQgICAgPSB0bXA7CiAgICAgICAgICAgICAgICBkc3R4aW5jID0gZHN0eGluYyAqIC0xOwogICAgICAgICAgICAgICAgZHN0eWluYyA9IGRzdHlpbmMgKiAtMTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgaWYgKEREQmx0RngtPmR3RERGWCAmIEREQkxURlhfUk9UQVRFMjcwKQogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRtcCAgICAgICAgICA9IGRUb3BMZWZ0OwogICAgICAgICAgICAgICAgZFRvcExlZnQgICAgID0gZEJvdHRvbUxlZnQ7CiAgICAgICAgICAgICAgICBkQm90dG9tTGVmdCAgPSBkQm90dG9tUmlnaHQ7CiAgICAgICAgICAgICAgICBkQm90dG9tUmlnaHQgPSBkVG9wUmlnaHQ7CiAgICAgICAgICAgICAgICBkVG9wUmlnaHQgICAgPSB0bXA7CiAgICAgICAgICAgICAgICB0bXB4eSAgID0gZHN0eGluYzsKICAgICAgICAgICAgICAgIGRzdHhpbmMgPSBkc3R5aW5jOwogICAgICAgICAgICAgICAgZHN0eWluYyA9IHRtcHh5OwogICAgICAgICAgICAgICAgZHN0eGluYyA9IGRzdHhpbmMgKiAtMTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgaWYgKEREQmx0RngtPmR3RERGWCAmIEREQkxURlhfUk9UQVRFOTApCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdG1wICAgICAgICAgID0gZFRvcExlZnQ7CiAgICAgICAgICAgICAgICBkVG9wTGVmdCAgICAgPSBkVG9wUmlnaHQ7CiAgICAgICAgICAgICAgICBkVG9wUmlnaHQgICAgPSBkQm90dG9tUmlnaHQ7CiAgICAgICAgICAgICAgICBkQm90dG9tUmlnaHQgPSBkQm90dG9tTGVmdDsKICAgICAgICAgICAgICAgIGRCb3R0b21MZWZ0ICA9IHRtcDsKICAgICAgICAgICAgICAgIHRtcHh5ICAgPSBkc3R4aW5jOwogICAgICAgICAgICAgICAgZHN0eGluYyA9IGRzdHlpbmM7CiAgICAgICAgICAgICAgICBkc3R5aW5jID0gdG1weHk7CiAgICAgICAgICAgICAgICBkc3R5aW5jID0gZHN0eWluYyAqIC0xOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBpZiAoRERCbHRGeC0+ZHdEREZYICYgRERCTFRGWF9aQlVGRkVSQkFTRURFU1QpCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLyogSSBkb24ndCB0aGluayB3ZSBuZWVkIHRvIGRvIGFueXRoaW5nIGFib3V0IHRoaXMgZmxhZyAqLwogICAgICAgICAgICAgICAgV0FSTigiRmxhZ3M9RERCTFRfRERGWCBub3RoaW5nIGRvbmUgZm9yIEREQkxURlhfWkJVRkZFUkJBU0VERVNUXG4iKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgZGJ1ZiA9IGRUb3BMZWZ0OwogICAgICAgICAgICAgIEZsYWdzICY9IH4oRERCTFRfRERGWCk7CiAgICAgICAgICB9CgojZGVmaW5lIENPUFlfQ09MT1JLRVlfRlgodHlwZSkgeyBcCiAgICAgICAgICAgIHR5cGUgKnMsICpkID0gKHR5cGUgKikgZGJ1ZiwgKmR4LCB0bXA7IFwKICAgICAgICAgICAgZm9yICh5ID0gc3kgPSAwOyB5IDwgZHN0aGVpZ2h0OyB5KyssIHN5ICs9IHlpbmMpIHsgXAogICAgICAgICAgICAgIHMgPSAodHlwZSopKHNiYXNlICsgKHN5ID4+IDE2KSAqIHNsb2NrLlBpdGNoKTsgXAogICAgICAgICAgICAgIGR4ID0gZDsgXAogICAgICAgICAgICAgIGZvciAoeCA9IHN4ID0gMDsgeCA8IGRzdHdpZHRoOyB4KyssIHN4ICs9IHhpbmMpIHsgXAogICAgICAgICAgICAgICAgICB0bXAgPSBzW3N4ID4+IDE2XTsgXAogICAgICAgICAgICAgICAgICBpZiAoKHRtcCAmIGtleW1hc2spIDwga2V5bG93IHx8ICh0bXAgJiBrZXltYXNrKSA+IGtleWhpZ2gpIGR4WzBdID0gdG1wOyBcCiAgICAgICAgICAgICAgICAgIGR4ID0gKHR5cGUqKSgoKExQQllURSlkeCkrZHN0eGluYyk7IFwKICAgICAgICAgICAgICB9IFwKICAgICAgICAgICAgICBkID0gKHR5cGUqKSgoKExQQllURSlkKStkc3R5aW5jKTsgXAogICAgICAgICAgICB9IFwKICAgICAgICAgICAgYnJlYWs7IH0KCiAgICAgICAgICAgIHN3aXRjaCAoYnBwKSB7CiAgICAgICAgICAgIGNhc2UgMTogQ09QWV9DT0xPUktFWV9GWChCWVRFKQogICAgICAgICAgICBjYXNlIDI6IENPUFlfQ09MT1JLRVlfRlgoV09SRCkKICAgICAgICAgICAgY2FzZSA0OiBDT1BZX0NPTE9SS0VZX0ZYKERXT1JEKQogICAgICAgICAgICBjYXNlIDM6CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIExQQllURSBzLGQgPSBkYnVmLCBkeDsKICAgICAgICAgICAgICAgIGZvciAoeSA9IHN5ID0gMDsgeSA8IGRzdGhlaWdodDsgeSsrLCBzeSArPSB5aW5jKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHNidWYgPSBzYmFzZSArIChzeSA+PiAxNikgKiBzbG9jay5QaXRjaDsKICAgICAgICAgICAgICAgICAgICBkeCA9IGQ7CiAgICAgICAgICAgICAgICAgICAgZm9yICh4ID0gc3ggPSAwOyB4IDwgZHN0d2lkdGg7IHgrKywgc3grPSB4aW5jKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgcGl4ZWw7CiAgICAgICAgICAgICAgICAgICAgICAgIHMgPSBzYnVmKzMqKHN4Pj4xNik7CiAgICAgICAgICAgICAgICAgICAgICAgIHBpeGVsID0gc1swXXwoc1sxXTw8OCl8KHNbMl08PDE2KTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChwaXhlbCAmIGtleW1hc2spIDwga2V5bG93IHx8IChwaXhlbCAmIGtleW1hc2spID4ga2V5aGlnaCkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZHhbMF0gPSAocGl4ZWwgICAgKSYweGZmOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZHhbMV0gPSAocGl4ZWw+PiA4KSYweGZmOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZHhbMl0gPSAocGl4ZWw+PjE2KSYweGZmOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGR4Kz0gZHN0eGluYzsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZCArPSBkc3R5aW5jOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICBGSVhNRSgiJXMgY29sb3Ita2V5ZWQgYmxpdCBub3QgaW1wbGVtZW50ZWQgZm9yIGJwcCAlZCFcbiIsCiAgICAgICAgICAgICAgICAgIChGbGFncyAmIEREQkxUX0tFWVNSQykgPyAiU291cmNlIiA6ICJEZXN0aW5hdGlvbiIsIGJwcCo4KTsKICAgICAgICAgICAgICAgICAgcmV0ID0gRERFUlJfVU5TVVBQT1JURUQ7CiAgICAgICAgICAgICAgICAgIGdvdG8gZXJyb3I7CiN1bmRlZiBDT1BZX0NPTE9SS0VZX0ZYCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgplcnJvcjoKICAgIGlmIChGbGFncyAmJiBGSVhNRV9PTihkM2Rfc3VyZmFjZSkpCiAgICB7CiAgICAgICAgRklYTUUoIlx0VW5zdXBwb3J0ZWQgZmxhZ3M6ICUwOGx4XG4iLCBGbGFncyk7CiAgICB9CgpyZWxlYXNlOgogICAgSVdpbmVEM0RTdXJmYWNlX1VubG9ja1JlY3QoaWZhY2UpOwogICAgaWYgKFNyY1N1cmZhY2UgJiYgU3JjU3VyZmFjZSAhPSBpZmFjZSkgSVdpbmVEM0RTdXJmYWNlX1VubG9ja1JlY3QoU3JjU3VyZmFjZSk7CiAgICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSVdpbmVEM0RTdXJmYWNlOjpCbHRGYXN0LCBHREkgdmVyc2lvbgogKgogKiBUaGlzIGlzIHRoZSBzb2Z0d2FyZSBpbXBsZW1lbnRhdGlvbiBvZiBCbHRGYXN0LCBhcyB1c2VkIGJ5IEdESSBzdXJmYWNlcwogKiBhbmQgYXMgYSBmYWxsYmFjayBmb3IgT3BlbkdMIHN1cmZhY2VzLiBUaGlzIGNvZGUgaXMgdGFrZW4gZnJvbSB0aGUgb2xkCiAqIERpcmVjdERyYXcgY29kZSwgYW5kIHdhcyBvcmlnaW5hbGx5IHdyaXR0ZW4gYnkgVHJhbnNHYW1pbmcuCiAqCiAqIFBhcmFtczoKICogIGRzdHg6CiAqICBkc3R5OgogKiAgU291cmNlOiBTb3VyY2Ugc3VyZmFjZSB0byBjb3B5IGZyb20KICogIHJzcmM6IFNvdXJjZSByZWN0YW5nbGUKICogIHRyYW5zOiBTb21lIEZsYWdzCiAqCiAqIFJldHVybnM6CiAqICBXSU5FRDNEX09LIG9uIHN1Y2Nlc3MKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpIUkVTVUxUIFdJTkFQSQpJV2luZUdESVN1cmZhY2VJbXBsX0JsdEZhc3QoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGRzdHgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBkc3R5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlICpTb3VyY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUNUICpyc3JjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgdHJhbnMpCnsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBpZmFjZTsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlNyYyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIFNvdXJjZTsKCiAgICBpbnQgICAgICAgICAgICAgICAgIGJwcCwgdywgaCwgeCwgeTsKICAgIFdJTkVEM0RMT0NLRURfUkVDVCAgZGxvY2ssc2xvY2s7CiAgICBIUkVTVUxUICAgICAgICAgICAgIHJldCA9IEREX09LOwogICAgUkVDVCAgICAgICAgICAgICAgICByc3JjMjsKICAgIFJFQ1QgICAgICAgICAgICAgICAgbG9ja19zcmMsIGxvY2tfZHN0LCBsb2NrX3VuaW9uOwogICAgQllURSAgICAgICAgICAgICAgICAqc2J1ZiwgKmRidWY7CiAgICBjb25zdCBQaXhlbEZvcm1hdERlc2MgKnNFbnRyeSwgKmRFbnRyeTsKCiAgICBpZiAoVFJBQ0VfT04oZDNkX3N1cmZhY2UpKQogICAgewogICAgICAgIFRSQUNFKCIoJXApLT4oJWxkLCVsZCwlcCwlcCwlMDhseClcbiIsIFRoaXMsZHN0eCxkc3R5LFNyYyxyc3JjLHRyYW5zKTsKCiAgICAgICAgaWYgKHJzcmMpCiAgICAgICAgewogICAgICAgICAgICBUUkFDRSgiXHRzcmNyZWN0OiAlbGR4JWxkLSVsZHglbGRcbiIscnNyYy0+bGVmdCxyc3JjLT50b3AsCiAgICAgICAgICAgICAgICAgIHJzcmMtPnJpZ2h0LHJzcmMtPmJvdHRvbSk7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIFRSQUNFKCIgc3JjcmVjdDogTlVMTFxuIik7CiAgICAgICAgfQogICAgfQoKICAgIGlmICgoVGhpcy0+RmxhZ3MgJiBTRkxBR19MT0NLRUQpIHx8CiAgICAgICAgKChTcmMgIT0gTlVMTCkgJiYgKFNyYy0+RmxhZ3MgJiBTRkxBR19MT0NLRUQpKSkKICAgIHsKICAgICAgICBXQVJOKCIgU3VyZmFjZSBpcyBidXN5LCByZXR1cm5pbmcgRERFUlJfU1VSRkFDRUJVU1lcbiIpOwogICAgICAgIHJldHVybiBEREVSUl9TVVJGQUNFQlVTWTsKICAgIH0KCiAgICBpZiAoIXJzcmMpCiAgICB7CiAgICAgICAgV0FSTigicnNyYyBpcyBOVUxMIVxuIik7CiAgICAgICAgcnNyYyA9ICZyc3JjMjsKICAgICAgICByc3JjLT5sZWZ0ID0gMDsKICAgICAgICByc3JjLT50b3AgPSAwOwogICAgICAgIHJzcmMtPnJpZ2h0ID0gU3JjLT5jdXJyZW50RGVzYy5XaWR0aDsKICAgICAgICByc3JjLT5ib3R0b20gPSBTcmMtPmN1cnJlbnREZXNjLkhlaWdodDsKICAgIH0KCiAgICAvKiBDaGVjayBzb3VyY2UgcmVjdCBmb3IgdmFsaWRpdHkuIENvcGllZCBmcm9tIG5vcm1hbCBCbHQuIEZpeGVzIEJhbGR1cidzIEdhdGUuKi8KICAgIGlmICgocnNyYy0+Ym90dG9tID4gU3JjLT5jdXJyZW50RGVzYy5IZWlnaHQpIHx8IChyc3JjLT5ib3R0b20gPCAwKSB8fAogICAgICAgIChyc3JjLT50b3AgICAgPiBTcmMtPmN1cnJlbnREZXNjLkhlaWdodCkgfHwgKHJzcmMtPnRvcCAgICA8IDApIHx8CiAgICAgICAgKHJzcmMtPmxlZnQgICA+IFNyYy0+Y3VycmVudERlc2MuV2lkdGgpICB8fCAocnNyYy0+bGVmdCAgIDwgMCkgfHwKICAgICAgICAocnNyYy0+cmlnaHQgID4gU3JjLT5jdXJyZW50RGVzYy5XaWR0aCkgIHx8IChyc3JjLT5yaWdodCAgPCAwKSB8fAogICAgICAgIChyc3JjLT5yaWdodCAgPCByc3JjLT5sZWZ0KSAgICAgICAgICAgICAgfHwgKHJzcmMtPmJvdHRvbSA8IHJzcmMtPnRvcCkpCiAgICB7CiAgICAgICAgV0FSTigiQXBwbGljYXRpb24gZ2F2ZSB1cyBiYWQgc291cmNlIHJlY3RhbmdsZSBmb3IgQmx0RmFzdC5cbiIpOwogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUkVDVDsKICAgIH0KCiAgICBoID0gcnNyYy0+Ym90dG9tIC0gcnNyYy0+dG9wOwogICAgaWYgKGggPiBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQtZHN0eSkgaCA9IFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodC1kc3R5OwogICAgaWYgKGggPiBTcmMtPmN1cnJlbnREZXNjLkhlaWdodC1yc3JjLT50b3ApIGg9U3JjLT5jdXJyZW50RGVzYy5IZWlnaHQtcnNyYy0+dG9wOwogICAgaWYgKGggPD0gMCkgcmV0dXJuIERERVJSX0lOVkFMSURSRUNUOwoKICAgIHcgPSByc3JjLT5yaWdodCAtIHJzcmMtPmxlZnQ7CiAgICBpZiAodyA+IFRoaXMtPmN1cnJlbnREZXNjLldpZHRoLWRzdHgpIHcgPSBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aC1kc3R4OwogICAgaWYgKHcgPiBTcmMtPmN1cnJlbnREZXNjLldpZHRoLXJzcmMtPmxlZnQpIHcgPSBTcmMtPmN1cnJlbnREZXNjLldpZHRoLXJzcmMtPmxlZnQ7CiAgICBpZiAodyA8PSAwKSByZXR1cm4gRERFUlJfSU5WQUxJRFJFQ1Q7CgogICAgLyogTm93IGNvbXB1dGUgdGhlIGxvY2tpbmcgcmVjdGFuZ2xlLi4uICovCiAgICBsb2NrX3NyYy5sZWZ0ID0gcnNyYy0+bGVmdDsKICAgIGxvY2tfc3JjLnRvcCA9IHJzcmMtPnRvcDsKICAgIGxvY2tfc3JjLnJpZ2h0ID0gbG9ja19zcmMubGVmdCArIHc7CiAgICBsb2NrX3NyYy5ib3R0b20gPSBsb2NrX3NyYy50b3AgKyBoOwoKICAgIGxvY2tfZHN0LmxlZnQgPSBkc3R4OwogICAgbG9ja19kc3QudG9wID0gZHN0eTsKICAgIGxvY2tfZHN0LnJpZ2h0ID0gZHN0eCArIHc7CiAgICBsb2NrX2RzdC5ib3R0b20gPSBkc3R5ICsgaDsKCiAgICBicHAgPSBUaGlzLT5ieXRlc1BlclBpeGVsOwoKICAgIC8qIFdlIG5lZWQgdG8gbG9jayB0aGUgc3VyZmFjZXMsIG9yIHdlIHdvbid0IGdldCByZWZyZXNoZXMgd2hlbiBkb25lLiAqLwogICAgaWYgKFNyYyA9PSBUaGlzKQogICAgewogICAgICAgIGludCBwaXRjaDsKCiAgICAgICAgVW5pb25SZWN0KCZsb2NrX3VuaW9uLCAmbG9ja19zcmMsICZsb2NrX2RzdCk7CgogICAgICAgIC8qIExvY2sgdGhlIHVuaW9uIG9mIHRoZSB0d28gcmVjdGFuZ2xlcyAqLwogICAgICAgIHJldCA9IElXaW5lRDNEU3VyZmFjZV9Mb2NrUmVjdChpZmFjZSwgJmRsb2NrLCAmbG9ja191bmlvbiwgMCk7CiAgICAgICAgaWYocmV0ICE9IEQzRF9PSykgZ290byBlcnJvcjsKCiAgICAgICAgcGl0Y2ggPSBkbG9jay5QaXRjaDsKICAgICAgICBzbG9jay5QaXRjaCA9IGRsb2NrLlBpdGNoOwoKICAgICAgICAvKiBTaW5jZSBzbG9jayB3YXMgb3JpZ2luYWxseSBjb3BpZWQgZnJvbSB0aGlzIHN1cmZhY2UncyBkZXNjcmlwdGlvbiwgd2UgY2FuIGp1c3QgcmV1c2UgaXQgKi8KICAgICAgICBhc3NlcnQoVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ICE9IE5VTEwpOwogICAgICAgIHNidWYgPSAoQllURSAqKVRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSArIGxvY2tfc3JjLnRvcCAqIHBpdGNoICsgbG9ja19zcmMubGVmdCAqIGJwcDsKICAgICAgICBkYnVmID0gKEJZVEUgKilUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkgKyBsb2NrX2RzdC50b3AgKiBwaXRjaCArIGxvY2tfZHN0LmxlZnQgKiBicHA7CiAgICAgICAgc0VudHJ5ID0gZ2V0Rm9ybWF0RGVzY0VudHJ5KFNyYy0+cmVzb3VyY2UuZm9ybWF0KTsKICAgICAgICBkRW50cnkgPSBzRW50cnk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgcmV0ID0gSVdpbmVEM0RTdXJmYWNlX0xvY2tSZWN0KFNvdXJjZSwgJnNsb2NrLCAmbG9ja19zcmMsIEQzRExPQ0tfUkVBRE9OTFkpOwogICAgICAgIGlmKHJldCAhPSBEM0RfT0spIGdvdG8gZXJyb3I7CiAgICAgICAgcmV0ID0gSVdpbmVEM0RTdXJmYWNlX0xvY2tSZWN0KGlmYWNlLCAmZGxvY2ssICZsb2NrX2RzdCwgMCk7CiAgICAgICAgaWYocmV0ICE9IEQzRF9PSykgZ290byBlcnJvcjsKCiAgICAgICAgc2J1ZiA9IHNsb2NrLnBCaXRzOwogICAgICAgIGRidWYgPSBkbG9jay5wQml0czsKICAgICAgICBUUkFDRSgiRHN0IGlzIGF0ICVwLCBTcmMgaXMgYXQgJXBcbiIsIGRidWYsIHNidWYpOwoKICAgICAgICBzRW50cnkgPSBnZXRGb3JtYXREZXNjRW50cnkoU3JjLT5yZXNvdXJjZS5mb3JtYXQpOwogICAgICAgIGRFbnRyeSA9IGdldEZvcm1hdERlc2NFbnRyeShUaGlzLT5yZXNvdXJjZS5mb3JtYXQpOwogICAgfQoKICAgIC8qIEhhbmRsZSBmaXJzdCB0aGUgRk9VUkNDIHN1cmZhY2VzLi4uICovCiAgICBpZiAoc0VudHJ5LT5pc0ZvdXJjYyAmJiBkRW50cnktPmlzRm91cmNjKQogICAgewogICAgICAgIFRSQUNFKCJGb3VyY2MgLT4gRm91cmNjIGNvcHlcbiIpOwogICAgICAgIGlmICh0cmFucykKICAgICAgICAgICAgRklYTUUoInRyYW5zIGFyZyBub3Qgc3VwcG9ydGVkIHdoZW4gYSBGT1VSQ0Mgc3VyZmFjZSBpcyBpbnZvbHZlZFxuIik7CiAgICAgICAgaWYgKGRzdHggfHwgZHN0eSkKICAgICAgICAgICAgRklYTUUoIm9mZnNldCBmb3IgZGVzdGluYXRpb24gc3VyZmFjZSBpcyBub3Qgc3VwcG9ydGVkXG4iKTsKICAgICAgICBpZiAoU3JjLT5yZXNvdXJjZS5mb3JtYXQgIT0gVGhpcy0+cmVzb3VyY2UuZm9ybWF0KQogICAgICAgIHsKICAgICAgICAgICAgRklYTUUoIkZPVVJDQy0+Rk9VUkNDIGNvcHkgb25seSBzdXBwb3J0ZWQgZm9yIHRoZSBzYW1lIHR5cGUgb2Ygc3VyZmFjZVxuIik7CiAgICAgICAgICAgIHJldCA9IERERVJSX0lOVkFMSURQSVhFTEZPUk1BVDsKICAgICAgICAgICAgZ290byBlcnJvcjsKICAgICAgICB9CiAgICAgICAgLyogRklYTUU6IFdhdGNoIG91dCB0aGF0IHRoZSBzaXplIGlzIGNvcnJlY3QgZm9yIEZPVVJDQyBzdXJmYWNlcyAqLwogICAgICAgIG1lbWNweShkYnVmLCBzYnVmLCBUaGlzLT5yZXNvdXJjZS5zaXplKTsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQogICAgaWYgKHNFbnRyeS0+aXNGb3VyY2MgJiYgIWRFbnRyeS0+aXNGb3VyY2MpCiAgICB7CiAgICAgICAgLyogVE9ETzogVXNlIHRoZSBsaWJ0eGNfZHh0bi5zbyBzaGFyZWQgbGlicmFyeSB0byBkbwogICAgICAgICAqIHNvZnR3YXJlIGRlY29tcHJlc3Npb24KICAgICAgICAgKi8KICAgICAgICBFUlIoIkRYVEMgZGVjb21wcmVzc2lvbiBub3Qgc3VwcG9ydGVkIGJ5IG5vd1xuIik7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICBpZiAodHJhbnMgJiAoRERCTFRGQVNUX1NSQ0NPTE9SS0VZIHwgRERCTFRGQVNUX0RFU1RDT0xPUktFWSkpCiAgICB7CiAgICAgICAgRFdPUkQga2V5bG93LCBrZXloaWdoOwogICAgICAgIFRSQUNFKCJDb2xvciBrZXllZCBjb3B5XG4iKTsKICAgICAgICBpZiAodHJhbnMgJiBEREJMVEZBU1RfU1JDQ09MT1JLRVkpCiAgICAgICAgewogICAgICAgICAgICBrZXlsb3cgID0gU3JjLT5TcmNCbHRDS2V5LmR3Q29sb3JTcGFjZUxvd1ZhbHVlOwogICAgICAgICAgICBrZXloaWdoID0gU3JjLT5TcmNCbHRDS2V5LmR3Q29sb3JTcGFjZUhpZ2hWYWx1ZTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgLyogSSdtIG5vdCBzdXJlIGlmIHRoaXMgaXMgY29ycmVjdCAqLwogICAgICAgICAgICBGSVhNRSgiRERCTFRGQVNUX0RFU1RDT0xPUktFWSBub3QgZnVsbHkgc3VwcG9ydGVkIHlldC5cbiIpOwogICAgICAgICAgICBrZXlsb3cgID0gVGhpcy0+RGVzdEJsdENLZXkuZHdDb2xvclNwYWNlTG93VmFsdWU7CiAgICAgICAgICAgIGtleWhpZ2ggPSBUaGlzLT5EZXN0Qmx0Q0tleS5kd0NvbG9yU3BhY2VIaWdoVmFsdWU7CiAgICAgICAgfQoKI2RlZmluZSBDT1BZQk9YX0NPTE9SS0VZKHR5cGUpIHsgXAogICAgICAgICAgICB0eXBlICpkLCAqcywgdG1wOyBcCiAgICAgICAgICAgIHMgPSAodHlwZSAqKSBzYnVmOyBcCiAgICAgICAgICAgIGQgPSAodHlwZSAqKSBkYnVmOyBcCiAgICAgICAgICAgIGZvciAoeSA9IDA7IHkgPCBoOyB5KyspIHsgXAogICAgICAgICAgICAgICAgZm9yICh4ID0gMDsgeCA8IHc7IHgrKykgeyBcCiAgICAgICAgICAgICAgICAgICAgdG1wID0gc1t4XTsgXAogICAgICAgICAgICAgICAgICAgIGlmICh0bXAgPCBrZXlsb3cgfHwgdG1wID4ga2V5aGlnaCkgZFt4XSA9IHRtcDsgXAogICAgICAgICAgICAgICAgfSBcCiAgICAgICAgICAgICAgICBzID0gKHR5cGUgKikoKEJZVEUgKilzICsgc2xvY2suUGl0Y2gpOyBcCiAgICAgICAgICAgICAgICBkID0gKHR5cGUgKikoKEJZVEUgKilkICsgZGxvY2suUGl0Y2gpOyBcCiAgICAgICAgICAgIH0gXAogICAgICAgICAgICBicmVhazsgXAogICAgICAgIH0KCiAgICAgICAgc3dpdGNoIChicHApIHsKICAgICAgICAgICAgY2FzZSAxOiBDT1BZQk9YX0NPTE9SS0VZKEJZVEUpCiAgICAgICAgICAgIGNhc2UgMjogQ09QWUJPWF9DT0xPUktFWShXT1JEKQogICAgICAgICAgICBjYXNlIDQ6IENPUFlCT1hfQ09MT1JLRVkoRFdPUkQpCiAgICAgICAgICAgIGNhc2UgMzoKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgQllURSAqZCwgKnM7CiAgICAgICAgICAgICAgICBEV09SRCB0bXA7CiAgICAgICAgICAgICAgICBzID0gKEJZVEUgKikgc2J1ZjsKICAgICAgICAgICAgICAgIGQgPSAoQllURSAqKSBkYnVmOwogICAgICAgICAgICAgICAgZm9yICh5ID0gMDsgeSA8IGg7IHkrKykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBmb3IgKHggPSAwOyB4IDwgdyAqIDM7IHggKz0gMykKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRtcCA9IChEV09SRClzW3hdICsgKChEV09SRClzW3ggKyAxXSA8PCA4KSArICgoRFdPUkQpc1t4ICsgMl0gPDwgMTYpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAodG1wIDwga2V5bG93IHx8IHRtcCA+IGtleWhpZ2gpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRbeCArIDBdID0gc1t4ICsgMF07CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkW3ggKyAxXSA9IHNbeCArIDFdOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZFt4ICsgMl0gPSBzW3ggKyAyXTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBzICs9IHNsb2NrLlBpdGNoOwogICAgICAgICAgICAgICAgICAgIGQgKz0gZGxvY2suUGl0Y2g7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgRklYTUUoIlNvdXJjZSBjb2xvciBrZXkgYmxpdHRpbmcgbm90IHN1cHBvcnRlZCBmb3IgYnBwICVkXG4iLGJwcCo4KTsKICAgICAgICAgICAgICAgIHJldCA9IERERVJSX1VOU1VQUE9SVEVEOwogICAgICAgICAgICAgICAgZ290byBlcnJvcjsKICAgICAgICB9CiN1bmRlZiBDT1BZQk9YX0NPTE9SS0VZCiAgICAgICAgVFJBQ0UoIkNvcHkgRG9uZVxuIik7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgaW50IHdpZHRoID0gdyAqIGJwcDsKICAgICAgICBUUkFDRSgiTk8gY29sb3Iga2V5IGNvcHlcbiIpOwogICAgICAgIGZvciAoeSA9IDA7IHkgPCBoOyB5KyspCiAgICAgICAgewogICAgICAgICAgICAvKiBUaGlzIGlzIHByZXR0eSBlYXN5LCBhIGxpbmUgZm9yIGxpbmUgbWVtY3B5ICovCiAgICAgICAgICAgIG1lbWNweShkYnVmLCBzYnVmLCB3aWR0aCk7CiAgICAgICAgICAgIHNidWYgKz0gc2xvY2suUGl0Y2g7CiAgICAgICAgICAgIGRidWYgKz0gZGxvY2suUGl0Y2g7CiAgICAgICAgfQogICAgICAgIFRSQUNFKCJDb3B5IGRvbmVcbiIpOwogICAgfQoKZXJyb3I6CiAgICBpZiAoU3JjID09IFRoaXMpCiAgICB7CiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1VubG9ja1JlY3QoaWZhY2UpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIElXaW5lRDNEU3VyZmFjZV9VbmxvY2tSZWN0KGlmYWNlKTsKICAgICAgICBJV2luZUQzRFN1cmZhY2VfVW5sb2NrUmVjdChTb3VyY2UpOwogICAgfQoKICAgIHJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJV2luZUQzRFN1cmZhY2U6OkxvYWRUZXh0dXJlLCBHREkgdmVyc2lvbgogKgogKiBUaGlzIGlzIG11dHVhbGx5IHVuc3VwcG9ydGVkIGJ5IEdESSBzdXJmYWNlcwogKgogKiBSZXR1cm5zOgogKiAgRDNERVJSX0lOVkFMSURDQUxMCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KSFJFU1VMVCBXSU5BUEkKSVdpbmVHRElTdXJmYWNlSW1wbF9Mb2FkVGV4dHVyZShJV2luZUQzRFN1cmZhY2UgKmlmYWNlKQp7CiAgICBFUlIoIlVuc3VwcG9ydGVkIG9uIFgxMSBzdXJmYWNlc1xuIik7CiAgICByZXR1cm4gRDNERVJSX0lOVkFMSURDQUxMOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSVdpbmVEM0RTdXJmYWNlOjpTYXZlU25hcHNob3QsIEdESSB2ZXJzaW9uCiAqCiAqIFRoaXMgbWV0aG9kIHdyaXRlcyB0aGUgc3VyZmFjZSdzIGNvbnRlbnRzIHRvIHRoZSBpbiB0Z2EgZm9ybWF0IHRvIHRoZQogKiBmaWxlIHNwZWNpZmllZCBpbiBmaWxlbmFtZS4KICoKICogUGFyYW1zOgogKiAgZmlsZW5hbWU6IEZpbGUgdG8gd3JpdGUgdG8KICoKICogUmV0dXJuczoKICogIFdJTkVEM0RFUlJfSU5WQUxJRENBTEwgaWYgdGhlIGZpbGUgY291bGRuJ3QgYmUgb3BlbmVkCiAqICBXSU5FRDNEX09LIG9uIHN1Y2Nlc3MKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgaW50IGdldF9zaGlmdChEV09SRCBjb2xvcl9tYXNrKSB7CiAgICBpbnQgc2hpZnQgPSAwOwogICAgd2hpbGUgKGNvbG9yX21hc2sgPiAweEZGKSB7CiAgICAgICAgY29sb3JfbWFzayA+Pj0gMTsKICAgICAgICBzaGlmdCArPSAxOwogICAgfQogICAgd2hpbGUgKChjb2xvcl9tYXNrICYgMHg4MCkgPT0gMCkgewogICAgICAgIGNvbG9yX21hc2sgPDw9IDE7CiAgICAgICAgc2hpZnQgLT0gMTsKICAgIH0KICAgIHJldHVybiBzaGlmdDsKfQoKCkhSRVNVTFQgV0lOQVBJCklXaW5lR0RJU3VyZmFjZUltcGxfU2F2ZVNuYXBzaG90KElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsCmNvbnN0IGNoYXIqIGZpbGVuYW1lKQp7CiAgICBGSUxFKiBmID0gTlVMTDsKICAgIFVJTlQgeSA9IDAsIHggPSAwOwogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICBzdGF0aWMgY2hhciAqb3V0cHV0ID0gTlVMTDsKICAgIHN0YXRpYyBpbnQgc2l6ZSA9IDA7CiAgICBjb25zdCBQaXhlbEZvcm1hdERlc2MgKmZvcm1hdEVudHJ5ID0gZ2V0Rm9ybWF0RGVzY0VudHJ5KFRoaXMtPnJlc291cmNlLmZvcm1hdCk7CgogICAgaWYgKFRoaXMtPnBvdzJXaWR0aCA+IHNpemUpIHsKICAgICAgICBvdXRwdXQgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgVGhpcy0+cG93MldpZHRoICogMyk7CiAgICAgICAgc2l6ZSA9IFRoaXMtPnBvdzJXaWR0aDsKICAgIH0KCgogICAgZiA9IGZvcGVuKGZpbGVuYW1lLCAidysiKTsKICAgIGlmIChOVUxMID09IGYpIHsKICAgICAgICBFUlIoIm9wZW5pbmcgb2YgJXMgZmFpbGVkIHdpdGhcbiIsIGZpbGVuYW1lKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KICAgIGZwcmludGYoZiwgIlA2XG4lZCAlZFxuMjU1XG4iLCBUaGlzLT5wb3cyV2lkdGgsIFRoaXMtPnBvdzJIZWlnaHQpOwoKICAgIGlmIChUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9QOCkgewogICAgICAgIHVuc2lnbmVkIGNoYXIgdGFibGVbMjU2XVszXTsKICAgICAgICBpbnQgaTsKCiAgICAgICAgaWYgKFRoaXMtPnBhbGV0dGUgPT0gTlVMTCkgewogICAgICAgICAgICBmY2xvc2UoZik7CiAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgICAgIH0KICAgICAgICBmb3IgKGkgPSAwOyBpIDwgMjU2OyBpKyspIHsKICAgICAgICAgICAgdGFibGVbaV1bMF0gPSBUaGlzLT5wYWxldHRlLT5wYWxlbnRzW2ldLnBlUmVkOwogICAgICAgICAgICB0YWJsZVtpXVsxXSA9IFRoaXMtPnBhbGV0dGUtPnBhbGVudHNbaV0ucGVHcmVlbjsKICAgICAgICAgICAgdGFibGVbaV1bMl0gPSBUaGlzLT5wYWxldHRlLT5wYWxlbnRzW2ldLnBlQmx1ZTsKICAgICAgICB9CiAgICAgICAgZm9yICh5ID0gMDsgeSA8IFRoaXMtPnBvdzJIZWlnaHQ7IHkrKykgewogICAgICAgICAgICB1bnNpZ25lZCBjaGFyICpzcmMgPSAodW5zaWduZWQgY2hhciAqKSBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkgKyAoeSAqIDEgKiBJV2luZUQzRFN1cmZhY2VfR2V0UGl0Y2goaWZhY2UpKTsKICAgICAgICAgICAgZm9yICh4ID0gMDsgeCA8IFRoaXMtPnBvdzJXaWR0aDsgeCsrKSB7CiAgICAgICAgICAgICAgICB1bnNpZ25lZCBjaGFyIGNvbG9yID0gKnNyYzsKICAgICAgICAgICAgICAgIHNyYyArPSAxOwoKICAgICAgICAgICAgICAgIG91dHB1dFszICogeCArIDBdID0gdGFibGVbY29sb3JdWzBdOwogICAgICAgICAgICAgICAgb3V0cHV0WzMgKiB4ICsgMV0gPSB0YWJsZVtjb2xvcl1bMV07CiAgICAgICAgICAgICAgICBvdXRwdXRbMyAqIHggKyAyXSA9IHRhYmxlW2NvbG9yXVsyXTsKICAgICAgICAgICAgfQogICAgICAgICAgICBmd3JpdGUob3V0cHV0LCAzICogVGhpcy0+cG93MldpZHRoLCAxLCBmKTsKICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIGludCByZWRfc2hpZnQsIGdyZWVuX3NoaWZ0LCBibHVlX3NoaWZ0LCBwaXhfd2lkdGg7CgogICAgICAgIHBpeF93aWR0aCA9IFRoaXMtPmJ5dGVzUGVyUGl4ZWw7CgogICAgICAgIHJlZF9zaGlmdCA9IGdldF9zaGlmdChmb3JtYXRFbnRyeS0+cmVkTWFzayk7CiAgICAgICAgZ3JlZW5fc2hpZnQgPSBnZXRfc2hpZnQoZm9ybWF0RW50cnktPmdyZWVuTWFzayk7CiAgICAgICAgYmx1ZV9zaGlmdCA9IGdldF9zaGlmdChmb3JtYXRFbnRyeS0+Ymx1ZU1hc2spOwoKICAgICAgICBmb3IgKHkgPSAwOyB5IDwgVGhpcy0+cG93MkhlaWdodDsgeSsrKSB7CiAgICAgICAgICAgIHVuc2lnbmVkIGNoYXIgKnNyYyA9ICh1bnNpZ25lZCBjaGFyICopIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSArICh5ICogMSAqIElXaW5lRDNEU3VyZmFjZV9HZXRQaXRjaChpZmFjZSkpOwogICAgICAgICAgICBmb3IgKHggPSAwOyB4IDwgVGhpcy0+cG93MldpZHRoOyB4KyspIHsJICAgIAogICAgICAgICAgICAgICAgdW5zaWduZWQgaW50IGNvbG9yOwogICAgICAgICAgICAgICAgdW5zaWduZWQgaW50IGNvbXA7CiAgICAgICAgICAgICAgICBpbnQgaTsKCiAgICAgICAgICAgICAgICBjb2xvciA9IDA7CiAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgcGl4X3dpZHRoOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICBjb2xvciB8PSBzcmNbaV0gPDwgKDggKiBpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHNyYyArPSAxICogcGl4X3dpZHRoOwoKICAgICAgICAgICAgICAgIGNvbXAgPSBjb2xvciAmIGZvcm1hdEVudHJ5LT5yZWRNYXNrOwogICAgICAgICAgICAgICAgb3V0cHV0WzMgKiB4ICsgMF0gPSByZWRfc2hpZnQgPiAwID8gY29tcCA+PiByZWRfc2hpZnQgOiBjb21wIDw8IC1yZWRfc2hpZnQ7CiAgICAgICAgICAgICAgICBjb21wID0gY29sb3IgJiBmb3JtYXRFbnRyeS0+Z3JlZW5NYXNrOwogICAgICAgICAgICAgICAgb3V0cHV0WzMgKiB4ICsgMV0gPSBncmVlbl9zaGlmdCA+IDAgPyBjb21wID4+IGdyZWVuX3NoaWZ0IDogY29tcCA8PCAtZ3JlZW5fc2hpZnQ7CiAgICAgICAgICAgICAgICBjb21wID0gY29sb3IgJiBmb3JtYXRFbnRyeS0+Ymx1ZU1hc2s7CiAgICAgICAgICAgICAgICBvdXRwdXRbMyAqIHggKyAyXSA9IGJsdWVfc2hpZnQgPiAwID8gY29tcCA+PiBibHVlX3NoaWZ0IDogY29tcCA8PCAtYmx1ZV9zaGlmdDsKICAgICAgICAgICAgfQogICAgICAgICAgICBmd3JpdGUob3V0cHV0LCAzICogVGhpcy0+cG93MldpZHRoLCAxLCBmKTsKICAgICAgICB9CiAgICB9CiAgICBmY2xvc2UoZik7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElXaW5lRDNEU3VyZmFjZTo6UHJpdmF0ZVNldHVwLCBHREkgdmVyc2lvbgogKgogKiBJbml0aWFsaXplcyB0aGUgR0RJIHN1cmZhY2UsIGFrYSBjcmVhdGVzIHRoZSBESUIgc2VjdGlvbiB3ZSByZW5kZXIgdG8KICogVGhlIERJQiBzZWN0aW9uIGNyZWF0aW9uIGlzIGRvbmUgYnkgY2FsbGluZyBHZXREQywgd2hpY2ggd2lsbCBjcmVhdGUgdGhlCiAqIHNlY3Rpb24gYW5kIHJlbGVhc2luZyB0aGUgZGMgdG8gYWxsb3cgdGhlIGFwcCB0byB1c2UgaXQuIFRoZSBkaWIgc2VjdGlvbgogKiB3aWxsIHN0YXkgdW50aWwgdGhlIHN1cmZhY2UgaXMgcmVsZWFzZWQKICoKICogR0RJIHN1cmZhY2VzIGRvIG5vdCBuZWVkIHRvIGJlIGEgcG93ZXIgb2YgMiBpbiBzaXplLCBzbyB0aGUgcG93MiBzaXplcwogKiBhcmUgc2V0IHRvIHRoZSByZWFsIHNpemVzIHRvIHNhdmUgbWVtb3J5LiBUaGUgTk9OUE9XMiBmbGFnIGlzIHVuc2V0IHRvCiAqIGF2b2lkIGNvbmZ1c2lvbiBpbiB0aGUgc2hhcmVkIHN1cmZhY2UgY29kZS4KICoKICogUmV0dXJuczoKICogIEQzRF9PSyBvbiBzdWNjZXNzCiAqICBUaGUgcmV0dXJuIHZhbHVlcyBvZiBjYWxsZWQgbWV0aG9kcyBvbiBmYWlsdXJlCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KSFJFU1VMVCBXSU5BUEkKSVdpbmVHRElTdXJmYWNlSW1wbF9Qcml2YXRlU2V0dXAoSVdpbmVEM0RTdXJmYWNlICppZmFjZSkKewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIGlmYWNlOwogICAgSFJFU1VMVCBocjsKICAgIEhEQyBoZGM7CiAgICBsb25nIG9sZHNpemUgPSBUaGlzLT5yZXNvdXJjZS5zaXplOwoKICAgIC8qIFN5c21lbSB0ZXh0dXJlcyBoYXZlIG1lbW9yeSBhbHJlYWR5IGFsbG9jYXRlZCAtCiAgICAgKiByZWxlYXNlIGl0LCB0aGlzIGF2b2lkcyBhbiB1bm5lY2Vzc2FyeSBtZW1jcHkKICAgICAqLwogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KTsKICAgIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSA9IE5VTEw7CgogICAgLyogV2UgZG9uJ3QgbWluZCB0aGUgbm9ucG93MiBzdHVmZiBpbiBHREkgKi8KICAgIFRoaXMtPnJlc291cmNlLnNpemUgPSBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aCAqIGdldEZvcm1hdERlc2NFbnRyeShUaGlzLT5yZXNvdXJjZS5mb3JtYXQpLT5icHAgKiBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aDsKICAgIFRoaXMtPnBvdzJTaXplID0gVGhpcy0+cmVzb3VyY2Uuc2l6ZTsKICAgIFRoaXMtPnBvdzJXaWR0aCA9IFRoaXMtPmN1cnJlbnREZXNjLldpZHRoOwogICAgVGhpcy0+cG93MkhlaWdodCA9IFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodDsKICAgIFRoaXMtPkZsYWdzICY9IH5TRkxBR19OT05QT1cyOwoKICAgIC8qIEFkanVzdCB0aGUgb3BlbmdsIG1lbSBjb3VudGVyICovCiAgICBnbG9iYWxDaGFuZ2VHbFJhbShUaGlzLT5yZXNvdXJjZS5zaXplIC0gb2xkc2l6ZSk7CgogICAgLyogQ2FsbCBHZXREQyB0byBjcmVhdGUgYSBESUIgc2VjdGlvbi4gV2Ugd2lsbCB1c2UgdGhhdAogICAgICogRElCIHNlY3Rpb24gZm9yIHJlbmRlcmluZwogICAgICoKICAgICAqIFJlbGVhc2UgdGhlIERDIGFmdGVyd2FyZHMgdG8gYWxsb3cgdGhlIGFwcCB0byB1c2UgaXQKICAgICAqLwogICAgaHIgPSBJV2luZUQzRFN1cmZhY2VfR2V0REMoaWZhY2UsICZoZGMpOwogICAgaWYoRkFJTEVEKGhyKSkKICAgIHsKICAgICAgICBFUlIoIiglcCkgSVdpbmVEM0RTdXJmYWNlOjpHZXREQyBmYWlsZWQgd2l0aCBociAlMDhseFxuIiwgVGhpcywgaHIpOwogICAgICAgIHJldHVybiBocjsKICAgIH0KICAgIGhyID0gSVdpbmVEM0RTdXJmYWNlX1JlbGVhc2VEQyhpZmFjZSwgaGRjKTsKICAgIGlmKEZBSUxFRChocikpCiAgICB7CiAgICAgICAgRVJSKCIoJXApIElXaW5lRDNEU3VyZmFjZTo6UmVsZWFzZURDIGZhaWxlZCB3aXRoIGhyICUwOGx4XG4iLCBUaGlzLCBocik7CiAgICAgICAgcmV0dXJuIGhyOwogICAgfQoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9Cgpjb25zdCBJV2luZUQzRFN1cmZhY2VWdGJsIElXaW5lR0RJU3VyZmFjZV9WdGJsID0KewogICAgLyogSVVua25vd24gKi8KICAgIElXaW5lRDNEU3VyZmFjZUltcGxfUXVlcnlJbnRlcmZhY2UsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0FkZFJlZiwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfUmVsZWFzZSwKICAgIC8qIElXaW5lRDNEUmVzb3VyY2UgKi8KICAgIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0UGFyZW50LAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXREZXZpY2UsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1NldFByaXZhdGVEYXRhLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXRQcml2YXRlRGF0YSwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfRnJlZVByaXZhdGVEYXRhLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9TZXRQcmlvcml0eSwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0UHJpb3JpdHksCiAgICBJV2luZUdESVN1cmZhY2VJbXBsX1ByZUxvYWQsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0dldFR5cGUsCiAgICAvKiBJV2luZUQzRFN1cmZhY2UgKi8KICAgIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0Q29udGFpbmVyUGFyZW50LAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXRDb250YWluZXIsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0dldERlc2MsCiAgICBJV2luZUdESVN1cmZhY2VJbXBsX0xvY2tSZWN0LAogICAgSVdpbmVHRElTdXJmYWNlSW1wbF9VbmxvY2tSZWN0LAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXREQywKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfUmVsZWFzZURDLAogICAgSVdpbmVHRElTdXJmYWNlSW1wbF9GbGlwLAogICAgSVdpbmVHRElTdXJmYWNlSW1wbF9CbHQsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0dldEJsdFN0YXR1cywKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0RmxpcFN0YXR1cywKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfSXNMb3N0LAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9SZXN0b3JlLAogICAgSVdpbmVHRElTdXJmYWNlSW1wbF9CbHRGYXN0LAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXRQYWxldHRlLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9TZXRQYWxldHRlLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9SZWFsaXplUGFsZXR0ZSwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfU2V0Q29sb3JLZXksCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0dldFBpdGNoLAogICAgLyogSW50ZXJuYWwgdXNlOiAqLwogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9DbGVhbkRpcnR5UmVjdCwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfQWRkRGlydHlSZWN0LAogICAgSVdpbmVHRElTdXJmYWNlSW1wbF9Mb2FkVGV4dHVyZSwKICAgIElXaW5lR0RJU3VyZmFjZUltcGxfU2F2ZVNuYXBzaG90LAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9TZXRDb250YWluZXIsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1NldFBCdWZmZXJTdGF0ZSwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfU2V0R2xUZXh0dXJlRGVzYywKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0R2xEZXNjLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXREYXRhLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9TZXRGb3JtYXQsCiAgICBJV2luZUdESVN1cmZhY2VJbXBsX1ByaXZhdGVTZXR1cAp9Owo=