LyoKKiBDb3B5cmlnaHQgqSB7MTk5OX0sIEludGVybmF0aW9uYWwgQnVzaW5lc3MgTWFjaGluZXMgQ29ycG9yYXRpb24gYW5kIG90aGVycy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqICAgRGF0ZSAgICAgICAgTmFtZSAgICAgICAgRGVzY3JpcHRpb24KKiAgIDEwLzIyLzk5ICAgIGFsYW4gICAgICAgIENyZWF0aW9uLgoqICAgMTEvMTEvOTkgICAgcmdpbGxhbSAgICAgQ29tcGxldGUgcG9ydCBmcm9tIEphdmEuCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKi8KCiNpZm5kZWYgUkJCSV9ICiNkZWZpbmUgUkJCSV9ICgojaW5jbHVkZSAidW5pY29kZS91dHlwZXMuaCIKI2luY2x1ZGUgInVuaWNvZGUvYnJraXRlci5oIgoKY2xhc3MgUnVsZUJhc2VkQnJlYWtJdGVyYXRvclRhYmxlczsKY2xhc3MgQnJlYWtJdGVyYXRvcjsKCi8qKgogKiA8cD5BIHN1YmNsYXNzIG9mIEJyZWFrSXRlcmF0b3Igd2hvc2UgYmVoYXZpb3IgaXMgc3BlY2lmaWVkIHVzaW5nIGEgbGlzdCBvZiBydWxlcy48L3A+CiAqIAogKiA8cD5UaGVyZSBhcmUgdHdvIGtpbmRzIG9mIHJ1bGVzLCB3aGljaCBhcmUgc2VwYXJhdGVkIGJ5IHNlbWljb2xvbnM6IDxpPnN1YnN0aXR1dGlvbnM8L2k+CiAqIGFuZCA8aT5yZWd1bGFyIGV4cHJlc3Npb25zLjwvaT48L3A+CiAqIAogKiA8cD5BIHN1YnN0aXR1dGlvbiBydWxlIGRlZmluZXMgYSBuYW1lIHRoYXQgY2FuIGJlIHVzZWQgaW4gcGxhY2Ugb2YgYW4gZXhwcmVzc2lvbi4gSXQKICogY29uc2lzdHMgb2YgYSBuYW1lLCB3aGljaCBpcyBhIHN0cmluZyBvZiBjaGFyYWN0ZXJzIGNvbnRhaW5lZCBpbiBhbmdsZSBicmFja2V0cywgYW4gZXF1YWxzCiAqIHNpZ24sIGFuZCBhbiBleHByZXNzaW9uLiAoVGhlcmUgY2FuIGJlIG5vIHdoaXRlc3BhY2Ugb24gZWl0aGVyIHNpZGUgb2YgdGhlIGVxdWFscyBzaWduLikKICogVG8ga2VlcCBpdHMgc3ludGFjdGljIG1lYW5pbmcgaW50YWN0LCB0aGUgZXhwcmVzc2lvbiBtdXN0IGJlIGVuY2xvc2VkIGluIHBhcmVudGhlc2VzIG9yCiAqIHNxdWFyZSBicmFja2V0cy4gQSBzdWJzdGl0dXRpb24gaXMgdmlzaWJsZSBhZnRlciBpdHMgZGVmaW5pdGlvbiwgYW5kIGlzIGZpbGxlZCBpbiB1c2luZwogKiBzaW1wbGUgdGV4dHVhbCBzdWJzdGl0dXRpb24uIFN1YnN0aXR1dGlvbiBkZWZpbml0aW9ucyBjYW4gY29udGFpbiBvdGhlciBzdWJzdGl0dXRpb25zLCBhcwogKiBsb25nIGFzIHRob3NlIHN1YnN0aXR1dGlvbnMgaGF2ZSBiZWVuIGRlZmluZWQgZmlyc3QuIFN1YnN0aXR1dGlvbnMgYXJlIGdlbmVyYWxseSB1c2VkIHRvCiAqIG1ha2UgdGhlIHJlZ3VsYXIgZXhwcmVzc2lvbnMgKHdoaWNoIGNhbiBnZXQgcXVpdGUgY29tcGxleCkgc2hvcnRlZCBhbmQgZWFzaWVyIHRvIHJlYWQuCiAqIFRoZXkgdHlwaWNhbGx5IGRlZmluZSBlaXRoZXIgY2hhcmFjdGVyIGNhdGVnb3JpZXMgb3IgY29tbW9ubHktdXNlZCBzdWJleHByZXNzaW9ucy48L3A+CiAqIAogKiA8cD5UaGVyZSBpcyBvbmUgc3BlY2lhbCBzdWJzdGl0dXRpb24uJm5ic3A7IElmIHRoZSBkZXNjcmlwdGlvbiBkZWZpbmVzIGEgc3Vic3RpdHV0aW9uCiAqIGNhbGxlZCAmcXVvdDsmbHQ7aWdub3JlJmd0OyZxdW90OywgdGhlIGV4cHJlc3Npb24gbXVzdCBiZSBhIFtdIGV4cHJlc3Npb24sIGFuZCB0aGUKICogZXhwcmVzc2lvbiBkZWZpbmVzIGEgc2V0IG9mIGNoYXJhY3RlcnMgKHRoZSAmcXVvdDs8ZW0+aWdub3JlIGNoYXJhY3RlcnM8L2VtPiZxdW90OykgdGhhdAogKiB3aWxsIGJlIHRyYW5zcGFyZW50IHRvIHRoZSBCcmVha0l0ZXJhdG9yLiZuYnNwOyBBIHNlcXVlbmNlIG9mIGNoYXJhY3RlcnMgd2lsbCBicmVhayB0aGUKICogc2FtZSB3YXkgaXQgd291bGQgaWYgYW55IGlnbm9yZSBjaGFyYWN0ZXJzIGl0IGNvbnRhaW5zIGFyZSB0YWtlbiBvdXQuJm5ic3A7IEJyZWFrCiAqIHBvc2l0aW9ucyBuZXZlciBvY2N1ciBiZWZvZXIgaWdub3JlIGNoYXJhY3RlcnMuPC9wPgogKiAKICogPHA+QSByZWd1bGFyIGV4cHJlc3Npb24gdXNlcyBhIHN1YnNldCBvZiB0aGUgbm9ybWFsIFVuaXggcmVndWxhci1leHByZXNzaW9uIHN5bnRheCwgYW5kCiAqIGRlZmluZXMgYSBzZXF1ZW5jZSBvZiBjaGFyYWN0ZXJzIHRvIGJlIGtlcHQgdG9nZXRoZXIuIFdpdGggb25lIHNpZ25pZmljYW50IGV4Y2VwdGlvbiwgdGhlCiAqIGl0ZXJhdG9yIHVzZXMgYSBsb25nZXN0LXBvc3NpYmxlLW1hdGNoIGFsZ29yaXRobSB3aGVuIG1hdGNoaW5nIHRleHQgdG8gcmVndWxhcgogKiBleHByZXNzaW9ucy4gVGhlIGl0ZXJhdG9yIGFsc28gdHJlYXRzIGRlc2NyaXB0aW9ucyBjb250YWluaW5nIG11bHRpcGxlIHJlZ3VsYXIgZXhwcmVzc2lvbnMKICogYXMgaWYgdGhleSB3ZXJlIE9SZWQgdG9nZXRoZXIgKGkuZS4sIGFzIGlmIHRoZXkgd2VyZSBzZXBhcmF0ZWQgYnkgfCkuPC9wPgogKiAKICogPHA+VGhlIHNwZWNpYWwgY2hhcmFjdGVycyByZWNvZ25pemVkIGJ5IHRoZSByZWd1bGFyLWV4cHJlc3Npb24gcGFyc2VyIGFyZSBhcyBmb2xsb3dzOjwvcD4KICogCiAqIDxibG9ja3F1b3RlPgogKiAgIDx0YWJsZSBib3JkZXI9IjEiIHdpZHRoPSIxMDAlIj4KICogICAgIDx0cj4KICogICAgICAgPHRkIHdpZHRoPSI2JSI+KjwvdGQ+CiAqICAgICAgIDx0ZCB3aWR0aD0iOTQlIj5TcGVjaWZpZXMgdGhhdCB0aGUgZXhwcmVzc2lvbiBwcmVjZWRpbmcgdGhlIGFzdGVyaXNrIG1heSBvY2N1ciBhbnkgbnVtYmVyCiAqICAgICAgIG9mIHRpbWVzIChpbmNsdWRpbmcgbm90IGF0IGFsbCkuPC90ZD4KICogICAgIDwvdHI+CiAqICAgICA8dHI+CiAqICAgICAgIDx0ZCB3aWR0aD0iNiUiPnt9PC90ZD4KICogICAgICAgPHRkIHdpZHRoPSI5NCUiPkVuY2xvc2VzIGEgc2VxdWVuY2Ugb2YgY2hhcmFjdGVycyB0aGF0IGlzIG9wdGlvbmFsLjwvdGQ+CiAqICAgICA8L3RyPgogKiAgICAgPHRyPgogKiAgICAgICA8dGQgd2lkdGg9IjYlIj4oKTwvdGQ+CiAqICAgICAgIDx0ZCB3aWR0aD0iOTQlIj5FbmNsb3NlcyBhIHNlcXVlbmNlIG9mIGNoYXJhY3RlcnMuJm5ic3A7IElmIGZvbGxvd2VkIGJ5ICosIHRoZSBzZXF1ZW5jZQogKiAgICAgICByZXBlYXRzLiZuYnNwOyBPdGhlcndpc2UsIHRoZSBwYXJlbnRoZXNlcyBhcmUganVzdCBhIGdyb3VwaW5nIGRldmljZSBhbmQgYSB3YXkgdG8gZGVsaW1pdAogKiAgICAgICB0aGUgZW5kcyBvZiBleHByZXNzaW9ucyBjb250YWluaW5nIHwuPC90ZD4KICogICAgIDwvdHI+CiAqICAgICA8dHI+CiAqICAgICAgIDx0ZCB3aWR0aD0iNiUiPnw8L3RkPgogKiAgICAgICA8dGQgd2lkdGg9Ijk0JSI+U2VwYXJhdGVzIHR3byBhbHRlcm5hdGl2ZSBzZXF1ZW5jZXMgb2YgY2hhcmFjdGVycy4mbmJzcDsgRWl0aGVyIG9uZQogKiAgICAgICBzZXF1ZW5jZSBvciB0aGUgb3RoZXIsIGJ1dCBub3QgYm90aCwgbWF0Y2hlcyB0aGlzIGV4cHJlc3Npb24uJm5ic3A7IFRoZSB8IGNoYXJhY3RlciBjYW4KICogICAgICAgb25seSBvY2N1ciBpbnNpZGUgKCkuPC90ZD4KICogICAgIDwvdHI+CiAqICAgICA8dHI+CiAqICAgICAgIDx0ZCB3aWR0aD0iNiUiPi48L3RkPgogKiAgICAgICA8dGQgd2lkdGg9Ijk0JSI+TWF0Y2hlcyBhbnkgY2hhcmFjdGVyLjwvdGQ+CiAqICAgICA8L3RyPgogKiAgICAgPHRyPgogKiAgICAgICA8dGQgd2lkdGg9IjYlIj4qPzwvdGQ+CiAqICAgICAgIDx0ZCB3aWR0aD0iOTQlIj5TcGVjaWZpZXMgYSBub24tZ3JlZWR5IGFzdGVyaXNrLiZuYnNwOyAqPyB3b3JrcyB0aGUgc2FtZSB3YXkgYXMgKiwgZXhjZXB0CiAqICAgICAgIHdoZW4gdGhlcmUgaXMgb3ZlcmxhcCBiZXR3ZWVuIHRoZSBsYXN0IGdyb3VwIG9mIGNoYXJhY3RlcnMgaW4gdGhlIGV4cHJlc3Npb24gcHJlY2VkaW5nIHRoZQogKiAgICAgICAqIGFuZCB0aGUgZmlyc3QgZ3JvdXAgb2YgY2hhcmFjdGVycyBmb2xsb3dpbmcgdGhlICouJm5ic3A7IFdoZW4gdGhlcmUgaXMgdGhpcyBraW5kIG9mCiAqICAgICAgIG92ZXJsYXAsICogd2lsbCBtYXRjaCB0aGUgbG9uZ2VzdCBzZXF1ZW5jZSBvZiBjaGFyYWN0ZXJzIHRoYXQgbWF0Y2ggdGhlIGV4cHJlc3Npb24gYmVmb3JlCiAqICAgICAgIHRoZSAqLCBhbmQgKj8gd2lsbCBtYXRjaCB0aGUgc2hvcnRlc3Qgc2VxdWVuY2Ugb2YgY2hhcmFjdGVycyBtYXRjaGluZyB0aGUgZXhwcmVzc2lvbgogKiAgICAgICBiZWZvcmUgdGhlICo/LiZuYnNwOyBGb3IgZXhhbXBsZSwgaWYgeW91IGhhdmUgJnF1b3Q7eHh5eHl5eXh5eHl4eHl4eXh5eSZxdW90OyBpbiB0aGUgdGV4dCwKICogICAgICAgJnF1b3Q7eFt4eV0qeCZxdW90OyB3aWxsIG1hdGNoIHRocm91Z2ggdG8gdGhlIGxhc3QgeCAoaS5lLiwgJnF1b3Q7PHN0cm9uZz54eHl4eXl5eHl4eXh4eXh5eDwvc3Ryb25nPnl5JnF1b3Q7LAogKiAgICAgICBidXQgJnF1b3Q7eFt4eV0qP3gmcXVvdDsgd2lsbCBvbmx5IG1hdGNoIHRoZSBmaXJzdCB0d28geGVzICgmcXVvdDs8c3Ryb25nPnh4PC9zdHJvbmc+eXh5eXl4eXh5eHh5eHl4eXkmcXVvdDspLjwvdGQ+CiAqICAgICA8L3RyPgogKiAgICAgPHRyPgogKiAgICAgICA8dGQgd2lkdGg9IjYlIj5bXTwvdGQ+CiAqICAgICAgIDx0ZCB3aWR0aD0iOTQlIj5TcGVjaWZpZXMgYSBncm91cCBvZiBhbHRlcm5hdGl2ZSBjaGFyYWN0ZXJzLiZuYnNwOyBBIFtdIGV4cHJlc3Npb24gd2lsbAogKiAgICAgICBtYXRjaCBhbnkgc2luZ2xlIGNoYXJhY3RlciB0aGF0IGlzIHNwZWNpZmllZCBpbiB0aGUgW10gZXhwcmVzc2lvbi4mbmJzcDsgRm9yIG1vcmUgb24gdGhlCiAqICAgICAgIHN5bnRheCBvZiBbXSBleHByZXNzaW9ucywgc2VlIGJlbG93LjwvdGQ+CiAqICAgICA8L3RyPgogKiAgICAgPHRyPgogKiAgICAgICA8dGQgd2lkdGg9IjYlIj4vPC90ZD4KICogICAgICAgPHRkIHdpZHRoPSI5NCUiPlNwZWNpZmllcyB3aGVyZSB0aGUgYnJlYWsgcG9zaXRpb24gc2hvdWxkIGdvIGlmIHRleHQgbWF0Y2hlcyB0aGlzCiAqICAgICAgIGV4cHJlc3Npb24uJm5ic3A7IChlLmcuLCAmcXVvdDtbYS16XSYjNDI7L1s6WnM6XSoxJnF1b3Q7IHdpbGwgbWF0Y2ggaWYgdGhlIGl0ZXJhdG9yIHNlZXMgYSBydW4KICogICAgICAgb2YgbGV0dGVycywgZm9sbG93ZWQgYnkgYSBydW4gb2Ygd2hpdGVzcGFjZSwgZm9sbG93ZWQgYnkgYSBkaWdpdCwgYnV0IHRoZSBicmVhayBwb3NpdGlvbgogKiAgICAgICB3aWxsIGFjdHVhbGx5IGdvIGJlZm9yZSB0aGUgd2hpdGVzcGFjZSkuJm5ic3A7IEV4cHJlc3Npb25zIHRoYXQgZG9uJ3QgY29udGFpbiAvIHB1dCB0aGUKICogICAgICAgYnJlYWsgcG9zaXRpb24gYXQgdGhlIGVuZCBvZiB0aGUgbWF0Y2hpbmcgdGV4dC48L3RkPgogKiAgICAgPC90cj4KICogICAgIDx0cj4KICogICAgICAgPHRkIHdpZHRoPSI2JSI+XDwvdGQ+CiAqICAgICAgIDx0ZCB3aWR0aD0iOTQlIj5Fc2NhcGUgY2hhcmFjdGVyLiZuYnNwOyBUaGUgXCBpdHNlbGYgaXMgaWdub3JlZCwgYnV0IGNhdXNlcyB0aGUgbmV4dAogKiAgICAgICBjaGFyYWN0ZXIgdG8gYmUgdHJlYXRlZCBhcyBsaXRlcmFsIGNoYXJhY3Rlci4mbmJzcDsgVGhpcyBoYXMgbm8gZWZmZWN0IGZvciBtYW55CiAqICAgICAgIGNoYXJhY3RlcnMsIGJ1dCBmb3IgdGhlIGNoYXJhY3RlcnMgbGlzdGVkIGFib3ZlLCB0aGlzIGRlcHJpdmVzIHRoZW0gb2YgdGhlaXIgc3BlY2lhbAogKiAgICAgICBtZWFuaW5nLiZuYnNwOyAoVGhlcmUgYXJlIG5vIHNwZWNpYWwgZXNjYXBlIHNlcXVlbmNlcyBmb3IgVW5pY29kZSBjaGFyYWN0ZXJzLCBvciB0YWJzIGFuZAogKiAgICAgICBuZXdsaW5lczsgdGhlc2UgYXJlIGFsbCBoYW5kbGVkIGJ5IGEgaGlnaGVyLWxldmVsIHByb3RvY29sLiZuYnNwOyBJbiBhIEphdmEgc3RyaW5nLAogKiAgICAgICAmcXVvdDtcbiZxdW90OyB3aWxsIGJlIGNvbnZlcnRlZCB0byBhIGxpdGVyYWwgbmV3bGluZSBjaGFyYWN0ZXIgYnkgdGhlIHRpbWUgdGhlCiAqICAgICAgIHJlZ3VsYXItZXhwcmVzc2lvbiBwYXJzZXIgc2VlcyBpdC4mbmJzcDsgT2YgY291cnNlLCB0aGlzIG1lYW5zIHRoYXQgXCBzZXF1ZW5jZXMgdGhhdCBhcmUKICogICAgICAgdmlzaWJsZSB0byB0aGUgcmVnZXhwIHBhcnNlciBtdXN0IGJlIHdyaXR0ZW4gYXMgXFwgd2hlbiBpbnNpZGUgYSBKYXZhIHN0cmluZy4pJm5ic3A7IEFsbAogKiAgICAgICBjaGFyYWN0ZXJzIGluIHRoZSBBU0NJSSByYW5nZSBleGNlcHQgZm9yIGxldHRlcnMsIGRpZ2l0cywgYW5kIGNvbnRyb2wgY2hhcmFjdGVycyBhcmUKICogICAgICAgcmVzZXJ2ZWQgY2hhcmFjdGVycyB0byB0aGUgcGFyc2VyIGFuZCBtdXN0IGJlIHByZWNlZGVkIGJ5IFwgZXZlbiBpZiB0aGV5IGN1cnJlbnRseSBkb24ndAogKiAgICAgICBtZWFuIGFueXRoaW5nLjwvdGQ+CiAqICAgICA8L3RyPgogKiAgICAgPHRyPgogKiAgICAgICA8dGQgd2lkdGg9IjYlIj4hPC90ZD4KICogICAgICAgPHRkIHdpZHRoPSI5NCUiPklmICEgYXBwZWFycyBhdCB0aGUgYmVnaW5uaW5nIG9mIGEgcmVndWxhciBleHByZXNzaW9uLCBpdCB0ZWxscyB0aGUgcmVnZXhwCiAqICAgICAgIHBhcnNlciB0aGF0IHRoaXMgZXhwcmVzc2lvbiBzcGVjaWZpZXMgdGhlIGJhY2t3YXJkcy1pdGVyYXRpb24gYmVoYXZpb3Igb2YgdGhlIGl0ZXJhdG9yLAogKiAgICAgICBhbmQgbm90IGl0cyBub3JtYWwgaXRlcmF0aW9uIGJlaGF2aW9yLiZuYnNwOyBUaGlzIGlzIGdlbmVyYWxseSBvbmx5IHVzZWQgaW4gc2l0dWF0aW9ucwogKiAgICAgICB3aGVyZSB0aGUgYXV0b21hdGljYWxseS1nZW5lcmF0ZWQgYmFja3dhcmRzLWl0ZXJhdGlvbiBicmhhdmlvciBkb2Vzbid0IHByb2R1Y2UKICogICAgICAgc2F0aXNmYWN0b3J5IHJlc3VsdHMgYW5kIG11c3QgYmUgc3VwcGxlbWVudGVkIHdpdGggZXh0cmEgY2xpZW50LXNwZWNpZmllZCBydWxlcy48L3RkPgogKiAgICAgPC90cj4KICogICAgIDx0cj4KICogICAgICAgPHRkIHdpZHRoPSI2JSI+PGVtPihhbGwgb3RoZXJzKTwvZW0+PC90ZD4KICogICAgICAgPHRkIHdpZHRoPSI5NCUiPkFsbCBvdGhlciBjaGFyYWN0ZXJzIGFyZSB0cmVhdGVkIGFzIGxpdGVyYWwgY2hhcmFjdGVycywgd2hpY2ggbXVzdCBtYXRjaAogKiAgICAgICB0aGUgY29ycmVzcG9uZGluZyBjaGFyYWN0ZXIocykgaW4gdGhlIHRleHQgZXhhY3RseS48L3RkPgogKiAgICAgPC90cj4KICogICA8L3RhYmxlPgogKiA8L2Jsb2NrcXVvdGU+CiAqIAogKiA8cD5XaXRoaW4gYSBbXSBleHByZXNzaW9uLCBhIG51bWJlciBvZiBvdGhlciBzcGVjaWFsIGNoYXJhY3RlcnMgY2FuIGJlIHVzZWQgdG8gc3BlY2lmeQogKiBncm91cHMgb2YgY2hhcmFjdGVyczo8L3A+CiAqIAogKiA8YmxvY2txdW90ZT4KICogICA8dGFibGUgYm9yZGVyPSIxIiB3aWR0aD0iMTAwJSI+CiAqICAgICA8dHI+CiAqICAgICAgIDx0ZCB3aWR0aD0iNiUiPi08L3RkPgogKiAgICAgICA8dGQgd2lkdGg9Ijk0JSI+U3BlY2lmaWVzIGEgcmFuZ2Ugb2YgbWF0Y2hpbmcgY2hhcmFjdGVycy4mbmJzcDsgRm9yIGV4YW1wbGUKICogICAgICAgJnF1b3Q7W2EtcF0mcXVvdDsgbWF0Y2hlcyBhbGwgbG93ZXJjYXNlIExhdGluIGxldHRlcnMgZnJvbSBhIHRvIHAgKGluY2x1c2l2ZSkuJm5ic3A7IFRoZSAtCiAqICAgICAgIHNpZ24gc3BlY2lmaWVzIHJhbmdlcyBvZiBjb250aW51b3VzIFVuaWNvZGUgbnVtZXJpYyB2YWx1ZXMsIG5vdCByYW5nZXMgb2YgY2hhcmFjdGVycyBpbiBhCiAqICAgICAgIGxhbmd1YWdlJ3MgYWxwaGFiZXRpY2FsIG9yZGVyOiAmcXVvdDtbYS16XSZxdW90OyBkb2Vzbid0IGluY2x1ZGUgY2FwaXRhbCBsZXR0ZXJzLCBub3IgZG9lcwogKiAgICAgICBpdCBpbmNsdWRlIGFjY2VudGVkIGxldHRlcnMgc3VjaCBhcyBhLXVtbGF1dC48L3RkPgogKiAgICAgPC90cj4KICogICAgIDx0cj4KICogICAgICAgPHRkIHdpZHRoPSI2JSI+Ojo8L3RkPgogKiAgICAgICA8dGQgd2lkdGg9Ijk0JSI+QSBwYWlyIG9mIGNvbG9ucyBjb250YWluaW5nIGEgb25lLSBvciB0d28tbGV0dGVyIGNvZGUgbWF0Y2hlcyBhbGwKICogICAgICAgY2hhcmFjdGVycyBpbiB0aGUgY29ycmVzcG9uZGluZyBVbmljb2RlIGNhdGVnb3J5LiZuYnNwOyBUaGUgdHdvLWxldHRlciBjb2RlcyBhcmUgdGhlIHNhbWUKICogICAgICAgYXMgdGhlIHR3by1sZXR0ZXIgY29kZXMgaW4gdGhlIFVuaWNvZGUgZGF0YWJhc2UgKGZvciBleGFtcGxlLCAmcXVvdDtbOlNjOjpTbTpdJnF1b3Q7CiAqICAgICAgIG1hdGNoZXMgYWxsIGN1cnJlbmN5IHN5bWJvbHMgYW5kIGFsbCBtYXRoIHN5bWJvbHMpLiZuYnNwOyBTcGVjaWZ5aW5nIGEgb25lLWxldHRlciBjb2RlIGlzCiAqICAgICAgIHRoZSBzYW1lIGFzIHNwZWNpZnlpbmcgYWxsIHR3by1sZXR0ZXIgY29kZXMgdGhhdCBiZWdpbiB3aXRoIHRoYXQgbGV0dGVyIChmb3IgZXhhbXBsZSwKICogICAgICAgJnF1b3Q7WzpMOl0mcXVvdDsgbWF0Y2hlcyBhbGwgbGV0dGVycywgYW5kIGlzIGVxdWl2YWxlbnQgdG8KICogICAgICAgJnF1b3Q7WzpMdTo6TGw6OkxvOjpMbTo6THQ6XSZxdW90OykuJm5ic3A7IEFueXRoaW5nIG90aGVyIHRoYW4gYSB2YWxpZCB0d28tbGV0dGVyIFVuaWNvZGUKICogICAgICAgY2F0ZWdvcnkgY29kZSBvciBhIHNpbmdsZSBsZXR0ZXIgdGhhdCBiZWdpbnMgYSBVbmljb2RlIGNhdGVnb3J5IGNvZGUgaXMgaWxsZWdhbCB3aXRoaW4KICogICAgICAgY29sb25zLjwvdGQ+CiAqICAgICA8L3RyPgogKiAgICAgPHRyPgogKiAgICAgICA8dGQgd2lkdGg9IjYlIj5bXTwvdGQ+CiAqICAgICAgIDx0ZCB3aWR0aD0iOTQlIj5bXSBleHByZXNzaW9ucyBjYW4gbmVzdC4mbmJzcDsgVGhpcyBoYXMgbm8gZWZmZWN0LCBleGNlcHQgd2hlbiB1c2VkIGluCiAqICAgICAgIGNvbmp1bmN0aW9uIHdpdGggdGhlIF4gdG9rZW4uPC90ZD4KICogICAgIDwvdHI+CiAqICAgICA8dHI+CiAqICAgICAgIDx0ZCB3aWR0aD0iNiUiPl48L3RkPgogKiAgICAgICA8dGQgd2lkdGg9Ijk0JSI+RXhjbHVkZXMgdGhlIGNoYXJhY3RlciAob3IgdGhlIGNoYXJhY3RlcnMgaW4gdGhlIFtdIGV4cHJlc3Npb24pIGZvbGxvd2luZwogKiAgICAgICBpdCBmcm9tIHRoZSBncm91cCBvZiBjaGFyYWN0ZXJzLiZuYnNwOyBGb3IgZXhhbXBsZSwgJnF1b3Q7W2Etel5wXSZxdW90OyBtYXRjaGVzIGFsbCBMYXRpbgogKiAgICAgICBsb3dlcmNhc2UgbGV0dGVycyBleGNlcHQgcC4mbmJzcDsgJnF1b3Q7WzpMOl5bXHU0ZTAwLVx1OWZmZl1dJnF1b3Q7IG1hdGNoZXMgYWxsIGxldHRlcnMKICogICAgICAgZXhjZXB0IHRoZSBIYW4gaWRlb2dyYXBocy48L3RkPgogKiAgICAgPC90cj4KICogICAgIDx0cj4KICogICAgICAgPHRkIHdpZHRoPSI2JSI+PGVtPihhbGwgb3RoZXJzKTwvZW0+PC90ZD4KICogICAgICAgPHRkIHdpZHRoPSI5NCUiPkFsbCBvdGhlciBjaGFyYWN0ZXJzIGFyZSB0cmVhdGVkIGFzIGxpdGVyYWwgY2hhcmFjdGVycy4mbmJzcDsgKEZvcgogKiAgICAgICBleGFtcGxlLCAmcXVvdDtbYWVpb3VdJnF1b3Q7IHNwZWNpZmllcyBqdXN0IHRoZSBsZXR0ZXJzIGEsIGUsIGksIG8sIGFuZCB1Lik8L3RkPgogKiAgICAgPC90cj4KICogICA8L3RhYmxlPgogKiA8L2Jsb2NrcXVvdGU+CiAqIAogKiA8cD5Gb3IgYSBtb3JlIGNvbXBsZXRlIGV4cGxhbmF0aW9uLCBzZWUgPGEKICogaHJlZj0iaHR0cDovL3d3dy5pYm0uY29tL2phdmEvZWR1Y2F0aW9uL2JvdW5kYXJpZXMvYm91bmRhcmllcy5odG1sIj5odHRwOi8vd3d3LmlibS5jb20vamF2YS9lZHVjYXRpb24vYm91bmRhcmllcy9ib3VuZGFyaWVzLmh0bWw8L2E+LgogKiAmbmJzcDsgRm9yIGV4YW1wbGVzLCBzZWUgdGhlIHJlc291cmNlIGRhdGEgKHdoaWNoIGlzIGFubm90YXRlZCkuPC9wPgogKgogKiBAYXV0aG9yIFJpY2hhcmQgR2lsbGFtCiAqLwpjbGFzcyBVX0kxOE5fQVBJIFJ1bGVCYXNlZEJyZWFrSXRlcmF0b3IgOiBwdWJsaWMgQnJlYWtJdGVyYXRvciB7CgpwdWJsaWM6CiAgICAvKioKICAgICAqIEEgdG9rZW4gdXNlZCBhcyBhIGNoYXJhY3Rlci1jYXRlZ29yeSB2YWx1ZSB0byBpZGVudGlmeSBpZ25vcmUgY2hhcmFjdGVycwogICAgICovCiAgICBzdGF0aWMgaW50OF90IElHTk9SRTsKCnByaXZhdGU6CiAgICAvKioKICAgICAqIFRoZSBzdGF0ZSBudW1iZXIgb2YgdGhlIHN0YXJ0aW5nIHN0YXRlCiAgICAgKi8KICAgIHN0YXRpYyBpbnQxNl90IFNUQVJUX1NUQVRFOwoKICAgIC8qKgogICAgICogVGhlIHN0YXRlLXRyYW5zaXRpb24gdmFsdWUgaW5kaWNhdGluZyAic3RvcCIKICAgICAqLwogICAgc3RhdGljIGludDE2X3QgU1RPUF9TVEFURTsKCnByb3RlY3RlZDoKICAgIC8qKgogICAgICogVGhlIGNoYXJhY3RlciBpdGVyYXRvciB0aHJvdWdoIHdoaWNoIHRoaXMgQnJlYWtJdGVyYXRvciBhY2Nlc3NlcyB0aGUgdGV4dAogICAgICovCiAgICBDaGFyYWN0ZXJJdGVyYXRvciogdGV4dDsKCiAgICAvKioKICAgICAqIFRoZSBkYXRhIHRhYmxlcyB0aGlzIGl0ZXJhdG9yIHVzZXMgdG8gZGV0ZXJtaW5lIHRoZSBicmVhayBwb3NpdGlvbnMKICAgICAqLwogICAgUnVsZUJhc2VkQnJlYWtJdGVyYXRvclRhYmxlcyogdGFibGVzOwoKcHJpdmF0ZToKICAgIC8qKgogICAgICogQ2xhc3MgSUQKICAgICAqLwogICAgc3RhdGljIGNoYXIgZmdDbGFzc0lEOwovKgogKiBIU1lTOiBUbyBiZSByZXZpc2l0ZWQsIG9uY2UgdGhlIGN0b3IgYXJlIG1hZGUgcHVibGljLgogKi8KIHByb3RlY3RlZDoKICAgIC8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICAgIC8vIGNvbnN0cnVjdG9ycwogICAgLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogICAgCi8vIFRoaXMgY29uc3RydWN0b3IgdXNlcyB0aGUgdWRhdGEgaW50ZXJmYWNlIHRvIGNyZWF0ZSBhIEJyZWFrSXRlcmF0b3Igd2hvc2UKLy8gaW50ZXJuYWwgdGFibGVzIGxpdmUgaW4gYSBtZW1vcnktbWFwcGVkIGZpbGUuICAiaW1hZ2UiIGlzIGEgcG9pbnRlciB0byB0aGUKLy8gYmVnaW5uaW5nIG9mIHRoYXQgZmlsZS4KUnVsZUJhc2VkQnJlYWtJdGVyYXRvcihjb25zdCB2b2lkKiBpbWFnZSk7CgogcHVibGljOgogICAgLyoqCiAgICAgKiBDb3B5IGNvbnN0cnVjdG9yLiAgV2lsbCBwcm9kdWNlIGEgY29sbGF0b3Igd2l0aCB0aGUgc2FtZSBiZWhhdmlvciwKICAgICAqIGFuZCB3aGljaCBpdGVyYXRlcyBvdmVyIHRoZSBzYW1lIHRleHQsIGFzIHRoZSBvbmUgcGFzc2VkIGluLgogICAgICovCiAgICBSdWxlQmFzZWRCcmVha0l0ZXJhdG9yKGNvbnN0IFJ1bGVCYXNlZEJyZWFrSXRlcmF0b3ImIHRoYXQpOwoKICAgIC8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICAgIC8vIGJvaWxlcnBsYXRlCiAgICAvLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgogICAgLyoqCiAgICAgKiBEZXN0cnVjdG9yCiAgICAgKi8KICAgIHZpcnR1YWwgflJ1bGVCYXNlZEJyZWFrSXRlcmF0b3IoKTsKCiAgICAvKioKICAgICAqIEFzc2lnbm1lbnQgb3BlcmF0b3IuICBTZXRzIHRoaXMgaXRlcmF0b3IgdG8gaGF2ZSB0aGUgc2FtZSBiZWhhdmlvciwKICAgICAqIGFuZCBpdGVyYXRlIG92ZXIgdGhlIHNhbWUgdGV4dCwgYXMgdGhlIG9uZSBwYXNzZWQgaW4uCiAgICAgKi8KICAgIFJ1bGVCYXNlZEJyZWFrSXRlcmF0b3ImIG9wZXJhdG9yPShjb25zdCBSdWxlQmFzZWRCcmVha0l0ZXJhdG9yJiB0aGF0KTsKCiAgICAvKioKICAgICAqIEVxdWFsaXR5IG9wZXJhdG9yLiAgUmV0dXJucyBUUlVFIGlmIGJvdGggQnJlYWtJdGVyYXRvcnMgYXJlIG9mIHRoZQogICAgICogc2FtZSBjbGFzcywgaGF2ZSB0aGUgc2FtZSBiZWhhdmlvciwgYW5kIGl0ZXJhdGUgb3ZlciB0aGUgc2FtZSB0ZXh0LgogICAgICovCiAgICB2aXJ0dWFsIGJvb2xfdCBvcGVyYXRvcj09KGNvbnN0IEJyZWFrSXRlcmF0b3ImIHRoYXQpIGNvbnN0OwoKICAgIC8qKgogICAgICogTm90LWVxdWFsIG9wZXJhdG9yLiAgSWYgb3BlcmF0b3I9PSByZXR1cm5zIFRSVUUsIHRoaXMgcmV0dXJucyBGQUxTRSwKICAgICAqIGFuZCB2aWNlIHZlcnNhLgogICAgICovCiAgICBib29sX3Qgb3BlcmF0b3IhPShjb25zdCBCcmVha0l0ZXJhdG9yJiB0aGF0KSBjb25zdDsKCiAgICAvKioKICAgICAqIFJldHVybnMgYSBuZXdseS1jb25zdHJ1Y3RlZCBSdWxlQmFzZWRCcmVha0l0ZXJhdG9yIHdpdGggdGhlIHNhbWUKICAgICAqIGJlaGF2aW9yLCBhbmQgaXRlcmF0aW5nIG92ZXIgdGhlIHNhbWUgdGV4dCwgYXMgdGhpcyBvbmUuCiAgICAgKi8KICAgIHZpcnR1YWwgQnJlYWtJdGVyYXRvciogY2xvbmUodm9pZCkgY29uc3Q7CgogICAgLyoqCiAgICAgKiBDb21wdXRlIGEgaGFzaCBjb2RlIGZvciB0aGlzIEJyZWFrSXRlcmF0b3IKICAgICAqIEByZXR1cm4gQSBoYXNoIGNvZGUKICAgICAqLwogICAgdmlydHVhbCBpbnQzMl90IGhhc2hDb2RlKHZvaWQpIGNvbnN0OwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgZGVzY3JpcHRpb24gdXNlZCB0byBjcmVhdGUgdGhpcyBpdGVyYXRvcgogICAgICovCiAgICB2aXJ0dWFsIGNvbnN0IFVuaWNvZGVTdHJpbmcmIGdldFJ1bGVzKHZvaWQpIGNvbnN0OwoKICAgIC8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICAgIC8vIEJyZWFrSXRlcmF0b3Igb3ZlcnJpZGVzCiAgICAvLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgogICAgLyoqCiAgICAgKiBSZXR1cm4gYSBDaGFyYWN0ZXJJdGVyYXRvciBvdmVyIHRoZSB0ZXh0IGJlaW5nIGFuYWx5emVkLiAgVGhpcyB2ZXJzaW9uCiAgICAgKiBvZiB0aGlzIG1ldGhvZCByZXR1cm5zIHRoZSBhY3R1YWwgQ2hhcmFjdGVySXRlcmF0b3Igd2UncmUgdXNpbmcgaW50ZXJuYWxseS4KICAgICAqIENoYW5naW5nIHRoZSBzdGF0ZSBvZiB0aGlzIGl0ZXJhdG9yIGNhbiBoYXZlIHVuZGVmaW5lZCBjb25zZXF1ZW5jZXMuICBJZgogICAgICogeW91IG5lZWQgdG8gY2hhbmdlIGl0LCBjbG9uZSBpdCBmaXJzdC4KICAgICAqIEByZXR1cm4gQW4gaXRlcmF0b3Igb3ZlciB0aGUgdGV4dCBiZWluZyBhbmFseXplZC4KICAgICAqLwogICAgdmlydHVhbCBjb25zdCBDaGFyYWN0ZXJJdGVyYXRvciYgZ2V0VGV4dCh2b2lkKSBjb25zdDsKCiAgICAvKioKICAgICAqIFJldHVybnMgYSBuZXdseS1jcmVhdGVkIENoYXJhY3Rlckl0ZXJhdG9yIHRoYXQgdGhlIGNhbGxlciBpcyB0byB0YWtlCiAgICAgKiBvd25lcnNoaXAgb2YuCiAgICAgKiBUSElTIEZVTkNUSU9OIFNIT1VMRCBOT1QgQkUgSEVSRS4gIElUJ1MgSEVSRSBCRUNBVVNFIEJyZWFrSXRlcmF0b3IgREVGSU5FUwogICAgICogSVQgQVMgUFVSRSBWSVJUVUFMLCBGT1JDSU5HIFJCQkkgVE8gSU1QTEVNRU5UIElULiAgSVQgU0hPVUxEIEJFIFJFTU9WRUQKICAgICAqIEZST00gKkJPVEgqIENMQVNTRVMuCiAgICAgKi8KICAgIHZpcnR1YWwgQ2hhcmFjdGVySXRlcmF0b3IqIGNyZWF0ZVRleHQodm9pZCkgY29uc3Q7CgogICAgLyoqCiAgICAgKiBTZXQgdGhlIGl0ZXJhdG9yIHRvIGFuYWx5emUgYSBuZXcgcGllY2Ugb2YgdGV4dC4gIFRoaXMgZnVuY3Rpb24gcmVzZXRzCiAgICAgKiB0aGUgY3VycmVudCBpdGVyYXRpb24gcG9zaXRpb24gdG8gdGhlIGJlZ2lubmluZyBvZiB0aGUgdGV4dC4KICAgICAqIEBwYXJhbSBuZXdUZXh0IEFuIGl0ZXJhdG9yIG92ZXIgdGhlIHRleHQgdG8gYW5hbHl6ZS4gIFRoZSBCcmVha0l0ZXJhdG9yCiAgICAgKiB0YWtlcyBvd25lcnNoaXAgb2YgdGhlIGNoYXJhY3RlciBpdGVyYXRvci4gIFRoZSBjYWxsZXIgTVVTVCBOT1QgZGVsZXRlIGl0IQogICAgICovCiAgICB2aXJ0dWFsIHZvaWQgYWRvcHRUZXh0KENoYXJhY3Rlckl0ZXJhdG9yKiBuZXdUZXh0KTsKCiAgICAvKioKICAgICAqIFNldCB0aGUgaXRlcmF0b3IgdG8gYW5hbHl6ZSBhIG5ldyBwaWVjZSBvZiB0ZXh0LiAgVGhpcyBmdW5jdGlvbiByZXNldHMKICAgICAqIHRoZSBjdXJyZW50IGl0ZXJhdGlvbiBwb3NpdGlvbiB0byB0aGUgYmVnaW5uaW5nIG9mIHRoZSB0ZXh0LgogICAgICogQHBhcmFtIG5ld1RleHQgVGhlIHRleHQgdG8gYW5hbHl6ZS4KICAgICAqLwogICAgdmlydHVhbCB2b2lkIHNldFRleHQoY29uc3QgVW5pY29kZVN0cmluZyYgbmV3VGV4dCk7CgogICAgLyoqCiAgICAgKiBTZXQgdGhlIGl0ZXJhdG9yIHRvIGFuYWx5emUgYSBuZXcgcGllY2Ugb2YgdGV4dC4gIFRoaXMgZnVuY3Rpb24gcmVzZXRzCiAgICAgKiB0aGUgY3VycmVudCBpdGVyYXRpb24gcG9zaXRpb24gdG8gdGhlIGJlZ2lubmluZyBvZiB0aGUgdGV4dC4KICAgICAqIEBwYXJhbSBuZXdUZXh0IFRoZSB0ZXh0IHRvIGFuYWx5emUuCiAgICAgKiBUSElTIEZVTkNUSU9OIFNIT1VMRCBOT1QgQkUgSEVSRS4gIElUJ1MgSEVSRSBCRUNBVVNFIEJyZWFrSXRlcmF0b3IgREVGSU5FUwogICAgICogSVQgQVMgUFVSRSBWSVJUVUFMLCBGT1JDSU5HIFJCQkkgVE8gSU1QTEVNRU5UIElULiAgSVQgU0hPVUxEIEJFIFJFTU9WRUQKICAgICAqIEZST00gKkJPVEgqIENMQVNTRVMuCiAgICAgKi8KICAgIHZpcnR1YWwgdm9pZCBzZXRUZXh0KGNvbnN0IFVuaWNvZGVTdHJpbmcqIG5ld1RleHQpOwoKICAgIC8qKgogICAgICogU2V0cyB0aGUgY3VycmVudCBpdGVyYXRpb24gcG9zaXRpb24gdG8gdGhlIGJlZ2lubmluZyBvZiB0aGUgdGV4dC4KICAgICAqIChpLmUuLCB0aGUgQ2hhcmFjdGVySXRlcmF0b3IncyBzdGFydGluZyBvZmZzZXQpLgogICAgICogQHJldHVybiBUaGUgb2Zmc2V0IG9mIHRoZSBiZWdpbm5pbmcgb2YgdGhlIHRleHQuCiAgICAgKi8KICAgIHZpcnR1YWwgaW50MzJfdCBmaXJzdCh2b2lkKTsKCiAgICAvKioKICAgICAqIFNldHMgdGhlIGN1cnJlbnQgaXRlcmF0aW9uIHBvc2l0aW9uIHRvIHRoZSBlbmQgb2YgdGhlIHRleHQuCiAgICAgKiAoaS5lLiwgdGhlIENoYXJhY3Rlckl0ZXJhdG9yJ3MgZW5kaW5nIG9mZnNldCkuCiAgICAgKiBAcmV0dXJuIFRoZSB0ZXh0J3MgcGFzdC10aGUtZW5kIG9mZnNldC4KICAgICAqLwogICAgdmlydHVhbCBpbnQzMl90IGxhc3Qodm9pZCk7CgogICAgLyoqCiAgICAgKiBBZHZhbmNlcyB0aGUgaXRlcmF0b3IgZWl0aGVyIGZvcndhcmQgb3IgYmFja3dhcmQgdGhlIHNwZWNpZmllZCBudW1iZXIgb2Ygc3RlcHMuCiAgICAgKiBOZWdhdGl2ZSB2YWx1ZXMgbW92ZSBiYWNrd2FyZCwgYW5kIHBvc2l0aXZlIHZhbHVlcyBtb3ZlIGZvcndhcmQuICBUaGlzIGlzCiAgICAgKiBlcXVpdmFsZW50IHRvIHJlcGVhdGVkbHkgY2FsbGluZyBuZXh0KCkgb3IgcHJldmlvdXMoKS4KICAgICAqIEBwYXJhbSBuIFRoZSBudW1iZXIgb2Ygc3RlcHMgdG8gbW92ZS4gIFRoZSBzaWduIGluZGljYXRlcyB0aGUgZGlyZWN0aW9uCiAgICAgKiAobmVnYXRpdmUgaXMgYmFja3dhcmRzLCBhbmQgcG9zaXRpdmUgaXMgZm9yd2FyZHMpLgogICAgICogQHJldHVybiBUaGUgY2hhcmFjdGVyIG9mZnNldCBvZiB0aGUgYm91bmRhcnkgcG9zaXRpb24gbiBib3VuZGFyaWVzIGF3YXkgZnJvbQogICAgICogdGhlIGN1cnJlbnQgb25lLgogICAgICovCiAgICB2aXJ0dWFsIGludDMyX3QgbmV4dChpbnQzMl90IG4pOwoKICAgIC8qKgogICAgICogQWR2YW5jZXMgdGhlIGl0ZXJhdG9yIHRvIHRoZSBuZXh0IGJvdW5kYXJ5IHBvc2l0aW9uLgogICAgICogQHJldHVybiBUaGUgcG9zaXRpb24gb2YgdGhlIGZpcnN0IGJvdW5kYXJ5IGFmdGVyIHRoaXMgb25lLgogICAgICovCiAgICB2aXJ0dWFsIGludDMyX3QgbmV4dCh2b2lkKTsKCiAgICAvKioKICAgICAqIEFkdmFuY2VzIHRoZSBpdGVyYXRvciBiYWNrd2FyZHMsIHRvIHRoZSBsYXN0IGJvdW5kYXJ5IHByZWNlZGluZyB0aGlzIG9uZS4KICAgICAqIEByZXR1cm4gVGhlIHBvc2l0aW9uIG9mIHRoZSBsYXN0IGJvdW5kYXJ5IHBvc2l0aW9uIHByZWNlZGluZyB0aGlzIG9uZS4KICAgICAqLwogICAgdmlydHVhbCBpbnQzMl90IHByZXZpb3VzKHZvaWQpOwoKICAgIC8qKgogICAgICogU2V0cyB0aGUgaXRlcmF0b3IgdG8gcmVmZXIgdG8gdGhlIGZpcnN0IGJvdW5kYXJ5IHBvc2l0aW9uIGZvbGxvd2luZwogICAgICogdGhlIHNwZWNpZmllZCBwb3NpdGlvbi4KICAgICAqIEBvZmZzZXQgVGhlIHBvc2l0aW9uIGZyb20gd2hpY2ggdG8gYmVnaW4gc2VhcmNoaW5nIGZvciBhIGJyZWFrIHBvc2l0aW9uLgogICAgICogQHJldHVybiBUaGUgcG9zaXRpb24gb2YgdGhlIGZpcnN0IGJyZWFrIGFmdGVyIHRoZSBjdXJyZW50IHBvc2l0aW9uLgogICAgICovCiAgICB2aXJ0dWFsIGludDMyX3QgZm9sbG93aW5nKGludDMyX3Qgb2Zmc2V0KTsKCiAgICAvKioKICAgICAqIFNldHMgdGhlIGl0ZXJhdG9yIHRvIHJlZmVyIHRvIHRoZSBsYXN0IGJvdW5kYXJ5IHBvc2l0aW9uIGJlZm9yZSB0aGUKICAgICAqIHNwZWNpZmllZCBwb3NpdGlvbi4KICAgICAqIEBvZmZzZXQgVGhlIHBvc2l0aW9uIHRvIGJlZ2luIHNlYXJjaGluZyBmb3IgYSBicmVhayBmcm9tLgogICAgICogQHJldHVybiBUaGUgcG9zaXRpb24gb2YgdGhlIGxhc3QgYm91bmRhcnkgYmVmb3JlIHRoZSBzdGFydGluZyBwb3NpdGlvbi4KICAgICAqLwogICAgdmlydHVhbCBpbnQzMl90IHByZWNlZGluZyhpbnQzMl90IG9mZnNldCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIHNwZWNmaWVkIHBvc2l0aW9uIGlzIGEgYm91bmRhcnkgcG9zaXRpb24uICBBcyBhIHNpZGUKICAgICAqIGVmZmVjdCwgbGVhdmVzIHRoZSBpdGVyYXRvciBwb2ludGluZyB0byB0aGUgZmlyc3QgYm91bmRhcnkgcG9zaXRpb24gYXQKICAgICAqIG9yIGFmdGVyICJvZmZzZXQiLgogICAgICogQHBhcmFtIG9mZnNldCB0aGUgb2Zmc2V0IHRvIGNoZWNrLgogICAgICogQHJldHVybiBUcnVlIGlmICJvZmZzZXQiIGlzIGEgYm91bmRhcnkgcG9zaXRpb24uCiAgICAgKi8KICAgIHZpcnR1YWwgYm9vbF90IGlzQm91bmRhcnkoaW50MzJfdCBvZmZzZXQpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgY3VycmVudCBpdGVyYXRpb24gcG9zaXRpb24uCiAgICAgKiBAcmV0dXJuIFRoZSBjdXJyZW50IGl0ZXJhdGlvbiBwb3NpdGlvbi4KICAgICAqLwogICAgdmlydHVhbCBpbnQzMl90IGN1cnJlbnQodm9pZCkgY29uc3Q7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgdW5pcXVlIGNsYXNzIElEIFBPTFlNT1JQSElDQUxMWS4gIFB1cmUgdmlydHVhbCBvdmVycmlkZS4KICAgICAqIFRoaXMgbWV0aG9kIGlzIHRvIGltcGxlbWVudCBhIHNpbXBsZSB2ZXJzaW9uIG9mIFJUVEksIHNpbmNlIG5vdCBhbGwKICAgICAqIEMrKyBjb21waWxlcnMgc3VwcG9ydCBnZW51aW5lIFJUVEkuICBQb2x5bW9ycGhpYyBvcGVyYXRvcj09KCkgYW5kCiAgICAgKiBjbG9uZSgpIG1ldGhvZHMgY2FsbCB0aGlzIG1ldGhvZC4KICAgICAqCiAgICAgKiBAcmV0dXJuICAgICAgICAgIFRoZSBjbGFzcyBJRCBmb3IgdGhpcyBvYmplY3QuIEFsbCBvYmplY3RzIG9mIGEKICAgICAqICAgICAgICAgICAgICAgICAgZ2l2ZW4gY2xhc3MgaGF2ZSB0aGUgc2FtZSBjbGFzcyBJRC4gIE9iamVjdHMgb2YKICAgICAqICAgICAgICAgICAgICAgICAgb3RoZXIgY2xhc3NlcyBoYXZlIGRpZmZlcmVudCBjbGFzcyBJRHMuCiAgICAgKi8KICAgIGlubGluZSB2aXJ0dWFsIFVDbGFzc0lEIGdldER5bmFtaWNDbGFzc0lEKHZvaWQpIGNvbnN0OwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgY2xhc3MgSUQgZm9yIHRoaXMgY2xhc3MuICBUaGlzIGlzIHVzZWZ1bCBvbmx5IGZvcgogICAgICogY29tcGFyaW5nIHRvIGEgcmV0dXJuIHZhbHVlIGZyb20gZ2V0RHluYW1pY0NsYXNzSUQoKS4gIEZvciBleGFtcGxlOgogICAgICoKICAgICAqICAgICAgQmFzZSogcG9seW1vcnBoaWNfcG9pbnRlciA9IGNyZWF0ZVBvbHltb3JwaGljT2JqZWN0KCk7CiAgICAgKiAgICAgIGlmIChwb2x5bW9ycGhpY19wb2ludGVyLT5nZXREeW5hbWljQ2xhc3NJRCgpID09CiAgICAgKiAgICAgICAgICBEZXJpdmVkOjpnZXRTdGF0aWNDbGFzc0lEKCkpIC4uLgogICAgICoKICAgICAqIEByZXR1cm4gICAgICAgICAgVGhlIGNsYXNzIElEIGZvciBhbGwgb2JqZWN0cyBvZiB0aGlzIGNsYXNzLgogICAgICovCiAgICBpbmxpbmUgc3RhdGljIFVDbGFzc0lEIGdldFN0YXRpY0NsYXNzSUQodm9pZCk7Cgpwcm90ZWN0ZWQ6CiAgICAvLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAgICAvLyBpbXBsZW1lbnRhdGlvbgogICAgLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogICAgLyoqCiAgICAgKiBUaGlzIG1ldGhvZCBpcyB0aGUgYWN0dWFsIGltcGxlbWVudGF0aW9uIG9mIHRoZSBuZXh0KCkgbWV0aG9kLiAgQWxsIGl0ZXJhdGlvbgogICAgICogdmVjdG9ycyB0aHJvdWdoIGhlcmUuICBUaGlzIG1ldGhvZCBpbml0aWFsaXplcyB0aGUgc3RhdGUgbWFjaGluZSB0byBzdGF0ZSAxCiAgICAgKiBhbmQgYWR2YW5jZXMgdGhyb3VnaCB0aGUgdGV4dCBjaGFyYWN0ZXIgYnkgY2hhcmFjdGVyIHVudGlsIHdlIHJlYWNoIHRoZSBlbmQKICAgICAqIG9mIHRoZSB0ZXh0IG9yIHRoZSBzdGF0ZSBtYWNoaW5lIHRyYW5zaXRpb25zIHRvIHN0YXRlIDAuICBXZSB1cGRhdGUgb3VyIHJldHVybgogICAgICogdmFsdWUgZXZlcnkgdGltZSB0aGUgc3RhdGUgbWFjaGluZSBwYXNzZXMgdGhyb3VnaCBhIHBvc3NpYmxlIGVuZCBzdGF0ZS4KICAgICAqLwogICAgdmlydHVhbCBpbnQzMl90IGhhbmRsZU5leHQodm9pZCk7CgogICAgLyoqCiAgICAgKiBUaGlzIG1ldGhvZCBiYWNrcyB0aGUgaXRlcmF0b3IgYmFjayB1cCB0byBhICJzYWZlIHBvc2l0aW9uIiBpbiB0aGUgdGV4dC4KICAgICAqIFRoaXMgaXMgYSBwb3NpdGlvbiB0aGF0IHdlIGtub3csIHdpdGhvdXQgYW55IGNvbnRleHQsIG11c3QgYmUgYSBicmVhayBwb3NpdGlvbi4KICAgICAqIFRoZSB2YXJpb3VzIGNhbGxpbmcgbWV0aG9kcyB0aGVuIGl0ZXJhdGUgZm9yd2FyZCBmcm9tIHRoaXMgc2FmZSBwb3NpdGlvbiB0bwogICAgICogdGhlIGFwcHJvcHJpYXRlIHBvc2l0aW9uIHRvIHJldHVybi4gIChGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIHRoZSBkZXNjcmlwdGlvbgogICAgICogb2YgYnVpbGRCYWNrd2FyZHNTdGF0ZVRhYmxlKCkgaW4gUnVsZUJhc2VkQnJlYWtJdGVyYXRvci5CdWlsZGVyLikKICAgICAqLwogICAgdmlydHVhbCBpbnQzMl90IGhhbmRsZVByZXZpb3VzKHZvaWQpOwoKICAgIC8qKgogICAgICogRHVtcHMgY2FjaGVzIGFuZCBwZXJmb3JtcyBvdGhlciBhY3Rpb25zIGFzc29jaWF0ZWQgd2l0aCBhIGNvbXBsZXRlIGNoYW5nZQogICAgICogaW4gdGV4dCBvciBpdGVyYXRpb24gcG9zaXRpb24uICBUaGlzIGZ1bmN0aW9uIGlzIGEgbm8tb3AgaW4gUnVsZUJhc2VkQnJlYWtJdGVyYXRvciwKICAgICAqIGJ1dCBzdWJjbGFzc2VzIGNhbiBhbmQgZG8gb3ZlcnJpZGUgaXQuCiAgICAgKi8KICAgIHZpcnR1YWwgdm9pZCByZXNldCh2b2lkKTsKCnByaXZhdGU6CgogICAgLyoqCiAgICAgKiBDb25zdHJ1Y3RzIGEgUnVsZUJhc2VkQnJlYWtJdGVyYXRvciB0aGF0IHVzZXMgdGhlIGFscmVhZHktY3JlYXRlZAogICAgICogdGFibGVzIG9iamVjdCB0aGF0IGlzIHBhc3NlZCBpbiBhcyBhIHBhcmFtZXRlci4KICAgICAqLwogICAgUnVsZUJhc2VkQnJlYWtJdGVyYXRvcihSdWxlQmFzZWRCcmVha0l0ZXJhdG9yVGFibGVzKiB0YWJsZXMpOwoKICAgIGZyaWVuZCBjbGFzcyBCcmVha0l0ZXJhdG9yOwp9OwoKaW5saW5lIGJvb2xfdCBSdWxlQmFzZWRCcmVha0l0ZXJhdG9yOjpvcGVyYXRvciE9KGNvbnN0IEJyZWFrSXRlcmF0b3ImIHRoYXQpIGNvbnN0IHsKICAgIHJldHVybiAhb3BlcmF0b3I9PSh0aGF0KTsKfQoKaW5saW5lIFVDbGFzc0lEIFJ1bGVCYXNlZEJyZWFrSXRlcmF0b3I6OmdldER5bmFtaWNDbGFzc0lEKHZvaWQpIGNvbnN0IHsKICAgIHJldHVybiBSdWxlQmFzZWRCcmVha0l0ZXJhdG9yOjpnZXRTdGF0aWNDbGFzc0lEKCk7Cn0KCmlubGluZSBVQ2xhc3NJRCBSdWxlQmFzZWRCcmVha0l0ZXJhdG9yOjpnZXRTdGF0aWNDbGFzc0lEKHZvaWQpIHsKICAgIHJldHVybiAoVUNsYXNzSUQpKCZmZ0NsYXNzSUQpOwp9CgojZW5kaWYK