LyoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKiBDT1BZUklHSFQ6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKiAgIChDKSBDb3B5cmlnaHQgVGFsaWdlbnQsIEluYy4sICAxOTk2ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKiAgIChDKSBDb3B5cmlnaHQgSW50ZXJuYXRpb25hbCBCdXNpbmVzcyBNYWNoaW5lcyBDb3Jwb3JhdGlvbiwgIDE5OTYtMTk5OSAgICAgICAgICAgICAgICoKKiAgIExpY2Vuc2VkIE1hdGVyaWFsIC0gUHJvZ3JhbS1Qcm9wZXJ0eSBvZiBJQk0gLSBBbGwgUmlnaHRzIFJlc2VydmVkLiAgICAgICAgICAgICAgICAgICoKKiAgIFVTIEdvdmVybm1lbnQgVXNlcnMgUmVzdHJpY3RlZCBSaWdodHMgLSBVc2UsIGR1cGxpY2F0aW9uLCBvciBkaXNjbG9zdXJlICAgICAgICAgICAgICoKKiAgIHJlc3RyaWN0ZWQgYnkgR1NBIEFEUCBTY2hlZHVsZSBDb250cmFjdCB3aXRoIElCTSBDb3JwLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKi8KLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vCi8vIEZpbGUgY29sZWl0ci5oCi8vCi8vIAovLwovLyBDcmVhdGVkIGJ5OiBIZWxlbmEgU2hpaAovLwovLyBNb2RpZmljYXRpb24gSGlzdG9yeToKLy8KLy8gIERhdGUgICAgICAgICBOYW1lICAgICAgICAgIERlc2NyaXB0aW9uCi8vCi8vICA4LzE4Lzk3ICAgICBoZWxlbmEgICAgICBBZGRlZCBpbnRlcm5hbCBBUEkgZG9jdW1lbnRhdGlvbi4KLy8gMDgvMDMvOTggICAgICAgIGVybSAgICAgICAgICAgIFN5bmNoZWQgd2l0aCAxLjIgdmVyc2lvbiBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuamF2YQovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiNpZm5kZWYgQ09MRUlUUl9ICiNkZWZpbmUgQ09MRUlUUl9ICgoKI2luY2x1ZGUgInVuaXN0ci5oIgojaW5jbHVkZSAidGJsY29sbC5oIgojaW5jbHVkZSAiY2hhcml0ZXIuaCIKCgpjbGFzcyBOb3JtYWxpemVyOwpjbGFzcyBWZWN0b3JPZkludDsKY2xhc3MgVmVjdG9yT2ZQVG9Db250cmFjdEVsZW1lbnQ7CgovKioKICogVGhlIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciBjbGFzcyBpcyB1c2VkIGFzIGFuIGl0ZXJhdG9yIHRvIHdhbGsgdGhyb3VnaAogKiBlYWNoIGNoYXJhY3RlciBvZiBhbiBpbnRlcm5hdGlvbmFsIHN0cmluZy4gVXNlIHRoZSBpdGVyYXRvciB0byByZXR1cm4gdGhlCiAqIG9yZGVyaW5nIHByaW9yaXR5IG9mIHRoZSBwb3NpdGlvbmVkIGNoYXJhY3Rlci4gVGhlIG9yZGVyaW5nIHByaW9yaXR5IG9mCiAqIGEgY2hhcmFjdGVyLCB3aGljaCB3ZSByZWZlciB0byBhcyBhIGtleSwgZGVmaW5lcyBob3cgYSBjaGFyYWN0ZXIgaXMKICogY29sbGF0ZWQgaW4gdGhlIGdpdmVuIGNvbGxhdGlvbiBvYmplY3QuCiAqIEZvciBleGFtcGxlLCBjb25zaWRlciB0aGUgZm9sbG93aW5nIGluIFNwYW5pc2g6CiAqIDxwcmU+CiAqIC4gICAgICAgImNhIiAtPiB0aGUgZmlyc3Qga2V5IGlzIGtleSgnYycpIGFuZCBzZWNvbmQga2V5IGlzIGtleSgnYScpLgogKiAuICAgICAgICJjaGEiIC0+IHRoZSBmaXJzdCBrZXkgaXMga2V5KCdjaCcpIGFuZCBzZWNvbmQga2V5IGlzIGtleSgnYScpLgogKiA8L3ByZT4KICogQW5kIGluIEdlcm1hbiwKICogPHByZT4KICogLiAgICAgICAi5mIiLT4gdGhlIGZpcnN0IGtleSBpcyBrZXkoJ2EnKSwgdGhlIHNlY29uZCBrZXkgaXMga2V5KCdlJyksIGFuZAogKiAuICAgICAgIHRoZSB0aGlyZCBrZXkgaXMga2V5KCdiJykuCiAqIDwvcHJlPgogKiBUaGUga2V5IG9mIGEgY2hhcmFjdGVyLCBpcyBhbiBpbnRlZ2VyIGNvbXBvc2VkIG9mIHByaW1hcnkgb3JkZXIoc2hvcnQpLAogKiBzZWNvbmRhcnkgb3JkZXIoY2hhciksIGFuZCB0ZXJ0aWFyeSBvcmRlcihjaGFyKS4gIEphdmEgc3RyaWN0bHkgZGVmaW5lcwogKiB0aGUgc2l6ZSBhbmQgc2lnbmVkbmVzcyBvZiBpdHMgcHJpbWl0aXZlIGRhdGEgdHlwZXMuICBUaGVyZWZvcmUsIHRoZSBzdGF0aWMKICogZnVuY3Rpb25zIHByaW1hcnlPcmRlcigpLCBzZWNvbmRhcnlPcmRlcigpLCBhbmQgdGVydGlhcnlPcmRlcigpIHJldHVybiBpbnQzMl90CiAqIHRvIGVuc3VyZSB0aGUgY29ycmVjdG5lc3Mgb2YgdGhlIGtleSB2YWx1ZS4KICogPHA+RXhhbXBsZSBvZiB0aGUgaXRlcmF0b3IgdXNhZ2U6ICh3aXRob3V0IGVycm9yIGNoZWNraW5nKQogKiA8cHJlPgogKiAuICB2b2lkIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcl9FeGFtcGxlKCkKICogLiAgewogKiAuICAgICAgVW5pY29kZVN0cmluZyBzdHIgPSAiVGhpcyBpcyBhIHRlc3QiOwogKiAuICAgICAgVUVycm9yQ29kZSBzdWNjZXNzID0gVV9aRVJPX0VSUk9SOwogKiAuICAgICAgUnVsZUJhc2VkQ29sbGF0b3IqIHJiYyA9CiAqIC4gICAgICAgICAgKFJ1bGVCYXNlZENvbGxhdG9yKikgUnVsZUJhc2VkQ29sbGF0b3I6OmNyZWF0ZUluc3RhbmNlKHN1Y2Nlc3MpOwogKiAuICAgICAgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKiBjID0KICogLiAgICAgICAgICByYmMtPmNyZWF0ZUNvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciggc3RyICk7CiAqIC4gICAgICBpbnQzMl90IG9yZGVyID0gYy0+bmV4dChzdWNjZXNzKTsKICogLiAgICAgIGludDMyX3QgcHJpbWFyeU9yZGVyID0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpwcmltYXJ5T3JkZXIoIG9yZGVyICk7CiAqIC4gICAgICBkZWxldGUgYzsKICogLiAgICAgIGRlbGV0ZSByYmM7CiAqIC4gIH0KICogPC9wcmU+CiAqIDxwPgogKiBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6Om5leHQgcmV0dXJucyB0aGUgY29sbGF0aW9uIG9yZGVyIG9mIHRoZSBuZXh0CiAqIGNoYXJhY3RlciBiYXNlZCBvbiB0aGUgY29tcGFyaXNvbiBsZXZlbCBvZiB0aGUgY29sbGF0b3IuICBBIGNvbGxhdGlvbiBvcmRlciAKICogY29uc2lzdHMgb2YgcHJpbWFyeSBvcmRlciwgc2Vjb25kYXJ5IG9yZGVyIGFuZCB0ZXJ0aWFyeSBvcmRlci4gIFRoZSBkYXRhIAogKiB0eXBlIG9mIHRoZSBjb2xsYXRpb24gb3JkZXIgaXMgPHN0cm9uZz5pbnQzMl90PC9zdHJvbmc+LiAgVGhlIGZpcnN0IDE2IGJpdHMgb2YgCiAqIGEgY29sbGF0aW9uIG9yZGVyIGlzIGl0cyBwcmltYXJ5IG9yZGVyOyB0aGUgbmV4dCA4IGJpdHMgaXMgdGhlIHNlY29uZGFyeSAKICogb3JkZXIgYW5kIHRoZSBsYXN0IDggYml0cyBpcyB0aGUgdGVydGlhcnkgb3JkZXIuCiAqCiAqIEBzZWUgICAgICAgICAgICAgICAgQ29sbGF0b3IKICogQHNlZSAgICAgICAgICAgICAgICBSdWxlQmFzZWRDb2xsYXRvcgogKiBAdmVyc2lvbiAgICAgICAgICAgIDEuOSAxLzMwLzk3CiAqIEBhdXRob3IgICAgICAgICAgICAgSGVsZW5hIFNoaWgKICovCmNsYXNzIFVfSTE4Tl9BUEkgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yCnsKcHVibGljIDogICAgIAogICAgLyoqCiAgICAgKiBOVUxMT1JERVIgaW5kaWNhdGVzIHRoZSBpdGVyYXRvciBoYXMgY29uc3VtZWQgdGhlIGxhc3QgZWxlbWVudC4KICAgICAqLwogICAgc3RhdGljICBpbnQzMl90IGNvbnN0ICAgTlVMTE9SREVSOwoKICAgIC8qKiBEZXN0cnVjdG9yCiAgICAgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB+Q29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKCk7CiAgICAvKioKICAgICAqIFJldHVybnMgdHJ1ZSBpZiAib3RoZXIiIGlzIHRoZSBzYW1lIGFzICJ0aGlzIgogICAgICovCiAgICB2aXJ0dWFsICAgICBib29sX3QgICAgICAgICAgb3BlcmF0b3I9PShjb25zdCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3ImIG90aGVyKSBjb25zdDsKCiAgICAvKioKICAgICAqIFJldHVybnMgdHJ1ZSBpZiAib3RoZXIiIGlzIG5vdCB0aGUgc2FtZSBhcyAidGhpcyIuCiAgICAgKi8KICAgIHZpcnR1YWwgICAgIGJvb2xfdCAgICAgICAgICBvcGVyYXRvciE9KGNvbnN0IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciYgb3RoZXIpIGNvbnN0OwoKICAgIC8qKgogICAgICogUmVzZXRzIHRoZSBjdXJzb3IgdG8gdGhlIGJlZ2lubmluZyBvZiB0aGUgc3RyaW5nLgogICAgICovCiAgICAgICAgICAgIHZvaWQgICAgICAgICAgICAgICAgcmVzZXQodm9pZCk7CiAgICAvKioKICAgICAqIEdldHMgdGhlIG9yZGVyaW5nIHByaW9yaXR5IG9mIHRoZSBuZXh0IGNoYXJhY3RlciBpbiB0aGUgc3RyaW5nLgogICAgICogQHBhcmFtIHN0YXR1cyB0aGUgZXJyb3IgY29kZSBzdGF0dXMuCiAgICAgKiBAcmV0dXJuIHRoZSBuZXh0IGNoYXJhY3RlcidzIG9yZGVyaW5nLiAgUmV0dXJucyBOVUxMT1JERVIgaWYKICAgICAqIHRoZSBlbmQgb2Ygc3RyaW5nIGlzIHJlYWNoZWQuCiAgICAgKi8KICAgICAgICAgICAgaW50MzJfdCAgICAgICAgICAgICBuZXh0KFVFcnJvckNvZGUmIHN0YXR1cyk7CiAgICAgLyoqCiAgICAgICogR2V0IHRoZSBvcmRlcmluZyBwcmlvcml0eSBvZiB0aGUgcHJldmlvdXMgY29sbGF0aW9uIGVsZW1lbnQgaW4gdGhlIHN0cmluZy4KICAgICAgKiBAcGFyYW0gc3RhdHVzIHRoZSBlcnJvciBjb2RlIHN0YXR1cy4KICAgICAgKiBAcmV0dXJuIHRoZSBwcmV2aW91cyBlbGVtZW50J3Mgb3JkZXJpbmcuICBSZXR1cm5zIE5VTExPUkRFUiBpZgogICAgICAqIHRoZSBiZWdpbm5pbmcgb2Ygc3RyaW5nIGlzIHJlYWNoZWQuCiAgICAgICovCiAgICAgICAgICAgIGludDMyX3QgICAgICAgICAgICAgICAgIHByZXZpb3VzKFVFcnJvckNvZGUmIHN0YXR1cyk7CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBwcmltYXJ5IG9yZGVyIG9mIGEgY29sbGF0aW9uIG9yZGVyLgogICAgICogQHBhcmFtIG9yZGVyIHRoZSBjb2xsYXRpb24gb3JkZXIKICAgICAqIEByZXR1cm4gdGhlIHByaW1hcnkgb3JkZXIgb2YgYSBjb2xsYXRpb24gb3JkZXIuCiAgICAgKi8KICAgIHN0YXRpYyAgaW50MzJfdCAgICAgICAgICAgICBwcmltYXJ5T3JkZXIoaW50MzJfdCBvcmRlcik7CiAgICAvKioKICAgICAqIEdldHMgdGhlIHNlY29uZGFyeSBvcmRlciBvZiBhIGNvbGxhdGlvbiBvcmRlci4KICAgICAqIEBwYXJhbSBvcmRlciB0aGUgY29sbGF0aW9uIG9yZGVyCiAgICAgKiBAcmV0dXJuIHRoZSBzZWNvbmRhcnkgb3JkZXIgb2YgYSBjb2xsYXRpb24gb3JkZXIuCiAgICAgKi8KICAgIHN0YXRpYyAgaW50MzJfdCAgICAgICAgICAgICBzZWNvbmRhcnlPcmRlcihpbnQzMl90IG9yZGVyKTsKICAgIC8qKgogICAgICogR2V0cyB0aGUgdGVydGlhcnkgb3JkZXIgb2YgYSBjb2xsYXRpb24gb3JkZXIuCiAgICAgKiBAcGFyYW0gb3JkZXIgdGhlIGNvbGxhdGlvbiBvcmRlcgogICAgICogQHJldHVybiB0aGUgdGVydGlhcnkgb3JkZXIgb2YgYSBjb2xsYXRpb24gb3JkZXIuCiAgICAgKi8KICAgIHN0YXRpYyAgaW50MzJfdCAgICAgICAgICAgICB0ZXJ0aWFyeU9yZGVyKGludDMyX3Qgb3JkZXIpOwogICAgLyoqCiAgICAgKiAgUmV0dXJuIHRoZSBtYXhpbXVtIGxlbmd0aCBvZiBhbnkgZXhwYW5zaW9uIHNlcXVlbmNlcyB0aGF0IGVuZAogICAgICogIHdpdGggdGhlIHNwZWNpZmllZCBjb21wYXJpc29uIG9yZGVyLgogICAgICogIEBwYXJhbSBvcmRlciBhIGNvbGxhdGlvbiBvcmRlciByZXR1cm5lZCBieSBwcmV2aW91cyBvciBuZXh0LgogICAgICogIEByZXR1cm4gdGhlIG1heGltdW0gbGVuZ3RoIG9mIGFueSBleHBhbnNpb24gc2VxdWVuY2VzIGVuZGluZwogICAgICogICAgICAgICAgd2l0aCB0aGUgc3BlY2lmaWVkIG9yZGVyLgogICAgICovCiAgICAgICAgaW50MzJfdCAgICAgICAgICAgICAgICAgICAgZ2V0TWF4RXhwYW5zaW9uKGludDMyX3Qgb3JkZXIpIGNvbnN0OwoKcHVibGljOgogICAgLyoqCiAgICAgKiAgR2V0cyB0aGUgY29tcGFyaXNvbiBvcmRlciBpbiB0aGUgZGVzaXJlZCBzdHJlbmd0aC4gIElnbm9yZSB0aGUgb3RoZXIKICAgICAqICBkaWZmZXJlbmNlcy4KICAgICAqICBAcGFyYW0gb3JkZXIgVGhlIG9yZGVyIHZhbHVlCiAgICAgKi8KICAgICAgICAgICBpbnQzMl90ICAgICAgICAgICAgICBzdHJlbmd0aE9yZGVyKGludDMyX3Qgb3JkZXIpIGNvbnN0OwogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBzb3VyY2Ugc3RyaW5nLgogICAgICogQHBhcmFtIHN0ciB0aGUgc291cmNlIHN0cmluZy4KICAgICAqIEBwYXJhbSBzdGF0dXMgdGhlIGVycm9yIGNvZGUgc3RhdHVzLgogICAgICovCiAgICAgICAgICAgIHZvaWQgICAgICAgICAgICAgICAgc2V0VGV4dChjb25zdCAgIFVuaWNvZGVTdHJpbmcmICBzdHIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmICAgICAgc3RhdHVzKTsKICAgICAvKioKICAgICAqIFNldHMgdGhlIHNvdXJjZSBzdHJpbmcuCiAgICAgKiBAcGFyYW0gc3RyIHRoZSBzb3VyY2UgY2hhcmFjdGVyIGl0ZXJhdG9yLgogICAgICogQHBhcmFtIHN0YXR1cyB0aGUgZXJyb3IgY29kZSBzdGF0dXMuCiAgICAgKi8KICAgICAgICAgICAgdm9pZCAgICAgICAgICAgICAgICBzZXRUZXh0KENoYXJhY3Rlckl0ZXJhdG9yJiAgc3RyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgICAgICAgICAgICBzdGF0dXMpOwogICAvKioKICAgICAqICBDaGVja3MgaWYgYSBjb21wYXJpc29uIG9yZGVyIGlzIGlnbm9yYWJsZS4KICAgICAqICBAcGFyYW0gb3JkZXIgdGhlIGNvbGxhdGlvbiBvcmRlci4KICAgICAqICBAcmV0dXJuIFRSVUUgaWYgYSBjaGFyYWN0ZXIgaXMgaWdub3JhYmxlLCBGQUxTRSBvdGhlcndpc2UuCiAgICAgKi8KICAgIHN0YXRpYyAgICBib29sX3QgICAgICAgICAgICAgIGlzSWdub3JhYmxlKGludDMyX3Qgb3JkZXIpOwogICAgLyoqCiAgICAgKiAgR2V0cyB0aGUgb2Zmc2V0IG9mIHRoZSBjdXJyZW50bHkgcHJvY2Vzc2VkIGNoYXJhY3RlciBpbiB0aGUgc291cmNlIHN0cmluZy4KICAgICAqICBAcmV0dXJuIHRoZSBvZmZzZXQgb2YgdGhlIGNoYXJhY3Rlci4KICAgICAqLwogICAgICAgICAgICBVVGV4dE9mZnNldCAgICAgICAgICBnZXRPZmZzZXQodm9pZCkgY29uc3Q7CiAgICAvKioKICAgICAqICBTZXRzIHRoZSBvZmZzZXQgb2YgdGhlIGN1cnJlbnRseSBwcm9jZXNzZWQgY2hhcmFjdGVyIGluIHRoZSBzb3VyY2Ugc3RyaW5nLgogICAgICogIEBwYXJhbSBuZXdPZmZzZXQgdGhlIG5ldyBvZmZzZXQuCiAgICAgKiAgQHBhcmFtIHN0YXR1cyB0aGUgZXJyb3IgY29kZSBzdGF0dXMuCiAgICAgKiAgQHJldHVybiB0aGUgb2Zmc2V0IG9mIHRoZSBjaGFyYWN0ZXIuCiAgICAgKi8KICAgICAgICAgICAgdm9pZCAgICAgICAgICAgICAgICBzZXRPZmZzZXQoVVRleHRPZmZzZXQgbmV3T2Zmc2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpOwpwcm90ZWN0ZWQ6CiAgICAvKioKICAgICAqIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciBjb25zdHJ1Y3Rvci4gIFRoaXMgdGFrZXMgdGhlIHNvdXJjZSBzdHJpbmcgYW5kCiAgICAgKiB0aGUgY29sbGF0aW9uIG9iamVjdC4gIFRoZSBjdXJzb3Igd2lsbCB3YWxrIHRocnUgdGhlIHNvdXJjZSBzdHJpbmcgYmFzZWQKICAgICAqIG9uIHRoZSBwcmVkZWZpbmVkIGNvbGxhdGlvbiBydWxlcy4gIElmIHRoZSBzb3VyY2Ugc3RyaW5nIGlzIGVtcHR5LAogICAgICogTlVMTE9SREVSIHdpbGwgYmUgcmV0dXJuZWQgb24gdGhlIGNhbGxzIHRvIG5leHQoKS4KICAgICAqIEBwYXJhbSBzb3VyY2VUZXh0IHRoZSBzb3VyY2Ugc3RyaW5nLgogICAgICogQHBhcmFtIHN0YXJ0T2Zmc2V0IHRoZSBiZWdpbm5pbmcgb2Zmc2V0IG9mIHRoZSBzdHJpbmcgd2hlcmUgdGhlIGN1cnNvcgogICAgICogc3RhcnRzIHRoZSBpdGVyYXRpbmcuCiAgICAgKiBAcGFyYW0gZW5kT2Zmc2V0IHRoZSBlbmRpbmcgb2Zmc2V0IG9mIHRoZSBzdHJpbmcgd2hlcmUgdGhlIGN1cnNvcgogICAgICogc3RvcHMgdGhlIGl0ZXJhdGluZy4KICAgICAqIEBwYXJhbSBvcmRlciB0aGUgY29sbGF0aW9uIG9iamVjdC4KICAgICAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciggICBjb25zdCAgIFVuaWNvZGVTdHJpbmcmICBzb3VyY2VUZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCAgIFJ1bGVCYXNlZENvbGxhdG9yKiAgb3JkZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cyk7CgogICAgLyoqCiAgICAgKiBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IgY29uc3RydWN0b3IuICBUaGlzIHRha2VzIHRoZSBzb3VyY2Ugc3RyaW5nIGFuZAogICAgICogdGhlIGNvbGxhdGlvbiBvYmplY3QuICBUaGUgY3Vyc29yIHdpbGwgd2FsayB0aHJ1IHRoZSBzb3VyY2Ugc3RyaW5nIGJhc2VkCiAgICAgKiBvbiB0aGUgcHJlZGVmaW5lZCBjb2xsYXRpb24gcnVsZXMuICBJZiB0aGUgc291cmNlIHN0cmluZyBpcyBlbXB0eSwKICAgICAqIE5VTExPUkRFUiB3aWxsIGJlIHJldHVybmVkIG9uIHRoZSBjYWxscyB0byBuZXh0KCkuCiAgICAgKiBAcGFyYW0gc291cmNlVGV4dCB0aGUgc291cmNlIHN0cmluZy4KICAgICAqIEBwYXJhbSBzdGFydE9mZnNldCB0aGUgYmVnaW5uaW5nIG9mZnNldCBvZiB0aGUgc3RyaW5nIHdoZXJlIHRoZSBjdXJzb3IKICAgICAqIHN0YXJ0cyB0aGUgaXRlcmF0aW5nLgogICAgICogQHBhcmFtIGVuZE9mZnNldCB0aGUgZW5kaW5nIG9mZnNldCBvZiB0aGUgc3RyaW5nIHdoZXJlIHRoZSBjdXJzb3IKICAgICAqIHN0b3BzIHRoZSBpdGVyYXRpbmcuCiAgICAgKiBAcGFyYW0gb3JkZXIgdGhlIGNvbGxhdGlvbiBvYmplY3QuCiAgICAgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IoICAgY29uc3QgICAgQ2hhcmFjdGVySXRlcmF0b3ImICBzb3VyY2VUZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCAgIFJ1bGVCYXNlZENvbGxhdG9yKiAgb3JkZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cyk7CiAgICAvKioKICAgICAqIEFzc2lnbm1lbnQgb3BlcmF0b3IKICAgICAqLwogICAgY29uc3QgICBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3ImCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3BlcmF0b3I9KGNvbnN0IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciYgb3RoZXIpOwpwdWJsaWM6CiAgICAvKioKICAgICAqIENvcHkgY29uc3RydWN0b3IuCiAgICAgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IoY29uc3QgIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciYgb3RoZXIpOwogICAgLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICAgIC8vIHByaXZhdGVzCiAgICAvLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQpwcml2YXRlOgogICAgLyoqCiAgICAgKiBEZWZhdWx0IGNvbnN0cnVjdG9yLgogICAgICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKCk7CiAgICAvKioKICAgICAqIENvcHkgY29uc3RydWN0b3IuCiAgICAgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IoY29uc3QgUnVsZUJhc2VkQ29sbGF0b3IqIG9yZGVyKTsKCiAgICAvKioKICAgICAqIEdldHMgdGhlIG9yZGVyaW5nIHByaW9yaXR5IG9mIHRoZSBuZXh0IGNvbnRyYWN0aW5nIGNoYXJhY3RlciBpbiB0aGUKICAgICAqIHN0cmluZy4KICAgICAqIEBwYXJhbSBjaCB0aGUgc3RhcnRpbmcgY2hhcmFjdGVyIG9mIGEgY29udHJhY3RpbmcgY2hhcmFjdGVyIHRva2VuCiAgICAgKiBAcGFyYW0gc3RhdHVzIHRoZSBlcnJvciBjb2RlIHN0YXR1cy4KICAgICAqIEByZXR1cm4gdGhlIG5leHQgY29udHJhY3RpbmcgY2hhcmFjdGVyJ3Mgb3JkZXJpbmcuICBSZXR1cm5zIE5VTExPUkRFUgogICAgICogaWYgdGhlIGVuZCBvZiBzdHJpbmcgaXMgcmVhY2hlZC4KICAgICAqLwogICAgICAgICAgICBpbnQzMl90ICAgICAgICAgICAgIG5leHRDb250cmFjdENoYXIoICAgVUNoYXIgICAgIGNoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgIHN0YXR1cyk7CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBvcmRlcmluZyBwcmlvcml0eSBvZiB0aGUgcHJldmlvdXMgY29udHJhY3RpbmcgY2hhcmFjdGVyIGluIHRoZQogICAgICogc3RyaW5nLgogICAgICogQHBhcmFtIGNoIHRoZSBzdGFydGluZyBjaGFyYWN0ZXIgb2YgYSBjb250cmFjdGluZyBjaGFyYWN0ZXIgdG9rZW4KICAgICAqIEBwYXJhbSBzdGF0dXMgdGhlIGVycm9yIGNvZGUgc3RhdHVzLgogICAgICogQHJldHVybiB0aGUgcHJldmlvdXMgY29udHJhY3RpbmcgY2hhcmFjdGVyJ3Mgb3JkZXJpbmcuICBSZXR1cm5zIE5VTExPUkRFUgogICAgICogaWYgdGhlIHN0YXJ0IG9mIHN0cmluZyBpcyByZWFjaGVkLgogICAgICovCiAgICAgICAgICAgIGludDMyX3QgICAgICAgICAgICAgcHJldkNvbnRyYWN0Q2hhciggICBVQ2hhciAgICAgY2gsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiAgc3RhdHVzKTsKCiAgICBmcmllbmQgIGNsYXNzICAgUnVsZUJhc2VkQ29sbGF0b3I7CiAgICBzdGF0aWMgIGNvbnN0ICAgaW50MzJfdCAgICAgICAgIFVOTUFQUEVEQ0hBUlZBTFVFOwoKICAgICAgICAgICAgTm9ybWFsaXplciogICAgICAgICAgICB0ZXh0OyAgICAgICAvLyBvd25pbmcgCgogICAgICAgICAgICBWZWN0b3JPZkludCogICAgICAgIGJ1ZmZlckFsaWFzOwogICAgICAgICAgICBpbnQzMl90ICAgICAgICAgICAgIHN3YXBPcmRlcjsgIC8vIGZvciB1bm1hcHBlZCBjaGFyYWN0ZXJzCiAgICAgICAgICAgIGludDMyX3QgICAgICAgICAgICAgZXhwSW5kZXg7CiAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcgICAgICAga2V5OwogICAgY29uc3QgICBSdWxlQmFzZWRDb2xsYXRvciogIG9yZGVyQWxpYXM7Cn07CgoKLyoqCiAqIEdldCB0aGUgcHJpbWFyeSBvcmRlciBvZiBhIGNvbGxhdGlvbiBvcmRlci4KICogQHBhcmFtIG9yZGVyIHRoZSBjb2xsYXRpb24gb3JkZXIKICogQHJldHVybiB0aGUgcHJpbWFyeSBvcmRlciBvZiBhIGNvbGxhdGlvbiBvcmRlci4KICovCmlubGluZSBpbnQzMl90CkNvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6cHJpbWFyeU9yZGVyKGludDMyX3Qgb3JkZXIpCnsKICAgIG9yZGVyICY9IFJ1bGVCYXNlZENvbGxhdG9yOjpQUklNQVJZT1JERVJNQVNLOwogICAgcmV0dXJuIChvcmRlciA+PiBSdWxlQmFzZWRDb2xsYXRvcjo6UFJJTUFSWU9SREVSU0hJRlQpOwp9Ci8qKgogKiBHZXQgdGhlIHNlY29uZGFyeSBvcmRlciBvZiBhIGNvbGxhdGlvbiBvcmRlci4KICogQHBhcmFtIG9yZGVyIHRoZSBjb2xsYXRpb24gb3JkZXIKICogQHJldHVybiB0aGUgc2Vjb25kYXJ5IG9yZGVyIG9mIGEgY29sbGF0aW9uIG9yZGVyLgogKi8KaW5saW5lIGludDMyX3QKQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpzZWNvbmRhcnlPcmRlcihpbnQzMl90IG9yZGVyKQp7CiAgICBvcmRlciA9IG9yZGVyICYgUnVsZUJhc2VkQ29sbGF0b3I6OlNFQ09OREFSWU9SREVSTUFTSzsKICAgIHJldHVybiAob3JkZXIgPj4gUnVsZUJhc2VkQ29sbGF0b3I6OlNFQ09OREFSWU9SREVSU0hJRlQpOwp9Ci8qKgogKiBHZXQgdGhlIHRlcnRpYXJ5IG9yZGVyIG9mIGEgY29sbGF0aW9uIG9yZGVyLgogKiBAcGFyYW0gb3JkZXIgdGhlIGNvbGxhdGlvbiBvcmRlcgogKiBAcmV0dXJuIHRoZSB0ZXJ0aWFyeSBvcmRlciBvZiBhIGNvbGxhdGlvbiBvcmRlci4KICovCmlubGluZSBpbnQzMl90CkNvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6dGVydGlhcnlPcmRlcihpbnQzMl90IG9yZGVyKQp7CiAgICByZXR1cm4gKG9yZGVyICY9IFJ1bGVCYXNlZENvbGxhdG9yOjpURVJUSUFSWU9SREVSTUFTSyk7Cn0KCmlubGluZSBpbnQzMl90CkNvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6Z2V0TWF4RXhwYW5zaW9uKGludDMyX3Qgb3JkZXIpIGNvbnN0CnsKICAgIHJldHVybiBvcmRlckFsaWFzLT5nZXRNYXhFeHBhbnNpb24ob3JkZXIpOwp9CgppbmxpbmUgYm9vbF90CkNvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6aXNJZ25vcmFibGUoaW50MzJfdCBvcmRlcikKewogICAgcmV0dXJuIChwcmltYXJ5T3JkZXIob3JkZXIpID09IDApOwp9CgojZW5kaWYK