LyoKKiBDb3B5cmlnaHQgqSB7MTk5OX0sIEludGVybmF0aW9uYWwgQnVzaW5lc3MgTWFjaGluZXMgQ29ycG9yYXRpb24gYW5kIG90aGVycy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqICAgRGF0ZSAgICAgICAgTmFtZSAgICAgICAgRGVzY3JpcHRpb24KKiAgIDExLzE3Lzk5ICAgIGFsaXUgICAgICAgIENyZWF0aW9uLgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiovCiNpZm5kZWYgUkJUX1JVTEVfSAojZGVmaW5lIFJCVF9SVUxFX0gKCiNpbmNsdWRlICJ1bmljb2RlL3VuaXN0ci5oIgojaW5jbHVkZSAidW5pY29kZS91dHJhbnMuaCIKCmNsYXNzIFJlcGxhY2VhYmxlOwpjbGFzcyBUcmFuc2xpdGVyYXRpb25SdWxlRGF0YTsKY2xhc3MgVW5pY29kZUZpbHRlcjsKCi8qKgogKiBBIHRyYW5zbGl0ZXJhdGlvbiBydWxlIHVzZWQgYnkKICogPGNvZGU+UnVsZUJhc2VkVHJhbnNsaXRlcmF0b3I8L2NvZGU+LgogKiA8Y29kZT5UcmFuc2xpdGVyYXRpb25SdWxlPC9jb2RlPiBpcyBhbiBpbW11dGFibGUgb2JqZWN0LgogKgogKiA8cD5BIHJ1bGUgY29uc2lzdHMgb2YgYW4gaW5wdXQgcGF0dGVybiBhbmQgYW4gb3V0cHV0IHN0cmluZy4gIFdoZW4KICogdGhlIGlucHV0IHBhdHRlcm4gaXMgbWF0Y2hlZCwgdGhlIG91dHB1dCBzdHJpbmcgaXMgZW1pdHRlZC4gIFRoZQogKiBpbnB1dCBwYXR0ZXJuIGNvbnNpc3RzIG9mIHplcm8gb3IgbW9yZSBjaGFyYWN0ZXJzIHdoaWNoIGFyZSBtYXRjaGVkCiAqIGV4YWN0bHkgKHRoZSBrZXkpIGFuZCBvcHRpb25hbCBjb250ZXh0LiAgQ29udGV4dCBtdXN0IG1hdGNoIGlmIGl0CiAqIGlzIHNwZWNpZmllZC4gIENvbnRleHQgbWF5IGJlIHNwZWNpZmllZCBiZWZvcmUgdGhlIGtleSwgYWZ0ZXIgdGhlCiAqIGtleSwgb3IgYm90aC4gIFRoZSBrZXksIHByZWNlZGluZyBjb250ZXh0LCBhbmQgZm9sbG93aW5nIGNvbnRleHQKICogbWF5IGNvbnRhaW4gdmFyaWFibGVzLiAgVmFyaWFibGVzIHJlcHJlc2VudCBhIHNldCBvZiBVbmljb2RlCiAqIGNoYXJhY3RlcnMsIHN1Y2ggYXMgdGhlIGxldHRlcnMgPGk+YTwvaT4gdGhyb3VnaCA8aT56PC9pPi4KICogVmFyaWFibGVzIGFyZSBkZXRlY3RlZCBieSBsb29raW5nIHVwIGVhY2ggY2hhcmFjdGVyIGluIGEgc3VwcGxpZWQKICogdmFyaWFibGUgbGlzdCB0byBzZWUgaWYgaXQgaGFzIGJlZW4gc28gZGVmaW5lZC4gCiAqCiAqIEBhdXRob3IgQWxhbiBMaXUKICovCmNsYXNzIFRyYW5zbGl0ZXJhdGlvblJ1bGUgewoKcHVibGljOgoKICAgIC8qKgogICAgICogQ29uc3RhbnRzIHJldHVybmVkIGJ5IDxjb2RlPmdldE1hdGNoRGVncmVlKCk8L2NvZGU+IGluZGljYXRpbmcKICAgICAqIHRoZSBkZWdyZWUgb2YgbWF0Y2ggYmV0d2VlbiB0aGUgdGV4dCBhbmQgdGhpcyBydWxlLgogICAgICogQHNlZSAjZ2V0TWF0Y2hEZWdyZWUKICAgICAqLwogICAgZW51bSB7CiAgICAgICAgLyoqCiAgICAgICAgICogQ29uc3RhbnQgcmV0dXJuZWQgYnkgPGNvZGU+Z2V0TWF0Y2hEZWdyZWUoKTwvY29kZT4KICAgICAgICAgKiBpbmRpY2F0aW5nIGEgbWlzbWF0Y2ggYmV0d2VlbiB0aGUgdGV4dCBhbmQgdGhpcyBydWxlLiAgT25lCiAgICAgICAgICogb3IgbW9yZSBjaGFyYWN0ZXJzIG9mIHRoZSBjb250ZXh0IG9yIGtleSBkbyBub3QgbWF0Y2ggdGhlCiAgICAgICAgICogdGV4dC4KICAgICAgICAgKi8KICAgICAgICBNSVNNQVRDSCwKCiAgICAgICAgLyoqCiAgICAgICAgICogQ29uc3RhbnQgcmV0dXJuZWQgYnkgPGNvZGU+Z2V0TWF0Y2hEZWdyZWUoKTwvY29kZT4KICAgICAgICAgKiBpbmRpY2F0aW5nIGEgcGFydGlhbCBtYXRjaCBiZXR3ZWVuIHRoZSB0ZXh0IGFuZCB0aGlzIHJ1bGUuCiAgICAgICAgICogQWxsIGNoYXJhY3RlcnMgb2YgdGhlIHRleHQgbWF0Y2ggdGhlIGNvcnJlc3BvbmRpbmcgY29udGV4dAogICAgICAgICAqIG9yIGtleSwgYnV0IG1vcmUgY2hhcmFjdGVycyBhcmUgcmVxdWlyZWQgZm9yIGEgY29tcGxldGUKICAgICAgICAgKiBtYXRjaC4gIFRoZXJlIGFyZSBzb21lIGtleSBvciBjb250ZXh0IGNoYXJhY3RlcnMgYXQgdGhlIGVuZAogICAgICAgICAqIG9mIHRoZSBwYXR0ZXJuIHRoYXQgcmVtYWluIHVubWF0Y2hlZCBiZWNhdXNlIHRoZSB0ZXh0IGlzbid0CiAgICAgICAgICogbG9uZyBlbm91Z2guCiAgICAgICAgICovCiAgICAgICAgUEFSVElBTF9NQVRDSCwKICAgICAgICAKICAgICAgICAvKioKICAgICAgICAgKiBDb25zdGFudCByZXR1cm5lZCBieSA8Y29kZT5nZXRNYXRjaERlZ3JlZSgpPC9jb2RlPgogICAgICAgICAqIGluZGljYXRpbmcgYSBjb21wbGV0ZSBtYXRjaCBiZXR3ZWVuIHRoZSB0ZXh0IGFuZCB0aGlzIHJ1bGUuCiAgICAgICAgICogVGhlIHRleHQgbWF0Y2hlcyBhbGwgY29udGV4dCBhbmQga2V5IGNoYXJhY3RlcnMuCiAgICAgICAgICovCiAgICAgICAgRlVMTF9NQVRDSAogICAgfTsKCnByaXZhdGU6CgogICAgLyoqCiAgICAgKiBUaGUgc3RyaW5nIHRoYXQgbXVzdCBiZSBtYXRjaGVkLCBjb25zaXN0aW5nIG9mIHRoZSBhbnRlQ29udGV4dCwga2V5LAogICAgICogYW5kIHBvc3RDb250ZXh0LCBjb25jYXRlbmF0ZWQgdG9nZXRoZXIsIGluIHRoYXQgb3JkZXIuICBTb21lIGNvbXBvbmVudHMKICAgICAqIG1heSBiZSBlbXB0eSAoemVybyBsZW5ndGgpLgogICAgICogQHNlZSBhbnRlQ29udGV4dExlbmd0aAogICAgICogQHNlZSBrZXlMZW5ndGgKICAgICAqLwogICAgVW5pY29kZVN0cmluZyBwYXR0ZXJuOwoKICAgIC8qKgogICAgICogVGhlIHN0cmluZyB0aGF0IGlzIGVtaXR0ZWQgaWYgdGhlIGtleSwgYW50ZUNvbnRleHQsIGFuZCBwb3N0Q29udGV4dAogICAgICogYXJlIG1hdGNoZWQuCiAgICAgKi8KICAgIFVuaWNvZGVTdHJpbmcgb3V0cHV0OwoKICAgIC8qKgogICAgICogQXJyYXkgb2Ygc2VnbWVudHMuICBUaGVzZSBhcmUgc2VnbWVudHMgb2YgdGhlIGlucHV0IHN0cmluZyB0aGF0IG1heSBiZQogICAgICogcmVmZXJlbmNlZCBhbmQgYXBwZWFyIGluIHRoZSBvdXRwdXQgc3RyaW5nLiAgRWFjaCBzZWdtZW50IGlzIHN0b3JlZCBhcyBhbgogICAgICogb2Zmc2V0LCBsaW1pdCBwYWlyLiAgU2VnbWVudHMgYXJlIHJlZmVyZW5jZWQgYnkgYSAxLWJhc2VkIGluZGV4OwogICAgICogcmVmZXJlbmNlIGkgdGh1cyBpbmNsdWRlcyBjaGFyYWN0ZXJzIGF0IG9mZnNldCBzZWdtZW50c1syKmktMl0gdG8KICAgICAqIHNlZ21lbnRzWzIqaS0xXS0xIGluIHRoZSBwYXR0ZXJuIHN0cmluZy4KICAgICAqCiAgICAgKiBJbiB0aGUgb3V0cHV0IHN0cmluZywgYSBzZWdtZW50IHJlZmVyZW5jZSBpcyBpbmRpY2F0ZWQgYnkgYSBjaGFyYWN0ZXIgaW4KICAgICAqIGEgc3BlY2lhbCByYW5nZSwgYXMgZGVmaW5lZCBieSBSdWxlQmFzZWRUcmFuc2xpdGVyYXRvci5EYXRhLgogICAgICoKICAgICAqIE1vc3QgcnVsZXMgaGF2ZSBubyBzZWdtZW50cywgaW4gd2hpY2ggY2FzZSBzZWdtZW50cyBpcyBudWxsLCBhbmQgdGhlCiAgICAgKiBvdXRwdXQgc3RyaW5nIG5lZWQgbm90IGJlIGNoZWNrZWQgZm9yIHNlZ21lbnQgcmVmZXJlbmNlIGNoYXJhY3RlcnMuCiAgICAgKi8KICAgIGludDMyX3QqIHNlZ21lbnRzOwoKICAgIC8qKgogICAgICogVGhlIGxlbmd0aCBvZiB0aGUgc3RyaW5nIHRoYXQgbXVzdCBtYXRjaCBiZWZvcmUgdGhlIGtleS4gIElmCiAgICAgKiB6ZXJvLCB0aGVuIHRoZXJlIGlzIG5vIG1hdGNoaW5nIHJlcXVpcmVtZW50IGJlZm9yZSB0aGUga2V5LgogICAgICogU3Vic3RyaW5nIFswLGFudGVDb250ZXh0TGVuZ3RoKSBvZiBwYXR0ZXJuIGlzIHRoZSBhbnRlQ29udGV4dC4KICAgICAqLwogICAgaW50MzJfdCBhbnRlQ29udGV4dExlbmd0aDsKCiAgICAvKioKICAgICAqIFRoZSBsZW5ndGggb2YgdGhlIGtleS4gIFN1YnN0cmluZyBbYW50ZUNvbnRleHRMZW5ndGgsCiAgICAgKiBhbnRlQ29udGV4dExlbmd0aCArIGtleUxlbmd0aCkgaXMgdGhlIGtleS4KCiAgICAgKi8KICAgIGludDMyX3Qga2V5TGVuZ3RoOwoKICAgIC8qKgogICAgICogVGhlIHBvc2l0aW9uIG9mIHRoZSBjdXJzb3IgYWZ0ZXIgZW1pdHRpbmcgdGhlIG91dHB1dCBzdHJpbmcsIGZyb20gMCB0bwogICAgICogb3V0cHV0Lmxlbmd0aCgpLiAgRm9yIG1vc3QgcnVsZXMgd2l0aCBubyBzcGVjaWFsIGN1cnNvciBzcGVjaWZpY2F0aW9uLAogICAgICogdGhlIGN1cnNvclBvcyBpcyBvdXRwdXQubGVuZ3RoKCkuCiAgICAgKi8KICAgIGludDMyX3QgY3Vyc29yUG9zOwoKcHVibGljOgoKICAgIC8qKgogICAgICogQ29uc3RydWN0IGEgbmV3IHJ1bGUgd2l0aCB0aGUgZ2l2ZW4gaW5wdXQsIG91dHB1dCB0ZXh0LCBhbmQgb3RoZXIKICAgICAqIGF0dHJpYnV0ZXMuICBBIGN1cnNvciBwb3NpdGlvbiBtYXkgYmUgc3BlY2lmaWVkIGZvciB0aGUgb3V0cHV0IHRleHQuCiAgICAgKiBAcGFyYW0gaW5wdXQgaW5wdXQgc3RyaW5nLCBpbmNsdWRpbmcga2V5IGFuZCBvcHRpb25hbCBhbnRlIGFuZAogICAgICogcG9zdCBjb250ZXh0CiAgICAgKiBAcGFyYW0gYW50ZUNvbnRleHRQb3Mgb2Zmc2V0IGludG8gaW5wdXQgdG8gZW5kIG9mIGFudGUgY29udGV4dCwgb3IgLTEgaWYKICAgICAqIG5vbmUuICBNdXN0IGJlIDw9IGlucHV0Lmxlbmd0aCgpIGlmIG5vdCAtMS4KICAgICAqIEBwYXJhbSBwb3N0Q29udGV4dFBvcyBvZmZzZXQgaW50byBpbnB1dCB0byBzdGFydCBvZiBwb3N0IGNvbnRleHQsIG9yIC0xCiAgICAgKiBpZiBub25lLiAgTXVzdCBiZSA8PSBpbnB1dC5sZW5ndGgoKSBpZiBub3QgLTEsIGFuZCBtdXN0IGJlID49CiAgICAgKiBhbnRlQ29udGV4dFBvcy4KICAgICAqIEBwYXJhbSBvdXRwdXQgb3V0cHV0IHN0cmluZwogICAgICogQHBhcmFtIGN1cnNvclBvcyBvZmZzZXQgaW50byBvdXRwdXQgYXQgd2hpY2ggY3Vyc29yIGlzIGxvY2F0ZWQsIG9yIC0xIGlmCiAgICAgKiBub25lLiAgSWYgbGVzcyB0aGFuIHplcm8sIHRoZW4gdGhlIGN1cnNvciBpcyBwbGFjZWQgYWZ0ZXIgdGhlCiAgICAgKiA8Y29kZT5vdXRwdXQ8L2NvZGU+OyB0aGF0IGlzLCAtMSBpcyBlcXVpdmFsZW50IHRvCiAgICAgKiA8Y29kZT5vdXRwdXQubGVuZ3RoKCk8L2NvZGU+LiAgSWYgZ3JlYXRlciB0aGFuCiAgICAgKiA8Y29kZT5vdXRwdXQubGVuZ3RoKCk8L2NvZGU+IHRoZW4gYW4gZXhjZXB0aW9uIGlzIHRocm93bi4KICAgICAqIEBwYXJhbSBhZG9wdGVkU2VncyBhcnJheSBvZiAybiBpbnRlZ2Vycy4gIEVhY2ggb2YgbiBwYWlycyBjb25zaXN0cyBvZiBvZmZzZXQsCiAgICAgKiBsaW1pdCBmb3IgYSBzZWdtZW50IG9mIHRoZSBpbnB1dCBzdHJpbmcuICBDaGFyYWN0ZXJzIGluIHRoZSBvdXRwdXQgc3RyaW5nCiAgICAgKiByZWZlciB0byB0aGVzZSBzZWdtZW50cyBpZiB0aGV5IGFyZSBpbiBhIHNwZWNpYWwgcmFuZ2UgZGV0ZXJtaW5lZCBieSB0aGUKICAgICAqIGFzc29jaWF0ZWQgUnVsZUJhc2VkVHJhbnNsaXRlcmF0b3IuRGF0YSBvYmplY3QuICBNYXkgYmUgbnVsbCBpZiB0aGVyZSBhcmUKICAgICAqIG5vIHNlZ21lbnRzLgogICAgICovCiAgICBUcmFuc2xpdGVyYXRpb25SdWxlKGNvbnN0IFVuaWNvZGVTdHJpbmcmIGlucHV0LAogICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IGFudGVDb250ZXh0UG9zLCBpbnQzMl90IHBvc3RDb250ZXh0UG9zLAogICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlU3RyaW5nJiBvdXRwdXQsCiAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QgY3Vyc29yUG9zLCBpbnQzMl90IGN1cnNvck9mZnNldCwKICAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCogYWRvcHRlZFNlZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cyk7CgogICAgLyoqCiAgICAgKiBDb25zdHJ1Y3QgYSBuZXcgcnVsZSB3aXRoIHRoZSBnaXZlbiBpbnB1dCwgb3V0cHV0IHRleHQsIGFuZCBvdGhlcgogICAgICogYXR0cmlidXRlcy4gIEEgY3Vyc29yIHBvc2l0aW9uIG1heSBiZSBzcGVjaWZpZWQgZm9yIHRoZSBvdXRwdXQgdGV4dC4KICAgICAqIEBwYXJhbSBpbnB1dCBpbnB1dCBzdHJpbmcsIGluY2x1ZGluZyBrZXkgYW5kIG9wdGlvbmFsIGFudGUgYW5kCiAgICAgKiBwb3N0IGNvbnRleHQKICAgICAqIEBwYXJhbSBhbnRlQ29udGV4dFBvcyBvZmZzZXQgaW50byBpbnB1dCB0byBlbmQgb2YgYW50ZSBjb250ZXh0LCBvciAtMSBpZgogICAgICogbm9uZS4gIE11c3QgYmUgPD0gaW5wdXQubGVuZ3RoKCkgaWYgbm90IC0xLgogICAgICogQHBhcmFtIHBvc3RDb250ZXh0UG9zIG9mZnNldCBpbnRvIGlucHV0IHRvIHN0YXJ0IG9mIHBvc3QgY29udGV4dCwgb3IgLTEKICAgICAqIGlmIG5vbmUuICBNdXN0IGJlIDw9IGlucHV0Lmxlbmd0aCgpIGlmIG5vdCAtMSwgYW5kIG11c3QgYmUgPj0KICAgICAqIGFudGVDb250ZXh0UG9zLgogICAgICogQHBhcmFtIG91dHB1dCBvdXRwdXQgc3RyaW5nCiAgICAgKiBAcGFyYW0gY3Vyc29yUG9zIG9mZnNldCBpbnRvIG91dHB1dCBhdCB3aGljaCBjdXJzb3IgaXMgbG9jYXRlZCwgb3IgLTEgaWYKICAgICAqIG5vbmUuICBJZiBsZXNzIHRoYW4gemVybywgdGhlbiB0aGUgY3Vyc29yIGlzIHBsYWNlZCBhZnRlciB0aGUKICAgICAqIDxjb2RlPm91dHB1dDwvY29kZT47IHRoYXQgaXMsIC0xIGlzIGVxdWl2YWxlbnQgdG8KICAgICAqIDxjb2RlPm91dHB1dC5sZW5ndGgoKTwvY29kZT4uICBJZiBncmVhdGVyIHRoYW4KICAgICAqIDxjb2RlPm91dHB1dC5sZW5ndGgoKTwvY29kZT4gdGhlbiBhbiBleGNlcHRpb24gaXMgdGhyb3duLgogICAgICovCiAgICBUcmFuc2xpdGVyYXRpb25SdWxlKGNvbnN0IFVuaWNvZGVTdHJpbmcmIGlucHV0LAogICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IGFudGVDb250ZXh0UG9zLCBpbnQzMl90IHBvc3RDb250ZXh0UG9zLAogICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlU3RyaW5nJiBvdXRwdXQsCiAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QgY3Vyc29yUG9zLAogICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpOwoKICAgIC8qKgogICAgICogRGVzdHJ1Y3Rvci4KICAgICAqLwogICAgdmlydHVhbCB+VHJhbnNsaXRlcmF0aW9uUnVsZSgpOwoKICAgIC8qKgogICAgICogUmV0dXJuIHRoZSBwb3NpdGlvbiBvZiB0aGUgY3Vyc29yIHdpdGhpbiB0aGUgb3V0cHV0IHN0cmluZy4KICAgICAqIEByZXR1cm4gYSB2YWx1ZSBmcm9tIDAgdG8gPGNvZGU+Z2V0T3V0cHV0KCkubGVuZ3RoKCk8L2NvZGU+LCBpbmNsdXNpdmUuCiAgICAgKi8KICAgIHZpcnR1YWwgaW50MzJfdCBnZXRDdXJzb3JQb3Modm9pZCkgY29uc3Q7CgogICAgLyoqCiAgICAgKiBSZXR1cm4gdGhlIHByZWNlZGluZyBjb250ZXh0IGxlbmd0aC4gIFRoaXMgbWV0aG9kIGlzIG5lZWRlZCB0bwogICAgICogc3VwcG9ydCB0aGUgPGNvZGU+VHJhbnNsaXRlcmF0b3I8L2NvZGU+IG1ldGhvZAogICAgICogPGNvZGU+Z2V0TWF4aW11bUNvbnRleHRMZW5ndGgoKTwvY29kZT4uCiAgICAgKi8KICAgIHZpcnR1YWwgaW50MzJfdCBnZXRBbnRlQ29udGV4dExlbmd0aCh2b2lkKSBjb25zdDsKCiAgICAvKioKICAgICAqIEludGVybmFsIG1ldGhvZC4gIFJldHVybnMgOC1iaXQgaW5kZXggdmFsdWUgZm9yIHRoaXMgcnVsZS4KICAgICAqIFRoaXMgaXMgdGhlIGxvdyBieXRlIG9mIHRoZSBmaXJzdCBjaGFyYWN0ZXIgb2YgdGhlIGtleSwKICAgICAqIHVubGVzcyB0aGUgZmlyc3QgY2hhcmFjdGVyIG9mIHRoZSBrZXkgaXMgYSBzZXQuICBJZiBpdCdzIGEKICAgICAqIHNldCwgb3Igb3RoZXJ3aXNlIGNhbiBtYXRjaCBtdWx0aXBsZSBrZXlzLCB0aGUgaW5kZXggdmFsdWUgaXMgLTEuCiAgICAgKi8KICAgIGludDE2X3QgZ2V0SW5kZXhWYWx1ZShjb25zdCBUcmFuc2xpdGVyYXRpb25SdWxlRGF0YSYgZGF0YSkgY29uc3Q7CgogICAgLyoqCiAgICAgKiBEbyBhIHJlcGxhY2VtZW50IG9mIHRoZSBpbnB1dCBwYXR0ZXJuIHdpdGggdGhlIG91dHB1dCB0ZXh0IGluCiAgICAgKiB0aGUgZ2l2ZW4gc3RyaW5nLCBhdCB0aGUgZ2l2ZW4gb2Zmc2V0LiAgVGhpcyBtZXRob2QgYXNzdW1lcwogICAgICogdGhhdCBhIG1hdGNoIGhhcyBhbHJlYWR5IGJlZW4gZm91bmQgaW4gdGhlIGdpdmVuIHRleHQgYXQgdGhlCiAgICAgKiBnaXZlbiBwb3NpdGlvbi4KICAgICAqIEBwYXJhbSB0ZXh0IHRoZSB0ZXh0IGNvbnRhaW5pbmcgdGhlIHN1YnN0cmluZyB0byBiZSByZXBsYWNlZAogICAgICogQHBhcmFtIG9mZnNldCB0aGUgb2Zmc2V0IGludG8gdGhlIHRleHQgYXQgd2hpY2ggdGhlIHBhdHRlcm4KICAgICAqIG1hdGNoZXMuICBUaGlzIGlzIHRoZSBvZmZzZXQgdG8gdGhlIHBvaW50IGFmdGVyIHRoZSBhbnRlCiAgICAgKiBjb250ZXh0LCBpZiBhbnksIGFuZCBiZWZvcmUgdGhlIG1hdGNoIHN0cmluZyBhbmQgYW55IHBvc3QKICAgICAqIGNvbnRleHQuCiAgICAgKiBAcGFyYW0gZGF0YSB0aGUgUnVsZUJhc2VkVHJhbnNsaXRlcmF0b3IuRGF0YSBvYmplY3Qgc3BlY2lmeWluZwogICAgICogY29udGV4dCBmb3IgdGhpcyB0cmFuc2xpdGVyYXRvci4KICAgICAqIEByZXR1cm4gdGhlIGNoYW5nZSBpbiB0aGUgbGVuZ3RoIG9mIHRoZSB0ZXh0CiAgICAgKi8KICAgIGludDMyX3QgcmVwbGFjZShSZXBsYWNlYWJsZSYgdGV4dCwgaW50MzJfdCBvZmZzZXQsCiAgICAgICAgICAgICAgICAgICAgY29uc3QgVHJhbnNsaXRlcmF0aW9uUnVsZURhdGEmIGRhdGEpIGNvbnN0OwoKICAgIC8qKgogICAgICogSW50ZXJuYWwgbWV0aG9kLiAgUmV0dXJucyB0cnVlIGlmIHRoaXMgcnVsZSBtYXRjaGVzIHRoZSBnaXZlbgogICAgICogaW5kZXggdmFsdWUuICBUaGUgaW5kZXggdmFsdWUgaXMgYW4gOC1iaXQgaW50ZWdlciwgMC4uMjU1LAogICAgICogcmVwcmVzZW50aW5nIHRoZSBsb3cgYnl0ZSBvZiB0aGUgZmlyc3QgY2hhcmFjdGVyIG9mIHRoZSBrZXkuCiAgICAgKiBJdCBtYXRjaGVzIHRoaXMgcnVsZSBpZiBpdCBtYXRjaGVzIHRoZSBmaXJzdCBjaGFyYWN0ZXIgb2YgdGhlCiAgICAgKiBrZXksIG9yIGlmIHRoZSBmaXJzdCBjaGFyYWN0ZXIgb2YgdGhlIGtleSBpcyBhIHNldCwgYW5kIHRoZSBzZXQKICAgICAqIGNvbnRhaW5zIGFueSBjaGFyYWN0ZXIgd2l0aCBhIGxvdyBieXRlIGVxdWFsIHRvIHRoZSBpbmRleAogICAgICogdmFsdWUuICBJZiB0aGUgcnVsZSBjb250YWlucyBvbmx5IGFudGUgY29udGV4dCwgYXMgaW4gZm9vKT5iYXIsCiAgICAgKiB0aGVuIGl0IHdpbGwgbWF0Y2ggYW55IGtleS4KICAgICAqLwogICAgVUJvb2wgbWF0Y2hlc0luZGV4VmFsdWUodWludDhfdCB2LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFRyYW5zbGl0ZXJhdGlvblJ1bGVEYXRhJiBkYXRhKSBjb25zdDsKCiAgICAvKioKICAgICAqIFJldHVybiB0cnVlIGlmIHRoaXMgcnVsZSBtYXNrcyBhbm90aGVyIHJ1bGUuICBJZiByMSBtYXNrcyByMiB0aGVuCiAgICAgKiByMSBtYXRjaGVzIGFueSBpbnB1dCBzdHJpbmcgdGhhdCByMiBtYXRjaGVzLiAgSWYgcjEgbWFza3MgcjIgYW5kIHIyIG1hc2tzCiAgICAgKiByMSB0aGVuIHIxID09IHIyLiAgRXhhbXBsZXM6ICJhPngiIG1hc2tzICJhYj55Ii4gICJhPngiIG1hc2tzICJhW2JdPnkiLgogICAgICogIltjXWE+eCIgbWFza3MgIltkY11hPnkiLgogICAgICovCiAgICB2aXJ0dWFsIFVCb29sIG1hc2tzKGNvbnN0IFRyYW5zbGl0ZXJhdGlvblJ1bGUmIHIyKSBjb25zdDsKCiAgICAvKioKICAgICAqIFJldHVybiB0cnVlIGlmIHRoaXMgcnVsZSBtYXRjaGVzIHRoZSBnaXZlbiB0ZXh0LgogICAgICogQHBhcmFtIHRleHQgdGhlIHRleHQsIGJvdGggdHJhbnNsYXRlZCBhbmQgdW50cmFuc2xhdGVkCiAgICAgKiBAcGFyYW0gc3RhcnQgdGhlIGJlZ2lubmluZyBpbmRleCwgaW5jbHVzaXZlOyA8Y29kZT4wIDw9IHN0YXJ0CiAgICAgKiA8PSBsaW1pdDwvY29kZT4uCiAgICAgKiBAcGFyYW0gbGltaXQgdGhlIGVuZGluZyBpbmRleCwgZXhjbHVzaXZlOyA8Y29kZT5zdGFydCA8PSBsaW1pdAogICAgICogPD0gdGV4dC5sZW5ndGgoKTwvY29kZT4uCiAgICAgKiBAcGFyYW0gY3Vyc29yIHBvc2l0aW9uIGF0IHdoaWNoIHRvIHRyYW5zbGF0ZSBuZXh0LCByZXByZXNlbnRpbmcgb2Zmc2V0CiAgICAgKiBpbnRvIHRleHQuICBUaGlzIHZhbHVlIG11c3QgYmUgYmV0d2VlbiA8Y29kZT5zdGFydDwvY29kZT4gYW5kCiAgICAgKiA8Y29kZT5saW1pdDwvY29kZT4uCiAgICAgKiBAcGFyYW0gZmlsdGVyIHRoZSBmaWx0ZXIuICBBbnkgY2hhcmFjdGVyIGZvciB3aGljaAogICAgICogPHR0PmZpbHRlci5pc0luKCk8L3R0PiByZXR1cm5zIDx0dD5mYWxzZTwvdHQ+IHdpbGwgbm90IGJlCiAgICAgKiBhbHRlcmVkIGJ5IHRoaXMgdHJhbnNsaXRlcmF0b3IuICBJZiA8dHQ+ZmlsdGVyPC90dD4gaXMKICAgICAqIDx0dD5udWxsPC90dD4gdGhlbiBubyBmaWx0ZXJpbmcgaXMgYXBwbGllZC4KICAgICAqLwogICAgdmlydHVhbCBVQm9vbCBtYXRjaGVzKGNvbnN0IFJlcGxhY2VhYmxlJiB0ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVUcmFuc1Bvc2l0aW9uJiBwb3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVHJhbnNsaXRlcmF0aW9uUnVsZURhdGEmIGRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVW5pY29kZUZpbHRlciogZmlsdGVyKSBjb25zdDsKCiAgICAvKioKICAgICAqIFJldHVybiB0aGUgZGVncmVlIG9mIG1hdGNoIGJldHdlZW4gdGhpcyBydWxlIGFuZCB0aGUgZ2l2ZW4gdGV4dC4gIFRoZQogICAgICogZGVncmVlIG9mIG1hdGNoIG1heSBiZSBtaXNtYXRjaCwgYSBwYXJ0aWFsIG1hdGNoLCBvciBhIGZ1bGwgbWF0Y2guICBBCiAgICAgKiBtaXNtYXRjaCBtZWFucyBhdCBsZWFzdCBvbmUgY2hhcmFjdGVyIG9mIHRoZSB0ZXh0IGRvZXMgbm90IG1hdGNoIHRoZQogICAgICogY29udGV4dCBvciBrZXkuICBBIHBhcnRpYWwgbWF0Y2ggbWVhbnMgc29tZSBjb250ZXh0IGFuZCBrZXkgY2hhcmFjdGVycwogICAgICogbWF0Y2gsIGJ1dCB0aGUgdGV4dCBpcyBub3QgbG9uZyBlbm91Z2ggdG8gbWF0Y2ggYWxsIG9mIHRoZW0uICBBIGZ1bGwKICAgICAqIG1hdGNoIG1lYW5zIGFsbCBjb250ZXh0IGFuZCBrZXkgY2hhcmFjdGVycyBtYXRjaC4KICAgICAqIEBwYXJhbSB0ZXh0IHRoZSB0ZXh0LCBib3RoIHRyYW5zbGF0ZWQgYW5kIHVudHJhbnNsYXRlZAogICAgICogQHBhcmFtIHN0YXJ0IHRoZSBiZWdpbm5pbmcgaW5kZXgsIGluY2x1c2l2ZTsgPGNvZGU+MCA8PSBzdGFydAogICAgICogPD0gbGltaXQ8L2NvZGU+LgogICAgICogQHBhcmFtIGxpbWl0IHRoZSBlbmRpbmcgaW5kZXgsIGV4Y2x1c2l2ZTsgPGNvZGU+c3RhcnQgPD0gbGltaXQKICAgICAqIDw9IHRleHQubGVuZ3RoKCk8L2NvZGU+LgogICAgICogQHBhcmFtIGN1cnNvciBwb3NpdGlvbiBhdCB3aGljaCB0byB0cmFuc2xhdGUgbmV4dCwgcmVwcmVzZW50aW5nIG9mZnNldAogICAgICogaW50byB0ZXh0LiAgVGhpcyB2YWx1ZSBtdXN0IGJlIGJldHdlZW4gPGNvZGU+c3RhcnQ8L2NvZGU+IGFuZAogICAgICogPGNvZGU+bGltaXQ8L2NvZGU+LgogICAgICogQHBhcmFtIGZpbHRlciB0aGUgZmlsdGVyLiAgQW55IGNoYXJhY3RlciBmb3Igd2hpY2gKICAgICAqIDx0dD5maWx0ZXIuaXNJbigpPC90dD4gcmV0dXJucyA8dHQ+ZmFsc2U8L3R0PiB3aWxsIG5vdCBiZQogICAgICogYWx0ZXJlZCBieSB0aGlzIHRyYW5zbGl0ZXJhdG9yLiAgSWYgPHR0PmZpbHRlcjwvdHQ+IGlzCiAgICAgKiA8dHQ+bnVsbDwvdHQ+IHRoZW4gbm8gZmlsdGVyaW5nIGlzIGFwcGxpZWQuCiAgICAgKiBAcmV0dXJuIG9uZSBvZiA8Y29kZT5NSVNNQVRDSDwvY29kZT4sIDxjb2RlPlBBUlRJQUxfTUFUQ0g8L2NvZGU+LCBvcgogICAgICogPGNvZGU+RlVMTF9NQVRDSDwvY29kZT4uCiAgICAgKiBAc2VlICNNSVNNQVRDSAogICAgICogQHNlZSAjUEFSVElBTF9NQVRDSAogICAgICogQHNlZSAjRlVMTF9NQVRDSAogICAgICovCiAgICB2aXJ0dWFsIGludDMyX3QgZ2V0TWF0Y2hEZWdyZWUoY29uc3QgUmVwbGFjZWFibGUmIHRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVVRyYW5zUG9zaXRpb24mIHBvcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBUcmFuc2xpdGVyYXRpb25SdWxlRGF0YSYgZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlRmlsdGVyKiBmaWx0ZXIpIGNvbnN0OwoKICAgIC8qKgogICAgICogUmV0dXJuIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyBvZiB0aGUgdGV4dCB0aGF0IG1hdGNoIHRoaXMgcnVsZS4gIElmCiAgICAgKiB0aGVyZSBpcyBhIG1pc21hdGNoLCByZXR1cm4gLTEuICBJZiB0aGUgdGV4dCBpcyBub3QgbG9uZyBlbm91Z2ggdG8gbWF0Y2gKICAgICAqIGFueSBjaGFyYWN0ZXJzLCByZXR1cm4gMC4KICAgICAqIEBwYXJhbSB0ZXh0IHRoZSB0ZXh0LCBib3RoIHRyYW5zbGF0ZWQgYW5kIHVudHJhbnNsYXRlZAogICAgICogQHBhcmFtIHN0YXJ0IHRoZSBiZWdpbm5pbmcgaW5kZXgsIGluY2x1c2l2ZTsgPGNvZGU+MCA8PSBzdGFydAogICAgICogPD0gbGltaXQ8L2NvZGU+LgogICAgICogQHBhcmFtIGxpbWl0IHRoZSBlbmRpbmcgaW5kZXgsIGV4Y2x1c2l2ZTsgPGNvZGU+c3RhcnQgPD0gbGltaXQKICAgICAqIDw9IHRleHQubGVuZ3RoKCk8L2NvZGU+LgogICAgICogQHBhcmFtIGN1cnNvciBwb3NpdGlvbiBhdCB3aGljaCB0byB0cmFuc2xhdGUgbmV4dCwgcmVwcmVzZW50aW5nIG9mZnNldAogICAgICogaW50byB0ZXh0LiAgVGhpcyB2YWx1ZSBtdXN0IGJlIGJldHdlZW4gPGNvZGU+c3RhcnQ8L2NvZGU+IGFuZAogICAgICogPGNvZGU+bGltaXQ8L2NvZGU+LgogICAgICogQHBhcmFtIHRlbXBsIHRoZSB0ZXh0IHRvIG1hdGNoIGFnYWluc3QuICBBbGwgY2hhcmFjdGVycyBtdXN0IG1hdGNoLgogICAgICogQHBhcmFtIGRhdGEgYSBkaWN0aW9uYXJ5IG9mIHZhcmlhYmxlcyBtYXBwaW5nIDxjb2RlPkNoYXJhY3RlcjwvY29kZT4KICAgICAqIHRvIDxjb2RlPlVuaWNvZGVTZXQ8L2NvZGU+CiAgICAgKiBAcGFyYW0gZmlsdGVyIHRoZSBmaWx0ZXIuICBBbnkgY2hhcmFjdGVyIGZvciB3aGljaAogICAgICogPHR0PmZpbHRlci5pc0luKCk8L3R0PiByZXR1cm5zIDx0dD5mYWxzZTwvdHQ+IHdpbGwgbm90IGJlCiAgICAgKiBhbHRlcmVkIGJ5IHRoaXMgdHJhbnNsaXRlcmF0b3IuICBJZiA8dHQ+ZmlsdGVyPC90dD4gaXMKICAgICAqIDx0dD5udWxsPC90dD4gdGhlbiBubyBmaWx0ZXJpbmcgaXMgYXBwbGllZC4KICAgICAqIEByZXR1cm4gLTEgaWYgdGhlcmUgaXMgYSBtaXNtYXRjaCwgMCBpZiB0aGUgdGV4dCBpcyBub3QgbG9uZyBlbm91Z2ggdG8KICAgICAqIG1hdGNoIGFueSBjaGFyYWN0ZXJzLCBvdGhlcndpc2UgdGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIG9mIHRleHQgdGhhdAogICAgICogbWF0Y2ggdGhpcyBydWxlLgogICAgICovCiAgICB2aXJ0dWFsIGludDMyX3QgZ2V0UmVnaW9uTWF0Y2hMZW5ndGgoY29uc3QgUmVwbGFjZWFibGUmIHRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVVRyYW5zUG9zaXRpb24mIHBvcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlU3RyaW5nJiB0ZW1wbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBUcmFuc2xpdGVyYXRpb25SdWxlRGF0YSYgZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlRmlsdGVyKiBmaWx0ZXIpIGNvbnN0OwogICAgCiAgICAvKioKICAgICAqIFJldHVybiB0cnVlIGlmIHRoZSBnaXZlbiBrZXkgbWF0Y2hlcyB0aGUgZ2l2ZW4gdGV4dC4gIFRoaXMgbWV0aG9kCiAgICAgKiBhY2NvdW50cyBmb3IgdGhlIGZhY3QgdGhhdCB0aGUga2V5IGNoYXJhY3RlciBtYXkgcmVwcmVzZW50IGEgY2hhcmFjdGVyCiAgICAgKiBzZXQuICBOb3RlIHRoYXQgdGhlIGtleSBhbmQgdGV4dCBjaGFyYWN0ZXJzIG1heSBub3QgYmUgaW50ZXJjaGFuZ2VkCiAgICAgKiB3aXRob3V0IGFsdGVyaW5nIHRoZSByZXN1bHRzLgogICAgICogQHBhcmFtIGtleUNoYXIgYSBjaGFyYWN0ZXIgaW4gdGhlIG1hdGNoIGtleQogICAgICogQHBhcmFtIHRleHRDaGFyIGEgY2hhcmFjdGVyIGluIHRoZSB0ZXh0IGJlaW5nIHRyYW5zbGl0ZXJhdGVkCiAgICAgKiBAcGFyYW0gZGF0YSBhIGRpY3Rpb25hcnkgb2YgdmFyaWFibGVzIG1hcHBpbmcgPGNvZGU+Q2hhcmFjdGVyPC9jb2RlPgogICAgICogdG8gPGNvZGU+VW5pY29kZVNldDwvY29kZT4KICAgICAqIEBwYXJhbSBmaWx0ZXIgdGhlIGZpbHRlci4gIEFueSBjaGFyYWN0ZXIgZm9yIHdoaWNoCiAgICAgKiA8dHQ+ZmlsdGVyLmlzSW4oKTwvdHQ+IHJldHVybnMgPHR0PmZhbHNlPC90dD4gd2lsbCBub3QgYmUKICAgICAqIGFsdGVyZWQgYnkgdGhpcyB0cmFuc2xpdGVyYXRvci4gIElmIDx0dD5maWx0ZXI8L3R0PiBpcwogICAgICogPHR0Pm51bGw8L3R0PiB0aGVuIG5vIGZpbHRlcmluZyBpcyBhcHBsaWVkLgogICAgICovCiAgICB2aXJ0dWFsIFVCb29sIGNoYXJNYXRjaGVzKFVDaGFyIGtleUNoYXIsIFVDaGFyIHRleHRDaGFyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVHJhbnNsaXRlcmF0aW9uUnVsZURhdGEmIGRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlRmlsdGVyKiBmaWx0ZXIpIGNvbnN0OwoKcHJpdmF0ZToKCiAgICB2b2lkIGluaXQoY29uc3QgVW5pY29kZVN0cmluZyYgaW5wdXQsCiAgICAgICAgICAgICAgaW50MzJfdCBhbnRlQ29udGV4dFBvcywgaW50MzJfdCBwb3N0Q29udGV4dFBvcywKICAgICAgICAgICAgICBjb25zdCBVbmljb2RlU3RyaW5nJiBvdXRwdXQsCiAgICAgICAgICAgICAgaW50MzJfdCBjdXJzb3JQb3MsIGludDMyX3QgY3Vyc29yT2Zmc2V0LAogICAgICAgICAgICAgIGludDMyX3QqIGFkb3B0ZWRTZWdzLAogICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cyk7Cn07CgojZW5kaWYK