LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqDQoqIKkgMjAxNCBNaWNyb2NoaXAgVGVjaG5vbG9neSBJbmMuIGFuZCBpdHMgc3Vic2lkaWFyaWVzLg0KKiBZb3UgbWF5IHVzZSB0aGlzIHNvZnR3YXJlIGFuZCBhbnkgZGVyaXZhdGl2ZXMgZXhjbHVzaXZlbHkgd2l0aA0KKiBNaWNyb2NoaXAgcHJvZHVjdHMuDQoqIFRISVMgU09GVFdBUkUgSVMgU1VQUExJRUQgQlkgTUlDUk9DSElQICJBUyBJUyIuDQoqIE5PIFdBUlJBTlRJRVMsIFdIRVRIRVIgRVhQUkVTUywgSU1QTElFRCBPUiBTVEFUVVRPUlksIEFQUExZIFRPIFRISVMgU09GVFdBUkUsDQoqIElOQ0xVRElORyBBTlkgSU1QTElFRCBXQVJSQU5USUVTIE9GIE5PTi1JTkZSSU5HRU1FTlQsIE1FUkNIQU5UQUJJTElUWSwNCiogQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLCBPUiBJVFMgSU5URVJBQ1RJT04gV0lUSCBNSUNST0NISVANCiogUFJPRFVDVFMsIENPTUJJTkFUSU9OIFdJVEggQU5ZIE9USEVSIFBST0RVQ1RTLCBPUiBVU0UgSU4gQU5ZIEFQUExJQ0FUSU9OLg0KKiBJTiBOTyBFVkVOVCBXSUxMIE1JQ1JPQ0hJUCBCRSBMSUFCTEUgRk9SIEFOWSBJTkRJUkVDVCwgU1BFQ0lBTCwgUFVOSVRJVkUsDQoqIElOQ0lERU5UQUwgT1IgQ09OU0VRVUVOVElBTCBMT1NTLCBEQU1BR0UsIENPU1QgT1IgRVhQRU5TRSBPRiBBTlkgS0lORA0KKiBXSEFUU09FVkVSIFJFTEFURUQgVE8gVEhFIFNPRlRXQVJFLCBIT1dFVkVSIENBVVNFRCwgRVZFTiBJRiBNSUNST0NISVAgSEFTDQoqIEJFRU4gQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT1IgVEhFIERBTUFHRVMgQVJFIEZPUkVTRUVBQkxFLg0KKiBUTyBUSEUgRlVMTEVTVCBFWFRFTlQgQUxMT1dFRCBCWSBMQVcsIE1JQ1JPQ0hJUCdTIFRPVEFMIExJQUJJTElUWSBPTiBBTEwNCiogQ0xBSU1TIElOIEFOWSBXQVkgUkVMQVRFRCBUTyBUSElTIFNPRlRXQVJFIFdJTEwgTk9UIEVYQ0VFRCBUSEUgQU1PVU5UIE9GDQoqIEZFRVMsIElGIEFOWSwgVEhBVCBZT1UgSEFWRSBQQUlEIERJUkVDVExZIFRPIE1JQ1JPQ0hJUCBGT1IgVEhJUyBTT0ZUV0FSRS4NCiogTUlDUk9DSElQIFBST1ZJREVTIFRISVMgU09GVFdBUkUgQ09ORElUSU9OQUxMWSBVUE9OIFlPVVIgQUNDRVBUQU5DRQ0KKiBPRiBUSEVTRSBURVJNUy4NCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLw0KDQoNCi8qKiBAZmlsZSBtZWMxNHh4X2dwaW8uYw0KICpNRUMxNHh4IEdQSU8gaGFyZHdhcmUgYWNjZXNzDQogKi8NCi8qKiBAZGVmZ3JvdXAgTUVDMTR4eCBQZXJpcGhlcmFscyBHUElPDQogKiAgQHsNCiAqLw0KDQoNCiNpbmNsdWRlICJhcHBjZmcuaCINCiNpbmNsdWRlICJwbGF0Zm9ybS5oIg0KI2luY2x1ZGUgIk1FQzE0eHgvbWVjMTR4eC5oIg0KI2luY2x1ZGUgIk1FQzE0eHgvbWVjMTR4eF9ncGlvLmgiDQoNCg0KDQpzdGF0aWMgdWludDMyX3QgZ3Bpb19oYXNfZHJ2X3N0ciAoIGVudW0gZ3Bpb19pZF90IGdwaW9faWQgKTsNCg0KDQojaWZkZWYgRU5BQkxFX0dQSU9fUElOX1ZBTElEQVRJT04NCg0Kc3RhdGljIGNvbnN0IHVpbnQzMl90IGdwaW9fcG9ydF9iaXRtYXBzW05VTV9HUElPX1BPUlRTXSA9IA0Kew0KICAgIChHUElPX1BPUlRfQV9CSVRNQVApLA0KICAgIChHUElPX1BPUlRfQl9CSVRNQVApLA0KICAgIChHUElPX1BPUlRfQ19CSVRNQVApLA0KICAgIChHUElPX1BPUlRfRF9CSVRNQVApDQp9Ow0KDQojZW5kaWYNCg0KLy8gDQovLyBEcml2ZSBTdHJlbmd0aCBSZWdpc3RlciBiaXRtYXANCi8vDQpzdGF0aWMgY29uc3QgdWludDMyX3QgZ3Bpb19kcnZfc3RyX2JpdG1hcFtOVU1fR1BJT19QT1JUU10gPSANCnsNCiAgICAoR1BJT19QT1JUX0FfRFJWU1RSX0JJVE1BUCksDQogICAgKEdQSU9fUE9SVF9CX0RSVlNUUl9CSVRNQVApLA0KICAgIChHUElPX1BPUlRfQ19EUlZTVFJfQklUTUFQKSwNCiAgICAoR1BJT19QT1JUX0RfRFJWU1RSX0JJVE1BUCkNCn07DQoNCg0Kc3RydWN0IGdwaW9fY2ZnIA0Kew0KICAgdWludDE2X3QgYml0X21hc2s7DQogICB1aW50OF90IGJpdF9wb3M7DQp9Ow0KDQpzdGF0aWMgY29uc3Qgc3RydWN0IGdwaW9fY2ZnIGdwaW9fY2ZnX3RibFtHUElPX1BST1BfTUFYXSA9IA0Kew0KICAgeyAweDAwMDN1LCAweDAwdSB9LA0KICAgeyAweDAwMEN1LCAweDAydSB9LA0KICAgeyAweDAwRjB1LCAweDA0dSB9LA0KICAgeyAweDAxMDB1LCAweDA4dSB9LA0KICAgeyAweDAyMDB1LCAweDA5dSB9LA0KICAgeyAweDA0MDB1LCAweDBBdSB9LA0KICAgeyAweDA4MDB1LCAweDBCdSB9LA0KICAgeyAweDMwMDB1LCAweDBDdSB9LA0KICAgeyAweDNGRkZ1LCAweDAwdSB9DQp9Ow0KDQpzdGF0aWMgdWludDMyX3QgZ3Bpb19waW5fY3RybF9hZGRyKGVudW0gZ3Bpb19pZF90IGdwaW9faWQpDQp7DQogICAgcmV0dXJuICgodWludDMyX3QpKEdQSU9fQkFTRSkgKyAodWludDMyX3QpKGdwaW9faWQgPDwgMikpOw0KfQ0KDQojaWZkZWYgRU5BQkxFX0dQSU9fUElOX1ZBTElEQVRJT04NCg0KLyoqDQogKiBncGlvX2lzX3ZhbGlkIC0gbG9jYWwgaGVscGVyIGNoZWNrcyBpZiBHUElPIHBpbiBpcyANCiAqIGltcGxlbWVudGVkIGluIHRoaXMgaGFyZHdhcmUuIA0KICogDQogKiBAYXV0aG9yIHN3b3JsZXkgDQogKiANCiAqIEBwYXJhbSBncGlvX2lkIDAtYmFzZWQgR1BJTyBJRA0KICogDQogKiBAcmV0dXJuIHVpbnQ4X3QgTm9uLXplcm8oR1BJTyBQaW4gaW1wbGVtZW50ZWQpLCAwKG5vdCANCiAqICAgICAgICAgaW1wbGVtZW50ZWQpLg0KICovDQpzdGF0aWMgdWludDhfdCBncGlvX2lzX3ZhbGlkICggZW51bSBncGlvX2lkX3QgZ3Bpb19pZCApDQp7DQogICB1aW50MTZfdCBncF9iYW5rOw0KDQogICBncF9iYW5rID0gMDsNCg0KICAgaWYgKCAodWludDE2X3QpZ3Bpb19pZCA8ICh1aW50MTZfdCkoTUFYX0dQSU9fSUQpICkNCiAgIHsNCiAgICAgIGdwX2JhbmsgPSAodWludDE2X3QpZ3Bpb19pZCA+PiA1Ow0KICAgICAgaWYgKCBncGlvX3BvcnRfYml0bWFwc1tncF9iYW5rXSAmICgxIDw8IChncGlvX2lkICYgMHgwMDFGdSkpICkNCiAgICAgIHsgDQogICAgICAgICByZXR1cm4gdHJ1ZTsNCiAgICAgIH0NCiAgIH0NCg0KICAgcmV0dXJuIGZhbHNlOw0KfQ0KDQojZWxzZQ0Kc3RhdGljIHVpbnQzMl90IGdwaW9faXNfdmFsaWQoZW51bSBncGlvX2lkX3QgZ3Bpb19pZCkgeyByZXR1cm4gdHJ1ZTsgfQ0KDQojZW5kaWYNCg0Kc3RhdGljIHVpbnQ4X3QgZ3Bpb19iYW5rX251bShlbnVtIGdwaW9faWRfdCBncGlvX2lkKQ0Kew0KICAgIHJldHVybiAodWludDhfdCkoZ3Bpb19pZCkgPj4gNTsNCn0NCg0KDQpzdGF0aWMgdWludDhfdCBncGlvX3Bpbl9udW0oZW51bSBncGlvX2lkX3QgZ3Bpb19pZCkNCnsNCiAgICByZXR1cm4gKHVpbnQ4X3QpKGdwaW9faWQpICYgMHgxRnU7DQp9DQoNCg0KLyoqDQogKiBncGlvX2hhc19kcnZfc3RyIC0gTG9jYWwgaGVscGVyIHRvIGNoZWNrIGlmIEdQSU8gcGluIGhhcyANCiAqIGFzc29jaWF0ZWQgZHJpdmUgc3RyZW5ndGggcmVnaXN0ZXIuIA0KICogDQogKiBAYXV0aG9yIHN3b3JsZXkgDQogKiANCiAqIEBwYXJhbSBncGlvX2lkIDAtYmFzZWQgR1BJTyBJRA0KICogDQogKiBAcmV0dXJuIHVpbnQzMl90IDAoTm8gRHJpdmUgU3RyZW5ndGgpLCBOb24temVybyhQaHlzaWNhbCANCiAqICAgICAgICAgYWRkcmVzcyBvZiBEcml2ZSBTdHJlbmd0aCBSZWdpc3RlcikuDQogKi8NCnN0YXRpYyB1aW50MzJfdCBncGlvX2hhc19kcnZfc3RyICggZW51bSBncGlvX2lkX3QgZ3Bpb19pZCApDQp7DQogICAgdWludDMyX3QgYmFuaywgYml0cG9zLCBhZGRyOw0KICAgIA0KICAgIGFkZHIgPSAwdWw7DQogICAgaWYgKCBncGlvX2lkIDwgTUFYX0dQSU9fSUQgKQ0KICAgIHsNCiAgICAgICAgYmFuayA9IGdwaW9fYmFua19udW0oZ3Bpb19pZCk7DQogICAgICAgIGJpdHBvcyA9IGdwaW9fcGluX251bShncGlvX2lkKTsNCiAgICAgICAgaWYgKCBncGlvX2Rydl9zdHJfYml0bWFwW2JhbmtdICYgKDF1bCA8PCBiaXRwb3MpICkNCiAgICAgICAgew0KICAgICAgICAgICAgYWRkciA9IChHUElPX1BDVFJMMl9CQVNFKSArICgodWludDMyX3QpKGdwaW9faWQpIDw8IDIpOw0KICAgICAgICAgICAgaWYgKCBncGlvX2lkID4gR1BJT18wMDc3X0lEICkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBhZGRyIC09IDB4MjB1bDsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgIH0NCiAgICANCiAgICByZXR1cm4gYWRkcjsNCn0NCg0KDQp1aW50MTZfdCBHUElPR2V0Q29uZmlnKGVudW0gZ3Bpb19pZF90IGdwaW9faWQpDQp7DQogICAgaWYgKGdwaW9faXNfdmFsaWQoZ3Bpb19pZCkpIHsNCiAgICAgICAgcmV0dXJuICAqKCh2b2xhdGlsZSB1aW50MTZfdCAqKWdwaW9fcGluX2N0cmxfYWRkcihncGlvX2lkKSk7DQogICAgfSBlbHNlIHsNCiAgICAgICAgcmV0dXJuIDB1Ow0KICAgIH0NCn0NCg0KDQp2b2lkIEdQSU9TZXRDb25maWcoZW51bSBncGlvX2lkX3QgZ3Bpb19pZCwgdWludDE2X3QgY29uZmlnKQ0Kew0KICAgIHZvbGF0aWxlIHVpbnQxNl90ICogcDsNCiAgICANCiAgICBpZiAoZ3Bpb19pc192YWxpZChncGlvX2lkKSkgew0KICAgICAgICBwID0gKHZvbGF0aWxlIHVpbnQxNl90ICopZ3Bpb19waW5fY3RybF9hZGRyKGdwaW9faWQpOw0KICAgICAgICAqcCA9IGNvbmZpZzsNCiAgICB9DQp9DQoNCg0Kdm9pZCBHUElPQ29uZmlnQW5kT3IoZW51bSBncGlvX2lkX3QgZ3Bpb19pZCwgdWludDE2X3QgYW5kX21hc2ssIHVpbnQxNl90IG9yX21hc2spDQp7DQogICAgdm9sYXRpbGUgdWludDE2X3QgKiBwOw0KDQoNCiAgICBpZiAoZ3Bpb19pc192YWxpZChncGlvX2lkKSkgew0KICAgICAgICBwID0gKHZvbGF0aWxlIHVpbnQxNl90ICopZ3Bpb19waW5fY3RybF9hZGRyKGdwaW9faWQpOw0KICAgICAgICAqcCA9ICgqcCAmIGFuZF9tYXNrKSB8IG9yX21hc2s7DQogICAgfQ0KfQ0KDQoNCnVpbnQzMl90IEdQSU9HZXRDb250cm9sKGVudW0gZ3Bpb19pZF90IGdwaW9faWQpDQp7DQogICAgaWYgKGdwaW9faXNfdmFsaWQoZ3Bpb19pZCkpIHsNCiAgICAgICAgcmV0dXJuICooKHZvbGF0aWxlIHVpbnQzMl90ICopZ3Bpb19waW5fY3RybF9hZGRyKGdwaW9faWQpKTsNCiAgICB9IGVsc2Ugew0KICAgICAgICByZXR1cm4gMHhGRkZGRkZGRnVsOw0KICAgIH0NCn0NCg0KDQp2b2lkIEdQSU9TZXRDb250cm9sKGVudW0gZ3Bpb19pZF90IGdwaW9faWQsIHVpbnQzMl90IGN0cmxfdmFsKQ0Kew0KICAgIHZvbGF0aWxlIHVpbnQzMl90ICogcDsNCiAgICANCiAgICBpZiAoZ3Bpb19pc192YWxpZChncGlvX2lkKSkgew0KICAgICAgICBwID0gKHZvbGF0aWxlIHVpbnQzMl90ICopZ3Bpb19waW5fY3RybF9hZGRyKGdwaW9faWQpOw0KICAgICAgICAqcCA9IGN0cmxfdmFsOw0KICAgIH0NCn0NCg0KDQp2b2lkIEdQSU9Db250cm9sQW5kT3IoZW51bSBncGlvX2lkX3QgZ3Bpb19pZCwgdWludDMyX3QgYW5kX21hc2ssIHVpbnQzMl90IG9yX21hc2spDQp7DQogICAgdm9sYXRpbGUgdWludDMyX3QgKiBwOw0KDQogICAgaWYgKGdwaW9faXNfdmFsaWQoZ3Bpb19pZCkpIHsNCiAgICAgICAgcCA9ICh2b2xhdGlsZSB1aW50MzJfdCAqKWdwaW9fcGluX2N0cmxfYWRkcihncGlvX2lkKTsNCiAgICAgICAgKnAgPSAoKnAgJiBhbmRfbWFzaykgfCBvcl9tYXNrOw0KICAgIH0NCn0NCg0KDQovKioNCiAqIEdQSU9Qcm9wZXJ0eVNldCAtIFByb2dyYW0gc3BlY2lmaWVkIEdQSU8gUGluIGNvbmZpZ3VyYXRpb24gDQogKiBpdGVtLiANCiAqIA0KICogQGF1dGhvciBzd29ybGV5IA0KICogDQogKiBAcGFyYW0gZ3Bpb19pZCAwLWJhc2VkIEdQSU8gSUQNCiAqIEBwYXJhbSBncGlvX3Byb3AgZW51bWVyYXRlZCBHUElPIFByb3BlcnR5KGNvbmZpZ3VyYXRpb24gaXRlbSkNCiAqIEBwYXJhbSBwcm9wX3ZhbCBuZXcgcHJvcGVydHkgdmFsdWUNCiAqLw0Kdm9pZCBHUElPUHJvcGVydHlTZXQgKCBlbnVtIGdwaW9faWRfdCBncGlvX2lkLCANCiAgICAgICAgICAgICAgICAgICAgICAgZW51bSBncGlvX3Byb3BfdCBncGlvX3Byb3AsDQogICAgICAgICAgICAgICAgICAgICAgIHVpbnQxNl90IHByb3BfdmFsDQogICAgICAgICAgICAgICAgICAgICApDQp7DQogICAgdm9sYXRpbGUgdWludDE2X3QgKiBwOw0KICAgIHVpbnQxNl90IGdwX2NmZzsNCiAgDQogICAgZ3BfY2ZnID0gMHU7DQoNCiAgICBpZiAoIGdwaW9faXNfdmFsaWQoZ3Bpb19pZCkgJiYgKCh1aW50MTZfdClncGlvX3Byb3AgPCAodWludDE2X3QpR1BJT19QUk9QX01BWCkgKQ0KICAgIHsNCiAgICAgICAgcCA9ICh2b2xhdGlsZSB1aW50MTZfdCAqKWdwaW9fcGluX2N0cmxfYWRkcihncGlvX2lkKTsNCiAgICAgICAgZ3BfY2ZnID0gKnA7DQogICAgICAgIGdwX2NmZyAmPSB+KGdwaW9fY2ZnX3RibFtncGlvX3Byb3BdLmJpdF9tYXNrKTsNCiAgICAgICAgZ3BfY2ZnIHw9IChwcm9wX3ZhbCA8PCBncGlvX2NmZ190YmxbZ3Bpb19wcm9wXS5iaXRfcG9zKSAmIA0KICAgICAgICAgICAgICAgICAgZ3Bpb19jZmdfdGJsW2dwaW9fcHJvcF0uYml0X21hc2s7IA0KICAgICAgICAqcCA9IGdwX2NmZzsNCiAgICB9DQp9DQoNCg0KLyoqDQogKiBHUElPR2V0U2xld1JhdGUgLSBSZXR1cm4gR1BJTyBQaW4gU2xldyBSYXRlDQogKiANCiAqIEBhdXRob3Igc3dvcmxleSANCiAqIA0KICogQHBhcmFtIGdwaW9faWQgMC1iYXNlZCBHUElPIElEDQogKiANCiAqIEByZXR1cm4gdWludDhfdCBHUElPIFBpbiBTbGV3IFJhdGU6IDAoU2xvdykgb3IgMShGYXN0KQ0KICovDQp1aW50OF90IEdQSU9HZXRTbGV3UmF0ZSggZW51bSBncGlvX2lkX3QgZ3Bpb19pZCApDQp7DQogICAgdWludDMyX3QgYWRkcjsNCiAgICB1aW50OF90IHNsZXc7DQogICAgDQogICAgYWRkciA9IGdwaW9faGFzX2Rydl9zdHIoZ3Bpb19pZCk7DQogICAgaWYgKCAwdWwgIT0gYWRkciApDQogICAgew0KICAgICAgICBzbGV3ID0gKCgqKHZvbGF0aWxlIHVpbnQ4X3QgKilhZGRyKSA+PiBHUElPX0RSVl9TTEVXX0JJVFBPUykgJiAweDAxdTsNCiAgICB9DQogICAgZWxzZQ0KICAgIHsNCiAgICAgICAgc2xldyA9IDB1Ow0KICAgIH0NCiAgICANCiAgICByZXR1cm4gc2xldzsNCn0NCg0KDQovKioNCiAqIEdQSU9TZXRTbGV3UmF0ZSAtIFByb2dyYW0gR1BJTyBQaW4ncyBTbGV3IFJhdGUNCiAqIA0KICogQGF1dGhvciBzd29ybGV5IA0KICogDQogKiBAcGFyYW0gZ3Bpb19pZCAwLWJhc2VkIEdQSU8gSUQNCiAqIEBwYXJhbSBzbGV3X3JhdGUgbmV3IHNsZXcgcmF0ZTogMChTbG93KSwgTm9uLXplcm8oRmFzdCkNCiAqLw0Kdm9pZCBHUElPU2V0U2xld1JhdGUgKCBlbnVtIGdwaW9faWRfdCBncGlvX2lkLA0KICAgICAgICAgICAgICAgICAgICAgICBlbnVtIGdwaW9fc2xld19yYXRlX3Qgc2xld19yYXRlICkNCnsNCiAgICB1aW50MzJfdCBhZGRyOw0KICAgIA0KICAgIGFkZHIgPSBncGlvX2hhc19kcnZfc3RyKGdwaW9faWQgKTsNCiAgICBpZiAoIGFkZHIgKQ0KICAgIHsNCiAgICAgICAgKih2b2xhdGlsZSB1aW50OF90ICopYWRkciA9ICgqKHZvbGF0aWxlIHVpbnQ4X3QgKilhZGRyICYgDQogICAgICAgICAgICB+KEdQSU9fRFJWX1NMRVdfTUFTSykpIHwgDQogICAgICAgICAgICAoKHNsZXdfcmF0ZSA8PCAoR1BJT19EUlZfU0xFV19CSVRQT1MpKSAmIChHUElPX0RSVl9TTEVXX01BU0spKTsNCiAgICB9DQp9DQoNCg0KLyoqDQogKiBHUElPR2V0RHJpdmVTdHIgLSBHZXQgR1BJTyBQaW4ncyBEcml2ZSBTdHJlbmd0aCANCiAqIA0KICogQGF1dGhvciBzd29ybGV5IA0KICogDQogKiBAcGFyYW0gZ3Bpb19pZCAwLWJhc2VkIEdQSU8gSUQNCiAqIA0KICogQHJldHVybiB1aW50OF90IFBpbiBEcml2ZSBTdHJlbmd0aDogMD0ybUEsIDE9NG1BLCAyPThtQSwgDQogKiAgICAgICAgIDM9MTJtQS4NCiAqLw0KdWludDhfdCBHUElPR2V0RHJpdmVTdHIgKCBlbnVtIGdwaW9faWRfdCBncGlvX2lkICkNCnsNCiAgICB1aW50MzJfdCBhZGRyOw0KICAgIA0KICAgIGFkZHIgPSBncGlvX2hhc19kcnZfc3RyKGdwaW9faWQgKTsNCiAgICBpZiAoIGFkZHIgKQ0KICAgIHsNCiAgICAgICAgcmV0dXJuICgoKih2b2xhdGlsZSB1aW50OF90ICopYWRkcikgPj4gR1BJT19EUlZfU1RSX0JJVFBPUykgJiAoR1BJT19EUlZfU1RSX01BU0spOw0KICAgIH0NCiAgICBlbHNlDQogICAgew0KICAgICAgICByZXR1cm4gMHU7DQogICAgfQ0KfQ0KDQoNCi8qKg0KICogR1BJT1NldERyaXZlU3RyIC0gUHJvZ3JhbSBHUElPIFBpbidzIERyaXZlIFN0cmVuZ3RoDQogKiANCiAqIEBhdXRob3Igc3dvcmxleSANCiAqIA0KICogQHBhcmFtIGdwaW9faWQgMC1iYXNlZCBHUElPIElEDQogKiBAcGFyYW0gZHJ2X3N0ciBlbnVtZXJhdGVkIGRyaXZlIHN0cmVuZ3RoOiAwPTJtQSwgMT00bUEsIA0KICogICAgICAgICAgICAgICAgMj04bUEsIDM9MTJtQQ0KICovDQp2b2lkIEdQSU9TZXREcml2ZVN0ciAoIGVudW0gZ3Bpb19pZF90IGdwaW9faWQsDQogICAgICAgICAgICAgICAgICAgICAgIGVudW0gZ3Bpb19kcnZfc3RyX3QgZHJ2X3N0ciApDQp7DQogICAgdWludDMyX3QgYWRkcjsNCiAgICB1aW50OF90IHI4Ow0KICAgIA0KICAgIGFkZHIgPSBncGlvX2hhc19kcnZfc3RyKGdwaW9faWQpOw0KICAgIGlmICggYWRkciApDQogICAgew0KICAgICAgICByOCA9ICoodm9sYXRpbGUgdWludDhfdCAqKWFkZHIgJiB+KEdQSU9fRFJWX1NUUl9NQVNLKTsNCiAgICAgICAgcjggKz0gKChkcnZfc3RyIDw8IEdQSU9fRFJWX1NUUl9CSVRQT1MpICYgR1BJT19EUlZfU1RSX01BU0spOw0KICAgICAgICAqKHZvbGF0aWxlIHVpbnQ4X3QgKilhZGRyID0gcjg7DQogICAgfQ0KfQ0KDQoNCi8qKg0KICogR1BJT0dldERyaXZlU3RyQW5kU2xldyAtIFJldHVybiBjb21iaW5lZCB2YWx1ZSByZXByZXNlbnRpbmcgDQogKiBEcml2ZSBTdHJlbmd0aCBhbmQgU2xldyBSYXRlLiANCiAqIA0KICogQGF1dGhvciBzd29ybGV5IA0KICogDQogKiBAcGFyYW0gZ3Bpb19pZCAwLWJhc2VkIEdQSU8gSUQNCiAqIA0KICogQHJldHVybiB1aW50OF90IGJpdFswXSA9IFNsZXcgUmF0ZSwgYml0c1szOjFdPTAoUmVzZXJ2ZWQpLCANCiAqICAgICAgICAgYml0c1s1OjRdPURyaXZlIFN0cmVuZ3RoLCBiaXRzWzc6Nl09MChSZXNlcnZlZCkNCiAqLw0KdWludDhfdCBHUElPR2V0RHJpdmVTdHJBbmRTbGV3ICggZW51bSBncGlvX2lkX3QgZ3Bpb19pZCApDQp7DQogICAgdWludDMyX3QgYWRkcjsNCiAgICANCiAgICBhZGRyID0gZ3Bpb19oYXNfZHJ2X3N0cihncGlvX2lkICk7DQogICAgaWYgKCBhZGRyICkNCiAgICB7DQogICAgICAgIHJldHVybiAoKih2b2xhdGlsZSB1aW50OF90ICopYWRkcik7DQogICAgfQ0KICAgIGVsc2UNCiAgICB7DQogICAgICAgIHJldHVybiAwdTsNCiAgICB9DQp9DQoNCg0KLyoqDQogKiBHUElPU2V0RHJpdmVTdHJBbmRTbGV3IC0gUHJvZ3JhbSBHUElPIFBpbidzIGRyaXZlIHN0cmVuZ3RoIA0KICogYW5kIHNsZXcgcmF0ZS4gDQogKiANCiAqIEBhdXRob3Igc3dvcmxleSANCiAqIA0KICogQHBhcmFtIGdwaW9faWQgMC1iYXNlZCBHUElPIElEDQogKiBAcGFyYW0gZHJ2X2FuZF9zbGV3IGJpdFswXSA9IFNsZXcgUmF0ZSwgYml0c1szOjFdPTAoUmVzZXJ2ZWQpLCANCiAqICAgICAgICAgYml0c1s1OjRdPURyaXZlIFN0cmVuZ3RoLCBiaXRzWzc6Nl09MChSZXNlcnZlZCkNCiAqLw0Kdm9pZCBHUElPU2V0RHJpdmVTdHJBbmRTbGV3ICggZW51bSBncGlvX2lkX3QgZ3Bpb19pZCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQ4X3QgZHJ2X2FuZF9zbGV3ICkNCnsNCiAgICB1aW50MzJfdCBhZGRyOw0KICAgIHVpbnQ4X3Qgcjg7DQogICAgDQogICAgYWRkciA9IGdwaW9faGFzX2Rydl9zdHIoZ3Bpb19pZCk7DQogICAgaWYgKCBhZGRyICkNCiAgICB7DQogICAgICAgIHI4ID0gKih2b2xhdGlsZSB1aW50OF90ICopYWRkciAmIH4oR1BJT19EUlZfU0xFV19NQVNLICsgR1BJT19EUlZfU1RSX01BU0spOw0KICAgICAgICByOCB8PSAoZHJ2X2FuZF9zbGV3ICYgKEdQSU9fRFJWX1NMRVdfTUFTSyArIEdQSU9fRFJWX1NUUl9NQVNLKSk7DQogICAgICAgICoodm9sYXRpbGUgdWludDhfdCAqKWFkZHIgPSByODsNCiAgICB9DQp9DQoNCg0KLyoqDQogKiBHUElPU2V0T3V0cHV0IC0gUHJvZ3JhbSBHUElPIFBpbidzIG91dHB1dCBzdGF0ZSB1c2luZyBQaW4gDQogKiBjb25maWd1cmF0aW9uIHJlZ2lzdGVyIChub3QgcGFyYWxsZWwgb3V0cHV0IHJlZ2lzdGVyKS4gDQogKiANCiAqIEBhdXRob3Igc3dvcmxleSANCiAqIA0KICogQHBhcmFtIGdwaW9faWQgMC1iYXNlZCBHUElPIElEDQogKiBAcGFyYW0gZ3Bpb19zdGF0ZSBwaW4gc3RhdGU6IGFjdHVhbCBwaW4gc3RhdGUgYXQgcGFkIHdpbGwgDQogKiAgICAgICAgICAgICAgICAgICBkZXBlbmQgdXBvbiBHUElPIE91dHB1dCBpbnZlcnQNCiAqICAgICAgICAgICAgICAgICAgIGNvbmZpZ3VyYXRpb24uDQogKiBAbm90ZSBwZWZvcm1zIGEgYnl0ZSB3aWRlIHdyaXRlIHRvIGJ5dGUgb2Zmc2V0IDIgb2YgdGhlIEdQSU8gDQogKiAgICAgICBQaW4ncyAzMi1iaXQgY29uZmlndXJhdGlvbiByZWdpc3Rlci4gTm8NCiAqICAgICAgIHJlYWQtbW9kaWZ5LXdyaXRlLg0KICovDQp2b2lkIEdQSU9TZXRPdXRwdXQgKCBlbnVtIGdwaW9faWRfdCBncGlvX2lkLCANCiAgICAgICAgICAgICAgICAgICAgIHVpbnQ4X3QgZ3Bpb19zdGF0ZQ0KICAgICAgICAgICAgICAgICAgICAgKQ0Kew0KICAgIHZvbGF0aWxlIHVpbnQ4X3QgKiBwOw0KICAgIA0KICAgIGlmICggZ3Bpb19pc192YWxpZChncGlvX2lkKSApDQogICAgew0KICAgICAgICBwID0gKHZvbGF0aWxlIHVpbnQ4X3QgKikoZ3Bpb19waW5fY3RybF9hZGRyKGdwaW9faWQpICsgMnVsKTsNCiAgICAgICAgaWYgKGdwaW9fc3RhdGUpIHsNCiAgICAgICAgICAgICpwID0gMHgwMXU7DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAqcCA9IDB1Ow0KICAgICAgICB9DQogICAgfQ0KfQ0KDQoNCnZvaWQgR1BJT1RvZ2dsZU91dHB1dCAoIGVudW0gZ3Bpb19pZF90IGdwaW9faWQgKQ0Kew0KICAgIHZvbGF0aWxlIHVpbnQ4X3QgKiBwOw0KDQogICAgaWYgKCBncGlvX2lzX3ZhbGlkKGdwaW9faWQpICkNCiAgICB7DQogICAgICAgIHAgPSAodm9sYXRpbGUgdWludDhfdCAqKShncGlvX3Bpbl9jdHJsX2FkZHIoZ3Bpb19pZCkgKyAydWwpOw0KICAgICAgICAqcCBePSAweDAxdTsNCiAgICB9DQp9DQoNCg0KLyoqDQogKiBHUElPUmVhZFBpbiAtIFJlYWQgR1BJTyBQaW4ncyBQYWQgSW5wdXQgZnJvbSBjb25maWd1cmF0aW9uIA0KICogcmVnaXN0ZXIuIA0KICogDQogKiBAYXV0aG9yIHN3b3JsZXkgDQogKiANCiAqIEBwYXJhbSBncGlvX2lkIDAtYmFzZWQgR1BJTyBJRC4NCiAqIA0KICogQHJldHVybiB1aW50OF90IDAgb3IgMSBkZXBlbmRpbmcgdXBvbiB0aGUgc3RhdGUgb2YgdGhlIEdQSU8gDQogKiAgICAgICAgIHBhZC4NCiAqIEBub3RlIHBlcmZvcm1zIGEgYnl0ZSByZWFkIG9mIG9mZnNldCAzIG9mIHRoZSBHUElPIFBpbidzIA0KICogICAgICAgMzItYml0IGNvbmZpZ3VyYXRpb24gcmVnaXN0ZXIuDQogKi8NCnVpbnQ4X3QgR1BJT1JlYWRQaW4oIGVudW0gZ3Bpb19pZF90IGdwaW9faWQgKQ0Kew0KICAgIGlmICggZ3Bpb19pc192YWxpZChncGlvX2lkKSApDQogICAgew0KICAgICAgICByZXR1cm4gKigodm9sYXRpbGUgdWludDhfdCAqKShncGlvX3Bpbl9jdHJsX2FkZHIoZ3Bpb19pZCkgKyAzdWwpKTsNCiAgICB9IA0KICAgIGVsc2UgDQogICAgew0KICAgICAgICByZXR1cm4gMHU7DQogICAgfQ0KfQ0KDQoNCi8qKiBHUElPUGluTG9jayAtIExvY2sgc3BlY2lmaWVkIEdQSU8ncyBjb250cm9sIHJlZ2lzdGVyLg0KICogIEBwYXJhbSBlbnVtIGdwaW9faWRfdCB6ZXJvIGJhc2VkIEdQSU8gSUQNCiAqICBAbm90ZSBMb2NrIGJpdCBpcyBvbmx5IGNsZWFyZWQgb24gUE9SLiBMb2NrIHJlZ2lzdGVycw0KICogIGFyZSBpbiByZXZlcnNlIG9yZGVyLCBmaXJzdCByZWdpc3RlciBpcyBhdCB0b3AgYWRkcmVzcy4NCiAqICBHUElPX0xPQ0tfQkFTRSBkZWZpbmVkIHRvIHRvcChmaXJzdCkgcmVnaXN0ZXIgYWRkcmVzcy4NCiAqICAqLyANCnZvaWQgR1BJT1BpbkxvY2soZW51bSBncGlvX2lkX3QgZ3Bpb19pZCkNCnsNCiAgICB1aW50MzJfdCBhZGRyOw0KICAgIHVpbnQ4X3QgYmFuaywgYml0cG9zOw0KDQogICAgaWYgKGdwaW9faXNfdmFsaWQoZ3Bpb19pZCkpIHsNCiAgICAgICAgYmFuayA9IGdwaW9fYmFua19udW0oZ3Bpb19pZCk7ICAvLyAwIC0gNA0KICAgICAgICBiaXRwb3MgPSBncGlvX3Bpbl9udW0oZ3Bpb19pZCk7IC8vIDAgLSAzMQ0KICAgICAgICBhZGRyID0gKHVpbnQzMl90KShHUElPX0xPQ0tfQkFTRSkgLSAoYmFuayA8PCAyKTsNCiAgICAgICAgKih2b2xhdGlsZSB1aW50MzJfdCAqKWFkZHIgfD0gKDF1bCA8PCBiaXRwb3MpOw0KICAgIH0gDQp9DQoNCg0KLyogZW5kIG1lYzE0eHhfZ3Bpby5jICovDQovKiogICBAfQ0KICovDQoNCg==