LyoKKiBDb3B5cmlnaHQgqSB7MTk5OX0sIEludGVybmF0aW9uYWwgQnVzaW5lc3MgTWFjaGluZXMgQ29ycG9yYXRpb24gYW5kIG90aGVycy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqICAgRGF0ZSAgICAgICAgTmFtZSAgICAgICAgRGVzY3JpcHRpb24KKiAgIDExLzE3Lzk5ICAgIGFsaXUgICAgICAgIENyZWF0aW9uLgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiovCiNpZm5kZWYgUkJUX1JVTEVfSAojZGVmaW5lIFJCVF9SVUxFX0gKCiNpbmNsdWRlICJ1bmljb2RlL3VuaXN0ci5oIgoKY2xhc3MgUmVwbGFjZWFibGU7CmNsYXNzIFRyYW5zbGl0ZXJhdGlvblJ1bGVEYXRhOwpjbGFzcyBVbmljb2RlRmlsdGVyOwoKLyoqCiAqIEEgdHJhbnNsaXRlcmF0aW9uIHJ1bGUgdXNlZCBieQogKiA8Y29kZT5SdWxlQmFzZWRUcmFuc2xpdGVyYXRvcjwvY29kZT4uCiAqIDxjb2RlPlRyYW5zbGl0ZXJhdGlvblJ1bGU8L2NvZGU+IGlzIGFuIGltbXV0YWJsZSBvYmplY3QuCiAqCiAqIDxwPkEgcnVsZSBjb25zaXN0cyBvZiBhbiBpbnB1dCBwYXR0ZXJuIGFuZCBhbiBvdXRwdXQgc3RyaW5nLiAgV2hlbgogKiB0aGUgaW5wdXQgcGF0dGVybiBpcyBtYXRjaGVkLCB0aGUgb3V0cHV0IHN0cmluZyBpcyBlbWl0dGVkLiAgVGhlCiAqIGlucHV0IHBhdHRlcm4gY29uc2lzdHMgb2YgemVybyBvciBtb3JlIGNoYXJhY3RlcnMgd2hpY2ggYXJlIG1hdGNoZWQKICogZXhhY3RseSAodGhlIGtleSkgYW5kIG9wdGlvbmFsIGNvbnRleHQuICBDb250ZXh0IG11c3QgbWF0Y2ggaWYgaXQKICogaXMgc3BlY2lmaWVkLiAgQ29udGV4dCBtYXkgYmUgc3BlY2lmaWVkIGJlZm9yZSB0aGUga2V5LCBhZnRlciB0aGUKICoga2V5LCBvciBib3RoLiAgVGhlIGtleSwgcHJlY2VkaW5nIGNvbnRleHQsIGFuZCBmb2xsb3dpbmcgY29udGV4dAogKiBtYXkgY29udGFpbiB2YXJpYWJsZXMuICBWYXJpYWJsZXMgcmVwcmVzZW50IGEgc2V0IG9mIFVuaWNvZGUKICogY2hhcmFjdGVycywgc3VjaCBhcyB0aGUgbGV0dGVycyA8aT5hPC9pPiB0aHJvdWdoIDxpPno8L2k+LgogKiBWYXJpYWJsZXMgYXJlIGRldGVjdGVkIGJ5IGxvb2tpbmcgdXAgZWFjaCBjaGFyYWN0ZXIgaW4gYSBzdXBwbGllZAogKiB2YXJpYWJsZSBsaXN0IHRvIHNlZSBpZiBpdCBoYXMgYmVlbiBzbyBkZWZpbmVkLiAKICoKICogQGF1dGhvciBBbGFuIExpdQogKi8KY2xhc3MgVHJhbnNsaXRlcmF0aW9uUnVsZSB7CgpwdWJsaWM6CgogICAgLyoqCiAgICAgKiBDb25zdGFudHMgcmV0dXJuZWQgYnkgPGNvZGU+Z2V0TWF0Y2hEZWdyZWUoKTwvY29kZT4gaW5kaWNhdGluZwogICAgICogdGhlIGRlZ3JlZSBvZiBtYXRjaCBiZXR3ZWVuIHRoZSB0ZXh0IGFuZCB0aGlzIHJ1bGUuCiAgICAgKiBAc2VlICNnZXRNYXRjaERlZ3JlZQogICAgICovCiAgICBlbnVtIHsKICAgICAgICAvKioKICAgICAgICAgKiBDb25zdGFudCByZXR1cm5lZCBieSA8Y29kZT5nZXRNYXRjaERlZ3JlZSgpPC9jb2RlPgogICAgICAgICAqIGluZGljYXRpbmcgYSBtaXNtYXRjaCBiZXR3ZWVuIHRoZSB0ZXh0IGFuZCB0aGlzIHJ1bGUuICBPbmUKICAgICAgICAgKiBvciBtb3JlIGNoYXJhY3RlcnMgb2YgdGhlIGNvbnRleHQgb3Iga2V5IGRvIG5vdCBtYXRjaCB0aGUKICAgICAgICAgKiB0ZXh0LgogICAgICAgICAqLwogICAgICAgIE1JU01BVENILAoKICAgICAgICAvKioKICAgICAgICAgKiBDb25zdGFudCByZXR1cm5lZCBieSA8Y29kZT5nZXRNYXRjaERlZ3JlZSgpPC9jb2RlPgogICAgICAgICAqIGluZGljYXRpbmcgYSBwYXJ0aWFsIG1hdGNoIGJldHdlZW4gdGhlIHRleHQgYW5kIHRoaXMgcnVsZS4KICAgICAgICAgKiBBbGwgY2hhcmFjdGVycyBvZiB0aGUgdGV4dCBtYXRjaCB0aGUgY29ycmVzcG9uZGluZyBjb250ZXh0CiAgICAgICAgICogb3Iga2V5LCBidXQgbW9yZSBjaGFyYWN0ZXJzIGFyZSByZXF1aXJlZCBmb3IgYSBjb21wbGV0ZQogICAgICAgICAqIG1hdGNoLiAgVGhlcmUgYXJlIHNvbWUga2V5IG9yIGNvbnRleHQgY2hhcmFjdGVycyBhdCB0aGUgZW5kCiAgICAgICAgICogb2YgdGhlIHBhdHRlcm4gdGhhdCByZW1haW4gdW5tYXRjaGVkIGJlY2F1c2UgdGhlIHRleHQgaXNuJ3QKICAgICAgICAgKiBsb25nIGVub3VnaC4KICAgICAgICAgKi8KICAgICAgICBQQVJUSUFMX01BVENILAogICAgICAgIAogICAgICAgIC8qKgogICAgICAgICAqIENvbnN0YW50IHJldHVybmVkIGJ5IDxjb2RlPmdldE1hdGNoRGVncmVlKCk8L2NvZGU+CiAgICAgICAgICogaW5kaWNhdGluZyBhIGNvbXBsZXRlIG1hdGNoIGJldHdlZW4gdGhlIHRleHQgYW5kIHRoaXMgcnVsZS4KICAgICAgICAgKiBUaGUgdGV4dCBtYXRjaGVzIGFsbCBjb250ZXh0IGFuZCBrZXkgY2hhcmFjdGVycy4KICAgICAgICAgKi8KICAgICAgICBGVUxMX01BVENICiAgICB9OwoKcHJpdmF0ZToKCiAgICAvKioKICAgICAqIFRoZSBzdHJpbmcgdGhhdCBtdXN0IGJlIG1hdGNoZWQsIGNvbnNpc3Rpbmcgb2YgdGhlIGFudGVDb250ZXh0LCBrZXksCiAgICAgKiBhbmQgcG9zdENvbnRleHQsIGNvbmNhdGVuYXRlZCB0b2dldGhlciwgaW4gdGhhdCBvcmRlci4gIFNvbWUgY29tcG9uZW50cwogICAgICogbWF5IGJlIGVtcHR5ICh6ZXJvIGxlbmd0aCkuCiAgICAgKiBAc2VlIGFudGVDb250ZXh0TGVuZ3RoCiAgICAgKiBAc2VlIGtleUxlbmd0aAogICAgICovCiAgICBVbmljb2RlU3RyaW5nIHBhdHRlcm47CgogICAgLyoqCiAgICAgKiBUaGUgc3RyaW5nIHRoYXQgaXMgZW1pdHRlZCBpZiB0aGUga2V5LCBhbnRlQ29udGV4dCwgYW5kIHBvc3RDb250ZXh0CiAgICAgKiBhcmUgbWF0Y2hlZC4KICAgICAqLwogICAgVW5pY29kZVN0cmluZyBvdXRwdXQ7CgogICAgLyoqCiAgICAgKiBBcnJheSBvZiBzZWdtZW50cy4gIFRoZXNlIGFyZSBzZWdtZW50cyBvZiB0aGUgaW5wdXQgc3RyaW5nIHRoYXQgbWF5IGJlCiAgICAgKiByZWZlcmVuY2VkIGFuZCBhcHBlYXIgaW4gdGhlIG91dHB1dCBzdHJpbmcuICBFYWNoIHNlZ21lbnQgaXMgc3RvcmVkIGFzIGFuCiAgICAgKiBvZmZzZXQsIGxpbWl0IHBhaXIuICBTZWdtZW50cyBhcmUgcmVmZXJlbmNlZCBieSBhIDEtYmFzZWQgaW5kZXg7CiAgICAgKiByZWZlcmVuY2UgaSB0aHVzIGluY2x1ZGVzIGNoYXJhY3RlcnMgYXQgb2Zmc2V0IHNlZ21lbnRzWzIqaS0yXSB0bwogICAgICogc2VnbWVudHNbMippLTFdLTEgaW4gdGhlIHBhdHRlcm4gc3RyaW5nLgogICAgICoKICAgICAqIEluIHRoZSBvdXRwdXQgc3RyaW5nLCBhIHNlZ21lbnQgcmVmZXJlbmNlIGlzIGluZGljYXRlZCBieSBhIGNoYXJhY3RlciBpbgogICAgICogYSBzcGVjaWFsIHJhbmdlLCBhcyBkZWZpbmVkIGJ5IFJ1bGVCYXNlZFRyYW5zbGl0ZXJhdG9yLkRhdGEuCiAgICAgKgogICAgICogTW9zdCBydWxlcyBoYXZlIG5vIHNlZ21lbnRzLCBpbiB3aGljaCBjYXNlIHNlZ21lbnRzIGlzIG51bGwsIGFuZCB0aGUKICAgICAqIG91dHB1dCBzdHJpbmcgbmVlZCBub3QgYmUgY2hlY2tlZCBmb3Igc2VnbWVudCByZWZlcmVuY2UgY2hhcmFjdGVycy4KICAgICAqLwogICAgaW50MzJfdCogc2VnbWVudHM7CgogICAgLyoqCiAgICAgKiBUaGUgbGVuZ3RoIG9mIHRoZSBzdHJpbmcgdGhhdCBtdXN0IG1hdGNoIGJlZm9yZSB0aGUga2V5LiAgSWYKICAgICAqIHplcm8sIHRoZW4gdGhlcmUgaXMgbm8gbWF0Y2hpbmcgcmVxdWlyZW1lbnQgYmVmb3JlIHRoZSBrZXkuCiAgICAgKiBTdWJzdHJpbmcgWzAsYW50ZUNvbnRleHRMZW5ndGgpIG9mIHBhdHRlcm4gaXMgdGhlIGFudGVDb250ZXh0LgogICAgICovCiAgICBpbnQzMl90IGFudGVDb250ZXh0TGVuZ3RoOwoKICAgIC8qKgogICAgICogVGhlIGxlbmd0aCBvZiB0aGUga2V5LiAgU3Vic3RyaW5nIFthbnRlQ29udGV4dExlbmd0aCwKICAgICAqIGFudGVDb250ZXh0TGVuZ3RoICsga2V5TGVuZ3RoKSBpcyB0aGUga2V5LgoKICAgICAqLwogICAgaW50MzJfdCBrZXlMZW5ndGg7CgogICAgLyoqCiAgICAgKiBUaGUgcG9zaXRpb24gb2YgdGhlIGN1cnNvciBhZnRlciBlbWl0dGluZyB0aGUgb3V0cHV0IHN0cmluZywgZnJvbSAwIHRvCiAgICAgKiBvdXRwdXQubGVuZ3RoKCkuICBGb3IgbW9zdCBydWxlcyB3aXRoIG5vIHNwZWNpYWwgY3Vyc29yIHNwZWNpZmljYXRpb24sCiAgICAgKiB0aGUgY3Vyc29yUG9zIGlzIG91dHB1dC5sZW5ndGgoKS4KICAgICAqLwogICAgaW50MzJfdCBjdXJzb3JQb3M7CgpwdWJsaWM6CgogICAgLyoqCiAgICAgKiBDb25zdHJ1Y3QgYSBuZXcgcnVsZSB3aXRoIHRoZSBnaXZlbiBpbnB1dCwgb3V0cHV0IHRleHQsIGFuZCBvdGhlcgogICAgICogYXR0cmlidXRlcy4gIEEgY3Vyc29yIHBvc2l0aW9uIG1heSBiZSBzcGVjaWZpZWQgZm9yIHRoZSBvdXRwdXQgdGV4dC4KICAgICAqIEBwYXJhbSBpbnB1dCBpbnB1dCBzdHJpbmcsIGluY2x1ZGluZyBrZXkgYW5kIG9wdGlvbmFsIGFudGUgYW5kCiAgICAgKiBwb3N0IGNvbnRleHQKICAgICAqIEBwYXJhbSBhbnRlQ29udGV4dFBvcyBvZmZzZXQgaW50byBpbnB1dCB0byBlbmQgb2YgYW50ZSBjb250ZXh0LCBvciAtMSBpZgogICAgICogbm9uZS4gIE11c3QgYmUgPD0gaW5wdXQubGVuZ3RoKCkgaWYgbm90IC0xLgogICAgICogQHBhcmFtIHBvc3RDb250ZXh0UG9zIG9mZnNldCBpbnRvIGlucHV0IHRvIHN0YXJ0IG9mIHBvc3QgY29udGV4dCwgb3IgLTEKICAgICAqIGlmIG5vbmUuICBNdXN0IGJlIDw9IGlucHV0Lmxlbmd0aCgpIGlmIG5vdCAtMSwgYW5kIG11c3QgYmUgPj0KICAgICAqIGFudGVDb250ZXh0UG9zLgogICAgICogQHBhcmFtIG91dHB1dCBvdXRwdXQgc3RyaW5nCiAgICAgKiBAcGFyYW0gY3Vyc29yUG9zIG9mZnNldCBpbnRvIG91dHB1dCBhdCB3aGljaCBjdXJzb3IgaXMgbG9jYXRlZCwgb3IgLTEgaWYKICAgICAqIG5vbmUuICBJZiBsZXNzIHRoYW4gemVybywgdGhlbiB0aGUgY3Vyc29yIGlzIHBsYWNlZCBhZnRlciB0aGUKICAgICAqIDxjb2RlPm91dHB1dDwvY29kZT47IHRoYXQgaXMsIC0xIGlzIGVxdWl2YWxlbnQgdG8KICAgICAqIDxjb2RlPm91dHB1dC5sZW5ndGgoKTwvY29kZT4uICBJZiBncmVhdGVyIHRoYW4KICAgICAqIDxjb2RlPm91dHB1dC5sZW5ndGgoKTwvY29kZT4gdGhlbiBhbiBleGNlcHRpb24gaXMgdGhyb3duLgogICAgICogQHBhcmFtIGFkb3B0ZWRTZWdzIGFycmF5IG9mIDJuIGludGVnZXJzLiAgRWFjaCBvZiBuIHBhaXJzIGNvbnNpc3RzIG9mIG9mZnNldCwKICAgICAqIGxpbWl0IGZvciBhIHNlZ21lbnQgb2YgdGhlIGlucHV0IHN0cmluZy4gIENoYXJhY3RlcnMgaW4gdGhlIG91dHB1dCBzdHJpbmcKICAgICAqIHJlZmVyIHRvIHRoZXNlIHNlZ21lbnRzIGlmIHRoZXkgYXJlIGluIGEgc3BlY2lhbCByYW5nZSBkZXRlcm1pbmVkIGJ5IHRoZQogICAgICogYXNzb2NpYXRlZCBSdWxlQmFzZWRUcmFuc2xpdGVyYXRvci5EYXRhIG9iamVjdC4gIE1heSBiZSBudWxsIGlmIHRoZXJlIGFyZQogICAgICogbm8gc2VnbWVudHMuCiAgICAgKi8KICAgIFRyYW5zbGl0ZXJhdGlvblJ1bGUoY29uc3QgVW5pY29kZVN0cmluZyYgaW5wdXQsCiAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QgYW50ZUNvbnRleHRQb3MsIGludDMyX3QgcG9zdENvbnRleHRQb3MsCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVuaWNvZGVTdHJpbmcmIG91dHB1dCwKICAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCBjdXJzb3JQb3MsIGludDMyX3QgY3Vyc29yT2Zmc2V0LAogICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90KiBhZG9wdGVkU2VncywKICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKTsKCiAgICAvKioKICAgICAqIENvbnN0cnVjdCBhIG5ldyBydWxlIHdpdGggdGhlIGdpdmVuIGlucHV0LCBvdXRwdXQgdGV4dCwgYW5kIG90aGVyCiAgICAgKiBhdHRyaWJ1dGVzLiAgQSBjdXJzb3IgcG9zaXRpb24gbWF5IGJlIHNwZWNpZmllZCBmb3IgdGhlIG91dHB1dCB0ZXh0LgogICAgICogQHBhcmFtIGlucHV0IGlucHV0IHN0cmluZywgaW5jbHVkaW5nIGtleSBhbmQgb3B0aW9uYWwgYW50ZSBhbmQKICAgICAqIHBvc3QgY29udGV4dAogICAgICogQHBhcmFtIGFudGVDb250ZXh0UG9zIG9mZnNldCBpbnRvIGlucHV0IHRvIGVuZCBvZiBhbnRlIGNvbnRleHQsIG9yIC0xIGlmCiAgICAgKiBub25lLiAgTXVzdCBiZSA8PSBpbnB1dC5sZW5ndGgoKSBpZiBub3QgLTEuCiAgICAgKiBAcGFyYW0gcG9zdENvbnRleHRQb3Mgb2Zmc2V0IGludG8gaW5wdXQgdG8gc3RhcnQgb2YgcG9zdCBjb250ZXh0LCBvciAtMQogICAgICogaWYgbm9uZS4gIE11c3QgYmUgPD0gaW5wdXQubGVuZ3RoKCkgaWYgbm90IC0xLCBhbmQgbXVzdCBiZSA+PQogICAgICogYW50ZUNvbnRleHRQb3MuCiAgICAgKiBAcGFyYW0gb3V0cHV0IG91dHB1dCBzdHJpbmcKICAgICAqIEBwYXJhbSBjdXJzb3JQb3Mgb2Zmc2V0IGludG8gb3V0cHV0IGF0IHdoaWNoIGN1cnNvciBpcyBsb2NhdGVkLCBvciAtMSBpZgogICAgICogbm9uZS4gIElmIGxlc3MgdGhhbiB6ZXJvLCB0aGVuIHRoZSBjdXJzb3IgaXMgcGxhY2VkIGFmdGVyIHRoZQogICAgICogPGNvZGU+b3V0cHV0PC9jb2RlPjsgdGhhdCBpcywgLTEgaXMgZXF1aXZhbGVudCB0bwogICAgICogPGNvZGU+b3V0cHV0Lmxlbmd0aCgpPC9jb2RlPi4gIElmIGdyZWF0ZXIgdGhhbgogICAgICogPGNvZGU+b3V0cHV0Lmxlbmd0aCgpPC9jb2RlPiB0aGVuIGFuIGV4Y2VwdGlvbiBpcyB0aHJvd24uCiAgICAgKi8KICAgIFRyYW5zbGl0ZXJhdGlvblJ1bGUoY29uc3QgVW5pY29kZVN0cmluZyYgaW5wdXQsCiAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QgYW50ZUNvbnRleHRQb3MsIGludDMyX3QgcG9zdENvbnRleHRQb3MsCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVuaWNvZGVTdHJpbmcmIG91dHB1dCwKICAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCBjdXJzb3JQb3MsCiAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cyk7CgogICAgLyoqCiAgICAgKiBEZXN0cnVjdG9yLgogICAgICovCiAgICB2aXJ0dWFsIH5UcmFuc2xpdGVyYXRpb25SdWxlKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm4gdGhlIHBvc2l0aW9uIG9mIHRoZSBjdXJzb3Igd2l0aGluIHRoZSBvdXRwdXQgc3RyaW5nLgogICAgICogQHJldHVybiBhIHZhbHVlIGZyb20gMCB0byA8Y29kZT5nZXRPdXRwdXQoKS5sZW5ndGgoKTwvY29kZT4sIGluY2x1c2l2ZS4KICAgICAqLwogICAgdmlydHVhbCBpbnQzMl90IGdldEN1cnNvclBvcyh2b2lkKSBjb25zdDsKCiAgICAvKioKICAgICAqIFJldHVybiB0aGUgcHJlY2VkaW5nIGNvbnRleHQgbGVuZ3RoLiAgVGhpcyBtZXRob2QgaXMgbmVlZGVkIHRvCiAgICAgKiBzdXBwb3J0IHRoZSA8Y29kZT5UcmFuc2xpdGVyYXRvcjwvY29kZT4gbWV0aG9kCiAgICAgKiA8Y29kZT5nZXRNYXhpbXVtQ29udGV4dExlbmd0aCgpPC9jb2RlPi4KICAgICAqLwogICAgdmlydHVhbCBpbnQzMl90IGdldEFudGVDb250ZXh0TGVuZ3RoKHZvaWQpIGNvbnN0OwoKICAgIC8qKgogICAgICogSW50ZXJuYWwgbWV0aG9kLiAgUmV0dXJucyA4LWJpdCBpbmRleCB2YWx1ZSBmb3IgdGhpcyBydWxlLgogICAgICogVGhpcyBpcyB0aGUgbG93IGJ5dGUgb2YgdGhlIGZpcnN0IGNoYXJhY3RlciBvZiB0aGUga2V5LAogICAgICogdW5sZXNzIHRoZSBmaXJzdCBjaGFyYWN0ZXIgb2YgdGhlIGtleSBpcyBhIHNldC4gIElmIGl0J3MgYQogICAgICogc2V0LCBvciBvdGhlcndpc2UgY2FuIG1hdGNoIG11bHRpcGxlIGtleXMsIHRoZSBpbmRleCB2YWx1ZSBpcyAtMS4KICAgICAqLwogICAgaW50MTZfdCBnZXRJbmRleFZhbHVlKGNvbnN0IFRyYW5zbGl0ZXJhdGlvblJ1bGVEYXRhJiBkYXRhKSBjb25zdDsKCiAgICAvKioKICAgICAqIERvIGEgcmVwbGFjZW1lbnQgb2YgdGhlIGlucHV0IHBhdHRlcm4gd2l0aCB0aGUgb3V0cHV0IHRleHQgaW4KICAgICAqIHRoZSBnaXZlbiBzdHJpbmcsIGF0IHRoZSBnaXZlbiBvZmZzZXQuICBUaGlzIG1ldGhvZCBhc3N1bWVzCiAgICAgKiB0aGF0IGEgbWF0Y2ggaGFzIGFscmVhZHkgYmVlbiBmb3VuZCBpbiB0aGUgZ2l2ZW4gdGV4dCBhdCB0aGUKICAgICAqIGdpdmVuIHBvc2l0aW9uLgogICAgICogQHBhcmFtIHRleHQgdGhlIHRleHQgY29udGFpbmluZyB0aGUgc3Vic3RyaW5nIHRvIGJlIHJlcGxhY2VkCiAgICAgKiBAcGFyYW0gb2Zmc2V0IHRoZSBvZmZzZXQgaW50byB0aGUgdGV4dCBhdCB3aGljaCB0aGUgcGF0dGVybgogICAgICogbWF0Y2hlcy4gIFRoaXMgaXMgdGhlIG9mZnNldCB0byB0aGUgcG9pbnQgYWZ0ZXIgdGhlIGFudGUKICAgICAqIGNvbnRleHQsIGlmIGFueSwgYW5kIGJlZm9yZSB0aGUgbWF0Y2ggc3RyaW5nIGFuZCBhbnkgcG9zdAogICAgICogY29udGV4dC4KICAgICAqIEBwYXJhbSBkYXRhIHRoZSBSdWxlQmFzZWRUcmFuc2xpdGVyYXRvci5EYXRhIG9iamVjdCBzcGVjaWZ5aW5nCiAgICAgKiBjb250ZXh0IGZvciB0aGlzIHRyYW5zbGl0ZXJhdG9yLgogICAgICogQHJldHVybiB0aGUgY2hhbmdlIGluIHRoZSBsZW5ndGggb2YgdGhlIHRleHQKICAgICAqLwogICAgaW50MzJfdCByZXBsYWNlKFJlcGxhY2VhYmxlJiB0ZXh0LCBpbnQzMl90IG9mZnNldCwKICAgICAgICAgICAgICAgICAgICBjb25zdCBUcmFuc2xpdGVyYXRpb25SdWxlRGF0YSYgZGF0YSkgY29uc3Q7CgogICAgLyoqCiAgICAgKiBJbnRlcm5hbCBtZXRob2QuICBSZXR1cm5zIHRydWUgaWYgdGhpcyBydWxlIG1hdGNoZXMgdGhlIGdpdmVuCiAgICAgKiBpbmRleCB2YWx1ZS4gIFRoZSBpbmRleCB2YWx1ZSBpcyBhbiA4LWJpdCBpbnRlZ2VyLCAwLi4yNTUsCiAgICAgKiByZXByZXNlbnRpbmcgdGhlIGxvdyBieXRlIG9mIHRoZSBmaXJzdCBjaGFyYWN0ZXIgb2YgdGhlIGtleS4KICAgICAqIEl0IG1hdGNoZXMgdGhpcyBydWxlIGlmIGl0IG1hdGNoZXMgdGhlIGZpcnN0IGNoYXJhY3RlciBvZiB0aGUKICAgICAqIGtleSwgb3IgaWYgdGhlIGZpcnN0IGNoYXJhY3RlciBvZiB0aGUga2V5IGlzIGEgc2V0LCBhbmQgdGhlIHNldAogICAgICogY29udGFpbnMgYW55IGNoYXJhY3RlciB3aXRoIGEgbG93IGJ5dGUgZXF1YWwgdG8gdGhlIGluZGV4CiAgICAgKiB2YWx1ZS4gIElmIHRoZSBydWxlIGNvbnRhaW5zIG9ubHkgYW50ZSBjb250ZXh0LCBhcyBpbiBmb28pPmJhciwKICAgICAqIHRoZW4gaXQgd2lsbCBtYXRjaCBhbnkga2V5LgogICAgICovCiAgICBVQm9vbCBtYXRjaGVzSW5kZXhWYWx1ZSh1aW50OF90IHYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVHJhbnNsaXRlcmF0aW9uUnVsZURhdGEmIGRhdGEpIGNvbnN0OwoKICAgIC8qKgogICAgICogUmV0dXJuIHRydWUgaWYgdGhpcyBydWxlIG1hc2tzIGFub3RoZXIgcnVsZS4gIElmIHIxIG1hc2tzIHIyIHRoZW4KICAgICAqIHIxIG1hdGNoZXMgYW55IGlucHV0IHN0cmluZyB0aGF0IHIyIG1hdGNoZXMuICBJZiByMSBtYXNrcyByMiBhbmQgcjIgbWFza3MKICAgICAqIHIxIHRoZW4gcjEgPT0gcjIuICBFeGFtcGxlczogImE+eCIgbWFza3MgImFiPnkiLiAgImE+eCIgbWFza3MgImFbYl0+eSIuCiAgICAgKiAiW2NdYT54IiBtYXNrcyAiW2RjXWE+eSIuCiAgICAgKi8KICAgIHZpcnR1YWwgVUJvb2wgbWFza3MoY29uc3QgVHJhbnNsaXRlcmF0aW9uUnVsZSYgcjIpIGNvbnN0OwoKICAgIC8qKgogICAgICogUmV0dXJuIHRydWUgaWYgdGhpcyBydWxlIG1hdGNoZXMgdGhlIGdpdmVuIHRleHQuCiAgICAgKiBAcGFyYW0gdGV4dCB0aGUgdGV4dCwgYm90aCB0cmFuc2xhdGVkIGFuZCB1bnRyYW5zbGF0ZWQKICAgICAqIEBwYXJhbSBzdGFydCB0aGUgYmVnaW5uaW5nIGluZGV4LCBpbmNsdXNpdmU7IDxjb2RlPjAgPD0gc3RhcnQKICAgICAqIDw9IGxpbWl0PC9jb2RlPi4KICAgICAqIEBwYXJhbSBsaW1pdCB0aGUgZW5kaW5nIGluZGV4LCBleGNsdXNpdmU7IDxjb2RlPnN0YXJ0IDw9IGxpbWl0CiAgICAgKiA8PSB0ZXh0Lmxlbmd0aCgpPC9jb2RlPi4KICAgICAqIEBwYXJhbSBjdXJzb3IgcG9zaXRpb24gYXQgd2hpY2ggdG8gdHJhbnNsYXRlIG5leHQsIHJlcHJlc2VudGluZyBvZmZzZXQKICAgICAqIGludG8gdGV4dC4gIFRoaXMgdmFsdWUgbXVzdCBiZSBiZXR3ZWVuIDxjb2RlPnN0YXJ0PC9jb2RlPiBhbmQKICAgICAqIDxjb2RlPmxpbWl0PC9jb2RlPi4KICAgICAqIEBwYXJhbSBmaWx0ZXIgdGhlIGZpbHRlci4gIEFueSBjaGFyYWN0ZXIgZm9yIHdoaWNoCiAgICAgKiA8dHQ+ZmlsdGVyLmlzSW4oKTwvdHQ+IHJldHVybnMgPHR0PmZhbHNlPC90dD4gd2lsbCBub3QgYmUKICAgICAqIGFsdGVyZWQgYnkgdGhpcyB0cmFuc2xpdGVyYXRvci4gIElmIDx0dD5maWx0ZXI8L3R0PiBpcwogICAgICogPHR0Pm51bGw8L3R0PiB0aGVuIG5vIGZpbHRlcmluZyBpcyBhcHBsaWVkLgogICAgICovCiAgICB2aXJ0dWFsIFVCb29sIG1hdGNoZXMoY29uc3QgUmVwbGFjZWFibGUmIHRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3Qgc3RhcnQsIGludDMyX3QgbGltaXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QgY3Vyc29yLAogICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBUcmFuc2xpdGVyYXRpb25SdWxlRGF0YSYgZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVW5pY29kZUZpbHRlciogZmlsdGVyKSBjb25zdDsKCiAgICAvKioKICAgICAqIFJldHVybiB0aGUgZGVncmVlIG9mIG1hdGNoIGJldHdlZW4gdGhpcyBydWxlIGFuZCB0aGUgZ2l2ZW4gdGV4dC4gIFRoZQogICAgICogZGVncmVlIG9mIG1hdGNoIG1heSBiZSBtaXNtYXRjaCwgYSBwYXJ0aWFsIG1hdGNoLCBvciBhIGZ1bGwgbWF0Y2guICBBCiAgICAgKiBtaXNtYXRjaCBtZWFucyBhdCBsZWFzdCBvbmUgY2hhcmFjdGVyIG9mIHRoZSB0ZXh0IGRvZXMgbm90IG1hdGNoIHRoZQogICAgICogY29udGV4dCBvciBrZXkuICBBIHBhcnRpYWwgbWF0Y2ggbWVhbnMgc29tZSBjb250ZXh0IGFuZCBrZXkgY2hhcmFjdGVycwogICAgICogbWF0Y2gsIGJ1dCB0aGUgdGV4dCBpcyBub3QgbG9uZyBlbm91Z2ggdG8gbWF0Y2ggYWxsIG9mIHRoZW0uICBBIGZ1bGwKICAgICAqIG1hdGNoIG1lYW5zIGFsbCBjb250ZXh0IGFuZCBrZXkgY2hhcmFjdGVycyBtYXRjaC4KICAgICAqIEBwYXJhbSB0ZXh0IHRoZSB0ZXh0LCBib3RoIHRyYW5zbGF0ZWQgYW5kIHVudHJhbnNsYXRlZAogICAgICogQHBhcmFtIHN0YXJ0IHRoZSBiZWdpbm5pbmcgaW5kZXgsIGluY2x1c2l2ZTsgPGNvZGU+MCA8PSBzdGFydAogICAgICogPD0gbGltaXQ8L2NvZGU+LgogICAgICogQHBhcmFtIGxpbWl0IHRoZSBlbmRpbmcgaW5kZXgsIGV4Y2x1c2l2ZTsgPGNvZGU+c3RhcnQgPD0gbGltaXQKICAgICAqIDw9IHRleHQubGVuZ3RoKCk8L2NvZGU+LgogICAgICogQHBhcmFtIGN1cnNvciBwb3NpdGlvbiBhdCB3aGljaCB0byB0cmFuc2xhdGUgbmV4dCwgcmVwcmVzZW50aW5nIG9mZnNldAogICAgICogaW50byB0ZXh0LiAgVGhpcyB2YWx1ZSBtdXN0IGJlIGJldHdlZW4gPGNvZGU+c3RhcnQ8L2NvZGU+IGFuZAogICAgICogPGNvZGU+bGltaXQ8L2NvZGU+LgogICAgICogQHBhcmFtIGZpbHRlciB0aGUgZmlsdGVyLiAgQW55IGNoYXJhY3RlciBmb3Igd2hpY2gKICAgICAqIDx0dD5maWx0ZXIuaXNJbigpPC90dD4gcmV0dXJucyA8dHQ+ZmFsc2U8L3R0PiB3aWxsIG5vdCBiZQogICAgICogYWx0ZXJlZCBieSB0aGlzIHRyYW5zbGl0ZXJhdG9yLiAgSWYgPHR0PmZpbHRlcjwvdHQ+IGlzCiAgICAgKiA8dHQ+bnVsbDwvdHQ+IHRoZW4gbm8gZmlsdGVyaW5nIGlzIGFwcGxpZWQuCiAgICAgKiBAcmV0dXJuIG9uZSBvZiA8Y29kZT5NSVNNQVRDSDwvY29kZT4sIDxjb2RlPlBBUlRJQUxfTUFUQ0g8L2NvZGU+LCBvcgogICAgICogPGNvZGU+RlVMTF9NQVRDSDwvY29kZT4uCiAgICAgKiBAc2VlICNNSVNNQVRDSAogICAgICogQHNlZSAjUEFSVElBTF9NQVRDSAogICAgICogQHNlZSAjRlVMTF9NQVRDSAogICAgICovCiAgICB2aXJ0dWFsIGludDMyX3QgZ2V0TWF0Y2hEZWdyZWUoY29uc3QgUmVwbGFjZWFibGUmIHRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCBzdGFydCwgaW50MzJfdCBsaW1pdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IGN1cnNvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBUcmFuc2xpdGVyYXRpb25SdWxlRGF0YSYgZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlRmlsdGVyKiBmaWx0ZXIpIGNvbnN0OwoKICAgIC8qKgogICAgICogUmV0dXJuIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyBvZiB0aGUgdGV4dCB0aGF0IG1hdGNoIHRoaXMgcnVsZS4gIElmCiAgICAgKiB0aGVyZSBpcyBhIG1pc21hdGNoLCByZXR1cm4gLTEuICBJZiB0aGUgdGV4dCBpcyBub3QgbG9uZyBlbm91Z2ggdG8gbWF0Y2gKICAgICAqIGFueSBjaGFyYWN0ZXJzLCByZXR1cm4gMC4KICAgICAqIEBwYXJhbSB0ZXh0IHRoZSB0ZXh0LCBib3RoIHRyYW5zbGF0ZWQgYW5kIHVudHJhbnNsYXRlZAogICAgICogQHBhcmFtIHN0YXJ0IHRoZSBiZWdpbm5pbmcgaW5kZXgsIGluY2x1c2l2ZTsgPGNvZGU+MCA8PSBzdGFydAogICAgICogPD0gbGltaXQ8L2NvZGU+LgogICAgICogQHBhcmFtIGxpbWl0IHRoZSBlbmRpbmcgaW5kZXgsIGV4Y2x1c2l2ZTsgPGNvZGU+c3RhcnQgPD0gbGltaXQKICAgICAqIDw9IHRleHQubGVuZ3RoKCk8L2NvZGU+LgogICAgICogQHBhcmFtIGN1cnNvciBwb3NpdGlvbiBhdCB3aGljaCB0byB0cmFuc2xhdGUgbmV4dCwgcmVwcmVzZW50aW5nIG9mZnNldAogICAgICogaW50byB0ZXh0LiAgVGhpcyB2YWx1ZSBtdXN0IGJlIGJldHdlZW4gPGNvZGU+c3RhcnQ8L2NvZGU+IGFuZAogICAgICogPGNvZGU+bGltaXQ8L2NvZGU+LgogICAgICogQHBhcmFtIHRlbXBsIHRoZSB0ZXh0IHRvIG1hdGNoIGFnYWluc3QuICBBbGwgY2hhcmFjdGVycyBtdXN0IG1hdGNoLgogICAgICogQHBhcmFtIGRhdGEgYSBkaWN0aW9uYXJ5IG9mIHZhcmlhYmxlcyBtYXBwaW5nIDxjb2RlPkNoYXJhY3RlcjwvY29kZT4KICAgICAqIHRvIDxjb2RlPlVuaWNvZGVTZXQ8L2NvZGU+CiAgICAgKiBAcGFyYW0gZmlsdGVyIHRoZSBmaWx0ZXIuICBBbnkgY2hhcmFjdGVyIGZvciB3aGljaAogICAgICogPHR0PmZpbHRlci5pc0luKCk8L3R0PiByZXR1cm5zIDx0dD5mYWxzZTwvdHQ+IHdpbGwgbm90IGJlCiAgICAgKiBhbHRlcmVkIGJ5IHRoaXMgdHJhbnNsaXRlcmF0b3IuICBJZiA8dHQ+ZmlsdGVyPC90dD4gaXMKICAgICAqIDx0dD5udWxsPC90dD4gdGhlbiBubyBmaWx0ZXJpbmcgaXMgYXBwbGllZC4KICAgICAqIEByZXR1cm4gLTEgaWYgdGhlcmUgaXMgYSBtaXNtYXRjaCwgMCBpZiB0aGUgdGV4dCBpcyBub3QgbG9uZyBlbm91Z2ggdG8KICAgICAqIG1hdGNoIGFueSBjaGFyYWN0ZXJzLCBvdGhlcndpc2UgdGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIG9mIHRleHQgdGhhdAogICAgICogbWF0Y2ggdGhpcyBydWxlLgogICAgICovCiAgICB2aXJ0dWFsIGludDMyX3QgZ2V0UmVnaW9uTWF0Y2hMZW5ndGgoY29uc3QgUmVwbGFjZWFibGUmIHRleHQsIGludDMyX3Qgc3RhcnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCBsaW1pdCwgaW50MzJfdCBjdXJzb3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVW5pY29kZVN0cmluZyYgdGVtcGwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVHJhbnNsaXRlcmF0aW9uUnVsZURhdGEmIGRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVW5pY29kZUZpbHRlciogZmlsdGVyKSBjb25zdDsKICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm4gdHJ1ZSBpZiB0aGUgZ2l2ZW4ga2V5IG1hdGNoZXMgdGhlIGdpdmVuIHRleHQuICBUaGlzIG1ldGhvZAogICAgICogYWNjb3VudHMgZm9yIHRoZSBmYWN0IHRoYXQgdGhlIGtleSBjaGFyYWN0ZXIgbWF5IHJlcHJlc2VudCBhIGNoYXJhY3RlcgogICAgICogc2V0LiAgTm90ZSB0aGF0IHRoZSBrZXkgYW5kIHRleHQgY2hhcmFjdGVycyBtYXkgbm90IGJlIGludGVyY2hhbmdlZAogICAgICogd2l0aG91dCBhbHRlcmluZyB0aGUgcmVzdWx0cy4KICAgICAqIEBwYXJhbSBrZXlDaGFyIGEgY2hhcmFjdGVyIGluIHRoZSBtYXRjaCBrZXkKICAgICAqIEBwYXJhbSB0ZXh0Q2hhciBhIGNoYXJhY3RlciBpbiB0aGUgdGV4dCBiZWluZyB0cmFuc2xpdGVyYXRlZAogICAgICogQHBhcmFtIGRhdGEgYSBkaWN0aW9uYXJ5IG9mIHZhcmlhYmxlcyBtYXBwaW5nIDxjb2RlPkNoYXJhY3RlcjwvY29kZT4KICAgICAqIHRvIDxjb2RlPlVuaWNvZGVTZXQ8L2NvZGU+CiAgICAgKiBAcGFyYW0gZmlsdGVyIHRoZSBmaWx0ZXIuICBBbnkgY2hhcmFjdGVyIGZvciB3aGljaAogICAgICogPHR0PmZpbHRlci5pc0luKCk8L3R0PiByZXR1cm5zIDx0dD5mYWxzZTwvdHQ+IHdpbGwgbm90IGJlCiAgICAgKiBhbHRlcmVkIGJ5IHRoaXMgdHJhbnNsaXRlcmF0b3IuICBJZiA8dHQ+ZmlsdGVyPC90dD4gaXMKICAgICAqIDx0dD5udWxsPC90dD4gdGhlbiBubyBmaWx0ZXJpbmcgaXMgYXBwbGllZC4KICAgICAqLwogICAgdmlydHVhbCBVQm9vbCBjaGFyTWF0Y2hlcyhVQ2hhciBrZXlDaGFyLCBVQ2hhciB0ZXh0Q2hhciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFRyYW5zbGl0ZXJhdGlvblJ1bGVEYXRhJiBkYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVW5pY29kZUZpbHRlciogZmlsdGVyKSBjb25zdDsKCnByaXZhdGU6CgogICAgdm9pZCBpbml0KGNvbnN0IFVuaWNvZGVTdHJpbmcmIGlucHV0LAogICAgICAgICAgICAgIGludDMyX3QgYW50ZUNvbnRleHRQb3MsIGludDMyX3QgcG9zdENvbnRleHRQb3MsCiAgICAgICAgICAgICAgY29uc3QgVW5pY29kZVN0cmluZyYgb3V0cHV0LAogICAgICAgICAgICAgIGludDMyX3QgY3Vyc29yUG9zLCBpbnQzMl90IGN1cnNvck9mZnNldCwKICAgICAgICAgICAgICBpbnQzMl90KiBhZG9wdGVkU2VncywKICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpOwp9OwoKI2VuZGlmCg==