LyoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogQ29weXJpZ2h0IChDKSAxOTk2LTIwMDEsIEludGVybmF0aW9uYWwgQnVzaW5lc3MgTWFjaGluZXMgQ29ycG9yYXRpb24gYW5kCiogb3RoZXJzLiBBbGwgUmlnaHRzIFJlc2VydmVkLgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKi8KCi8qKgoqIEZpbGUgdGJsY29sbC5oCioKKiBDcmVhdGVkIGJ5OiBIZWxlbmEgU2hpaAoqCiogTW9kaWZpY2F0aW9uIEhpc3Rvcnk6CioKKiAgRGF0ZSAgICAgICAgTmFtZSAgICAgICAgRGVzY3JpcHRpb24KKiAgMi81Lzk3ICAgICAgYWxpdSAgICAgICAgQWRkZWQgc3RyZWFtSW4gYW5kIHN0cmVhbU91dCBtZXRob2RzLiAgQWRkZWQKKiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RydWN0b3Igd2hpY2ggcmVhZHMgUnVsZUJhc2VkQ29sbGF0b3Igb2JqZWN0IGZyb20KKiAgICAgICAgICAgICAgICAgICAgICAgICAgYSBiaW5hcnkgZmlsZS4gIEFkZGVkIHdyaXRlVG9GaWxlIG1ldGhvZCB3aGljaCBzdHJlYW1zCiogICAgICAgICAgICAgICAgICAgICAgICAgIFJ1bGVCYXNlZENvbGxhdG9yIG91dCB0byBhIGJpbmFyeSBmaWxlLiAgVGhlIHN0cmVhbUluCiogICAgICAgICAgICAgICAgICAgICAgICAgIGFuZCBzdHJlYW1PdXQgbWV0aG9kcyB1c2UgaXN0cmVhbSBhbmQgb3N0cmVhbSBvYmplY3RzCiogICAgICAgICAgICAgICAgICAgICAgICAgIGluIGJpbmFyeSBtb2RlLgoqICAyLzEyLzk3ICAgICBhbGl1ICAgICAgICBNb2RpZmllZCB0byB1c2UgVGFibGVDb2xsYXRpb25EYXRhIHN1Yi1vYmplY3QgdG8KKiAgICAgICAgICAgICAgICAgICAgICAgICAgaG9sZCBpbnZhcmlhbnQgZGF0YS4KKiAgMi8xMy85NyAgICAgYWxpdSAgICAgICAgTW92ZWQgc2V2ZXJhbCBtZXRob2RzIGludG8gdGhpcyBjbGFzcyBmcm9tIENvbGxhdGlvbi4KKiAgICAgICAgICAgICAgICAgICAgICAgICAgQWRkZWQgYSBwcml2YXRlIFJ1bGVCYXNlZENvbGxhdG9yKExvY2FsZSYpIGNvbnN0cnVjdG9yLAoqICAgICAgICAgICAgICAgICAgICAgICAgICB0byBiZSB1c2VkIGJ5IENvbGxhdG9yOjpjcmVhdGVEZWZhdWx0KCkuICBHZW5lcmFsCiogICAgICAgICAgICAgICAgICAgICAgICAgIGNsZWFuIHVwLgoqICAyLzIwLzk3ICAgICBoZWxlbmEgICAgICBBZGRlZCBjbG9uZSwgb3BlcmF0b3I9PSwgb3BlcmF0b3IhPSwgb3BlcmF0b3I9LCBhbmQgY29weQoqICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdHJ1Y3RvciBhbmQgZ2V0RHluYW1pY0NsYXNzSUQuCiogIDMvNS85NyAgICAgIGFsaXUgICAgICAgIE1vZGlmaWVkIGNvbnN0cnVjdEZyb21GaWxlKCkgdG8gYWRkIHBhcmFtZXRlcgoqICAgICAgICAgICAgICAgICAgICAgICAgICBzcGVjaWZ5aW5nIHdoZXRoZXIgb3Igbm90IGJpbmFyeSBsb2FkaW5nIGlzIHRvIGJlCiogICAgICAgICAgICAgICAgICAgICAgICAgIGF0dGVtcHRlZC4gIFRoaXMgaXMgcmVxdWlyZWQgZm9yIGR5bmFtaWMgcnVsZSBsb2FkaW5nLgoqIDA1LzA3Lzk3ICAgICBoZWxlbmEgICAgICBBZGRlZCBtZW1vcnkgYWxsb2NhdGlvbiBlcnJvciBkZXRlY3Rpb24uCiogIDYvMTcvOTcgICAgIGhlbGVuYSAgICAgIEFkZGVkIElERU5USUNBTCBzdHJlbmd0aCBmb3IgY29tcGFyZSwgY2hhbmdlZCBnZXRSdWxlcyB0bwoqICAgICAgICAgICAgICAgICAgICAgICAgICB1c2UgTWVyZ2VDb2xsYXRpb246OmdldFBhdHRlcm4uCiogIDYvMjAvOTcgICAgIGhlbGVuYSAgICAgIEphdmEgY2xhc3MgbmFtZSBjaGFuZ2UuCiogIDgvMTgvOTcgICAgIGhlbGVuYSAgICAgIEFkZGVkIGludGVybmFsIEFQSSBkb2N1bWVudGF0aW9uLgoqIDA5LzAzLzk3ICAgICBoZWxlbmEgICAgICBBZGRlZCBjcmVhdGVDb2xsYXRpb25LZXlWYWx1ZXMoKS4KKiAwMi8xMC85OCAgICAgZGFtaWJhICAgICAgQWRkZWQgY29tcGFyZSB3aXRoICJsZW5ndGgiIHBhcmFtZXRlcgoqIDA4LzA1Lzk4ICAgICBlcm0gICAgICAgICBTeW5jaGVkIHdpdGggMS4yIHZlcnNpb24gb2YgUnVsZUJhc2VkQ29sbGF0b3IuamF2YQoqIDA0LzIzLzk5ICAgICBzdGVwaGVuICAgICBSZW1vdmVkIEVEZWNvbXBvc2l0aW9uTW9kZSwgbWVyZ2VkIHdpdGgKKiAgICAgICAgICAgICAgICAgICAgICAgICAgTm9ybWFsaXplcjo6RU1vZGUKKiAwNi8xNC85OSAgICAgc3RlcGhlbiAgICAgUmVtb3ZlZCBrUmVzb3VyY2VCdW5kbGVTdWZmaXgKKiAxMS8wMi85OSAgICAgaGVsZW5hICAgICAgQ29sbGF0b3IgcGVyZm9ybWFuY2UgZW5oYW5jZW1lbnRzLiAgRWxpbWluYXRlcyB0aGUKKiAgICAgICAgICAgICAgICAgICAgICAgICAgVW5pY29kZVN0cmluZyBjb25zdHJ1Y3Rpb24gYW5kIHNwZWNpYWwgY2FzZSBmb3IgTk9fT1AuCiogMTEvMjMvOTkgICAgIHNybCAgICAgICAgIE1vcmUgcGVyZm9ybWFuY2UgZW5oYW5jZW1lbnRzLiBVcGRhdGVzIHRvIE5vcm1hbGl6ZXJJdGVyYXRvcgoqICAgICAgICAgICAgICAgICAgICAgICAgICBpbnRlcm5hbCBzdGF0ZSBtYW5hZ2VtZW50LgoqIDEyLzE1Lzk5ICAgICBhbGl1ICAgICAgICBVcGRhdGUgdG8gc3VwcG9ydCBUaGFpIGNvbGxhdGlvbi4gIE1vdmUgTm9ybWFsaXplckl0ZXJhdG9yCiogICAgICAgICAgICAgICAgICAgICAgICAgIHRvIGltcGxlbWVudGF0aW9uIGZpbGUuCiogMDEvMjkvMDEgICAgIHN5bndlZSAgICAgIE1vZGlmaWVkIGludG8gYSBDKysgd3JhcHBlciB3aGljaCBjYWxscyBDIEFQSQoqICAgICAgICAgICAgICAgICAgICAgICAgICAodWNvbC5oKQoqLwoKI2lmbmRlZiBUQkxDT0xMX0gKI2RlZmluZSBUQkxDT0xMX0gKCiNpbmNsdWRlICJ1bmljb2RlL2NvbGwuaCIKI2luY2x1ZGUgInVuaWNvZGUvc29ydGtleS5oIgojaW5jbHVkZSAidW5pY29kZS9ub3JtbHpyLmgiCgpVX05BTUVTUEFDRV9CRUdJTgoKY2xhc3MgUnVsZUJhc2VkQ29sbGF0b3JTdHJlYW1lcjsKY2xhc3MgU3RyaW5nU2VhcmNoOwpjbGFzcyBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I7CgovKioKICogVGhlIFJ1bGVCYXNlZENvbGxhdG9yIGNsYXNzIHByb3ZpZGVzIHRoZSBzaW1wbGUgaW1wbGVtZW50YXRpb24gb2YKICogQ29sbGF0b3IsIHVzaW5nIGRhdGEtZHJpdmVuIHRhYmxlcy4gVGhlIHVzZXIgY2FuIGNyZWF0ZSBhIGN1c3RvbWl6ZWQKICogdGFibGUtYmFzZWQgY29sbGF0aW9uLgogKiA8UD4KICogUnVsZUJhc2VkQ29sbGF0b3IgbWFwcyBjaGFyYWN0ZXJzIHRvIGNvbGxhdGlvbiBrZXlzLgogKiA8cD4KICogVGFibGUgQ29sbGF0aW9uIGhhcyB0aGUgZm9sbG93aW5nIHJlc3RyaWN0aW9ucyBmb3IgZWZmaWNpZW5jeSAob3RoZXIKICogc3ViY2xhc3NlcyBtYXkgYmUgdXNlZCBmb3IgbW9yZSBjb21wbGV4IGxhbmd1YWdlcykgOgogKiAgICAgICA8cD4xLiBJZiB0aGUgRnJlbmNoIHNlY29uZGFyeSBvcmRlcmluZyBpcyBzcGVjaWZpZWQgaW4gYSBjb2xsYXRpb24KICogICAgICAgICAgICAgb2JqZWN0LCBpdCBpcyBhcHBsaWVkIHRvIHRoZSB3aG9sZSBvYmplY3QuCiAqICAgICAgIDxwPjIuIEFsbCBub24tbWVudGlvbmVkIFVuaWNvZGUgY2hhcmFjdGVycyBhcmUgYXQgdGhlIGVuZCBvZiB0aGUKICogICAgICAgICAgICAgY29sbGF0aW9uIG9yZGVyLgogKiAgICAgICA8cD4zLiBQcml2YXRlIHVzZSBjaGFyYWN0ZXJzIGFyZSB0cmVhdGVkIGFzIGlkZW50aWNhbC4gIFRoZSBwcml2YXRlCiAqICAgICAgICAgICAgIHVzZSBhcmVhIGluIFVuaWNvZGUgaXMgMHhFODAwLTB4RjhGRi4KICogPHA+VGhlIGNvbGxhdGlvbiB0YWJsZSBpcyBjb21wb3NlZCBvZiBhIGxpc3Qgb2YgY29sbGF0aW9uIHJ1bGVzLCB3aGVyZSBlYWNoCiAqIHJ1bGUgaXMgb2YgdGhyZWUgZm9ybXM6CiAqIDxwcmU+CiAqIFxjb2RlCiAqICAgICA8bW9kaWZpZXIgPgogKiAgICAgPHJlbGF0aW9uID4gJmx0OyB0ZXh0LWFyZ3VtZW50ID4KICogICAgIDxyZXNldCA+ICZsdDsgdGV4dC1hcmd1bWVudCA+CiAqIFxlbmRjb2RlCiAqIDwvcHJlPgogKiBUaGUgZm9sbG93aW5nIGRlbW9uc3RyYXRlcyBob3cgdG8gY3JlYXRlIHlvdXIgb3duIGNvbGxhdGlvbiBydWxlczoKICogPFVMIFR5cGU9cm91bmQ+CiAqICAgIDxMST48c3Ryb25nPlRleHQgQXJndW1lbnQ8L3N0cm9uZz46IEEgdGV4dCBhcmd1bWVudCBpcyBhbnkgc2VxdWVuY2Ugb2YKICogICAgICAgIGNoYXJhY3RlcnMsIGV4Y2x1ZGluZyBzcGVjaWFsIGNoYXJhY3RlcnMgKHRoYXQgaXMsIHdoaXRlc3BhY2UKICogICAgICAgIGNoYXJhY3RlcnMgYW5kIHRoZSBjaGFyYWN0ZXJzIHVzZWQgaW4gbW9kaWZpZXIsIHJlbGF0aW9uIGFuZCByZXNldCkuCiAqICAgICAgICBJZiB0aG9zZSBjaGFyYWN0ZXJzIGFyZSBkZXNpcmVkLCB5b3UgY2FuIHB1dCB0aGVtIGluIHNpbmdsZSBxdW90ZXMKICogICAgICAgIChlLmcuIGFtcGVyc2FuZCA9PiAnJicpLjxQPgogKiAgICA8TEk+PHN0cm9uZz5Nb2RpZmllcjwvc3Ryb25nPjogVGhlcmUgaXMgYSBzaW5nbGUgbW9kaWZpZXIsCiAqICAgICAgICB3aGljaCBpcyB1c2VkIHRvIHNwZWNpZnkgdGhhdCBhbGwgc2Vjb25kYXJ5IGRpZmZlcmVuY2VzIGFyZQogKiAgICAgICAgc29ydGVkIGJhY2t3YXJkcy4KICogICAgICAgIDxwPidAJyA6IEluZGljYXRlcyB0aGF0IHNlY29uZGFyeSBkaWZmZXJlbmNlcywgc3VjaCBhcyBhY2NlbnRzLCBhcmUKICogICAgICAgICAgICAgICAgIHNvcnRlZCBiYWNrd2FyZHMsIGFzIGluIEZyZW5jaC48UD4KICogICAgPExJPjxzdHJvbmc+UmVsYXRpb248L3N0cm9uZz46IFRoZSByZWxhdGlvbnMgYXJlIHRoZSBmb2xsb3dpbmc6CiAqICAgICAgICA8VUwgVHlwZT1zcXVhcmU+CiAqICAgICAgICAgICAgPExJPicmbHQ7JyA6IEdyZWF0ZXIsIGFzIGEgbGV0dGVyIGRpZmZlcmVuY2UgKHByaW1hcnkpCiAqICAgICAgICAgICAgPExJPic7JyA6IEdyZWF0ZXIsIGFzIGFuIGFjY2VudCBkaWZmZXJlbmNlIChzZWNvbmRhcnkpCiAqICAgICAgICAgICAgPExJPicsJyA6IEdyZWF0ZXIsIGFzIGEgY2FzZSBkaWZmZXJlbmNlICh0ZXJ0aWFyeSkKICogICAgICAgICAgICA8TEk+Jz0nIDogRXF1YWwKICogICAgICAgIDwvVUw+PFA+CiAqICAgIDxMST48c3Ryb25nPlJlc2V0PC9zdHJvbmc+OiBUaGVyZSBpcyBhIHNpbmdsZSByZXNldCwKICogICAgICAgIHdoaWNoIGlzIHVzZWQgcHJpbWFyaWx5IGZvciBjb250cmFjdGlvbnMgYW5kIGV4cGFuc2lvbnMsIGJ1dCB3aGljaAogKiAgICAgICAgY2FuIGFsc28gYmUgdXNlZCB0byBhZGQgYSBtb2RpZmljYXRpb24gYXQgdGhlIGVuZCBvZiBhIHNldCBvZiBydWxlcy4KICogICAgICAgIDxwPicmJyA6IEluZGljYXRlcyB0aGF0IHRoZSBuZXh0IHJ1bGUgZm9sbG93cyB0aGUgcG9zaXRpb24gdG8gd2hlcmUKICogICAgICAgICAgICB0aGUgcmVzZXQgdGV4dC1hcmd1bWVudCB3b3VsZCBiZSBzb3J0ZWQuCiAqIDwvVUw+CiAqCiAqIDxwPgogKiBUaGlzIHNvdW5kcyBtb3JlIGNvbXBsaWNhdGVkIHRoYW4gaXQgaXMgaW4gcHJhY3RpY2UuIEZvciBleGFtcGxlLCB0aGUKICogZm9sbG93aW5nIGFyZSBlcXVpdmFsZW50IHdheXMgb2YgZXhwcmVzc2luZyB0aGUgc2FtZSB0aGluZzoKICogPHByZT4KICogXGNvZGUKICogICAgIGEgPCBiIDwgYwogKiAgICAgYSA8IGIgJiBiICA8IGMKICogICAgIGEgPCBjICYgYSAgPCBiCiAqIFxlbmRjb2RlCiAqIDwvcHJlPgogKiBOb3RpY2UgdGhhdCB0aGUgb3JkZXIgaXMgaW1wb3J0YW50LCBhcyB0aGUgc3Vic2VxdWVudCBpdGVtIGdvZXMgaW1tZWRpYXRlbHkKICogYWZ0ZXIgdGhlIHRleHQtYXJndW1lbnQuIFRoZSBmb2xsb3dpbmcgYXJlIG5vdCBlcXVpdmFsZW50OgogKiA8cHJlPgogKiBcY29kZQogKiAgICAgYSA8ICBiICYgYSAgPCBjCiAqICAgICBhIDwgIGMgJiBhICA8IGIKICogXGVuZGNvZGUKICogPC9wcmU+CiAqIEVpdGhlciB0aGUgdGV4dC1hcmd1bWVudCBtdXN0IGFscmVhZHkgYmUgcHJlc2VudCBpbiB0aGUgc2VxdWVuY2UsIG9yIHNvbWUKICogaW5pdGlhbCBzdWJzdHJpbmcgb2YgdGhlIHRleHQtYXJndW1lbnQgbXVzdCBiZSBwcmVzZW50LiAoZS5nLiAiYSAmbHQ7IGIgJgogKiBhZSAmbHQ7IGUiIGlzIHZhbGlkIHNpbmNlICJhIiBpcyBwcmVzZW50IGluIHRoZSBzZXF1ZW5jZSBiZWZvcmUgImFlIiBpcwogKiByZXNldCkuIEluIHRoaXMgbGF0dGVyIGNhc2UsICJhZSIgaXMgbm90IGVudGVyZWQgYW5kIHRyZWF0ZWQgYXMgYSBzaW5nbGUKICogY2hhcmFjdGVyOyBpbnN0ZWFkLCAiZSIgaXMgc29ydGVkIGFzIGlmIGl0IHdlcmUgZXhwYW5kZWQgdG8gdHdvIGNoYXJhY3RlcnM6CiAqICJhIiBmb2xsb3dlZCBieSBhbiAiZSIuIFRoaXMgZGlmZmVyZW5jZSBhcHBlYXJzIGluIG5hdHVyYWwgbGFuZ3VhZ2VzOiBpbgogKiB0cmFkaXRpb25hbCBTcGFuaXNoICJjaCIgaXMgdHJlYXRlZCBhcyB0aG91Z2ggaXQgY29udHJhY3RzIHRvIGEgc2luZ2xlCiAqIGNoYXJhY3RlciAoZXhwcmVzc2VkIGFzICJjICZsdDsgY2ggJmx0OyBkIiksIHdoaWxlIGluIHRyYWRpdGlvbmFsIEdlcm1hbgogKiAi5CIgKGEtdW1sYXV0KSBpcyB0cmVhdGVkIGFzIHRob3VnaCBpdCBleHBhbmRzIHRvIHR3byBjaGFyYWN0ZXJzIChleHByZXNzZWQKICogYXMgImEgJiBhZSA7IOQgJmx0OyBiIikuCiAqIDxwPjxzdHJvbmc+SWdub3JhYmxlIENoYXJhY3RlcnM8L3N0cm9uZz4KICogPHA+Rm9yIGlnbm9yYWJsZSBjaGFyYWN0ZXJzLCB0aGUgZmlyc3QgcnVsZSBtdXN0IHN0YXJ0IHdpdGggYSByZWxhdGlvbiAodGhlCiAqIGV4YW1wbGVzIHdlIGhhdmUgdXNlZCBhYm92ZSBhcmUgcmVhbGx5IGZyYWdtZW50czsgImEgJmx0OyBiIiByZWFsbHkgc2hvdWxkCiAqIGJlICImbHQ7IGEgJmx0OyBiIikuIElmLCBob3dldmVyLCB0aGUgZmlyc3QgcmVsYXRpb24gaXMgbm90ICImbHQ7IiwgdGhlbgogKiBhbGwgdGhlIHRleHQtYXJndW1lbnRzIHVwIHRvIHRoZSBmaXJzdCAiJmx0OyIgYXJlIGlnbm9yYWJsZS4gRm9yIGV4YW1wbGUsCiAqICIsIC0gJmx0OyBhICZsdDsgYiIgbWFrZXMgIi0iIGFuIGlnbm9yYWJsZSBjaGFyYWN0ZXIsIGFzIHdlIHNhdyBlYXJsaWVyIGluCiAqIHRoZSB3b3JkICJibGFjay1iaXJkcyIuIEluIHRoZSBzYW1wbGVzIGZvciBkaWZmZXJlbnQgbGFuZ3VhZ2VzLCB5b3Ugc2VlCiAqIHRoYXQgbW9zdCBhY2NlbnRzIGFyZSBpZ25vcmFibGUuCiAqIDxwPjxzdHJvbmc+Tm9ybWFsaXphdGlvbiBhbmQgQWNjZW50czwvc3Ryb25nPgogKiA8cD5UaGUgQ29sbGF0b3Igb2JqZWN0IGF1dG9tYXRpY2FsbHkgbm9ybWFsaXplcyB0ZXh0IGludGVybmFsbHkgdG8KICogc2VwYXJhdGUgYWNjZW50cyBmcm9tIGJhc2UgY2hhcmFjdGVycyB3aGVyZSBwb3NzaWJsZS4gVGhpcyBpcyBkb25lIGJvdGgKICogd2hlbiBwcm9jZXNzaW5nIHRoZSBydWxlcywgYW5kIHdoZW4gY29tcGFyaW5nIHR3byBzdHJpbmdzLiBDb2xsYXRvciBhbHNvCiAqIHVzZXMgdGhlIFVuaWNvZGUgY2Fub25pY2FsIG1hcHBpbmcgdG8gZW5zdXJlIHRoYXQgY29tYmluaW5nIHNlcXVlbmNlcyBhcmUKICogc29ydGVkIHByb3Blcmx5IChmb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlCiAqIDxBIEhSRUY9Imh0dHA6Ly93d3cuYXcuY29tL2RldnByZXNzIj4gVGhlIFVuaWNvZGUgU3RhbmRhcmQsIFZlcnNpb24gMi4wPC9BPgogKiAuKTwvUD4KICogPHA+PHN0cm9uZz5FcnJvcnM8L3N0cm9uZz4KICogPHA+VGhlIGZvbGxvd2luZyBhcmUgZXJyb3JzOgogKiA8VUwgVHlwZT1yb3VuZD4KICogICAgIDxMST5BIHRleHQtYXJndW1lbnQgY29udGFpbnMgdW5xdW90ZWQgcHVuY3R1YXRpb24gc3ltYm9scwogKiAgICAgICAgKGUuZy4gImEgJmx0OyBiLWMgJmx0OyBkIikuCiAqICAgICA8TEk+QSByZWxhdGlvbiBvciByZXNldCBjaGFyYWN0ZXIgbm90IGZvbGxvd2VkIGJ5IGEgdGV4dC1hcmd1bWVudAogKiAgICAgICAgKGUuZy4gImEgJmx0OyAsIGIiKS4KICogICAgIDxMST5BIHJlc2V0IHdoZXJlIHRoZSB0ZXh0LWFyZ3VtZW50IChvciBhbiBpbml0aWFsIHN1YnN0cmluZyBvZiB0aGUKICogICAgICAgICB0ZXh0LWFyZ3VtZW50KSBpcyBub3QgYWxyZWFkeSBpbiB0aGUgc2VxdWVuY2UuCiAqICAgICAgICAgKGUuZy4gImEgJmx0OyBiICYgZSAmbHQ7IGYiKQogKiA8L1VMPgogKiA8cHJlPgogKiBcY29kZQogKiAgICAgRXhhbXBsZXM6CiAqICAgICBTaW1wbGU6ICAgICAiPCBhIDwgYiA8IGMgPCBkIgogKiAgICAgTm9yd2VnaWFuOiAgIjwgYSxBPCBiLEI8IGMsQzwgZCxEPCBlLEU8IGYsRjwgZyxHPCBoLEg8IGksSTwgaixKCiAqICAgICAgICAgICAgICAgICAgPCBrLEs8IGwsTDwgbSxNPCBuLE48IG8sTzwgcCxQPCBxLFE8IHIsUjwgcyxTPCB0LFQKICogICAgICAgICAgICAgICAgICA8IHUsVTwgdixWPCB3LFc8IHgsWDwgeSxZPCB6LFoKICogICAgICAgICAgICAgICAgICA8IOU9YbAsxT1BsAogKiAgICAgICAgICAgICAgICAgIDthYSxBQTwg5izGPCD4LNgiCiAqIFxlbmRjb2RlCiAqIDwvcHJlPgogKiA8cD5UbyBjcmVhdGUgYSB0YWJsZS1iYXNlZCBjb2xsYXRpb24gb2JqZWN0LCBzaW1wbHkgc3VwcGx5IHRoZSBjb2xsYXRpb24KICogcnVsZXMgdG8gdGhlIFJ1bGVCYXNlZENvbGxhdG9yIGNvbnRydWN0b3IuICBGb3IgZXhhbXBsZToKICogPHByZT4KICogXGNvZGUKICogICAgIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOwogKiAgICAgUnVsZUJhc2VkQ29sbGF0b3IgKm15U2ltcGxlID0KICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgUnVsZUJhc2VkQ29sbGF0b3IoU2ltcGxlLCBzdGF0dXMpOwogKiBcZW5kY29kZQogKiA8L3ByZT4KICogPHA+QW5vdGhlciBleGFtcGxlOgogKiA8cHJlPgogKiBcY29kZQogKiAgICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAqICAgICBSdWxlQmFzZWRDb2xsYXRvciAqbXlOb3J3ZWdpYW4gPQogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBSdWxlQmFzZWRDb2xsYXRvcihOb3J3ZWdpYW4sIHN0YXR1cyk7CiAqIFxlbmRjb2RlCiAqIDwvcHJlPgogKiBUbyBhZGQgcnVsZXMgb24gdG9wIG9mIGFuIGV4aXN0aW5nIHRhYmxlLCBzaW1wbHkgc3VwcGx5IHRoZSBvcmdpbmFsIHJ1bGVzCiAqIGFuZCBtb2RpZmljYXRpb25zIHRvIFJ1bGVCYXNlZENvbGxhdG9yIGNvbnN0cnVjdG9yLiAgRm9yIGV4YW1wbGUsCiAqIDxwcmU+CiAqIFxjb2RlCiAqICAgICAgVHJhZGl0aW9uYWwgU3BhbmlzaCAoZnJhZ21lbnQpOiAuLi4gJiBDIDwgY2ggLCBjSCAsIENoICwgQ0ggLi4uCiAqICAgICAgR2VybWFuIChmcmFnbWVudCkgOiAuLi48IHkgLCBZIDwgeiAsIFoKICogICAgICAgICAgICAgICAgICAgICAgICAgICYgQUUsIMQgJiBBRSwg5AogKiAgICAgICAgICAgICAgICAgICAgICAgICAgJiBPRSAsINYgJiBPRSwg9gogKiAgICAgICAgICAgICAgICAgICAgICAgICAgJiBVRSAsINwgJiBVRSwg/AogKiAgICAgIFN5bWJvbHMgKGZyYWdtZW50KTogLi4uPCB5LCBZIDwgeiAsIFoKICogICAgICAgICAgICAgICAgICAgICAgICAgICYgUXVlc3Rpb24tbWFyayA7ICc/JwogKiAgICAgICAgICAgICAgICAgICAgICAgICAgJiBBbXBlcnNhbmQgOyAnJicKICogICAgICAgICAgICAgICAgICAgICAgICAgICYgRG9sbGFyLXNpZ24gOyAnJCcKICogXGVuZGNvZGUKICogPC9wcmU+CiAqIDxwPlRvIGNyZWF0ZSBhIGNvbGxhdGlvbiBvYmplY3QgZm9yIHRyYWRpdGlvbmFsIFNwYW5pc2gsIHRoZSB1c2VyIGNhbiB0YWtlCiAqIHRoZSBFbmdsaXNoIGNvbGxhdGlvbiBydWxlcyBhbmQgYWRkIHRoZSBhZGRpdGlvbmFsIHJ1bGVzIHRvIHRoZSB0YWJsZS4KICogRm9yIGV4YW1wbGU6CiAqIDxwcmU+CiAqIFxjb2RlCiAqICAgICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAqICAgICAgVW5pY29kZVN0cmluZyBydWxlcyhERUZBVUxUUlVMRVMpOwogKiAgICAgIHJ1bGVzICs9ICImIEMgJmx0OyBjaCwgY0gsIENoLCBDSCI7CiAqICAgICAgUnVsZUJhc2VkQ29sbGF0b3IgKm15U3BhbmlzaCA9CiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBSdWxlQmFzZWRDb2xsYXRvcihydWxlcywgc3RhdHVzKTsKICogXGVuZGNvZGUKICogPC9wcmU+CiAqIDxwPkluIG9yZGVyIHRvIHNvcnQgc3ltYm9scyBpbiB0aGUgc2ltaWxpYXIgb3JkZXIgb2Ygc29ydGluZyB0aGVpcgogKiBhbHBoYWJldGljIGVxdWl2YWxlbnRzLCB5b3UgY2FuIGRvIHRoZSBmb2xsb3dpbmcsCiAqIDxwcmU+CiAqIFxjb2RlCiAqICAgICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAqICAgICAgVW5pY29kZVN0cmluZyBydWxlcyhERUZBVUxUUlVMRVMpOwogKiAgICAgIHJ1bGVzICs9ICImIFF1ZXN0aW9uLW1hcmsgOyAnPycgJiBBbXBlcnNhbmQgOyAnJicgJiBEb2xsYXItc2lnbiA7CiAqICAgICAgICAgICAgICAgJyQnICI7CiAqICAgICAgUnVsZUJhc2VkQ29sbGF0b3IgKm15VGFibGUgPQogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgUnVsZUJhc2VkQ29sbGF0b3IocnVsZXMsIHN0YXR1cyk7CiAqIFxlbmRjb2RlCiAqIDwvcHJlPgogKiA8cD5Bbm90aGVyIHdheSBvZiBjcmVhdGluZyB0aGUgdGFibGUtYmFzZWQgY29sbGF0aW9uIG9iamVjdCwgbXlTaW1wbGUsCiAqIGlzOgogKiA8cHJlPgogKiBcY29kZQogKiAgICAgIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOwogKiAgICAgIFJ1bGVCYXNlZENvbGxhdG9yICpteVNpbXBsZSA9IG5ldwogKiAgICAgICAgUnVsZUJhc2VkQ29sbGF0b3IoIiA8IGEgPCBiICYgYiA8IGMgJiBjIDwgZCIsIHN0YXR1cyk7CiAqIFxlbmRjb2RlCiAqIDwvcHJlPgogKiBPciwKICogPHByZT4KICogXGNvZGUKICogICAgICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKICogICAgICBSdWxlQmFzZWRDb2xsYXRvciAqbXlTaW1wbGUgPSBuZXcKICogICAgICAgICAgICBSdWxlQmFzZWRDb2xsYXRvcigiIDwgYSA8IGIgPCBkICYgYiA8IGMiLCBzdGF0dXMpOwogKiBcZW5kY29kZQogKiA8L3ByZT4KICogQmVjYXVzZSAiICZsdDsgYSAmbHQ7IGIgJmx0OyBjICZsdDsgZCIgaXMgdGhlIHNhbWUgYXMgImEgJmx0OyBiICZsdDsgZCAmIGIKICogICAgICAgICAgJmx0OyBjIiBvciAiJmx0OyBhICZsdDsgYiAmIGIgJmx0OyBjICYgYyAmbHQ7IGQiLgogKgogKiA8cD5UbyBjb21iaW5lIGNvbGxhdGlvbnMgZnJvbSB0d28gbG9jYWxlcywgKHdpdGhvdXQgZXJyb3IgaGFuZGxpbmcgZm9yCiAqIGNsYXJpdHkpCiAqIDxwcmU+CiAqIFxjb2RlCiAqICAgICAvLyBDcmVhdGUgYW4gZW5fVVMgQ29sbGF0b3Igb2JqZWN0CiAqICAgICBMb2NhbGUgbG9jYWxlX2VuX1VTKCJlbiIsICJVUyIsICIiKTsKICogICAgIFJ1bGVCYXNlZENvbGxhdG9yKiBlbl9VU0NvbGxhdG9yID0gKFJ1bGVCYXNlZENvbGxhdG9yKikKICogICAgICAgICBDb2xsYXRvcjo6Y3JlYXRlSW5zdGFuY2UoIGxvY2FsZV9lbl9VUywgc3VjY2VzcyApOwogKgogKiAgICAgLy8gQ3JlYXRlIGEgZGFfREsgQ29sbGF0b3Igb2JqZWN0CiAqICAgICBMb2NhbGUgbG9jYWxlX2RhX0RLKCJkYSIsICJESyIsICIiKTsKICogICAgIFJ1bGVCYXNlZENvbGxhdG9yKiBkYV9ES0NvbGxhdG9yID0gKFJ1bGVCYXNlZENvbGxhdG9yKikKICogICAgICAgICBDb2xsYXRvcjo6Y3JlYXRlSW5zdGFuY2UoIGxvY2FsZV9kYV9ESywgc3VjY2VzcyApOwogKgogKiAgICAgLy8gQ29tYmluZSB0aGUgdHdvCiAqICAgICAvLyBGaXJzdCwgZ2V0IHRoZSBjb2xsYXRpb24gcnVsZXMgZnJvbSBlbl9VU0NvbGxhdG9yCiAqICAgICBVbmljb2RlU3RyaW5nIHJ1bGVzID0gZW5fVVNDb2xsYXRvci0+Z2V0UnVsZXMoKTsKICogICAgIC8vIFNlY29uZCwgZ2V0IHRoZSBjb2xsYXRpb24gcnVsZXMgZnJvbSBkYV9ES0NvbGxhdG9yCiAqICAgICBydWxlcyArPSBkYV9ES0NvbGxhdG9yLT5nZXRSdWxlcygpOwogKiAgICAgUnVsZUJhc2VkQ29sbGF0b3IqIG5ld0NvbGxhdG9yID0KICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgUnVsZUJhc2VkQ29sbGF0b3IocnVsZXMsIHN1Y2Nlc3MpOwogKiAgICAgLy8gbmV3Q29sbGF0b3IgaGFzIHRoZSBjb21iaW5lZCBydWxlcwogKiBcZW5kY29kZQogKiA8L3ByZT4KICogPHA+QW5vdGhlciBtb3JlIGludGVyZXN0aW5nIGV4YW1wbGUgd291bGQgYmUgdG8gbWFrZSBjaGFuZ2VzIG9uIGFuIGV4aXN0aW5nCiAqIHRhYmxlIHRvIGNyZWF0ZSBhIG5ldyBjb2xsYXRpb24gb2JqZWN0LiAgRm9yIGV4YW1wbGUsIGFkZAogKiAiJiBDICZsdDsgY2gsIGNILCBDaCwgQ0giIHRvIHRoZSBlbl9VU0NvbGxhdGlvbiBvYmplY3QgdG8gY3JlYXRlIHlvdXIgb3duCiAqIEVuZ2xpc2ggY29sbGF0aW9uIG9iamVjdCwKICogPHByZT4KICogXGNvZGUKICogICAgIC8vIENyZWF0ZSBhIG5ldyBDb2xsYXRvciBvYmplY3Qgd2l0aCBhZGRpdGlvbmFsIHJ1bGVzCiAqICAgICBydWxlcyA9IGVuX1VTQ29sbGF0b3ItPmdldFJ1bGVzKCk7CiAqICAgICBydWxlcyArPSAiJiBDIDwgY2gsIGNILCBDaCwgQ0giOwogKiAgICAgUnVsZUJhc2VkQ29sbGF0b3IqIG15Q29sbGF0b3IgPQogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBSdWxlQmFzZWRDb2xsYXRvcihydWxlcywgc3VjY2Vzcyk7CiAqICAgICAvLyBteUNvbGxhdG9yIGNvbnRhaW5zIHRoZSBuZXcgcnVsZXMKICogXGVuZGNvZGUKICogPC9wcmU+CiAqCiAqIDxwPlRoZSBmb2xsb3dpbmcgZXhhbXBsZSBkZW1vbnN0cmF0ZXMgaG93IHRvIGNoYW5nZSB0aGUgb3JkZXIgb2YKICogbm9uLXNwYWNpbmcgYWNjZW50cywKICogPHByZT4KICogXGNvZGUKICogICAgICBVQ2hhciBjb250ZW50c1tdID0gewogKiAgICAgICAgICAnPScsIDB4MDMwMSwgJzsnLCAweDAzMDAsICc7JywgMHgwMzAyLAogKiAgICAgICAgICAnOycsIDB4MDMwOCwgJzsnLCAweDAzMjcsICcsJywgMHgwMzAzLCAgICAvLyBtYWluIGFjY2VudHMKICogICAgICAgICAgJzsnLCAweDAzMDQsICc7JywgMHgwMzA1LCAnOycsIDB4MDMwNiwgICAgLy8gbWFpbiBhY2NlbnRzCiAqICAgICAgICAgICc7JywgMHgwMzA3LCAnOycsIDB4MDMwOSwgJzsnLCAweDAzMEEsICAgIC8vIG1haW4gYWNjZW50cwogKiAgICAgICAgICAnOycsIDB4MDMwQiwgJzsnLCAweDAzMEMsICc7JywgMHgwMzBELCAgICAvLyBtYWluIGFjY2VudHMKICogICAgICAgICAgJzsnLCAweDAzMEUsICc7JywgMHgwMzBGLCAnOycsIDB4MDMxMCwgICAgLy8gbWFpbiBhY2NlbnRzCiAqICAgICAgICAgICc7JywgMHgwMzExLCAnOycsIDB4MDMxMiwgICAgICAgICAgICAgICAgIC8vIG1haW4gYWNjZW50cwogKiAgICAgICAgICAnPCcsICdhJywgJywnLCAnQScsICc7JywgJ2EnLCAnZScsICcsJywgJ0EnLCAnRScsCiAqICAgICAgICAgICc7JywgMHgwMGU2LCAnLCcsIDB4MDBjNiwgJzwnLCAnYicsICcsJywgJ0InLAogKiAgICAgICAgICAnPCcsICdjJywgJywnLCAnQycsICc8JywgJ2UnLCAnLCcsICdFJywgJyYnLAogKiAgICAgICAgICAnQycsICc8JywgJ2QnLCAnLCcsICdEJywgMCB9OwogKiAgICAgIFVuaWNvZGVTdHJpbmcgb2xkUnVsZXMoY29udGVudHMpOwogKiAgICAgIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOwogKiAgICAgIC8vIGNoYW5nZSB0aGUgb3JkZXIgb2YgYWNjZW50IGNoYXJhY3RlcnMKICogICAgICBVQ2hhciBhZGRPbltdID0geyAnJicsICcsJywgMHgwMzAwLCAnOycsIDB4MDMwOCwgJzsnLCAweDAzMDIsIDAgfTsKICogICAgICBvbGRSdWxlcyArPSBhZGRPbjsKICogICAgICBSdWxlQmFzZWRDb2xsYXRvciAqbXlDb2xsYXRpb24gPQogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgUnVsZUJhc2VkQ29sbGF0b3Iob2xkUnVsZXMsIHN0YXR1cyk7CiAqICBcZW5kY29kZQogKiA8L3ByZT4KICoKICogPHA+IFRoZSBsYXN0IGV4YW1wbGUgc2hvd3MgaG93IHRvIHB1dCBuZXcgcHJpbWFyeSBvcmRlcmluZyBpbiBiZWZvcmUgdGhlCiAqIGRlZmF1bHQgc2V0dGluZy4gRm9yIGV4YW1wbGUsIGluIEphcGFuZXNlIGNvbGxhdGlvbiwgeW91IGNhbiBlaXRoZXIgc29ydAogKiBFbmdsaXNoIGNoYXJhY3RlcnMgYmVmb3JlIG9yIGFmdGVyIEphcGFuZXNlIGNoYXJhY3RlcnMsCiAqIDxwcmU+CiAqIFxjb2RlCiAqICAgICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAqICAgICAgLy8gZ2V0IGVuX1VTIGNvbGxhdGlvbiBydWxlcwogKiAgICAgIFJ1bGVCYXNlZENvbGxhdG9yKiBlbl9VU0NvbGxhdGlvbiA9IChSdWxlQmFzZWRDb2xsYXRvciopCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb2xsYXRvcjo6Y3JlYXRlSW5zdGFuY2UoTG9jYWxlOjpVUywgc3RhdHVzKTsKICogICAgICAvLyBBbHdheXMgY2hlY2sgdGhlIGVycm9yIGNvZGUgYWZ0ZXIgZWFjaCBjYWxsLgogKiAgICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkgcmV0dXJuOwogKiAgICAgIC8vIGFkZCBhIGZldyBKYXBhbmVzZSBjaGFyYWN0ZXIgdG8gc29ydCBiZWZvcmUgRW5nbGlzaCBjaGFyYWN0ZXJzCiAqICAgICAgLy8gc3VwcG9zZSB0aGUgbGFzdCBjaGFyYWN0ZXIgYmVmb3JlIHRoZSBmaXJzdCBiYXNlIGxldHRlciAnYScgaW4KICogICAgICAvLyB0aGUgRW5nbGlzaCBjb2xsYXRpb24gcnVsZSBpcyAweDIyMTIKICogICAgICBVQ2hhciBqYVN0cmluZ1tdID0geycmJywgMHgyMjEyLCAnPCcsIDB4MzA0MSwgJywnLCAweDMwNDIsICc8JywKICogICAgICAgICAgICAgICAgICAgICAgICAgIDB4MzA0MywgJywnLCAweDMwNDQsIDB9OwogKiAgICAgIFVuaWNvZGVTdHJpbmcgcnVsZXMoZW5fVVNDb2xsYXRpb24tPmdldFJ1bGVzKCkpOwogKiAgICAgIHJ1bGVzICs9IGphU3RyaW5nOwogKiAgICAgIFJ1bGVCYXNlZENvbGxhdG9yICpteUphcGFuZXNlQ29sbGF0aW9uID0KICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFJ1bGVCYXNlZENvbGxhdG9yKHJ1bGVzLCBzdGF0dXMpOwogKiBcZW5kY29kZQogKiA8L3ByZT4KICogPHA+PHN0cm9uZz5OT1RFPC9zdHJvbmc+OiBUeXBpY2FsbHksIGEgY29sbGF0aW9uIG9iamVjdCBpcyBjcmVhdGVkIHdpdGgKICogQ29sbGF0b3I6OmNyZWF0ZUluc3RhbmNlKCkuCiAqIDxwPgogKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IDxjb2RlPlJ1bGVCYXNlZENvbGxhdG9yPC9jb2RlPnMgd2l0aCBkaWZmZXJlbnQKICogTG9jYWxlLCBDb2xsYXRpb25TdHJlbmd0aCBhbmQgRGVjb21wb3NpdGlvbiBtb2RlIHNldHRpbmdzIHdpbGwgcmV0dXJuCiAqIGRpZmZlcmVudCBzb3J0IG9yZGVycyBmb3IgdGhlIHNhbWUgc2V0IG9mIHN0cmluZ3MuIExvY2FsZXMgaGF2ZSBzcGVjaWZpYwogKiBjb2xsYXRpb24gcnVsZXMsIGFuZCB0aGUgd2F5IGluIHdoaWNoIHNlY29uZGFyeSBhbmQgdGVydGlhcnkgZGlmZmVyZW5jZXMKICogYXJlIHRha2VuIGludG8gYWNjb3VudCwgZm9yIGV4YW1wbGUsIHdpbGwgcmVzdWx0IGluIGEgZGlmZmVyZW50IHNvcnRpbmcKICogb3JkZXIgZm9yIHNhbWUgc3RyaW5ncy4KICogPHA+CiAqIEBzZWUgICAgICAgIENvbGxhdG9yCiAqIEB2ZXJzaW9uICAgIDEuOCBKYW4gOCAyMDAxCiAqLwpjbGFzcyBVX0kxOE5fQVBJIFJ1bGVCYXNlZENvbGxhdG9yIDogcHVibGljIENvbGxhdG9yCnsKcHVibGljOgoKICAvLyBjb25zdHJ1Y3RvciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogIC8qKgogICAqIFJ1bGVCYXNlZENvbGxhdG9yIGNvbnN0cnVjdG9yLiBUaGlzIHRha2VzIHRoZSB0YWJsZSBydWxlcyBhbmQgYnVpbGRzIGEKICAgKiBjb2xsYXRpb24gdGFibGUgb3V0IG9mIHRoZW0uIFBsZWFzZSBzZWUgUnVsZUJhc2VkQ29sbGF0b3IgY2xhc3MKICAgKiBkZXNjcmlwdGlvbiBmb3IgbW9yZSBkZXRhaWxzIG9uIHRoZSBjb2xsYXRpb24gcnVsZSBzeW50YXguCiAgICogQHBhcmFtIHJ1bGVzIHRoZSBjb2xsYXRpb24gcnVsZXMgdG8gYnVpbGQgdGhlIGNvbGxhdGlvbiB0YWJsZSBmcm9tLgogICAqIEBwYXJhbSBzdGF0dXMgcmVwb3J0aW5nIGEgc3VjY2VzcyBvciBhbiBlcnJvci4KICAgKiBAc2VlIExvY2FsZQogICAqLwogICAgUnVsZUJhc2VkQ29sbGF0b3IoY29uc3QgVW5pY29kZVN0cmluZyYgcnVsZXMsIFVFcnJvckNvZGUmIHN0YXR1cyk7CgogIC8qKgogICAqIFJ1bGVCYXNlZENvbGxhdG9yIGNvbnN0cnVjdG9yLiBUaGlzIHRha2VzIHRoZSB0YWJsZSBydWxlcyBhbmQgYnVpbGRzIGEKICAgKiBjb2xsYXRpb24gdGFibGUgb3V0IG9mIHRoZW0uIFBsZWFzZSBzZWUgUnVsZUJhc2VkQ29sbGF0b3IgY2xhc3MKICAgKiBkZXNjcmlwdGlvbiBmb3IgbW9yZSBkZXRhaWxzIG9uIHRoZSBjb2xsYXRpb24gcnVsZSBzeW50YXguCiAgICogQHBhcmFtIHJ1bGVzIHRoZSBjb2xsYXRpb24gcnVsZXMgdG8gYnVpbGQgdGhlIGNvbGxhdGlvbiB0YWJsZSBmcm9tLgogICAqIEBwYXJhbSBjb2xsYXRpb25TdHJlbmd0aCBkZWZhdWx0IHN0cmVuZ3RoIGZvciBjb21wYXJpc29uCiAgICogQHBhcmFtIHN0YXR1cyByZXBvcnRpbmcgYSBzdWNjZXNzIG9yIGFuIGVycm9yLgogICAqIEBzZWUgTG9jYWxlCiAgICovCiAgUnVsZUJhc2VkQ29sbGF0b3IoY29uc3QgVW5pY29kZVN0cmluZyYgcnVsZXMsCiAgICAgICAgICAgICAgICAgICAgICAgRUNvbGxhdGlvblN0cmVuZ3RoIGNvbGxhdGlvblN0cmVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cyk7CgogIC8qKgogICAqIFJ1bGVCYXNlZENvbGxhdG9yIGNvbnN0cnVjdG9yLiBUaGlzIHRha2VzIHRoZSB0YWJsZSBydWxlcyBhbmQgYnVpbGRzIGEKICAgKiBjb2xsYXRpb24gdGFibGUgb3V0IG9mIHRoZW0uIFBsZWFzZSBzZWUgUnVsZUJhc2VkQ29sbGF0b3IgY2xhc3MKICAgKiBkZXNjcmlwdGlvbiBmb3IgbW9yZSBkZXRhaWxzIG9uIHRoZSBjb2xsYXRpb24gcnVsZSBzeW50YXguCiAgICogQHBhcmFtIHJ1bGVzIHRoZSBjb2xsYXRpb24gcnVsZXMgdG8gYnVpbGQgdGhlIGNvbGxhdGlvbiB0YWJsZSBmcm9tLgogICAqIEBwYXJhbSBkZWNvbXBvc2l0aW9uTW9kZSB0aGUgbm9ybWFsaXNhdGlvbiBtb2RlCiAgICogQHBhcmFtIHN0YXR1cyByZXBvcnRpbmcgYSBzdWNjZXNzIG9yIGFuIGVycm9yLgogICAqIEBzZWUgTG9jYWxlCiAgICovCiAgUnVsZUJhc2VkQ29sbGF0b3IoY29uc3QgVW5pY29kZVN0cmluZyYgcnVsZXMsCiAgICAgICAgICAgICAgICAgICAgVUNvbEF0dHJpYnV0ZVZhbHVlIGRlY29tcG9zaXRpb25Nb2RlLAogICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cyk7CgogIC8qKgogICAqIFJ1bGVCYXNlZENvbGxhdG9yIGNvbnN0cnVjdG9yLiBUaGlzIHRha2VzIHRoZSB0YWJsZSBydWxlcyBhbmQgYnVpbGRzIGEKICAgKiBjb2xsYXRpb24gdGFibGUgb3V0IG9mIHRoZW0uIFBsZWFzZSBzZWUgUnVsZUJhc2VkQ29sbGF0b3IgY2xhc3MKICAgKiBkZXNjcmlwdGlvbiBmb3IgbW9yZSBkZXRhaWxzIG9uIHRoZSBjb2xsYXRpb24gcnVsZSBzeW50YXguCiAgICogQHBhcmFtIHJ1bGVzIHRoZSBjb2xsYXRpb24gcnVsZXMgdG8gYnVpbGQgdGhlIGNvbGxhdGlvbiB0YWJsZSBmcm9tLgogICAqIEBwYXJhbSBjb2xsYXRpb25TdHJlbmd0aCBkZWZhdWx0IHN0cmVuZ3RoIGZvciBjb21wYXJpc29uCiAgICogQHBhcmFtIGRlY29tcG9zaXRpb25Nb2RlIHRoZSBub3JtYWxpc2F0aW9uIG1vZGUKICAgKiBAcGFyYW0gc3RhdHVzIHJlcG9ydGluZyBhIHN1Y2Nlc3Mgb3IgYW4gZXJyb3IuCiAgICogQHNlZSBMb2NhbGUKICAgKi8KICBSdWxlQmFzZWRDb2xsYXRvcihjb25zdCBVbmljb2RlU3RyaW5nJiBydWxlcywKICAgICAgICAgICAgICAgICAgICBFQ29sbGF0aW9uU3RyZW5ndGggY29sbGF0aW9uU3RyZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgVUNvbEF0dHJpYnV0ZVZhbHVlIGRlY29tcG9zaXRpb25Nb2RlLAogICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cyk7CgogIC8qKgogICAqIENvcHkgY29uc3RydWN0b3IuCiAgICogQHBhcmFtIHRoZSBSdWxlQmFzZWRDb2xsYXRvciBvYmplY3QgdG8gYmUgY29waWVkCiAgICogQHNlZSBMb2NhbGUKICAgKi8KICAgIFJ1bGVCYXNlZENvbGxhdG9yKGNvbnN0IFJ1bGVCYXNlZENvbGxhdG9yJiBvdGhlcik7CgogIC8vIGRlc3RydWN0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgLyoqCiAgICogRGVzdHJ1Y3Rvci4KICAgKi8KICAgIHZpcnR1YWwgflJ1bGVCYXNlZENvbGxhdG9yKCk7CgogIC8vIHB1YmxpYyBtZXRob2RzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgLyoqCiAgICogQXNzaWdubWVudCBvcGVyYXRvci4KICAgKiBAcGFyYW0gb3RoZXIgb3RoZXIgUnVsZUJhc2VkQ29sbGF0b3Igb2JqZWN0IHRvIGNvbXBhcmUgd2l0aC4KICAgKi8KICAgIFJ1bGVCYXNlZENvbGxhdG9yJiBvcGVyYXRvcj0oY29uc3QgUnVsZUJhc2VkQ29sbGF0b3ImIG90aGVyKTsKCiAgLyoqCiAgICogUmV0dXJucyB0cnVlIGlmIGFyZ3VtZW50IGlzIHRoZSBzYW1lIGFzIHRoaXMgb2JqZWN0LgogICAqIEBwYXJhbSBvdGhlciBDb2xsYXRvciBvYmplY3QgdG8gYmUgY29tcGFyZWQuCiAgICogQHJldHVybiB0cnVlIGlmIGFyZ3VtZW50cyBpcyB0aGUgc2FtZSBhcyB0aGlzIG9iamVjdC4KICAgKi8KICB2aXJ0dWFsIFVCb29sIG9wZXJhdG9yPT0oY29uc3QgQ29sbGF0b3ImIG90aGVyKSBjb25zdDsKCiAgLyoqCiAgICogUmV0dXJucyB0cnVlIGlmIGFyZ3VtZW50IGlzIG5vdCB0aGUgc2FtZSBhcyB0aGlzIG9iamVjdC4KICAgKiBAcGFyYW0gb3RoZXIgQ29sbGF0b3Igb2JqZWN0IHRvIGJlIGNvbXBhcmVkCiAgICogQHJldHVybiByZXR1cm5zIHRydWUgaWYgYXJndW1lbnQgaXMgbm90IHRoZSBzYW1lIGFzIHRoaXMgb2JqZWN0LgogICAqLwogIHZpcnR1YWwgVUJvb2wgb3BlcmF0b3IhPShjb25zdCBDb2xsYXRvciYgb3RoZXIpIGNvbnN0OwoKICAvKioKICAgKiBNYWtlcyBhIGRlZXAgY29weSBvZiB0aGUgb2JqZWN0LgogICAqIFRoZSBjYWxsZXIgb3ducyB0aGUgcmV0dXJuZWQgb2JqZWN0LgogICAqIEByZXR1cm4gdGhlIGNsb25lZCBvYmplY3QuCiAgICovCiAgdmlydHVhbCBDb2xsYXRvciogY2xvbmUodm9pZCkgY29uc3Q7CgogIC8qKgogICAqIENyZWF0ZXMgYSBjb2xsYXRpb24gZWxlbWVudCBpdGVyYXRvciBmb3IgdGhlIHNvdXJjZSBzdHJpbmcuIFRoZSBjYWxsZXIgb2YKICAgKiB0aGlzIG1ldGhvZCBpcyByZXNwb25zaWJsZSBmb3IgdGhlIG1lbW9yeSBtYW5hZ2VtZW50IG9mIHRoZSByZXR1cm4KICAgKiBwb2ludGVyLgogICAqIEBwYXJhbSBzb3VyY2UgdGhlIHN0cmluZyBvdmVyIHdoaWNoIHRoZSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3Igd2lsbAogICAqICAgICAgICBpdGVyYXRlLgogICAqIEByZXR1cm4gdGhlIGNvbGxhdGlvbiBlbGVtZW50IGl0ZXJhdG9yIG9mIHRoZSBzb3VyY2Ugc3RyaW5nIHVzaW5nIHRoaXMgYXMKICAgKiAgICAgICAgIHRoZSBiYXNlZCBDb2xsYXRvci4KICAgKi8KICAgIHZpcnR1YWwgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKiBjcmVhdGVDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlU3RyaW5nJiBzb3VyY2UpIGNvbnN0OwoKICAvKioKICAgKiBDcmVhdGVzIGEgY29sbGF0aW9uIGVsZW1lbnQgaXRlcmF0b3IgZm9yIHRoZSBzb3VyY2UuIFRoZSBjYWxsZXIgb2YgdGhpcwogICAqIG1ldGhvZCBpcyByZXNwb25zaWJsZSBmb3IgdGhlIG1lbW9yeSBtYW5hZ2VtZW50IG9mIHRoZSByZXR1cm5lZCBwb2ludGVyLgogICAqIEBwYXJhbSBzb3VyY2UgdGhlIENoYXJhY3Rlckl0ZXJhdG9yIHdoaWNoIHByb2R1Y2VzIHRoZSBjaGFyYWN0ZXJzIG92ZXIKICAgKiAgICAgICAgd2hpY2ggdGhlIENvbGxhdGlvbkVsZW1lbnRJdGdlcmF0b3Igd2lsbCBpdGVyYXRlLgogICAqIEByZXR1cm4gdGhlIGNvbGxhdGlvbiBlbGVtZW50IGl0ZXJhdG9yIG9mIHRoZSBzb3VyY2UgdXNpbmcgdGhpcyBhcyB0aGUKICAgKiAgICAgICAgIGJhc2VkIENvbGxhdG9yLgogICAqLwogIHZpcnR1YWwgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKiBjcmVhdGVDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IENoYXJhY3Rlckl0ZXJhdG9yJiBzb3VyY2UpIGNvbnN0OwoKICAvKioKICAgKiBDb21wYXJlcyBhIHJhbmdlIG9mIGNoYXJhY3RlciBkYXRhIHN0b3JlZCBpbiB0d28gZGlmZmVyZW50IHN0cmluZ3MgYmFzZWQKICAgKiBvbiB0aGUgY29sbGF0aW9uIHJ1bGVzLiBSZXR1cm5zIGluZm9ybWF0aW9uIGFib3V0IHdoZXRoZXIgYSBzdHJpbmcgaXMKICAgKiBsZXNzIHRoYW4sIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byBhbm90aGVyIHN0cmluZyBpbiBhIGxhbmd1YWdlLgogICAqIFRoaXMgY2FuIGJlIG92ZXJyaWRlbiBpbiBhIHN1YmNsYXNzLgogICAqIEBwYXJhbSBzb3VyY2UgdGhlIHNvdXJjZSBzdHJpbmcuCiAgICogQHBhcmFtIHRhcmdldCB0aGUgdGFyZ2V0IHN0cmluZyB0byBiZSBjb21wYXJlZCB3aXRoIHRoZSBzb3VyY2Ugc3RyaW5nLgogICAqIEByZXR1cm4gdGhlIGNvbXBhcmlzb24gcmVzdWx0LiBHUkVBVEVSIGlmIHRoZSBzb3VyY2Ugc3RyaW5nIGlzIGdyZWF0ZXIKICAgKiAgICAgICAgIHRoYW4gdGhlIHRhcmdldCBzdHJpbmcsIExFU1MgaWYgdGhlIHNvdXJjZSBpcyBsZXNzIHRoYW4gdGhlCiAgICogICAgICAgICB0YXJnZXQuIE90aGVyd2lzZSwgcmV0dXJucyBFUVVBTC4KICAgKi8KICB2aXJ0dWFsIEVDb21wYXJpc29uUmVzdWx0IGNvbXBhcmUoY29uc3QgVW5pY29kZVN0cmluZyYgc291cmNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlU3RyaW5nJiB0YXJnZXQpIGNvbnN0OwoKCiAgLyoqCiAgICogQ29tcGFyZXMgYSByYW5nZSBvZiBjaGFyYWN0ZXIgZGF0YSBzdG9yZWQgaW4gdHdvIGRpZmZlcmVudCBzdHJpbmdzIGJhc2VkCiAgICogb24gdGhlIGNvbGxhdGlvbiBydWxlcyB1cCB0byB0aGUgc3BlY2lmaWVkIGxlbmd0aC4gUmV0dXJucyBpbmZvcm1hdGlvbgogICAqIGFib3V0IHdoZXRoZXIgYSBzdHJpbmcgaXMgbGVzcyB0aGFuLCBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gYW5vdGhlcgogICAqIHN0cmluZyBpbiBhIGxhbmd1YWdlLiBUaGlzIGNhbiBiZSBvdmVycmlkZW4gaW4gYSBzdWJjbGFzcy4KICAgKiBAcGFyYW0gc291cmNlIHRoZSBzb3VyY2Ugc3RyaW5nLgogICAqIEBwYXJhbSB0YXJnZXQgdGhlIHRhcmdldCBzdHJpbmcgdG8gYmUgY29tcGFyZWQgd2l0aCB0aGUgc291cmNlIHN0cmluZy4KICAgKiBAcGFyYW0gbGVuZ3RoIGNvbXBhcmVzIHVwIHRvIHRoZSBzcGVjaWZpZWQgbGVuZ3RoCiAgICogQHJldHVybiB0aGUgY29tcGFyaXNvbiByZXN1bHQuIEdSRUFURVIgaWYgdGhlIHNvdXJjZSBzdHJpbmcgaXMgZ3JlYXRlcgogICAqICAgICAgICAgdGhhbiB0aGUgdGFyZ2V0IHN0cmluZywgTEVTUyBpZiB0aGUgc291cmNlIGlzIGxlc3MgdGhhbiB0aGUKICAgKiAgICAgICAgIHRhcmdldC4gT3RoZXJ3aXNlLCByZXR1cm5zIEVRVUFMLgogICAqLwogIHZpcnR1YWwgRUNvbXBhcmlzb25SZXN1bHQgY29tcGFyZShjb25zdCBVbmljb2RlU3RyaW5nJiBzb3VyY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVuaWNvZGVTdHJpbmcmICB0YXJnZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QgbGVuZ3RoKSBjb25zdDsKCiAgLyoqCiAgICogVGhlIGNvbXBhcmlzb24gZnVuY3Rpb24gY29tcGFyZXMgdGhlIGNoYXJhY3RlciBkYXRhIHN0b3JlZCBpbiB0d28KICAgKiBkaWZmZXJlbnQgc3RyaW5nIGFycmF5cy4gUmV0dXJucyBpbmZvcm1hdGlvbiBhYm91dCB3aGV0aGVyIGEgc3RyaW5nIGFycmF5CiAgICogaXMgbGVzcyB0aGFuLCBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gYW5vdGhlciBzdHJpbmcgYXJyYXkuCiAgICogPHA+RXhhbXBsZSBvZiB1c2U6CiAgICogPHByZT4KICAgKiAuICAgICAgIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOwogICAqIC4gICAgICAgQ29sbGF0b3IgKm15Q29sbGF0aW9uID0KICAgKiAuICAgICAgICAgICAgICAgICAgICAgICAgIENvbGxhdG9yOjpjcmVhdGVJbnN0YW5jZShMb2NhbGU6OlVTLCBzdGF0dXMpOwogICAqIC4gICAgICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKSByZXR1cm47CiAgICogLiAgICAgICBteUNvbGxhdGlvbi0+c2V0U3RyZW5ndGgoQ29sbGF0b3I6OlBSSU1BUlkpOwogICAqIC4gICAgICAgLy8gcmVzdWx0IHdvdWxkIGJlIENvbGxhdG9yOjpFUVVBTCAoImFiYyIgPT0gIkFCQyIpCiAgICogLiAgICAgICAvLyAobm8gcHJpbWFyeSBkaWZmZXJlbmNlIGJldHdlZW4gImFiYyIgYW5kICJBQkMiKQogICAqIC4gICAgICAgQ29sbGF0b3I6OlVDb2xsYXRpb25SZXN1bHQgcmVzdWx0ID0KICAgKiAuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXlDb2xsYXRpb24tPmNvbXBhcmUoTCJhYmMiLCAzLCBMIkFCQyIsIDMpOwogICAqIC4gICAgICAgbXlDb2xsYXRpb24tPnNldFN0cmVuZ3RoKENvbGxhdG9yOjpURVJUSUFSWSk7CiAgICogLiAgICAgICAvLyByZXN1bHQgd291bGQgYmUgQ29sbGF0b3I6OkxFU1MgKGFiYyIgJmx0OyZsdDsmbHQ7ICJBQkMiKQogICAqIC4gICAgICAgLy8gKHdpdGggdGVydGlhcnkgZGlmZmVyZW5jZSBiZXR3ZWVuICJhYmMiIGFuZCAiQUJDIikKICAgKiAuICAgICAgIENvbGxhdG9yOjpVQ29sbGF0aW9uUmVzdWx0IHJlc3VsdCA9CiAgICogLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG15Q29sbGF0aW9uLT5jb21wYXJlKEwiYWJjIiwgMywgTCJBQkMiLCAzKTsKICAgKiA8L3ByZT4KICAgKiBAcGFyYW0gc291cmNlIHRoZSBzb3VyY2Ugc3RyaW5nIGFycmF5IHRvIGJlIGNvbXBhcmVkIHdpdGguCiAgICogQHBhcmFtIHNvdXJjZUxlbmd0aCB0aGUgbGVuZ3RoIG9mIHRoZSBzb3VyY2Ugc3RyaW5nIGFycmF5LiBJZiB0aGlzIHZhbHVlCiAgICogICAgICAgIGlzIGVxdWFsIHRvIC0xLCB0aGUgc3RyaW5nIGFycmF5IGlzIG51bGwtdGVybWluYXRlZC4KICAgKiBAcGFyYW0gdGFyZ2V0IHRoZSBzdHJpbmcgdGhhdCBpcyB0byBiZSBjb21wYXJlZCB3aXRoIHRoZSBzb3VyY2Ugc3RyaW5nLgogICAqIEBwYXJhbSB0YXJnZXRMZW5ndGggdGhlIGxlbmd0aCBvZiB0aGUgdGFyZ2V0IHN0cmluZyBhcnJheS4gSWYgdGhpcyB2YWx1ZQogICAqICAgICAgICBpcyBlcXVhbCB0byAtMSwgdGhlIHN0cmluZyBhcnJheSBpcyBudWxsLXRlcm1pbmF0ZWQuCiAgICogQHJldHVybiBSZXR1cm5zIGEgYnl0ZSB2YWx1ZS4gR1JFQVRFUiBpZiBzb3VyY2UgaXMgZ3JlYXRlciB0aGFuIHRhcmdldDsKICAgKiAgICAgICAgIEVRVUFMIGlmIHNvdXJjZSBpcyBlcXVhbCB0byB0YXJnZXQ7IExFU1MgaWYgc291cmNlIGlzIGxlc3MgdGhhbgogICAqICAgICAgICAgdGFyZ2V0CiAgICovCiAgdmlydHVhbCBFQ29tcGFyaXNvblJlc3VsdCBjb21wYXJlKGNvbnN0IFVDaGFyKiBzb3VyY2UsIGludDMyX3Qgc291cmNlTGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVQ2hhciogdGFyZ2V0LCBpbnQzMl90IHRhcmdldExlbmd0aCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Q7CgogIC8qKgogICogVHJhbnNmb3JtcyBhIHNwZWNpZmllZCByZWdpb24gb2YgdGhlIHN0cmluZyBpbnRvIGEgc2VyaWVzIG9mIGNoYXJhY3RlcnMKICAqIHRoYXQgY2FuIGJlIGNvbXBhcmVkIHdpdGggQ29sbGF0aW9uS2V5LmNvbXBhcmUuIFVzZSBhIENvbGxhdGlvbktleSB3aGVuCiAgKiB5b3UgbmVlZCB0byBkbyByZXBlYXRlZCBjb21wYXJpc2lvbnMgb24gdGhlIHNhbWUgc3RyaW5nLiBGb3IgYSBzaW5nbGUKICAqIGNvbXBhcmlzb24gdGhlIGNvbXBhcmUgbWV0aG9kIHdpbGwgYmUgZmFzdGVyLgogICogQHBhcmFtIHNvdXJjZSB0aGUgc291cmNlIHN0cmluZy4KICAqIEBwYXJhbSBrZXkgdGhlIHRyYW5zZm9ybWVkIGtleSBvZiB0aGUgc291cmNlIHN0cmluZy4KICAqIEBwYXJhbSBzdGF0dXMgdGhlIGVycm9yIGNvZGUgc3RhdHVzLgogICogQHJldHVybiB0aGUgdHJhbnNmb3JtZWQga2V5LgogICogQHNlZSBDb2xsYXRpb25LZXkKICAqLwogIHZpcnR1YWwgQ29sbGF0aW9uS2V5JiBnZXRDb2xsYXRpb25LZXkoY29uc3QgVW5pY29kZVN0cmluZyYgc291cmNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29sbGF0aW9uS2V5JiBrZXksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpIGNvbnN0OwoKICAvKioKICAqIFRyYW5zZm9ybXMgYSBzcGVjaWZpZWQgcmVnaW9uIG9mIHRoZSBzdHJpbmcgaW50byBhIHNlcmllcyBvZiBjaGFyYWN0ZXJzCiAgKiB0aGF0IGNhbiBiZSBjb21wYXJlZCB3aXRoIENvbGxhdGlvbktleS5jb21wYXJlLiBVc2UgYSBDb2xsYXRpb25LZXkgd2hlbgogICogeW91IG5lZWQgdG8gZG8gcmVwZWF0ZWQgY29tcGFyaXNpb25zIG9uIHRoZSBzYW1lIHN0cmluZy4gRm9yIGEgc2luZ2xlCiAgKiBjb21wYXJpc29uIHRoZSBjb21wYXJlIG1ldGhvZCB3aWxsIGJlIGZhc3Rlci4KICAqIEBwYXJhbSBzb3VyY2UgdGhlIHNvdXJjZSBzdHJpbmcuCiAgKiBAcGFyYW0ga2V5IHRoZSB0cmFuc2Zvcm1lZCBrZXkgb2YgdGhlIHNvdXJjZSBzdHJpbmcuCiAgKiBAcGFyYW0gc3RhdHVzIHRoZSBlcnJvciBjb2RlIHN0YXR1cy4KICAqIEByZXR1cm4gdGhlIHRyYW5zZm9ybWVkIGtleS4KICAqIEBzZWUgQ29sbGF0aW9uS2V5CiAgKi8KICB2aXJ0dWFsIENvbGxhdGlvbktleSYgZ2V0Q29sbGF0aW9uS2V5KGNvbnN0IFVDaGFyICpzb3VyY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IHNvdXJjZUxlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbGxhdGlvbktleSYga2V5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKSBjb25zdDsKCiAgLyoqCiAgICogR2VuZXJhdGVzIHRoZSBoYXNoIGNvZGUgZm9yIHRoZSBydWxlLWJhc2VkIGNvbGxhdGlvbiBvYmplY3QuCiAgICogQHJldHVybiB0aGUgaGFzaCBjb2RlLgogICAqLwogIHZpcnR1YWwgaW50MzJfdCBoYXNoQ29kZSh2b2lkKSBjb25zdDsKCiAgLyoqCiAgICogR2V0cyB0aGUgdGFibGUtYmFzZWQgcnVsZXMgZm9yIHRoZSBjb2xsYXRpb24gb2JqZWN0LgogICAqIEByZXR1cm4gcmV0dXJucyB0aGUgY29sbGF0aW9uIHJ1bGVzIHRoYXQgdGhlIHRhYmxlIGNvbGxhdGlvbiBvYmplY3Qgd2FzCiAgICogICAgICAgICBjcmVhdGVkIGZyb20uCiAgICovCiAgY29uc3QgVW5pY29kZVN0cmluZyYgZ2V0UnVsZXModm9pZCkgY29uc3Q7CgogIC8qKgogICAqIFJldHVybiB0aGUgbWF4aW11bSBsZW5ndGggb2YgYW55IGV4cGFuc2lvbiBzZXF1ZW5jZXMgdGhhdCBlbmQgd2l0aCB0aGUKICAgKiBzcGVjaWZpZWQgY29tcGFyaXNvbiBvcmRlci4KICAgKiBAcGFyYW0gb3JkZXIgYSBjb2xsYXRpb24gb3JkZXIgcmV0dXJuZWQgYnkgcHJldmlvdXMgb3IgbmV4dC4KICAgKiBAcmV0dXJuIG1heGltdW0gc2l6ZSBvZiB0aGUgZXhwYW5zaW9uIHNlcXVlbmNlcyBlbmRpbmcgd2l0aCB0aGUgY29sbGF0aW9uCiAgICogICAgICAgICBlbGVtZW50IG9yIDEgaWYgY29sbGF0aW9uIGVsZW1lbnQgZG9lcyBub3Qgb2NjdXIgYXQgdGhlIGVuZCBvZgogICAqICAgICAgICAgYW55IGV4cGFuc2lvbiBzZXF1ZW5jZQogICAqIEBzZWUgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yI2dldE1heEV4cGFuc2lvbgogICAqLwogICAgaW50MzJfdCBnZXRNYXhFeHBhbnNpb24oaW50MzJfdCBvcmRlcikgY29uc3Q7CgogIC8qKgogICAqIFJldHVybnMgYSB1bmlxdWUgY2xhc3MgSUQgUE9MWU1PUlBISUNBTExZLiBQdXJlIHZpcnR1YWwgb3ZlcnJpZGUuIFRoaXMKICAgKiBtZXRob2QgaXMgdG8gaW1wbGVtZW50IGEgc2ltcGxlIHZlcnNpb24gb2YgUlRUSSwgc2luY2Ugbm90IGFsbCBDKysKICAgKiBjb21waWxlcnMgc3VwcG9ydCBnZW51aW5lIFJUVEkuIFBvbHltb3JwaGljIG9wZXJhdG9yPT0oKSBhbmQgY2xvbmUoKQogICAqIG1ldGhvZHMgY2FsbCB0aGlzIG1ldGhvZC4KICAgKiBAcmV0dXJuIFRoZSBjbGFzcyBJRCBmb3IgdGhpcyBvYmplY3QuIEFsbCBvYmplY3RzIG9mIGEgZ2l2ZW4gY2xhc3MgaGF2ZQogICAqICAgICAgICAgdGhlIHNhbWUgY2xhc3MgSUQuIE9iamVjdHMgb2Ygb3RoZXIgY2xhc3NlcyBoYXZlIGRpZmZlcmVudCBjbGFzcwogICAqICAgICAgICAgSURzLgogICAqLwogIHZpcnR1YWwgVUNsYXNzSUQgZ2V0RHluYW1pY0NsYXNzSUQodm9pZCkgY29uc3QKICB7CiAgICByZXR1cm4gUnVsZUJhc2VkQ29sbGF0b3I6OmdldFN0YXRpY0NsYXNzSUQoKTsKICB9CgogIC8qKgogICAqIFJldHVybnMgdGhlIGNsYXNzIElEIGZvciB0aGlzIGNsYXNzLiBUaGlzIGlzIHVzZWZ1bCBvbmx5IGZvciBjb21wYXJpbmcgdG8KICAgKiBhIHJldHVybiB2YWx1ZSBmcm9tIGdldER5bmFtaWNDbGFzc0lEKCkuIEZvciBleGFtcGxlOgogICAqIDxwcmU+CiAgICogQmFzZSogcG9seW1vcnBoaWNfcG9pbnRlciA9IGNyZWF0ZVBvbHltb3JwaGljT2JqZWN0KCk7CiAgICogaWYgKHBvbHltb3JwaGljX3BvaW50ZXItPmdldER5bmFtaWNDbGFzc0lEKCkgPT0KICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERlcml2ZWQ6OmdldFN0YXRpY0NsYXNzSUQoKSkgLi4uCiAgICogPC9wcmU+CiAgICogQHJldHVybiBUaGUgY2xhc3MgSUQgZm9yIGFsbCBvYmplY3RzIG9mIHRoaXMgY2xhc3MuCiAgICovCiAgc3RhdGljIFVDbGFzc0lEIGdldFN0YXRpY0NsYXNzSUQodm9pZCkKICB7CiAgICByZXR1cm4gKFVDbGFzc0lEKSZmZ0NsYXNzSUQ7CiAgfQoKICAvKioKICAgKiBSZXR1cm5zIHRoZSBiaW5hcnkgZm9ybWF0IG9mIHRoZSBjbGFzcydzIHJ1bGVzLiBUaGUgZm9ybWF0IGlzIHRoYXQgb2YKICAgKiAuY29sIGZpbGVzLgogICAqIEBwYXJhbSBsZW5ndGggUmV0dXJucyB0aGUgbGVuZ3RoIG9mIHRoZSBkYXRhLCBpbiBieXRlcwogICAqIEBwYXJhbSBzdGF0dXMgdGhlIGVycm9yIGNvZGUgc3RhdHVzLgogICAqIEByZXR1cm4gbWVtb3J5LCBvd25lZCBieSB0aGUgY2FsbGVyLCBvZiBzaXplICdsZW5ndGgnIGJ5dGVzLgogICAqLwogIHVpbnQ4X3QgKmNsb25lUnVsZURhdGEoaW50MzJfdCAmbGVuZ3RoLCBVRXJyb3JDb2RlICZzdGF0dXMpOwoKICAgIC8qKgogICAgICogUmV0dXJucyBjdXJyZW50IHJ1bGVzLiBEZWx0YSBkZWZpbmVzIHdoZXRoZXIgZnVsbCBydWxlcyBhcmUgcmV0dXJuZWQgb3IKICAgICAqIGp1c3QgdGhlIHRhaWxvcmluZy4KICAgICAqIEBwYXJhbSBkZWx0YSBvbmUgb2YgVUNPTF9UQUlMT1JJTkdfT05MWSwgVUNPTF9GVUxMX1JVTEVTLgogICAgICogQHJldHVybiBVbmljb2RlU3RyaW5nIHdpdGggcnVsZXMKICAgICAqLwogICAgVW5pY29kZVN0cmluZyBnZXRSdWxlcyhVQ29sUnVsZU9wdGlvbiBkZWx0YSk7CgogIC8qKgogICAqIFVuaXZlcnNhbCBhdHRyaWJ1dGUgc2V0dGVyCiAgICogQHBhcmFtIGF0dHIgYXR0cmlidXRlIHR5cGUKICAgKiBAcGFyYW0gdmFsdWUgYXR0cmlidXRlIHZhbHVlCiAgICogQHBhcmFtIHN0YXR1cyB0byBpbmRpY2F0ZSB3aGV0aGVyIHRoZSBvcGVyYXRpb24gd2VudCBvbiBzbW9vdGhseSBvciB0aGVyZSB3ZXJlIGVycm9ycwogICAqLwogIHZpcnR1YWwgdm9pZCBzZXRBdHRyaWJ1dGUoVUNvbEF0dHJpYnV0ZSBhdHRyLCBVQ29sQXR0cmlidXRlVmFsdWUgdmFsdWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlICZzdGF0dXMpOwoKICAvKioKICAgKiBVbml2ZXJzYWwgYXR0cmlidXRlIGdldHRlci4KICAgKiBAcGFyYW0gYXR0ciBhdHRyaWJ1dGUgdHlwZQogICAqIEBwYXJhbSBzdGF0dXMgdG8gaW5kaWNhdGUgd2hldGhlciB0aGUgb3BlcmF0aW9uIHdlbnQgb24gc21vb3RobHkgb3IgdGhlcmUgd2VyZSBlcnJvcnMKICAgKiBAcmV0dXJuIGF0dHJpYnV0ZSB2YWx1ZQogICAqLwogIHZpcnR1YWwgVUNvbEF0dHJpYnV0ZVZhbHVlIGdldEF0dHJpYnV0ZShVQ29sQXR0cmlidXRlIGF0dHIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUgJnN0YXR1cyk7CgogIC8qKiAKICAgKiBTZXRzIHRoZSB2YXJpYWJsZSB0b3AgdG8gYSBjb2xsYXRpb24gZWxlbWVudCB2YWx1ZSBvZiBhIHN0cmluZyBzdXBwbGllZC4gCiAgICogQHBhcmFtIHZhclRvcCBvbmUgb3IgbW9yZSAoaWYgY29udHJhY3Rpb24pIFVDaGFycyB0byB3aGljaCB0aGUgdmFyaWFibGUgdG9wIHNob3VsZCBiZSBzZXQKICAgKiBAcGFyYW0gbGVuIGxlbmd0aCBvZiB2YXJpYWJsZSB0b3Agc3RyaW5nLiBJZiAtMSBpdCBpcyBjb25zaWRlcmVkIHRvIGJlIHplcm8gdGVybWluYXRlZC4KICAgKiBAcGFyYW0gc3RhdHVzIGVycm9yIGNvZGUuIElmIGVycm9yIGNvZGUgaXMgc2V0LCB0aGUgcmV0dXJuIHZhbHVlIGlzIHVuZGVmaW5lZC4gRXJyb3JzIHNldCBieSB0aGlzIGZ1bmN0aW9uIGFyZTogPGJyPgogICAqICAgIFVfQ0VfTk9UX0ZPVU5EX0VSUk9SIGlmIG1vcmUgdGhhbiBvbmUgY2hhcmFjdGVyIHdhcyBwYXNzZWQgYW5kIHRoZXJlIGlzIG5vIHN1Y2ggYSBjb250cmFjdGlvbjxicj4KICAgKiAgICBVX1BSSU1BUllfVE9PX0xPTkdfRVJST1IgaWYgdGhlIHByaW1hcnkgZm9yIHRoZSB2YXJpYWJsZSB0b3AgaGFzIG1vcmUgdGhhbiB0d28gYnl0ZXMKICAgKiBAcmV0dXJuIGEgMzIgYml0IHZhbHVlIGNvbnRhaW5pbmcgdGhlIHZhbHVlIG9mIHRoZSB2YXJpYWJsZSB0b3AgaW4gdXBwZXIgMTYgYml0cy4gTG93ZXIgMTYgYml0cyBhcmUgdW5kZWZpbmVkCiAgICogQGRyYWZ0CiAgICovCiAgdmlydHVhbCB1aW50MzJfdCBzZXRWYXJpYWJsZVRvcChjb25zdCBVQ2hhciAqdmFyVG9wLCBpbnQzMl90IGxlbiwgVUVycm9yQ29kZSAmc3RhdHVzKTsKCiAgLyoqIAogICAqIFNldHMgdGhlIHZhcmlhYmxlIHRvcCB0byBhIGNvbGxhdGlvbiBlbGVtZW50IHZhbHVlIG9mIGEgc3RyaW5nIHN1cHBsaWVkLiAKICAgKiBAcGFyYW0gdmFyVG9wIGFuIFVuaWNvZGVTdHJpbmcgc2l6ZSAxIG9yIG1vcmUgKGlmIGNvbnRyYWN0aW9uKSBvZiBVQ2hhcnMgdG8gd2hpY2ggdGhlIHZhcmlhYmxlIHRvcCBzaG91bGQgYmUgc2V0CiAgICogQHBhcmFtIHN0YXR1cyBlcnJvciBjb2RlLiBJZiBlcnJvciBjb2RlIGlzIHNldCwgdGhlIHJldHVybiB2YWx1ZSBpcyB1bmRlZmluZWQuIEVycm9ycyBzZXQgYnkgdGhpcyBmdW5jdGlvbiBhcmU6IDxicj4KICAgKiAgICBVX0NFX05PVF9GT1VORF9FUlJPUiBpZiBtb3JlIHRoYW4gb25lIGNoYXJhY3RlciB3YXMgcGFzc2VkIGFuZCB0aGVyZSBpcyBubyBzdWNoIGEgY29udHJhY3Rpb248YnI+CiAgICogICAgVV9QUklNQVJZX1RPT19MT05HX0VSUk9SIGlmIHRoZSBwcmltYXJ5IGZvciB0aGUgdmFyaWFibGUgdG9wIGhhcyBtb3JlIHRoYW4gdHdvIGJ5dGVzCiAgICogQHJldHVybiBhIDMyIGJpdCB2YWx1ZSBjb250YWluaW5nIHRoZSB2YWx1ZSBvZiB0aGUgdmFyaWFibGUgdG9wIGluIHVwcGVyIDE2IGJpdHMuIExvd2VyIDE2IGJpdHMgYXJlIHVuZGVmaW5lZAogICAqIEBkcmFmdAogICAqLwogIHZpcnR1YWwgdWludDMyX3Qgc2V0VmFyaWFibGVUb3AoY29uc3QgVW5pY29kZVN0cmluZyB2YXJUb3AsIFVFcnJvckNvZGUgJnN0YXR1cyk7CgogIC8qKiAKICAgKiBTZXRzIHRoZSB2YXJpYWJsZSB0b3AgdG8gYSBjb2xsYXRpb24gZWxlbWVudCB2YWx1ZSBzdXBwbGllZC4gVmFyaWFibGUgdG9wIGlzIHNldCB0byB0aGUgdXBwZXIgMTYgYml0cy4gCiAgICogTG93ZXIgMTYgYml0cyBhcmUgaWdub3JlZC4KICAgKiBAcGFyYW0gdmFyVG9wIENFIHZhbHVlLCBhcyByZXR1cm5lZCBieSBzZXRWYXJpYWJsZVRvcCBvciB1Y29sKWdldFZhcmlhYmxlVG9wCiAgICogQHBhcmFtIHN0YXR1cyBlcnJvciBjb2RlIChub3QgY2hhbmdlZCBieSBmdW5jdGlvbikKICAgKiBAZHJhZnQKICAgKi8KICB2aXJ0dWFsIHZvaWQgc2V0VmFyaWFibGVUb3AoY29uc3QgdWludDMyX3QgdmFyVG9wLCBVRXJyb3JDb2RlICZzdGF0dXMpOwoKICAvKiogCiAgICogR2V0cyB0aGUgdmFyaWFibGUgdG9wIHZhbHVlIG9mIGEgQ29sbGF0b3IuIAogICAqIExvd2VyIDE2IGJpdHMgYXJlIHVuZGVmaW5lZCBhbmQgc2hvdWxkIGJlIGlnbm9yZWQuCiAgICogQHBhcmFtIHN0YXR1cyBlcnJvciBjb2RlIChub3QgY2hhbmdlZCBieSBmdW5jdGlvbikuIElmIGVycm9yIGNvZGUgaXMgc2V0LCB0aGUgcmV0dXJuIHZhbHVlIGlzIHVuZGVmaW5lZC4KICAgKiBAZHJhZnQKICAgKi8KICB2aXJ0dWFsIHVpbnQzMl90IGdldFZhcmlhYmxlVG9wKFVFcnJvckNvZGUgJnN0YXR1cykgY29uc3Q7CgogIC8qKgogICAqIFRocmVhZCBzYWZlIGNsb25pbmcgb3BlcmF0aW9uLgogICAqIEByZXR1cm4gcG9pbnRlciB0byB0aGUgbmV3IGNsb25lLCB1c2VyIHNob3VsZCByZW1vdmUgaXQuCiAgICovCiAgdmlydHVhbCBDb2xsYXRvciogc2FmZUNsb25lKHZvaWQpOwoKICAvKioKICAgKiBHZXQgdGhlIHNvcnQga2V5IGFzIGFuIGFycmF5IG9mIGJ5dGVzIGZyb20gYW4gVW5pY29kZVN0cmluZy4KICAgKiBAcGFyYW0gc291cmNlIHN0cmluZyB0byBiZSBwcm9jZXNzZWQuCiAgICogQHBhcmFtIHJlc3VsdCBidWZmZXIgdG8gc3RvcmUgcmVzdWx0IGluLiBJZiBOVUxMLCBudW1iZXIgb2YgYnl0ZXMgbmVlZGVkCiAgICogICAgICAgIHdpbGwgYmUgcmV0dXJuZWQuCiAgICogQHBhcmFtIHJlc3VsdExlbmd0aCBsZW5ndGggb2YgdGhlIHJlc3VsdCBidWZmZXIuIElmIGlmIG5vdCBlbm91Z2ggdGhlCiAgICogICAgICAgIGJ1ZmZlciB3aWxsIGJlIGZpbGxlZCB0byBjYXBhY2l0eS4KICAgKiBAcmV0dXJuIE51bWJlciBvZiBieXRlcyBuZWVkZWQgZm9yIHN0b3JpbmcgdGhlIHNvcnQga2V5CiAgICovCiAgdmlydHVhbCBpbnQzMl90IGdldFNvcnRLZXkoY29uc3QgVW5pY29kZVN0cmluZyYgc291cmNlLCB1aW50OF90ICpyZXN1bHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCByZXN1bHRMZW5ndGgpIGNvbnN0OwoKICAvKioKICAgKiBHZXQgdGhlIHNvcnQga2V5IGFzIGFuIGFycmF5IG9mIGJ5dGVzIGZyb20gYW4gVUNoYXIgYnVmZmVyLgogICAqIEBwYXJhbSBzb3VyY2Ugc3RyaW5nIHRvIGJlIHByb2Nlc3NlZC4KICAgKiBAcGFyYW0gc291cmNlTGVuZ3RoIGxlbmd0aCBvZiBzdHJpbmcgdG8gYmUgcHJvY2Vzc2VkLiBJZiAtMSwgdGhlIHN0cmluZwogICAqICAgICAgICBpcyAwIHRlcm1pbmF0ZWQgYW5kIGxlbmd0aCB3aWxsIGJlIGRlY2lkZWQgYnkgdGhlIGZ1bmN0aW9uLgogICAqIEBwYXJhbSByZXN1bHQgYnVmZmVyIHRvIHN0b3JlIHJlc3VsdCBpbi4gSWYgTlVMTCwgbnVtYmVyIG9mIGJ5dGVzIG5lZWRlZAogICAqICAgICAgICB3aWxsIGJlIHJldHVybmVkLgogICAqIEBwYXJhbSByZXN1bHRMZW5ndGggbGVuZ3RoIG9mIHRoZSByZXN1bHQgYnVmZmVyLiBJZiBpZiBub3QgZW5vdWdoIHRoZQogICAqICAgICAgICBidWZmZXIgd2lsbCBiZSBmaWxsZWQgdG8gY2FwYWNpdHkuCiAgICogQHJldHVybiBOdW1iZXIgb2YgYnl0ZXMgbmVlZGVkIGZvciBzdG9yaW5nIHRoZSBzb3J0IGtleQogICAqLwogIHZpcnR1YWwgaW50MzJfdCBnZXRTb3J0S2V5KGNvbnN0IFVDaGFyICpzb3VyY2UsIGludDMyX3Qgc291cmNlTGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQ4X3QgKnJlc3VsdCwgaW50MzJfdCByZXN1bHRMZW5ndGgpIGNvbnN0OwoKICAvKioKICAqIERldGVybWluZXMgdGhlIG1pbmltdW0gc3RyZW5ndGggdGhhdCB3aWxsIGJlIHVzZSBpbiBjb21wYXJpc29uIG9yCiAgKiB0cmFuc2Zvcm1hdGlvbi4KICAqIDxwPkUuZy4gd2l0aCBzdHJlbmd0aCA9PSBTRUNPTkRBUlksIHRoZSB0ZXJ0aWFyeSBkaWZmZXJlbmNlIGlzIGlnbm9yZWQKICAqIDxwPkUuZy4gd2l0aCBzdHJlbmd0aCA9PSBQUklNQVJZLCB0aGUgc2Vjb25kYXJ5IGFuZCB0ZXJ0aWFyeSBkaWZmZXJlbmNlCiAgKiBhcmUgaWdub3JlZC4KICAqIEByZXR1cm4gdGhlIGN1cnJlbnQgY29tcGFyaXNvbiBsZXZlbC4KICAqIEBzZWUgUnVsZUJhc2VkQ29sbGF0b3Ijc2V0U3RyZW5ndGgKICAqLwogIHZpcnR1YWwgRUNvbGxhdGlvblN0cmVuZ3RoIGdldFN0cmVuZ3RoKHZvaWQpIGNvbnN0OwoKICAvKioKICAqIFNldHMgdGhlIG1pbmltdW0gc3RyZW5ndGggdG8gYmUgdXNlZCBpbiBjb21wYXJpc29uIG9yIHRyYW5zZm9ybWF0aW9uLgogICogPHA+RXhhbXBsZSBvZiB1c2U6CiAgKiA8cHJlPgogICogLiBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKICAqIC4gQ29sbGF0b3IqbXlDb2xsYXRpb24gPSBDb2xsYXRvcjo6Y3JlYXRlSW5zdGFuY2UoTG9jYWxlOjpVUywKICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzKTsKICAqIC4gaWYgKFVfRkFJTFVSRShzdGF0dXMpKSByZXR1cm47CiAgKiAuIG15Q29sbGF0aW9uLT5zZXRTdHJlbmd0aChDb2xsYXRvcjo6UFJJTUFSWSk7CiAgKiAuIC8vIHJlc3VsdCB3aWxsIGJlICJhYmMiID09ICJBQkMiCiAgKiAuIC8vIHRlcnRpYXJ5IGRpZmZlcmVuY2VzIHdpbGwgYmUgaWdub3JlZAogICogLiBDb2xsYXRvcjo6Q29tcGFyaXNvblJlc3VsdCByZXN1bHQgPSBteUNvbGxhdGlvbi0+Y29tcGFyZSgiYWJjIiwKICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkFCQyIpOwogICogPC9wcmU+CiAgKiBAc2VlIFJ1bGVCYXNlZENvbGxhdG9yI2dldFN0cmVuZ3RoCiAgKiBAcGFyYW0gbmV3U3RyZW5ndGggdGhlIG5ldyBjb21wYXJpc29uIGxldmVsLgogICogQHN0YWJsZQogICovCiAgdmlydHVhbCB2b2lkIHNldFN0cmVuZ3RoKEVDb2xsYXRpb25TdHJlbmd0aCBuZXdTdHJlbmd0aCk7CgogIC8vIGRlcHJlY2F0ZWQgZnVuY3Rpb25zIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAvKioKICAgKiBSdWxlQmFzZWRDb2xsYXRvciBjb25zdHJ1Y3Rvci4gVGhpcyB0YWtlcyB0aGUgdGFibGUgcnVsZXMgYW5kIGJ1aWxkcyBhCiAgICogY29sbGF0aW9uIHRhYmxlIG91dCBvZiB0aGVtLiBQbGVhc2Ugc2VlIFJ1bGVCYXNlZENvbGxhdG9yIGNsYXNzCiAgICogZGVzY3JpcHRpb24gZm9yIG1vcmUgZGV0YWlscyBvbiB0aGUgY29sbGF0aW9uIHJ1bGUgc3ludGF4LgogICAqIEBwYXJhbSBydWxlcyB0aGUgY29sbGF0aW9uIHJ1bGVzIHRvIGJ1aWxkIHRoZSBjb2xsYXRpb24gdGFibGUgZnJvbS4KICAgKiBAcGFyYW0gZGVjb21wb3NpdGlvbk1vZGUgdGhlIG5vcm1hbGlzYXRpb24gbW9kZQogICAqIEBwYXJhbSBzdGF0dXMgcmVwb3J0aW5nIGEgc3VjY2VzcyBvciBhbiBlcnJvci4KICAgKiBAc2VlIExvY2FsZQogICAqIEBkZXByZWNhdGVkIFRvIGJlIHJlbW92ZWQgYWZ0ZXIgMjAwMi1zZXAtMzAsIHNwZWNpZnkgdGhlIGRlY29tcG9zaXRpb24gbW9kZSB3aXRoIGEgVUNvbEF0dHJpYnV0ZVZhbHVlLgogICAqLwogIFJ1bGVCYXNlZENvbGxhdG9yKGNvbnN0IFVuaWNvZGVTdHJpbmcmIHJ1bGVzLAogICAgICAgICAgICAgICAgICAgIE5vcm1hbGl6ZXI6OkVNb2RlIGRlY29tcG9zaXRpb25Nb2RlLAogICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cyk7CgogIC8qKgogICAqIFJ1bGVCYXNlZENvbGxhdG9yIGNvbnN0cnVjdG9yLiBUaGlzIHRha2VzIHRoZSB0YWJsZSBydWxlcyBhbmQgYnVpbGRzIGEKICAgKiBjb2xsYXRpb24gdGFibGUgb3V0IG9mIHRoZW0uIFBsZWFzZSBzZWUgUnVsZUJhc2VkQ29sbGF0b3IgY2xhc3MKICAgKiBkZXNjcmlwdGlvbiBmb3IgbW9yZSBkZXRhaWxzIG9uIHRoZSBjb2xsYXRpb24gcnVsZSBzeW50YXguCiAgICogQHBhcmFtIHJ1bGVzIHRoZSBjb2xsYXRpb24gcnVsZXMgdG8gYnVpbGQgdGhlIGNvbGxhdGlvbiB0YWJsZSBmcm9tLgogICAqIEBwYXJhbSBjb2xsYXRpb25TdHJlbmd0aCBkZWZhdWx0IHN0cmVuZ3RoIGZvciBjb21wYXJpc29uCiAgICogQHBhcmFtIGRlY29tcG9zaXRpb25Nb2RlIHRoZSBub3JtYWxpc2F0aW9uIG1vZGUKICAgKiBAcGFyYW0gc3RhdHVzIHJlcG9ydGluZyBhIHN1Y2Nlc3Mgb3IgYW4gZXJyb3IuCiAgICogQHNlZSBMb2NhbGUKICAgKiBAZGVwcmVjYXRlZCBUbyBiZSByZW1vdmVkIGFmdGVyIDIwMDItc2VwLTMwLCBzcGVjaWZ5IHRoZSBkZWNvbXBvc2l0aW9uIG1vZGUgd2l0aCBhIFVDb2xBdHRyaWJ1dGVWYWx1ZS4KICAgKi8KICBSdWxlQmFzZWRDb2xsYXRvcihjb25zdCBVbmljb2RlU3RyaW5nJiBydWxlcywKICAgICAgICAgICAgICAgICAgICBFQ29sbGF0aW9uU3RyZW5ndGggY29sbGF0aW9uU3RyZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgTm9ybWFsaXplcjo6RU1vZGUgZGVjb21wb3NpdGlvbk1vZGUsCiAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKTsKCiAgLyoqCiAgKiBTZXQgdGhlIGRlY29tcG9zaXRpb24gbW9kZSBvZiB0aGUgQ29sbGF0b3Igb2JqZWN0LiBzdWNjZXNzIGlzIGVxdWFsIHRvCiAgKiBVX0lMTEVHQUxfQVJHVU1FTlRfRVJST1IgaWYgZXJyb3Igb2NjdXJzLgogICogQHBhcmFtIHRoZSBuZXcgZGVjb21wb3NpdGlvbiBtb2RlCiAgKiBAc2VlIENvbGxhdG9yI2dldERlY29tcG9zaXRpb24KICAqIEBkZXByZWNhdGVkIFRvIGJlIHJlbW92ZWQgYWZ0ZXIgMjAwMi1zZXAtMzA7IHVzZSBzZXRBdHRyaWJ1dGUoKS4KICAqLwogIHZpcnR1YWwgdm9pZCBzZXREZWNvbXBvc2l0aW9uKE5vcm1hbGl6ZXI6OkVNb2RlICBtb2RlKTsKCiAgLyoqCiAgKiBHZXQgdGhlIGRlY29tcG9zaXRpb24gbW9kZSBvZiB0aGUgQ29sbGF0b3Igb2JqZWN0LgogICogQHJldHVybiB0aGUgZGVjb21wb3NpdGlvbiBtb2RlCiAgKiBAc2VlIENvbGxhdG9yI3NldERlY29tcG9zaXRpb24KICAqIEBkZXByZWNhdGVkIFRvIGJlIHJlbW92ZWQgYWZ0ZXIgMjAwMi1zZXAtMzA7IHVzZSBnZXRBdHRyaWJ1dGUoKS4KICAqLwogIHZpcnR1YWwgTm9ybWFsaXplcjo6RU1vZGUgZ2V0RGVjb21wb3NpdGlvbih2b2lkKSBjb25zdDsKCnByaXZhdGU6CgogIC8vIHByaXZhdGUgc3RhdGljIGNvbnN0YW50cyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICBzdGF0aWMgY29uc3QgaW50MzJfdCBVTk1BUFBFRDsKICBzdGF0aWMgY29uc3QgaW50MzJfdCBDSEFSSU5ERVg7ICAvLyBuZWVkIGxvb2sgdXAgaW4gLmNvbW1pdCgpCiAgc3RhdGljIGNvbnN0IGludDMyX3QgRVhQQU5EQ0hBUklOREVYOyAvLyBFeHBhbmQgaW5kZXggZm9sbG93cwogIHN0YXRpYyBjb25zdCBpbnQzMl90IENPTlRSQUNUQ0hBUklOREVYOyAgLy8gY29udHJhY3QgaW5kZXhlcyBmb2xsb3cKCiAgc3RhdGljIGNvbnN0IGludDMyX3QgUFJJTUFSWU9SREVSSU5DUkVNRU5UOwogIHN0YXRpYyBjb25zdCBpbnQzMl90IFNFQ09OREFSWU9SREVSSU5DUkVNRU5UOwogIHN0YXRpYyBjb25zdCBpbnQzMl90IFRFUlRJQVJZT1JERVJJTkNSRU1FTlQ7CiAgc3RhdGljIGNvbnN0IGludDMyX3QgUFJJTUFSWU9SREVSTUFTSzsKICBzdGF0aWMgY29uc3QgaW50MzJfdCBTRUNPTkRBUllPUkRFUk1BU0s7CiAgc3RhdGljIGNvbnN0IGludDMyX3QgVEVSVElBUllPUkRFUk1BU0s7CiAgc3RhdGljIGNvbnN0IGludDMyX3QgSUdOT1JBQkxFTUFTSzsKICBzdGF0aWMgY29uc3QgaW50MzJfdCBQUklNQVJZRElGRkVSRU5DRU9OTFk7CiAgc3RhdGljIGNvbnN0IGludDMyX3QgU0VDT05EQVJZRElGRkVSRU5DRU9OTFk7CiAgc3RhdGljIGNvbnN0IGludDMyX3QgUFJJTUFSWU9SREVSU0hJRlQ7CiAgc3RhdGljIGNvbnN0IGludDMyX3QgU0VDT05EQVJZT1JERVJTSElGVDsKCiAgc3RhdGljIGNvbnN0IGludDMyX3QgQ09MRUxFTUVOVFNUQVJUOwogIHN0YXRpYyBjb25zdCBpbnQzMl90IFBSSU1BUllMT1daRVJPTUFTSzsKICBzdGF0aWMgY29uc3QgaW50MzJfdCBSRVNFVFNFQ09OREFSWVRFUlRJQVJZOwogIHN0YXRpYyBjb25zdCBpbnQzMl90IFJFU0VUVEVSVElBUlk7CgogIHN0YXRpYyBjb25zdCBpbnQzMl90IFBSSU1JR05PUkFCTEU7CgogIHN0YXRpYyBjb25zdCBpbnQxNl90IEZJTEVJRDsKICBzdGF0aWMgY29uc3QgY2hhciAgICBrRmlsZW5hbWVTdWZmaXhbXTsKCiAgLy8gcHJpdmF0ZSBzdGF0aWMgdmFyaWFibGVzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogIC8qKgogICogc3RhdGljIGNsYXNzIGlkCiAgKi8KICBzdGF0aWMgY29uc3QgY2hhciBmZ0NsYXNzSUQ7CgogIC8vIHByaXZhdGUgZGF0YSBtZW1iZXJzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICBVQm9vbCBkYXRhSXNPd25lZDsKCiAgLyoqCiAgKiBjIHN0cnVjdCBmb3IgY29sbGF0aW9uLiBBbGwgaW5pdGlhbGlzYXRpb24gZm9yIGl0IGhhcyB0byBiZSBkb25lIHRocm91Z2gKICAqIHNldFVDb2xsYXRvcigpLgogICovCiAgVUNvbGxhdG9yICp1Y29sbGF0b3I7CgogIC8qKgogICogUnVsZSBVbmljb2RlU3RyaW5nCiAgKi8KICBVbmljb2RlU3RyaW5nICp1cnVsZXN0cmluZzsKCiAgLy8gZnJpZW5kIGNsYXNzZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgLyoqCiAgKiBTdHJlYW1lciB1c2VkIHRvIHJlYWQvd3JpdGUgYmluYXJ5IGNvbGxhdGlvbiBkYXRhIGZpbGVzLgogICovCiAgZnJpZW5kIGNsYXNzIFJ1bGVCYXNlZENvbGxhdG9yU3RyZWFtZXI7CgogIC8qKgogICogVXNlZCB0byBpdGVyYXRlIG92ZXIgY29sbGF0aW9uIGVsZW1lbnRzIGluIGEgY2hhcmFjdGVyIHNvdXJjZS4KICAqLwogIGZyaWVuZCBjbGFzcyBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I7CgogIC8qKgogICogQ29sbGF0b3IgT05MWSBuZWVkcyBhY2Nlc3MgdG8gUnVsZUJhc2VkQ29sbGF0b3IoY29uc3QgTG9jYWxlJiwKICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmKQogICovCiAgZnJpZW5kIGNsYXNzIENvbGxhdG9yOwoKICAvKioKICAqIFNlYXJjaGluZyBvdmVyIGNvbGxhdGlvbiBlbGVtZW50cyBpbiBhIGNoYXJhY3RlciBzb3VyY2UKICAqLwogIGZyaWVuZCBjbGFzcyBTdHJpbmdTZWFyY2g7CgogIC8vIHByaXZhdGUgY29uc3RydWN0b3JzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogIC8qKgogICAqIERlZmF1bHQgY29uc3RydWN0b3IKICAgKi8KICBSdWxlQmFzZWRDb2xsYXRvcigpOwoKICAvKioKICAqIENvbnN0cnVjdG9yIHRoYXQgdGFrZXMgaW4gYSBVQ29sbGF0b3Igc3RydWN0CiAgKiBAcGFyYW0gY29sbGF0b3IgVUNvbGxhdG9yIHN0cnVjdAogICovCiAgUnVsZUJhc2VkQ29sbGF0b3IoVUNvbGxhdG9yICpjb2xsYXRvciwgVW5pY29kZVN0cmluZyAqcnVsZSk7CgogIC8qKgogICAqIFJ1bGVCYXNlZENvbGxhdG9yIGNvbnN0cnVjdG9yLiBUaGlzIGNvbnN0cnVjdG9yIHRha2VzIGEgbG9jYWxlLiBUaGUKICAgKiBvbmx5IGNhbGxlciBvZiB0aGlzIGNsYXNzIHNob3VsZCBiZSBDb2xsYXRvcjo6Y3JlYXRlSW5zdGFuY2UoKS4gSWYKICAgKiBjcmVhdGVJbnN0YW5jZSgpIGhhcHBlbnMgdG8ga25vdyB0aGF0IHRoZSByZXF1ZXN0ZWQgbG9jYWxlJ3MgY29sbGF0aW9uIGlzCiAgICogaW1wbGVtZW50ZWQgYXMgYSBSdWxlQmFzZWRDb2xsYXRvciwgaXQgY2FuIHRoZW4gY2FsbCB0aGlzIGNvbnN0cnVjdG9yLgogICAqIE9USEVSV0lTRSBJVCBTSE9VTEROJ1QsIHNpbmNlIHRoaXMgY29uc3RydWN0b3IgQUxXQVlTIFJFVFVSTlMgQSBWQUxJRAogICAqIENPTExBVElPTiBUQUJMRS4gSXQgZG9lcyB0aGlzIGJ5IGZhbGxpbmcgYmFjayB0byBkZWZhdWx0cy4KICAgKiBAcGFyYW0gZGVzaXJlZExvY2FsZSBsb2NhbGUgdXNlZAogICAqIEBwYXJhbSBzdGF0dXMgZXJyb3IgY29kZSBzdGF0dXMKICAgKi8KICBSdWxlQmFzZWRDb2xsYXRvcihjb25zdCBMb2NhbGUmIGRlc2lyZWRMb2NhbGUsIFVFcnJvckNvZGUmIHN0YXR1cyk7CgogIC8qKiBjb21tb24gY29uc3RydWN0b3IgaW1wbGVtZW50YXRpb24gKi8KICB2b2lkCiAgY29uc3RydWN0KGNvbnN0IFVuaWNvZGVTdHJpbmcmIHJ1bGVzLAogICAgICAgICAgICBVQ29sQXR0cmlidXRlVmFsdWUgY29sbGF0aW9uU3RyZW5ndGgsCiAgICAgICAgICAgIFVDb2xBdHRyaWJ1dGVWYWx1ZSBkZWNvbXBvc2l0aW9uTW9kZSwKICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKTsKCiAgLy8gcHJpdmF0ZSBtZXRob2RzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgLyoqCiAgKiBDcmVhdGVzIHRoZSBjIHN0cnVjdCBmb3IgdWNvbGxhdG9yCiAgKiBAcGFyYW0gbG9jYWxlIGRlc2lyZWQgbG9jYWxlCiAgKiBAcGFyYW0gc3RhdHVzIGVycm9yIHN0YXR1cwogICovCiAgdm9pZCBzZXRVQ29sbGF0b3IoY29uc3QgTG9jYWxlJiBsb2NhbGUsIFVFcnJvckNvZGUmIHN0YXR1cyk7CgogIC8qKgogICogQ3JlYXRlcyB0aGUgYyBzdHJ1Y3QgZm9yIHVjb2xsYXRvcgogICogQHBhcmFtIGxvY2FsZSBkZXNpcmVkIGxvY2FsZSBuYW1lCiAgKiBAcGFyYW0gc3RhdHVzIGVycm9yIHN0YXR1cwogICovCiAgdm9pZCBzZXRVQ29sbGF0b3IoY29uc3QgY2hhciogbG9jYWxlLCBVRXJyb3JDb2RlJiBzdGF0dXMpOwoKICAvKioKICAqIENyZWF0ZXMgdGhlIGMgc3RydWN0IGZvciB1Y29sbGF0b3IKICAqIEBwYXJhbSBjb2xsYXRvciBuZXcgdWNvbGxhdG9yIGRhdGEKICAqLwogIHZvaWQgc2V0VUNvbGxhdG9yKFVDb2xsYXRvciAqY29sbGF0b3IpOwoKICAvKioKICAqIENyZWF0ZXMgdGhlIGMgc3RydWN0IGZvciB1Y29sbGF0b3IuIFRoaXMgdXNlZCBpbnRlcm5hbGx5IGJ5IFN0cmluZ1NlYXJjaC4KICAqIEhlbmNlIHRoZSByZXNwb25zaWJpbGl0eSBvZiBjbGVhbmluZyB1cCB0aGUgdWNvbGxhdG9yIGlzIG5vdCBkb25lIGJ5CiAgKiB0aGlzIFJ1bGVCYXNlZENvbGxhdG9yLiBUaGUgaXNEYXRhT3duZWQgZmxhZyBpcyBzZXQgdG8gRkFMU0UuCiAgKiBAcGFyYW0gY29sbGF0b3IgbmV3IHVjb2xsYXRvciBkYXRhCiAgKiBAcGFyYW0gcnVsZXMgY29ycmVzcG9uZGluZyBjb2xsYXRpb24gcnVsZXMKICAqLwogIHZvaWQgc2V0VUNvbGxhdG9yKFVDb2xsYXRvciAqY29sbGF0b3IsIFVuaWNvZGVTdHJpbmcgKnJ1bGVzKTsKCiAgLyoqCiAgKiBHZXQgVUNvbGxhdG9yIGRhdGEgc3RydWN0LiBVc2VkIG9ubHkgYnkgU3RyaW5nU2VhcmNoLgogICogQHJldHVybiBVQ29sbGF0b3IgZGF0YSBzdHJ1Y3QKICAqLwogIGNvbnN0IFVDb2xsYXRvciAqIGdldFVDb2xsYXRvcigpOwoKICAvKioKICAqIENvbnZlcnRzIEMncyBVQ29sbGF0aW9uUmVzdWx0IHRvIEVDb21wYXJpc29uUmVzdWx0CiAgKiBAcGFyYW0gcmVzdWx0IG1lbWJlciBvZiB0aGUgZW51bSBVQ29tcGFyaXNvblJlc3VsdAogICogQHJldHVybiBFQ29tcGFyaXNvblJlc3VsdCBlcXVpdmFsZW50IG9mIFVDb2xsYXRpb25SZXN1bHQKICAqLwogIENvbGxhdG9yOjpFQ29tcGFyaXNvblJlc3VsdCBnZXRFQ29tcGFyaXNvblJlc3VsdCgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVUNvbGxhdGlvblJlc3VsdCAmcmVzdWx0KSBjb25zdDsKCiAgLyoqCiAgKiBDb252ZXJ0cyBDJ3MgVUNvbGxhdGlvblN0cmVuZ3RoIHRvIEVDb2xsYXRpb25TdHJlbmd0aAogICogQHBhcmFtIHN0cmVuZ3RoIG1lbWJlciBvZiB0aGUgZW51bSBVQ29sbGF0aW9uU3RyZW5ndGgKICAqIEByZXR1cm4gRUNvbGxhdGlvblN0cmVuZ3RoIGVxdWl2YWxlbnQgb2YgVUNvbGxhdGlvblN0cmVuZ3RoCiAgKi8KICBDb2xsYXRvcjo6RUNvbGxhdGlvblN0cmVuZ3RoIGdldEVDb2xsYXRpb25TdHJlbmd0aCgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVQ29sbGF0aW9uU3RyZW5ndGggJnN0cmVuZ3RoKSBjb25zdDsKCiAgLyoqCiAgKiBDb252ZXJ0cyBDKysncyBFQ29sbGF0aW9uU3RyZW5ndGggdG8gVUNvbGxhdGlvblN0cmVuZ3RoCiAgKiBAcGFyYW0gc3RyZW5ndGggbWVtYmVyIG9mIHRoZSBlbnVtIEVDb2xsYXRpb25TdHJlbmd0aAogICogQHJldHVybiBVQ29sbGF0aW9uU3RyZW5ndGggZXF1aXZhbGVudCBvZiBFQ29sbGF0aW9uU3RyZW5ndGgKICAqLwogIFVDb2xsYXRpb25TdHJlbmd0aCBnZXRVQ29sbGF0aW9uU3RyZW5ndGgoCiAgICBjb25zdCBDb2xsYXRvcjo6RUNvbGxhdGlvblN0cmVuZ3RoICZzdHJlbmd0aCkgY29uc3Q7Cn07CgovLyBpbmxpbmUgbWV0aG9kIGltcGxlbWVudGF0aW9uIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKaW5saW5lIFVCb29sIFJ1bGVCYXNlZENvbGxhdG9yOjpvcGVyYXRvciE9KGNvbnN0IENvbGxhdG9yJiBvdGhlcikgY29uc3QKewogIHJldHVybiAhKCp0aGlzID09IG90aGVyKTsKfQoKaW5saW5lIHZvaWQgUnVsZUJhc2VkQ29sbGF0b3I6OnNldFVDb2xsYXRvcihjb25zdCBjaGFyICpsb2NhbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSAmc3RhdHVzKQp7CiAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogICAgcmV0dXJuOwogIGlmICh1Y29sbGF0b3IgJiYgZGF0YUlzT3duZWQpCiAgICB1Y29sX2Nsb3NlKHVjb2xsYXRvcik7CiAgdWNvbGxhdG9yID0gdWNvbF9vcGVuKGxvY2FsZSwgJnN0YXR1cyk7Cn0KCmlubGluZSB2b2lkIFJ1bGVCYXNlZENvbGxhdG9yOjpzZXRVQ29sbGF0b3IoY29uc3QgTG9jYWxlICZsb2NhbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSAmc3RhdHVzKQp7CiAgc2V0VUNvbGxhdG9yKGxvY2FsZS5nZXROYW1lKCksIHN0YXR1cyk7Cn0KCmlubGluZSB2b2lkIFJ1bGVCYXNlZENvbGxhdG9yOjpzZXRVQ29sbGF0b3IoVUNvbGxhdG9yICpjb2xsYXRvcikKewogIGlmICh1Y29sbGF0b3IgJiYgZGF0YUlzT3duZWQpIHsKICAgIHVjb2xfY2xvc2UodWNvbGxhdG9yKTsKICB9CiAgdWNvbGxhdG9yID0gY29sbGF0b3I7Cn0KCmlubGluZSB2b2lkIFJ1bGVCYXNlZENvbGxhdG9yOjpzZXRVQ29sbGF0b3IoVUNvbGxhdG9yICAgICAqY29sbGF0b3IsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcgKnJ1bGVzKQp7CiAgICBpZiAodWNvbGxhdG9yICYmIGRhdGFJc093bmVkKSB7CiAgICAgICAgdWNvbF9jbG9zZSh1Y29sbGF0b3IpOwogICAgICAgIGRlbGV0ZSB1cnVsZXN0cmluZzsKICAgIH0KICAgIHVjb2xsYXRvciAgID0gY29sbGF0b3I7CiAgICB1cnVsZXN0cmluZyA9IHJ1bGVzOwogICAgZGF0YUlzT3duZWQgPSBGQUxTRTsKfQoKaW5saW5lIGNvbnN0IFVDb2xsYXRvciAqIFJ1bGVCYXNlZENvbGxhdG9yOjpnZXRVQ29sbGF0b3IoKQp7CiAgICByZXR1cm4gdWNvbGxhdG9yOwp9CgppbmxpbmUgQ29sbGF0b3I6OkVDb21wYXJpc29uUmVzdWx0IFJ1bGVCYXNlZENvbGxhdG9yOjpnZXRFQ29tcGFyaXNvblJlc3VsdCgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVDb2xsYXRpb25SZXN1bHQgJnJlc3VsdCkgY29uc3QKewogIHN3aXRjaCAocmVzdWx0KQogIHsKICBjYXNlIFVDT0xfTEVTUyA6CiAgICByZXR1cm4gQ29sbGF0b3I6OkxFU1M7CiAgY2FzZSBVQ09MX0VRVUFMIDoKICAgIHJldHVybiBDb2xsYXRvcjo6RVFVQUw7CiAgZGVmYXVsdCA6CiAgICByZXR1cm4gQ29sbGF0b3I6OkdSRUFURVI7CiAgfQp9CgppbmxpbmUgQ29sbGF0b3I6OkVDb2xsYXRpb25TdHJlbmd0aCBSdWxlQmFzZWRDb2xsYXRvcjo6Z2V0RUNvbGxhdGlvblN0cmVuZ3RoKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVQ29sbGF0aW9uU3RyZW5ndGggJnN0cmVuZ3RoKSBjb25zdAp7CiAgc3dpdGNoIChzdHJlbmd0aCkKICB7CiAgY2FzZSBVQ09MX1BSSU1BUlkgOgogICAgcmV0dXJuIENvbGxhdG9yOjpQUklNQVJZOwogIGNhc2UgVUNPTF9TRUNPTkRBUlkgOgogICAgcmV0dXJuIENvbGxhdG9yOjpTRUNPTkRBUlk7CiAgY2FzZSBVQ09MX1RFUlRJQVJZIDoKICAgIHJldHVybiBDb2xsYXRvcjo6VEVSVElBUlk7CiAgY2FzZSBVQ09MX1FVQVRFUk5BUlkgOgogICAgcmV0dXJuIENvbGxhdG9yOjpRVUFURVJOQVJZOyAgIAogIGRlZmF1bHQgOgogICAgcmV0dXJuIENvbGxhdG9yOjpJREVOVElDQUw7CiAgfQp9CgppbmxpbmUgVUNvbGxhdGlvblN0cmVuZ3RoIFJ1bGVCYXNlZENvbGxhdG9yOjpnZXRVQ29sbGF0aW9uU3RyZW5ndGgoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQ29sbGF0b3I6OkVDb2xsYXRpb25TdHJlbmd0aCAmc3RyZW5ndGgpIGNvbnN0CnsKICBzd2l0Y2ggKHN0cmVuZ3RoKQogIHsKICBjYXNlIENvbGxhdG9yOjpQUklNQVJZIDoKICAgIHJldHVybiBVQ09MX1BSSU1BUlk7CiAgY2FzZSBDb2xsYXRvcjo6U0VDT05EQVJZIDoKICAgIHJldHVybiBVQ09MX1NFQ09OREFSWTsKICBjYXNlIENvbGxhdG9yOjpURVJUSUFSWSA6CiAgICByZXR1cm4gVUNPTF9URVJUSUFSWTsKICBjYXNlIENvbGxhdG9yOjpRVUFURVJOQVJZIDoKICAgIHJldHVybiBVQ09MX1FVQVRFUk5BUlk7CiAgZGVmYXVsdCA6CiAgICByZXR1cm4gVUNPTF9JREVOVElDQUw7CiAgfQp9CgpVX05BTUVTUEFDRV9FTkQKCiNlbmRpZgo=