LyoKKiBDb3B5cmlnaHQgqSB7MTk5OX0sIEludGVybmF0aW9uYWwgQnVzaW5lc3MgTWFjaGluZXMgQ29ycG9yYXRpb24gYW5kIG90aGVycy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqICAgRGF0ZSAgICAgICAgTmFtZSAgICAgICAgRGVzY3JpcHRpb24KKiAgIDExLzE3Lzk5ICAgIGFsaXUgICAgICAgIENyZWF0aW9uLgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiovCiNpZm5kZWYgUkJUX1NFVF9ICiNkZWZpbmUgUkJUX1NFVF9ICgojaW5jbHVkZSAidXZlY3Rvci5oIgojaW5jbHVkZSAidW5pY29kZS91dHJhbnMuaCIKCmNsYXNzIFJlcGxhY2VhYmxlOwpjbGFzcyBUcmFuc2xpdGVyYXRpb25SdWxlOwpjbGFzcyBUcmFuc2xpdGVyYXRpb25SdWxlRGF0YTsKY2xhc3MgVW5pY29kZUZpbHRlcjsKY2xhc3MgVW5pY29kZVN0cmluZzsKCi8qKgogKiBBIHNldCBvZiBydWxlcyBmb3IgYSA8Y29kZT5SdWxlQmFzZWRUcmFuc2xpdGVyYXRvcjwvY29kZT4uICBUaGlzIHNldCBlbmNvZGVzCiAqIHRoZSB0cmFuc2xpdGVyYXRpb24gaW4gb25lIGRpcmVjdGlvbiBmcm9tIG9uZSBzZXQgb2YgY2hhcmFjdGVycyBvciBzaG9ydAogKiBzdHJpbmdzIHRvIGFub3RoZXIuICBBIDxjb2RlPlJ1bGVCYXNlZFRyYW5zbGl0ZXJhdG9yPC9jb2RlPiBjb25zaXN0cyBvZiB1cCB0bwogKiB0d28gc3VjaCBzZXRzLCBvbmUgZm9yIHRoZSBmb3J3YXJkIGRpcmVjdGlvbiwgYW5kIG9uZSBmb3IgdGhlIHJldmVyc2UuCiAqCiAqIDxwPkEgPGNvZGU+VHJhbnNsaXRlcmF0aW9uUnVsZVNldDwvY29kZT4gaGFzIG9uZSBpbXBvcnRhbnQgb3BlcmF0aW9uLCB0aGF0IG9mCiAqIGZpbmRpbmcgYSBtYXRjaGluZyBydWxlIGF0IGEgZ2l2ZW4gcG9pbnQgaW4gdGhlIHRleHQuICBUaGlzIGlzIGFjY29tcGxpc2hlZAogKiBieSB0aGUgPGNvZGU+ZmluZE1hdGNoKCk8L2NvZGU+IG1ldGhvZC4KICoKICogQGF1dGhvciBBbGFuIExpdQogKi8KY2xhc3MgVHJhbnNsaXRlcmF0aW9uUnVsZVNldCB7CiAgICAvKioKICAgICAqIFZlY3RvciBvZiBydWxlcywgaW4gdGhlIG9yZGVyIGFkZGVkLiAgVGhpcyBpcyBvbmx5IHVzZWQgd2hpbGUgdGhlIHJ1bGUKICAgICAqIHNldCBpcyBnZXR0aW5nIGJ1aWx0LiAgQWZ0ZXIgdGhhdCwgZnJlZXplKCkgcmVvcmRlcnMgYW5kIGluZGV4ZXMgdGhlCiAgICAgKiBydWxlcywgYW5kIHRoaXMgVmVjdG9yIGlzIGZyZWVkLgogICAgICovCiAgICBVVmVjdG9yKiBydWxlVmVjdG9yOwoKICAgIC8qKgogICAgICogTGVuZ3RoIG9mIHRoZSBsb25nZXN0IHByZWNlZGluZyBjb250ZXh0CiAgICAgKi8KICAgIGludDMyX3QgbWF4Q29udGV4dExlbmd0aDsKCiAgICAvKioKICAgICAqIFNvcnRlZCBhbmQgaW5kZXhlZCB0YWJsZSBvZiBydWxlcy4gIFRoaXMgaXMgY3JlYXRlZCBieSBmcmVlemUoKSBmcm9tCiAgICAgKiB0aGUgcnVsZXMgaW4gcnVsZVZlY3Rvci4KICAgICAqLwogICAgVHJhbnNsaXRlcmF0aW9uUnVsZSoqIHJ1bGVzOwoKICAgIC8qKgogICAgICogSW5kZXggdGFibGUuICBGb3IgdGV4dCBoYXZpbmcgYSBmaXJzdCBjaGFyYWN0ZXIgYywgY29tcHV0ZSB4ID0gYyYweEZGLgogICAgICogTm93IHVzZSBydWxlc1tpbmRleFt4XS4uaW5kZXhbeCsxXS0xXS4gIFRoaXMgaW5kZXggdGFibGUgaXMgY3JlYXRlZCBieQogICAgICogZnJlZXplKCkuCiAgICAgKi8KICAgIGludDMyX3QgaW5kZXhbMjU3XTsKCnB1YmxpYzoKCiAgICAvKioKICAgICAqIENvbnN0cnVjdCBhIG5ldyBlbXB0eSBydWxlIHNldC4KICAgICAqLwogICAgVHJhbnNsaXRlcmF0aW9uUnVsZVNldCgpOwoKICAgIC8qKgogICAgICogRGVzdHJ1Y3Rvci4KICAgICAqLwogICAgdmlydHVhbCB+VHJhbnNsaXRlcmF0aW9uUnVsZVNldCgpOwoKICAgIC8qKgogICAgICogUmV0dXJuIHRoZSBtYXhpbXVtIGNvbnRleHQgbGVuZ3RoLgogICAgICogQHJldHVybiB0aGUgbGVuZ3RoIG9mIHRoZSBsb25nZXN0IHByZWNlZGluZyBjb250ZXh0LgogICAgICovCiAgICB2aXJ0dWFsIGludDMyX3QgZ2V0TWF4aW11bUNvbnRleHRMZW5ndGgodm9pZCkgY29uc3Q7CgogICAgLyoqCiAgICAgKiBBZGQgYSBydWxlIHRvIHRoaXMgc2V0LiAgUnVsZXMgYXJlIGFkZGVkIGluIG9yZGVyLCBhbmQgb3JkZXIgaXMKICAgICAqIHNpZ25pZmljYW50LgogICAgICoKICAgICAqIDxwPk9uY2UgZnJlZXplKCkgaXMgY2FsbGVkLCB0aGlzIG1ldGhvZCBtdXN0IG5vdCBiZSBjYWxsZWQuCiAgICAgKiBAcGFyYW0gYWRvcHRlZFJ1bGUgdGhlIHJ1bGUgdG8gYWRkCiAgICAgKi8KICAgIHZpcnR1YWwgdm9pZCBhZGRSdWxlKFRyYW5zbGl0ZXJhdGlvblJ1bGUqIGFkb3B0ZWRSdWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKTsKCiAgICAvKioKICAgICAqIENsb3NlIHRoaXMgcnVsZSBzZXQgdG8gZnVydGhlciBhZGRpdGlvbnMsIGNoZWNrIGl0IGZvciBtYXNrZWQgcnVsZXMsCiAgICAgKiBhbmQgaW5kZXggaXQgdG8gb3B0aW1pemUgcGVyZm9ybWFuY2UuICBPbmNlIHRoaXMgbWV0aG9kIGlzIGNhbGxlZCwKICAgICAqIGFkZFJ1bGUoKSBjYW4gbm8gbG9uZ2VyIGJlIGNhbGxlZC4KICAgICAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHNvbWUgcnVsZXMgYXJlIG1hc2tlZAogICAgICovCiAgICB2aXJ0dWFsIHZvaWQgZnJlZXplKGNvbnN0IFRyYW5zbGl0ZXJhdGlvblJ1bGVEYXRhJiBkYXRhLAogICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpOwoKICAgIC8qKgogICAgICogQXR0ZW1wdCB0byBmaW5kIGEgbWF0Y2hpbmcgcnVsZSBhdCB0aGUgc3BlY2lmaWVkIHBvaW50IGluIHRoZSB0ZXh0LgogICAgICogQHBhcmFtIHRleHQgdGhlIHRleHQsIGJvdGggdHJhbnNsYXRlZCBhbmQgdW50cmFuc2xhdGVkCiAgICAgKiBAcGFyYW0gc3RhcnQgdGhlIGJlZ2lubmluZyBpbmRleCwgaW5jbHVzaXZlOyA8Y29kZT4wIDw9IHN0YXJ0CiAgICAgKiA8PSBsaW1pdDwvY29kZT4uCiAgICAgKiBAcGFyYW0gbGltaXQgdGhlIGVuZGluZyBpbmRleCwgZXhjbHVzaXZlOyA8Y29kZT5zdGFydCA8PSBsaW1pdAogICAgICogPD0gdGV4dC5sZW5ndGgoKTwvY29kZT4uCiAgICAgKiBAcGFyYW0gY3Vyc29yIHBvc2l0aW9uIGF0IHdoaWNoIHRvIHRyYW5zbGF0ZSBuZXh0LCByZXByZXNlbnRpbmcgb2Zmc2V0CiAgICAgKiBpbnRvIHRleHQuICBUaGlzIHZhbHVlIG11c3QgYmUgYmV0d2VlbiA8Y29kZT5zdGFydDwvY29kZT4gYW5kCiAgICAgKiA8Y29kZT5saW1pdDwvY29kZT4uCiAgICAgKiBAcGFyYW0gZGF0YSBhIGRpY3Rpb25hcnkgbWFwcGluZyB2YXJpYWJsZXMgdG8gdGhlIHNldHMgdGhleQogICAgICogcmVwcmVzZW50IChtYXBzIDxjb2RlPkNoYXJhY3RlcjwvY29kZT4gdG8gPGNvZGU+VW5pY29kZVNldDwvY29kZT4pCiAgICAgKiBAcGFyYW0gZmlsdGVyIHRoZSBmaWx0ZXIuICBBbnkgY2hhcmFjdGVyIGZvciB3aGljaAogICAgICogPHR0PmZpbHRlci5pc0luKCk8L3R0PiByZXR1cm5zIDx0dD5mYWxzZTwvdHQ+IHdpbGwgbm90IGJlCiAgICAgKiBhbHRlcmVkIGJ5IHRoaXMgdHJhbnNsaXRlcmF0b3IuICBJZiA8dHQ+ZmlsdGVyPC90dD4gaXMKICAgICAqIDx0dD5udWxsPC90dD4gdGhlbiBubyBmaWx0ZXJpbmcgaXMgYXBwbGllZC4KICAgICAqIEByZXR1cm4gdGhlIG1hdGNoaW5nIHJ1bGUsIG9yIG51bGwgaWYgbm9uZSBmb3VuZC4KICAgICAqLwogICAgdmlydHVhbCBUcmFuc2xpdGVyYXRpb25SdWxlKiBmaW5kTWF0Y2goY29uc3QgUmVwbGFjZWFibGUmIHRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVVHJhbnNQb3NpdGlvbiYgcG9zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVHJhbnNsaXRlcmF0aW9uUnVsZURhdGEmIGRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlRmlsdGVyKiBmaWx0ZXIpIGNvbnN0OwogICAgCiAgICAvKioKICAgICAqIEF0dGVtcHQgdG8gZmluZCBhIG1hdGNoaW5nIHJ1bGUgYXQgdGhlIHNwZWNpZmllZCBwb2ludCBpbiB0aGUgdGV4dC4KICAgICAqIFVubGlrZSA8Y29kZT5maW5kTWF0Y2goKTwvY29kZT4sIHRoaXMgbWV0aG9kIGRvZXMgYW4gaW5jcmVtZW50YWwgbWF0Y2guCiAgICAgKiBBbiBpbmNyZW1lbnRhbCBtYXRjaCByZXF1aXJlcyB0aGF0IHRoZXJlIGJlIG5vIHBhcnRpYWwgbWF0Y2hlcyB0aGF0IG1pZ2h0CiAgICAgKiBwcmUtZW1wdCB0aGUgZnVsbCBtYXRjaCB0aGF0IGlzIGZvdW5kLiAgSWYgdGhlcmUgYXJlIHBhcnRpYWwgbWF0Y2hlcywKICAgICAqIHRoZW4gbnVsbCBpcyByZXR1cm5lZC4gIEEgbm9uLW51bGwgcmVzdWx0IGluZGljYXRlcyB0aGF0IGEgZnVsbCBtYXRjaCBoYXMKICAgICAqIGJlZW4gZm91bmQsIGFuZCB0aGF0IGl0IGNhbm5vdCBiZSBwcmUtZW1wdGVkIGJ5IGEgcGFydGlhbCBtYXRjaAogICAgICogcmVnYXJkbGVzcyBvZiB3aGF0IGFkZGl0aW9uYWwgdGV4dCBpcyBhZGRlZCB0byB0aGUgdHJhbnNsYXRpb24gYnVmZmVyLgogICAgICogQHBhcmFtIHRleHQgdGhlIHRleHQsIGJvdGggdHJhbnNsYXRlZCBhbmQgdW50cmFuc2xhdGVkCiAgICAgKiBAcGFyYW0gc3RhcnQgdGhlIGJlZ2lubmluZyBpbmRleCwgaW5jbHVzaXZlOyA8Y29kZT4wIDw9IHN0YXJ0CiAgICAgKiA8PSBsaW1pdDwvY29kZT4uCiAgICAgKiBAcGFyYW0gbGltaXQgdGhlIGVuZGluZyBpbmRleCwgZXhjbHVzaXZlOyA8Y29kZT5zdGFydCA8PSBsaW1pdAogICAgICogPD0gdGV4dC5sZW5ndGgoKTwvY29kZT4uCiAgICAgKiBAcGFyYW0gY3Vyc29yIHBvc2l0aW9uIGF0IHdoaWNoIHRvIHRyYW5zbGF0ZSBuZXh0LCByZXByZXNlbnRpbmcgb2Zmc2V0CiAgICAgKiBpbnRvIHRleHQuICBUaGlzIHZhbHVlIG11c3QgYmUgYmV0d2VlbiA8Y29kZT5zdGFydDwvY29kZT4gYW5kCiAgICAgKiA8Y29kZT5saW1pdDwvY29kZT4uCiAgICAgKiBAcGFyYW0gZGF0YSBhIGRpY3Rpb25hcnkgbWFwcGluZyB2YXJpYWJsZXMgdG8gdGhlIHNldHMgdGhleQogICAgICogcmVwcmVzZW50IChtYXBzIDxjb2RlPkNoYXJhY3RlcjwvY29kZT4gdG8gPGNvZGU+VW5pY29kZVNldDwvY29kZT4pCiAgICAgKiBAcGFyYW0gcGFydGlhbCBvdXRwdXQgcGFyYW1ldGVyLiAgPGNvZGU+cGFydGlhbFswXTwvY29kZT4gaXMgc2V0IHRvCiAgICAgKiB0cnVlIGlmIGEgcGFydGlhbCBtYXRjaCBpcyByZXR1cm5lZC4KICAgICAqIEBwYXJhbSBmaWx0ZXIgdGhlIGZpbHRlci4gIEFueSBjaGFyYWN0ZXIgZm9yIHdoaWNoCiAgICAgKiA8dHQ+ZmlsdGVyLmlzSW4oKTwvdHQ+IHJldHVybnMgPHR0PmZhbHNlPC90dD4gd2lsbCBub3QgYmUKICAgICAqIGFsdGVyZWQgYnkgdGhpcyB0cmFuc2xpdGVyYXRvci4gIElmIDx0dD5maWx0ZXI8L3R0PiBpcwogICAgICogPHR0Pm51bGw8L3R0PiB0aGVuIG5vIGZpbHRlcmluZyBpcyBhcHBsaWVkLgogICAgICogQHJldHVybiB0aGUgbWF0Y2hpbmcgcnVsZSwgb3IgbnVsbCBpZiBub25lIGZvdW5kLCBvciBpZiB0aGUgdGV4dCBidWZmZXIKICAgICAqIGRvZXMgbm90IGhhdmUgZW5vdWdoIHRleHQgeWV0IHRvIHVuYW1iaWd1b3VzbHkgbWF0Y2ggYSBydWxlLgogICAgICovCiAgICB2aXJ0dWFsIFRyYW5zbGl0ZXJhdGlvblJ1bGUqIGZpbmRJbmNyZW1lbnRhbE1hdGNoKGNvbnN0IFJlcGxhY2VhYmxlJiB0ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVVRyYW5zUG9zaXRpb24mIHBvcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFRyYW5zbGl0ZXJhdGlvblJ1bGVEYXRhJiBkYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUJvb2wmIGlzUGFydGlhbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVuaWNvZGVGaWx0ZXIqIGZpbHRlcikgY29uc3Q7Cn07CiNlbmRpZgo=