LyoKICogdGFibGVfaXRlcmF0b3IuYyAKICovCi8qIFBvcnRpb25zIG9mIHRoaXMgZmlsZSBhcmUgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvcHlyaWdodChzKS4gIFNlZQogKiB0aGUgTmV0LVNOTVAncyBDT1BZSU5HIGZpbGUgZm9yIG1vcmUgZGV0YWlscyBhbmQgb3RoZXIgY29weXJpZ2h0cwogKiB0aGF0IG1heSBhcHBseToKICovCi8qCiAqIFBvcnRpb25zIG9mIHRoaXMgZmlsZSBhcmUgY29weXJpZ2h0ZWQgYnk6CiAqIENvcHlyaWdodCCpIDIwMDMgU3VuIE1pY3Jvc3lzdGVtcywgSW5jLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBVc2UgaXMgc3ViamVjdCB0byBsaWNlbnNlIHRlcm1zIHNwZWNpZmllZCBpbiB0aGUgQ09QWUlORyBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhlIE5ldC1TTk1QIHBhY2thZ2UuCiAqLwoKLyoqIEBkZWZncm91cCB0YWJsZV9pdGVyYXRvciB0YWJsZV9pdGVyYXRvcgogKiAgVGhlIHRhYmxlIGl0ZXJhdG9yIGhlbHBlciBpcyBkZXNpZ25lZCB0byBzaW1wbGlmeSB0aGUgdGFzayBvZiB3cml0aW5nIGEgdGFibGUgaGFuZGxlciBmb3IgdGhlIG5ldC1zbm1wIGFnZW50IHdoZW4gdGhlIGRhdGEgYmVpbmcgYWNjZXNzZWQgaXMgbm90IGluIGFuIG9pZCBzb3J0ZWQgZm9ybSBhbmQgbXVzdCBiZSBhY2Nlc3NlZCBleHRlcm5hbGx5LgogKiAgQGluZ3JvdXAgdGFibGUKICAgIEZ1bmN0aW9uYWxseSwgaXQgaXMgYSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIHRoZSBtb3JlCiAgICBnZW5lcmljIHRhYmxlIGhlbHBlciBidXQgZWFzaWVzIHRoZSBidXJkZW4gb2YgR0VUTkVYVCBwcm9jZXNzaW5nIGJ5CiAgICBtYW51YWxseSBsb29waW5nIHRocm91Z2ggYWxsIHRoZSBkYXRhIGluZGV4ZXMgcmV0cmlldmVkIHRocm91Z2gKICAgIGZ1bmN0aW9uIGNhbGxzIHdoaWNoIHNob3VsZCBiZSBzdXBwbGllZCBieSB0aGUgbW9kdWxlIHRoYXQgd2lzaGVzCiAgICBoZWxwLiAgVGhlIG1vZHVsZSB0aGUgdGFibGVfaXRlcmF0b3IgaGVscHMgc2hvdWxkLCBhZnRlcndhcmRzLAogICAgbmV2ZXIgYmUgY2FsbGVkIGZvciB0aGUgY2FzZSBvZiAiTU9ERV9HRVRORVhUIiBhbmQgb25seSBmb3IgdGhlIEdFVAogICAgYW5kIFNFVCByZWxhdGVkIG1vZGVzIGluc3RlYWQuCiAKICAgIFRoZSBmdW5kYW1lbnRhbCBub3Rpb24gYmV0d2VlbiB0aGUgdGFibGUgaXRlcmF0b3IgaXMgdGhhdCBpdAogICAgYWxsb3dzIHlvdXIgY29kZSB0byBpdGVyYXRlIG92ZXIgZWFjaCAicm93IiB3aXRoaW4geW91ciBkYXRhCiAgICBzdG9yYWdlIG1lY2hhbmlzbSwgd2l0aG91dCByZXF1aXJpbmcgdGhhdCBpdCBiZSBzb3J0ZWQgaW4gYQogICAgU05NUC1pbmRleC1jb21wbGlhbnQgbWFubmVyLiAgVGhyb3VnaCB0aGUgZ2V0X2ZpcnN0X2RhdGFfcG9pbnQgYW5kCiAgICBnZXRfbmV4dF9kYXRhX3BvaW50IGhvb2tzLCB0aGUgdGFibGVfaXRlcmF0b3IgaGVscGVyIHdpbGwKICAgIHJlcGVhdGVkbHkgY2FsbCB5b3VyIGhvb2tzIHRvIGZpbmQgdGhlICJwcm9wZXIiIHJvdyBvZiBkYXRhIHRoYXQKICAgIG5lZWRzIHByb2Nlc3NpbmcuICBUaGUgZm9sbG93aW5nIGNvbmNlcHRzIGFyZSBpbXBvcnRhbnQ6CgogICAgICAtIEEgbG9vcCBjb250ZXh0IGlzIGEgcG9pbnRlciB3aGljaCBpbmRpY2F0ZXMgd2hlcmUgaW4gdGhlCiAgICAgICAgY3VycmVudCBwcm9jZXNzaW5nIG9mIGEgc2V0IG9mIHJvd3MgeW91IGN1cnJlbnRseSBhcmUuICBBbGxvd3MKCXRoZSBnZXRfKl9kYXRhX3BvaW50IHJvdXRpbmVzIHRvIG1vdmUgZnJvbSBvbmUgcm93IHRvIHRoZSBuZXh0LAoJb25jZSB0aGUgaXRlcmF0b3IgaGFuZGxlciBoYXMgaWRlbnRpZmllZCB0aGUgYXBwcm9wcmlhdGUgcm93IGZvcgoJdGhpcyByZXF1ZXN0LCB0aGUgam9iIG9mIHRoZSBsb29wIGNvbnRleHQgaXMgZG9uZS4gIFRoZQogICAgICAgIG1vc3Qgc2ltcGxlIGV4YW1wbGUgd291bGQgYmUgYSBwb2ludGVyIHRvIGFuIGludGVnZXIgd2hpY2gKICAgICAgICBzaW1wbHkgY291bnRzIHJvd3MgZnJvbSAxIHRvIFguICBNb3JlIGNvbW1vbmx5LCBpdCBtaWdodCBiZSBhCiAgICAgICAgcG9pbnRlciB0byBhIGxpbmtlZCBsaXN0IG5vZGUsIG9yIHNvbWVvdGhlciBpbnRlcm5hbCBvcgogICAgICAgIGV4dGVybmFsIHJlZmVyZW5jZSB0byBhIGRhdGEgc2V0IChmaWxlIHNlZWsgdmFsdWUsIGFycmF5CiAgICAgICAgcG9pbnRlciwgLi4uKS4gIElmIGFsbG9jYXRlZCBkdXJpbmcgaXRlcmF0aW9uLCBlaXRoZXIgdGhlCiAgICAgICAgZnJlZV9sb29wX2NvbnRleHRfYXRfZW5kIChwcmVmZXJhYmx5KSBvciB0aGUgZnJlZV9sb29wX2NvbnRleHQKICAgICAgICBwb2ludGVycyBzaG91bGQgYmUgc2V0LgoKICAgICAgLSBBIGRhdGEgY29udGV4dCBpcyBzb21ldGhpbmcgdGhhdCB5b3VyIGhhbmRsZXIgY29kZSBjYW4gdXNlCiAgICAgICAgaW4gb3JkZXIgdG8gcmV0cmlldmUgdGhlIHJlc3Qgb2YgdGhlIGRhdGEgZm9yIHRoZSBuZWVkZWQKICAgICAgICByb3cuICBUaGlzIGRhdGEgY2FuIGJlIGFjY2Vzc2VkIGluIHlvdXIgaGFuZGxlciB2aWEKCW5ldHNubXBfZXh0cmFjdF9pdGVyYXRvcl9jb250ZXh0IGFwaSB3aXRoIHRoZSBuZXRzbm1wX3JlcXVlc3RfaW5mbwoJc3RydWN0dXJlIHRoYXQncyBwYXNzZWQgaW4uCglUaGUgaW1wb3J0YW50IGRpZmZlcmVuY2UgYmV0d2VlbiBhIGxvb3AgY29udGV4dCBhbmQgYQogICAgICAgIGRhdGEgY29udGV4dCBpcyB0aGF0IG11bHRpcGxlIGRhdGEgY29udGV4dHMgY2FuIGJlIGtlcHQgYnkgdGhlCiAgICAgICAgdGFibGVfaXRlcmF0b3IgaGVscGVyLCB3aGVyZSBhcyBvbmx5IG9uZSBsb29wIGNvbnRleHQgd2lsbAogICAgICAgIGV2ZXIgYmUgaGVsZCBieSB0aGUgdGFibGVfaXRlcmF0b3IgaGVscGVyLiAgSWYgYWxsb2NhdGVkCiAgICAgICAgZHVyaW5nIGl0ZXJhdGlvbiB0aGUgZnJlZV9kYXRhX2NvbnRleHQgcG9pbnRlciBzaG91bGQgYmUgc2V0CiAgICAgICAgdG8gYW4gYXBwcm9wcmlhdGUgZnVuY3Rpb24uCiAKICAgIFRoZSB0YWJsZSBpdGVyYXRvciBvcGVyYXRlcyBpbiBhIHNlcmllcyBvZiBzdGVwcyB0aGF0IGNhbGwgeW91cgogICAgY29kZSBob29rcyBmcm9tIHlvdXIgbmV0c25tcF9pdGVyYXRvcl9pbmZvIHJlZ2lzdHJhdGlvbiBwb2ludGVyLgogCiAgICAgIC0gdGhlIGdldF9maXJzdF9kYXRhX3BvaW50IGhvb2sgaXMgY2FsbGVkIGF0IHRoZSBiZWdpbm5pbmcgb2YKICAgICAgICBwcm9jZXNzaW5nLiAgSXQgc2hvdWxkIHNldCB0aGUgdmFyaWFibGUgbGlzdCB0byBhIGxpc3Qgb2YKICAgICAgICBpbmRleGVzIGZvciB0aGUgZ2l2ZW4gdGFibGUuICBJdCBzaG91bGQgYWxzbyBzZXQgdGhlCiAgICAgICAgbG9vcF9jb250ZXh0IGFuZCBtYXliZSBhIGRhdGFfY29udGV4dCB3aGljaCB5b3Ugd2lsbCBnZXQgYQogICAgICAgIHBvaW50ZXIgYmFjayB0byB3aGVuIGl0IG5lZWRzIHRvIGNhbGwgeW91ciBjb2RlIHRvIHJldHJpZXZlCiAgICAgICAgYWN0dWFsIGRhdGEgbGF0ZXIuICBUaGUgbGlzdCBvZiBpbmRleGVzIHNob3VsZCBiZSByZXR1cm5lZAogICAgICAgIGFmdGVyIGJlaW5nIHVwZGF0ZS4KCiAgICAgIC0gdGhlIGdldF9uZXh0X2RhdGFfcG9pbnQgaG9vayBpcyB0aGVuIGNhbGxlZCByZXBlYXRlZGx5IGFuZCBpcwogICAgICAgIHBhc3NlZCB0aGUgbG9vcCBjb250ZXh0IGFuZCB0aGUgZGF0YSBjb250ZXh0IGZvciBpdCB0byB1cGRhdGUuCiAgICAgICAgVGhlIGluZGV4ZXMsIGxvb3AgY29udGV4dCBhbmQgZGF0YSBjb250ZXh0IHNob3VsZCBhbGwgYmUKICAgICAgICB1cGRhdGVkIGlmIG1vcmUgZGF0YSBpcyBhdmFpbGFibGUsIG90aGVyd2lzZSB0aGV5IHNob3VsZCBiZQogICAgICAgIGxlZnQgYWxvbmUgYW5kIGEgTlVMTCBzaG91bGQgYmUgcmV0dXJuZWQuICBJZGVhbGx5LCBpdCBzaG91bGQKICAgICAgICB1cGRhdGUgdGhlIGxvb3AgY29udGV4dCB3aXRob3V0IHRoZSBuZWVkIHRvIHJlYWxsb2NhdGUgaXQuICBJZgogICAgICAgIHJlYWxsb2NhdGlvbiBpcyBuZWNlc3NhcnkgZm9yIGV2ZXJ5IGl0ZXJhdGl2ZSBzdGVwLCB0aGVuIHRoZQogICAgICAgIGZyZWVfbG9vcF9jb250ZXh0IGZ1bmN0aW9uIHBvaW50ZXIgc2hvdWxkIGJlIHNldC4gIElmIG5vdCwKICAgICAgICB0aGVuIHRoZSBmcmVlX2xvb3BfY29udGV4dF9hdF9lbmQgcG9pbnRlciBzaG91bGQgYmUgc2V0LCB3aGljaAogICAgICAgIGlzIG1vcmUgZWZmaWNpZW50IHNpbmNlIGEgbWFsbG9jL2ZyZWUgd2lsbCBvbmx5IGJlIHBlcmZvcm1lZAogICAgICAgIG9uY2UgZm9yIGV2ZXJ5IGl0ZXJhdGlvbi4KICoKICogIEB7CiAqLwoKI2luY2x1ZGUgPG5ldC1zbm1wL25ldC1zbm1wLWNvbmZpZy5oPgoKI2luY2x1ZGUgPG5ldC1zbm1wL25ldC1zbm1wLWluY2x1ZGVzLmg+CiNpbmNsdWRlIDxuZXQtc25tcC9hZ2VudC9uZXQtc25tcC1hZ2VudC1pbmNsdWRlcy5oPgoKI2luY2x1ZGUgPG5ldC1zbm1wL2FnZW50L3RhYmxlX2l0ZXJhdG9yLmg+CgojaWYgSEFWRV9TVFJJTkdfSAojaW5jbHVkZSA8c3RyaW5nLmg+CiNlbHNlCiNpbmNsdWRlIDxzdHJpbmdzLmg+CiNlbmRpZgoKI2luY2x1ZGUgPG5ldC1zbm1wL2FnZW50L3RhYmxlLmg+CiNpbmNsdWRlIDxuZXQtc25tcC9hZ2VudC9zZXJpYWxpemUuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL2FnZW50L3N0YXNoX2NhY2hlLmg+CgovKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqCiAqIEl0ZXJhdG9yIEFQSTogVGFibGUgbWFpbnRlbmFuY2UKICoKICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqLwoKICAgIC8qCiAgICAgKiBJdGVyYXRvci1iYXNlZCB0YWJsZXMgYXJlIHR5cGljYWxseSBtYWludGFpbmVkIGJ5IGV4dGVybmFsCiAgICAgKiAgY29kZSwgYW5kIHRoaXMgaGVscGVyIGlzIHJlYWxseSBvbmx5IGNvbmNlcm5lZCB3aXRoCiAgICAgKiAgbWFwcGluZyBiZXR3ZWVuIGEgd2FsayB0aHJvdWdoIHRoaXMgbG9jYWwgcmVwcmVzZW50YXRpb24sCiAgICAgKiAgYW5kIHRoZSByZXF1aXJlbWVudHMgb2YgU05NUCB0YWJsZSBvcmRlcmluZy4KICAgICAqIEhvd2V2ZXIsIHRoZXJlJ3MgYSBjYXNlIHRvIGJlIG1hZGUgZm9yIGNvbnNpZGVyaW5nIHRoZQogICAgICogIGl0ZXJhdG9yIGluZm8gc3RydWN0dXJlIGFzIGVuY2Fwc3VsYXRpbmcgdGhlIHRhYmxlLCBzbwogICAgICogIGl0J3MgcHJvYmFibHkgd29ydGggZGVmaW5pbmcgdGhlIHRhYmxlIGNyZWF0aW9uL2RlbGV0aW9uCiAgICAgKiAgcm91dGluZXMgZnJvbSB0aGUgZ2VuZXJpYyBBUEkuCiAgICAgKgogICAgICogVGltZSB3aWxsIHNob3cgd2hldGhlciB0aGlzIGlzIGEgc2Vuc2libGUgYXBwcm9hY2ggb3Igbm90LgogICAgICovCm5ldHNubXBfaXRlcmF0b3JfaW5mbyAqCm5ldHNubXBfaXRlcmF0b3JfY3JlYXRlX3RhYmxlKCBOZXRzbm1wX0ZpcnN0X0RhdGFfUG9pbnQgKmZpcnN0RFAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZXRzbm1wX05leHRfRGF0YV9Qb2ludCAgKm5leHREUCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5ldHNubXBfRmlyc3RfRGF0YV9Qb2ludCAqZ2V0aWR4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICAgICppbmRleGVzKQp7CiAgICBuZXRzbm1wX2l0ZXJhdG9yX2luZm8gKmlpbmZvID0KICAgICAgICBTTk1QX01BTExPQ19UWVBFREVGKG5ldHNubXBfaXRlcmF0b3JfaW5mbyk7CgogICAgaWYgKCAhaWluZm8gKQogICAgICAgIHJldHVybiBOVUxMOwoKICAgIGlmICggaW5kZXhlcyApCiAgICAgICAgaWluZm8tPmluZGV4ZXMgPSBzbm1wX2Nsb25lX3ZhcmJpbmQoaW5kZXhlcyk7CiAgICBpaW5mby0+Z2V0X2ZpcnN0X2RhdGFfcG9pbnQgPSBmaXJzdERQOwogICAgaWluZm8tPmdldF9uZXh0X2RhdGFfcG9pbnQgID0gbmV4dERQOwogICAgaWluZm8tPmdldF9yb3dfaW5kZXhlcyAgICAgID0gZ2V0aWR4OwoKICAgIHJldHVybiBpaW5mbzsKfQoKdm9pZApuZXRzbm1wX2l0ZXJhdG9yX2RlbGV0ZV90YWJsZSggbmV0c25tcF9pdGVyYXRvcl9pbmZvICppaW5mbyApCnsKICAgIGlmICghaWluZm8pCiAgICAgICAgcmV0dXJuOwoKICAgIGlmIChpaW5mby0+aW5kZXhlcykgewogICAgICAgIHNubXBfZnJlZV92YXJiaW5kKCBpaW5mby0+aW5kZXhlcyApOwogICAgICAgIGlpbmZvLT5pbmRleGVzID0gTlVMTDsKICAgIH0KICAgIFNOTVBfRlJFRSggaWluZm8gKTsKfQoKICAgIC8qCiAgICAgKiBUaGUgcmVzdCBvZiB0aGUgdGFibGUgbWFpbnRlbmFuY2Ugc2VjdGlvbiBvZiB0aGUKICAgICAqICAgZ2VuZXJpYyB0YWJsZSBBUEkgaXMgTm90IEFwcGxpY2FibGUgdG8gdGhpcyBoZWxwZXIuCiAgICAgKgogICAgICogVGhlIGNvbnRlbnRzIG9mIGEgaXRlcmF0b3ItYmFzZWQgdGFibGUgd2lsbCBiZQogICAgICogIG1haW50YWluZWQgYnkgdGhlIHRhYmxlLXNwZWNpZmljIG1vZHVsZSBpdHNlbGYuCiAgICAgKi8KCi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICoKICogSXRlcmF0b3IgQVBJOiBNSUIgbWFpbnRlbmFuY2UKICoKICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqLwoKLyoqIHJldHVybnMgYSBuZXRzbm1wX21pYl9oYW5kbGVyIG9iamVjdCBmb3IgdGhlIHRhYmxlX2l0ZXJhdG9yIGhlbHBlciAqLwpuZXRzbm1wX21pYl9oYW5kbGVyICoKbmV0c25tcF9nZXRfdGFibGVfaXRlcmF0b3JfaGFuZGxlcihuZXRzbm1wX2l0ZXJhdG9yX2luZm8gKmlpbmZvKQp7CiAgICBuZXRzbm1wX21pYl9oYW5kbGVyICptZTsKCiAgICBpZiAoIWlpbmZvKQogICAgICAgIHJldHVybiBOVUxMOwoKICAgIG1lID0KICAgICAgICBuZXRzbm1wX2NyZWF0ZV9oYW5kbGVyKFRBQkxFX0lURVJBVE9SX05BTUUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3RhYmxlX2l0ZXJhdG9yX2hlbHBlcl9oYW5kbGVyKTsKCiAgICBpZiAoIW1lKQogICAgICAgIHJldHVybiBOVUxMOwoKICAgIG1lLT5teXZvaWQgPSBpaW5mbzsKICAgIHJldHVybiBtZTsKfQoKLyoqIAogKiBDcmVhdGVzIGFuZCByZWdpc3RlcnMgYSB0YWJsZSBpdGVyYXRvciBoZWxwZXIgaGFuZGxlciBjYWxsaW5nIAogKiBuZXRzbm1wX2NyZWF0ZV9oYW5kbGVyIHdpdGggYSBoYW5kbGVyIG5hbWUgc2V0IHRvIFRBQkxFX0lURVJBVE9SX05BTUUgCiAqIGFuZCBhY2Nlc3MgbWV0aG9kLCBuZXRzbm1wX3RhYmxlX2l0ZXJhdG9yX2hlbHBlcl9oYW5kbGVyLgogKgogKiBJZiBOT1RfU0VSSUFMSVpFRCBpcyBub3QgZGVmaW5lZCB0aGUgZnVuY3Rpb24gaW5qZWN0cyB0aGUgc2VyaWFsaXplCiAqIGhhbmRsZXIgaW50byB0aGUgY2FsbGluZyBjaGFpbiBwcmlvciB0byBjYWxsaW5nIG5ldHNubXBfcmVnaXN0ZXJfdGFibGUuCiAqCiAqIEBwYXJhbSByZWdpbmZvIGlzIGEgcG9pbnRlciB0byBhIG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gc3RydWN0CiAqCiAqIEBwYXJhbSBpaW5mbyBpcyBhIHBvaW50ZXIgdG8gYSBuZXRzbm1wX2l0ZXJhdG9yX2luZm8gc3RydWN0CiAqCiAqIEByZXR1cm4gTUlCX1JFR0lTVEVSRURfT0sgaXMgcmV0dXJuZWQgaWYgdGhlIHJlZ2lzdHJhdGlvbiB3YXMgYSBzdWNjZXNzLgogKglGYWlsdXJlcyBhcmUgTUlCX1JFR0lTVFJBVElPTl9GQUlMRUQsIE1JQl9EVVBMSUNBVEVfUkVHSVNUUkFUSU9OLgogKglJZiBpaW5mbyBpcyBOVUxMLCBTTk1QRVJSX0dFTkVSUiBpcyByZXR1cm5lZC4KICoKICovCmludApuZXRzbm1wX3JlZ2lzdGVyX3RhYmxlX2l0ZXJhdG9yKG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gKnJlZ2luZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9pdGVyYXRvcl9pbmZvICppaW5mbykKewogICAgcmVnaW5mby0+bW9kZXMgfD0gSEFORExFUl9DQU5fU1RBU0g7CiAgICBuZXRzbm1wX2luamVjdF9oYW5kbGVyKHJlZ2luZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfZ2V0X3RhYmxlX2l0ZXJhdG9yX2hhbmRsZXIoaWluZm8pKTsKICAgIGlmICghaWluZm8pCiAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwogICAgaWYgKCFpaW5mby0+aW5kZXhlcyAmJiBpaW5mby0+dGFibGVfcmVnaW5mbyAmJgogICAgICAgICAgICAgICAgICAgICAgICAgICBpaW5mby0+dGFibGVfcmVnaW5mby0+aW5kZXhlcyApCiAgICAgICAgaWluZm8tPmluZGV4ZXMgPSBzbm1wX2Nsb25lX3ZhcmJpbmQoIGlpbmZvLT50YWJsZV9yZWdpbmZvLT5pbmRleGVzICk7CgogICAgcmV0dXJuIG5ldHNubXBfcmVnaXN0ZXJfdGFibGUocmVnaW5mbywgaWluZm8tPnRhYmxlX3JlZ2luZm8pOwp9CgovKiogZXh0cmFjdHMgdGhlIHRhYmxlX2l0ZXJhdG9yIHNwZWNpZmljIGRhdGEgZnJvbSBhIHJlcXVlc3QuCiAqIFRoaXMgZnVuY3Rpb24gZXh0cmFjdHMgdGhlIHRhYmxlIGl0ZXJhdG9yIHNwZWNpZmljIGRhdGEgZnJvbSBhIAogKiBuZXRzbm1wX3JlcXVlc3RfaW5mbyBvYmplY3QuICBDYWxscyBuZXRzbm1wX3JlcXVlc3RfZ2V0X2xpc3RfZGF0YQogKiB3aXRoIHJlcXVlc3QtPnBhcmVudF9kYXRhIHNldCB3aXRoIGRhdGEgZnJvbSBhIHJlcXVlc3QgdGhhdCB3YXMgYWRkZWQgCiAqIHByZXZpb3VzbHkgYnkgYSBtb2R1bGUgYW5kIFRBQkxFX0lURVJBVE9SX05BTUUgaGFuZGxlciBuYW1lLgogKgogKiBAcGFyYW0gcmVxdWVzdCB0aGUgbmV0c25tcCByZXF1ZXN0IGluZm8gc3RydWN0dXJlCiAqCiAqIEByZXR1cm4gYSB2b2lkIHBvaW50ZXIocmVxdWVzdC0+cGFyZW50X2RhdGEtPmRhdGEpLCBvdGhlcndpc2UgTlVMTCBpcwogKiAgICAgICAgIHJldHVybmVkIGlmIHJlcXVlc3QgaXMgTlVMTCBvciByZXF1ZXN0LT5wYXJlbnRfZGF0YSBpcyBOVUxMIG9yCiAqICAgICAgICAgcmVxdWVzdC0+cGFyZW50X2RhdGEgb2JqZWN0IGlzIG5vdCBmb3VuZC50aGUgbmV0CiAqCiAqLwpORVRTTk1QX0lOTElORSB2b2lkICAgICoKbmV0c25tcF9leHRyYWN0X2l0ZXJhdG9yX2NvbnRleHQobmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3QpCnsKICAgIHJldHVybiBuZXRzbm1wX3JlcXVlc3RfZ2V0X2xpc3RfZGF0YShyZXF1ZXN0LCBUQUJMRV9JVEVSQVRPUl9OQU1FKTsKfQoKLyoqIGluc2VydHMgdGFibGVfaXRlcmF0b3Igc3BlY2lmaWMgZGF0YSBmb3IgYSBuZXdseQogKiAgY3JlYXRlZCByb3cgaW50byBhIHJlcXVlc3QgKi8KTkVUU05NUF9JTkxJTkUgdm9pZApuZXRzbm1wX2luc2VydF9pdGVyYXRvcl9jb250ZXh0KG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0LCB2b2lkICpkYXRhKQp7CiAgICBuZXRzbm1wX3JlcXVlc3RfaW5mbyAgICAgICAqcmVxOwogICAgbmV0c25tcF90YWJsZV9yZXF1ZXN0X2luZm8gKnRhYmxlX2luZm8gPSBOVUxMOwogICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICAgICAgKnRoaXNfaW5kZXggPSBOVUxMOwogICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICAgICAgKnRoYXRfaW5kZXggPSBOVUxMOwogICAgb2lkICAgICAgYmFzZV9vaWRbXSA9IHswLCAwfTsJLyogTWFrZSBzdXJlIGluZGV4IE9JRHMgYXJlIGxlZ2FsISAqLwogICAgb2lkICAgICAgdGhpc19vaWRbTUFYX09JRF9MRU5dOwogICAgb2lkICAgICAgdGhhdF9vaWRbTUFYX09JRF9MRU5dOwogICAgc2l6ZV90ICAgdGhpc19vaWRfbGVuLCB0aGF0X29pZF9sZW47CgogICAgaWYgKCFyZXF1ZXN0KQogICAgICAgIHJldHVybjsKCiAgICAvKgogICAgICogV2UnbGwgYWRkIHRoZSBuZXcgcm93IGluZm9ybWF0aW9uIHRvIGFueSByZXF1ZXN0CiAgICAgKiBzdHJ1Y3R1cmUgd2l0aCB0aGUgc2FtZSBpbmRleCB2YWx1ZXMgYXMgdGhlIHJlcXVlc3QKICAgICAqIHBhc3NlZCBpbiAod2hpY2ggaW5jbHVkZXMgdGhhdCBvbmUhKS4KICAgICAqCiAgICAgKiBTbyBjb25zdHJ1Y3QgYW4gT0lEIGJhc2VkIG9uIHRoZXNlIGluZGV4IHZhbHVlcy4KICAgICAqLwoKICAgIHRhYmxlX2luZm8gPSBuZXRzbm1wX2V4dHJhY3RfdGFibGVfaW5mbyhyZXF1ZXN0KTsKICAgIHRoaXNfaW5kZXggPSB0YWJsZV9pbmZvLT5pbmRleGVzOwogICAgYnVpbGRfb2lkX25vYWxsb2ModGhpc19vaWQsIE1BWF9PSURfTEVOLCAmdGhpc19vaWRfbGVuLAogICAgICAgICAgICAgICAgICAgICAgYmFzZV9vaWQsIDIsIHRoaXNfaW5kZXgpOwoKICAgIC8qCiAgICAgKiBXZSBuZWVkIHRvIGxvb2sgdGhyb3VnaCB0aGUgd2hvbGUgb2YgdGhlIHJlcXVlc3QgbGlzdAogICAgICogKGFzIHJlY2VpdmVkIGJ5IHRoZSBjdXJyZW50IGhhbmRsZXIpLCBhcyB0aGVyZSdzIG5vCiAgICAgKiBndWFyYW50ZWUgdGhhdCB0aGlzIHJvdXRpbmUgd2lsbCBiZSBjYWxsZWQgYnkgdGhlIGZpcnN0CiAgICAgKiB2YXJiaW5kIHRoYXQgcmVmZXJzIHRvIHRoaXMgcm93LgogICAgICogICBJbiBwYXJ0aWN1bGFyLCBhIFJvd1N0YXR1cyBjb250cm9sbGVkIHJvdyBjcmVhdGlvbgogICAgICogbWF5IGVhc2lseSBvY2N1ciBsYXRlciBpbiB0aGUgdmFyaWFibGUgbGlzdC4KICAgICAqCiAgICAgKiBTbyBmaXJzdCwgd2UgcmV3aW5kIHRvIHRoZSBoZWFkIG9mIHRoZSBsaXN0Li4uLgogICAgICovCiAgICBmb3IgKHJlcT1yZXF1ZXN0OyByZXEtPnByZXY7IHJlcT1yZXEtPnByZXYpCiAgICAgICAgOwoKICAgIC8qCiAgICAgKiAuLi4gYW5kIHRoZW4gc3RhcnQgbG9va2luZyBmb3IgbWF0Y2hpbmcgaW5kZXhlcwogICAgICogKGJ5IGNvbnN0cnVjdGluZyBPSURzIGZyb20gdGhlc2UgaW5kZXggdmFsdWVzKQogICAgICovCiAgICBmb3IgKDsgcmVxOyByZXE9cmVxLT5uZXh0KSB7CiAgICAgICAgdGFibGVfaW5mbyA9IG5ldHNubXBfZXh0cmFjdF90YWJsZV9pbmZvKHJlcSk7CiAgICAgICAgdGhhdF9pbmRleCA9IHRhYmxlX2luZm8tPmluZGV4ZXM7CiAgICAgICAgYnVpbGRfb2lkX25vYWxsb2ModGhhdF9vaWQsIE1BWF9PSURfTEVOLCAmdGhhdF9vaWRfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgIGJhc2Vfb2lkLCAyLCB0aGF0X2luZGV4KTsKICAgICAgCiAgICAgICAgLyoKICAgICAgICAgKiBUaGlzIHJlcXVlc3QgaGFzIHRoZSBzYW1lIGluZGV4IHZhbHVlcywKICAgICAgICAgKiBzbyBhZGQgdGhlIG5ld2x5LWNyZWF0ZWQgcm93IGluZm9ybWF0aW9uLgogICAgICAgICAqLwogICAgICAgIGlmIChzbm1wX29pZF9jb21wYXJlKHRoaXNfb2lkLCB0aGlzX29pZF9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhhdF9vaWQsIHRoYXRfb2lkX2xlbikgPT0gMCkgewogICAgICAgICAgICBuZXRzbm1wX3JlcXVlc3RfYWRkX2xpc3RfZGF0YShyZXEsCiAgICAgICAgICAgICAgICBuZXRzbm1wX2NyZWF0ZV9kYXRhX2xpc3QoVEFCTEVfSVRFUkFUT1JfTkFNRSwgZGF0YSwgTlVMTCkpOwogICAgICAgIH0KICAgIH0KfQoKI2RlZmluZSBUSV9SRVFVRVNUX0NBQ0hFICJ0aV9jYWNoZSIKCnR5cGVkZWYgc3RydWN0IHRpX2NhY2hlX2luZm9fcyB7CiAgIG9pZCBiZXN0X21hdGNoW01BWF9PSURfTEVOXTsKICAgc2l6ZV90IGJlc3RfbWF0Y2hfbGVuOwogICB2b2lkICpkYXRhX2NvbnRleHQ7CiAgIE5ldHNubXBfRnJlZV9EYXRhX0NvbnRleHQgKmZyZWVfY29udGV4dDsKICAgbmV0c25tcF9pdGVyYXRvcl9pbmZvICppaW5mbzsKICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICpyZXN1bHRzOwp9IHRpX2NhY2hlX2luZm87CgpzdGF0aWMgdm9pZApuZXRzbm1wX2ZyZWVfdGlfY2FjaGUodm9pZCAqaXQpIHsKICAgIHRpX2NhY2hlX2luZm8gKmJlZXIgPSAodGlfY2FjaGVfaW5mbyopaXQ7CiAgICBpZiAoIWl0KSByZXR1cm47CiAgICBpZiAoYmVlci0+ZGF0YV9jb250ZXh0ICYmIGJlZXItPmZyZWVfY29udGV4dCkgewogICAgICAgICAgICAoYmVlci0+ZnJlZV9jb250ZXh0KShiZWVyLT5kYXRhX2NvbnRleHQsIGJlZXItPmlpbmZvKTsKICAgIH0KICAgIGlmIChiZWVyLT5yZXN1bHRzKSB7CiAgICAgICAgc25tcF9mcmVlX3ZhcmJpbmQoYmVlci0+cmVzdWx0cyk7CiAgICB9CiAgICBmcmVlKGJlZXIpOwp9CgovKiBjYWNoZXMgaW5mb3JtYXRpb24gKGluIHRoZSByZXF1ZXN0KSB3ZSdsbCBuZWVkIGF0IGEgbGF0ZXIgcG9pbnQgaW4gdGltZSAqLwpzdGF0aWMgdGlfY2FjaGVfaW5mbyAqCm5ldHNubXBfaXRlcmF0b3JfcmVtZW1iZXIobmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgb2lkICpvaWRfdG9fc2F2ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplX3Qgb2lkX3RvX3NhdmVfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKmNhbGxiYWNrX2RhdGFfY29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICpjYWxsYmFja19sb29wX2NvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9pdGVyYXRvcl9pbmZvICppaW5mbykKewogICAgdGlfY2FjaGVfaW5mbyAqdGlfaW5mbzsKCiAgICBpZiAoIXJlcXVlc3QgfHwgIW9pZF90b19zYXZlIHx8IG9pZF90b19zYXZlX2xlbiA+IE1BWF9PSURfTEVOKQogICAgICAgIHJldHVybiBOVUxMOwoKICAgIC8qIGV4dHJhY3QgZXhpc3RpbmcgY2FjaGVkIHN0YXRlICovCiAgICB0aV9pbmZvID0gKHRpX2NhY2hlX2luZm8qKW5ldHNubXBfcmVxdWVzdF9nZXRfbGlzdF9kYXRhKHJlcXVlc3QsIFRJX1JFUVVFU1RfQ0FDSEUpOwoKICAgIC8qIG5vIGV4aXN0aW5nIGNhY2hlZCBzdGF0ZS4gIG1ha2UgYSBuZXcgb25lLiAqLwogICAgaWYgKCF0aV9pbmZvKSB7CiAgICAgICAgdGlfaW5mbyA9IFNOTVBfTUFMTE9DX1RZUEVERUYodGlfY2FjaGVfaW5mbyk7CiAgICAgICAgaWYgKHRpX2luZm8gPT0gTlVMTCkKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgbmV0c25tcF9yZXF1ZXN0X2FkZF9saXN0X2RhdGEocmVxdWVzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2NyZWF0ZV9kYXRhX2xpc3QKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoVElfUkVRVUVTVF9DQUNIRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGlfaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9mcmVlX3RpX2NhY2hlKSk7CiAgICB9CgogICAgLyogZnJlZSBleGlzdGluZyBjYWNoZSBiZWZvcmUgcmVwbGFjaW5nICovCiAgICBpZiAodGlfaW5mby0+ZGF0YV9jb250ZXh0ICYmIHRpX2luZm8tPmZyZWVfY29udGV4dCkKICAgICAgICAodGlfaW5mby0+ZnJlZV9jb250ZXh0KSh0aV9pbmZvLT5kYXRhX2NvbnRleHQsIGlpbmZvKTsKCiAgICAvKiBtYXliZSBnZW5lcmF0ZSBpdCBmcm9tIHRoZSBsb29wIGNvbnRleHQ/ICovCiAgICBpZiAoaWluZm8tPm1ha2VfZGF0YV9jb250ZXh0ICYmICFjYWxsYmFja19kYXRhX2NvbnRleHQpIHsKICAgICAgICBjYWxsYmFja19kYXRhX2NvbnRleHQgPQogICAgICAgICAgICAoaWluZm8tPm1ha2VfZGF0YV9jb250ZXh0KShjYWxsYmFja19sb29wX2NvbnRleHQsIGlpbmZvKTsKCiAgICB9CgogICAgLyogc2F2ZSBkYXRhIGFzIHJlcXVlc3RlZCAqLwogICAgdGlfaW5mby0+ZGF0YV9jb250ZXh0ID0gY2FsbGJhY2tfZGF0YV9jb250ZXh0OwogICAgdGlfaW5mby0+ZnJlZV9jb250ZXh0ID0gaWluZm8tPmZyZWVfZGF0YV9jb250ZXh0OwogICAgdGlfaW5mby0+YmVzdF9tYXRjaF9sZW4gPSBvaWRfdG9fc2F2ZV9sZW47CiAgICB0aV9pbmZvLT5paW5mbyA9IGlpbmZvOwogICAgaWYgKG9pZF90b19zYXZlX2xlbikKICAgICAgICBtZW1jcHkodGlfaW5mby0+YmVzdF9tYXRjaCwgb2lkX3RvX3NhdmUsIG9pZF90b19zYXZlX2xlbiAqIHNpemVvZihvaWQpKTsKCiAgICByZXR1cm4gdGlfaW5mbzsKfSAgICAKCiNkZWZpbmUgVEFCTEVfSVRFUkFUT1JfTk9UQUdBSU4gMjU1Ci8qIGltcGxlbWVudHMgdGhlIHRhYmxlX2l0ZXJhdG9yIGhlbHBlciAqLwppbnQKbmV0c25tcF90YWJsZV9pdGVyYXRvcl9oZWxwZXJfaGFuZGxlcihuZXRzbm1wX21pYl9oYW5kbGVyICpoYW5kbGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gKnJlZ2luZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9hZ2VudF9yZXF1ZXN0X2luZm8gKnJlcWluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3RzKQp7CiAgICBuZXRzbm1wX3RhYmxlX3JlZ2lzdHJhdGlvbl9pbmZvICp0YmxfaW5mbzsKICAgIG5ldHNubXBfdGFibGVfcmVxdWVzdF9pbmZvICp0YWJsZV9pbmZvID0gTlVMTDsKICAgIG9pZCAgICAgICAgICAgICBjb2xvaWRbTUFYX09JRF9MRU5dOwogICAgc2l6ZV90ICAgICAgICAgIGNvbG9pZF9sZW47CiAgICBpbnQgICAgICAgICAgICAgcmV0ID0gU05NUF9FUlJfTk9FUlJPUjsKICAgIHN0YXRpYyBvaWQgICAgICBteW5hbWVbTUFYX09JRF9MRU5dOwogICAgc2l6ZV90ICAgICAgICAgIG15bmFtZV9sZW47CiAgICBpbnQgICAgICAgICAgICAgb2xkbW9kZSA9IDA7CiAgICBuZXRzbm1wX2l0ZXJhdG9yX2luZm8gKmlpbmZvOwogICAgaW50IG5vdGRvbmU7CiAgICBpbnQgaGludG9rID0gMDsKICAgIG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0LCAqcmVxdG1wID0gTlVMTDsKICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqaW5kZXhfc2VhcmNoID0gTlVMTDsKICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqZnJlZV90aGlzX2luZGV4X3NlYXJjaCA9IE5VTEw7CiAgICB2b2lkICAgICAgICAgICAqY2FsbGJhY2tfbG9vcF9jb250ZXh0ID0gTlVMTCwgKmxhc3RfbG9vcF9jb250ZXh0OwogICAgdm9pZCAgICAgICAgICAgKmNhbGxiYWNrX2RhdGFfY29udGV4dCA9IE5VTEw7CiAgICB0aV9jYWNoZV9pbmZvICAqdGlfaW5mbyA9IE5VTEw7CiAgICBpbnQgICAgICAgICAgICAgcmVxdWVzdF9jb3VudCA9IDA7CiAgICBuZXRzbm1wX29pZF9zdGFzaF9ub2RlICoqY2luZm8gPSBOVUxMOwogICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICpvbGRfaW5kZXhlcyA9IE5VTEwsICp2YjsKICAgIG5ldHNubXBfdGFibGVfcmVnaXN0cmF0aW9uX2luZm8gKnRhYmxlX3JlZ19pbmZvID0gTlVMTDsKICAgIGludCBpOwogICAgbmV0c25tcF9kYXRhX2xpc3QgICAgKmxkYXRhID0gTlVMTDsKICAgIAogICAgaWluZm8gPSAobmV0c25tcF9pdGVyYXRvcl9pbmZvICopIGhhbmRsZXItPm15dm9pZDsKICAgIGlmICghaWluZm8gfHwgIXJlZ2luZm8gfHwgIXJlcWluZm8pCiAgICAgICAgcmV0dXJuIFNOTVBfRVJSX0dFTkVSUjsKCiAgICB0YmxfaW5mbyA9IGlpbmZvLT50YWJsZV9yZWdpbmZvOwoKICAgIC8qCiAgICAgKiBjb3B5IGluIHRoZSB0YWJsZSByZWdpc3RyYXRpb24gb2lkIGZvciBsYXRlciB1c2UgCiAgICAgKi8KICAgIGNvbG9pZF9sZW4gPSByZWdpbmZvLT5yb290b2lkX2xlbiArIDI7CiAgICBtZW1jcHkoY29sb2lkLCByZWdpbmZvLT5yb290b2lkLCByZWdpbmZvLT5yb290b2lkX2xlbiAqIHNpemVvZihvaWQpKTsKICAgIGNvbG9pZFtyZWdpbmZvLT5yb290b2lkX2xlbl0gPSAxOyAgIC8qIHRhYmxlLmVudHJ5IG5vZGUgKi8KCiAgICAvKgogICAgICogaWxsZWdhbGx5IGdvdCBoZXJlIGlmIHRoZXNlIGZ1bmN0aW9ucyBhcmVuJ3QgZGVmaW5lZCAKICAgICAqLwogICAgaWYgKGlpbmZvLT5nZXRfZmlyc3RfZGF0YV9wb2ludCA9PSBOVUxMIHx8CiAgICAgICAgaWluZm8tPmdldF9uZXh0X2RhdGFfcG9pbnQgPT0gTlVMTCkgewogICAgICAgIHNubXBfbG9nKExPR19FUlIsCiAgICAgICAgICAgICAgICAgInRhYmxlX2l0ZXJhdG9yIGhlbHBlciBjYWxsZWQgd2l0aG91dCBkYXRhIGFjY2Vzc29yIGZ1bmN0aW9uc1xuIik7CiAgICAgICAgcmV0dXJuIFNOTVBfRVJSX0dFTkVSUjsKICAgIH0KCiAgICAvKiBwcmVsaW1pbmFyeSBhbmFseXNpcyAqLwogICAgc3dpdGNoIChyZXFpbmZvLT5tb2RlKSB7CiAgICBjYXNlIE1PREVfR0VUX1NUQVNIOgogICAgICAgIGNpbmZvID0gbmV0c25tcF9leHRyYWN0X3N0YXNoX2NhY2hlKHJlcWluZm8pOwogICAgICAgIHRhYmxlX3JlZ19pbmZvID0gbmV0c25tcF9maW5kX3RhYmxlX3JlZ2lzdHJhdGlvbl9pbmZvKHJlZ2luZm8pOwoKICAgICAgICAvKiBYWFg6IG1vdmUgdGhpcyBtYWxsb2MgdG8gc3Rhc2hfY2FjaGUgaGFuZGxlcj8gKi8KICAgICAgICByZXF0bXAgPSBTTk1QX01BTExPQ19UWVBFREVGKG5ldHNubXBfcmVxdWVzdF9pbmZvKTsKICAgICAgICBpZiAocmVxdG1wID09IE5VTEwpCiAgICAgICAgICAgIHJldHVybiBTTk1QX0VSUl9HRU5FUlI7CiAgICAgICAgcmVxdG1wLT5zdWJ0cmVlID0gcmVxdWVzdHMtPnN1YnRyZWU7CiAgICAgICAgdGFibGVfaW5mbyA9IG5ldHNubXBfZXh0cmFjdF90YWJsZV9pbmZvKHJlcXVlc3RzKTsKICAgICAgICBuZXRzbm1wX3JlcXVlc3RfYWRkX2xpc3RfZGF0YShyZXF0bXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9jcmVhdGVfZGF0YV9saXN0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFRBQkxFX0hBTkRMRVJfTkFNRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHZvaWQgKikgdGFibGVfaW5mbywgTlVMTCkpOwoKICAgICAgICAvKiByZW1lbWJlciB0aGUgaW5kZXhlcyB0aGF0IHdlcmUgb3JpZ2luYWxseSBwYXJzZWQuICovCiAgICAgICAgb2xkX2luZGV4ZXMgPSB0YWJsZV9pbmZvLT5pbmRleGVzOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgTU9ERV9HRVRORVhUOgogICAgICAgIGZvcihyZXF1ZXN0ID0gcmVxdWVzdHMgOyByZXF1ZXN0OyByZXF1ZXN0ID0gcmVxdWVzdC0+bmV4dCkgewogICAgICAgICAgICBpZiAocmVxdWVzdC0+cHJvY2Vzc2VkKQogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIHRhYmxlX2luZm8gPSBuZXRzbm1wX2V4dHJhY3RfdGFibGVfaW5mbyhyZXF1ZXN0KTsKICAgICAgICAgICAgaWYgKHRhYmxlX2luZm8gPT0gTlVMTCkgewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIENsZWFudXAgCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIGlmIChmcmVlX3RoaXNfaW5kZXhfc2VhcmNoKQogICAgICAgICAgICAgICAgICAgIHNubXBfZnJlZV92YXJiaW5kKGZyZWVfdGhpc19pbmRleF9zZWFyY2gpOwogICAgICAgICAgICAgICAgcmV0dXJuIFNOTVBfRVJSX0dFTkVSUjsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAodGFibGVfaW5mby0+Y29sbnVtIDwgdGJsX2luZm8tPm1pbl9jb2x1bW4gLSAxKSB7CiAgICAgICAgICAgICAgICAvKiBYWFg6IG9wdGltaXplIGJldHRlciB0aGFuIHRoaXMgKi8KICAgICAgICAgICAgICAgIC8qIGZvciBub3csIGp1c3QgaW5jcmVhc2UgdG8gY29sbnVtLTEgKi8KICAgICAgICAgICAgICAgIC8qIHdlIG5lZWQgdG8ganVtcCB0byB0aGUgbG93ZXN0IHJlc3VsdCBvZiB0aGUgbWluX2NvbHVtbgogICAgICAgICAgICAgICAgICAgYW5kIHRha2UgaXQsIGNvbXBhcmluZyB0byBub3RoaW5nIGZyb20gdGhlIHJlcXVlc3QgKi8KICAgICAgICAgICAgICAgIHRhYmxlX2luZm8tPmNvbG51bSA9IHRibF9pbmZvLT5taW5fY29sdW1uIC0gMTsKICAgICAgICAgICAgfSBlbHNlIGlmICh0YWJsZV9pbmZvLT5jb2xudW0gPiB0YmxfaW5mby0+bWF4X2NvbHVtbikgewogICAgICAgICAgICAgICAgcmVxdWVzdC0+cHJvY2Vzc2VkID0gVEFCTEVfSVRFUkFUT1JfTk9UQUdBSU47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRpX2luZm8gPSAodGlfY2FjaGVfaW5mbyopCiAgICAgICAgICAgICAgICBuZXRzbm1wX3JlcXVlc3RfZ2V0X2xpc3RfZGF0YShyZXF1ZXN0LCBUSV9SRVFVRVNUX0NBQ0hFKTsKICAgICAgICAgICAgaWYgKCF0aV9pbmZvKSB7CiAgICAgICAgICAgICAgICB0aV9pbmZvID0gU05NUF9NQUxMT0NfVFlQRURFRih0aV9jYWNoZV9pbmZvKTsKICAgICAgICAgICAgICAgIGlmICh0aV9pbmZvID09IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICAgICAqIENsZWFudXAgCiAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgaWYgKGZyZWVfdGhpc19pbmRleF9zZWFyY2gpCiAgICAgICAgICAgICAgICAgICAgICAgIHNubXBfZnJlZV92YXJiaW5kKGZyZWVfdGhpc19pbmRleF9zZWFyY2gpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBTTk1QX0VSUl9HRU5FUlI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBuZXRzbm1wX3JlcXVlc3RfYWRkX2xpc3RfZGF0YShyZXF1ZXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9jcmVhdGVfZGF0YV9saXN0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoVElfUkVRVUVTVF9DQUNIRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aV9pbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfZnJlZV90aV9jYWNoZSkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKiBYWFg6IGlmIG5vIHZhbGlkIHJlcXVlc3RzLCBkb24ndCBldmVuIGxvb3AgYmVsb3cgKi8KICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICB9CgogICAgLyoKICAgICAqIGNvbGxlY3QgYWxsIGluZm9ybWF0aW9uIGZvciBlYWNoIG5lZWRlZCByb3cKICAgICAqLwogICAgaWYgKHJlcWluZm8tPm1vZGUgPT0gTU9ERV9HRVQgfHwKICAgICAgICByZXFpbmZvLT5tb2RlID09IE1PREVfR0VUTkVYVCB8fAogICAgICAgIHJlcWluZm8tPm1vZGUgPT0gTU9ERV9HRVRfU1RBU0ggfHwKICAgICAgICByZXFpbmZvLT5tb2RlID09IE1PREVfU0VUX1JFU0VSVkUxKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBDb3VudCB0aGUgbnVtYmVyIG9mIHJlcXVlc3QgaW4gdGhlIGxpc3QsCiAgICAgICAgICogICBzbyB0aGF0IHdlJ2xsIGtub3cgd2hlbiB3ZSdyZSBmaW5pc2hlZAogICAgICAgICAqLwogICAgICAgIGZvcihyZXF1ZXN0ID0gcmVxdWVzdHMgOyByZXF1ZXN0OyByZXF1ZXN0ID0gcmVxdWVzdC0+bmV4dCkKICAgICAgICAgIGlmICghcmVxdWVzdC0+cHJvY2Vzc2VkKQogICAgICAgICAgICByZXF1ZXN0X2NvdW50Kys7CiAgICAgICAgbm90ZG9uZSA9IDE7CiAgICAgICAgaGludG9rID0gMTsKICAgICAgICB3aGlsZShub3Rkb25lKSB7CiAgICAgICAgICAgIG5vdGRvbmUgPSAwOwoKICAgICAgICAgICAgLyogZmluZCBmaXJzdCBkYXRhIHBvaW50ICovCiAgICAgICAgICAgIGlmICghaW5kZXhfc2VhcmNoKSB7CiAgICAgICAgICAgICAgICBpZiAoZnJlZV90aGlzX2luZGV4X3NlYXJjaCkgewogICAgICAgICAgICAgICAgICAgIC8qIHByZXZpb3VzbHkgZG9uZSAqLwogICAgICAgICAgICAgICAgICAgIGluZGV4X3NlYXJjaCA9IGZyZWVfdGhpc19pbmRleF9zZWFyY2g7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGZvcihyZXF1ZXN0PXJlcXVlc3RzIDsgcmVxdWVzdDsgcmVxdWVzdD1yZXF1ZXN0LT5uZXh0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRhYmxlX2luZm8gPSBuZXRzbm1wX2V4dHJhY3RfdGFibGVfaW5mbyhyZXF1ZXN0KTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRhYmxlX2luZm8pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKCF0YWJsZV9pbmZvKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNubXBfbG9nKExPR19XQVJOSU5HLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibm8gdmFsaWQgcmVxdWVzdHMgZm9yIGl0ZXJhdG9yIHRhYmxlICVzXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWdpbmZvLT5oYW5kbGVyTmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfZnJlZV9yZXF1ZXN0X2RhdGFfc2V0cyhyZXF0bXApOwogICAgICAgICAgICAgICAgICAgICAgICBTTk1QX0ZSRUUocmVxdG1wKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFNOTVBfRVJSX05PRVJST1I7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGluZGV4X3NlYXJjaCA9IHNubXBfY2xvbmVfdmFyYmluZCh0YWJsZV9pbmZvLT5pbmRleGVzKTsKICAgICAgICAgICAgICAgICAgICBmcmVlX3RoaXNfaW5kZXhfc2VhcmNoID0gaW5kZXhfc2VhcmNoOwoKICAgICAgICAgICAgICAgICAgICAvKiBzZXR1cCwgbWFsbG9jIHNlYXJjaCBkYXRhOiAqLwogICAgICAgICAgICAgICAgICAgIGlmICghaW5kZXhfc2VhcmNoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgICAgICAgICAqIGhtbW0uLi4uICBpbnZhbGlkIHRhYmxlPyAKICAgICAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgICAgIHNubXBfbG9nKExPR19XQVJOSU5HLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiaW52YWxpZCBpbmRleCBsaXN0IG9yIGZhaWxlZCBtYWxsb2MgZm9yIHRhYmxlICVzXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWdpbmZvLT5oYW5kbGVyTmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfZnJlZV9yZXF1ZXN0X2RhdGFfc2V0cyhyZXF0bXApOwogICAgICAgICAgICAgICAgICAgICAgICBTTk1QX0ZSRUUocmVxdG1wKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFNOTVBfRVJSX05PRVJST1I7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAvKiBpZiBzb3J0ZWQsIHBhc3MgaW4gYSBoaW50ICovCiAgICAgICAgICAgIGlmIChoaW50b2sgJiYgKGlpbmZvLT5mbGFncyAmIE5FVFNOTVBfSVRFUkFUT1JfRkxBR19TT1JURUQpKSB7CiAgICAgICAgICAgICAgICBjYWxsYmFja19sb29wX2NvbnRleHQgPSB0YWJsZV9pbmZvOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGluZGV4X3NlYXJjaCA9CiAgICAgICAgICAgICAgICAoaWluZm8tPmdldF9maXJzdF9kYXRhX3BvaW50KSAoJmNhbGxiYWNrX2xvb3BfY29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmY2FsbGJhY2tfZGF0YV9jb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4X3NlYXJjaCwgaWluZm8pOwoKICAgICAgICAgICAgLyogbG9vcCBvdmVyIGVhY2ggZGF0YSBwb2ludCAqLwogICAgICAgICAgICB3aGlsZShpbmRleF9zZWFyY2gpIHsKCiAgICAgICAgICAgICAgICAvKiByZW1lbWJlciB0byBmcmVlIHRoaXMgbGF0ZXIgKi8KICAgICAgICAgICAgICAgIGZyZWVfdGhpc19pbmRleF9zZWFyY2ggPSBpbmRleF9zZWFyY2g7CiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgLyogY29tcGFyZSBhZ2FpbnN0IGVhY2ggcmVxdWVzdCovCiAgICAgICAgICAgICAgICBmb3IocmVxdWVzdCA9IHJlcXVlc3RzIDsgcmVxdWVzdDsgcmVxdWVzdCA9IHJlcXVlc3QtPm5leHQpIHsKICAgICAgICAgICAgICAgICAgICBpZiAocmVxdWVzdC0+cHJvY2Vzc2VkKQogICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKCiAgICAgICAgICAgICAgICAgICAgLyogWFhYOiBzdG9yZSBpbiBhbiBhcnJheSBmb3IgZmFzdGVyIHJldHJpZXZhbCAqLwogICAgICAgICAgICAgICAgICAgIHRhYmxlX2luZm8gPSBuZXRzbm1wX2V4dHJhY3RfdGFibGVfaW5mbyhyZXF1ZXN0KTsKICAgICAgICAgICAgICAgICAgICBpZiAodGFibGVfaW5mbyA9PSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgICAgICAgICAqIENsZWFudXAgCiAgICAgICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoZnJlZV90aGlzX2luZGV4X3NlYXJjaCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNubXBfZnJlZV92YXJiaW5kKGZyZWVfdGhpc19pbmRleF9zZWFyY2gpOwogICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2ZyZWVfcmVxdWVzdF9kYXRhX3NldHMocmVxdG1wKTsKICAgICAgICAgICAgICAgICAgICAgICAgU05NUF9GUkVFKHJlcXRtcCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBTTk1QX0VSUl9HRU5FUlI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGNvbG9pZFtyZWdpbmZvLT5yb290b2lkX2xlbiArIDFdID0gdGFibGVfaW5mby0+Y29sbnVtOwoKICAgICAgICAgICAgICAgICAgICB0aV9pbmZvID0gKHRpX2NhY2hlX2luZm8qKQogICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3JlcXVlc3RfZ2V0X2xpc3RfZGF0YShyZXF1ZXN0LCBUSV9SRVFVRVNUX0NBQ0hFKTsKCiAgICAgICAgICAgICAgICAgICAgc3dpdGNoKHJlcWluZm8tPm1vZGUpIHsKICAgICAgICAgICAgICAgICAgICBjYXNlIE1PREVfR0VUOgogICAgICAgICAgICAgICAgICAgIGNhc2UgTU9ERV9TRVRfUkVTRVJWRTE6CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIGxvb2tpbmcgZm9yIGV4YWN0IG1hdGNoZXMgKi8KICAgICAgICAgICAgICAgICAgICAgICAgYnVpbGRfb2lkX25vYWxsb2MobXluYW1lLCBNQVhfT0lEX0xFTiwgJm15bmFtZV9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9pZCwgY29sb2lkX2xlbiwgaW5kZXhfc2VhcmNoKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNubXBfb2lkX2NvbXBhcmUobXluYW1lLCBteW5hbWVfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0LT5yZXF1ZXN0dmItPm5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3QtPnJlcXVlc3R2Yi0+bmFtZV9sZW5ndGgpID09IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICoga2VlcCB0aGlzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuZXRzbm1wX2l0ZXJhdG9yX3JlbWVtYmVyKHJlcXVlc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBteW5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBteW5hbWVfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2tfZGF0YV9jb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2tfbG9vcF9jb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWluZm8pID09IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIENsZWFudXAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZyZWVfdGhpc19pbmRleF9zZWFyY2gpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNubXBfZnJlZV92YXJiaW5kCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZnJlZV90aGlzX2luZGV4X3NlYXJjaCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9mcmVlX3JlcXVlc3RfZGF0YV9zZXRzKHJlcXRtcCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU05NUF9GUkVFKHJlcXRtcCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFNOTVBfRVJSX0dFTkVSUjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3RfY291bnQtLTsgICAvKiBPbmUgbGVzcyB0byBsb29rIGZvciAqLwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlpbmZvLT5mcmVlX2RhdGFfY29udGV4dCAmJiBjYWxsYmFja19kYXRhX2NvbnRleHQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoaWluZm8tPmZyZWVfZGF0YV9jb250ZXh0KShjYWxsYmFja19kYXRhX2NvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWluZm8pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgICAgICBjYXNlIE1PREVfR0VUX1NUQVNIOgogICAgICAgICAgICAgICAgICAgICAgICAvKiBjb2xsZWN0IGRhdGEgZm9yIGVhY2ggY29sdW1uIGZvciBldmVyeSByb3cgKi8KICAgICAgICAgICAgICAgICAgICAgICAgYnVpbGRfb2lkX25vYWxsb2MobXluYW1lLCBNQVhfT0lEX0xFTiwgJm15bmFtZV9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9pZCwgY29sb2lkX2xlbiwgaW5kZXhfc2VhcmNoKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmVxaW5mby0+bW9kZSA9IE1PREVfR0VUOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVxdG1wKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgbGRhdGEgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfZ2V0X2xpc3Rfbm9kZShyZXF0bXAtPnBhcmVudF9kYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUQUJMRV9JVEVSQVRPUl9OQU1FKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFsZGF0YSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9yZXF1ZXN0X2FkZF9saXN0X2RhdGEocmVxdG1wLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9jcmVhdGVfZGF0YV9saXN0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoVEFCTEVfSVRFUkFUT1JfTkFNRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsYmFja19kYXRhX2NvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCkpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogbWF5IGhhdmUgY2hhbmdlZCAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgbGRhdGEtPmRhdGEgPSBjYWxsYmFja19kYXRhX2NvbnRleHQ7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIHRhYmxlX2luZm8tPmluZGV4ZXMgPSBpbmRleF9zZWFyY2g7CiAgICAgICAgICAgICAgICAgICAgICAgIGZvcihpID0gdGFibGVfcmVnX2luZm8tPm1pbl9jb2x1bW47CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpIDw9IChpbnQpdGFibGVfcmVnX2luZm8tPm1heF9jb2x1bW47IGkrKykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgbXluYW1lW3JlZ2luZm8tPnJvb3RvaWRfbGVuICsgMV0gPSBpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFibGVfaW5mby0+Y29sbnVtID0gaTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZiID0gcmVxdG1wLT5yZXF1ZXN0dmIgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNOTVBfTUFMTE9DX1RZUEVERUYobmV0c25tcF92YXJpYWJsZV9saXN0KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2YiA9PSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBDbGVhbnVwIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmcmVlX3RoaXNfaW5kZXhfc2VhcmNoKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzbm1wX2ZyZWVfdmFyYmluZAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGZyZWVfdGhpc19pbmRleF9zZWFyY2gpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBTTk1QX0VSUl9HRU5FUlI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2Yi0+dHlwZSA9IEFTTl9OVUxMOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgc25tcF9zZXRfdmFyX29iamlkKHZiLCBteW5hbWUsIG15bmFtZV9sZW4pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9jYWxsX25leHRfaGFuZGxlcihoYW5kbGVyLCByZWdpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXFpbmZvLCByZXF0bXApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdG1wLT5yZXF1ZXN0dmIgPSBOVUxMOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdG1wLT5wcm9jZXNzZWQgPSAwOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHZiLT50eXBlICE9IEFTTl9OVUxMKSB7IC8qIFhYWCwgbm90IGFsbCAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfb2lkX3N0YXNoX2FkZF9kYXRhKGNpbmZvLCBteW5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXluYW1lX2xlbiwgdmIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzbm1wX2ZyZWVfdmFyKHZiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICByZXFpbmZvLT5tb2RlID0gTU9ERV9HRVRfU1RBU0g7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgICAgICBjYXNlIE1PREVfR0VUTkVYVDoKICAgICAgICAgICAgICAgICAgICAgICAgLyogbG9va2luZyBmb3IgIm5leHQiIG1hdGNoZXMgKi8KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5ldHNubXBfY2hlY2tfZ2V0bmV4dF9yZXBseQogICAgICAgICAgICAgICAgICAgICAgICAgICAgKHJlcXVlc3QsIGNvbG9pZCwgY29sb2lkX2xlbiwgaW5kZXhfc2VhcmNoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICZ0aV9pbmZvLT5yZXN1bHRzKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5ldHNubXBfaXRlcmF0b3JfcmVtZW1iZXIocmVxdWVzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpX2luZm8tPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0cy0+bmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpX2luZm8tPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0cy0+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lX2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrX2RhdGFfY29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrX2xvb3BfY29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlpbmZvKSA9PSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBDbGVhbnVwIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmcmVlX3RoaXNfaW5kZXhfc2VhcmNoKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzbm1wX2ZyZWVfdmFyYmluZAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGZyZWVfdGhpc19pbmRleF9zZWFyY2gpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBTTk1QX0VSUl9HRU5FUlI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICogIElmIHdlJ3ZlIGJlZW4gdG9sZCB0aGF0IHRoZSByb3dzIGFyZSBzb3J0ZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiAgIHRoZW4gdGhlIGZpcnN0IHZhbGlkIG9uZSB3ZSBmaW5kCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiAgIG11c3QgYmUgdGhlIHJpZ2h0IG9uZS4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlpbmZvLT5mbGFncyAmIE5FVFNOTVBfSVRFUkFUT1JfRkxBR19TT1JURUQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdF9jb3VudC0tOwogICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpaW5mby0+ZnJlZV9kYXRhX2NvbnRleHQgJiYgY2FsbGJhY2tfZGF0YV9jb250ZXh0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGlpbmZvLT5mcmVlX2RhdGFfY29udGV4dCkoY2FsbGJhY2tfZGF0YV9jb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlpbmZvKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICAgICAgY2FzZSBNT0RFX1NFVF9SRVNFUlZFMjoKICAgICAgICAgICAgICAgICAgICBjYXNlIE1PREVfU0VUX0ZSRUU6CiAgICAgICAgICAgICAgICAgICAgY2FzZSBNT0RFX1NFVF9VTkRPOgogICAgICAgICAgICAgICAgICAgIGNhc2UgTU9ERV9TRVRfQ09NTUlUOgogICAgICAgICAgICAgICAgICAgICAgICAvKiBuZWVkZWQgcHJvY2Vzc2luZyBhbHJlYWR5IGRvbmUgaW4gUkVTRVJWRTEgKi8KICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgIHNubXBfbG9nKExPR19FUlIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YWJsZV9pdGVyYXRvciBjYWxsZWQgd2l0aCB1bnN1cHBvcnRlZCBtb2RlXG4iKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7ICAvKiBYWFggcmV0dXJuICovCiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLyogSXMgdGhlcmUgYW55IHBvaW50IGluIGNhcnJ5aW5nIG9uPyAqLwogICAgICAgICAgICAgICAgaWYgKCFyZXF1ZXN0X2NvdW50KQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgLyogZ2V0IHRoZSBuZXh0IHNlYXJjaCBwb3NzaWJpbGl0eSAqLwogICAgICAgICAgICAgICAgbGFzdF9sb29wX2NvbnRleHQgPSBjYWxsYmFja19sb29wX2NvbnRleHQ7CiAgICAgICAgICAgICAgICBpbmRleF9zZWFyY2ggPQogICAgICAgICAgICAgICAgICAgIChpaW5mby0+Z2V0X25leHRfZGF0YV9wb2ludCkgKCZjYWxsYmFja19sb29wX2NvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmNhbGxiYWNrX2RhdGFfY29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmRleF9zZWFyY2gsIGlpbmZvKTsKICAgICAgICAgICAgICAgIGlmIChpaW5mby0+ZnJlZV9sb29wX2NvbnRleHQgJiYgbGFzdF9sb29wX2NvbnRleHQgJiYKICAgICAgICAgICAgICAgICAgICBjYWxsYmFja19kYXRhX2NvbnRleHQgIT0gbGFzdF9sb29wX2NvbnRleHQpIHsKICAgICAgICAgICAgICAgICAgICAoaWluZm8tPmZyZWVfbG9vcF9jb250ZXh0KSAobGFzdF9sb29wX2NvbnRleHQsIGlpbmZvKTsKICAgICAgICAgICAgICAgICAgICBsYXN0X2xvb3BfY29udGV4dCA9IE5VTEw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qIGZyZWUgbG9vcCBjb250ZXh0IGJlZm9yZSBnb2luZyBvbiAqLwogICAgICAgICAgICBpZiAoY2FsbGJhY2tfbG9vcF9jb250ZXh0ICYmIGlpbmZvLT5mcmVlX2xvb3BfY29udGV4dF9hdF9lbmQpIHsKICAgICAgICAgICAgICAgIChpaW5mby0+ZnJlZV9sb29wX2NvbnRleHRfYXRfZW5kKSAoY2FsbGJhY2tfbG9vcF9jb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpaW5mbyk7CiAgICAgICAgICAgICAgICBjYWxsYmFja19sb29wX2NvbnRleHQgPSBOVUxMOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKiBkZWNpZGUgd2hpY2ggKEdFVE5FWFQpIHJlcXVlc3RzIGFyZSBub3QgeWV0IGZpbGxlZCAqLwogICAgICAgICAgICBpZiAocmVxaW5mby0+bW9kZSA9PSBNT0RFX0dFVE5FWFQpIHsKICAgICAgICAgICAgICAgIGZvcihyZXF1ZXN0ID0gcmVxdWVzdHMgOyByZXF1ZXN0OyByZXF1ZXN0ID0gcmVxdWVzdC0+bmV4dCkgewogICAgICAgICAgICAgICAgICAgIGlmIChyZXF1ZXN0LT5wcm9jZXNzZWQpCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgIHRpX2luZm8gPSAodGlfY2FjaGVfaW5mbyopCiAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfcmVxdWVzdF9nZXRfbGlzdF9kYXRhKHJlcXVlc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRJX1JFUVVFU1RfQ0FDSEUpOwogICAgICAgICAgICAgICAgICAgIGlmICghdGlfaW5mby0+cmVzdWx0cykgewogICAgICAgICAgICAgICAgICAgICAgaW50IG5jOwogICAgICAgICAgICAgICAgICAgICAgICB0YWJsZV9pbmZvID0gbmV0c25tcF9leHRyYWN0X3RhYmxlX2luZm8ocmVxdWVzdCk7CiAgICAgICAgICAgICAgICAgICAgICAgIG5jID0gbmV0c25tcF90YWJsZV9uZXh0X2NvbHVtbih0YWJsZV9pbmZvKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKDAgPT0gbmMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9pZFtyZWdpbmZvLT5yb290b2lkX2xlbisxXSA9IHRhYmxlX2luZm8tPmNvbG51bSsxOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgc25tcF9zZXRfdmFyX29iamlkKHJlcXVlc3QtPnJlcXVlc3R2YiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvaWQsIHJlZ2luZm8tPnJvb3RvaWRfbGVuKzIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdC0+cHJvY2Vzc2VkID0gVEFCTEVfSVRFUkFUT1JfTk9UQUdBSU47CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICB0YWJsZV9pbmZvLT5jb2xudW0gPSBuYzsKICAgICAgICAgICAgICAgICAgICAgICAgICBoaW50b2sgPSAwOwogICAgICAgICAgICAgICAgICAgICAgICAgIG5vdGRvbmUgPSAxOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIGlmIChyZXFpbmZvLT5tb2RlID09IE1PREVfR0VUIHx8CiAgICAgICAgcmVxaW5mby0+bW9kZSA9PSBNT0RFX0dFVE5FWFQgfHwKICAgICAgICByZXFpbmZvLT5tb2RlID09IE1PREVfU0VUX1JFU0VSVkUxKSB7CiAgICAgICAgLyogcGVyIHJlcXVlc3QgbGFzdCBtaW51dGUgcHJvY2Vzc2luZyAqLwogICAgICAgIGZvcihyZXF1ZXN0ID0gcmVxdWVzdHMgOyByZXF1ZXN0OyByZXF1ZXN0ID0gcmVxdWVzdC0+bmV4dCkgewogICAgICAgICAgICBpZiAocmVxdWVzdC0+cHJvY2Vzc2VkKQogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIHRpX2luZm8gPSAodGlfY2FjaGVfaW5mbyopCiAgICAgICAgICAgICAgICBuZXRzbm1wX3JlcXVlc3RfZ2V0X2xpc3RfZGF0YShyZXF1ZXN0LCBUSV9SRVFVRVNUX0NBQ0hFKTsKICAgICAgICAgICAgdGFibGVfaW5mbyA9CiAgICAgICAgICAgICAgICBuZXRzbm1wX2V4dHJhY3RfdGFibGVfaW5mbyhyZXF1ZXN0KTsKCiAgICAgICAgICAgIGlmICghdGlfaW5mbykKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIAogICAgICAgICAgICBzd2l0Y2gocmVxaW5mby0+bW9kZSkgewoKICAgICAgICAgICAgY2FzZSBNT0RFX0dFVE5FWFQ6CiAgICAgICAgICAgICAgICBpZiAodGlfaW5mby0+YmVzdF9tYXRjaF9sZW4pCiAgICAgICAgICAgICAgICAgICAgc25tcF9zZXRfdmFyX29iamlkKHJlcXVlc3QtPnJlcXVlc3R2YiwgdGlfaW5mby0+YmVzdF9tYXRjaCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGlfaW5mby0+YmVzdF9tYXRjaF9sZW4pOwogICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgY29sb2lkW3JlZ2luZm8tPnJvb3RvaWRfbGVuKzFdID0gCiAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfdGFibGVfbmV4dF9jb2x1bW4odGFibGVfaW5mbyk7CiAgICAgICAgICAgICAgICAgICAgaWYgKDAgPT0gY29sb2lkW3JlZ2luZm8tPnJvb3RvaWRfbGVuKzFdKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIG91dCBvZiByYW5nZS4gKi8KICAgICAgICAgICAgICAgICAgICAgICAgY29sb2lkW3JlZ2luZm8tPnJvb3RvaWRfbGVuKzFdID0gdGJsX2luZm8tPm1heF9jb2x1bW4gKyAxOwogICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0LT5wcm9jZXNzZWQgPSBUQUJMRV9JVEVSQVRPUl9OT1RBR0FJTjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgc25tcF9zZXRfdmFyX29iamlkKHJlcXVlc3QtPnJlcXVlc3R2YiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb2lkLCByZWdpbmZvLT5yb290b2lkX2xlbisyKTsKICAgICAgICAgICAgICAgICAgICByZXF1ZXN0LT5wcm9jZXNzZWQgPSAxOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgc25tcF9mcmVlX3ZhcmJpbmQodGFibGVfaW5mby0+aW5kZXhlcyk7CiAgICAgICAgICAgICAgICB0YWJsZV9pbmZvLT5pbmRleGVzID0gc25tcF9jbG9uZV92YXJiaW5kKHRpX2luZm8tPnJlc3VsdHMpOwogICAgICAgICAgICAgICAgLyogRkFMTCBUSFJPVUdIICovCgogICAgICAgICAgICBjYXNlIE1PREVfR0VUOgogICAgICAgICAgICBjYXNlIE1PREVfU0VUX1JFU0VSVkUxOgogICAgICAgICAgICAgICAgaWYgKHRpX2luZm8tPmRhdGFfY29udGV4dCkKICAgICAgICAgICAgICAgICAgICAvKiB3ZSBkb24ndCBhZGQgYSBmcmVlIHBvaW50ZXIsIHNpbmNlIGl0J3MgaW4gdGhlCiAgICAgICAgICAgICAgICAgICAgICAgVElfUkVRVUVTVF9DQUNIRSBpbnN0ZWFkICovCiAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9yZXF1ZXN0X2FkZF9saXN0X2RhdGEocmVxdWVzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2NyZWF0ZV9kYXRhX2xpc3QKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoVEFCTEVfSVRFUkFUT1JfTkFNRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGlfaW5mby0+ZGF0YV9jb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMKSk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgCiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgLyogd2UgY2hhbmdlIGFsbCBHRVRORVhUIG9wZXJhdGlvbnMgaW50byBHRVQgb3BlcmF0aW9ucy4KICAgICAgICAgICB3aHk/IGJlY2F1c2Ugd2UncmUganVzdCBzbyBuaWNlIHRvIHRoZSBsb3dlciBsZXZlbHMuCiAgICAgICAgICAgbWF5YmUgc29tZWRheSB0aGV5J2xsIHBheSB1cyBmb3IgaXQuICBkb3VidGZ1bCB0aG91Z2guICovCiAgICAgICAgb2xkbW9kZSA9IHJlcWluZm8tPm1vZGU7CiAgICAgICAgaWYgKHJlcWluZm8tPm1vZGUgPT0gTU9ERV9HRVRORVhUKSB7CiAgICAgICAgICAgIHJlcWluZm8tPm1vZGUgPSBNT0RFX0dFVDsKICAgICAgICB9CiAgICB9IGVsc2UgaWYgKHJlcWluZm8tPm1vZGUgPT0gTU9ERV9HRVRfU1RBU0gpIHsKICAgICAgICBuZXRzbm1wX2ZyZWVfcmVxdWVzdF9kYXRhX3NldHMocmVxdG1wKTsKICAgICAgICBTTk1QX0ZSRUUocmVxdG1wKTsKICAgICAgICB0YWJsZV9pbmZvLT5pbmRleGVzID0gb2xkX2luZGV4ZXM7CiAgICB9CgoKICAgIC8qIEZpbmFsbHksIHdlIGdldCB0byBjYWxsIHRoZSBuZXh0IGhhbmRsZXIgYmVsb3cgdXMuICBCb3ksIHdhc24ndAogICAgICAgYWxsIHRoYXQgc2ltcGxlPyAgVGhleSBiZXR0ZXIgYmUgZ2xhZCB0aGV5IGRvbid0IGhhdmUgdG8gZG8gaXQhICovCiAgICBpZiAocmVxaW5mby0+bW9kZSAhPSBNT0RFX0dFVF9TVEFTSCkgewogICAgICAgIERFQlVHTVNHVEwoKCJ0YWJsZV9pdGVyYXRvciIsICJjYWxsIHN1YmhhbmRsZXIgZm9yIG1vZGU6ICVzXG4iLAogICAgICAgICAgICAgICAgICAgIHNlX2ZpbmRfbGFiZWxfaW5fc2xpc3QoImFnZW50X21vZGUiLCBvbGRtb2RlKSkpOwogICAgICAgIHJldCA9CiAgICAgICAgICAgIG5ldHNubXBfY2FsbF9uZXh0X2hhbmRsZXIoaGFuZGxlciwgcmVnaW5mbywgcmVxaW5mbywgcmVxdWVzdHMpOwogICAgfQoKICAgIC8qIHJldmVyc2UgdGhlIHByZXZpb3VzbHkgc2F2ZWQgbW9kZSBpZiB3ZSB3ZXJlIGEgZ2V0bmV4dCAqLwogICAgaWYgKG9sZG1vZGUgPT0gTU9ERV9HRVRORVhUKSB7CiAgICAgICAgcmVxaW5mby0+bW9kZSA9IG9sZG1vZGU7CiAgICB9CgogICAgLyogY2xlYW51cCAqLwogICAgaWYgKGZyZWVfdGhpc19pbmRleF9zZWFyY2gpCiAgICAgICAgc25tcF9mcmVlX3ZhcmJpbmQoZnJlZV90aGlzX2luZGV4X3NlYXJjaCk7CgogICAgcmV0dXJuIHJldDsKfQoKLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKgogKiBJdGVyYXRvciBBUEk6IFJvdyBvcGVyYXRpb25zCiAqCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi8KCnZvaWQgKgpuZXRzbm1wX2l0ZXJhdG9yX3Jvd19maXJzdCggbmV0c25tcF9pdGVyYXRvcl9pbmZvICppaW5mbyApIHsKICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqdnAxLCAqdnAyOwogICAgdm9pZCAqY3R4MSwgKmN0eDI7CgogICAgaWYgKCFpaW5mbykKICAgICAgICByZXR1cm4gTlVMTDsKCiAgICB2cDEgPSBzbm1wX2Nsb25lX3ZhcmJpbmQoaWluZm8tPmluZGV4ZXMpOwogICAgdnAyID0gaWluZm8tPmdldF9maXJzdF9kYXRhX3BvaW50KCAmY3R4MSwgJmN0eDIsIHZwMSwgaWluZm8gKTsKCiAgICBpZiAoIXZwMikKICAgICAgICBjdHgyID0gTlVMTDsKCiAgICAvKiBmcmVlIGxvb3AgY29udGV4dCA/PyAqLwogICAgc25tcF9mcmVlX3ZhcmJpbmQoIHZwMSApOwogICAgcmV0dXJuIGN0eDI7ICAvKiBvciAqY3R4MiA/PyAqLwp9Cgp2b2lkICoKbmV0c25tcF9pdGVyYXRvcl9yb3dfZ2V0KCBuZXRzbm1wX2l0ZXJhdG9yX2luZm8gKmlpbmZvLCB2b2lkICpyb3cgKQp7CiAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKnZwMSwgKnZwMjsKICAgIHZvaWQgKmN0eDEsICpjdHgyOwoKICAgIGlmICghaWluZm8gfHwgIXJvdykKICAgICAgICByZXR1cm4gTlVMTDsKCiAgICAgICAgLyoKICAgICAgICAgKiBUaGlzIHJvdXRpbmUgcmVsaWVzIG9uIGJlaW5nIGFibGUgdG8KICAgICAgICAgKiAgIGRldGVybWluZSB0aGUgaW5kZXhlcyBmb3IgYSBnaXZlbiByb3cuICAKICAgICAgICAgKi8KICAgIGlmICghaWluZm8tPmdldF9yb3dfaW5kZXhlcykKICAgICAgICByZXR1cm4gTlVMTDsKCiAgICB2cDEgID0gc25tcF9jbG9uZV92YXJiaW5kKGlpbmZvLT5pbmRleGVzKTsKICAgIGN0eDEgPSByb3c7ICAgLyogUHJvYmFibHkgb25seSBuZWVkIG9uZSBvZiB0aGVzZSAuLi4gKi8KICAgIGN0eDIgPSByb3c7CiAgICB2cDIgID0gaWluZm8tPmdldF9yb3dfaW5kZXhlcyggJmN0eDEsICZjdHgyLCB2cDEsIGlpbmZvICk7CgogICAgY3R4MiA9IE5VTEw7CiAgICBpZiAodnAyKSB7CiAgICAgICAgY3R4MiA9IG5ldHNubXBfaXRlcmF0b3Jfcm93X2dldF9ieWlkeCggaWluZm8sIHZwMiApOwogICAgfQogICAgc25tcF9mcmVlX3ZhcmJpbmQoIHZwMSApOwogICAgcmV0dXJuIGN0eDI7Cn0KCnZvaWQgKgpuZXRzbm1wX2l0ZXJhdG9yX3Jvd19uZXh0KCBuZXRzbm1wX2l0ZXJhdG9yX2luZm8gKmlpbmZvLCB2b2lkICpyb3cgKQp7CiAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKnZwMSwgKnZwMjsKICAgIHZvaWQgKmN0eDEsICpjdHgyOwoKICAgIGlmICghaWluZm8gfHwgIXJvdykKICAgICAgICByZXR1cm4gTlVMTDsKCiAgICAgICAgLyoKICAgICAgICAgKiBUaGlzIHJvdXRpbmUgcmVsaWVzIG9uIGJlaW5nIGFibGUgdG8KICAgICAgICAgKiAgIGRldGVybWluZSB0aGUgaW5kZXhlcyBmb3IgYSBnaXZlbiByb3cuICAKICAgICAgICAgKi8KICAgIGlmICghaWluZm8tPmdldF9yb3dfaW5kZXhlcykKICAgICAgICByZXR1cm4gTlVMTDsKCiAgICB2cDEgID0gc25tcF9jbG9uZV92YXJiaW5kKGlpbmZvLT5pbmRleGVzKTsKICAgIGN0eDEgPSByb3c7ICAgLyogUHJvYmFibHkgb25seSBuZWVkIG9uZSBvZiB0aGVzZSAuLi4gKi8KICAgIGN0eDIgPSByb3c7CiAgICB2cDIgID0gaWluZm8tPmdldF9yb3dfaW5kZXhlcyggJmN0eDEsICZjdHgyLCB2cDEsIGlpbmZvICk7CgogICAgY3R4MiA9IE5VTEw7CiAgICBpZiAodnAyKSB7CiAgICAgICAgY3R4MiA9IG5ldHNubXBfaXRlcmF0b3Jfcm93X25leHRfYnlpZHgoIGlpbmZvLCB2cDIgKTsKICAgIH0KICAgIHNubXBfZnJlZV92YXJiaW5kKCB2cDEgKTsKICAgIHJldHVybiBjdHgyOwp9Cgp2b2lkICoKbmV0c25tcF9pdGVyYXRvcl9yb3dfZ2V0X2J5aWR4KCAgbmV0c25tcF9pdGVyYXRvcl9pbmZvICppaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICppbmRleGVzICkKewogICAgb2lkICAgIGR1bW15W10gPSB7MCwwfTsgICAvKiBLZWVwICdidWlsZF9vaWQnIGhhcHB5ICovCiAgICBvaWQgICAgaW5zdGFuY2VbTUFYX09JRF9MRU5dOwogICAgc2l6ZV90IGxlbiA9ICAgIE1BWF9PSURfTEVOOwoKICAgIGlmICghaWluZm8gfHwgIWluZGV4ZXMpCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgYnVpbGRfb2lkX25vYWxsb2MoaW5zdGFuY2UsIE1BWF9PSURfTEVOLCAmbGVuLAogICAgICAgICAgICAgICAgICAgICAgZHVtbXksIDIsIGluZGV4ZXMpOwogICAgcmV0dXJuIG5ldHNubXBfaXRlcmF0b3Jfcm93X2dldF9ieW9pZCggaWluZm8sIGluc3RhbmNlKzIsIGxlbi0yICk7Cn0KCnZvaWQgKgpuZXRzbm1wX2l0ZXJhdG9yX3Jvd19uZXh0X2J5aWR4KCBuZXRzbm1wX2l0ZXJhdG9yX2luZm8gKmlpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKmluZGV4ZXMgKQp7CiAgICBvaWQgICAgZHVtbXlbXSA9IHswLDB9OwogICAgb2lkICAgIGluc3RhbmNlW01BWF9PSURfTEVOXTsKICAgIHNpemVfdCBsZW4gPSAgICBNQVhfT0lEX0xFTjsKCiAgICBpZiAoIWlpbmZvIHx8ICFpbmRleGVzKQogICAgICAgIHJldHVybiBOVUxMOwoKICAgIGJ1aWxkX29pZF9ub2FsbG9jKGluc3RhbmNlLCBNQVhfT0lEX0xFTiwgJmxlbiwKICAgICAgICAgICAgICAgICAgICAgIGR1bW15LCAyLCBpbmRleGVzKTsKICAgIHJldHVybiBuZXRzbm1wX2l0ZXJhdG9yX3Jvd19uZXh0X2J5b2lkKCBpaW5mbywgaW5zdGFuY2UrMiwgbGVuLTIgKTsKfQoKdm9pZCAqCm5ldHNubXBfaXRlcmF0b3Jfcm93X2dldF9ieW9pZCggIG5ldHNubXBfaXRlcmF0b3JfaW5mbyAqaWluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9pZCAqaW5zdGFuY2UsIHNpemVfdCBsZW4gKQp7CiAgICBvaWQgICAgZHVtbXlbXSA9IHswLDB9OwogICAgb2lkICAgIHRoaXNfaW5zdFsgTUFYX09JRF9MRU5dOwogICAgc2l6ZV90IHRoaXNfbGVuOwogICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICp2cDEsICp2cDI7CiAgICB2b2lkICpjdHgxLCAqY3R4MjsKICAgIGludCAgIG47CgogICAgaWYgKCFpaW5mbyB8fCAhaWluZm8tPmdldF9maXJzdF9kYXRhX3BvaW50CiAgICAgICAgICAgICAgIHx8ICFpaW5mby0+Z2V0X25leHRfZGF0YV9wb2ludCApCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgaWYgKCAhaW5zdGFuY2UgfHwgIWxlbiApCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgdnAxID0gc25tcF9jbG9uZV92YXJiaW5kKGlpbmZvLT5pbmRleGVzKTsKICAgIHZwMiA9IGlpbmZvLT5nZXRfZmlyc3RfZGF0YV9wb2ludCggJmN0eDEsICZjdHgyLCB2cDEsIGlpbmZvICk7CiAgICBERUJVR01TR1RMKCgidGFibGU6aXRlcmF0b3I6Z2V0IiwgImZpcnN0IERQOiAlcCAlcCAlcFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4MSwgY3R4MiwgdnAyKSk7CgogICAgLyogWFhYIC0gZnJlZSBjb250ZXh0ID8gKi8KICAgIAogICAgd2hpbGUgKCB2cDIgKSB7CiAgICAgICAgdGhpc19sZW4gPSBNQVhfT0lEX0xFTjsKICAgICAgICBidWlsZF9vaWRfbm9hbGxvYyh0aGlzX2luc3QsIE1BWF9PSURfTEVOLCAmdGhpc19sZW4sIGR1bW15LCAyLCB2cDIpOwogICAgICAgIG4gPSBzbm1wX29pZF9jb21wYXJlKCBpbnN0YW5jZSwgbGVuLCB0aGlzX2luc3QrMiwgdGhpc19sZW4tMiApOwogICAgICAgIGlmICggbiA9PSAwICkKICAgICAgICAgICAgYnJlYWs7ICAvKiBGb3VuZCBtYXRjaGluZyByb3cgKi8KCiAgICAgICAgaWYgKCggbiA+IDApICYmCiAgICAgICAgICAgIChpaW5mby0+ZmxhZ3MgJiBORVRTTk1QX0lURVJBVE9SX0ZMQUdfU09SVEVEKSkgewogICAgICAgICAgICB2cDIgPSBOVUxMOyAgLyogUm93IG5vdCBwcmVzZW50ICovCiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICAKICAgICAgICB2cDIgPSBpaW5mby0+Z2V0X25leHRfZGF0YV9wb2ludCggJmN0eDEsICZjdHgyLCB2cDIsIGlpbmZvICk7CiAgICAgICAgREVCVUdNU0dUTCgoInRhYmxlOml0ZXJhdG9yOmdldCIsICJuZXh0IERQOiAlcCAlcCAlcFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eDEsIGN0eDIsIHZwMikpOwogICAgICAgIC8qIFhYWCAtIGZyZWUgY29udGV4dCA/ICovCiAgICB9CiAgICAgICAgICAgCiAgICAvKiBYWFggLSBmaW5hbCBmcmVlIGNvbnRleHQgPyAqLwogICAgc25tcF9mcmVlX3ZhcmJpbmQoIHZwMSApOwoKICAgIHJldHVybiAoIHZwMiA/IGN0eDIgOiBOVUxMICk7Cn0KCnZvaWQgKgpuZXRzbm1wX2l0ZXJhdG9yX3Jvd19uZXh0X2J5b2lkKCBuZXRzbm1wX2l0ZXJhdG9yX2luZm8gKmlpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvaWQgKmluc3RhbmNlLCBzaXplX3QgbGVuICkKewogICAgb2lkICAgIGR1bW15W10gPSB7MCwwfTsKICAgIG9pZCAgICB0aGlzX2luc3RbIE1BWF9PSURfTEVOXTsKICAgIHNpemVfdCB0aGlzX2xlbjsKICAgIG9pZCAgICBiZXN0X2luc3RbIE1BWF9PSURfTEVOXTsKICAgIHNpemVfdCBiZXN0X2xlbiA9IDA7CiAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKnZwMSwgKnZwMjsKICAgIHZvaWQgKmN0eDEsICpjdHgyOwogICAgaW50ICAgbjsKCiAgICBpZiAoIWlpbmZvIHx8ICFpaW5mby0+Z2V0X2ZpcnN0X2RhdGFfcG9pbnQKICAgICAgICAgICAgICAgfHwgIWlpbmZvLT5nZXRfbmV4dF9kYXRhX3BvaW50ICkKICAgICAgICByZXR1cm4gTlVMTDsKCiAgICB2cDEgPSBzbm1wX2Nsb25lX3ZhcmJpbmQoaWluZm8tPmluZGV4ZXMpOwogICAgdnAyID0gaWluZm8tPmdldF9maXJzdF9kYXRhX3BvaW50KCAmY3R4MSwgJmN0eDIsIHZwMSwgaWluZm8gKTsKICAgIERFQlVHTVNHVEwoKCJ0YWJsZTppdGVyYXRvcjpnZXQiLCAiZmlyc3QgRFA6ICVwICVwICVwXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHgxLCBjdHgyLCB2cDIpKTsKCiAgICBpZiAoICFpbnN0YW5jZSB8fCAhbGVuICkgewogICAgICAgIHNubXBfZnJlZV92YXJiaW5kKCB2cDEgKTsKICAgICAgICByZXR1cm4gKCB2cDIgPyBjdHgyIDogTlVMTCApOyAgIC8qIEZpcnN0IGVudHJ5ICovCiAgICB9CgogICAgLyogWFhYIC0gZnJlZSBjb250ZXh0ID8gKi8KICAgIAogICAgd2hpbGUgKCB2cDIgKSB7CiAgICAgICAgdGhpc19sZW4gPSBNQVhfT0lEX0xFTjsKICAgICAgICBidWlsZF9vaWRfbm9hbGxvYyh0aGlzX2luc3QsIE1BWF9PSURfTEVOLCAmdGhpc19sZW4sIGR1bW15LCAyLCB2cDIpOwogICAgICAgIG4gPSBzbm1wX29pZF9jb21wYXJlKCBpbnN0YW5jZSwgbGVuLCB0aGlzX2luc3QrMiwgdGhpc19sZW4tMiApOwoKICAgICAgICAvKgogICAgICAgICAqIExvb2sgZm9yIHRoZSBiZXN0LWZpdCBjYW5kaWRhdGUgZm9yIHRoZSBuZXh0IHJvdwogICAgICAgICAqICAgKGJlYXJpbmcgaW4gbWluZCB0aGUgcm93cyBtYXkgbm90IGJlIG9yZGVyZWQgImNvcnJlY3RseSIpCiAgICAgICAgICovCiAgICAgICAgaWYgKCBuID4gMCApIHsKICAgICAgICAgICAgaWYgKCBiZXN0X2xlbiA9PSAwICkgewogICAgICAgICAgICAgICAgbWVtY3B5KCBiZXN0X2luc3QsIHRoaXNfaW5zdCwgc2l6ZW9mKCB0aGlzX2luc3QgKSk7CiAgICAgICAgICAgICAgICBiZXN0X2xlbiA9IHRoaXNfbGVuOwogICAgICAgICAgICAgICAgaWYgKGlpbmZvLT5mbGFncyAmIE5FVFNOTVBfSVRFUkFUT1JfRkxBR19TT1JURUQpCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBuID0gc25tcF9vaWRfY29tcGFyZSggYmVzdF9pbnN0LCBiZXN0X2xlbiwgdGhpc19pbnN0LCB0aGlzX2xlbiApOwogICAgICAgICAgICAgICAgaWYgKCBuIDwgMCApIHsKICAgICAgICAgICAgICAgICAgICBtZW1jcHkoIGJlc3RfaW5zdCwgdGhpc19pbnN0LCBzaXplb2YoIHRoaXNfaW5zdCApKTsKICAgICAgICAgICAgICAgICAgICBiZXN0X2xlbiA9IHRoaXNfbGVuOwogICAgICAgICAgICAgICAgICAgIGlmIChpaW5mby0+ZmxhZ3MgJiBORVRTTk1QX0lURVJBVE9SX0ZMQUdfU09SVEVEKQogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICB2cDIgPSBpaW5mby0+Z2V0X25leHRfZGF0YV9wb2ludCggJmN0eDEsICZjdHgyLCB2cDIsIGlpbmZvICk7CiAgICAgICAgREVCVUdNU0dUTCgoInRhYmxlOml0ZXJhdG9yOmdldCIsICJuZXh0IERQOiAlcCAlcCAlcFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eDEsIGN0eDIsIHZwMikpOwogICAgICAgIC8qIFhYWCAtIGZyZWUgY29udGV4dCA/ICovCiAgICB9CiAgICAgICAgICAgCiAgICAvKiBYWFggLSBmaW5hbCBmcmVlIGNvbnRleHQgPyAqLwogICAgc25tcF9mcmVlX3ZhcmJpbmQoIHZwMSApOwoKICAgIHJldHVybiAoIHZwMiA/IGN0eDIgOiBOVUxMICk7Cn0KCmludApuZXRzbm1wX2l0ZXJhdG9yX3Jvd19jb3VudCggbmV0c25tcF9pdGVyYXRvcl9pbmZvICppaW5mbyApCnsKICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqdnAxLCAqdnAyOwogICAgdm9pZCAqY3R4MSwgKmN0eDI7CiAgICBpbnQgICBpPTA7CgogICAgaWYgKCFpaW5mbyB8fCAhaWluZm8tPmdldF9maXJzdF9kYXRhX3BvaW50CiAgICAgICAgICAgICAgIHx8ICFpaW5mby0+Z2V0X25leHRfZGF0YV9wb2ludCApCiAgICAgICAgcmV0dXJuIDA7CgogICAgdnAxID0gc25tcF9jbG9uZV92YXJiaW5kKGlpbmZvLT5pbmRleGVzKTsKICAgIHZwMiA9IGlpbmZvLT5nZXRfZmlyc3RfZGF0YV9wb2ludCggJmN0eDEsICZjdHgyLCB2cDEsIGlpbmZvICk7CiAgICBpZiAoIXZwMikgewogICAgICAgIHNubXBfZnJlZV92YXJiaW5kKCB2cDEgKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KICAgIAogICAgREVCVUdNU0dUTCgoInRhYmxlOml0ZXJhdG9yOmNvdW50IiwgImZpcnN0IERQOiAlcCAlcCAlcFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHgxLCBjdHgyLCB2cDIpKTsKCiAgICAvKiBYWFggLSBmcmVlIGNvbnRleHQgPyAqLwoKICAgIHdoaWxlICh2cDIpIHsKICAgICAgICBpKys7CiAgICAgICAgdnAyID0gaWluZm8tPmdldF9uZXh0X2RhdGFfcG9pbnQoICZjdHgxLCAmY3R4MiwgdnAyLCBpaW5mbyApOwogICAgICAgIERFQlVHTVNHVEwoKCJ0YWJsZTppdGVyYXRvcjpjb3VudCIsICJuZXh0IERQOiAlcCAlcCAlcCAoJWQpXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHgxLCBjdHgyLCB2cDIsIGkpKTsKICAgICAgICAvKiBYWFggLSBmcmVlIGNvbnRleHQgPyAqLwogICAgfQogICAgICAgICAgIAogICAgLyogWFhYIC0gZmluYWwgZnJlZSBjb250ZXh0ID8gKi8KICAgIHNubXBfZnJlZV92YXJiaW5kKCB2cDEgKTsKICAgIHJldHVybiBpOwp9CgoKLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKgogKiBJdGVyYXRvciBBUEk6IEluZGV4IG9wZXJhdGlvbnMKICoKICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqLwoKCi8qKiBAfSAqLwo=