LyoKICogQ29weXJpZ2h0IChjKSAyMDA3LTIwMDggQXRoZXJvcyBDb21tdW5pY2F0aW9ucyBJbmMuCiAqCiAqIFBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGFuZC9vciBkaXN0cmlidXRlIHRoaXMgc29mdHdhcmUgZm9yIGFueQogKiBwdXJwb3NlIHdpdGggb3Igd2l0aG91dCBmZWUgaXMgaGVyZWJ5IGdyYW50ZWQsIHByb3ZpZGVkIHRoYXQgdGhlIGFib3ZlCiAqIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2UgYXBwZWFyIGluIGFsbCBjb3BpZXMuCiAqCiAqIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCAiQVMgSVMiIEFORCBUSEUgQVVUSE9SIERJU0NMQUlNUyBBTEwgV0FSUkFOVElFUwogKiBXSVRIIFJFR0FSRCBUTyBUSElTIFNPRlRXQVJFIElOQ0xVRElORyBBTEwgSU1QTElFRCBXQVJSQU5USUVTIE9GCiAqIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUy4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUiBCRSBMSUFCTEUgRk9SCiAqIEFOWSBTUEVDSUFMLCBESVJFQ1QsIElORElSRUNULCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgT1IgQU5ZIERBTUFHRVMKICogV0hBVFNPRVZFUiBSRVNVTFRJTkcgRlJPTSBMT1NTIE9GIFVTRSwgREFUQSBPUiBQUk9GSVRTLCBXSEVUSEVSIElOIEFOCiAqIEFDVElPTiBPRiBDT05UUkFDVCwgTkVHTElHRU5DRSBPUiBPVEhFUiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GCiAqIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SIFBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuCiAqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgTW9kdWxlIE5hbWUgOiBtbS5jICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgQWJzdHJhY3QgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIFRoaXMgbW9kdWxlIGNvbnRhaW5zIGNvbW1vbiBmdW5jdGlvbnMgZm9yIGhhbmRsZSBtYW5hZ2VtZW50ICAgICAqLwovKiAgICAgIGZyYW1lLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgTk9URVMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIE5vbmUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwojaW5jbHVkZSAiY3ByZWNvbXAuaCIKI2luY2x1ZGUgIi4uL2hhbC9ocHJlZy5oIgoKLyogVE9ETyA6IHB1dCBhbGwgY29uc3RhbnQgdGFibGVzIHRvIGEgZmlsZSAqLwpjb25zdCB1OF90IHpnMTFiUmF0ZVRibFs0XSA9IHsyLCA0LCAxMSwgMjJ9Owpjb25zdCB1OF90IHpnMTFnUmF0ZVRibFs4XSA9IHsxMiwgMTgsIDI0LCAzNiwgNDgsIDcyLCA5NiwgMTA4fTsKCi8qIDB4ZmYgPT4gZWxlbWVudCBkb2VzIG5vdCBleGlzdCAqLwpjb25zdCB1OF90IHpnRWxlbWVudE9mZnNldFRhYmxlW10gPQp7CiAgICA0LCAgICAgIC8qICAwIDogYXNvYyByZXEgKi8KICAgIDYsICAgICAgLyogIDEgOiBhc29jIHJzcCAqLwogICAgMTAsICAgICAvKiAgMiA6IHJlYXNvYyByZXEqLwogICAgNiwgICAgICAvKiAgMyA6IHJlYXNvYyByc3AgKi8KICAgIDAsICAgICAgLyogIDQgOiBwcm9iZSByZXEgKi8KICAgIDEyLCAgICAgLyogIDUgOiBwcm9iZSByc3AgKi8KICAgIDB4ZmYsICAgLyogIDYgOiByZXNlcnZlZCAqLwogICAgMHhmZiwgICAvKiAgNyA6IHJlc2VydmVkICovCiAgICAxMiwgICAgIC8qICA4IDogYmVhY29uICovCiAgICA0LCAgICAgIC8qICA5IDogQVRJTSAqLwogICAgMHhmZiwgICAvKiAxMCA6IGRpc2Fzb2MgKi8KICAgIDYsICAgICAgLyogMTEgOiBhdXRoICovCiAgICAweGZmLCAgIC8qIDEyIDogZGVhdXRoICovCiAgICA0LCAgICAgIC8qIDEzIDogYWN0aW9uICovCiAgICAweGZmLCAgIC8qIDE0IDogcmVzZXJ2ZWQgKi8KICAgIDB4ZmYsICAgLyogMTUgOiByZXNlcnZlZCAqLwp9OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgRlVOQ1RJT04gREVTQ1JJUFRJT04gICAgICAgICAgICAgICAgICB6ZkZpbmRFbGVtZW50ICAgICAgICAgICAgICAgKi8KLyogICAgICBGaW5kIGEgc3BlY2lmaWMgZWxlbWVudCBpbiBtYW5hZ2VtZW50IGZyYW1lICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgSU5QVVRTICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgICBkZXYgOiBkZXZpY2UgcG9pbnRlciAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgICBidWYgOiBtYW5hZ2VtZW50IGZyYW1lIGJ1ZmZlciAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgICBlaWQgOiB0YXJnZXQgZWxlbWVudCBpZCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgT1VUUFVUUyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgICBieXRlIG9mZnNldCBvZiB0YXJnZXQgZWxlbWVudCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgICBvciAweGZmZmYgaWYgbm90IGZvdW5kICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgQVVUSE9SICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgICBTdGVwaGVuIENoZW4gICAgICAgIFp5REFTIFRlY2hub2xvZ3kgQ29ycG9yYXRpb24gICAgMjAwNS4xMCAgICAgKi8KLyogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KdTE2X3QgemZGaW5kRWxlbWVudCh6ZGV2X3QqIGRldiwgemJ1Zl90KiBidWYsIHU4X3QgZWlkKQp7CiAgICB1OF90IHN1YlR5cGU7CiAgICB1MTZfdCBvZmZzZXQ7CiAgICB1MTZfdCBidWZMZW47CiAgICB1MTZfdCBlbGVuOwogICAgdThfdCBpZCwgSFRFaWQ9MDsKICAgIHU4X3Qgb3VpWzRdID0gezB4MDAsIDB4NTAsIDB4ZjIsIDB4MDF9OwogICAgdThfdCBvdWkxMW5bM10gPSB7MHgwMCwweDkwLDB4NEN9OwogICAgdThfdCBIVFR5cGUgPSAwOwoKICAgIC8qIEdldCBvZmZzZXQgb2YgZmlyc3QgZWxlbWVudCAqLwogICAgc3ViVHlwZSA9ICh6bXdfcnhfYnVmX3JlYWRiKGRldiwgYnVmLCAwKSA+PiA0KTsKICAgIGlmICgob2Zmc2V0ID0gemdFbGVtZW50T2Zmc2V0VGFibGVbc3ViVHlwZV0pID09IDB4ZmYpCiAgICB7CiAgICAgICAgem1fYXNzZXJ0KDApOwogICAgfQoKICAgIC8qIFBsdXMgd2xhbiBoZWFkZXIgKi8KICAgIG9mZnNldCArPSAyNDsKCiAgICAvLyBqaGxlZSBIVCAwCgogICAgaWYgKChlaWQgPT0gWk1fV0xBTl9FSURfSFRfQ0FQQUJJTElUWSkgfHwKICAgICAgICAoZWlkID09IFpNX1dMQU5fRUlEX0VYVEVOREVEX0hUX0NBUEFCSUxJVFkpKQogICAgewogICAgICAgIEhURWlkID0gZWlkOwogICAgICAgIGVpZCA9IFpNX1dMQU5fRUlEX1dQQV9JRTsKICAgICAgICBIVFR5cGUgPSAxOwogICAgfQoKCiAgICBidWZMZW4gPSB6ZndCdWZHZXRTaXplKGRldiwgYnVmKTsKICAgIC8qIFNlYXJjaCBsb29wICovCiAgICB3aGlsZSAoKG9mZnNldCsyKTxidWZMZW4pICAgICAgICAgICAgICAgICAgIC8vIGluY2x1ZGluZyBlbGVtZW50IElEIGFuZCBsZW5ndGggKDJieXRlcykKICAgIHsKICAgICAgICAvKiBTZWFyY2ggdGFyZ2V0IGVsZW1lbnQgKi8KICAgICAgICBpZiAoKGlkID0gem13X3J4X2J1Zl9yZWFkYihkZXYsIGJ1Ziwgb2Zmc2V0KSkgPT0gZWlkKQogICAgICAgIHsKICAgICAgICAgICAgLyogQmluZ28gKi8KICAgICAgICAgICAgaWYgKChlbGVuID0gem13X3J4X2J1Zl9yZWFkYihkZXYsIGJ1Ziwgb2Zmc2V0KzEpKT4oYnVmTGVuIC0gb2Zmc2V0KSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLyogRWxlbWVudCBsZW5ndGggZXJyb3IgKi8KICAgICAgICAgICAgICAgIHJldHVybiAweGZmZmY7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICggZWxlbiA9PSAwICYmIGVpZCAhPSBaTV9XTEFOX0VJRF9TU0lEKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvKiBFbGVtZW50IGxlbmd0aCBlcnJvciAqLwogICAgICAgICAgICAgICAgcmV0dXJuIDB4ZmZmZjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCBlaWQgPT0gWk1fV0xBTl9FSURfV1BBX0lFICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLyogYXZvaWQgc3RhIHRvIGJlIHRob3VnaHQgdXNlIDExbiB3aGVuIGZpbmQgYSBXUEFfSUUgKi8KICAgICAgICAgICAgICAgIGlmICggKEhUVHlwZSA9PSAwKSAmJiB6ZlJ4QnVmZmVyRXF1YWxUb1N0cihkZXYsIGJ1Ziwgb3VpLCBvZmZzZXQrMiwgNCkgKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBvZmZzZXQ7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gamhsZWUgSFQgMAogICAgICAgICAgICAgICAgLy8gQ1dZYW5nKCspCgogICAgICAgICAgICAgICAgaWYgKChIVFR5cGUgPT0gMSkgJiYgKCB6ZlJ4QnVmZmVyRXF1YWxUb1N0cihkZXYsIGJ1Ziwgb3VpMTFuLCBvZmZzZXQrMiwgMykgKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoIHptd19yeF9idWZfcmVhZGIoZGV2LCBidWYsIG9mZnNldCs1KSA9PSBIVEVpZCApCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gb2Zmc2V0ICsgNTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIG9mZnNldDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvKiBBZHZhbmNlIHRvIG5leHQgZWxlbWVudCAqLwogICAgICAgICNpZiAxCiAgICAgICAgZWxlbiA9IHptd19yeF9idWZfcmVhZGIoZGV2LCBidWYsIG9mZnNldCsxKTsKICAgICAgICAjZWxzZQogICAgICAgIGlmICgoZWxlbiA9IHptd19yeF9idWZfcmVhZGIoZGV2LCBidWYsIG9mZnNldCsxKSkgPT0gMCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiAweGZmZmY7CiAgICAgICAgfQogICAgICAgICNlbmRpZgoKICAgICAgICBvZmZzZXQgKz0gKGVsZW4rMik7CiAgICB9CiAgICByZXR1cm4gMHhmZmZmOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgRlVOQ1RJT04gREVTQ1JJUFRJT04gICAgICAgICAgICAgICAgICB6ZkZpbmRXaWZpRWxlbWVudCAgICAgICAgICAgKi8KLyogICAgICBGaW5kIGEgc3BlY2lmaWMgV2lmaSBlbGVtZW50IGluIG1hbmFnZW1lbnQgZnJhbWUgICAgICAgICAgICAgICAgKi8KLyogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgSU5QVVRTICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgICBkZXYgOiBkZXZpY2UgcG9pbnRlciAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgICBidWYgOiBtYW5hZ2VtZW50IGZyYW1lIGJ1ZmZlciAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgICB0eXBlIDogT1VJIHR5cGUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgICBzdWJUeXBlIDogT1VJIHN1YnR5cGUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgT1VUUFVUUyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgICBieXRlIG9mZnNldCBvZiB0YXJnZXQgZWxlbWVudCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgICBvciAweGZmZmYgaWYgbm90IGZvdW5kICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgQVVUSE9SICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgICBTdGVwaGVuIENoZW4gICAgICAgIFp5REFTIFRlY2hub2xvZ3kgQ29ycG9yYXRpb24gICAgMjAwNi4xICAgICAgKi8KLyogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KdTE2X3QgemZGaW5kV2lmaUVsZW1lbnQoemRldl90KiBkZXYsIHpidWZfdCogYnVmLCB1OF90IHR5cGUsIHU4X3Qgc3VidHlwZSkKewogICAgdThfdCBzdWJUeXBlOwogICAgdTE2X3Qgb2Zmc2V0OwogICAgdTE2X3QgYnVmTGVuOwogICAgdTE2X3QgZWxlbjsKICAgIHU4X3QgaWQ7CiAgICB1OF90IHRtcDsKCiAgICAvKiBHZXQgb2Zmc2V0IG9mIGZpcnN0IGVsZW1lbnQgKi8KICAgIHN1YlR5cGUgPSAoem13X3J4X2J1Zl9yZWFkYihkZXYsIGJ1ZiwgMCkgPj4gNCk7CgogICAgaWYgKChvZmZzZXQgPSB6Z0VsZW1lbnRPZmZzZXRUYWJsZVtzdWJUeXBlXSkgPT0gMHhmZikKICAgIHsKICAgICAgICB6bV9hc3NlcnQoMCk7CiAgICB9CgogICAgLyogUGx1cyB3bGFuIGhlYWRlciAqLwogICAgb2Zmc2V0ICs9IDI0OwoKICAgIGJ1ZkxlbiA9IHpmd0J1ZkdldFNpemUoZGV2LCBidWYpOwogICAgLyogU2VhcmNoIGxvb3AgKi8KICAgIHdoaWxlICgob2Zmc2V0KzIpPGJ1ZkxlbikgICAgICAgICAgICAgICAgICAgLy8gaW5jbHVkaW5nIGVsZW1lbnQgSUQgYW5kIGxlbmd0aCAoMmJ5dGVzKQogICAgewogICAgICAgIC8qIFNlYXJjaCB0YXJnZXQgZWxlbWVudCAqLwogICAgICAgIGlmICgoaWQgPSB6bXdfcnhfYnVmX3JlYWRiKGRldiwgYnVmLCBvZmZzZXQpKSA9PSBaTV9XTEFOX0VJRF9XSUZJX0lFKQogICAgICAgIHsKICAgICAgICAgICAgLyogQmluZ28gKi8KICAgICAgICAgICAgaWYgKChlbGVuID0gem13X3J4X2J1Zl9yZWFkYihkZXYsIGJ1Ziwgb2Zmc2V0KzEpKT4oYnVmTGVuIC0gb2Zmc2V0KSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLyogRWxlbWVudCBsZW5ndGggZXJyb3IgKi8KICAgICAgICAgICAgICAgIHJldHVybiAweGZmZmY7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICggZWxlbiA9PSAwICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIDB4ZmZmZjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCgodG1wID0gem13X3J4X2J1Zl9yZWFkYihkZXYsIGJ1Ziwgb2Zmc2V0KzIpKSA9PSAweDAwKQogICAgICAgICAgICAgICAgICAgICYmICgodG1wID0gem13X3J4X2J1Zl9yZWFkYihkZXYsIGJ1Ziwgb2Zmc2V0KzMpKSA9PSAweDUwKQogICAgICAgICAgICAgICAgICAgICYmICgodG1wID0gem13X3J4X2J1Zl9yZWFkYihkZXYsIGJ1Ziwgb2Zmc2V0KzQpKSA9PSAweEYyKQogICAgICAgICAgICAgICAgICAgICYmICgodG1wID0gem13X3J4X2J1Zl9yZWFkYihkZXYsIGJ1Ziwgb2Zmc2V0KzUpKSA9PSB0eXBlKSkKCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICggc3VidHlwZSAhPSAweGZmICkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoICh0bXAgPSB6bXdfcnhfYnVmX3JlYWRiKGRldiwgYnVmLCBvZmZzZXQrNikpID09IHN1YnR5cGUgICkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBvZmZzZXQ7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBvZmZzZXQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLyogQWR2YW5jZSB0byBuZXh0IGVsZW1lbnQgKi8KICAgICAgICBpZiAoKGVsZW4gPSB6bXdfcnhfYnVmX3JlYWRiKGRldiwgYnVmLCBvZmZzZXQrMSkpID09IDApCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gMHhmZmZmOwogICAgICAgIH0KICAgICAgICBvZmZzZXQgKz0gKGVsZW4rMik7CiAgICB9CiAgICByZXR1cm4gMHhmZmZmOwp9Cgp1MTZfdCB6ZlJlbW92ZUVsZW1lbnQoemRldl90KiBkZXYsIHU4X3QqIGJ1ZiwgdTE2X3Qgc2l6ZSwgdThfdCBlaWQpCnsKICAgIHUxNl90IG9mZnNldCA9IDA7CiAgICB1MTZfdCBlbGVuOwogICAgdThfdCAgSFRFaWQgPSAwOwogICAgdThfdCAgb3VpWzRdID0gezB4MDAsIDB4NTAsIDB4ZjIsIDB4MDF9OwogICAgdThfdCAgb3VpMTFuWzNdID0gezB4MDAsMHg5MCwweDRDfTsKICAgIHU4X3QgIEhUVHlwZSA9IDA7CgogICAgaWYgKChlaWQgPT0gWk1fV0xBTl9FSURfSFRfQ0FQQUJJTElUWSkgfHwKICAgICAgICAoZWlkID09IFpNX1dMQU5fRUlEX0VYVEVOREVEX0hUX0NBUEFCSUxJVFkpKQogICAgewogICAgICAgIEhURWlkID0gZWlkOwogICAgICAgIGVpZCA9IFpNX1dMQU5fRUlEX1dQQV9JRTsKICAgICAgICBIVFR5cGUgPSAxOwogICAgfQoKICAgIHdoaWxlIChvZmZzZXQgPCBzaXplKQogICAgewogICAgICAgIGVsZW4gPSAqKGJ1ZitvZmZzZXQrMSk7CgogICAgICAgIGlmICgqKGJ1ZitvZmZzZXQpID09IGVpZCkKICAgICAgICB7CiAgICAgICAgICAgIGlmICggZWlkID09IFpNX1dMQU5fRUlEX1dQQV9JRSApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICggKEhUVHlwZSA9PSAwKQogICAgICAgICAgICAgICAgICAgICAmJiAoKihidWYrb2Zmc2V0KzIpID09IG91aVswXSkKICAgICAgICAgICAgICAgICAgICAgJiYgKCooYnVmK29mZnNldCszKSA9PSBvdWlbMV0pCiAgICAgICAgICAgICAgICAgICAgICYmICgqKGJ1ZitvZmZzZXQrNCkgPT0gb3VpWzJdKQogICAgICAgICAgICAgICAgICAgICAmJiAoKihidWYrb2Zmc2V0KzUpID09IG91aVszXSkgKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHpmTWVtb3J5TW92ZShidWYrb2Zmc2V0LCBidWYrb2Zmc2V0K2VsZW4rMiwgc2l6ZS1vZmZzZXQtZWxlbi0yKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gKHNpemUtZWxlbi0yKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoIChIVFR5cGUgPT0gMSkKICAgICAgICAgICAgICAgICAgICAmJiAoKihidWYrb2Zmc2V0KzIpID09IG91aTExblswXSkKICAgICAgICAgICAgICAgICAgICAmJiAoKihidWYrb2Zmc2V0KzMpID09IG91aTExblsxXSkKICAgICAgICAgICAgICAgICAgICAmJiAoKihidWYrb2Zmc2V0KzQpID09IG91aTExblsyXSkKICAgICAgICAgICAgICAgICAgICAmJiAoKihidWYrb2Zmc2V0KzUpID09IEhURWlkKSApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgemZNZW1vcnlNb3ZlKGJ1ZitvZmZzZXQsIGJ1ZitvZmZzZXQrZWxlbisyLCBzaXplLW9mZnNldC1lbGVuLTIpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiAoc2l6ZS1lbGVuLTIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgemZNZW1vcnlNb3ZlKGJ1ZitvZmZzZXQsIGJ1ZitvZmZzZXQrZWxlbisyLCBzaXplLW9mZnNldC1lbGVuLTIpOwogICAgICAgICAgICAgICAgcmV0dXJuIChzaXplLWVsZW4tMik7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIG9mZnNldCArPSAoZWxlbisyKTsKICAgIH0KCiAgICByZXR1cm4gc2l6ZTsKfQoKdTE2X3QgemZVcGRhdGVFbGVtZW50KHpkZXZfdCogZGV2LCB1OF90KiBidWYsIHUxNl90IHNpemUsIHU4X3QqIHVwZGF0ZWVpZCkKewogICAgdTE2X3Qgb2Zmc2V0ID0gMDsKICAgIHUxNl90IGVsZW47CgogICAgd2hpbGUgKG9mZnNldCA8IHNpemUpIHsKICAgICAgICBlbGVuID0gKihidWYrb2Zmc2V0KzEpOwoKICAgICAgICBpZiAoKihidWYrb2Zmc2V0KSA9PSB1cGRhdGVlaWRbMF0pIHsKICAgICAgICAgICAgaWYgKHVwZGF0ZWVpZFsxXSA8PSBlbGVuKSB7CiAgICAgICAgICAgICAgICB6Zk1lbW9yeU1vdmUoYnVmK29mZnNldCwgdXBkYXRlZWlkLCB1cGRhdGVlaWRbMV0rMik7CiAgICAgICAgICAgICAgICB6Zk1lbW9yeU1vdmUoYnVmK29mZnNldCt1cGRhdGVlaWRbMV0rMiwgYnVmK29mZnNldCtlbGVuKzIsIHNpemUtb2Zmc2V0LWVsZW4tMik7CgogICAgICAgICAgICAgICAgcmV0dXJuIHNpemUtKGVsZW4tdXBkYXRlZWlkWzFdKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHpmTWVtb3J5TW92ZShidWYrb2Zmc2V0K3VwZGF0ZWVpZFsxXSsyLCBidWYrb2Zmc2V0K2VsZW4rMiwgc2l6ZS1vZmZzZXQtZWxlbi0yKTsKICAgICAgICAgICAgICAgIHpmTWVtb3J5TW92ZShidWYrb2Zmc2V0LCB1cGRhdGVlaWQsIHVwZGF0ZWVpZFsxXSsyKTsKCiAgICAgICAgICAgICAgICByZXR1cm4gc2l6ZSsodXBkYXRlZWlkWzFdLWVsZW4pOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBvZmZzZXQgKz0gKGVsZW4rMik7CiAgICB9CgogICAgcmV0dXJuIHNpemU7Cn0KCnUxNl90IHpmRmluZFN1cGVyR0VsZW1lbnQoemRldl90KiBkZXYsIHpidWZfdCogYnVmLCB1OF90IHR5cGUpCnsKICAgIHU4X3Qgc3ViVHlwZTsKICAgIHUxNl90IG9mZnNldDsKICAgIHUxNl90IGJ1ZkxlbjsKICAgIHUxNl90IGVsZW47CiAgICB1OF90IGlkOwogICAgdThfdCBzdXBlcl9mZWF0dXJlOwogICAgdThfdCBvdWlTdXBlckdbNl0gPSB7MHgwMCwweDAzLDB4N2YsMHgwMSwgMHgwMSwgMHgwMH07CgogICAgem13X2dldF93bGFuX2RldihkZXYpOwoKICAgIC8qIEdldCBvZmZzZXQgb2YgZmlyc3QgZWxlbWVudCAqLwogICAgc3ViVHlwZSA9ICh6bXdfcnhfYnVmX3JlYWRiKGRldiwgYnVmLCAwKSA+PiA0KTsKICAgIGlmICgob2Zmc2V0ID0gemdFbGVtZW50T2Zmc2V0VGFibGVbc3ViVHlwZV0pID09IDB4ZmYpCiAgICB7CiAgICAgICAgem1fYXNzZXJ0KDApOwogICAgfQoKICAgIC8qIFBsdXMgd2xhbiBoZWFkZXIgKi8KICAgIG9mZnNldCArPSAyNDsKCiAgICBidWZMZW4gPSB6ZndCdWZHZXRTaXplKGRldiwgYnVmKTsKICAgIC8qIFNlYXJjaCBsb29wICovCiAgICB3aGlsZSAoKG9mZnNldCsyKTxidWZMZW4pICAgICAgICAgICAgICAgICAgIC8vIGluY2x1ZGluZyBlbGVtZW50IElEIGFuZCBsZW5ndGggKDJieXRlcykKICAgIHsKICAgICAgICAvKiBTZWFyY2ggdGFyZ2V0IGVsZW1lbnQgKi8KICAgICAgICBpZiAoKGlkID0gem13X3J4X2J1Zl9yZWFkYihkZXYsIGJ1Ziwgb2Zmc2V0KSkgPT0gWk1fV0xBTl9FSURfVkVORE9SX1BSSVZBVEUpCiAgICAgICAgewogICAgICAgICAgICAvKiBCaW5nbyAqLwogICAgICAgICAgICBpZiAoKGVsZW4gPSB6bXdfcnhfYnVmX3JlYWRiKGRldiwgYnVmLCBvZmZzZXQrMSkpPihidWZMZW4gLSBvZmZzZXQpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvKiBFbGVtZW50IGxlbmd0aCBlcnJvciAqLwogICAgICAgICAgICAgICAgcmV0dXJuIDB4ZmZmZjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCBlbGVuID09IDAgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gMHhmZmZmOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoemZSeEJ1ZmZlckVxdWFsVG9TdHIoZGV2LCBidWYsIG91aVN1cGVyRywgb2Zmc2V0KzIsIDYpICYmICggem13X3J4X2J1Zl9yZWFkYihkZXYsIGJ1Ziwgb2Zmc2V0KzEpID49IDYpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvKiBzdXBlcl9mZWF0dXJlIDA6dXNlRmFzdEZyYW1lLCAxOnVzZUNvbXByZXNzaW9uLCAyOnVzZVR1cmJvUHJpbWUgKi8KICAgICAgICAgICAgICAgIHN1cGVyX2ZlYXR1cmU9IHptd19yeF9idWZfcmVhZGIoZGV2LCBidWYsIG9mZnNldCs4KTsKICAgICAgICAgICAgICAgIGlmICgoc3VwZXJfZmVhdHVyZSAmIDB4MDEpIHx8IChzdXBlcl9mZWF0dXJlICYgMHgwMikgfHwgKHN1cGVyX2ZlYXR1cmUgJiAweDA0KSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gb2Zmc2V0OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8qIEFkdmFuY2UgdG8gbmV4dCBlbGVtZW50ICovCiAgICAgICAgI2lmIDEKICAgICAgICBlbGVuID0gem13X3J4X2J1Zl9yZWFkYihkZXYsIGJ1Ziwgb2Zmc2V0KzEpOwogICAgICAgICNlbHNlCiAgICAgICAgaWYgKChlbGVuID0gem13X3J4X2J1Zl9yZWFkYihkZXYsIGJ1Ziwgb2Zmc2V0KzEpKSA9PSAwKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIDB4ZmZmZjsKICAgICAgICB9CiAgICAgICAgI2VuZGlmCgogICAgICAgIG9mZnNldCArPSAoZWxlbisyKTsKICAgIH0KICAgIHJldHVybiAweGZmZmY7Cn0KCnUxNl90IHpmRmluZFhSRWxlbWVudCh6ZGV2X3QqIGRldiwgemJ1Zl90KiBidWYsIHU4X3QgdHlwZSkKewogICAgdThfdCBzdWJUeXBlOwogICAgdTE2X3Qgb2Zmc2V0OwogICAgdTE2X3QgYnVmTGVuOwogICAgdTE2X3QgZWxlbjsKICAgIHU4X3QgaWQ7CiAgICB1OF90IG91aXhyWzZdID0gezB4MDAsMHgwMywweDdmLDB4MDMsIDB4MDEsIDB4MDB9OwoKICAgIHptd19nZXRfd2xhbl9kZXYoZGV2KTsKCiAgICAvKiBHZXQgb2Zmc2V0IG9mIGZpcnN0IGVsZW1lbnQgKi8KICAgIHN1YlR5cGUgPSAoem13X3J4X2J1Zl9yZWFkYihkZXYsIGJ1ZiwgMCkgPj4gNCk7CiAgICBpZiAoKG9mZnNldCA9IHpnRWxlbWVudE9mZnNldFRhYmxlW3N1YlR5cGVdKSA9PSAweGZmKQogICAgewogICAgICAgIHptX2Fzc2VydCgwKTsKICAgIH0KCiAgICAvKiBQbHVzIHdsYW4gaGVhZGVyICovCiAgICBvZmZzZXQgKz0gMjQ7CgogICAgYnVmTGVuID0gemZ3QnVmR2V0U2l6ZShkZXYsIGJ1Zik7CiAgICAvKiBTZWFyY2ggbG9vcCAqLwogICAgd2hpbGUgKChvZmZzZXQrMik8YnVmTGVuKSAgICAgICAgICAgICAgICAgICAvLyBpbmNsdWRpbmcgZWxlbWVudCBJRCBhbmQgbGVuZ3RoICgyYnl0ZXMpCiAgICB7CiAgICAgICAgLyogU2VhcmNoIHRhcmdldCBlbGVtZW50ICovCiAgICAgICAgaWYgKChpZCA9IHptd19yeF9idWZfcmVhZGIoZGV2LCBidWYsIG9mZnNldCkpID09IFpNX1dMQU5fRUlEX1ZFTkRPUl9QUklWQVRFKQogICAgICAgIHsKICAgICAgICAgICAgLyogQmluZ28gKi8KICAgICAgICAgICAgaWYgKChlbGVuID0gem13X3J4X2J1Zl9yZWFkYihkZXYsIGJ1Ziwgb2Zmc2V0KzEpKT4oYnVmTGVuIC0gb2Zmc2V0KSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLyogRWxlbWVudCBsZW5ndGggZXJyb3IgKi8KICAgICAgICAgICAgICAgIHJldHVybiAweGZmZmY7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICggZWxlbiA9PSAwICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIDB4ZmZmZjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKHpmUnhCdWZmZXJFcXVhbFRvU3RyKGRldiwgYnVmLCBvdWl4ciwgb2Zmc2V0KzIsIDYpICYmICggem13X3J4X2J1Zl9yZWFkYihkZXYsIGJ1Ziwgb2Zmc2V0KzEpID49IDYpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gb2Zmc2V0OwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8qIEFkdmFuY2UgdG8gbmV4dCBlbGVtZW50ICovCiAgICAgICAgI2lmIDEKICAgICAgICBlbGVuID0gem13X3J4X2J1Zl9yZWFkYihkZXYsIGJ1Ziwgb2Zmc2V0KzEpOwogICAgICAgICNlbHNlCiAgICAgICAgaWYgKChlbGVuID0gem13X3J4X2J1Zl9yZWFkYihkZXYsIGJ1Ziwgb2Zmc2V0KzEpKSA9PSAwKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIDB4ZmZmZjsKICAgICAgICB9CiAgICAgICAgI2VuZGlmCgogICAgICAgIG9mZnNldCArPSAoZWxlbisyKTsKICAgIH0KICAgIHJldHVybiAweGZmZmY7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgIEZVTkNUSU9OIERFU0NSSVBUSU9OICAgICAgICAgICAgICAgICAgemZNbUFkZEllU3VwcG9ydFJhdGUgICAgICAgICovCi8qICAgICAgQWRkIGluZm9ybWF0aW9uIGVsZW1lbnQgU3VwcG9ydCBSYXRlIHRvIGJ1ZmZlci4gICAgICAgICAgICAgICAgICovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgIElOUFVUUyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgZGV2IDogZGV2aWNlIHBvaW50ZXIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgYnVmIDogYnVmZmVyIHRvIGFkZCBpbmZvcm1hdGlvbiBlbGVtZW50ICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgb2Zmc2V0IDogYWRkIGluZm9ybWF0aW9uIGVsZW1lbnQgZnJvbSB0aGlzIG9mZnNldCAgICAgICAgICAgICAgICovCi8qICAgICAgZWlkIDogZWxlbWVudCBJRCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgcmF0ZVNldCA6ICBDQ0sgb3IgT0ZETSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgIE9VVFBVVFMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgYnVmZmVyIG9mZnNldCBhZnRlciBhZGRpbmcgaW5mb3JtYXRpb24gZWxlbWVudCAgICAgICAgICAgICAgICAgICovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgIEFVVEhPUiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgU3RlcGhlbiBDaGVuICAgICAgICBaeURBUyBUZWNobm9sb2d5IENvcnBvcmF0aW9uICAgIDIwMDUuMTAgICAgICovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnUxNl90IHpmTW1BZGRJZVN1cHBvcnRSYXRlKHpkZXZfdCogZGV2LCB6YnVmX3QqIGJ1ZiwgdTE2X3Qgb2Zmc2V0LCB1OF90IGVpZCwgdThfdCByYXRlU2V0KQp7CiAgICB1OF90IGxlbiA9IDA7CiAgICB1MTZfdCBpOwoKICAgIHptd19nZXRfd2xhbl9kZXYoZGV2KTsKCiAgICAvL2lmICggKHJhdGVTZXQgPT0gWk1fUkFURV9TRVRfT0ZETSkmJigod2QtPmdSYXRlICYgMHhmZikgPT0gMCkgKQogICAgLy97CiAgICAvLyAgICByZXR1cm4gb2Zmc2V0OwogICAgLy99CgogICAgLyogSW5mb3JtYXRpb24gOiBTdXBwb3J0IFJhdGUgKi8KICAgIGlmICggcmF0ZVNldCA9PSBaTV9SQVRFX1NFVF9DQ0sgKQogICAgewogICAgICAgIGZvciAoaT0wOyBpPDQ7IGkrKykKICAgICAgICB7CiAgICAgICAgICAgIGlmICgod2QtPmJSYXRlICYgKDB4MTw8aSkpID09ICgweDE8PGkpKQogICAgICAgICAgICAvL2lmICgoMHhmICYgKDB4MTw8aSkpID09ICgweDE8PGkpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB6bXdfdHhfYnVmX3dyaXRlYihkZXYsIGJ1Ziwgb2Zmc2V0K2xlbisyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgemcxMWJSYXRlVGJsW2ldKygod2QtPmJSYXRlQmFzaWMgJiAoMHgxPDxpKSk8PCg3LWkpKSk7CiAgICAgICAgICAgICAgICBsZW4rKzsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIGVsc2UgaWYgKCByYXRlU2V0ID09IFpNX1JBVEVfU0VUX09GRE0gKQogICAgewogICAgICAgIGZvciAoaT0wOyBpPDg7IGkrKykKICAgICAgICB7CiAgICAgICAgICAgIGlmICgod2QtPmdSYXRlICYgKDB4MTw8aSkpID09ICgweDE8PGkpKQogICAgICAgICAgICAvL2lmICgoMHhmZiAmICgweDE8PGkpKSA9PSAoMHgxPDxpKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgem13X3R4X2J1Zl93cml0ZWIoZGV2LCBidWYsIG9mZnNldCtsZW4rMiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHpnMTFnUmF0ZVRibFtpXSsoKHdkLT5nUmF0ZUJhc2ljICYgKDB4MTw8aSkpPDwoNy1pKSkpOwogICAgICAgICAgICAgICAgbGVuKys7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgaWYgKGxlbiA+IDApCiAgICB7CiAgICAgICAgLyogRWxlbWVudCBJRCAqLwogICAgICAgIHptd190eF9idWZfd3JpdGViKGRldiwgYnVmLCBvZmZzZXQsIGVpZCk7CgogICAgICAgIC8qIEVsZW1lbnQgTGVuZ3RoICovCiAgICAgICAgem13X3R4X2J1Zl93cml0ZWIoZGV2LCBidWYsIG9mZnNldCsxLCBsZW4pOwoKICAgICAgICAvKiBSZXR1cm4gdmFsdWUgKi8KICAgICAgICBvZmZzZXQgKz0gKDIrbGVuKTsKICAgIH0KCiAgICByZXR1cm4gb2Zmc2V0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICBGVU5DVElPTiBERVNDUklQVElPTiAgICAgICAgICAgICAgICAgIHpmTW1BZGRJZURzICAgICAgICAgICAgICAgICAqLwovKiAgICAgIEFkZCBpbmZvcm1hdGlvbiBlbGVtZW50IERTIHRvIGJ1ZmZlci4gICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICBJTlBVVFMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIGRldiA6IGRldmljZSBwb2ludGVyICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIGJ1ZiA6IGJ1ZmZlciB0byBhZGQgaW5mb3JtYXRpb24gZWxlbWVudCAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIG9mZnNldCA6IGFkZCBpbmZvcm1hdGlvbiBlbGVtZW50IGZyb20gdGhpcyBvZmZzZXQgICAgICAgICAgICAgICAqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICBPVVRQVVRTICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIGJ1ZmZlciBvZmZzZXQgYWZ0ZXIgYWRkaW5nIGluZm9ybWF0aW9uIGVsZW1lbnQgICAgICAgICAgICAgICAgICAqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICBBVVRIT1IgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIFN0ZXBoZW4gQ2hlbiAgICAgICAgWnlEQVMgVGVjaG5vbG9neSBDb3Jwb3JhdGlvbiAgICAyMDA1LjEwICAgICAqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwp1MTZfdCB6Zk1tQWRkSWVEcyh6ZGV2X3QqIGRldiwgemJ1Zl90KiBidWYsIHUxNl90IG9mZnNldCkKewogICAgem13X2dldF93bGFuX2RldihkZXYpOwoKICAgIC8qIEVsZW1lbnQgSUQgKi8KICAgIHptd190eF9idWZfd3JpdGViKGRldiwgYnVmLCBvZmZzZXQrKywgWk1fV0xBTl9FSURfRFMpOwoKICAgIC8qIEVsZW1lbnQgTGVuZ3RoICovCiAgICB6bXdfdHhfYnVmX3dyaXRlYihkZXYsIGJ1Ziwgb2Zmc2V0KyssIDEpOwoKICAgIC8qIEluZm9ybWF0aW9uIDogRFMgKi8KICAgIHptd190eF9idWZfd3JpdGViKGRldiwgYnVmLCBvZmZzZXQrKywKICAgICAgICAgICAgICAgICAgICAgICAgIHpmQ2hGcmVxVG9OdW0od2QtPmZyZXF1ZW5jeSwgTlVMTCkpOwoKICAgIHJldHVybiBvZmZzZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICBGVU5DVElPTiBERVNDUklQVElPTiAgICAgICAgICAgICAgICAgIHpmTW1BZGRJZUVycCAgICAgICAgICAgICAgICAqLwovKiAgICAgIEFkZCBpbmZvcm1hdGlvbiBlbGVtZW50IEVSUCB0byBidWZmZXIuICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICBJTlBVVFMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIGRldiA6IGRldmljZSBwb2ludGVyICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIGJ1ZiA6IGJ1ZmZlciB0byBhZGQgaW5mb3JtYXRpb24gZWxlbWVudCAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIG9mZnNldCA6IGFkZCBpbmZvcm1hdGlvbiBlbGVtZW50IGZyb20gdGhpcyBvZmZzZXQgICAgICAgICAgICAgICAqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICBPVVRQVVRTICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIGJ1ZmZlciBvZmZzZXQgYWZ0ZXIgYWRkaW5nIGluZm9ybWF0aW9uIGVsZW1lbnQgICAgICAgICAgICAgICAgICAqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICBBVVRIT1IgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIFN0ZXBoZW4gQ2hlbiAgICAgICAgWnlEQVMgVGVjaG5vbG9neSBDb3Jwb3JhdGlvbiAgICAyMDA1LjEwICAgICAqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwp1MTZfdCB6Zk1tQWRkSWVFcnAoemRldl90KiBkZXYsIHpidWZfdCogYnVmLCB1MTZfdCBvZmZzZXQpCnsKICAgIHptd19nZXRfd2xhbl9kZXYoZGV2KTsKCiAgICAvKiBFbGVtZW50IElEICovCiAgICB6bXdfdHhfYnVmX3dyaXRlYihkZXYsIGJ1Ziwgb2Zmc2V0KyssIFpNX1dMQU5fRUlEX0VSUCk7CgogICAgLyogRWxlbWVudCBMZW5ndGggKi8KICAgIHptd190eF9idWZfd3JpdGViKGRldiwgYnVmLCBvZmZzZXQrKywgMSk7CgogICAgLyogSW5mb3JtYXRpb24gOiBFUlAgKi8KICAgIHptd190eF9idWZfd3JpdGViKGRldiwgYnVmLCBvZmZzZXQrKywgd2QtPmVycEVsZW1lbnQpOwoKICAgIHJldHVybiBvZmZzZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICBGVU5DVElPTiBERVNDUklQVElPTiAgICAgICAgICAgICAgICAgIHpmTW1BZGRJZVdwYSAgICAgICAgICAgICAgICAqLwovKiAgICAgIEFkZCBpbmZvcm1hdGlvbiBlbGVtZW50IFdQQSB0byBidWZmZXIuICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICBJTlBVVFMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIGRldiA6IGRldmljZSBwb2ludGVyICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIGJ1ZiA6IGJ1ZmZlciB0byBhZGQgaW5mb3JtYXRpb24gZWxlbWVudCAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIG9mZnNldCA6IGFkZCBpbmZvcm1hdGlvbiBlbGVtZW50IGZyb20gdGhpcyBvZmZzZXQgICAgICAgICAgICAgICAqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICBPVVRQVVRTICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIGJ1ZmZlciBvZmZzZXQgYWZ0ZXIgYWRkaW5nIGluZm9ybWF0aW9uIGVsZW1lbnQgICAgICAgICAgICAgICAgICAqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICBBVVRIT1IgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIFl1YW4tR3UgV2VpICAgICAgICAgWnlEQVMgVGVjaG5vbG9neSBDb3Jwb3JhdGlvbiAgICAyMDA2LjIgICAgICAqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwp1MTZfdCB6Zk1tQWRkSWVXcGEoemRldl90KiBkZXYsIHpidWZfdCogYnVmLCB1MTZfdCBvZmZzZXQsIHUxNl90IGFwSWQpCnsKICAgIC8vc3RydWN0IHpzV2xhbkRldiogd2QgPSAoc3RydWN0IHpzV2xhbkRldiopIHptd193bGFuX2RldihkZXYpOwogICAgaW50IGk7CgogICAgem13X2dldF93bGFuX2RldihkZXYpOwoKICAgIC8qIEVsZW1lbnQgSUQgKi8KICAgIC8vem13X2ludHR4X2J1Zl93cml0ZWIoZGV2LCBidWYsIG9mZnNldCsrLCBaTV9XTEFOX0VJRF9XUEFfSUUpOwoKICAgIC8qIEVsZW1lbnQgTGVuZ3RoICovCiAgICAvL3ptd19pbnR0eF9idWZfd3JpdGViKGRldiwgYnVmLCBvZmZzZXQrKywgd2QtPmFwLndwYUxlbik7CiAgICBmb3IoaSA9IDA7IGkgPCB3ZC0+YXAud3BhTGVuW2FwSWRdOyBpKyspCiAgICB7CiAgICAgICAgLyogSW5mb3JtYXRpb24gOiBXUEEgKi8KICAgICAgICB6bXdfdHhfYnVmX3dyaXRlYihkZXYsIGJ1Ziwgb2Zmc2V0KyssIHdkLT5hcC53cGFJZVthcElkXVtpXSk7CiAgICB9CgogICAgcmV0dXJuIG9mZnNldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgRlVOQ1RJT04gREVTQ1JJUFRJT04gICAgICAgICAgICAgICAgICB6Zk1tQWRkSFRDYXBhYmlsaXR5ICAgICAgICAgKi8KLyogICAgICBBZGQgSFQgQ2FwYWJpbGl0eSBJbmZvbWF0aW9uIHRvIGJ1ZmZlci4gICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgSU5QVVRTICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgICBkZXYgOiBkZXZpY2UgcG9pbnRlciAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgICBidWYgOiBidWZmZXIgdG8gYWRkIGluZm9ybWF0aW9uIGVsZW1lbnQgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgICBvZmZzZXQgOiBhZGQgaW5mb3JtYXRpb24gZWxlbWVudCBmcm9tIHRoaXMgb2Zmc2V0ICAgICAgICAgICAgICAgKi8KLyogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgT1VUUFVUUyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgICBidWZmZXIgb2Zmc2V0IGFmdGVyIGFkZGluZyBpbmZvcm1hdGlvbiBlbGVtZW50ICAgICAgICAgICAgICAgICAgKi8KLyogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgQVVUSE9SICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgICBDaGFvLVdlbiBZYW5nICAgICBaeURBUyBUZWNobm9sb2d5IENvcnBvcmF0aW9uICAgICAgIDIwMDYuMDYgICAgKi8KLyogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KdTE2X3QgemZNbUFkZEhUQ2FwYWJpbGl0eSh6ZGV2X3QqIGRldiwgemJ1Zl90KiBidWYsIHUxNl90IG9mZnNldCkKewogICAgdThfdCBPVUlbM10gPSB7MHgwLDB4OTAsMHg0Q307CiAgICB1MTZfdCBpOwoKICAgIHptd19nZXRfd2xhbl9kZXYoZGV2KTsKCiAgICAvKiBQcm9iIElEICovCiAgICB6bXdfYnVmX3dyaXRlYihkZXYsIGJ1Ziwgb2Zmc2V0KyssIFpNX1dMQU5fRUlEX1dQQV9JRSk7CgogICAgaWYgKCB3ZC0+d2xhbk1vZGUgPT0gWk1fTU9ERV9BUCApCiAgICB7CiAgICAgICAgLyogRWxlbWVudCBMZW5ndGggKi8KICAgICAgICB6bXdfYnVmX3dyaXRlYihkZXYsIGJ1Ziwgb2Zmc2V0KyssIHdkLT5hcC5IVENhcC5EYXRhLkxlbmd0aCArIDQpOwoKICAgICAgICAvKiBPVUkgRGF0YSAqLwogICAgICAgIGZvciAoaSA9IDA7IGkgPCAzOyBpKyspCiAgICAgICAgewogICAgICAgICAgICB6bXdfYnVmX3dyaXRlYihkZXYsIGJ1Ziwgb2Zmc2V0KyssIE9VSVtpXSk7CiAgICAgICAgfQoKICAgICAgICAvKiBFbGVtZW50IFR5cGUgSUQgKi8KICAgICAgICB6bXdfYnVmX3dyaXRlYihkZXYsIGJ1Ziwgb2Zmc2V0KyssIHdkLT5hcC5IVENhcC5EYXRhLkVsZW1lbnRJRCk7CgogICAgICAgIC8qIEhUIENhcGFiaWxpdHkgRGF0YSAqLwogICAgICAgIGZvciAoaSA9IDA7IGkgPCAyNjsgaSsrKQogICAgICAgIHsKICAgICAgICAgICAgem13X2J1Zl93cml0ZWIoZGV2LCBidWYsIG9mZnNldCsrLCB3ZC0+YXAuSFRDYXAuQnl0ZVtpKzJdKTsKICAgICAgICB9CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgLyogRWxlbWVudCBMZW5ndGggKi8KICAgICAgICB6bXdfYnVmX3dyaXRlYihkZXYsIGJ1Ziwgb2Zmc2V0KyssIHdkLT5zdGEuSFRDYXAuRGF0YS5MZW5ndGggKyA0KTsKCiAgICAgICAgLyogT1VJIERhdGEgKi8KICAgICAgICBmb3IgKGkgPSAwOyBpIDwgMzsgaSsrKQogICAgICAgIHsKICAgICAgICAgICAgem13X2J1Zl93cml0ZWIoZGV2LCBidWYsIG9mZnNldCsrLCBPVUlbaV0pOwogICAgICAgIH0KCiAgICAgICAgLyogRWxlbWVudCBUeXBlIElEICovCiAgICAgICAgem13X2J1Zl93cml0ZWIoZGV2LCBidWYsIG9mZnNldCsrLCB3ZC0+c3RhLkhUQ2FwLkRhdGEuRWxlbWVudElEKTsKCiAgICAgICAgLyogSFQgQ2FwYWJpbGl0eSBEYXRhICovCiAgICAgICAgZm9yIChpID0gMDsgaSA8IDI2OyBpKyspCiAgICAgICAgewogICAgICAgICAgICB6bXdfYnVmX3dyaXRlYihkZXYsIGJ1Ziwgb2Zmc2V0KyssIHdkLT5zdGEuSFRDYXAuQnl0ZVtpKzJdKTsKICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIG9mZnNldDsKfQoKCnUxNl90IHpmTW1BZGRQcmVOSFRDYXBhYmlsaXR5KHpkZXZfdCogZGV2LCB6YnVmX3QqIGJ1ZiwgdTE2X3Qgb2Zmc2V0KQp7CiAgICAvL3U4X3QgT1VJWzNdID0gezB4MCwweDkwLDB4NEN9OwogICAgdTE2X3QgaTsKCiAgICB6bXdfZ2V0X3dsYW5fZGV2KGRldik7CgogICAgLyogUHJvYiBJRCAqLwogICAgem13X2J1Zl93cml0ZWIoZGV2LCBidWYsIG9mZnNldCsrLCBaTV9XTEFOX1BSRU4yX0VJRF9IVENBUEFCSUxJVFkpOwoKICAgIGlmICggd2QtPndsYW5Nb2RlID09IFpNX01PREVfQVAgKQogICAgewogICAgICAgIC8qIEVsZW1lbnQgTGVuZ3RoICovCiAgICAgICAgem13X2J1Zl93cml0ZWIoZGV2LCBidWYsIG9mZnNldCsrLCB3ZC0+YXAuSFRDYXAuRGF0YS5MZW5ndGgpOwoKICAgICAgICAvKiBIVCBDYXBhYmlsaXR5IERhdGEgKi8KICAgICAgICBmb3IgKGkgPSAwOyBpIDwgMjY7IGkrKykKICAgICAgICB7CiAgICAgICAgICAgIHptd19idWZfd3JpdGViKGRldiwgYnVmLCBvZmZzZXQrKywgd2QtPmFwLkhUQ2FwLkJ5dGVbaSsyXSk7CiAgICAgICAgfQogICAgfQogICAgZWxzZQogICAgewogICAgICAgIC8qIEVsZW1lbnQgTGVuZ3RoICovCiAgICAgICAgem13X2J1Zl93cml0ZWIoZGV2LCBidWYsIG9mZnNldCsrLCB3ZC0+c3RhLkhUQ2FwLkRhdGEuTGVuZ3RoKTsKCiAgICAgICAgLyogSFQgQ2FwYWJpbGl0eSBEYXRhICovCiAgICAgICAgZm9yIChpID0gMDsgaSA8IDI2OyBpKyspCiAgICAgICAgewogICAgICAgICAgICB6bXdfYnVmX3dyaXRlYihkZXYsIGJ1Ziwgb2Zmc2V0KyssIHdkLT5zdGEuSFRDYXAuQnl0ZVtpKzJdKTsKICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIG9mZnNldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgRlVOQ1RJT04gREVTQ1JJUFRJT04gICAgICAgICAgICAgICAgemZNbUFkZEV4dGVuZGVkSFRDYXBhYmlsaXR5ICAgKi8KLyogICAgICBBZGQgRXh0ZW5kZWQgSFQgQ2FwYWJpbGl0eSBJbmZvbWF0aW9uIHRvIGJ1ZmZlci4gICAgICAgICAgICAgICAgKi8KLyogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgSU5QVVRTICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgICBkZXYgOiBkZXZpY2UgcG9pbnRlciAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgICBidWYgOiBidWZmZXIgdG8gYWRkIGluZm9ybWF0aW9uIGVsZW1lbnQgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgICBvZmZzZXQgOiBhZGQgaW5mb3JtYXRpb24gZWxlbWVudCBmcm9tIHRoaXMgb2Zmc2V0ICAgICAgICAgICAgICAgKi8KLyogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgT1VUUFVUUyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgICBidWZmZXIgb2Zmc2V0IGFmdGVyIGFkZGluZyBpbmZvcm1hdGlvbiBlbGVtZW50ICAgICAgICAgICAgICAgICAgKi8KLyogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgQVVUSE9SICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgICBDaGFvLVdlbiBZYW5nICAgICBaeURBUyBUZWNobm9sb2d5IENvcnBvcmF0aW9uICAgICAgIDIwMDYuMDYgICAgKi8KLyogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KdTE2X3QgemZNbUFkZEV4dGVuZGVkSFRDYXBhYmlsaXR5KHpkZXZfdCogZGV2LCB6YnVmX3QqIGJ1ZiwgdTE2X3Qgb2Zmc2V0KQp7CiAgICB1OF90IE9VSVszXSA9IHsweDAsMHg5MCwweDRDfTsKICAgIHUxNl90IGk7CgogICAgem13X2dldF93bGFuX2RldihkZXYpOwoKICAgIC8qIFByb2IgSUQgKi8KICAgIHptd19idWZfd3JpdGViKGRldiwgYnVmLCBvZmZzZXQrKywgWk1fV0xBTl9FSURfV1BBX0lFKTsKCiAgICBpZiAoIHdkLT53bGFuTW9kZSA9PSBaTV9NT0RFX0FQICkKICAgIHsKICAgICAgICAvKiBFbGVtZW50IExlbmd0aCAqLwogICAgICAgIHptd19idWZfd3JpdGViKGRldiwgYnVmLCBvZmZzZXQrKywgd2QtPmFwLkV4dEhUQ2FwLkRhdGEuTGVuZ3RoICsgNCk7CgogICAgICAgIC8qIE9VSSBEYXRhICovCiAgICAgICAgZm9yIChpID0gMDsgaSA8IDM7IGkrKykKICAgICAgICB7CiAgICAgICAgICAgIHptd19idWZfd3JpdGViKGRldiwgYnVmLCBvZmZzZXQrKywgT1VJW2ldKTsKICAgICAgICB9CgogICAgICAgIC8qIEVsZW1lbnQgVHlwZSBJRCAqLwogICAgICAgIHptd19idWZfd3JpdGViKGRldiwgYnVmLCBvZmZzZXQrKywgd2QtPmFwLkV4dEhUQ2FwLkRhdGEuRWxlbWVudElEKTsKCiAgICAgICAgLyogSFQgQ2FwYWJpbGl0eSBEYXRhICovCiAgICAgICAgZm9yIChpID0gMDsgaSA8IDIyOyBpKyspCiAgICAgICAgewogICAgICAgICAgICB6bXdfYnVmX3dyaXRlYihkZXYsIGJ1Ziwgb2Zmc2V0KyssIHdkLT5hcC5FeHRIVENhcC5CeXRlW2krMl0pOwogICAgICAgIH0KICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICAvKiBFbGVtZW50IExlbmd0aCAqLwogICAgICAgIHptd19idWZfd3JpdGViKGRldiwgYnVmLCBvZmZzZXQrKywgd2QtPnN0YS5FeHRIVENhcC5EYXRhLkxlbmd0aCArIDQpOwoKICAgICAgICAvKiBPVUkgRGF0YSAqLwogICAgICAgIGZvciAoaSA9IDA7IGkgPCAzOyBpKyspCiAgICAgICAgewogICAgICAgICAgICB6bXdfYnVmX3dyaXRlYihkZXYsIGJ1Ziwgb2Zmc2V0KyssIE9VSVtpXSk7CiAgICAgICAgfQoKICAgICAgICAvKiBFbGVtZW50IFR5cGUgSUQgKi8KICAgICAgICB6bXdfYnVmX3dyaXRlYihkZXYsIGJ1Ziwgb2Zmc2V0KyssIHdkLT5zdGEuRXh0SFRDYXAuRGF0YS5FbGVtZW50SUQpOwoKICAgICAgICAvKiBIVCBDYXBhYmlsaXR5IERhdGEgKi8KICAgICAgICBmb3IgKGkgPSAwOyBpIDwgMjI7IGkrKykKICAgICAgICB7CiAgICAgICAgICAgIHptd19idWZfd3JpdGViKGRldiwgYnVmLCBvZmZzZXQrKywgd2QtPnN0YS5FeHRIVENhcC5CeXRlW2krMl0pOwogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gb2Zmc2V0Owp9CgoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgIEZVTkNUSU9OIERFU0NSSVBUSU9OICAgICAgICAgICAgICAgICAgemZTZW5kTW1GcmFtZSAgICAgICAgICAgICAgICovCi8qICAgICAgU2VuZCBtYW5hZ2VtZW50IGZyYW1lLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgIElOUFVUUyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgZGV2IDogZGV2aWNlIHBvaW50ZXIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgZnJhbWVUeXBlIDogbWFuYWdlbWVudCBmcmFtZSB0eXBlICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgZHN0IDogZGVzdGluYXRpb24gTUFDIGFkZHJlc3MgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgcDEgOiBwYXJhbWV0ZXIgMSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgcDIgOiBwYXJhbWV0ZXIgMiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgcDMgOiBwYXJhbWV0ZXIgMyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgIE9VVFBVVFMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgbm9uZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgIEFVVEhPUiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgU3RlcGhlbiBDaGVuICAgICAgICBaeURBUyBUZWNobm9sb2d5IENvcnBvcmF0aW9uICAgIDIwMDUuMTAgICAgICovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qIHByb2JlIHJlcSA6IHAxPT4gYldpdGhTU0lELCBwMj0+UiwgcDM9PlIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qIHByb2JlIHJzcCA6IHAxPT5SLCBwMj0+UiwgcDM9PlZBUCBJRChBUCkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qIGRlYXV0aCA6IHAxPT5SZWFzb24gQ29kZSwgcDI9PlIsIHAzPT5WQVAgSUQoQVApICAgICAgICAgICAgICAgICAgICAgICovCi8qIERpc2Fzb2MgOiBwMT0+UmVhc29uIENvZGUsIHAyPT5SLCBwMz0+VkFQIElEKEFQKSAgICAgICAgICAgICAgICAgICAgICovCi8qIEFUSU0gOiBwMT0+UiwgcDI9PlIsIHAzPT5SICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qIChyZSlhc29jIHJzcCA6IHAxPT5TdGF0dXMgQ29kZSwgcDI9PkFJRCwgcDM9PlZBUCBJRChBUCkgICAgICAgICAgICAgICovCi8qIGFzb2MgcmVxIDogcDE9PlIsIHAyPT5SLCBwMz0+UiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qIHJlYXNvYyByZXEgOiBwMT0+QVAgTUFDWzBdLCBwMj0+QVAgTUFDWzFdLCBwMz0+QVAgTUFDWzJdICAgICAgICAgICAgICovCi8qIGF1dGggOiBwMT0+bG93PUFsZ29yaXRobSwgaGlnaD1UcmFuc2FjdGlvbiwgcDI9PlN0YXR1cywgcDM9PlZBUCBJRCAgICovCnZvaWQgemZTZW5kTW1GcmFtZSh6ZGV2X3QqIGRldiwgdThfdCBmcmFtZVR5cGUsIHUxNl90KiBkc3QsCiAgICAgICAgICAgICAgICAgICB1MzJfdCBwMSwgdTMyX3QgcDIsIHUzMl90IHAzKQp7CiAgICB6YnVmX3QqIGJ1ZjsKICAgIC8vdTE2X3QgYWRkclRibFNpemU7CiAgICAvL3N0cnVjdCB6c0FkZHJUYmwgYWRkclRibDsKICAgIHUxNl90IG9mZnNldCA9IDA7CiAgICB1MTZfdCBobGVuID0gMzI7CiAgICB1MTZfdCBoZWFkZXJbKDI0KzI1KzEpLzJdOwogICAgdTE2X3QgdmFwID0gMDsKICAgIHUxNl90IGk7CiAgICB1OF90IGVuY3J5cHQgPSAwOwogICAgdTE2X3QgYWlkOwoKICAgIHptd19nZXRfd2xhbl9kZXYoZGV2KTsKICAgIHptd19kZWNsYXJlX2Zvcl9jcml0aWNhbF9zZWN0aW9uKCk7CgogICAgem1fbXNnMl9tbShaTV9MVl8yLCAiU2VuZCBtbSBmcmFtZSwgdHlwZT0iLCBmcmFtZVR5cGUpOwogICAgLyogVEJEIDogTWF4aW11bSBzaXplIG9mIG1hbmFnbWVudCBmcmFtZSAqLwogICAgaWYgKChidWYgPSB6ZndCdWZBbGxvY2F0ZShkZXYsIDEwMjQpKSA9PSBOVUxMKQogICAgewogICAgICAgIHptX21zZzBfbW0oWk1fTFZfMCwgIkFsbG9jIG1tIGJ1ZiBGYWlsISIpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAvL1Jlc2VydmUgcm9vbSBmb3Igd2xhbiBoZWFkZXIKICAgIG9mZnNldCA9IGhsZW47CgogICAgc3dpdGNoIChmcmFtZVR5cGUpCiAgICB7CiAgICAgICAgY2FzZSBaTV9XTEFOX0ZSQU1FX1RZUEVfUFJPQkVSRVEgOgogICAgICAgICAgICBvZmZzZXQgPSB6ZlNlbmRQcm9iZVJlcShkZXYsIGJ1Ziwgb2Zmc2V0LCAodThfdCkgcDEpOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBaTV9XTEFOX0ZSQU1FX1RZUEVfUFJPQkVSU1AgOgogICAgICAgICAgICB6bV9tc2cwX21tKFpNX0xWXzMsICJwcm9iZSByc3AiKTsKICAgICAgICAgICAgLyogMjQtMzEgVGltZSBTdGFtcCA6IGhhcmR3YXJlIFdPTidUIGZpbGwgdGhpcyBmaWVsZCAqLwogICAgICAgICAgICB6bXdfdHhfYnVmX3dyaXRlaChkZXYsIGJ1Ziwgb2Zmc2V0LCAwKTsKICAgICAgICAgICAgem13X3R4X2J1Zl93cml0ZWgoZGV2LCBidWYsIG9mZnNldCsyLCAwKTsKICAgICAgICAgICAgem13X3R4X2J1Zl93cml0ZWgoZGV2LCBidWYsIG9mZnNldCs0LCAwKTsKICAgICAgICAgICAgem13X3R4X2J1Zl93cml0ZWgoZGV2LCBidWYsIG9mZnNldCs2LCAwKTsKICAgICAgICAgICAgb2Zmc2V0Kz04OwoKICAgICAgICAgICAgLyogQmVhY29uIEludGVydmFsICovCiAgICAgICAgICAgIHptd190eF9idWZfd3JpdGVoKGRldiwgYnVmLCBvZmZzZXQsIHdkLT5iZWFjb25JbnRlcnZhbCk7CiAgICAgICAgICAgIG9mZnNldCs9MjsKCiAgICAgICAgICAgIGlmICh3ZC0+d2xhbk1vZGUgPT0gWk1fTU9ERV9BUCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdmFwID0gKHUxNl90KSBwMzsKICAgICAgICAgICAgICAgIC8qIENhcGFiaWxpdHkgKi8KICAgICAgICAgICAgICAgIHptd190eF9idWZfd3JpdGVoKGRldiwgYnVmLCBvZmZzZXQsIHdkLT5hcC5jYXBhYlt2YXBdKTsKICAgICAgICAgICAgICAgIG9mZnNldCs9MjsKICAgICAgICAgICAgICAgIC8qIFNTSUQgKi8KICAgICAgICAgICAgICAgIG9mZnNldCA9IHpmQXBBZGRJZVNzaWQoZGV2LCBidWYsIG9mZnNldCwgdmFwKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8qIENhcGFiaWxpdHkgKi8KICAgICAgICAgICAgICAgIHptd190eF9idWZfd3JpdGViKGRldiwgYnVmLCBvZmZzZXQrKywgd2QtPnN0YS5jYXBhYmlsaXR5WzBdKTsKICAgICAgICAgICAgICAgIHptd190eF9idWZfd3JpdGViKGRldiwgYnVmLCBvZmZzZXQrKywgd2QtPnN0YS5jYXBhYmlsaXR5WzFdKTsKICAgICAgICAgICAgICAgIC8qIFNTSUQgKi8KICAgICAgICAgICAgICAgIG9mZnNldCA9IHpmU3RhQWRkSWVTc2lkKGRldiwgYnVmLCBvZmZzZXQpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKiBTdXBwb3J0IFJhdGUgKi8KICAgICAgICAgICAgaWYgKCB3ZC0+ZnJlcXVlbmN5IDwgMzAwMCApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgb2Zmc2V0ID0gemZNbUFkZEllU3VwcG9ydFJhdGUoZGV2LCBidWYsIG9mZnNldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWk1fV0xBTl9FSURfU1VQUE9SVF9SQVRFLCBaTV9SQVRFX1NFVF9DQ0spOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgb2Zmc2V0ID0gemZNbUFkZEllU3VwcG9ydFJhdGUoZGV2LCBidWYsIG9mZnNldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWk1fV0xBTl9FSURfU1VQUE9SVF9SQVRFLCBaTV9SQVRFX1NFVF9PRkRNKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyogRFMgcGFyYW1ldGVyIHNldCAqLwogICAgICAgICAgICBvZmZzZXQgPSB6Zk1tQWRkSWVEcyhkZXYsIGJ1Ziwgb2Zmc2V0KTsKCiAgICAgICAgICAgIC8qIFRPRE8goUcgSUJTUyAqLwogICAgICAgICAgICBpZiAoIHdkLT53bGFuTW9kZSA9PSBaTV9NT0RFX0lCU1MgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBvZmZzZXQgPSB6ZlN0YUFkZEllSWJzcyhkZXYsIGJ1Ziwgb2Zmc2V0KTsKCiAgICAgICAgICAgICAgICBpZiAod2QtPmZyZXF1ZW5jeSA8IDMwMDApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYoIHdkLT53ZmMuYklic3NHTW9kZQogICAgICAgICAgICAgICAgICAgICAgICAmJiAod2QtPnN1cHBvcnRNb2RlICYgKFpNX1dJUkVMRVNTX01PREVfMjRfNTR8Wk1fV0lSRUxFU1NfTU9ERV8yNF9OKSkgKSAgICAvLyBPbmx5IGFjY29tcGFueSB3aXRoIGVuYWJsaW5nIGEgbW9kZSAuCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAvKiBFUlAgSW5mb3JtYXRpb24gKi8KICAgICAgICAgICAgICAgICAgICAgICAgd2QtPmVycEVsZW1lbnQgPSAwOwogICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQgPSB6Zk1tQWRkSWVFcnAoZGV2LCBidWYsIG9mZnNldCk7CgogICAgICAgICAgICAgICAgICAgICAgICAvKiBFbmFibGUgRyBNb2RlICovCiAgICAgICAgICAgICAgICAgICAgICAgIC8qIEV4dGVuZGVkIFN1cHBvcnRlZCBSYXRlcyAqLwogICAgICAgICAgICAgICAgICAgCSAgICBvZmZzZXQgPSB6Zk1tQWRkSWVTdXBwb3J0UmF0ZShkZXYsIGJ1Ziwgb2Zmc2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFpNX1dMQU5fRUlEX0VYVEVOREVEX1JBVEUsIFpNX1JBVEVfU0VUX09GRE0pOwogICAgICAgICAgICAJICAgIH0KICAgICAgICAJICAgIH0KICAgICAgICAgICAgfQoKCiAgICAgICAgICAgIGlmICgod2QtPndsYW5Nb2RlID09IFpNX01PREVfQVApCiAgICAgICAgICAgICAgICAgJiYgKHdkLT5hcC53bGFuVHlwZVt2YXBdICE9IFpNX1dMQU5fVFlQRV9QVVJFX0IpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvKiBFUlAgSW5mb3JtYXRpb24gKi8KICAgICAgICAgICAgICAgIG9mZnNldCA9IHpmTW1BZGRJZUVycChkZXYsIGJ1Ziwgb2Zmc2V0KTsKCiAgICAgICAgICAgICAgICAvKiBFeHRlbmRlZCBTdXBwb3J0ZWQgUmF0ZXMgKi8KCQlpZiAoIHdkLT5mcmVxdWVuY3kgPCAzMDAwICkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIG9mZnNldCA9IHpmTW1BZGRJZVN1cHBvcnRSYXRlKGRldiwgYnVmLCBvZmZzZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWk1fV0xBTl9FSURfRVhURU5ERURfUkFURSwgWk1fUkFURV9TRVRfT0ZETSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyogRVJQIEluZm9ybWF0aW9uICovCiAgICAgICAgICAgIC8vb2Zmc2V0ID0gemZNbUFkZEllRXJwKGRldiwgYnVmLCBvZmZzZXQpOwoKICAgICAgICAgICAgLyogRXh0ZW5kZWQgU3VwcG9ydGVkIFJhdGVzICovCiAgICAgICAgICAgIC8vb2Zmc2V0ID0gemZNbUFkZEllU3VwcG9ydFJhdGUoZGV2LCBidWYsIG9mZnNldCwKICAgICAgICAgICAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBaTV9XTEFOX0VJRF9FWFRFTkRFRF9SQVRFLCBaTV9SQVRFX1NFVF9PRkRNKTsKCiAgICAgICAgICAgIC8qIFRPRE8gOiBSU04gKi8KICAgICAgICAgICAgaWYgKHdkLT53bGFuTW9kZSA9PSBaTV9NT0RFX0FQICYmIHdkLT5hcC53cGFTdXBwb3J0W3ZhcF0gPT0gMSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgb2Zmc2V0ID0gemZNbUFkZEllV3BhKGRldiwgYnVmLCBvZmZzZXQsIHZhcCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAoIHdkLT53bGFuTW9kZSA9PSBaTV9NT0RFX0lCU1MgJiYgd2QtPnN0YS5hdXRoTW9kZSA9PSBaTV9BVVRIX01PREVfV1BBMlBTSykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgb2Zmc2V0ID0gemZ3U3RhQWRkSWVXcGFSc24oZGV2LCBidWYsIG9mZnNldCwgWk1fV0xBTl9GUkFNRV9UWVBFX0FVVEgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKiBXTUUgUGFyYW1ldGVycyAqLwogICAgICAgICAgICBpZiAod2QtPndsYW5Nb2RlID09IFpNX01PREVfQVApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh3ZC0+YXAucW9zTW9kZSA9PSAxKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIG9mZnNldCA9IHpmQXBBZGRJZVdtZVBhcmEoZGV2LCBidWYsIG9mZnNldCwgdmFwKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCB3ZC0+d2xhbk1vZGUgIT0gWk1fTU9ERV9JQlNTICkKICAgICAgICAgICAgewogICAgICAgICAgICAvLyBqaGxlZSBIVCAwCiAgICAgICAgICAgIC8vQ1dZYW5nKCspCiAgICAgICAgICAgICAgICAvKiBUT0RPIDogTmVlZCB0byBjaGVjayBpZiBpdCBpcyBvayAqLwogICAgICAgICAgICAvKiBIVCBDYXBhYmlsaXRpZXMgSW5mbyAqLwogICAgICAgICAgICBvZmZzZXQgPSB6Zk1tQWRkSFRDYXBhYmlsaXR5KGRldiwgYnVmLCBvZmZzZXQpOwogICAgICAgICAgICAvL0NXWWFuZygrKQogICAgICAgICAgICAvKiBFeHRlbmRlZCBIVCBDYXBhYmlsaXRpZXMgSW5mbyAqLwogICAgICAgICAgICBvZmZzZXQgPSB6Zk1tQWRkRXh0ZW5kZWRIVENhcGFiaWxpdHkoZGV2LCBidWYsIG9mZnNldCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICggd2QtPnN0YS5pYnNzQWRkaXRpb25hbElFU2l6ZSApCiAgICAgICAgICAgICAgICBvZmZzZXQgPSB6ZlN0YUFkZElic3NBZGRpdGlvbmFsSUUoZGV2LCBidWYsIG9mZnNldCk7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIFpNX1dMQU5fRlJBTUVfVFlQRV9BVVRIIDoKICAgICAgICAgICAgaWYgKHAxID09IDB4MzAwMDEpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGhsZW4gKz0gNDsKICAgICAgICAgICAgICAgIG9mZnNldCArPSA0OyAgICAgICAgLy8gZm9yIHJlc2VydmluZyB3ZXAgaGVhZGVyCiAgICAgICAgICAgICAgICBlbmNyeXB0ID0gMTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyogQWxnb3RyaXRobSBOdW1iZXIgKi8KICAgICAgICAgICAgem13X3R4X2J1Zl93cml0ZWgoZGV2LCBidWYsIG9mZnNldCwgKHUxNl90KShwMSYweGZmZmYpKTsKICAgICAgICAgICAgb2Zmc2V0Kz0yOwoKICAgICAgICAgICAgLyogVHJhbnNhY3Rpb24gTnVtYmVyICovCiAgICAgICAgICAgIHptd190eF9idWZfd3JpdGVoKGRldiwgYnVmLCBvZmZzZXQsICh1MTZfdCkocDE+PjE2KSk7CiAgICAgICAgICAgIG9mZnNldCs9MjsKCiAgICAgICAgICAgIC8qIFN0YXR1cyBDb2RlICovCiAgICAgICAgICAgIHptd190eF9idWZfd3JpdGVoKGRldiwgYnVmLCBvZmZzZXQsICh1MTZfdClwMik7CiAgICAgICAgICAgIG9mZnNldCs9MjsKCiAgICAgICAgICAgIGlmICh3ZC0+d2xhbk1vZGUgPT0gWk1fTU9ERV9BUCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdmFwID0gKHUxNl90KSBwMzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyogQ2hhbGxlbmdlIFRleHQgPT4gc2hhcmUtMiBvciBzaGFyZS0zICovCiAgICAgICAgICAgIGlmIChwMSA9PSAweDIwMDAxKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAocDIgPT0gMCkgLy9TdGF0dXMgPT0gc3VjY2VzcwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHptd19idWZfd3JpdGVoKGRldiwgYnVmLCBvZmZzZXQsIDB4ODAxMCk7CiAgICAgICAgICAgICAgICAgICAgb2Zmc2V0Kz0yOwogICAgICAgICAgICAgICAgICAgIC8qIHNoYXJlLTIgOiBBUCBnZW5lcmF0ZSBjaGFsbGVuZ2UgdGV4dCAqLwogICAgICAgICAgICAgICAgICAgIGZvciAoaT0wOyBpPDEyODsgaSsrKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgd2QtPmFwLmNoYWxsZW5nZVRleHRbaV0gPSAodThfdCl6ZkdldFJhbmRvbU51bWJlcihkZXYsIDApOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB6ZkNvcHlUb0ludFR4QnVmZmVyKGRldiwgYnVmLCB3ZC0+YXAuY2hhbGxlbmdlVGV4dCwgb2Zmc2V0LCAxMjgpOwogICAgICAgICAgICAgICAgICAgIG9mZnNldCArPSAxMjg7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAocDEgPT0gMHgzMDAwMSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLyogc2hhcmUtMyA6IFNUQSByZXR1cm4gY2hhbGxlbmdlIFRleHQgKi8KICAgICAgICAgICAgICAgIHpmQ29weVRvSW50VHhCdWZmZXIoZGV2LCBidWYsIHdkLT5zdGEuY2hhbGxlbmdlVGV4dCwgb2Zmc2V0LCB3ZC0+c3RhLmNoYWxsZW5nZVRleHRbMV0rMik7CiAgICAgICAgICAgICAgICBvZmZzZXQgKz0gKHdkLT5zdGEuY2hhbGxlbmdlVGV4dFsxXSsyKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgWk1fV0xBTl9GUkFNRV9UWVBFX0FTT0NSRVEgOgogICAgICAgIGNhc2UgWk1fV0xBTl9GUkFNRV9UWVBFX1JFQVNPQ1JFUSA6CiAgICAgICAgICAgIC8qIENhcGFiaWxpdHkgKi8KICAgICAgICAgICAgem13X3R4X2J1Zl93cml0ZWIoZGV2LCBidWYsIG9mZnNldCsrLCB3ZC0+c3RhLmNhcGFiaWxpdHlbMF0pOwogICAgICAgICAgICB6bXdfdHhfYnVmX3dyaXRlYihkZXYsIGJ1Ziwgb2Zmc2V0KyssIHdkLT5zdGEuY2FwYWJpbGl0eVsxXSk7CgogICAgICAgICAgICAvKiBMaXN0ZW4gSW50ZXJ2YWwgKi8KICAgICAgICAgICAgem13X3R4X2J1Zl93cml0ZWgoZGV2LCBidWYsIG9mZnNldCwgMHgwMDA1KTsKICAgICAgICAgICAgb2Zmc2V0Kz0yOwoKICAgICAgICAgICAgLyogUmVhc3NvY2FpdGVkIFJlcXVlc3QgOiBDdXJyZW50IEFQIGFkZHJlc3MgKi8KICAgICAgICAgICAgaWYgKGZyYW1lVHlwZSA9PSBaTV9XTEFOX0ZSQU1FX1RZUEVfUkVBU09DUkVRKQogICAgICAgICAgICB7CiAgICAgICAgICAgIHptd190eF9idWZfd3JpdGVoKGRldiwgYnVmLCBvZmZzZXQsIHdkLT5zdGEuYnNzaWRbMF0pOwogICAgICAgICAgICAgICAgb2Zmc2V0Kz0yOwogICAgICAgICAgICB6bXdfdHhfYnVmX3dyaXRlaChkZXYsIGJ1Ziwgb2Zmc2V0LCB3ZC0+c3RhLmJzc2lkWzFdKTsKICAgICAgICAgICAgICAgIG9mZnNldCs9MjsKICAgICAgICAgICAgem13X3R4X2J1Zl93cml0ZWgoZGV2LCBidWYsIG9mZnNldCwgd2QtPnN0YS5ic3NpZFsyXSk7CiAgICAgICAgICAgICAgICBvZmZzZXQrPTI7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qIFNTSUQgKi8KICAgICAgICAgICAgb2Zmc2V0ID0gemZTdGFBZGRJZVNzaWQoZGV2LCBidWYsIG9mZnNldCk7CgoKICAgICAgICAgICAgaWYgKCB3ZC0+c3RhLmN1cnJlbnRGcmVxdWVuY3kgPCAzMDAwICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLyogU3VwcG9ydCBSYXRlICovCiAgICAgICAgICAgICAgICBvZmZzZXQgPSB6Zk1tQWRkSWVTdXBwb3J0UmF0ZShkZXYsIGJ1Ziwgb2Zmc2V0LCBaTV9XTEFOX0VJRF9TVVBQT1JUX1JBVEUsIFpNX1JBVEVfU0VUX0NDSyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvKiBTdXBwb3J0IFJhdGUgKi8KICAgICAgICAgICAgICAgIG9mZnNldCA9IHpmTW1BZGRJZVN1cHBvcnRSYXRlKGRldiwgYnVmLCBvZmZzZXQsIFpNX1dMQU5fRUlEX1NVUFBPUlRfUkFURSwgWk1fUkFURV9TRVRfT0ZETSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgod2QtPnN0YS5jYXBhYmlsaXR5WzFdICYgWk1fQklUXzApID09IDEpCiAgICAgICAgICAgIHsgICAvL3NwZWN0cnVtIG1hbmFnbWVudCBmbGFnIGVuYWJsZQogICAgICAgICAgICAgICAgb2Zmc2V0ID0gemZTdGFBZGRJZVBvd2VyQ2FwKGRldiwgYnVmLCBvZmZzZXQpOwogICAgICAgICAgICAgICAgb2Zmc2V0ID0gemZTdGFBZGRJZVN1cHBvcnRDaChkZXYsIGJ1Ziwgb2Zmc2V0KTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKHdkLT5zdGEuY3VycmVudEZyZXF1ZW5jeSA8IDMwMDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8qIEV4dGVuZGVkIFN1cHBvcnRlZCBSYXRlcyAqLwogICAgICAgICAgICAgICAgaWYgKHdkLT5zdXBwb3J0TW9kZSAmIChaTV9XSVJFTEVTU19NT0RFXzI0XzU0fFpNX1dJUkVMRVNTX01PREVfMjRfTikpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgb2Zmc2V0ID0gemZNbUFkZEllU3VwcG9ydFJhdGUoZGV2LCBidWYsIG9mZnNldCwgWk1fV0xBTl9FSURfRVhURU5ERURfUkFURSwgWk1fUkFURV9TRVRfT0ZETSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCgogICAgICAgICAgICAvL29mZnNldCA9IHpmU3RhQWRkSWVXcGFSc24oZGV2LCBidWYsIG9mZnNldCwgZnJhbWVUeXBlKTsKICAgICAgICAgICAgLy9Nb3ZlIHRvIHdyYXBwZXIgZnVuY3Rpb24sIGZvciBPUyBkaWZmZXJlbmNlLS1DV1lhbmcobSkKICAgICAgICAgICAgLy9mb3Igd2luZG93cyB3cmFwcGVyLCB6ZndTdGFBZGRJZVdwYVJzbigpIHNob3VsZCBiZSBiZWxvdzoKICAgICAgICAgICAgLy91MTZfdCB6ZndTdGFBZGRJZVdwYVJzbih6ZGV2X3QqIGRldiwgemJ1Zl90KiBidWYsIHUxNl90IG9mZnNldCwgdThfdCBmcmFtZVR5cGUpCiAgICAgICAgICAgIC8vewogICAgICAgICAgICAvLyAgICByZXR1cm4gemZTdGFBZGRJZVdwYVJzbihkZXYsIGJ1Ziwgb2Zmc2V0LCBmcmFtZVR5cGUpOwogICAgICAgICAgICAvL30KICAgICAgICAgICAgb2Zmc2V0ID0gemZ3U3RhQWRkSWVXcGFSc24oZGV2LCBidWYsIG9mZnNldCwgZnJhbWVUeXBlKTsKCiNpZmRlZiBaTV9FTkFCTEVfQ0VOQwogICAgICAgICAgICAvKiBDRU5DICovCiAgICAgICAgICAgIC8vaWYgKHdkLT5zdGEuZW5jcnlNb2RlID09IFpNX0NFTkMpCiAgICAgICAgICAgIG9mZnNldCA9IHpmU3RhQWRkSWVDZW5jKGRldiwgYnVmLCBvZmZzZXQpOwojZW5kaWYgLy9aTV9FTkFCTEVfQ0VOQwogICAgICAgICAgICBpZiAoKCh3ZC0+c3RhLndtZUVuYWJsZWQgJiBaTV9TVEFfV01FX0VOQUJMRV9CSVQpICE9IDApIC8vV01FIGVuYWJsZWQKICAgICAgICAgICAgICAmJiAoKHdkLT5zdGEuYXBXbWVDYXBhYmlsaXR5ICYgMHgxKSAhPSAwKSkgLy9XTUUgQVAKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKCgod2QtPnN0YS5hcFdtZUNhcGFiaWxpdHkgJiAweDgwKSAhPSAwKSAvL1VBUFNEIEFQCiAgICAgICAgICAgICAgICAgJiYgKCh3ZC0+c3RhLndtZUVuYWJsZWQgJiBaTV9TVEFfVUFQU0RfRU5BQkxFX0JJVCkgIT0gMCkpIC8vVUFQU0QgZW5hYmxlZAogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIG9mZnNldCA9IHpmU3RhQWRkSWVXbWVJbmZvKGRldiwgYnVmLCBvZmZzZXQsIHdkLT5zdGEud21lUW9zSW5mbyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgb2Zmc2V0ID0gemZTdGFBZGRJZVdtZUluZm8oZGV2LCBidWYsIG9mZnNldCwgMCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gamhsZWUgSFQgMAogICAgICAgICAgICAvL0NXWWFuZygrKQogICAgICAgICAgICBpZiAod2QtPnN0YS5FbmFibGVIVCAhPSAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAjaWZuZGVmIFpNX0RJU0FCTEVfQU1TRFU4S19TVVBQT1JUCiAgICAgICAgICAgICAgICAgICAgLy9TdXBwb3J0IDhLIEEtTVNEVQogICAgICAgICAgICAgICAgICAgIGlmICh3ZC0+c3RhLndlcFN0YXR1cyA9PSBaTV9FTkNSWVBUSU9OX1dFUF9ESVNBQkxFRCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHdkLT5zdGEuSFRDYXAuRGF0YS5IdENhcEluZm8gfD0gSFRDQVBfTWF4QU1TRFVMZW5ndGg7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHdkLT5zdGEuSFRDYXAuRGF0YS5IdENhcEluZm8gJj0gKH5IVENBUF9NYXhBTVNEVUxlbmd0aCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgI2Vsc2UKICAgICAgICAgICAgICAgICAgICAvL1N1cHBvcnQgNEsgQS1NU0RVCiAgICAgICAgICAgICAgICAgICAgd2QtPnN0YS5IVENhcC5EYXRhLkh0Q2FwSW5mbyAmPSAofkhUQ0FQX01heEFNU0RVTGVuZ3RoKTsKICAgICAgICAgICAgICAgICNlbmRpZgoKICAgICAgICAgICAgICAgIC8qIEhUIENhcGFiaWxpdGllcyBJbmZvICovCiAgICAgICAgICAgICAgICBpZiAod2QtPkJhbmRXaWR0aDQwID09IDEpIHsKICAgICAgICAgICAgICAgICAgICB3ZC0+c3RhLkhUQ2FwLkRhdGEuSHRDYXBJbmZvIHw9IEhUQ0FQX1N1cENoYW5uZWxXaWR0aFNldDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgIHdkLT5zdGEuSFRDYXAuRGF0YS5IdENhcEluZm8gJj0gfkhUQ0FQX1N1cENoYW5uZWxXaWR0aFNldDsKICAgICAgICAgICAgICAgICAgICAvL3dkLT5zdGEuSFRDYXAuRGF0YS5IdENhcEluZm8gfD0gSFRDQVBfU3VwQ2hhbm5lbFdpZHRoU2V0OwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHdkLT5zdGEuSFRDYXAuRGF0YS5BTVBEVVBhcmFtICY9IH5IVENBUF9NYXhSeEFNUERVMzsKICAgICAgICAgICAgICAgIHdkLT5zdGEuSFRDYXAuRGF0YS5BTVBEVVBhcmFtIHw9IEhUQ0FQX01heFJ4QU1QRFUzOwogICAgICAgICAgICAgICAgd2QtPnN0YS5IVENhcC5EYXRhLk1DU1NldFsxXSA9IDB4RkY7IC8vIE1DUyA4IH4gMTUKICAgICAgICAgICAgICAgIG9mZnNldCA9IHpmTW1BZGRIVENhcGFiaWxpdHkoZGV2LCBidWYsIG9mZnNldCk7CiAgICAgICAgICAgICAgICBvZmZzZXQgPSB6Zk1tQWRkUHJlTkhUQ2FwYWJpbGl0eShkZXYsIGJ1Ziwgb2Zmc2V0KTsKICAgICAgICAgICAgICAgIC8vQ1dZYW5nKCspCiAgICAgICAgICAgICAgICAvKiBFeHRlbmRlZCBIVCBDYXBhYmlsaXRpZXMgSW5mbyAqLwogICAgICAgICAgICAgICAgLy9vZmZzZXQgPSB6Zk1tQWRkRXh0ZW5kZWRIVENhcGFiaWxpdHkoZGV2LCBidWYsIG9mZnNldCk7CiAgICAgICAgICAgIH0KCgogICAgICAgICAgICAvL1N0b3JlIGFzb2MgcmVxdWVzdCBmcmFtZSBib2R5LCBmb3IgVklTVEEgb25seQogICAgICAgICAgICB3ZC0+c3RhLmFzb2NSZXFGcmFtZUJvZHlTaXplID0gKChvZmZzZXQgLSBobGVuKSA+CiAgICAgICAgICAgICAgICAgICAgWk1fQ0FDSEVEX0ZSQU1FQk9EWV9TSVpFKT8KICAgICAgICAgICAgICAgICAgICBaTV9DQUNIRURfRlJBTUVCT0RZX1NJWkU6KG9mZnNldCAtIGhsZW4pOwogICAgICAgICAgICBmb3IgKGk9MDsgaTx3ZC0+c3RhLmFzb2NSZXFGcmFtZUJvZHlTaXplOyBpKyspCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHdkLT5zdGEuYXNvY1JlcUZyYW1lQm9keVtpXSA9IHptd190eF9idWZfcmVhZGIoZGV2LCBidWYsIGkgKyBobGVuKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBaTV9XTEFOX0ZSQU1FX1RZUEVfQVNPQ1JTUCA6CiAgICAgICAgY2FzZSBaTV9XTEFOX0ZSQU1FX1RZUEVfUkVBU09DUlNQIDoKICAgICAgICAgICAgdmFwID0gKHUxNl90KSBwMzsKCiAgICAgICAgICAgIC8qIENhcGFiaWxpdHkgKi8KICAgICAgICAgICAgem13X3R4X2J1Zl93cml0ZWgoZGV2LCBidWYsIG9mZnNldCwgd2QtPmFwLmNhcGFiW3ZhcF0pOwogICAgICAgICAgICBvZmZzZXQrPTI7CgogICAgICAgICAgICAvKiBTdGF0dXMgQ29kZSAqLwogICAgICAgICAgICB6bXdfdHhfYnVmX3dyaXRlaChkZXYsIGJ1Ziwgb2Zmc2V0LCAodTE2X3QpcDEpOwogICAgICAgICAgICBvZmZzZXQrPTI7CgogICAgICAgICAgICAvKiBBSUQgKi8KICAgICAgICAgICAgem13X3R4X2J1Zl93cml0ZWgoZGV2LCBidWYsIG9mZnNldCwgKHUxNl90KShwMnwweGMwMDApKTsKICAgICAgICAgICAgb2Zmc2V0Kz0yOwoKCiAgICAgICAgICAgIGlmICggd2QtPmZyZXF1ZW5jeSA8IDMwMDAgKQogICAgICAgICAgICB7CiAgICAgICAgICAgIC8qIFN1cHBvcnQgUmF0ZSAqLwogICAgICAgICAgICBvZmZzZXQgPSB6Zk1tQWRkSWVTdXBwb3J0UmF0ZShkZXYsIGJ1Ziwgb2Zmc2V0LCBaTV9XTEFOX0VJRF9TVVBQT1JUX1JBVEUsIFpNX1JBVEVfU0VUX0NDSyk7CgogICAgICAgICAgICAvKiBFeHRlbmRlZCBTdXBwb3J0ZWQgUmF0ZXMgKi8KICAgICAgICAgICAgb2Zmc2V0ID0gemZNbUFkZEllU3VwcG9ydFJhdGUoZGV2LCBidWYsIG9mZnNldCwgWk1fV0xBTl9FSURfRVhURU5ERURfUkFURSwgWk1fUkFURV9TRVRfT0ZETSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvKiBTdXBwb3J0IFJhdGUgKi8KICAgICAgICAgICAgICAgIG9mZnNldCA9IHpmTW1BZGRJZVN1cHBvcnRSYXRlKGRldiwgYnVmLCBvZmZzZXQsIFpNX1dMQU5fRUlEX1NVUFBPUlRfUkFURSwgWk1fUkFURV9TRVRfT0ZETSk7CiAgICAgICAgICAgIH0KCgoKICAgICAgICAgICAgLyogV01FIFBhcmFtZXRlcnMgKi8KICAgICAgICAgICAgaWYgKHdkLT53bGFuTW9kZSA9PSBaTV9NT0RFX0FQKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvKiBUT0RPIDogaWYgV01FIFNUQSB0aGVuIHNlbmQgV01FIHBhcmFtZXRlciBlbGVtZW50ICovCiAgICAgICAgICAgICAgICBpZiAod2QtPmFwLnFvc01vZGUgPT0gMSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBvZmZzZXQgPSB6ZkFwQWRkSWVXbWVQYXJhKGRldiwgYnVmLCBvZmZzZXQsIHZhcCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gamhsZWUgSFQgMAogICAgICAgICAgICAvL0NXWWFuZygrKQogICAgICAgICAgICAvKiBIVCBDYXBhYmlsaXRpZXMgSW5mbyAqLwogICAgICAgICAgICBvZmZzZXQgPSB6Zk1tQWRkSFRDYXBhYmlsaXR5KGRldiwgYnVmLCBvZmZzZXQpOwogICAgICAgICAgICAvL0NXWWFuZygrKQogICAgICAgICAgICAvKiBFeHRlbmRlZCBIVCBDYXBhYmlsaXRpZXMgSW5mbyAqLwogICAgICAgICAgICBvZmZzZXQgPSB6Zk1tQWRkRXh0ZW5kZWRIVENhcGFiaWxpdHkoZGV2LCBidWYsIG9mZnNldCk7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIFpNX1dMQU5fRlJBTUVfVFlQRV9BVElNIDoKICAgICAgICAgICAgLyogTlVMTCBmcmFtZSAqLwogICAgICAgICAgICAvKiBUT0RPIDogYWRkIHR3byBkdW1iIGJ5dGVzIHRlbXBvcmFyaWx5ICovCiAgICAgICAgICAgIG9mZnNldCArPSAyOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBaTV9XTEFOX0ZSQU1FX1RZUEVfUU9TX05VTEwgOgogICAgICAgICAgICB6bXdfYnVmX3dyaXRlaChkZXYsIGJ1Ziwgb2Zmc2V0LCAweDAwMTApOwogICAgICAgICAgICBvZmZzZXQgKz0gMjsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgWk1fV0xBTl9EQVRBX0ZSQU1FIDoKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgWk1fV0xBTl9GUkFNRV9UWVBFX0RJU0FTT0MgOgogICAgICAgIGNhc2UgWk1fV0xBTl9GUkFNRV9UWVBFX0RFQVVUSCA6CiAgICAgICAgICAgIGlmICh3ZC0+d2xhbk1vZGUgPT0gWk1fTU9ERV9BUCkKICAgICAgICAgICAgewogICAgICAgICAgICAgIHZhcCA9ICh1MTZfdCkgcDM7CgogICAgICAgICAgICAgIGlmICgoYWlkID0gemZBcEZpbmRTdGEoZGV2LCBkc3QpKSAhPSAweGZmZmYpCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICB6bXdfZW50ZXJfY3JpdGljYWxfc2VjdGlvbihkZXYpOwogICAgICAgICAgICAgICAgICAvKiBDbGVhciBTVEEgdGFibGUgKi8KICAgICAgICAgICAgICAgICAgd2QtPmFwLnN0YVRhYmxlW2FpZF0udmFsaWQgPSAwOwoKICAgICAgICAgICAgICAgICAgem13X2xlYXZlX2NyaXRpY2FsX3NlY3Rpb24oZGV2KTsKCiAgICAgICAgICAgICAgICAgIGlmICh3ZC0+emZjYkRpc0Fzb2NOb3RpZnkgIT0gTlVMTCkKICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgd2QtPnpmY2JEaXNBc29jTm90aWZ5KGRldiwgKHU4X3QqKWRzdCwgdmFwKTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICAvKiBSZWFzb24gQ29kZSAqLwogICAgICAgICAgICB6bXdfdHhfYnVmX3dyaXRlaChkZXYsIGJ1Ziwgb2Zmc2V0LCAodTE2X3QpcDEpOwogICAgICAgICAgICBvZmZzZXQrPTI7CiAgICAgICAgICAgIGJyZWFrOwogICAgfQoKICAgIHpmd0J1ZlNldFNpemUoZGV2LCBidWYsIG9mZnNldCk7CgogICAgem1fbXNnMl9tbShaTV9MVl8yLCAibWFuYWdlbWVudCBmcmFtZSBib2R5IHNpemU9Iiwgb2Zmc2V0LWhsZW4pOwoKICAgIC8vQ29weSB3bGFuIGhlYWRlcgogICAgemZUeEdlbk1tSGVhZGVyKGRldiwgZnJhbWVUeXBlLCBkc3QsIGhlYWRlciwgb2Zmc2V0LWhsZW4sIGJ1ZiwgdmFwLCBlbmNyeXB0KTsKICAgIGZvciAoaT0wOyBpPChobGVuPj4xKTsgaSsrKQogICAgewogICAgICAgIHptd190eF9idWZfd3JpdGVoKGRldiwgYnVmLCBpKjIsIGhlYWRlcltpXSk7CiAgICB9CgogICAgLyogR2V0IGJ1ZmZlciBETUEgYWRkcmVzcyAqLwogICAgLy9pZiAoKGFkZHJUYmxTaXplID0gemZ3QnVmTWFwRG1hKGRldiwgYnVmLCAmYWRkclRibCkpID09IDApCiAgICAvL2lmICgoYWRkclRibFNpemUgPSB6ZndNYXBUeERtYShkZXYsIGJ1ZiwgJmFkZHJUYmwpKSA9PSAwKQogICAgLy97CiAgICAvLyAgICBnb3RvIHpsRXJyb3I7CiAgICAvL30KCiAgICB6bV9tc2cyX21tKFpNX0xWXzIsICJvZmZzZXQ9Iiwgb2Zmc2V0KTsKICAgIHptX21zZzJfbW0oWk1fTFZfMiwgImhsZW49IiwgaGxlbik7CiAgICAvL3ptX21zZzJfbW0oWk1fTFZfMiwgImFkZHJUYmxTaXplPSIsIGFkZHJUYmxTaXplKTsKICAgIC8vem1fbXNnMl9tbShaTV9MVl8yLCAiYWRkclRibC5sZW5bMF09IiwgYWRkclRibC5sZW5bMF0pOwogICAgLy96bV9tc2cyX21tKFpNX0xWXzIsICJhZGRyVGJsLnBoeXNBZGRybFswXT0iLCBhZGRyVGJsLnBoeXNBZGRybFswXSk7CiAgICAvL3ptX21zZzJfbW0oWk1fTFZfMiwgImJ1Zi0+ZGF0YT0iLCBidWYtPmRhdGEpOwoKICAgICNpZiAwCiAgICBpZiAoKGVyciA9IHpmSHBTZW5kKGRldiwgTlVMTCwgMCwgTlVMTCwgMCwgTlVMTCwgMCwgYnVmLCAwLAogICAgICAgICAgICBaTV9JTlRFUk5BTF9BTExPQ19CVUYsIDAsIDB4ZmYpKSAhPSBaTV9TVUNDRVNTKQogICAgewogICAgICAgIGdvdG8gemxFcnJvcjsKICAgIH0KICAgICNlbHNlCiAgICB6ZlB1dFZtbXEoZGV2LCBidWYpOwogICAgemZQdXNoVnR4cShkZXYpOwogICAgI2VuZGlmCgogICAgcmV0dXJuOwojaWYgMAp6bEVycm9yOgoKICAgIHpmd0J1ZkZyZWUoZGV2LCBidWYsIDApOwogICAgcmV0dXJuOwojZW5kaWYKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgIEZVTkNUSU9OIERFU0NSSVBUSU9OICAgICAgICAgICAgICAgICAgemZQcm9jZXNzTWFuYWdlbWVudCAgICAgICAgICovCi8qICAgICAgUHJvY2VzcyByZWNlaXZlZCBtYW5hZ2VtZW50IGZyYW1lLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgIElOUFVUUyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgZGV2IDogZGV2aWNlIHBvaW50ZXIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgYnVmIDogcmVjZWl2ZWQgbWFuYWdlbWVudCBmcmFtZSBidWZmZXIgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICBPVVRQVVRTICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIG5vbmUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICBBVVRIT1IgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIFN0ZXBoZW4gQ2hlbiAgICAgICAgWnlEQVMgVGVjaG5vbG9neSBDb3Jwb3JhdGlvbiAgICAyMDA1LjEwICAgICAqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwp2b2lkIHpmUHJvY2Vzc01hbmFnZW1lbnQoemRldl90KiBkZXYsIHpidWZfdCogYnVmLCBzdHJ1Y3QgenNBZGRpdGlvbkluZm8qIEFkZEluZm8pIC8vQ1dZYW5nKG0pCnsKICAgIHU4X3QgZnJhbWVUeXBlOwogICAgdTE2X3QgdGFbM107CiAgICB1MTZfdCByYVszXTsKICAgIHUxNl90IHZhcCA9IDAsIGluZGV4ID0gMDsKICAgIC8vdTE2X3QgaTsKCiAgICB6bXdfZ2V0X3dsYW5fZGV2KGRldik7CgogICAgcmFbMF0gPSB6bXdfcnhfYnVmX3JlYWRoKGRldiwgYnVmLCA0KTsKICAgIHJhWzFdID0gem13X3J4X2J1Zl9yZWFkaChkZXYsIGJ1ZiwgNik7CiAgICByYVsyXSA9IHptd19yeF9idWZfcmVhZGgoZGV2LCBidWYsIDgpOwoKICAgIHRhWzBdID0gem13X3J4X2J1Zl9yZWFkaChkZXYsIGJ1ZiwgMTApOwogICAgdGFbMV0gPSB6bXdfcnhfYnVmX3JlYWRoKGRldiwgYnVmLCAxMik7CiAgICB0YVsyXSA9IHptd19yeF9idWZfcmVhZGgoZGV2LCBidWYsIDE0KTsKCiAgICBmcmFtZVR5cGUgPSB6bXdfcnhfYnVmX3JlYWRiKGRldiwgYnVmLCAwKTsKCiAgICBpZiAod2QtPndsYW5Nb2RlID09IFpNX01PREVfQVApCiAgICB7CiNpZiAxCiAgICAgICAgdmFwID0gMDsKICAgICAgICBpZiAoKHJhWzBdICYgMHgxKSAhPSAxKQogICAgICAgIHsKICAgICAgICAgICAgLyogQVAgOiBGaW5kIHZpcnR1YWwgQVAgKi8KICAgICAgICAgICAgaWYgKChpbmRleCA9IHpmQXBGaW5kU3RhKGRldiwgdGEpKSAhPSAweGZmZmYpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHZhcCA9IHdkLT5hcC5zdGFUYWJsZVtpbmRleF0udmFwOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHptX21zZzJfbW0oWk1fTFZfMiwgInZhcD0iLCB2YXApOwojZW5kaWYKCiAgICAgICAgLyogRGlzcGF0Y2ggYnkgZnJhbWUgdHlwZSAqLwogICAgICAgIHN3aXRjaCAoZnJhbWVUeXBlKQogICAgICAgIHsKICAgICAgICAgICAgICAgIC8qIEJlYWNvbiAqLwogICAgICAgICAgICBjYXNlIFpNX1dMQU5fRlJBTUVfVFlQRV9CRUFDT04gOgogICAgICAgICAgICAgICAgemZBcFByb2Nlc3NCZWFjb24oZGV2LCBidWYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAvKiBBdXRoZW50aWNhdGlvbiAqLwogICAgICAgICAgICBjYXNlIFpNX1dMQU5fRlJBTUVfVFlQRV9BVVRIIDoKICAgICAgICAgICAgICAgIHpmQXBQcm9jZXNzQXV0aChkZXYsIGJ1ZiwgdGEsIHZhcCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIC8qIEFzc29jaWF0aW9uIHJlcXVlc3QgKi8KICAgICAgICAgICAgY2FzZSBaTV9XTEFOX0ZSQU1FX1RZUEVfQVNPQ1JFUSA6CiAgICAgICAgICAgICAgICAvKiBSZWFzc29jaWF0aW9uIHJlcXVlc3QgKi8KICAgICAgICAgICAgY2FzZSBaTV9XTEFOX0ZSQU1FX1RZUEVfUkVBU09DUkVRIDoKICAgICAgICAgICAgICAgIHpmQXBQcm9jZXNzQXNvY1JlcShkZXYsIGJ1ZiwgdGEsIHZhcCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIC8qIEFzc29jaWF0aW9uIHJlc3BvbnNlICovCiAgICAgICAgICAgIGNhc2UgWk1fV0xBTl9GUkFNRV9UWVBFX0FTT0NSU1AgOgogICAgICAgICAgICAgICAgLy96ZkFwUHJvY2Vzc0Fzb2NSc3AoZGV2LCBidWYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAvKiBEZWF1dGhlbnRpY2F0aW9uICovCiAgICAgICAgICAgIGNhc2UgWk1fV0xBTl9GUkFNRV9UWVBFX0RFQVVUSCA6CiAgICAgICAgICAgICAgICB6ZkFwUHJvY2Vzc0RlYXV0aChkZXYsIGJ1ZiwgdGEsIHZhcCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIC8qIERpc2Fzc29jaWF0aW9uICovCiAgICAgICAgICAgIGNhc2UgWk1fV0xBTl9GUkFNRV9UWVBFX0RJU0FTT0MgOgogICAgICAgICAgICAgICAgemZBcFByb2Nlc3NEaXNhc29jKGRldiwgYnVmLCB0YSwgdmFwKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgLyogUHJvYmUgcmVxdWVzdCAqLwogICAgICAgICAgICBjYXNlIFpNX1dMQU5fRlJBTUVfVFlQRV9QUk9CRVJFUSA6CiAgICAgICAgICAgICAgICB6ZlByb2Nlc3NQcm9iZVJlcShkZXYsIGJ1ZiwgdGEpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAvKiBQcm9iZSByZXNwb25zZSAqLwogICAgICAgICAgICBjYXNlIFpNX1dMQU5fRlJBTUVfVFlQRV9QUk9CRVJTUCA6CiAgICAgICAgICAgICAgICB6ZkFwUHJvY2Vzc1Byb2JlUnNwKGRldiwgYnVmLCBBZGRJbmZvKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgLyogQWN0aW9uICovCiAgICAgICAgICAgIGNhc2UgWk1fV0xBTl9GUkFNRV9UWVBFX0FDVElPTiA6CiAgICAgICAgICAgICAgICB6ZkFwUHJvY2Vzc0FjdGlvbihkZXYsIGJ1Zik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICB9CiAgICBlbHNlIC8vaWYgKCh3ZC0+d2xhbk1vZGUgPT0gWk1fTU9ERV9JTkZSQVNUUlVDVFVSRSkgfHwgKHdkLT53bGFuTW9kZSA9PSBaTV9NT0RFX0lCU1MpKQogICAgewogICAgICAgIC8qIERpc3BhdGNoIGJ5IGZyYW1lIHR5cGUgKi8KICAgICAgICBzd2l0Y2ggKGZyYW1lVHlwZSkKICAgICAgICB7CiAgICAgICAgICAgICAgICAvKiBCZWFjb24gKi8KICAgICAgICAgICAgY2FzZSBaTV9XTEFOX0ZSQU1FX1RZUEVfQkVBQ09OIDoKICAgICAgICAgICAgICAgIC8qIGlmIGVuYWJsZSA4MDIuMTFoIGFuZCBjdXJyZW50IGNoYW5lbCBpcyBzaWxlbnQgYnV0IHJlY2VpdmUgYmVhY29uIGZyb20gb3RoZXIgQVAgKi8KICAgICAgICAgICAgICAgIGlmICgoKHdkLT5yZWd1bGF0aW9uVGFibGUuYWxsb3dDaGFubmVsW3dkLT5yZWd1bGF0aW9uVGFibGUuQ3VyQ2hJbmRleF0uY2hhbm5lbEZsYWdzCiAgICAgICAgICAgICAgICAgICAgICAgICYgWk1fUkVHX0ZMQUdfQ0hBTk5FTF9DU0EpICE9IDApICYmIHdkLT5zdGEuREZTRW5hYmxlKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHdkLT5yZWd1bGF0aW9uVGFibGUuYWxsb3dDaGFubmVsW3dkLT5yZWd1bGF0aW9uVGFibGUuQ3VyQ2hJbmRleF0uY2hhbm5lbEZsYWdzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAmPSB+KFpNX1JFR19GTEFHX0NIQU5ORUxfQ1NBICYgWk1fUkVHX0ZMQUdfQ0hBTk5FTF9QQVNTSVZFKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHpmU3RhUHJvY2Vzc0JlYWNvbihkZXYsIGJ1ZiwgQWRkSW5mbyk7IC8vQ1dZYW5nKG0pCiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIC8qIEF1dGhlbnRpY2F0aW9uICovCiAgICAgICAgICAgIGNhc2UgWk1fV0xBTl9GUkFNRV9UWVBFX0FVVEggOgogICAgICAgICAgICAgICAgLyogVE9ETyA6IHZhcCBwYXJhbWV0ZXIgaXMgdXNlbGVzcyBpbiBTVEEgbW9kZSwgZ2V0IHJpZCBvZiBpdCAqLwogICAgICAgICAgICAgICAgemZTdGFQcm9jZXNzQXV0aChkZXYsIGJ1ZiwgdGEsIDApOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAvKiBBc3NvY2lhdGlvbiByZXF1ZXN0ICovCiAgICAgICAgICAgIGNhc2UgWk1fV0xBTl9GUkFNRV9UWVBFX0FTT0NSRVEgOgogICAgICAgICAgICAgICAgLyogVE9ETyA6IHZhcCBwYXJhbWV0ZXIgaXMgdXNlbGVzcyBpbiBTVEEgbW9kZSwgZ2V0IHJpZCBvZiBpdCAqLwogICAgICAgICAgICAgICAgemZTdGFQcm9jZXNzQXNvY1JlcShkZXYsIGJ1ZiwgdGEsIDApOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAvKiBBc3NvY2lhdGlvbiByZXNwb25zZSAqLwogICAgICAgICAgICBjYXNlIFpNX1dMQU5fRlJBTUVfVFlQRV9BU09DUlNQIDoKICAgICAgICAgICAgICAgIC8qIFJlYXNzb2NpYXRpb24gcmVxdWVzdCAqLwogICAgICAgICAgICBjYXNlIFpNX1dMQU5fRlJBTUVfVFlQRV9SRUFTT0NSU1AgOgogICAgICAgICAgICAgICAgemZTdGFQcm9jZXNzQXNvY1JzcChkZXYsIGJ1Zik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIC8qIERlYXV0aGVudGljYXRpb24gKi8KICAgICAgICAgICAgY2FzZSBaTV9XTEFOX0ZSQU1FX1RZUEVfREVBVVRIIDoKICAgICAgICAgICAgICAgIHptX2RlYnVnX21zZzAoIkRlYXV0aGVudGljYXRpb24gcmVjZWl2ZWQiKTsKICAgICAgICAgICAgICAgIHpmU3RhUHJvY2Vzc0RlYXV0aChkZXYsIGJ1Zik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIC8qIERpc2Fzc29jaWF0aW9uICovCiAgICAgICAgICAgIGNhc2UgWk1fV0xBTl9GUkFNRV9UWVBFX0RJU0FTT0MgOgogICAgICAgICAgICAgICAgem1fZGVidWdfbXNnMCgiRGlzYXNzb2NpYXRpb24gcmVjZWl2ZWQiKTsKICAgICAgICAgICAgICAgIHpmU3RhUHJvY2Vzc0Rpc2Fzb2MoZGV2LCBidWYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAvKiBQcm9iZSByZXF1ZXN0ICovCiAgICAgICAgICAgIGNhc2UgWk1fV0xBTl9GUkFNRV9UWVBFX1BST0JFUkVRIDoKICAgICAgICAgICAgICAgIHpmUHJvY2Vzc1Byb2JlUmVxKGRldiwgYnVmLCB0YSk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIC8qIFByb2JlIHJlc3BvbnNlICovCiAgICAgICAgICAgIGNhc2UgWk1fV0xBTl9GUkFNRV9UWVBFX1BST0JFUlNQIDoKICAgICAgICAgICAgICAgIC8qIGlmIGVuYWJsZSA4MDIuMTFoIGFuZCBjdXJyZW50IGNoYW5lbCBpcyBzaWxlbnQgYnV0IHJlY2VpdmUgcHJvYmUgcmVzcG9uc2UgZnJvbSBvdGhlciBBUCAqLwogICAgICAgICAgICAgICAgaWYgKCgod2QtPnJlZ3VsYXRpb25UYWJsZS5hbGxvd0NoYW5uZWxbd2QtPnJlZ3VsYXRpb25UYWJsZS5DdXJDaEluZGV4XS5jaGFubmVsRmxhZ3MKICAgICAgICAgICAgICAgICAgICAgICAgJiBaTV9SRUdfRkxBR19DSEFOTkVMX0NTQSkgIT0gMCkgJiYgd2QtPnN0YS5ERlNFbmFibGUpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgd2QtPnJlZ3VsYXRpb25UYWJsZS5hbGxvd0NoYW5uZWxbd2QtPnJlZ3VsYXRpb25UYWJsZS5DdXJDaEluZGV4XS5jaGFubmVsRmxhZ3MKICAgICAgICAgICAgICAgICAgICAgICAgICAgICY9IH4oWk1fUkVHX0ZMQUdfQ0hBTk5FTF9DU0EgJiBaTV9SRUdfRkxBR19DSEFOTkVMX1BBU1NJVkUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgemZTdGFQcm9jZXNzUHJvYmVSc3AoZGV2LCBidWYsIEFkZEluZm8pOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIFpNX1dMQU5fRlJBTUVfVFlQRV9BVElNOgogICAgICAgICAgICAgICAgemZTdGFQcm9jZXNzQXRpbShkZXYsIGJ1Zik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIC8qIEFjdGlvbiAqLwogICAgICAgICAgICBjYXNlIFpNX1dMQU5fRlJBTUVfVFlQRV9BQ1RJT04gOgogICAgICAgICAgICAgICAgem1fbXNnMF9tbShaTV9MVl8yLCAiUHJvY2Vzc0FjdGlvbk1ndEZyYW1lIik7CiAgICAgICAgICAgICAgICB6ZlN0YVByb2Nlc3NBY3Rpb24oZGV2LCBidWYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICBGVU5DVElPTiBERVNDUklQVElPTiAgICAgICAgICAgICAgICAgIHpmUHJvY2Vzc1Byb2JlUmVxICAgICAgICAgICAqLwovKiAgICAgIFByb2Nlc3MgcHJvYmUgcmVxdWVzdCBtYW5hZ2VtZW50IGZyYW1lLiAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICBJTlBVVFMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIGRldiA6IGRldmljZSBwb2ludGVyICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIGJ1ZiA6IGF1dGggZnJhbWUgYnVmZmVyICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICBPVVRQVVRTICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIG5vbmUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICBBVVRIT1IgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIFN0ZXBoZW4gQ2hlbiAgICAgICAgWnlEQVMgVGVjaG5vbG9neSBDb3Jwb3JhdGlvbiAgICAyMDA1LjEwICAgICAqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwp2b2lkIHpmUHJvY2Vzc1Byb2JlUmVxKHpkZXZfdCogZGV2LCB6YnVmX3QqIGJ1ZiwgdTE2X3QqIHNyYykKewogICAgdTE2X3Qgb2Zmc2V0OwogICAgdThfdCBsZW47CiAgICB1MTZfdCBpLCBqOwogICAgdThfdCBjaDsKICAgIHUxNl90IHNlbmRGbGFnOwoKICAgIHptd19nZXRfd2xhbl9kZXYoZGV2KTsKCiAgICAvKiBjaGVjayBtb2RlIDogQVAvSUJTUyAqLwogICAgaWYgKCh3ZC0+d2xhbk1vZGUgIT0gWk1fTU9ERV9BUCkgJiYgKHdkLT53bGFuTW9kZSAhPSBaTV9NT0RFX0lCU1MpKQogICAgewogICAgICAgIHptX21zZzBfbW0oWk1fTFZfMywgIklnbm9yZSBwcm9iZSByZXEiKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgaWYgKCh3ZC0+d2xhbk1vZGUgIT0gWk1fTU9ERV9BUCkgJiYgKHdkLT5zdGEuYWRhcHRlclN0YXRlID09IFpNX1NUQV9TVEFURV9ESVNDT05ORUNUKSkKICAgIHsKICAgICAgICB6bV9tc2cwX21tKFpNX0xWXzMsICJQYWNrZXRzIGRyb3BwZWQgZHVlIHRvIGRpc2Nvbm5lY3Qgc3RhdGUiKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgaWYgKCB3ZC0+d2xhbk1vZGUgPT0gWk1fTU9ERV9JQlNTICkKICAgIHsKICAgICAgICB6ZlNlbmRNbUZyYW1lKGRldiwgWk1fV0xBTl9GUkFNRV9UWVBFX1BST0JFUlNQLCBzcmMsIDAsIDAsIDApOwoKICAgICAgICByZXR1cm47CiAgICB9CgogICAgLyogY2hlY2sgU1NJRCAqLwogICAgaWYgKChvZmZzZXQgPSB6ZkZpbmRFbGVtZW50KGRldiwgYnVmLCBaTV9XTEFOX0VJRF9TU0lEKSkgPT0gMHhmZmZmKQogICAgewogICAgICAgIHptX21zZzBfbW0oWk1fTFZfMywgInByb2JlIHJlcSBTU0lEIG5vdCBmb3VuZCIpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBsZW4gPSB6bXdfcnhfYnVmX3JlYWRiKGRldiwgYnVmLCBvZmZzZXQrMSk7CgogICAgZm9yIChpPTA7IGk8Wk1fTUFYX0FQX1NVUFBPUlQ7IGkrKykKICAgIHsKICAgICAgICBpZiAoKHdkLT5hcC5hcEJpdG1hcCAmICgxPDxpKSkgIT0gMCkKICAgICAgICB7CiAgICAgICAgICAgIHptX21zZzFfbW0oWk1fTFZfMywgImxlbj0iLCBsZW4pOwogICAgICAgICAgICBzZW5kRmxhZyA9IDA7CiAgICAgICAgICAgIC8qIGJvYXJkY2FzdCBTU0lEICovCiAgICAgICAgICAgIGlmIChsZW4gPT0gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHdkLT5hcC5oaWRlU3NpZFtpXSA9PSAwKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHNlbmRGbGFnID0gMTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICAvKiBOb3QgYnJvYWRjYXN0IFNTSUQgKi8KICAgICAgICAgICAgZWxzZSBpZiAod2QtPmFwLnNzaWRMZW5baV0gPT0gbGVuKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBmb3IgKGo9MDsgajxsZW47IGorKykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoKGNoID0gem13X3J4X2J1Zl9yZWFkYihkZXYsIGJ1Ziwgb2Zmc2V0KzIraikpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAhPSB3ZC0+YXAuc3NpZFtpXVtqXSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChqID09IGxlbikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzZW5kRmxhZyA9IDE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHNlbmRGbGFnID09IDEpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8qIFNlbmQgcHJvYmUgcmVzcG9uc2UgKi8KICAgICAgICAgICAgICAgIHpmU2VuZE1tRnJhbWUoZGV2LCBaTV9XTEFOX0ZSQU1FX1RZUEVfUFJPQkVSU1AsIHNyYywgaSwgMCwgaSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgIEZVTkNUSU9OIERFU0NSSVBUSU9OICAgICAgICAgICAgICAgICAgemZQcm9jZXNzUHJvYmVSc3AgICAgICAgICAgICovCi8qICAgICAgUHJvY2VzcyBwcm9iZSByZXNwb25zZSBtYW5hZ2VtZW50IGZyYW1lLiAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgIElOUFVUUyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgZGV2IDogZGV2aWNlIHBvaW50ZXIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgYnVmIDogYXV0aCBmcmFtZSBidWZmZXIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICBBZGRJbmZvIDogUnggSGVhZGVyIGFuZCBSeCBNYWMgU3RhdHVzICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgIE9VVFBVVFMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgbm9uZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgIEFVVEhPUiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgQXJlc3MgWWFuZyAgICAgICAgICBaeURBUyBUZWNobm9sb2d5IENvcnBvcmF0aW9uICAgIDIwMDYuMTEgICAgICovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnZvaWQgemZQcm9jZXNzUHJvYmVSc3AoemRldl90KiBkZXYsIHpidWZfdCogYnVmLCBzdHJ1Y3QgenNBZGRpdGlvbkluZm8qIEFkZEluZm8pCnsKICAgIC8qIEdhdGhlciBzY2FuIHJlc3VsdCAqLwogICAgLyogUGFyc2UgVElNIGFuZCBzZW5kIFBTLVBPTEwgaW4gcG93ZXIgc2F2aW5nIG1vZGUgKi8KICAgIHN0cnVjdCB6c1dsYW5Qcm9iZVJzcEZyYW1lSGVhZGVyKiAgcFByb2JlUnNwSGVhZGVyOwogICAgc3RydWN0IHpzQnNzSW5mbyogcEJzc0luZm87CiAgICB1OF90ICAgcEJ1ZltzaXplb2Yoc3RydWN0IHpzV2xhblByb2JlUnNwRnJhbWVIZWFkZXIpXTsKICAgIGludCAgICByZXM7CgogICAgem13X2dldF93bGFuX2RldihkZXYpOwoKICAgIHptd19kZWNsYXJlX2Zvcl9jcml0aWNhbF9zZWN0aW9uKCk7CgogICAgemZDb3B5RnJvbVJ4QnVmZmVyKGRldiwgYnVmLCBwQnVmLCAwLAogICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihzdHJ1Y3QgenNXbGFuUHJvYmVSc3BGcmFtZUhlYWRlcikpOwogICAgcFByb2JlUnNwSGVhZGVyID0gKHN0cnVjdCB6c1dsYW5Qcm9iZVJzcEZyYW1lSGVhZGVyKikgcEJ1ZjsKCiAgICB6bXdfZW50ZXJfY3JpdGljYWxfc2VjdGlvbihkZXYpOwoKICAgIC8vem1fZGVidWdfbXNnMSgiYnNzIGNvdW50ID0gIiwgd2QtPnN0YS5ic3NMaXN0LmJzc0NvdW50KTsKCiAgICBwQnNzSW5mbyA9IHpmU3RhRmluZEJzc0luZm8oZGV2LCBidWYsIHBQcm9iZVJzcEhlYWRlcik7CgogICAgLy9pZiAoIGkgPT0gd2QtPnN0YS5ic3NMaXN0LmJzc0NvdW50ICkKICAgIGlmICggcEJzc0luZm8gPT0gTlVMTCApCiAgICB7CiAgICAgICAgLyogQWxsb2NhdGUgYSBuZXcgZW50cnkgaWYgQlNTIG5vdCBpbiB0aGUgc2NhbiBsaXN0ICovCiAgICAgICAgcEJzc0luZm8gPSB6ZkJzc0luZm9BbGxvY2F0ZShkZXYpOwogICAgICAgIGlmIChwQnNzSW5mbyAhPSBOVUxMKQogICAgICAgIHsKICAgICAgICAgICAgcmVzID0gemZTdGFJbml0QnNzSW5mbyhkZXYsIGJ1ZiwgcFByb2JlUnNwSGVhZGVyLCBwQnNzSW5mbywgQWRkSW5mbywgMCk7CiAgICAgICAgICAgIC8vemZEdW1wU1NJRChwQnNzSW5mby0+c3NpZFsxXSwgJihwQnNzSW5mby0+c3NpZFsyXSkpOwogICAgICAgICAgICBpZiAoIHJlcyAhPSAwICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgemZCc3NJbmZvRnJlZShkZXYsIHBCc3NJbmZvKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHpmQnNzSW5mb0luc2VydFRvTGlzdChkZXYsIHBCc3NJbmZvKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICByZXMgPSB6ZlN0YUluaXRCc3NJbmZvKGRldiwgYnVmLCBwUHJvYmVSc3BIZWFkZXIsIHBCc3NJbmZvLCBBZGRJbmZvLCAxKTsKICAgICAgICBpZiAocmVzID09IDIpCiAgICAgICAgewogICAgICAgICAgICB6ZkJzc0luZm9SZW1vdmVGcm9tTGlzdChkZXYsIHBCc3NJbmZvKTsKICAgICAgICAgICAgemZCc3NJbmZvRnJlZShkZXYsIHBCc3NJbmZvKTsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAoIHdkLT53bGFuTW9kZSA9PSBaTV9NT0RFX0lCU1MgKQogICAgICAgIHsKICAgICAgICAgICAgaW50IGlkeDsKCiAgICAgICAgICAgIC8vIEl0IHdvdWxkIHJlc2V0IHRoZSBhbGl2ZSBjb3VudGVyIGlmIHRoZSBwZWVyIHN0YXRpb24gaXMgZm91bmQhCiAgICAgICAgICAgIHpmU3RhRmluZEZyZWVPcHBvc2l0ZShkZXYsICh1MTZfdCAqKXBCc3NJbmZvLT5tYWNhZGRyLCAmaWR4KTsKICAgICAgICB9CiAgICB9CgogICAgem13X2xlYXZlX2NyaXRpY2FsX3NlY3Rpb24oZGV2KTsKCiAgICByZXR1cm47Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgIEZVTkNUSU9OIERFU0NSSVBUSU9OICAgICAgICAgICAgICAgICAgemZTZW5kUHJvYmVSZXEgICAgICAgICAgICAgICovCi8qICAgICAgU2VuZCBwcm9iZSByZXF1ZXN0IG1hbmFnZW1lbnQgZnJhbWUuICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgIElOUFVUUyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgZGV2IDogZGV2aWNlIHBvaW50ZXIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgIE9VVFBVVFMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgbm9uZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgIEFVVEhPUiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgSmktSHVhbmcgTGVlICAgICAgICBaeURBUyBUZWNobm9sb2d5IENvcnBvcmF0aW9uICAgIDIwMDUuMTEgICAgICovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgp1MTZfdCB6ZlNlbmRQcm9iZVJlcSh6ZGV2X3QqIGRldiwgemJ1Zl90KiBidWYsIHUxNl90IG9mZnNldCwgdThfdCBiV2l0aFNTSUQpCnsKICAgIHptd19nZXRfd2xhbl9kZXYoZGV2KTsKICAgIHptd19kZWNsYXJlX2Zvcl9jcml0aWNhbF9zZWN0aW9uKCk7CgoKICAgIC8qIFNTSUQgKi8KICAgIGlmIChiV2l0aFNTSUQgPT0gMCkgIC8qIGJyb2FkY2FzdCBzc2lkICovCiAgICB7CiAgICAgICAgLy96bXdfbGVhdmVfY3JpdGljYWxfc2VjdGlvbihkZXYpOwogICAgICAgIHptd190eF9idWZfd3JpdGViKGRldiwgYnVmLCBvZmZzZXQrKywgWk1fV0xBTl9FSURfU1NJRCk7CiAgICAgICAgem13X3R4X2J1Zl93cml0ZWIoZGV2LCBidWYsIG9mZnNldCsrLCAwKTsgICAvKiBsZW5ndGggPSAwICovCiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgem13X2VudGVyX2NyaXRpY2FsX3NlY3Rpb24oZGV2KTsKICAgICAgICBpZiAod2QtPndzLnByb2JpbmdTc2lkTGlzdFtiV2l0aFNTSUQtMV0uc3NpZExlbiA9PSAwKQogICAgICAgIHsKICAgICAgICAgICAgem13X3R4X2J1Zl93cml0ZWIoZGV2LCBidWYsIG9mZnNldCsrLCBaTV9XTEFOX0VJRF9TU0lEKTsKICAgICAgICAgICAgem13X3R4X2J1Zl93cml0ZWIoZGV2LCBidWYsIG9mZnNldCsrLCAwKTsgICAvKiBsZW5ndGggPSAwICovCiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIHptd190eF9idWZfd3JpdGViKGRldiwgYnVmLCBvZmZzZXQrKywgWk1fV0xBTl9FSURfU1NJRCk7CiAgICAgICAgICAgIHptd190eF9idWZfd3JpdGViKGRldiwgYnVmLCBvZmZzZXQrKywKICAgICAgICAgICAgICAgICAgICB3ZC0+d3MucHJvYmluZ1NzaWRMaXN0W2JXaXRoU1NJRC0xXS5zc2lkTGVuKTsKICAgICAgICAgICAgemZDb3B5VG9JbnRUeEJ1ZmZlcihkZXYsIGJ1ZiwKICAgICAgICAgICAgICAgICAgICB3ZC0+d3MucHJvYmluZ1NzaWRMaXN0W2JXaXRoU1NJRC0xXS5zc2lkLAogICAgICAgICAgICAgICAgICAgIG9mZnNldCwKICAgICAgICAgICAgICAgICAgICB3ZC0+d3MucHJvYmluZ1NzaWRMaXN0W2JXaXRoU1NJRC0xXS5zc2lkTGVuKTsgLyogc3NpZCAqLwogICAgICAgICAgICBvZmZzZXQgKz0gd2QtPndzLnByb2JpbmdTc2lkTGlzdFtiV2l0aFNTSUQtMV0uc3NpZExlbjsKICAgICAgICB9CiAgICAgICAgem13X2xlYXZlX2NyaXRpY2FsX3NlY3Rpb24oZGV2KTsKICAgIH0KCiAgICAvKiBTdXBwb3J0ZWQgcmF0ZXMgKi8KICAgIGlmICggd2QtPnN0YS5jdXJyZW50RnJlcXVlbmN5IDwgMzAwMCApCiAgICB7ICAgLyogODAyLjExYitnICovCiAgICAgICAgb2Zmc2V0ID0gemZNbUFkZEllU3VwcG9ydFJhdGUoZGV2LCBidWYsIG9mZnNldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBaTV9XTEFOX0VJRF9TVVBQT1JUX1JBVEUsIFpNX1JBVEVfU0VUX0NDSyk7CgogICAgICAgIGlmICh3ZC0+c3VwcG9ydE1vZGUgJiAoWk1fV0lSRUxFU1NfTU9ERV8yNF81NHxaTV9XSVJFTEVTU19NT0RFXzI0X04pKSB7CiAgICAgICAgICAgIGlmICh3ZC0+d2xhbk1vZGUgPT0gWk1fTU9ERV9JQlNTKSB7CiAgICAgICAgICAgICAgICBpZiAod2QtPndmYy5iSWJzc0dNb2RlKSB7CiAgICAgICAgICAgICAgICAgICAgb2Zmc2V0ID0gemZNbUFkZEllU3VwcG9ydFJhdGUoZGV2LCBidWYsIG9mZnNldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBaTV9XTEFOX0VJRF9FWFRFTkRFRF9SQVRFLCBaTV9SQVRFX1NFVF9PRkRNKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIG9mZnNldCA9IHpmTW1BZGRJZVN1cHBvcnRSYXRlKGRldiwgYnVmLCBvZmZzZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWk1fV0xBTl9FSURfRVhURU5ERURfUkFURSwgWk1fUkFURV9TRVRfT0ZETSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICBlbHNlCiAgICB7ICAvKiA4MDIuMTFhICovCiAgICAgICAgb2Zmc2V0ID0gemZNbUFkZEllU3VwcG9ydFJhdGUoZGV2LCBidWYsIG9mZnNldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBaTV9XTEFOX0VJRF9TVVBQT1JUX1JBVEUsIFpNX1JBVEVfU0VUX09GRE0pOwogICAgfQoKICAgIHJldHVybiBvZmZzZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICBGVU5DVElPTiBERVNDUklQVElPTiAgICAgICAgICAgICAgICAgIHpmVXBkYXRlRGVmYXVsdFFvc1BhcmFtZXRlciAqLwovKiAgICAgIFVwZGF0ZSBUeFFzIENXTUlOLCBDV01BWCwgQUlGUyBhbmQgVFhPIHRvIFdNRSBkZWZhdWx0IHZhbHVlLiAgICAqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICBJTlBVVFMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIGRldiA6IGRldmljZSBwb2ludGVyICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIG1vZGUgOiAwPT5TVEEsIDE9PkFQICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICBPVVRQVVRTICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIG5vbmUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICBBVVRIT1IgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIFN0ZXBoZW4gICAgICAgICAgICAgWnlEQVMgVGVjaG5vbG9neSBDb3Jwb3JhdGlvbiAgICAyMDA2LjYgICAgICAqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwp2b2lkIHpmVXBkYXRlRGVmYXVsdFFvc1BhcmFtZXRlcih6ZGV2X3QqIGRldiwgdThfdCBtb2RlKQp7CiAgICB1MTZfdCBjd21pbls1XTsKICAgIHUxNl90IGN3bWF4WzVdOwogICAgdTE2X3QgYWlmc1s1XTsKICAgIHUxNl90IHR4b3BbNV07CgogICAgLyogV01NIHBhcmFtZXRlciBmb3IgU1RBICovCiAgICAvKiBCZXN0IEVmZm9yICovCiAgICBjd21pblswXSA9IDE1OwogICAgY3dtYXhbMF0gPSAxMDIzOwogICAgYWlmc1swXSA9IDMgKiA5ICsgMTA7CiAgICB0eG9wWzBdID0gMDsKICAgIC8qIEJhY2sgR3JvdW5kICovCiAgICBjd21pblsxXSA9IDE1OwogICAgY3dtYXhbMV0gPSAxMDIzOwogICAgYWlmc1sxXSA9IDcgKiA5ICsgMTA7CiAgICB0eG9wWzFdID0gMDsKICAgIC8qIFZJREVPICovCiAgICBjd21pblsyXSA9IDc7CiAgICBjd21heFsyXSA9IDE1OwogICAgYWlmc1syXSA9IDIgKiA5ICsgMTA7CiAgICB0eG9wWzJdID0gOTQ7CiAgICAvKiBWT0lDRSAqLwogICAgY3dtaW5bM10gPSAzOwogICAgY3dtYXhbM10gPSA3OwogICAgYWlmc1szXSA9IDIgKiA5ICsgMTA7CiAgICB0eG9wWzNdID0gNDc7CiAgICAvKiBTcGVjaWFsIFR4USAqLwogICAgY3dtaW5bNF0gPSAzOwogICAgY3dtYXhbNF0gPSA3OwogICAgYWlmc1s0XSA9IDIgKiA5ICsgMTA7CiAgICB0eG9wWzRdID0gMDsKCiAgICAvKiBXTU0gcGFyYW1ldGVyIGZvciBBUCAqLwogICAgaWYgKG1vZGUgPT0gMSkKICAgIHsKICAgICAgICBjd21heFswXSA9IDYzOwogICAgICAgIGFpZnNbM10gPSAxICogOSArIDEwOwogICAgICAgIGFpZnNbNF0gPSAxICogOSArIDEwOwogICAgfQogICAgemZIcFVwZGF0ZVFvc1BhcmFtZXRlcihkZXYsIGN3bWluLCBjd21heCwgYWlmcywgdHhvcCk7Cn0KCnUxNl90IHpmRmluZEFUSEV4dENhcCh6ZGV2X3QqIGRldiwgemJ1Zl90KiBidWYsIHU4X3QgdHlwZSwgdThfdCBzdWJ0eXBlKQp7CiAgICB1OF90IHN1YlR5cGU7CiAgICB1MTZfdCBvZmZzZXQ7CiAgICB1MTZfdCBidWZMZW47CiAgICB1MTZfdCBlbGVuOwogICAgdThfdCBpZDsKICAgIHU4X3QgdG1wOwoKICAgIC8qIEdldCBvZmZzZXQgb2YgZmlyc3QgZWxlbWVudCAqLwogICAgc3ViVHlwZSA9ICh6bXdfcnhfYnVmX3JlYWRiKGRldiwgYnVmLCAwKSA+PiA0KTsKCiAgICBpZiAoKG9mZnNldCA9IHpnRWxlbWVudE9mZnNldFRhYmxlW3N1YlR5cGVdKSA9PSAweGZmKQogICAgewogICAgICAgIHptX2Fzc2VydCgwKTsKICAgIH0KCiAgICAvKiBQbHVzIHdsYW4gaGVhZGVyICovCiAgICBvZmZzZXQgKz0gMjQ7CgogICAgYnVmTGVuID0gemZ3QnVmR2V0U2l6ZShkZXYsIGJ1Zik7CgogICAgLyogU2VhcmNoIGxvb3AgKi8KICAgIHdoaWxlICgob2Zmc2V0KzIpPGJ1ZkxlbikgICAgICAgICAgICAgICAgICAgLy8gaW5jbHVkaW5nIGVsZW1lbnQgSUQgYW5kIGxlbmd0aCAoMmJ5dGVzKQogICAgewogICAgICAgIC8qIFNlYXJjaCB0YXJnZXQgZWxlbWVudCAqLwogICAgICAgIGlmICgoaWQgPSB6bXdfcnhfYnVmX3JlYWRiKGRldiwgYnVmLCBvZmZzZXQpKSA9PSBaTV9XTEFOX0VJRF9XSUZJX0lFKQogICAgICAgIHsKICAgICAgICAgICAgLyogQmluZ28gKi8KICAgICAgICAgICAgaWYgKChlbGVuID0gem13X3J4X2J1Zl9yZWFkYihkZXYsIGJ1Ziwgb2Zmc2V0KzEpKT4oYnVmTGVuIC0gb2Zmc2V0KSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLyogRWxlbWVudCBsZW5ndGggZXJyb3IgKi8KICAgICAgICAgICAgICAgIHJldHVybiAweGZmZmY7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICggZWxlbiA9PSAwICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIDB4ZmZmZjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCgodG1wID0gem13X3J4X2J1Zl9yZWFkYihkZXYsIGJ1Ziwgb2Zmc2V0KzIpKSA9PSAweDAwKQogICAgICAgICAgICAgICAgICAgICYmICgodG1wID0gem13X3J4X2J1Zl9yZWFkYihkZXYsIGJ1Ziwgb2Zmc2V0KzMpKSA9PSAweDAzKQogICAgICAgICAgICAgICAgICAgICYmICgodG1wID0gem13X3J4X2J1Zl9yZWFkYihkZXYsIGJ1Ziwgb2Zmc2V0KzQpKSA9PSAweDdmKQogICAgICAgICAgICAgICAgICAgICYmICgodG1wID0gem13X3J4X2J1Zl9yZWFkYihkZXYsIGJ1Ziwgb2Zmc2V0KzUpKSA9PSB0eXBlKSkKCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICggc3VidHlwZSAhPSAweGZmICkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoICh0bXAgPSB6bXdfcnhfYnVmX3JlYWRiKGRldiwgYnVmLCBvZmZzZXQrNikpID09IHN1YnR5cGUgICkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBvZmZzZXQ7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBvZmZzZXQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qIEFkdmFuY2UgdG8gbmV4dCBlbGVtZW50ICovCiAgICAgICAgaWYgKChlbGVuID0gem13X3J4X2J1Zl9yZWFkYihkZXYsIGJ1Ziwgb2Zmc2V0KzEpKSA9PSAwKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIDB4ZmZmZjsKICAgICAgICB9CiAgICAgICAgb2Zmc2V0ICs9IChlbGVuKzIpOwogICAgfQogICAgcmV0dXJuIDB4ZmZmZjsKfQoKdTE2X3QgemZGaW5kQnJkY21NcnZsUmxua0V4dENhcCh6ZGV2X3QqIGRldiwgemJ1Zl90KiBidWYpCnsKICAgIHU4X3Qgc3ViVHlwZTsKICAgIHUxNl90IG9mZnNldDsKICAgIHUxNl90IGJ1ZkxlbjsKICAgIHUxNl90IGVsZW47CiAgICB1OF90IGlkOwogICAgdThfdCB0bXA7CgogICAgLyogR2V0IG9mZnNldCBvZiBmaXJzdCBlbGVtZW50ICovCiAgICBzdWJUeXBlID0gKHptd19yeF9idWZfcmVhZGIoZGV2LCBidWYsIDApID4+IDQpOwoKICAgIGlmICgob2Zmc2V0ID0gemdFbGVtZW50T2Zmc2V0VGFibGVbc3ViVHlwZV0pID09IDB4ZmYpCiAgICB7CiAgICAgICAgem1fYXNzZXJ0KDApOwogICAgfQoKICAgIC8qIFBsdXMgd2xhbiBoZWFkZXIgKi8KICAgIG9mZnNldCArPSAyNDsKCiAgICBidWZMZW4gPSB6ZndCdWZHZXRTaXplKGRldiwgYnVmKTsKCiAgICAvKiBTZWFyY2ggbG9vcCAqLwogICAgd2hpbGUgKChvZmZzZXQrMik8YnVmTGVuKSAgICAgICAgICAgICAgICAgICAvLyBpbmNsdWRpbmcgZWxlbWVudCBJRCBhbmQgbGVuZ3RoICgyYnl0ZXMpCiAgICB7CiAgICAgICAgLyogU2VhcmNoIHRhcmdldCBlbGVtZW50ICovCiAgICAgICAgaWYgKChpZCA9IHptd19yeF9idWZfcmVhZGIoZGV2LCBidWYsIG9mZnNldCkpID09IFpNX1dMQU5fRUlEX1dJRklfSUUpCiAgICAgICAgewogICAgICAgICAgICAvKiBCaW5nbyAqLwogICAgICAgICAgICBpZiAoKGVsZW4gPSB6bXdfcnhfYnVmX3JlYWRiKGRldiwgYnVmLCBvZmZzZXQrMSkpPihidWZMZW4gLSBvZmZzZXQpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvKiBFbGVtZW50IGxlbmd0aCBlcnJvciAqLwogICAgICAgICAgICAgICAgcmV0dXJuIDB4ZmZmZjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCBlbGVuID09IDAgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gMHhmZmZmOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoKCh0bXAgPSB6bXdfcnhfYnVmX3JlYWRiKGRldiwgYnVmLCBvZmZzZXQrMikpID09IDB4MDApCiAgICAgICAgICAgICAgICAgICAgJiYgKCh0bXAgPSB6bXdfcnhfYnVmX3JlYWRiKGRldiwgYnVmLCBvZmZzZXQrMykpID09IDB4MTApCiAgICAgICAgICAgICAgICAgICAgJiYgKCh0bXAgPSB6bXdfcnhfYnVmX3JlYWRiKGRldiwgYnVmLCBvZmZzZXQrNCkpID09IDB4MTgpKQoKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIG9mZnNldDsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmICgoKHRtcCA9IHptd19yeF9idWZfcmVhZGIoZGV2LCBidWYsIG9mZnNldCsyKSkgPT0gMHgwMCkKICAgICAgICAgICAgICAgICAgICAmJiAoKHRtcCA9IHptd19yeF9idWZfcmVhZGIoZGV2LCBidWYsIG9mZnNldCszKSkgPT0gMHg1MCkKICAgICAgICAgICAgICAgICAgICAmJiAoKHRtcCA9IHptd19yeF9idWZfcmVhZGIoZGV2LCBidWYsIG9mZnNldCs0KSkgPT0gMHg0MykpCgogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gb2Zmc2V0OwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKChpZCA9IHptd19yeF9idWZfcmVhZGIoZGV2LCBidWYsIG9mZnNldCkpID09IDB4N0YpCiAgICAgICAgewogICAgICAgICAgICAvKiBCaW5nbyAqLwogICAgICAgICAgICBpZiAoKGVsZW4gPSB6bXdfcnhfYnVmX3JlYWRiKGRldiwgYnVmLCBvZmZzZXQrMSkpPihidWZMZW4gLSBvZmZzZXQpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvKiBFbGVtZW50IGxlbmd0aCBlcnJvciAqLwogICAgICAgICAgICAgICAgcmV0dXJuIDB4ZmZmZjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCBlbGVuID09IDAgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gMHhmZmZmOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoKHRtcCA9IHptd19yeF9idWZfcmVhZGIoZGV2LCBidWYsIG9mZnNldCsyKSkgPT0gMHgwMSkKCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBvZmZzZXQ7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qIEFkdmFuY2UgdG8gbmV4dCBlbGVtZW50ICovCiAgICAgICAgaWYgKChlbGVuID0gem13X3J4X2J1Zl9yZWFkYihkZXYsIGJ1Ziwgb2Zmc2V0KzEpKSA9PSAwKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIDB4ZmZmZjsKICAgICAgICB9CiAgICAgICAgb2Zmc2V0ICs9IChlbGVuKzIpOwogICAgfQogICAgcmV0dXJuIDB4ZmZmZjsKfQoKdTE2X3QgemZGaW5kTWFydmVsRXh0Q2FwKHpkZXZfdCogZGV2LCB6YnVmX3QqIGJ1ZikKewogICAgdThfdCBzdWJUeXBlOwogICAgdTE2X3Qgb2Zmc2V0OwogICAgdTE2X3QgYnVmTGVuOwogICAgdTE2X3QgZWxlbjsKICAgIHU4X3QgaWQ7CiAgICB1OF90IHRtcDsKCiAgICAvKiBHZXQgb2Zmc2V0IG9mIGZpcnN0IGVsZW1lbnQgKi8KICAgIHN1YlR5cGUgPSAoem13X3J4X2J1Zl9yZWFkYihkZXYsIGJ1ZiwgMCkgPj4gNCk7CgogICAgaWYgKChvZmZzZXQgPSB6Z0VsZW1lbnRPZmZzZXRUYWJsZVtzdWJUeXBlXSkgPT0gMHhmZikKICAgIHsKICAgICAgICB6bV9hc3NlcnQoMCk7CiAgICB9CgogICAgLyogUGx1cyB3bGFuIGhlYWRlciAqLwogICAgb2Zmc2V0ICs9IDI0OwoKICAgIGJ1ZkxlbiA9IHpmd0J1ZkdldFNpemUoZGV2LCBidWYpOwoKICAgIC8qIFNlYXJjaCBsb29wICovCiAgICB3aGlsZSAoKG9mZnNldCsyKTxidWZMZW4pICAgICAgICAgICAgICAgICAgIC8vIGluY2x1ZGluZyBlbGVtZW50IElEIGFuZCBsZW5ndGggKDJieXRlcykKICAgIHsKICAgICAgICAvKiBTZWFyY2ggdGFyZ2V0IGVsZW1lbnQgKi8KICAgICAgICBpZiAoKGlkID0gem13X3J4X2J1Zl9yZWFkYihkZXYsIGJ1Ziwgb2Zmc2V0KSkgPT0gWk1fV0xBTl9FSURfV0lGSV9JRSkKICAgICAgICB7CiAgICAgICAgICAgIC8qIEJpbmdvICovCiAgICAgICAgICAgIGlmICgoZWxlbiA9IHptd19yeF9idWZfcmVhZGIoZGV2LCBidWYsIG9mZnNldCsxKSk+KGJ1ZkxlbiAtIG9mZnNldCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8qIEVsZW1lbnQgbGVuZ3RoIGVycm9yICovCiAgICAgICAgICAgICAgICByZXR1cm4gMHhmZmZmOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoIGVsZW4gPT0gMCApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiAweGZmZmY7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgoKHRtcCA9IHptd19yeF9idWZfcmVhZGIoZGV2LCBidWYsIG9mZnNldCsyKSkgPT0gMHgwMCkKICAgICAgICAgICAgICAgICAgJiYgKCh0bXAgPSB6bXdfcnhfYnVmX3JlYWRiKGRldiwgYnVmLCBvZmZzZXQrMykpID09IDB4NTApCiAgICAgICAgICAgICAgICAgICYmICgodG1wID0gem13X3J4X2J1Zl9yZWFkYihkZXYsIGJ1Ziwgb2Zmc2V0KzQpKSA9PSAweDQzKSkKCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBvZmZzZXQ7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qIEFkdmFuY2UgdG8gbmV4dCBlbGVtZW50ICovCiAgICAgICAgaWYgKChlbGVuID0gem13X3J4X2J1Zl9yZWFkYihkZXYsIGJ1Ziwgb2Zmc2V0KzEpKSA9PSAwKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIDB4ZmZmZjsKICAgICAgICB9CiAgICAgICAgb2Zmc2V0ICs9IChlbGVuKzIpOwogICAgfQogICAgcmV0dXJuIDB4ZmZmZjsKfQoKdTE2X3QgemZGaW5kQnJvYWRjb21FeHRDYXAoemRldl90KiBkZXYsIHpidWZfdCogYnVmKQp7CiAgICB1OF90IHN1YlR5cGU7CiAgICB1MTZfdCBvZmZzZXQ7CiAgICB1MTZfdCBidWZMZW47CiAgICB1MTZfdCBlbGVuOwogICAgdThfdCBpZDsKICAgIHU4X3QgdG1wOwoKICAgIC8qIEdldCBvZmZzZXQgb2YgZmlyc3QgZWxlbWVudCAqLwogICAgc3ViVHlwZSA9ICh6bXdfcnhfYnVmX3JlYWRiKGRldiwgYnVmLCAwKSA+PiA0KTsKCiAgICBpZiAoKG9mZnNldCA9IHpnRWxlbWVudE9mZnNldFRhYmxlW3N1YlR5cGVdKSA9PSAweGZmKQogICAgewogICAgICAgIHptX2Fzc2VydCgwKTsKICAgIH0KCiAgICAvKiBQbHVzIHdsYW4gaGVhZGVyICovCiAgICBvZmZzZXQgKz0gMjQ7CgogICAgYnVmTGVuID0gemZ3QnVmR2V0U2l6ZShkZXYsIGJ1Zik7CgogICAgLyogU2VhcmNoIGxvb3AgKi8KICAgIHdoaWxlKChvZmZzZXQrMikgPCBidWZMZW4pICAgICAgICAgICAgICAgICAgIC8vIGluY2x1ZGluZyBlbGVtZW50IElEIGFuZCBsZW5ndGggKDJieXRlcykKICAgIHsKICAgICAgICAvKiBTZWFyY2ggdGFyZ2V0IGVsZW1lbnQgKi8KICAgICAgICBpZiAoKGlkID0gem13X3J4X2J1Zl9yZWFkYihkZXYsIGJ1Ziwgb2Zmc2V0KSkgPT0gWk1fV0xBTl9FSURfV0lGSV9JRSkKICAgICAgICB7CiAgICAgICAgICAgIC8qIEJpbmdvICovCiAgICAgICAgICAgIGlmICgoZWxlbiA9IHptd19yeF9idWZfcmVhZGIoZGV2LCBidWYsIG9mZnNldCsxKSkgPiAoYnVmTGVuIC0gb2Zmc2V0KSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLyogRWxlbWVudCBsZW5ndGggZXJyb3IgKi8KICAgICAgICAgICAgICAgIHJldHVybiAweGZmZmY7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChlbGVuID09IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiAweGZmZmY7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICggKCh0bXAgPSB6bXdfcnhfYnVmX3JlYWRiKGRldiwgYnVmLCBvZmZzZXQrMikpID09IDB4MDApCiAgICAgICAgICAgICAgICAgJiYgKCh0bXAgPSB6bXdfcnhfYnVmX3JlYWRiKGRldiwgYnVmLCBvZmZzZXQrMykpID09IDB4MTApCiAgICAgICAgICAgICAgICAgJiYgKCh0bXAgPSB6bXdfcnhfYnVmX3JlYWRiKGRldiwgYnVmLCBvZmZzZXQrNCkpID09IDB4MTgpICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIG9mZnNldDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyogQWR2YW5jZSB0byBuZXh0IGVsZW1lbnQgKi8KICAgICAgICBpZiAoKGVsZW4gPSB6bXdfcnhfYnVmX3JlYWRiKGRldiwgYnVmLCBvZmZzZXQrMSkpID09IDApCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gMHhmZmZmOwogICAgICAgIH0KCiAgICAgICAgb2Zmc2V0ICs9IChlbGVuKzIpOwogICAgfQoKICAgIHJldHVybiAweGZmZmY7Cn0KCnUxNl90IHpmRmluZFJsbmtFeHRDYXAoemRldl90KiBkZXYsIHpidWZfdCogYnVmKQp7CiAgICB1OF90IHN1YlR5cGU7CiAgICB1MTZfdCBvZmZzZXQ7CiAgICB1MTZfdCBidWZMZW47CiAgICB1MTZfdCBlbGVuOwogICAgdThfdCBpZDsKICAgIHU4X3QgdG1wOwoKICAgIC8qIEdldCBvZmZzZXQgb2YgZmlyc3QgZWxlbWVudCAqLwogICAgc3ViVHlwZSA9ICh6bXdfcnhfYnVmX3JlYWRiKGRldiwgYnVmLCAwKSA+PiA0KTsKCiAgICBpZiAoKG9mZnNldCA9IHpnRWxlbWVudE9mZnNldFRhYmxlW3N1YlR5cGVdKSA9PSAweGZmKQogICAgewogICAgICAgIHptX2Fzc2VydCgwKTsKICAgIH0KCiAgICAvKiBQbHVzIHdsYW4gaGVhZGVyICovCiAgICBvZmZzZXQgKz0gMjQ7CgogICAgYnVmTGVuID0gemZ3QnVmR2V0U2l6ZShkZXYsIGJ1Zik7CgogICAgLyogU2VhcmNoIGxvb3AgKi8KICAgIHdoaWxlKChvZmZzZXQrMikgPCBidWZMZW4pICAgICAgICAgICAgICAgICAgIC8vIGluY2x1ZGluZyBlbGVtZW50IElEIGFuZCBsZW5ndGggKDJieXRlcykKICAgIHsKICAgICAgICAvKiBTZWFyY2ggdGFyZ2V0IGVsZW1lbnQgKi8KICAgICAgICBpZiAoKGlkID0gem13X3J4X2J1Zl9yZWFkYihkZXYsIGJ1Ziwgb2Zmc2V0KSkgPT0gMHg3RikKICAgICAgICB7CiAgICAgICAgICAgIC8qIEJpbmdvICovCiAgICAgICAgICAgIGlmICgoZWxlbiA9IHptd19yeF9idWZfcmVhZGIoZGV2LCBidWYsIG9mZnNldCsxKSkgPiAoYnVmTGVuIC0gb2Zmc2V0KSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLyogRWxlbWVudCBsZW5ndGggZXJyb3IgKi8KICAgICAgICAgICAgICAgIHJldHVybiAweGZmZmY7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICggZWxlbiA9PSAwICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIDB4ZmZmZjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCh0bXAgPSB6bXdfcnhfYnVmX3JlYWRiKGRldiwgYnVmLCBvZmZzZXQrMikpID09IDB4MDEpCgogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gb2Zmc2V0OwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKiBBZHZhbmNlIHRvIG5leHQgZWxlbWVudCAqLwogICAgICAgIGlmICgoZWxlbiA9IHptd19yeF9idWZfcmVhZGIoZGV2LCBidWYsIG9mZnNldCsxKSkgPT0gMCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiAweGZmZmY7CiAgICAgICAgfQoKICAgICAgICBvZmZzZXQgKz0gKGVsZW4rMik7CiAgICB9CgogICAgcmV0dXJuIDB4ZmZmZjsKfQo=