LyoKKiBDb3B5cmlnaHQgqSB7MTk5OX0sIEludGVybmF0aW9uYWwgQnVzaW5lc3MgTWFjaGluZXMgQ29ycG9yYXRpb24gYW5kIG90aGVycy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqICAgRGF0ZSAgICAgICAgTmFtZSAgICAgICAgRGVzY3JpcHRpb24KKiAgIDExLzE3Lzk5ICAgIGFsaXUgICAgICAgIENyZWF0aW9uLgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiovCiNpZm5kZWYgUkJUX1JVTEVfSAojZGVmaW5lIFJCVF9SVUxFX0gKCiNpbmNsdWRlICJ1bmljb2RlL3VuaXN0ci5oIgojaW5jbHVkZSAidW5pY29kZS91dHJhbnMuaCIKCmNsYXNzIFJlcGxhY2VhYmxlOwpjbGFzcyBUcmFuc2xpdGVyYXRpb25SdWxlRGF0YTsKY2xhc3MgVW5pY29kZUZpbHRlcjsKCi8qKgogKiBBIHRyYW5zbGl0ZXJhdGlvbiBydWxlIHVzZWQgYnkKICogPGNvZGU+UnVsZUJhc2VkVHJhbnNsaXRlcmF0b3I8L2NvZGU+LgogKiA8Y29kZT5UcmFuc2xpdGVyYXRpb25SdWxlPC9jb2RlPiBpcyBhbiBpbW11dGFibGUgb2JqZWN0LgogKgogKiA8cD5BIHJ1bGUgY29uc2lzdHMgb2YgYW4gaW5wdXQgcGF0dGVybiBhbmQgYW4gb3V0cHV0IHN0cmluZy4gIFdoZW4KICogdGhlIGlucHV0IHBhdHRlcm4gaXMgbWF0Y2hlZCwgdGhlIG91dHB1dCBzdHJpbmcgaXMgZW1pdHRlZC4gIFRoZQogKiBpbnB1dCBwYXR0ZXJuIGNvbnNpc3RzIG9mIHplcm8gb3IgbW9yZSBjaGFyYWN0ZXJzIHdoaWNoIGFyZSBtYXRjaGVkCiAqIGV4YWN0bHkgKHRoZSBrZXkpIGFuZCBvcHRpb25hbCBjb250ZXh0LiAgQ29udGV4dCBtdXN0IG1hdGNoIGlmIGl0CiAqIGlzIHNwZWNpZmllZC4gIENvbnRleHQgbWF5IGJlIHNwZWNpZmllZCBiZWZvcmUgdGhlIGtleSwgYWZ0ZXIgdGhlCiAqIGtleSwgb3IgYm90aC4gIFRoZSBrZXksIHByZWNlZGluZyBjb250ZXh0LCBhbmQgZm9sbG93aW5nIGNvbnRleHQKICogbWF5IGNvbnRhaW4gdmFyaWFibGVzLiAgVmFyaWFibGVzIHJlcHJlc2VudCBhIHNldCBvZiBVbmljb2RlCiAqIGNoYXJhY3RlcnMsIHN1Y2ggYXMgdGhlIGxldHRlcnMgPGk+YTwvaT4gdGhyb3VnaCA8aT56PC9pPi4KICogVmFyaWFibGVzIGFyZSBkZXRlY3RlZCBieSBsb29raW5nIHVwIGVhY2ggY2hhcmFjdGVyIGluIGEgc3VwcGxpZWQKICogdmFyaWFibGUgbGlzdCB0byBzZWUgaWYgaXQgaGFzIGJlZW4gc28gZGVmaW5lZC4gCiAqCiAqIEBhdXRob3IgQWxhbiBMaXUKICovCmNsYXNzIFRyYW5zbGl0ZXJhdGlvblJ1bGUgewoKcHVibGljOgoKICAgIC8qKgogICAgICogQ29uc3RhbnRzIHJldHVybmVkIGJ5IDxjb2RlPmdldE1hdGNoRGVncmVlKCk8L2NvZGU+IGluZGljYXRpbmcKICAgICAqIHRoZSBkZWdyZWUgb2YgbWF0Y2ggYmV0d2VlbiB0aGUgdGV4dCBhbmQgdGhpcyBydWxlLgogICAgICogQHNlZSAjZ2V0TWF0Y2hEZWdyZWUKICAgICAqLwogICAgZW51bSB7CiAgICAgICAgLyoqCiAgICAgICAgICogQ29uc3RhbnQgcmV0dXJuZWQgYnkgPGNvZGU+Z2V0TWF0Y2hEZWdyZWUoKTwvY29kZT4KICAgICAgICAgKiBpbmRpY2F0aW5nIGEgbWlzbWF0Y2ggYmV0d2VlbiB0aGUgdGV4dCBhbmQgdGhpcyBydWxlLiAgT25lCiAgICAgICAgICogb3IgbW9yZSBjaGFyYWN0ZXJzIG9mIHRoZSBjb250ZXh0IG9yIGtleSBkbyBub3QgbWF0Y2ggdGhlCiAgICAgICAgICogdGV4dC4KICAgICAgICAgKi8KICAgICAgICBNSVNNQVRDSCwKCiAgICAgICAgLyoqCiAgICAgICAgICogQ29uc3RhbnQgcmV0dXJuZWQgYnkgPGNvZGU+Z2V0TWF0Y2hEZWdyZWUoKTwvY29kZT4KICAgICAgICAgKiBpbmRpY2F0aW5nIGEgcGFydGlhbCBtYXRjaCBiZXR3ZWVuIHRoZSB0ZXh0IGFuZCB0aGlzIHJ1bGUuCiAgICAgICAgICogQWxsIGNoYXJhY3RlcnMgb2YgdGhlIHRleHQgbWF0Y2ggdGhlIGNvcnJlc3BvbmRpbmcgY29udGV4dAogICAgICAgICAqIG9yIGtleSwgYnV0IG1vcmUgY2hhcmFjdGVycyBhcmUgcmVxdWlyZWQgZm9yIGEgY29tcGxldGUKICAgICAgICAgKiBtYXRjaC4gIFRoZXJlIGFyZSBzb21lIGtleSBvciBjb250ZXh0IGNoYXJhY3RlcnMgYXQgdGhlIGVuZAogICAgICAgICAqIG9mIHRoZSBwYXR0ZXJuIHRoYXQgcmVtYWluIHVubWF0Y2hlZCBiZWNhdXNlIHRoZSB0ZXh0IGlzbid0CiAgICAgICAgICogbG9uZyBlbm91Z2guCiAgICAgICAgICovCiAgICAgICAgUEFSVElBTF9NQVRDSCwKICAgICAgICAKICAgICAgICAvKioKICAgICAgICAgKiBDb25zdGFudCByZXR1cm5lZCBieSA8Y29kZT5nZXRNYXRjaERlZ3JlZSgpPC9jb2RlPgogICAgICAgICAqIGluZGljYXRpbmcgYSBjb21wbGV0ZSBtYXRjaCBiZXR3ZWVuIHRoZSB0ZXh0IGFuZCB0aGlzIHJ1bGUuCiAgICAgICAgICogVGhlIHRleHQgbWF0Y2hlcyBhbGwgY29udGV4dCBhbmQga2V5IGNoYXJhY3RlcnMuCiAgICAgICAgICovCiAgICAgICAgRlVMTF9NQVRDSAogICAgfTsKCiAgICAvKioKICAgICAqIFRoZSBjaGFyYWN0ZXIgYXQgaW5kZXggaSwgd2hlcmUgaSA8IGNvbnRleHRTdGFydCB8fCBpID49IGNvbnRleHRMaW1pdCwKICAgICAqIGlzIEVUSEVSLiAgVGhpcyBhbGxvd3MgZXhwbGljaXQgbWF0Y2hpbmcgYnkgcnVsZXMgYW5kIFVuaWNvZGVTZXRzCiAgICAgKiBvZiB0ZXh0IG91dHNpZGUgdGhlIGNvbnRleHQuICBJbiB0cmFkaXRpb25hbCB0ZXJtcywgdGhpcyBhbGxvd3MgYW5jaG9yaW5nCiAgICAgKiBhdCB0aGUgc3RhcnQgYW5kL29yIGVuZC4KICAgICAqLwogICAgc3RhdGljIGNvbnN0IFVDaGFyIEVUSEVSOwoKcHJpdmF0ZToKCiAgICAvKioKICAgICAqIFRoZSBzdHJpbmcgdGhhdCBtdXN0IGJlIG1hdGNoZWQsIGNvbnNpc3Rpbmcgb2YgdGhlIGFudGVDb250ZXh0LCBrZXksCiAgICAgKiBhbmQgcG9zdENvbnRleHQsIGNvbmNhdGVuYXRlZCB0b2dldGhlciwgaW4gdGhhdCBvcmRlci4gIFNvbWUgY29tcG9uZW50cwogICAgICogbWF5IGJlIGVtcHR5ICh6ZXJvIGxlbmd0aCkuCiAgICAgKiBAc2VlIGFudGVDb250ZXh0TGVuZ3RoCiAgICAgKiBAc2VlIGtleUxlbmd0aAogICAgICovCiAgICBVbmljb2RlU3RyaW5nIHBhdHRlcm47CgogICAgLyoqCiAgICAgKiBUaGUgc3RyaW5nIHRoYXQgaXMgZW1pdHRlZCBpZiB0aGUga2V5LCBhbnRlQ29udGV4dCwgYW5kIHBvc3RDb250ZXh0CiAgICAgKiBhcmUgbWF0Y2hlZC4KICAgICAqLwogICAgVW5pY29kZVN0cmluZyBvdXRwdXQ7CgogICAgLyoqCiAgICAgKiBBcnJheSBvZiBzZWdtZW50cy4gIFRoZXNlIGFyZSBzZWdtZW50cyBvZiB0aGUgaW5wdXQgc3RyaW5nIHRoYXQgbWF5IGJlCiAgICAgKiByZWZlcmVuY2VkIGFuZCBhcHBlYXIgaW4gdGhlIG91dHB1dCBzdHJpbmcuICBFYWNoIHNlZ21lbnQgaXMgc3RvcmVkIGFzIGFuCiAgICAgKiBvZmZzZXQsIGxpbWl0IHBhaXIuICBTZWdtZW50cyBhcmUgcmVmZXJlbmNlZCBieSBhIDEtYmFzZWQgaW5kZXg7CiAgICAgKiByZWZlcmVuY2UgaSB0aHVzIGluY2x1ZGVzIGNoYXJhY3RlcnMgYXQgb2Zmc2V0IHNlZ21lbnRzWzIqaS0yXSB0bwogICAgICogc2VnbWVudHNbMippLTFdLTEgaW4gdGhlIHBhdHRlcm4gc3RyaW5nLgogICAgICoKICAgICAqIEluIHRoZSBvdXRwdXQgc3RyaW5nLCBhIHNlZ21lbnQgcmVmZXJlbmNlIGlzIGluZGljYXRlZCBieSBhIGNoYXJhY3RlciBpbgogICAgICogYSBzcGVjaWFsIHJhbmdlLCBhcyBkZWZpbmVkIGJ5IFJ1bGVCYXNlZFRyYW5zbGl0ZXJhdG9yLkRhdGEuCiAgICAgKgogICAgICogTW9zdCBydWxlcyBoYXZlIG5vIHNlZ21lbnRzLCBpbiB3aGljaCBjYXNlIHNlZ21lbnRzIGlzIG51bGwsIGFuZCB0aGUKICAgICAqIG91dHB1dCBzdHJpbmcgbmVlZCBub3QgYmUgY2hlY2tlZCBmb3Igc2VnbWVudCByZWZlcmVuY2UgY2hhcmFjdGVycy4KICAgICAqLwogICAgaW50MzJfdCogc2VnbWVudHM7CgogICAgLyoqCiAgICAgKiBUaGUgbGVuZ3RoIG9mIHRoZSBzdHJpbmcgdGhhdCBtdXN0IG1hdGNoIGJlZm9yZSB0aGUga2V5LiAgSWYKICAgICAqIHplcm8sIHRoZW4gdGhlcmUgaXMgbm8gbWF0Y2hpbmcgcmVxdWlyZW1lbnQgYmVmb3JlIHRoZSBrZXkuCiAgICAgKiBTdWJzdHJpbmcgWzAsYW50ZUNvbnRleHRMZW5ndGgpIG9mIHBhdHRlcm4gaXMgdGhlIGFudGVDb250ZXh0LgogICAgICovCiAgICBpbnQzMl90IGFudGVDb250ZXh0TGVuZ3RoOwoKICAgIC8qKgogICAgICogVGhlIGxlbmd0aCBvZiB0aGUga2V5LiAgU3Vic3RyaW5nIFthbnRlQ29udGV4dExlbmd0aCwKICAgICAqIGFudGVDb250ZXh0TGVuZ3RoICsga2V5TGVuZ3RoKSBpcyB0aGUga2V5LgoKICAgICAqLwogICAgaW50MzJfdCBrZXlMZW5ndGg7CgogICAgLyoqCiAgICAgKiBUaGUgcG9zaXRpb24gb2YgdGhlIGN1cnNvciBhZnRlciBlbWl0dGluZyB0aGUgb3V0cHV0IHN0cmluZywgZnJvbSAwIHRvCiAgICAgKiBvdXRwdXQubGVuZ3RoKCkuICBGb3IgbW9zdCBydWxlcyB3aXRoIG5vIHNwZWNpYWwgY3Vyc29yIHNwZWNpZmljYXRpb24sCiAgICAgKiB0aGUgY3Vyc29yUG9zIGlzIG91dHB1dC5sZW5ndGgoKS4KICAgICAqLwogICAgaW50MzJfdCBjdXJzb3JQb3M7CgpwdWJsaWM6CgogICAgLyoqCiAgICAgKiBDb25zdHJ1Y3QgYSBuZXcgcnVsZSB3aXRoIHRoZSBnaXZlbiBpbnB1dCwgb3V0cHV0IHRleHQsIGFuZCBvdGhlcgogICAgICogYXR0cmlidXRlcy4gIEEgY3Vyc29yIHBvc2l0aW9uIG1heSBiZSBzcGVjaWZpZWQgZm9yIHRoZSBvdXRwdXQgdGV4dC4KICAgICAqIEBwYXJhbSBpbnB1dCBpbnB1dCBzdHJpbmcsIGluY2x1ZGluZyBrZXkgYW5kIG9wdGlvbmFsIGFudGUgYW5kCiAgICAgKiBwb3N0IGNvbnRleHQKICAgICAqIEBwYXJhbSBhbnRlQ29udGV4dFBvcyBvZmZzZXQgaW50byBpbnB1dCB0byBlbmQgb2YgYW50ZSBjb250ZXh0LCBvciAtMSBpZgogICAgICogbm9uZS4gIE11c3QgYmUgPD0gaW5wdXQubGVuZ3RoKCkgaWYgbm90IC0xLgogICAgICogQHBhcmFtIHBvc3RDb250ZXh0UG9zIG9mZnNldCBpbnRvIGlucHV0IHRvIHN0YXJ0IG9mIHBvc3QgY29udGV4dCwgb3IgLTEKICAgICAqIGlmIG5vbmUuICBNdXN0IGJlIDw9IGlucHV0Lmxlbmd0aCgpIGlmIG5vdCAtMSwgYW5kIG11c3QgYmUgPj0KICAgICAqIGFudGVDb250ZXh0UG9zLgogICAgICogQHBhcmFtIG91dHB1dCBvdXRwdXQgc3RyaW5nCiAgICAgKiBAcGFyYW0gY3Vyc29yUG9zIG9mZnNldCBpbnRvIG91dHB1dCBhdCB3aGljaCBjdXJzb3IgaXMgbG9jYXRlZCwgb3IgLTEgaWYKICAgICAqIG5vbmUuICBJZiBsZXNzIHRoYW4gemVybywgdGhlbiB0aGUgY3Vyc29yIGlzIHBsYWNlZCBhZnRlciB0aGUKICAgICAqIDxjb2RlPm91dHB1dDwvY29kZT47IHRoYXQgaXMsIC0xIGlzIGVxdWl2YWxlbnQgdG8KICAgICAqIDxjb2RlPm91dHB1dC5sZW5ndGgoKTwvY29kZT4uICBJZiBncmVhdGVyIHRoYW4KICAgICAqIDxjb2RlPm91dHB1dC5sZW5ndGgoKTwvY29kZT4gdGhlbiBhbiBleGNlcHRpb24gaXMgdGhyb3duLgogICAgICogQHBhcmFtIGN1cnNvck9mZnNldCBhbiBvZmZzZXQgdG8gYmUgYWRkZWQgdG8gY3Vyc29yUG9zIHRvIHBvc2l0aW9uIHRoZQogICAgICogY3Vyc29yIGVpdGhlciBpbiB0aGUgYW50ZSBjb250ZXh0LCBpZiA8IDAsIG9yIGluIHRoZSBwb3N0IGNvbnRleHQsIGlmID4KICAgICAqIDAuICBGb3IgZXhhbXBsZSwgdGhlIHJ1bGUgImFiY3tkZWZ9ID4gfCBAQEAgeHl6OyIgY2hhbmdlcyAiZGVmIiB0bwogICAgICogInh5eiIgYW5kIG1vdmVzIHRoZSBjdXJzb3IgdG8gYmVmb3JlICJhIi4gIEl0IHdvdWxkIGhhdmUgYSBjdXJzb3JPZmZzZXQKICAgICAqIG9mIC0zLgogICAgICogQHBhcmFtIGFkb3B0ZWRTZWdzIGFycmF5IG9mIDJuIGludGVnZXJzLiAgRWFjaCBvZiBuIHBhaXJzIGNvbnNpc3RzIG9mIG9mZnNldCwKICAgICAqIGxpbWl0IGZvciBhIHNlZ21lbnQgb2YgdGhlIGlucHV0IHN0cmluZy4gIENoYXJhY3RlcnMgaW4gdGhlIG91dHB1dCBzdHJpbmcKICAgICAqIHJlZmVyIHRvIHRoZXNlIHNlZ21lbnRzIGlmIHRoZXkgYXJlIGluIGEgc3BlY2lhbCByYW5nZSBkZXRlcm1pbmVkIGJ5IHRoZQogICAgICogYXNzb2NpYXRlZCBSdWxlQmFzZWRUcmFuc2xpdGVyYXRvci5EYXRhIG9iamVjdC4gIE1heSBiZSBudWxsIGlmIHRoZXJlIGFyZQogICAgICogbm8gc2VnbWVudHMuCiAgICAgKiBAcGFyYW0gYW5jaG9yU3RhcnQgVFJVRSBpZiB0aGUgdGhlIHJ1bGUgaXMgYW5jaG9yZWQgb24gdGhlIGxlZnQgdG8KICAgICAqIHRoZSBjb250ZXh0IHN0YXJ0CiAgICAgKiBAcGFyYW0gYW5jaG9yRW5kIFRSVUUgaWYgdGhlIHJ1bGUgaXMgYW5jaG9yZWQgb24gdGhlIHJpZ2h0IHRvIHRoZQogICAgICogY29udGV4dCBsaW1pdAogICAgICovCiAgICBUcmFuc2xpdGVyYXRpb25SdWxlKGNvbnN0IFVuaWNvZGVTdHJpbmcmIGlucHV0LAogICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IGFudGVDb250ZXh0UG9zLCBpbnQzMl90IHBvc3RDb250ZXh0UG9zLAogICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlU3RyaW5nJiBvdXRwdXQsCiAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QgY3Vyc29yUG9zLCBpbnQzMl90IGN1cnNvck9mZnNldCwKICAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCogYWRvcHRlZFNlZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgIFVCb29sIGFuY2hvclN0YXJ0LCBVQm9vbCBhbmNob3JFbmQsCiAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cyk7CgogICAgLyoqCiAgICAgKiBDb25zdHJ1Y3QgYSBuZXcgcnVsZSB3aXRoIHRoZSBnaXZlbiBpbnB1dCwgb3V0cHV0IHRleHQsIGFuZCBvdGhlcgogICAgICogYXR0cmlidXRlcy4gIEEgY3Vyc29yIHBvc2l0aW9uIG1heSBiZSBzcGVjaWZpZWQgZm9yIHRoZSBvdXRwdXQgdGV4dC4KICAgICAqIEBwYXJhbSBpbnB1dCBpbnB1dCBzdHJpbmcsIGluY2x1ZGluZyBrZXkgYW5kIG9wdGlvbmFsIGFudGUgYW5kCiAgICAgKiBwb3N0IGNvbnRleHQKICAgICAqIEBwYXJhbSBhbnRlQ29udGV4dFBvcyBvZmZzZXQgaW50byBpbnB1dCB0byBlbmQgb2YgYW50ZSBjb250ZXh0LCBvciAtMSBpZgogICAgICogbm9uZS4gIE11c3QgYmUgPD0gaW5wdXQubGVuZ3RoKCkgaWYgbm90IC0xLgogICAgICogQHBhcmFtIHBvc3RDb250ZXh0UG9zIG9mZnNldCBpbnRvIGlucHV0IHRvIHN0YXJ0IG9mIHBvc3QgY29udGV4dCwgb3IgLTEKICAgICAqIGlmIG5vbmUuICBNdXN0IGJlIDw9IGlucHV0Lmxlbmd0aCgpIGlmIG5vdCAtMSwgYW5kIG11c3QgYmUgPj0KICAgICAqIGFudGVDb250ZXh0UG9zLgogICAgICogQHBhcmFtIG91dHB1dCBvdXRwdXQgc3RyaW5nCiAgICAgKiBAcGFyYW0gY3Vyc29yUG9zIG9mZnNldCBpbnRvIG91dHB1dCBhdCB3aGljaCBjdXJzb3IgaXMgbG9jYXRlZCwgb3IgLTEgaWYKICAgICAqIG5vbmUuICBJZiBsZXNzIHRoYW4gemVybywgdGhlbiB0aGUgY3Vyc29yIGlzIHBsYWNlZCBhZnRlciB0aGUKICAgICAqIDxjb2RlPm91dHB1dDwvY29kZT47IHRoYXQgaXMsIC0xIGlzIGVxdWl2YWxlbnQgdG8KICAgICAqIDxjb2RlPm91dHB1dC5sZW5ndGgoKTwvY29kZT4uICBJZiBncmVhdGVyIHRoYW4KICAgICAqIDxjb2RlPm91dHB1dC5sZW5ndGgoKTwvY29kZT4gdGhlbiBhbiBleGNlcHRpb24gaXMgdGhyb3duLgogICAgICovCiAgICBUcmFuc2xpdGVyYXRpb25SdWxlKGNvbnN0IFVuaWNvZGVTdHJpbmcmIGlucHV0LAogICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IGFudGVDb250ZXh0UG9zLCBpbnQzMl90IHBvc3RDb250ZXh0UG9zLAogICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlU3RyaW5nJiBvdXRwdXQsCiAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QgY3Vyc29yUG9zLAogICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpOwoKICAgIC8qKgogICAgICogQ29weSBjb25zdHJ1Y3Rvci4KICAgICAqLwogICAgVHJhbnNsaXRlcmF0aW9uUnVsZShUcmFuc2xpdGVyYXRpb25SdWxlJiBvdGhlcik7CgogICAgLyoqCiAgICAgKiBEZXN0cnVjdG9yLgogICAgICovCiAgICB2aXJ0dWFsIH5UcmFuc2xpdGVyYXRpb25SdWxlKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm4gdGhlIHBvc2l0aW9uIG9mIHRoZSBjdXJzb3Igd2l0aGluIHRoZSBvdXRwdXQgc3RyaW5nLgogICAgICogQHJldHVybiBhIHZhbHVlIGZyb20gMCB0byA8Y29kZT5nZXRPdXRwdXQoKS5sZW5ndGgoKTwvY29kZT4sIGluY2x1c2l2ZS4KICAgICAqLwogICAgdmlydHVhbCBpbnQzMl90IGdldEN1cnNvclBvcyh2b2lkKSBjb25zdDsKCiAgICAvKioKICAgICAqIFJldHVybiB0aGUgcHJlY2VkaW5nIGNvbnRleHQgbGVuZ3RoLiAgVGhpcyBtZXRob2QgaXMgbmVlZGVkIHRvCiAgICAgKiBzdXBwb3J0IHRoZSA8Y29kZT5UcmFuc2xpdGVyYXRvcjwvY29kZT4gbWV0aG9kCiAgICAgKiA8Y29kZT5nZXRNYXhpbXVtQ29udGV4dExlbmd0aCgpPC9jb2RlPi4KICAgICAqLwogICAgdmlydHVhbCBpbnQzMl90IGdldEFudGVDb250ZXh0TGVuZ3RoKHZvaWQpIGNvbnN0OwoKICAgIC8qKgogICAgICogSW50ZXJuYWwgbWV0aG9kLiAgUmV0dXJucyA4LWJpdCBpbmRleCB2YWx1ZSBmb3IgdGhpcyBydWxlLgogICAgICogVGhpcyBpcyB0aGUgbG93IGJ5dGUgb2YgdGhlIGZpcnN0IGNoYXJhY3RlciBvZiB0aGUga2V5LAogICAgICogdW5sZXNzIHRoZSBmaXJzdCBjaGFyYWN0ZXIgb2YgdGhlIGtleSBpcyBhIHNldC4gIElmIGl0J3MgYQogICAgICogc2V0LCBvciBvdGhlcndpc2UgY2FuIG1hdGNoIG11bHRpcGxlIGtleXMsIHRoZSBpbmRleCB2YWx1ZSBpcyAtMS4KICAgICAqLwogICAgaW50MTZfdCBnZXRJbmRleFZhbHVlKGNvbnN0IFRyYW5zbGl0ZXJhdGlvblJ1bGVEYXRhJiBkYXRhKSBjb25zdDsKCiAgICAvKioKICAgICAqIERvIGEgcmVwbGFjZW1lbnQgb2YgdGhlIGlucHV0IHBhdHRlcm4gd2l0aCB0aGUgb3V0cHV0IHRleHQgaW4KICAgICAqIHRoZSBnaXZlbiBzdHJpbmcsIGF0IHRoZSBnaXZlbiBvZmZzZXQuICBUaGlzIG1ldGhvZCBhc3N1bWVzCiAgICAgKiB0aGF0IGEgbWF0Y2ggaGFzIGFscmVhZHkgYmVlbiBmb3VuZCBpbiB0aGUgZ2l2ZW4gdGV4dCBhdCB0aGUKICAgICAqIGdpdmVuIHBvc2l0aW9uLgogICAgICogQHBhcmFtIHRleHQgdGhlIHRleHQgY29udGFpbmluZyB0aGUgc3Vic3RyaW5nIHRvIGJlIHJlcGxhY2VkCiAgICAgKiBAcGFyYW0gb2Zmc2V0IHRoZSBvZmZzZXQgaW50byB0aGUgdGV4dCBhdCB3aGljaCB0aGUgcGF0dGVybgogICAgICogbWF0Y2hlcy4gIFRoaXMgaXMgdGhlIG9mZnNldCB0byB0aGUgcG9pbnQgYWZ0ZXIgdGhlIGFudGUKICAgICAqIGNvbnRleHQsIGlmIGFueSwgYW5kIGJlZm9yZSB0aGUgbWF0Y2ggc3RyaW5nIGFuZCBhbnkgcG9zdAogICAgICogY29udGV4dC4KICAgICAqIEBwYXJhbSBkYXRhIHRoZSBSdWxlQmFzZWRUcmFuc2xpdGVyYXRvci5EYXRhIG9iamVjdCBzcGVjaWZ5aW5nCiAgICAgKiBjb250ZXh0IGZvciB0aGlzIHRyYW5zbGl0ZXJhdG9yLgogICAgICogQHJldHVybiB0aGUgY2hhbmdlIGluIHRoZSBsZW5ndGggb2YgdGhlIHRleHQKICAgICAqLwogICAgaW50MzJfdCByZXBsYWNlKFJlcGxhY2VhYmxlJiB0ZXh0LCBpbnQzMl90IG9mZnNldCwKICAgICAgICAgICAgICAgICAgICBjb25zdCBUcmFuc2xpdGVyYXRpb25SdWxlRGF0YSYgZGF0YSkgY29uc3Q7CgogICAgLyoqCiAgICAgKiBJbnRlcm5hbCBtZXRob2QuICBSZXR1cm5zIHRydWUgaWYgdGhpcyBydWxlIG1hdGNoZXMgdGhlIGdpdmVuCiAgICAgKiBpbmRleCB2YWx1ZS4gIFRoZSBpbmRleCB2YWx1ZSBpcyBhbiA4LWJpdCBpbnRlZ2VyLCAwLi4yNTUsCiAgICAgKiByZXByZXNlbnRpbmcgdGhlIGxvdyBieXRlIG9mIHRoZSBmaXJzdCBjaGFyYWN0ZXIgb2YgdGhlIGtleS4KICAgICAqIEl0IG1hdGNoZXMgdGhpcyBydWxlIGlmIGl0IG1hdGNoZXMgdGhlIGZpcnN0IGNoYXJhY3RlciBvZiB0aGUKICAgICAqIGtleSwgb3IgaWYgdGhlIGZpcnN0IGNoYXJhY3RlciBvZiB0aGUga2V5IGlzIGEgc2V0LCBhbmQgdGhlIHNldAogICAgICogY29udGFpbnMgYW55IGNoYXJhY3RlciB3aXRoIGEgbG93IGJ5dGUgZXF1YWwgdG8gdGhlIGluZGV4CiAgICAgKiB2YWx1ZS4gIElmIHRoZSBydWxlIGNvbnRhaW5zIG9ubHkgYW50ZSBjb250ZXh0LCBhcyBpbiBmb28pPmJhciwKICAgICAqIHRoZW4gaXQgd2lsbCBtYXRjaCBhbnkga2V5LgogICAgICovCiAgICBVQm9vbCBtYXRjaGVzSW5kZXhWYWx1ZSh1aW50OF90IHYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVHJhbnNsaXRlcmF0aW9uUnVsZURhdGEmIGRhdGEpIGNvbnN0OwoKICAgIC8qKgogICAgICogUmV0dXJuIHRydWUgaWYgdGhpcyBydWxlIG1hc2tzIGFub3RoZXIgcnVsZS4gIElmIHIxIG1hc2tzIHIyIHRoZW4KICAgICAqIHIxIG1hdGNoZXMgYW55IGlucHV0IHN0cmluZyB0aGF0IHIyIG1hdGNoZXMuICBJZiByMSBtYXNrcyByMiBhbmQgcjIgbWFza3MKICAgICAqIHIxIHRoZW4gcjEgPT0gcjIuICBFeGFtcGxlczogImE+eCIgbWFza3MgImFiPnkiLiAgImE+eCIgbWFza3MgImFbYl0+eSIuCiAgICAgKiAiW2NdYT54IiBtYXNrcyAiW2RjXWE+eSIuCiAgICAgKi8KICAgIHZpcnR1YWwgVUJvb2wgbWFza3MoY29uc3QgVHJhbnNsaXRlcmF0aW9uUnVsZSYgcjIpIGNvbnN0OwoKICAgIC8qKgogICAgICogUmV0dXJuIHRydWUgaWYgdGhpcyBydWxlIG1hdGNoZXMgdGhlIGdpdmVuIHRleHQuCiAgICAgKiBAcGFyYW0gdGV4dCB0aGUgdGV4dCwgYm90aCB0cmFuc2xhdGVkIGFuZCB1bnRyYW5zbGF0ZWQKICAgICAqIEBwYXJhbSBzdGFydCB0aGUgYmVnaW5uaW5nIGluZGV4LCBpbmNsdXNpdmU7IDxjb2RlPjAgPD0gc3RhcnQKICAgICAqIDw9IGxpbWl0PC9jb2RlPi4KICAgICAqIEBwYXJhbSBsaW1pdCB0aGUgZW5kaW5nIGluZGV4LCBleGNsdXNpdmU7IDxjb2RlPnN0YXJ0IDw9IGxpbWl0CiAgICAgKiA8PSB0ZXh0Lmxlbmd0aCgpPC9jb2RlPi4KICAgICAqIEBwYXJhbSBjdXJzb3IgcG9zaXRpb24gYXQgd2hpY2ggdG8gdHJhbnNsYXRlIG5leHQsIHJlcHJlc2VudGluZyBvZmZzZXQKICAgICAqIGludG8gdGV4dC4gIFRoaXMgdmFsdWUgbXVzdCBiZSBiZXR3ZWVuIDxjb2RlPnN0YXJ0PC9jb2RlPiBhbmQKICAgICAqIDxjb2RlPmxpbWl0PC9jb2RlPi4KICAgICAqIEBwYXJhbSBmaWx0ZXIgdGhlIGZpbHRlci4gIEFueSBjaGFyYWN0ZXIgZm9yIHdoaWNoCiAgICAgKiA8dHQ+ZmlsdGVyLmlzSW4oKTwvdHQ+IHJldHVybnMgPHR0PmZhbHNlPC90dD4gd2lsbCBub3QgYmUKICAgICAqIGFsdGVyZWQgYnkgdGhpcyB0cmFuc2xpdGVyYXRvci4gIElmIDx0dD5maWx0ZXI8L3R0PiBpcwogICAgICogPHR0Pm51bGw8L3R0PiB0aGVuIG5vIGZpbHRlcmluZyBpcyBhcHBsaWVkLgogICAgICovCiAgICB2aXJ0dWFsIFVCb29sIG1hdGNoZXMoY29uc3QgUmVwbGFjZWFibGUmIHRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVVRyYW5zUG9zaXRpb24mIHBvcywKICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBUcmFuc2xpdGVyYXRpb25SdWxlRGF0YSYgZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlRmlsdGVyKiBmaWx0ZXIpIGNvbnN0OwoKICAgIC8qKgogICAgICogUmV0dXJuIHRoZSBkZWdyZWUgb2YgbWF0Y2ggYmV0d2VlbiB0aGlzIHJ1bGUgYW5kIHRoZSBnaXZlbiB0ZXh0LiAgVGhlCiAgICAgKiBkZWdyZWUgb2YgbWF0Y2ggbWF5IGJlIG1pc21hdGNoLCBhIHBhcnRpYWwgbWF0Y2gsIG9yIGEgZnVsbCBtYXRjaC4gIEEKICAgICAqIG1pc21hdGNoIG1lYW5zIGF0IGxlYXN0IG9uZSBjaGFyYWN0ZXIgb2YgdGhlIHRleHQgZG9lcyBub3QgbWF0Y2ggdGhlCiAgICAgKiBjb250ZXh0IG9yIGtleS4gIEEgcGFydGlhbCBtYXRjaCBtZWFucyBzb21lIGNvbnRleHQgYW5kIGtleSBjaGFyYWN0ZXJzCiAgICAgKiBtYXRjaCwgYnV0IHRoZSB0ZXh0IGlzIG5vdCBsb25nIGVub3VnaCB0byBtYXRjaCBhbGwgb2YgdGhlbS4gIEEgZnVsbAogICAgICogbWF0Y2ggbWVhbnMgYWxsIGNvbnRleHQgYW5kIGtleSBjaGFyYWN0ZXJzIG1hdGNoLgogICAgICogQHBhcmFtIHRleHQgdGhlIHRleHQsIGJvdGggdHJhbnNsYXRlZCBhbmQgdW50cmFuc2xhdGVkCiAgICAgKiBAcGFyYW0gc3RhcnQgdGhlIGJlZ2lubmluZyBpbmRleCwgaW5jbHVzaXZlOyA8Y29kZT4wIDw9IHN0YXJ0CiAgICAgKiA8PSBsaW1pdDwvY29kZT4uCiAgICAgKiBAcGFyYW0gbGltaXQgdGhlIGVuZGluZyBpbmRleCwgZXhjbHVzaXZlOyA8Y29kZT5zdGFydCA8PSBsaW1pdAogICAgICogPD0gdGV4dC5sZW5ndGgoKTwvY29kZT4uCiAgICAgKiBAcGFyYW0gY3Vyc29yIHBvc2l0aW9uIGF0IHdoaWNoIHRvIHRyYW5zbGF0ZSBuZXh0LCByZXByZXNlbnRpbmcgb2Zmc2V0CiAgICAgKiBpbnRvIHRleHQuICBUaGlzIHZhbHVlIG11c3QgYmUgYmV0d2VlbiA8Y29kZT5zdGFydDwvY29kZT4gYW5kCiAgICAgKiA8Y29kZT5saW1pdDwvY29kZT4uCiAgICAgKiBAcGFyYW0gZmlsdGVyIHRoZSBmaWx0ZXIuICBBbnkgY2hhcmFjdGVyIGZvciB3aGljaAogICAgICogPHR0PmZpbHRlci5pc0luKCk8L3R0PiByZXR1cm5zIDx0dD5mYWxzZTwvdHQ+IHdpbGwgbm90IGJlCiAgICAgKiBhbHRlcmVkIGJ5IHRoaXMgdHJhbnNsaXRlcmF0b3IuICBJZiA8dHQ+ZmlsdGVyPC90dD4gaXMKICAgICAqIDx0dD5udWxsPC90dD4gdGhlbiBubyBmaWx0ZXJpbmcgaXMgYXBwbGllZC4KICAgICAqIEByZXR1cm4gb25lIG9mIDxjb2RlPk1JU01BVENIPC9jb2RlPiwgPGNvZGU+UEFSVElBTF9NQVRDSDwvY29kZT4sIG9yCiAgICAgKiA8Y29kZT5GVUxMX01BVENIPC9jb2RlPi4KICAgICAqIEBzZWUgI01JU01BVENICiAgICAgKiBAc2VlICNQQVJUSUFMX01BVENICiAgICAgKiBAc2VlICNGVUxMX01BVENICiAgICAgKi8KICAgIHZpcnR1YWwgaW50MzJfdCBnZXRNYXRjaERlZ3JlZShjb25zdCBSZXBsYWNlYWJsZSYgdGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVVHJhbnNQb3NpdGlvbiYgcG9zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFRyYW5zbGl0ZXJhdGlvblJ1bGVEYXRhJiBkYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVuaWNvZGVGaWx0ZXIqIGZpbHRlcikgY29uc3Q7CgogICAgLyoqCiAgICAgKiBSZXR1cm4gdGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIG9mIHRoZSB0ZXh0IHRoYXQgbWF0Y2ggdGhpcyBydWxlLiAgSWYKICAgICAqIHRoZXJlIGlzIGEgbWlzbWF0Y2gsIHJldHVybiAtMS4gIElmIHRoZSB0ZXh0IGlzIG5vdCBsb25nIGVub3VnaCB0byBtYXRjaAogICAgICogYW55IGNoYXJhY3RlcnMsIHJldHVybiAwLgogICAgICogQHBhcmFtIHRleHQgdGhlIHRleHQsIGJvdGggdHJhbnNsYXRlZCBhbmQgdW50cmFuc2xhdGVkCiAgICAgKiBAcGFyYW0gc3RhcnQgdGhlIGJlZ2lubmluZyBpbmRleCwgaW5jbHVzaXZlOyA8Y29kZT4wIDw9IHN0YXJ0CiAgICAgKiA8PSBsaW1pdDwvY29kZT4uCiAgICAgKiBAcGFyYW0gbGltaXQgdGhlIGVuZGluZyBpbmRleCwgZXhjbHVzaXZlOyA8Y29kZT5zdGFydCA8PSBsaW1pdAogICAgICogPD0gdGV4dC5sZW5ndGgoKTwvY29kZT4uCiAgICAgKiBAcGFyYW0gY3Vyc29yIHBvc2l0aW9uIGF0IHdoaWNoIHRvIHRyYW5zbGF0ZSBuZXh0LCByZXByZXNlbnRpbmcgb2Zmc2V0CiAgICAgKiBpbnRvIHRleHQuICBUaGlzIHZhbHVlIG11c3QgYmUgYmV0d2VlbiA8Y29kZT5zdGFydDwvY29kZT4gYW5kCiAgICAgKiA8Y29kZT5saW1pdDwvY29kZT4uCiAgICAgKiBAcGFyYW0gZGF0YSBhIGRpY3Rpb25hcnkgb2YgdmFyaWFibGVzIG1hcHBpbmcgPGNvZGU+Q2hhcmFjdGVyPC9jb2RlPgogICAgICogdG8gPGNvZGU+VW5pY29kZVNldDwvY29kZT4KICAgICAqIEBwYXJhbSBmaWx0ZXIgdGhlIGZpbHRlci4gIEFueSBjaGFyYWN0ZXIgZm9yIHdoaWNoCiAgICAgKiA8dHQ+ZmlsdGVyLmlzSW4oKTwvdHQ+IHJldHVybnMgPHR0PmZhbHNlPC90dD4gd2lsbCBub3QgYmUKICAgICAqIGFsdGVyZWQgYnkgdGhpcyB0cmFuc2xpdGVyYXRvci4gIElmIDx0dD5maWx0ZXI8L3R0PiBpcwogICAgICogPHR0Pm51bGw8L3R0PiB0aGVuIG5vIGZpbHRlcmluZyBpcyBhcHBsaWVkLgogICAgICogQHJldHVybiAtMSBpZiB0aGVyZSBpcyBhIG1pc21hdGNoLCAwIGlmIHRoZSB0ZXh0IGlzIG5vdCBsb25nIGVub3VnaCB0bwogICAgICogbWF0Y2ggYW55IGNoYXJhY3RlcnMsIG90aGVyd2lzZSB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgb2YgdGV4dCB0aGF0CiAgICAgKiBtYXRjaCB0aGlzIHJ1bGUuCiAgICAgKi8KICAgIHZpcnR1YWwgaW50MzJfdCBnZXRSZWdpb25NYXRjaExlbmd0aChjb25zdCBSZXBsYWNlYWJsZSYgdGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVVHJhbnNQb3NpdGlvbiYgcG9zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFRyYW5zbGl0ZXJhdGlvblJ1bGVEYXRhJiBkYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVuaWNvZGVGaWx0ZXIqIGZpbHRlcikgY29uc3Q7CiAgICAKICAgIC8qKgogICAgICogUmV0dXJuIHRydWUgaWYgdGhlIGdpdmVuIGtleSBtYXRjaGVzIHRoZSBnaXZlbiB0ZXh0LiAgVGhpcyBtZXRob2QKICAgICAqIGFjY291bnRzIGZvciB0aGUgZmFjdCB0aGF0IHRoZSBrZXkgY2hhcmFjdGVyIG1heSByZXByZXNlbnQgYSBjaGFyYWN0ZXIKICAgICAqIHNldC4gIE5vdGUgdGhhdCB0aGUga2V5IGFuZCB0ZXh0IGNoYXJhY3RlcnMgbWF5IG5vdCBiZSBpbnRlcmNoYW5nZWQKICAgICAqIHdpdGhvdXQgYWx0ZXJpbmcgdGhlIHJlc3VsdHMuCiAgICAgKiBAcGFyYW0ga2V5Q2hhciBhIGNoYXJhY3RlciBpbiB0aGUgbWF0Y2gga2V5CiAgICAgKiBAcGFyYW0gdGV4dENoYXIgYSBjaGFyYWN0ZXIgaW4gdGhlIHRleHQgYmVpbmcgdHJhbnNsaXRlcmF0ZWQKICAgICAqIEBwYXJhbSBkYXRhIGEgZGljdGlvbmFyeSBvZiB2YXJpYWJsZXMgbWFwcGluZyA8Y29kZT5DaGFyYWN0ZXI8L2NvZGU+CiAgICAgKiB0byA8Y29kZT5Vbmljb2RlU2V0PC9jb2RlPgogICAgICogQHBhcmFtIGZpbHRlciB0aGUgZmlsdGVyLiAgQW55IGNoYXJhY3RlciBmb3Igd2hpY2gKICAgICAqIDx0dD5maWx0ZXIuaXNJbigpPC90dD4gcmV0dXJucyA8dHQ+ZmFsc2U8L3R0PiB3aWxsIG5vdCBiZQogICAgICogYWx0ZXJlZCBieSB0aGlzIHRyYW5zbGl0ZXJhdG9yLiAgSWYgPHR0PmZpbHRlcjwvdHQ+IGlzCiAgICAgKiA8dHQ+bnVsbDwvdHQ+IHRoZW4gbm8gZmlsdGVyaW5nIGlzIGFwcGxpZWQuCiAgICAgKi8KICAgIHZpcnR1YWwgVUJvb2wgY2hhck1hdGNoZXMoVUNoYXIga2V5Q2hhciwgY29uc3QgUmVwbGFjZWFibGUmIHRleHRDaGFyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IGluZGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVVHJhbnNQb3NpdGlvbiYgcG9zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBUcmFuc2xpdGVyYXRpb25SdWxlRGF0YSYgZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVW5pY29kZUZpbHRlciogZmlsdGVyKSBjb25zdDsKCiAgICAvKioKICAgICAqIFJldHVybiB0cnVlIGlmIHRoZSBnaXZlbiBrZXkgbWF0Y2hlcyB0aGUgZ2l2ZW4gdGV4dC4gIFRoaXMgbWV0aG9kCiAgICAgKiBhY2NvdW50cyBmb3IgdGhlIGZhY3QgdGhhdCB0aGUga2V5IGNoYXJhY3RlciBtYXkgcmVwcmVzZW50IGEgY2hhcmFjdGVyCiAgICAgKiBzZXQuICBOb3RlIHRoYXQgdGhlIGtleSBhbmQgdGV4dCBjaGFyYWN0ZXJzIG1heSBub3QgYmUgaW50ZXJjaGFuZ2VkCiAgICAgKiB3aXRob3V0IGFsdGVyaW5nIHRoZSByZXN1bHRzLgogICAgICogQHBhcmFtIGtleUNoYXIgYSBjaGFyYWN0ZXIgaW4gdGhlIG1hdGNoIGtleQogICAgICogQHBhcmFtIHRleHRDaGFyIGEgY2hhcmFjdGVyIGluIHRoZSB0ZXh0IGJlaW5nIHRyYW5zbGl0ZXJhdGVkCiAgICAgKiBAcGFyYW0gZGF0YSBhIGRpY3Rpb25hcnkgb2YgdmFyaWFibGVzIG1hcHBpbmcgPGNvZGU+Q2hhcmFjdGVyPC9jb2RlPgogICAgICogdG8gPGNvZGU+VW5pY29kZVNldDwvY29kZT4KICAgICAqIEBwYXJhbSBmaWx0ZXIgdGhlIGZpbHRlci4gIEFueSBjaGFyYWN0ZXIgZm9yIHdoaWNoCiAgICAgKiA8dHQ+ZmlsdGVyLmlzSW4oKTwvdHQ+IHJldHVybnMgPHR0PmZhbHNlPC90dD4gd2lsbCBub3QgYmUKICAgICAqIGFsdGVyZWQgYnkgdGhpcyB0cmFuc2xpdGVyYXRvci4gIElmIDx0dD5maWx0ZXI8L3R0PiBpcwogICAgICogPHR0Pm51bGw8L3R0PiB0aGVuIG5vIGZpbHRlcmluZyBpcyBhcHBsaWVkLgogICAgICovCi8vW0FOQ0hPUl0gICAgdmlydHVhbCBVQm9vbCBjaGFyTWF0Y2hlcyhVQ2hhciBrZXlDaGFyLCBVQ2hhciB0ZXh0Q2hhciwKLy9bQU5DSE9SXSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBUcmFuc2xpdGVyYXRpb25SdWxlRGF0YSYgZGF0YSwKLy9bQU5DSE9SXSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlRmlsdGVyKiBmaWx0ZXIpIGNvbnN0OwoKcHJpdmF0ZToKCiAgICB2b2lkIGluaXQoY29uc3QgVW5pY29kZVN0cmluZyYgaW5wdXQsCiAgICAgICAgICAgICAgaW50MzJfdCBhbnRlQ29udGV4dFBvcywgaW50MzJfdCBwb3N0Q29udGV4dFBvcywKICAgICAgICAgICAgICBjb25zdCBVbmljb2RlU3RyaW5nJiBvdXRwdXQsCiAgICAgICAgICAgICAgaW50MzJfdCBjdXJzb3JQb3MsIGludDMyX3QgY3Vyc29yT2Zmc2V0LAogICAgICAgICAgICAgIGludDMyX3QqIGFkb3B0ZWRTZWdzLAogICAgICAgICAgICAgIFVCb29sIGFuY2hvclN0YXJ0LCBVQm9vbCBhbmNob3JFbmQsCiAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKTsKCn07CgojZW5kaWYK