LyoKKiBDb3B5cmlnaHQgqSB7MTk5Ni0xOTk5fSwgSW50ZXJuYXRpb25hbCBCdXNpbmVzcyBNYWNoaW5lcyBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLiBBbGwgUmlnaHRzIFJlc2VydmVkLgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqLwovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8KLy8gRmlsZSB0YWJsZXMuaAovLwovLyAKLy8KLy8gQ3JlYXRlZCBieTogSGVsZW5hIFNoaWgKLy8KLy8gTW9kaWZpY2F0aW9uIEhpc3Rvcnk6Ci8vCi8vICBEYXRlICAgICAgICBOYW1lICAgICAgICBEZXNjcmlwdGlvbgovLyAgMi81Lzk3ICAgICAgYWxpdSAgICAgICAgQWRkZWQgc3RyZWFtSW4gYW5kIHN0cmVhbU91dCBtZXRob2RzIHRvIEVudHJ5UGFpciwKLy8gICAgICAgICAgICAgICAgICAgICAgICAgIFZlY3Rvck9mSW50LCBWZWN0b3JPZlBUb0V4cGFuZFRhYmxlLCBWZWN0b3JPZlBUb0NvbnRyYWN0RWxlbWVudCwKLy8gICAgICAgICAgICAgICAgICAgICAgICAgIFZlY3Rvck9mUFRvQ29udHJhY3RUYWJsZS4gIFRoZXNlIGFyZSB1c2VkIGJ5IFRhYmxlQ29sbGF0aW9uCi8vICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1JbiBhbmQgc3RyZWFtT3V0IG1ldGhvZHMuCi8vICAzLzUvOTcgICAgICBhbGl1ICAgICAgICBNYWRlIFZlY3Rvck9mUG9pbnRlcnNUb1BhdHRlcm5FbnRyeTo6YXQoKSBpbmxpbmUuCi8vICA1LzA3Lzk3ICAgICBoZWxlbmEgICAgICBBZGRlZCBpc0JvZ3VzKCkuCi8vICA2LzE4Lzk3ICAgICBoZWxlbmEgICAgICBBZGRlZCBWZWN0b3JPZlBvaW50ZXIgZm9yIHF1ZXVlLXVwIGV4dGVuc2lvbiBsaXN0IGluCi8vICAgICAgICAgICAgICAgICAgICAgICAgICBNZXJnZUNvbGxhdGlvbi4KLy8gIDgvMTgvOTcgICAgIGhlbGVuYSAgICAgIEFkZGVkIGludGVybmFsIEFQSSBkb2N1bWVudGF0aW9uLiAgTm90ZS4gQWxsIHRoZSBWZWN0b3JPZlhYWAovLyAgICAgICAgICAgICAgICAgICAgICAgICAgaW50ZXJmYWNlIGlzIGFib3V0IHRoZSBzYW1lLiAgVGhlIGludGVybmFsIEFQSSBkb2NzIHdpbGwgYmUKLy8gICAgICAgICAgICAgICAgICAgICAgICAgIGFkZGVkIHRvIG9ubHkgdGhlIGZpcnN0IHZlcnNpb24gYW5kIGFkZGl0aW9uYWwgZGVzY3JpcHRpb24KLy8gICAgICAgICAgICAgICAgICAgICAgICAgIHdpbGwgYmUgYWRkZWQgd2hlcmUgbmVjZXNzYXJ5LgovLyAgOC8wNC85OCAgICAgICAgZXJtICAgICAgICAgICAgQWRkZWQgZndkIG1lbWJlciB0byBFbnRyeVBhaXIuCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKI2lmbmRlZiBUQUJMRVNfSAojZGVmaW5lIFRBQkxFU19ICgoKI2luY2x1ZGUgImZpbGVzdHJtLmgiCiNpbmNsdWRlICJ1bWVtc3RybS5oIgojaW5jbHVkZSAidW5pY29kZS91bmlzdHIuaCIKI2luY2x1ZGUgInVuaWNvZGUvdXN0cmluZy5oIgoKLyoqCiAqIEVudHJ5UGFpciBpcyB1c2VkIGZvciBjb250cmFjdGluZyBjaGFyYWN0ZXJzLiAgRWFjaCBlbnRyeSBwYWlyIGNvbnRhaW5zIHRoZSBjb250cmFjdGluZyAKICogY2hhcmFjdGVyIHN0cmluZyBhbmQgaXRzIGNvbGxhdGlvbiBvcmRlci4KICovCmNsYXNzIEVudHJ5UGFpcgp7CnB1YmxpYzoKICAgIC8qKgogICAgICogQ29uc3RydWN0b3IKICAgICAqLwogICAgRW50cnlQYWlyKCk7CiAgICBFbnRyeVBhaXIoY29uc3QgVUNoYXIgKm5hbWUsIGludDMyX3QgbmFtZUxlbmd0aCwgaW50MzJfdCBhVmFsdWUsIFVCb29sIGFGd2QgPSBUUlVFKTsKICAgIH5FbnRyeVBhaXIoKTsKICAgIAogICAgaW5saW5lIFVCb29sIGVxdWFsVG8oY29uc3QgVUNoYXIgKmFOYW1lLCBpbnQzMl90IGFMZW4pOwogICAgaW5saW5lIGNvbnN0IFVuaWNvZGVTdHJpbmcmIGdldEVudHJ5TmFtZSgpOwoKICAgIGludDMyX3QgdmFsdWU7ICAgICAgICAgICAgICAgICAgLy8gQ29sbGF0aW9uIG9yZGVyCiAgICBVQm9vbCBmd2Q7ICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHJ1ZSBpZiB0aGlzIHBhaXIgaXMgZm9yIHRoZSBmb3J3YXJkIGRpcmVjdGlvbgoKICAgIC8qKgogICAgICogVGhlIHN0cmVhbUluIGFuZCBzdHJlYW1PdXQgbWV0aG9kcyByZWFkIGFuZCB3cml0ZSBvYmplY3RzIG9mIHRoaXMKICAgICAqIGNsYXNzIGFzIGJpbmFyeSwgcGxhdGZvcm0tZGVwZW5kZW50IGRhdGEgaW4gdGhlIGlvc3RyZWFtLiAgVGhlIHN0cmVhbQogICAgICogbXVzdCBiZSBpbiBpb3M6OmJpbmFyeSBtb2RlIGZvciB0aGlzIHRvIHdvcmsuICBUaGVzZSBtZXRob2RzIGFyZSBub3QKICAgICAqIGludGVuZGVkIGZvciBnZW5lcmFsIHB1YmxpYyB1c2U7IHRoZXkgYXJlIHVzZWQgYnkgdGhlIGZyYW1ld29yayB0byBpbXByb3ZlCiAgICAgKiBwZXJmb3JtYW5jZSBieSBzdG9yaW5nIGNlcnRhaW4gb2JqZWN0cyBpbiBiaW5hcnkgZmlsZXMuCiAgICAgKi8KICAgIHZvaWQgc3RyZWFtT3V0KEZpbGVTdHJlYW0qIG9zKSBjb25zdDsKICAgIHZvaWQgc3RyZWFtSW4oRmlsZVN0cmVhbSogaXMpOwoKICAgIHZvaWQgc3RyZWFtT3V0KFVNZW1vcnlTdHJlYW0qIG9zKSBjb25zdDsKICAgIHZvaWQgc3RyZWFtSW4oVU1lbW9yeVN0cmVhbSogaXMpOwoKICAgIC8qKgogICAgICogRGVwcmVjYXRlZAogICAgICovIAogICAgRW50cnlQYWlyKGNvbnN0IFVuaWNvZGVTdHJpbmcmIHN0ciwgaW50MzJfdCBhVmFsdWUsIFVCb29sIGFGd2QgPSBUUlVFKTsKcHJpdmF0ZToKICAgIFVuaWNvZGVTdHJpbmcgKnN0b3JhZ2U7CiAgICBjb25zdCBVQ2hhciAqbmFtZUNoYXJzOyAgICAgICAgLy8gQ29udHJhY3RpbmcgY2hhcmFjdGVycwogICAgaW50MzJfdCBuYW1lTGVuOwp9OwoKCi8qKgogKiBWZWN0b3JPZkludCBpcyBhIGR5bmFtaWMgYXJyYXkgb2YgMzItYml0IGludGVnZXJzLiAgCiAqIElkZWFsbHkgd2Ugd291bGQgdXNlIHRlbXBsYXRlcyBmb3IgdGhpcywgYnV0IHRoZXkncmUgbm90IHN1cHBvcnRlZAogKiBvbiBhbGwgb2YgdGhlIHBsYXRmb3JtcyB3ZSBuZWVkIHRvIHN1cHBvcnQuCiAqLwpjbGFzcyBWZWN0b3JPZkludCB7CgogICAgcHVibGljOgogICAgICAgIC8qKgogICAgICAgICAqIFRoZSBjaHVuayBzaXplIGJ5IHdoaWNoIHRoZSBhcnJheSBpcyBncm93bi4KICAgICAgICAgKiBUaGlzIHByb2JhYmx5IHNob3VsZG4ndCBiZSBpbiB0aGUgQVBJCiAgICAgICAgICovCiAgICAgICAgZW51bSBFR3Jvd3RoUmF0ZSB7IEdST1dUSF9SQVRFID0gNCB9OwogICAgICAgIC8qKgogICAgICAgICAqIENyZWF0ZXMgYSB2ZWN0b3IgdGhhdCBjb250YWlucyBlbGVtZW50cyBvZiBpbnRlZ2Vycy4KICAgICAgICAgKiBAcGFyYW0gaW5pdGlhbFNpemUgdGhlIGluaXRpYWwgc2l6ZSBvZiB0aGUgdmVjdG9yIG9iamVjdC4KICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWZWN0b3JPZkludChpbnQzMl90IGluaXRpYWxTaXplID0gMCk7CiAgICAgICAgLyoqCiAgICAgICAgICogQ29weSBjb25zdHJ1Y3Rvci4KICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWZWN0b3JPZkludChjb25zdCBWZWN0b3JPZkludCYgIHRoYXQpOwogICAgICAgIC8qKgogICAgICAgICAqIERlc3RydWN0b3IuCiAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgflZlY3Rvck9mSW50KCk7CgogICAgICAgIC8qKgogICAgICAgICAqIEFzc2lnbm1lbnQgb3BlcmF0b3IuCiAgICAgICAgICovCiAgICAgICAgY29uc3QgVmVjdG9yT2ZJbnQmICAgICAgb3BlcmF0b3I9KGNvbnN0IFZlY3Rvck9mSW50JiAgICB0aGF0KTsKICAgICAgICAKCiAgICAgICAgLyoqCiAgICAgICAgICogRXF1YWxpdHkgb3BlcmF0b3JzLgogICAgICAgICAqLwogICAgICAgIFVCb29sICAgICAgICAgICAgICAgICAgb3BlcmF0b3I9PShjb25zdCBWZWN0b3JPZkludCYgdGhhdCk7CiAgICAgICAgVUJvb2wgICAgICAgICAgICAgICAgICBvcGVyYXRvciE9KGNvbnN0IFZlY3Rvck9mSW50JiB0aGF0KTsKCiAgICAgICAgLyoqCiAgICAgICAgICogR2V0cyBhIHJlYWQtb25seSByZWZlcmVuY2UgdG8gdGhlIGVsZW1lbnQgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4KICAgICAgICAgKiBUaGlzIGRvZXMgbm90IGRvIHJhbmdlLWNoZWNraW5nOyBhbiBpbnZhbGlkIGluZGV4IG1heSBjYXVzZSBhIGNyYXNoLgogICAgICAgICAqIEByZXR1cm4gdGhlIGFjY2Vzc2VkIGVsZW1lbnQuCiAgICAgICAgICovCiAgICAgICAgaW50MzJfdCAgICAgICAgICAgICAgICAgb3BlcmF0b3JbXShpbnQzMl90ICBpbmRleCkgY29uc3Q7CiAgICAgICAgaW50MzJfdCAgICAgICAgICAgICAgICAgYXQoaW50MzJfdCAgaW5kZXgpIGNvbnN0OwoKICAgICAgICAvKioKICAgICAgICAgKiBHZXRzIGEgbm9uLWNvbnN0IHJlZmVyZW5jZSB0byB0aGUgZWxlbWVudCBhdCB0aGUgc3BlY2lmaWVkIGluZGV4LgogICAgICAgICAqIFRoaXMgZG9lcyByYW5nZS1jaGVja2luZzsgYWNjZXNzIHRvIGVsZW1lbnRzIGJleW9uZCB0aGUgZW5kIG9mIHRoZQogICAgICAgICAqIGFycmF5IHdpbGwgY2F1c2UgdGhlIGFycmF5IHRvIGdyb3cuCiAgICAgICAgICovCiAgICAgICAgaW50MzJfdCYgICAgICAgICAgICAgICAgb3BlcmF0b3JbXShpbnQzMl90ICBpbmRleCk7CiAgICAgICAgaW50MzJfdCYgICAgICAgICAgICAgICAgYXQoaW50MzJfdCAgaW5kZXgpOwoKICAgICAgICAvKioKICAgICAgICAgKiBTZXRzIHRoZSBlbGVtZW50IGF0IHRoZSBzcGVjaWZpZWQgaW5kZXggdG8gYSBkaWZmZXJlbnQgdmFsdWUuCiAgICAgICAgICogQHBhcmFtIGluZGV4IHRoZSBzcGVjaWZpZWQgaW5kZXguCiAgICAgICAgICogQHBhcmFtIHZhbHVlIHRoZSBuZXcgdmFsdWUuCiAgICAgICAgICovCiAgICAgICAgdm9pZCAgICAgICAgICAgICAgICAgICAgYXRQdXQoICBpbnQzMl90ICAgICBpbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGludDMyX3QmICB2YWx1ZSk7CiAgICAgICAgLyoqCiAgICAgICAgICogSW5zZXJ0cyBhIHZhbHVlIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXgsIHNsaWRpbmcgdGhlIHJlc3Qgb2YKICAgICAgICAgKiB0aGUgZWxlbWVudHMgaW4gdGhlIGFycmF5IG92ZXIgdG8gbWFrZSByb29tLgogICAgICAgICAqIEBwYXJhbSBpbmRleCB0aGUgc3BlY2lmaWVkIGluZGV4LgogICAgICAgICAqIEBwYXJhbSB2YWx1ZSB0aGUgdmFsdWUuCiAgICAgICAgICovCiAgICAgICAgdm9pZCAgICAgICAgICAgICAgICAgICAgYXRJbnNlcnQoICAgaW50MzJfdCAgICAgaW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBpbnQzMl90JiAgdmFsdWUpOwoKICAgICAgICAvKioKICAgICAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgaW4gdGhlIHZlY3Rvci4KICAgICAgICAgKiBAcmV0dXJuIHRoZSBzaXplIG9mIHZlY3Rvci4KICAgICAgICAgKi8KICAgICAgICBpbnQzMl90ICAgICAgICAgICAgICAgICBzaXplKHZvaWQpIGNvbnN0OwoKICAgICAgICAvKioKICAgICAgICAgKiBTZXRzIHRoZSBzaXplIG9mIHRoaXMgdmVjdG9yLiBJZiB0aGUgbmV3IHNpemUgaXMgZ3JlYXRlciB0aGFuIHRoZSAKICAgICAgICAgKiBjdXJyZW50IHNpemUsIG5ldyA8Y29kZT4wPC9jb2RlPiBpdGVtcyBhcmUgYWRkZWQgdG8gdGhlIGVuZCBvZiAKICAgICAgICAgKiB0aGUgdmVjdG9yLiBJZiB0aGUgbmV3IHNpemUgaXMgbGVzcyB0aGFuIHRoZSBjdXJyZW50IHNpemUsIGFsbCAKICAgICAgICAgKiBjb21wb25lbnRzIGF0IGluZGV4IDxjb2RlPm5ld1NpemU8L2NvZGU+IGFuZCBncmVhdGVyIGFyZSBkaXNjYXJkZWQuCiAgICAgICAgICogSWYgPGNvZGU+bmV3U2l6ZTwvY29kZT4gaXMgbmVnYXRpdmUgaXQgaXMgdHJlYXRlZCBhcyBpZiBpdCB3ZXJlIHplcm8uCiAgICAgICAgICoKICAgICAgICAgKiBAcGFyYW0gICBuZXdTaXplICAgdGhlIG5ldyBzaXplIG9mIHRoaXMgdmVjdG9yLgogICAgICAgICAqLwogICAgICAgIHZvaWQgICAgICAgICAgICAgICAgICAgIHNldFNpemUoaW50MzJfdCBuZXdTaXplKTsKCiAgICAgICAgLyoqCiAgICAgICAgICogQ2hlY2tzIGlmIHRoaXMgdmVjdG9yIG9iamVjdCBpcyB2YWxpZC4KICAgICAgICAgKiBAcmV0dXJuIFRSVUUgaWYgdGhlIHZlY3RvciBvYmplY3QgaXMgdmFsaWQsIEZBTFNFIG90aGVyd2lzZS4KICAgICAgICAgKi8KICAgICAgICBVQm9vbCAgICAgICAgICAgICAgICAgIGlzQm9ndXModm9pZCkgY29uc3Q7CgogICAgICAgIC8qKgogICAgICAgICAqIFRoZSBzdHJlYW1JbiBhbmQgc3RyZWFtT3V0IG1ldGhvZHMgcmVhZCBhbmQgd3JpdGUgb2JqZWN0cyBvZiB0aGlzCiAgICAgICAgICogY2xhc3MgYXMgYmluYXJ5LCBwbGF0Zm9ybS1kZXBlbmRlbnQgZGF0YSBpbiB0aGUgaW9zdHJlYW0uICBUaGUgc3RyZWFtCiAgICAgICAgICogbXVzdCBiZSBpbiBpb3M6OmJpbmFyeSBtb2RlIGZvciB0aGlzIHRvIHdvcmsuICBUaGVzZSBtZXRob2RzIGFyZSBub3QKICAgICAgICAgKiBpbnRlbmRlZCBmb3IgZ2VuZXJhbCBwdWJsaWMgdXNlOyB0aGV5IGFyZSB1c2VkIGJ5IHRoZSBmcmFtZXdvcmsgdG8gaW1wcm92ZQogICAgICAgICAqIHBlcmZvcm1hbmNlIGJ5IHN0b3JpbmcgY2VydGFpbiBvYmplY3RzIGluIGJpbmFyeSBmaWxlcy4KICAgICAgICAgKi8KICAgICAgICB2b2lkICAgICAgICAgICAgICAgICAgICBzdHJlYW1PdXQoRmlsZVN0cmVhbSogb3MpIGNvbnN0OwogICAgICAgIHZvaWQgICAgICAgICAgICAgICAgICAgIHN0cmVhbUluKEZpbGVTdHJlYW0qIGlzKTsKCiAgICAgICAgdm9pZCAgICAgICAgICAgICAgICAgICAgc3RyZWFtT3V0KFVNZW1vcnlTdHJlYW0qIG9zKSBjb25zdDsKICAgICAgICB2b2lkICAgICAgICAgICAgICAgICAgICBzdHJlYW1JbihVTWVtb3J5U3RyZWFtKiBpcyk7CgogICAgcHJpdmF0ZToKICAgICAgICAvKioKICAgICAgICAgKiBSZXNpemVzIHRoZSB2ZWN0b3IgaWYgbmVjZXNzYXJ5IHdoZW4gY29tcGFyZWQgdG8gYSBuZXcgc2l6ZS4KICAgICAgICAgKiBAcGFyYW0gbmV3U2l6ZSB0aGUgbmV3IHNpemUuCiAgICAgICAgICovCiAgICAgICAgdm9pZCAgICAgICAgICAgICAgICAgICAgICAgIHJlc2l6ZShpbnQzMl90ICBuZXdTaXplKTsKICAgIAogICAgICAgIGludDMyX3QgICAgICAgICAgICAgICAgICAgICBmU2l6ZTsKICAgICAgICBpbnQzMl90ICAgICAgICAgICAgICAgICAgICAgZkNhcGFjaXR5OwogICAgICAgIGludDMyX3QqICAgICAgICAgICAgICAgICAgICBmRWxlbWVudHM7CiAgICAgICAgVUJvb2wgICAgICAgICAgICAgICAgICAgICAgZkJvZ3VzOwp9OwoKLyoqCiAqIFZlY3Rvck9mUG9pbnRlciBpcyBhIGR5bmFtaWMgYXJyYXkgb2Ygdm9pZCogcG9pbnRlcnMuICAKICogIDxQPgogKiAgVGhpcyBpcyBhIHZlY3RvciBjbGFzcyB0aGF0IGlzIGRlc2lnbmVkIHRvIGJlIHVzZWQgd2l0aCBwb2ludGVyIHR5cGVzIGFuZCB3aGljaCBpbXBsZW1lbnRzCiAqICBvd25pbmcgc2VtYW50aWNzLiAgVGhhdCBpcywgb25jZSBhIHZhbHVlIGlzIHBsYWNlZCBhbiBlbGVtZW50IG9mIHRoZSB2ZWN0b3IsIHRoZSB2ZWN0b3IgaXMKICogIGNvbnNpZGVyZWQgdG8gb3duIGl0IGFuZCBpcyByZXNwb25zaWJsZSBmb3IgZGlzcG9zaW5nIGl0LiAgVGhpcyB3aWxsIGhhcHBlbiBib3RoIHdoZW4gdGhlCiAqICBlbGVtZW50IGlzIGNoYW5nZWQgdXNpbmcgYXRQdXQoKSBvciB0aHJvdWdoIGFuIFBvaW50ZXJUbyoqKiosIGFuZCB3aGVuIHRoZSB2ZWN0b3IgaXRzZWxmIGlzCiAqICBkaXNwb3NlZC4gIAogKiAgPFA+CiAqICBXQVJOSU5HOiAgVGhlIGNhbGxlciBtdXN0IGJlIGNhcmVmdWwgdG8gYXZvaWQgaG9sZGluZyBvbnRvIGFueSBkYW5nbGluZyByZWZlcmVuY2VzCiAqICBhZnRlciB0aGUgdmVjdG9yIGlzIGRpc3Bvc2VkLCBhbmQgdGhlIGNhbGxlciBtdXN0IGFsc28gYmUgY2FyZWZ1bCBub3QgdG8gcHV0IHRoZSBzYW1lCiAqICB2YWx1ZSBpbnRvIG1vcmUgdGhhbiBvbmUgZWxlbWVudCBpbiB0aGUgdmVjdG9yICh1bmxlc3MgdGhlIHZhbHVlIGlzIE5VTEwpLgogKiAgPFA+CiAqICBBcyB3aXRoIFZlY3Rvck9mKioqPiwgdGhlIHZlY3RvciBncm93cyBhcyBuZWNlc3NhcnkgdG8gYWNjb21tb2RhdGUgYWxsIGVsZW1lbnRzLCB0aGUKICogIHNpemUgaXMgb25lIHBsdXMgdGhlIGluZGV4IG9mIHRoZSBoaWdoZXN0IGVsZW1lbnQgdGhhdCdzIGJlZW4gc2V0LCBhbmQgYW55IGVsZW1lbnRzIGJlbG93CiAqICB0aGUgaGlnaGVzdCBlbGVtZW50IHRoYXQgYXJlbid0IGV4cGxpY2l0bHkgaW5pdGlhbGl6ZWQgYXJlIGluaXRpYWxpemVkIHRvIE5VTEwuCiAqLwpjbGFzcyBWZWN0b3JPZlBvaW50ZXIgewogICAgcHVibGljOgogICAgICAgIC8qKgogICAgICAgICAqIFRoZSBjaHVuayBzaXplIGJ5IHdoaWNoIHRoZSBhcnJheSBpcyBncm93bi4KICAgICAgICAgKiBUaGlzIHByb2JhYmx5IHNob3VsZG4ndCBiZSBpbiB0aGUgQVBJCiAgICAgICAgICovCiAgICAgICAgZW51bSBFR3Jvd3RoUmF0ZSB7IEdST1dUSF9SQVRFID0gNCB9OwogICAgICAgIC8qKgogICAgICAgICAqIENyZWF0ZXMgYSB2ZWN0b3IgdGhhdCBjb250YWlucyBlbGVtZW50cyBvZiBwb2ludGVycyB0byBvYmplY3RzLgogICAgICAgICAqIEBwYXJhbSBpbml0aWFsU2l6ZSB0aGUgaW5pdGlhbCBzaXplIG9mIHRoZSB2ZWN0b3Igb2JqZWN0LgogICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWZWN0b3JPZlBvaW50ZXIoaW50MzJfdCBpbml0aWFsU2l6ZSA9IDApOwogICAgICAgIC8qKgogICAgICAgICAqIENvcHkgY29uc3RydWN0b3IuCiAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlY3Rvck9mUG9pbnRlcihjb25zdCBWZWN0b3JPZlBvaW50ZXImICB0aGF0KTsKICAgICAgICAvKioKICAgICAgICAgKiBEZXN0cnVjdG9yLgogICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB+VmVjdG9yT2ZQb2ludGVyKCk7CiAgICAgICAgLyoqCiAgICAgICAgICogQXNzaWdubWVudCBvcGVyYXRvci4KICAgICAgICAgKi8KICAgICAgICBjb25zdCBWZWN0b3JPZlBvaW50ZXImICAgICAgb3BlcmF0b3I9KGNvbnN0IFZlY3Rvck9mUG9pbnRlciYgICAgdGhhdCk7CgogICAgICAgIC8qKgogICAgICAgICAqIEVxdWFsaXR5IG9wZXJhdG9ycy4KICAgICAgICAgKi8KICAgICAgICBVQm9vbCAgICAgICAgICAgICAgICAgICAgICBvcGVyYXRvcj09KGNvbnN0IFZlY3Rvck9mUG9pbnRlciYgdGhhdCk7CiAgICAgICAgVUJvb2wgICAgICAgICAgICAgICAgICAgICAgb3BlcmF0b3IhPShjb25zdCBWZWN0b3JPZlBvaW50ZXImIHRoYXQpOwoKICAgICAgICAvKioKICAgICAgICAgKiBHZXRzIGEgcmVhZC1vbmx5IHJlZmVyZW5jZSB0byB0aGUgZWxlbWVudCBhdCB0aGUgc3BlY2lmaWVkIGluZGV4LgogICAgICAgICAqIFRoaXMgZG9lcyBub3QgZG8gcmFuZ2UtY2hlY2tpbmc7IGFuIGludmFsaWQgaW5kZXggbWF5IGNhdXNlIGEgY3Jhc2guCiAgICAgICAgICogQHJldHVybiB0aGUgYWNjZXNzZWQgZWxlbWVudC4KICAgICAgICAgKi8KICAgICAgICB2b2lkKiAgICAgICAgICAgICAgICAgICAgICAgb3BlcmF0b3JbXShpbnQzMl90ICBpbmRleCkgY29uc3Q7CiAgICAgICAgdm9pZCogICAgICAgICAgICAgICAgICAgICAgIGF0KGludDMyX3QgIGluZGV4KSBjb25zdDsKCiAgICAgICAgLyoqCiAgICAgICAgICogR2V0cyBhIG5vbi1jb25zdCByZWZlcmVuY2UgdG8gdGhlIGVsZW1lbnQgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4KICAgICAgICAgKiBUaGlzIGRvZXMgcmFuZ2UtY2hlY2tpbmc7IGFjY2VzcyB0byBlbGVtZW50cyBiZXlvbmQgdGhlIGVuZCBvZiB0aGUKICAgICAgICAgKiBhcnJheSB3aWxsIGNhdXNlIHRoZSBhcnJheSB0byBncm93LgogICAgICAgICAqLwogICAgICAgIHZvaWQqJiAgICAgICAgICAgICAgICAgICAgICBvcGVyYXRvcltdKGludDMyX3QgIGluZGV4KTsKICAgICAgICB2b2lkKiYgICAgICAgICAgICAgICAgICAgICAgYXQoaW50MzJfdCAgaW5kZXgpOwoKICAgICAgICAvKioKICAgICAgICAgKiBTZXRzIHRoZSBlbGVtZW50IGF0IHRoZSBzcGVjaWZpZWQgaW5kZXggdG8gYSBkaWZmZXJlbnQgdmFsdWUuCiAgICAgICAgICogQHBhcmFtIGluZGV4IHRoZSBzcGVjaWZpZWQgaW5kZXguCiAgICAgICAgICogQHBhcmFtIHZhbHVlIHRoZSBuZXcgdmFsdWUuCiAgICAgICAgICovCiAgICAgICAgdm9pZCAgICAgICAgICAgICAgICAgICAgICAgIGF0UHV0KCAgaW50MzJfdCAgICAgICAgIGluZGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZvaWQqJiAgICB2YWx1ZSk7CgogICAgICAgIC8qKgogICAgICAgICAqIEluc2VydHMgYSB2YWx1ZSBhdCB0aGUgc3BlY2lmaWVkIGluZGV4LCBzbGlkaW5nIHRoZSByZXN0IG9mCiAgICAgICAgICogdGhlIGVsZW1lbnRzIGluIHRoZSBhcnJheSBvdmVyIHRvIG1ha2Ugcm9vbS4KICAgICAgICAgKiBAcGFyYW0gaW5kZXggdGhlIHNwZWNpZmllZCBpbmRleC4KICAgICAgICAgKiBAcGFyYW0gdmFsdWUgdGhlIHZhbHVlLgogICAgICAgICAqLwogICAgICAgIHZvaWQgICAgICAgICAgICAgICAgICAgICAgICBhdEluc2VydCggICBpbnQzMl90ICAgICBpbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgdm9pZComICAgIHZhbHVlKTsKICAgICAgICAvKioKICAgICAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgaW4gdGhlIHZlY3Rvci4KICAgICAgICAgKiBAcmV0dXJuIHRoZSBzaXplIG9mIHZlY3Rvci4KICAgICAgICAgKi8KICAgICAgICBpbnQzMl90ICAgICAgICAgICAgICAgICAgICAgc2l6ZSh2b2lkKSBjb25zdDsKCiAgICAgICAgLyoqCiAgICAgICAgICogQ2hlY2tzIGlmIHRoaXMgdmVjdG9yIG9iamVjdCBpcyB2YWxpZC4KICAgICAgICAgKiBAcmV0dXJuIFRSVUUgaWYgdGhlIHZlY3RvciBvYmplY3QgaXMgdmFsaWQsIEZBTFNFIG90aGVyd2lzZS4KICAgICAgICAgKi8KICAgICAgICBVQm9vbCAgICAgICAgICAgICAgICAgICAgICBpc0JvZ3VzKHZvaWQpIGNvbnN0OwoKICAgIHByaXZhdGU6CiAgICAgICAgLyoqCiAgICAgICAgICogUmVzaXplcyB0aGUgdmVjdG9yIGlmIG5lY2Vzc2FyeSB3aGVuIGNvbXBhcmVkIHRvIGEgbmV3IHNpemUuCiAgICAgICAgICogQHBhcmFtIG5ld1NpemUgdGhlIG5ldyBzaXplLgogICAgICAgICAqLwogICAgICAgIHZvaWQgICAgICAgICAgICAgICAgICAgICAgICByZXNpemUoaW50MzJfdCAgbmV3U2l6ZSk7CiAgICAKICAgICAgICBpbnQzMl90ICAgICAgICAgICAgICAgICAgICAgZlNpemU7CiAgICAgICAgaW50MzJfdCAgICAgICAgICAgICAgICAgICAgIGZDYXBhY2l0eTsKICAgICAgICB2b2lkKiogICAgICAgICAgICAgICAgICAgICAgZkVsZW1lbnRzOwogICAgICAgIFVCb29sICAgICAgICAgICAgICAgICAgICAgIGZCb2d1czsKfTsKCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyAgVGhlIGZvbGxvd2luZyBkaWFncmFtIHNob3dzIHRoZSBkYXRhIHN0cnVjdHVyZSBvZiB0aGUgUnVsZUJhc2VkQ29sbGF0b3Igb2JqZWN0LgovLyAgU3VwcG9zZSB3ZSBoYXZlIHRoZSBydWxlLCB3aGVyZSAnby11bWxhdXQnIGlzIHRoZSB1bmljb2RlIGNoYXIgMHgwMEY2LgovLyAgImEsIEEgPCBiLCBCIDwgYywgQywgY2gsIGNILCBDaCwgQ0ggPCBkLCBEIC4uLiA8IG8sIE87ICdvLXVtbGF1dCcvRSwgJ08tdW1sYXV0Jy9FIC4uLiIuCi8vICBXaGF0IHRoZSBydWxlIHNheXMgaXMsIHNvcnRzICdjaCdsaWdhdHVyZXMgYW5kICdjJyBvbmx5IHdpdGggdGVydGlhcnkgZGlmZmVyZW5jZSBhbmQKLy8gIHNvcnRzICdvLXVtbGF1dCcgYXMgaWYgaXQncyBhbHdheXMgZXhwYW5kZWQgd2l0aCAnZScuCi8vCi8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChWZWN0b3JPZlBUb0NvbnRyYWN0VGFibGUpICAgICAgICAgKFZlY3Rvck9mUFRvRXhwYW5kVGFibGUpCi8vIG1hcHBpbmcgdGFibGUgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250cmFjdGluZyBsaXN0ICAgICAgICAgICAgICAgICAgZXhwYW5kaW5nIGxpc3QKLy8gKGNvbnRhaW5zIGFsbCB1bmljb2RlIGNoYXIKLy8gIGVudHJpZXMpCi8vICAgICAgICAgICAgICAgICAgIChWZWN0b3JPZlBUb0NvbnRyYWN0RWxlbWVudCkgKihQVG9Db250cmFjdEVsZW1lbnQpICAgICAgKFBUb0V4cGFuZFRhYmxlKQovLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX19fICAgICAgICBfX19fX19fX19fX19fICAgICAgICAgX19fX19fX19fX19fX19fX19fX19fX19fXwovLyAgIF9fX19fX19fICAgICAgICAgICAgICAgICAgIHw9PT09PT58XypffC0tLS0tPnwnYycgIHx2KCdjJykgfCAgIHw9PT58dignbycpfHYoJ3VtbGF1dCcpfHYoJ2UnKXwKLy8gIHxfXHUwMDAxX3wtLT4gdignXHUwMDAxJykgICB8ICAgICAgfF86X3wgICAgICB8LS0tLS0tLS0tLS0tLXwgICB8ICAgfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18Ci8vICB8X1x1MDAwMl98LS0+IHYoJ1x1MDAwMicpICAgfCAgICAgIHxfOl98ICAgICAgfCdjaCcgfHYoJ2NoJyl8ICAgfCAgIHwgICAgICAgICAgICAgOiAgICAgICAgICAgfAovLyAgfF9fX186X19ffCAgICAgICAgICAgICAgICAgIHwgICAgICB8XzpffCAgICAgIHwtLS0tLS0tLS0tLS0tfCAgIHwgICB8LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwKLy8gIHxfX19fOl9fX3wgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICB8J2NIJyB8dignY0gnKXwgICB8ICAgfCAgICAgICAgICAgICA6ICAgICAgICAgICB8Ci8vICB8X18nYSdfX198LS0+IHYoJ2EnKSAgICAgICAgfCAgICAgICAgICAgICAgICAgfC0tLS0tLS0tLS0tLS18ICAgfCAgIHwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfAovLyAgfF9fJ2InX19ffC0tPiB2KCdiJykgICAgICAgIHwgICAgICAgICAgICAgICAgIHwnQ2gnIHx2KCdDaCcpfCAgIHwgICB8ICAgICAgICAgICAgIDogICAgICAgICAgIHwKLy8gIHxfX19fOl9fX3wgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICB8LS0tLS0tLS0tLS0tLXwgICB8ICAgfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18Ci8vICB8X19fXzpfX198ICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgfCdDSCcgfHYoJ0NIJyl8ICAgfCAgIHwgICAgICAgICAgICAgOiAgICAgICAgICAgfAovLyAgfF9fJ2NoJ19ffC0tLS0tLS0tLS0tLS0tLS0tLS0gICAgICAgICAgICAgICAgICAtLS0tLS0tLS0tLS0tICAgIHwgICB8LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwKLy8gIHxfX19fOl9fX3wgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgfCAgICAgICAgICAgICA6ICAgICAgICAgICB8Ci8vICB8by11bWxhdXR8LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICAgIHxfX19fX19fX19fX19fX19fX19fX19fX19ffAovLyAgfF9fX186X19ffAovLwovLwovLyBOb3RlZCBieSBIZWxlbmEgU2hpaCBvbiA2LzIzLzk3IHdpdGggcGVuZGluZyBkZXNpZ24gY2hhbmdlcyAoc2xpbW1pbmcgY29sbGF0aW9uKS4KLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgpjbGFzcyBWZWN0b3JPZlBUb0V4cGFuZFRhYmxlOwoKLyoqIAogKiBQVG9FeHBhbmRUYWJsZSBpcyBhIHNtYXJ0LXBvaW50ZXIgdG8gYSBWZWN0b3JPZkludCB0aGF0IGlzIHVzZWQgdG8gc3RvcmUKICogdGhlIGNvbGxhdGlvbiBvcmRlcnMgdGhhdCBhcmUgdGhlIHJlc3VsdCBvZiBhbiBleHBhbnNpb24uCiAqIDxQPgogKiBZb3UgY2FuIHVzZSB0aGlzIG9iamVjdCBhcyBpZiBpdCB3ZXJlIGEgcG9pbnRlciB0byBhIFZlY3Rvck9mSW50LCBlLmcuCiAqIDxwcmU+CiAqIFBUb0V4cGFuZFRhYmxlIGZvbyA9IC4uLi47CiAqIGZvby0+YXRJbnNlcnQoLi4uLik7CiAqIDwvcHJlPgogKi8KY2xhc3MgUFRvRXhwYW5kVGFibGUgewogICAgcHVibGljOgogICAgICAgIAogICAgICAgIC8qKgogICAgICAgICAqIERlc3RydWN0b3IuCiAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgflBUb0V4cGFuZFRhYmxlKCk7CiAgICAgICAgCiAgICAgICAgLyoqCiAgICAgICAgICogQXNzaWdubWVudCBvcGVyYXRvcnMKICAgICAgICAgKiBUaGUgZXhwYW5kIHRhYmxlIHRoYXQgdGhpcyBvYmplY3QgYWxyZWFkeSBwb2ludHMgdG8gKGlmIGFueSkgaXMgZGVsZXRlZC4KICAgICAgICAgKi8KICAgICAgICBjb25zdCBQVG9FeHBhbmRUYWJsZSYgICAgICAgICAgICAgICBvcGVyYXRvcj0oVmVjdG9yT2ZJbnQqICBuZXdWYWx1ZSk7CiAgICAgICAgY29uc3QgUFRvRXhwYW5kVGFibGUmICAgICAgICAgICAgICAgb3BlcmF0b3I9KGNvbnN0IFBUb0V4cGFuZFRhYmxlJiBwb2ludGVyVG9OZXdWYWx1ZSk7CgogICAgICAgIC8qKgogICAgICAgICAqIFBvaW50ZXIgb3BlcmF0b3Igb3ZlcnJpZGUKICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcGVyYXRvciBWZWN0b3JPZkludCooKSBjb25zdDsKCiAgICBwcml2YXRlOgogICAgICAgIC8qKgogICAgICAgICAqIENvbnN0cnVjdG9yCiAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUFRvRXhwYW5kVGFibGUoVmVjdG9yT2ZJbnQqJiAgICB2YWx1ZSk7CiAgICAgICAgLyoqCiAgICAgICAgICogQ29weSBjb25zdHJ1Y3Rvci4KICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQVG9FeHBhbmRUYWJsZShjb25zdCBQVG9FeHBhbmRUYWJsZSYgICAgdGhhdCk7CgogICAgICAgIFZlY3Rvck9mSW50KiYgICAgICAgICAgICAgICAgICAgICAgIGZWYWx1ZTsKCiAgICAgICAgZnJpZW5kIGNsYXNzIFZlY3Rvck9mUFRvRXhwYW5kVGFibGU7Cn07CgovKioKICogIFZlY3Rvck9mUG9pbnRlciBpcyBhIGR5bmFtaWMgYXJyYXkgb2YgUFRvRXhwYW5kVGFibGUgb2JqZWN0cwogKiAgd2hpY2ggaW4gdHVybiBwb2ludCB0byB0aGUgYXJyYXkgb2YgY29sbGF0aW9uIG9yZGVycyBmb3IgZWFjaCBleHBhbmRpbmcgY2hhcmFjdGVyLgogKiAgPFA+CiAqICBUaGlzIGlzIGEgdmVjdG9yIGNsYXNzIHRoYXQgaXMgZGVzaWduZWQgdG8gYmUgdXNlZCB3aXRoIHBvaW50ZXIgdHlwZXMgYW5kIHdoaWNoIGltcGxlbWVudHMKICogIG93bmluZyBzZW1hbnRpY3MuICBUaGF0IGlzLCBvbmNlIGEgdmFsdWUgaXMgcGxhY2VkIGFuIGVsZW1lbnQgb2YgdGhlIHZlY3RvciwgdGhlIHZlY3RvciBpcwogKiAgY29uc2lkZXJlZCB0byBvd24gaXQgYW5kIGlzIHJlc3BvbnNpYmxlIGZvciBkaXNwb3NpbmcgaXQuICBUaGlzIHdpbGwgaGFwcGVuIGJvdGggd2hlbiB0aGUKICogIGVsZW1lbnQgaXMgY2hhbmdlZCB1c2luZyBhdFB1dCgpIG9yIHRocm91Z2ggYW4gUG9pbnRlclRvKioqKiwgYW5kIHdoZW4gdGhlIHZlY3RvciBpdHNlbGYgaXMKICogIGRpc3Bvc2VkLiAgCiAqICA8UD4KICogIFdBUk5JTkc6ICBUaGUgY2FsbGVyIG11c3QgYmUgY2FyZWZ1bCB0byBhdm9pZCBob2xkaW5nIG9udG8gYW55IGRhbmdsaW5nIHJlZmVyZW5jZXMKICogIGFmdGVyIHRoZSB2ZWN0b3IgaXMgZGlzcG9zZWQsIGFuZCB0aGUgY2FsbGVyIG11c3QgYWxzbyBiZSBjYXJlZnVsIG5vdCB0byBwdXQgdGhlIHNhbWUKICogIHZhbHVlIGludG8gbW9yZSB0aGFuIG9uZSBlbGVtZW50IGluIHRoZSB2ZWN0b3IgKHVubGVzcyB0aGUgdmFsdWUgaXMgTlVMTCkuCiAqICA8UD4KICogIEFzIHdpdGggVmVjdG9yT2YqKio+LCB0aGUgdmVjdG9yIGdyb3dzIGFzIG5lY2Vzc2FyeSB0byBhY2NvbW1vZGF0ZSBhbGwgZWxlbWVudHMsIHRoZQogKiAgc2l6ZSBpcyBvbmUgcGx1cyB0aGUgaW5kZXggb2YgdGhlIGhpZ2hlc3QgZWxlbWVudCB0aGF0J3MgYmVlbiBzZXQsIGFuZCBhbnkgZWxlbWVudHMgYmVsb3cKICogIHRoZSBoaWdoZXN0IGVsZW1lbnQgdGhhdCBhcmVuJ3QgZXhwbGljaXRseSBpbml0aWFsaXplZCBhcmUgaW5pdGlhbGl6ZWQgdG8gTlVMTC4KICovCmNsYXNzIFZlY3Rvck9mUFRvRXhwYW5kVGFibGUgewogICAgcHVibGljOgoKICAgICAgICAvKioKICAgICAgICAgKiBUaGUgY2h1bmsgc2l6ZSBieSB3aGljaCB0aGUgYXJyYXkgaXMgZ3Jvd24uCiAgICAgICAgICogVGhpcyBwcm9iYWJseSBzaG91bGRuJ3QgYmUgaW4gdGhlIEFQSQogICAgICAgICAqLwogICAgICAgIGVudW0gRUdyb3d0aFJhdGUgeyBHUk9XVEhfUkFURSA9IDQgfTsKICAgICAgICAvKioKICAgICAgICAgKiBDcmVhdGVzIGEgdmVjdG9yIHRoYXQgY29udGFpbnMgZWxlbWVudHMgb2YgUFRvRXhwYW5kVGFibGUuCiAgICAgICAgICogQHBhcmFtIGluaXRpYWxTaXplIHRoZSBpbml0aWFsIHNpemUgb2YgdGhlIHZlY3RvciBvYmplY3QuCiAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBWZWN0b3JPZlBUb0V4cGFuZFRhYmxlKGludDMyX3QgIGluaXRpYWxTaXplID0gMCk7CiAgICAgICAgLyoqCiAgICAgICAgICogQ29weSBjb25zdHJ1Y3Rvci4KICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlY3Rvck9mUFRvRXhwYW5kVGFibGUoY29uc3QgVmVjdG9yT2ZQVG9FeHBhbmRUYWJsZSYgICAgdGhhdCk7CgogICAgICAgIC8qKgogICAgICAgICAqIERlc3RydWN0b3IuCiAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB+VmVjdG9yT2ZQVG9FeHBhbmRUYWJsZSgpOwoKICAgICAgICAvKioKICAgICAgICAgKiBBc3NpZ25tZW50IG9wZXJhdG9yLgogICAgICAgICAqLwogICAgICAgIGNvbnN0IFZlY3Rvck9mUFRvRXhwYW5kVGFibGUmICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcGVyYXRvcj0oY29uc3QgVmVjdG9yT2ZQVG9FeHBhbmRUYWJsZSYgdGhhdCk7CgogICAgICAgIC8qKgogICAgICAgICAqIFJldHVybiBhIG1vZGlmaWFibGUgc21hcnQtcG9pbnRlciB0byB0aGUgZXhwYW5zaW9uIHRhYmxlCiAgICAgICAgICogYXQgdGhlIGdpdmVuIGluZGV4LiAgQXNzaWduaW5nIHRvIHRoaXMgc21hcnQgcG9pbnRlciB3aWxsIHdvcmssIGUuZy4KICAgICAgICAgKiAgVmVjdG9yT2ZQVG9FeHBhbmRUYWJsZSBmb28gPSAuLi4uOwogICAgICAgICAqICBmb29bNV0gPSBuZXcgVmVjdG9yT2ZJbnQgLi4uOwogICAgICAgICAqIFRoaXMgZG9lcyByYW5nZS1jaGVja2luZzsgYWNjZXNzIHRvIGVsZW1lbnRzIGJleW9uZCB0aGUgZW5kIG9mIHRoZQogICAgICAgICAqIGFycmF5IHdpbGwgY2F1c2UgdGhlIGFycmF5IHRvIGdyb3cuCiAgICAgICAgICovCiAgICAgICAgUFRvRXhwYW5kVGFibGUgICAgICBhdChpbnQzMl90ICBpbmRleCk7CiAgICAgICAgUFRvRXhwYW5kVGFibGUgICAgICBvcGVyYXRvcltdKGludDMyX3QgIGluZGV4KTsKCiAgICAgICAgLyoqCiAgICAgICAgICogUmV0dXJuIGEgcG9pbnRlciB0byB0aGUgdGFibGUgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgICAqIFRoZSBwb2ludGVyIGl0c2VsZiBjYW5ub3QgYmUgbW9kaWZpZWQsIGJ1dCB0aGUgZWxlbWVudHMgaXQgcG9pbnRzIHRvIG1heToKICAgICAgICAgKiA8cHJlPgogICAgICAgICAqICBjb25zdCBWZWN0b3JPZlBUb0V4cGFuZFRhYmxlIGZvbyA9IC4uLi47CiAgICAgICAgICogIGZvb1s1XSA9IC4uLi47ICAgICAgLy8gTk9UIEFMTE9XRUQKICAgICAgICAgKiAgZm9vWzVdWzBdID0gMTIzNDU7ICAvLyBvawogICAgICAgICAqIDwvcHJlPgogICAgICAgICAqIFRoaXMgZG9lcyBub3QgZG8gcmFuZ2UtY2hlY2tpbmc7IGFuIGludmFsaWQgaW5kZXggbWF5IGNhdXNlIGEgY3Jhc2guCiAgICAgICAgICogQHJldHVybiB0aGUgYWNjZXNzZWQgZWxlbWVudC4KICAgICAgICAgKi8KICAgICAgICBWZWN0b3JPZkludCogICAgICAgIGF0KGludDMyX3QgIGluZGV4KSBjb25zdDsKICAgICAgICBWZWN0b3JPZkludCogICAgICAgIG9wZXJhdG9yW10oaW50MzJfdCAgaW5kZXgpIGNvbnN0OwoKICAgICAgICAvKioKICAgICAgICAgKiBTZXRzIHRoZSBlbGVtZW50IGF0IHRoZSBzcGVjaWZpZWQgaW5kZXggdG8gYSBkaWZmZXJlbnQgdmFsdWUuCiAgICAgICAgICogSWYgdGhlcmUgd2FzIGFyZWFkeSBhbiBvYmplY3Qgc3RvcmVkIGF0IHRoaXMgaW5kZXgsIGl0IGlzIGRlbGV0ZWQuCiAgICAgICAgICogQHBhcmFtIGluZGV4IHRoZSBzcGVjaWZpZWQgaW5kZXguCiAgICAgICAgICogQHBhcmFtIHZhbHVlIHRoZSBuZXcgdmFsdWUuCiAgICAgICAgICovCiAgICAgICAgdm9pZCAgICAgICAgICAgICAgICBhdFB1dCggIGludDMyX3QgICAgICAgICBpbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVmVjdG9yT2ZJbnQqICAgIHZhbHVlKTsKCiAgICAgICAgLyoqCiAgICAgICAgICogIk9ycGhhbiIgdGhlIHBvaW50ZXIgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4gIFRoZSBhcnJheSB3aWxsIG5vCiAgICAgICAgICogbG9uZ2VyIGNvbnRhaW4gYSByZWZlcmVuY2UgdG8gdGhlIG9iamVjdCwgYW5kIHRoZSBjYWxsZXIgaXMKICAgICAgICAgKiBub3cgcmVzcG9uc2libGUgZm9yIGRlbGV0aW5nIGl0cyBzdG9yYWdlLgogICAgICAgICAqLwogICAgICAgIFZlY3Rvck9mSW50KiAgICAgICAgb3JwaGFuQXQoaW50MzJfdCAgICBpbmRleCk7CgogICAgICAgIC8qKgogICAgICAgICAqIFJldHVybnMgdGhlIG51bWJlciBvZiBlbGVtZW50cyBpbiB0aGUgdmVjdG9yLgogICAgICAgICAqIEByZXR1cm4gdGhlIHNpemUgb2YgdmVjdG9yLgogICAgICAgICAqLwogICAgICAgIGludDMyX3QgICAgICAgICAgICAgc2l6ZSh2b2lkKSBjb25zdDsKCiAgICAgICAgLyoqCiAgICAgICAgICogQ2hlY2tzIGlmIHRoaXMgdmVjdG9yIG9iamVjdCBpcyB2YWxpZC4KICAgICAgICAgKiBAcmV0dXJuIFRSVUUgaWYgdGhlIHZlY3RvciBvYmplY3QgaXMgdmFsaWQsIEZBTFNFIG90aGVyd2lzZS4KICAgICAgICAgKi8KICAgICAgICBVQm9vbCAgICAgICAgICAgICAgaXNCb2d1cyh2b2lkKSBjb25zdDsKCiAgICAvKioKICAgICAqIFRoZSBzdHJlYW1JbiBhbmQgc3RyZWFtT3V0IG1ldGhvZHMgcmVhZCBhbmQgd3JpdGUgb2JqZWN0cyBvZiB0aGlzCiAgICAgKiBjbGFzcyBhcyBiaW5hcnksIHBsYXRmb3JtLWRlcGVuZGVudCBkYXRhIGluIHRoZSBpb3N0cmVhbS4gIFRoZSBzdHJlYW0KICAgICAqIG11c3QgYmUgaW4gaW9zOjpiaW5hcnkgbW9kZSBmb3IgdGhpcyB0byB3b3JrLiAgVGhlc2UgbWV0aG9kcyBhcmUgbm90CiAgICAgKiBpbnRlbmRlZCBmb3IgZ2VuZXJhbCBwdWJsaWMgdXNlOyB0aGV5IGFyZSB1c2VkIGJ5IHRoZSBmcmFtZXdvcmsgdG8gaW1wcm92ZQogICAgICogcGVyZm9ybWFuY2UgYnkgc3RvcmluZyBjZXJ0YWluIG9iamVjdHMgaW4gYmluYXJ5IGZpbGVzLgogICAgICovCiAgICAgICAgdm9pZCAgICAgICAgICAgICAgICBzdHJlYW1PdXQoRmlsZVN0cmVhbSogb3MpIGNvbnN0OwogICAgICAgIHZvaWQgICAgICAgICAgICAgICAgc3RyZWFtSW4oRmlsZVN0cmVhbSogaXMpOwoKICAgICAgICB2b2lkICAgICAgICAgICAgICAgIHN0cmVhbU91dChVTWVtb3J5U3RyZWFtKiBvcykgY29uc3Q7CiAgICAgICAgdm9pZCAgICAgICAgICAgICAgICBzdHJlYW1JbihVTWVtb3J5U3RyZWFtKiBpcyk7CgogICAgcHJpdmF0ZToKICAgICAgICAvKioKICAgICAgICAgKiBSZXNpemVzIHRoZSB2ZWN0b3IgaWYgbmVjZXNzYXJ5IHdoZW4gY29tcGFyZWQgdG8gYSBuZXcgc2l6ZS4KICAgICAgICAgKiBAcGFyYW0gbmV3U2l6ZSB0aGUgbmV3IHNpemUuCiAgICAgICAgICovCiAgICAgICAgdm9pZCAgICAgICAgICAgICAgICByZXNpemUoaW50MzJfdCAgICAgIG5ld1NpemUpOwoKICAgICAgICBpbnQzMl90ICAgICAgICAgICAgIGZTaXplOwogICAgICAgIGludDMyX3QgICAgICAgICAgICAgZkNhcGFjaXR5OwogICAgICAgIFZlY3Rvck9mSW50KiogICAgICAgZkVsZW1lbnRzOwogICAgICAgIFVCb29sICAgICAgICAgICAgICBmQm9ndXM7Cn07CgpjbGFzcyBWZWN0b3JPZlBUb0NvbnRyYWN0RWxlbWVudDsKCi8qKiAKICogUFRvQ29udHJhY3RFbGVtZW50IGlzIGEgc21hcnQtcG9pbnRlciB0byBhbiBhcnJheSB0aGF0IGlzIHVzZWQgdG8gc3RvcmUKICogdGhlIGNvbnRyYWN0aW5nLWNoYXJhY3RlciBzdHJpbmdzIHRoYXQgYXJlIGFzc29jaWF0ZWQgd2l0aCBhIGdpdmVuIFVuaWNvZGUgY2hhcmFjdGVyLgogKiA8UD4KICogWW91IGNhbiB1c2UgdGhpcyBvYmplY3QgYXMgaWYgaXQgd2VyZSBhIHBvaW50ZXIgdG8gYW4gRW50cnlQYWlyIGFycmF5LCBlLmcuCiAqIDxwcmU+CiAqIFBUb0NvbnRyYWN0RWxlbWVudCBmb28gPSAuLi4uOwogKiBmb28tPmVudHJ5TmFtZSA9IC4uLi47CiAqIDwvcHJlPgogKi8KY2xhc3MgUFRvQ29udHJhY3RFbGVtZW50IHsKICAgIHB1YmxpYzoKICAgICAgICAvKioKICAgICAgICAgKiBEZXN0cnVjdG9yLgogICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH5QVG9Db250cmFjdEVsZW1lbnQoKTsKICAgICAgICAKICAgICAgICAvKioKICAgICAgICAgKiBBc3NpZ25tZW50IG9wZXJhdG9ycwogICAgICAgICAqIFRoZSBFbnRyeVBhaXIgdGhhdCB0aGlzIG9iamVjdCBhbHJlYWR5IHBvaW50cyB0byAoaWYgYW55KSBpcyBkZWxldGVkLgogICAgICAgICAqLwogICAgICAgIGNvbnN0IFBUb0NvbnRyYWN0RWxlbWVudCYgICAgICAgICAgICAgICBvcGVyYXRvcj0oRW50cnlQYWlyKiAgICBuZXdWYWx1ZSk7CiAgICAgICAgY29uc3QgUFRvQ29udHJhY3RFbGVtZW50JiAgICAgICAgICAgICAgIG9wZXJhdG9yPShjb25zdCBQVG9Db250cmFjdEVsZW1lbnQmIHBvaW50ZXJUb05ld1ZhbHVlKTsKCiAgICAgICAgLyoqCiAgICAgICAgICogUG9pbnRlciBvcGVyYXRvciBvdmVycmlkZQogICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wZXJhdG9yIEVudHJ5UGFpciooKSBjb25zdDsKCiAgICBwcml2YXRlOgogICAgICAgIC8qKgogICAgICAgICAqIENvbnN0cnVjdG9yCiAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUFRvQ29udHJhY3RFbGVtZW50KEVudHJ5UGFpciomICB2YWx1ZSk7CiAgICAgICAgLyoqCiAgICAgICAgICogQ29weSBjb25zdHJ1Y3Rvci4KICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQVG9Db250cmFjdEVsZW1lbnQoY29uc3QgUFRvQ29udHJhY3RFbGVtZW50JiAgICB0aGF0KTsKCiAgICAgICAgRW50cnlQYWlyKiYgICAgICAgICAgICAgICAgICAgICBmVmFsdWU7CgogICAgICAgIGZyaWVuZCBjbGFzcyBWZWN0b3JPZlBUb0NvbnRyYWN0RWxlbWVudDsKfTsKCi8qKgogKiAgVGhlIHRhYmxlIHRoYXQgY29udGFpbnMgdGhlIGxpc3Qgb2YgY29udHJhY3RpbmcgY2hhcmFjdGVyIGVudHJpZXMuCiAqICA8UD4KICogIFRoaXMgaXMgYSB2ZWN0b3IgY2xhc3MgdGhhdCBpcyBkZXNpZ25lZCB0byBiZSB1c2VkIHdpdGggcG9pbnRlciB0eXBlcyBhbmQgd2hpY2ggaW1wbGVtZW50cwogKiAgb3duaW5nIHNlbWFudGljcy4gIFRoYXQgaXMsIG9uY2UgYSB2YWx1ZSBpcyBwbGFjZWQgYW4gZWxlbWVudCBvZiB0aGUgdmVjdG9yLCB0aGUgdmVjdG9yIGlzCiAqICBjb25zaWRlcmVkIHRvIG93biBpdCBhbmQgaXMgcmVzcG9uc2libGUgZm9yIGRpc3Bvc2luZyBpdC4gIFRoaXMgd2lsbCBoYXBwZW4gYm90aCB3aGVuIHRoZQogKiAgZWxlbWVudCBpcyBjaGFuZ2VkIHVzaW5nIGF0UHV0KCkgb3IgdGhyb3VnaCBhbiBQb2ludGVyVG8qKioqLCBhbmQgd2hlbiB0aGUgdmVjdG9yIGl0c2VsZiBpcwogKiAgZGlzcG9zZWQuICAKICogIDxQPgogKiAgV0FSTklORzogIFRoZSBjYWxsZXIgbXVzdCBiZSBjYXJlZnVsIHRvIGF2b2lkIGhvbGRpbmcgb250byBhbnkgZGFuZ2xpbmcgcmVmZXJlbmNlcwogKiAgYWZ0ZXIgdGhlIHZlY3RvciBpcyBkaXNwb3NlZCwgYW5kIHRoZSBjYWxsZXIgbXVzdCBhbHNvIGJlIGNhcmVmdWwgbm90IHRvIHB1dCB0aGUgc2FtZQogKiAgdmFsdWUgaW50byBtb3JlIHRoYW4gb25lIGVsZW1lbnQgaW4gdGhlIHZlY3RvciAodW5sZXNzIHRoZSB2YWx1ZSBpcyBOVUxMKS4KICogIDxQPgogKiAgQXMgd2l0aCBWZWN0b3JPZioqKj4sIHRoZSB2ZWN0b3IgZ3Jvd3MgYXMgbmVjZXNzYXJ5IHRvIGFjY29tbW9kYXRlIGFsbCBlbGVtZW50cywgdGhlCiAqICBzaXplIGlzIG9uZSBwbHVzIHRoZSBpbmRleCBvZiB0aGUgaGlnaGVzdCBlbGVtZW50IHRoYXQncyBiZWVuIHNldCwgYW5kIGFueSBlbGVtZW50cyBiZWxvdwogKiAgdGhlIGhpZ2hlc3QgZWxlbWVudCB0aGF0IGFyZW4ndCBleHBsaWNpdGx5IGluaXRpYWxpemVkIGFyZSBpbml0aWFsaXplZCB0byBOVUxMLgogKi8KY2xhc3MgVmVjdG9yT2ZQVG9Db250cmFjdEVsZW1lbnQgewogICAgcHVibGljOgogICAgICAgIC8qKgogICAgICAgICAqIFRoZSBjaHVuayBzaXplIGJ5IHdoaWNoIHRoZSBhcnJheSBpcyBncm93bi4KICAgICAgICAgKiBUaGlzIHByb2JhYmx5IHNob3VsZG4ndCBiZSBpbiB0aGUgQVBJCiAgICAgICAgICovCiAgICAgICAgZW51bSBFR3Jvd3RoUmF0ZSB7IEdST1dUSF9SQVRFID0gNCB9OwogICAgICAgIC8qKgogICAgICAgICAqIENyZWF0ZXMgYSB2ZWN0b3IgdGhhdCBjb250YWlucyBlbGVtZW50cyBvZiBQVG9Db250cmFjdEVsZW1lbnQuCiAgICAgICAgICogQHBhcmFtIGluaXRpYWxTaXplIHRoZSBpbml0aWFsIHNpemUgb2YgdGhlIHZlY3RvciBvYmplY3QuCiAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBWZWN0b3JPZlBUb0NvbnRyYWN0RWxlbWVudChpbnQzMl90ICBpbml0aWFsU2l6ZSA9IDApOwogICAgICAgIC8qKgogICAgICAgICAqIENvcHkgY29uc3RydWN0b3IuCiAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBWZWN0b3JPZlBUb0NvbnRyYWN0RWxlbWVudChjb25zdCBWZWN0b3JPZlBUb0NvbnRyYWN0RWxlbWVudCYgICAgdGhhdCk7CgogICAgICAgIC8qKgogICAgICAgICAqIERlc3RydWN0b3IuCiAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB+VmVjdG9yT2ZQVG9Db250cmFjdEVsZW1lbnQoKTsKCiAgICAgICAgLyoqCiAgICAgICAgICogQXNzaWdubWVudCBvcGVyYXRvci4KICAgICAgICAgKi8KICAgICAgICBjb25zdCBWZWN0b3JPZlBUb0NvbnRyYWN0RWxlbWVudCYgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wZXJhdG9yPShjb25zdCBWZWN0b3JPZlBUb0NvbnRyYWN0RWxlbWVudCYgdGhhdCk7CgogICAgICAgIC8qKgogICAgICAgICAqIFJldHVybiBhIG1vZGlmaWFibGUgc21hcnQtcG9pbnRlciB0byB0aGUgRW50cnlQYWlyCiAgICAgICAgICogYXQgdGhlIGdpdmVuIGluZGV4LiAgQXNzaWduaW5nIHRvIHRoaXMgc21hcnQgcG9pbnRlciB3aWxsIHdvcmssIGUuZy4KICAgICAgICAgKiA8cHJlPgogICAgICAgICAqICBQVG9Db250cmFjdEVsZW1lbnQgZm9vID0gLi4uLjsKICAgICAgICAgKiAgZm9vWzVdID0gLi4uOwogICAgICAgICAqIDwvcHJlPgogICAgICAgICAqIFRoaXMgZG9lcyByYW5nZS1jaGVja2luZzsgYWNjZXNzIHRvIGVsZW1lbnRzIGJleW9uZCB0aGUgZW5kIG9mIHRoZQogICAgICAgICAqIGFycmF5IHdpbGwgY2F1c2UgdGhlIGFycmF5IHRvIGdyb3cuCiAgICAgICAgICovCiAgICAgICAgUFRvQ29udHJhY3RFbGVtZW50ICBvcGVyYXRvcltdKGludDMyX3QgIGluZGV4KTsKICAgICAgICBQVG9Db250cmFjdEVsZW1lbnQgIGF0KGludDMyX3QgIGluZGV4KTsKCiAgICAgICAgLyoqCiAgICAgICAgICogUmV0dXJuIGEgcG9pbnRlciB0byB0aGUgRW50cnlQYWlyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICAgKiBUaGUgcG9pbnRlciBpdHNlbGYgY2Fubm90IGJlIG1vZGlmaWVkLCBidXQgdGhlIGVsZW1lbnRzIGl0IHBvaW50cyB0byBtYXk6CiAgICAgICAgICogPHByZT4KICAgICAgICAgKiAgY29uc3QgVmVjdG9yT2ZQVG9FeHBhbmRUYWJsZSBmb28gPSAuLi4uOwogICAgICAgICAqICBmb29bNV0gPSAuLi4uOyAgICAgICAgICAgICAgLy8gTk9UIEFMTE9XRUQKICAgICAgICAgKiAgZm9vWzVdLT5lbnRyeU5hbWUgPSAuLi4uOyAgIC8vIG9rCiAgICAgICAgICogPC9wcmU+CiAgICAgICAgICogVGhpcyBkb2VzIG5vdCBkbyByYW5nZS1jaGVja2luZzsgYW4gaW52YWxpZCBpbmRleCBtYXkgY2F1c2UgYSBjcmFzaC4KICAgICAgICAgKiBAcmV0dXJuIHRoZSBhY2Nlc3NlZCBlbGVtZW50LgogICAgICAgICAqLwogICAgICAgIEVudHJ5UGFpciogICAgICAgICAgb3BlcmF0b3JbXShpbnQzMl90ICBpbmRleCkgY29uc3Q7CiAgICAgICAgRW50cnlQYWlyKiAgICAgICAgICBhdChpbnQzMl90ICBpbmRleCkgY29uc3Q7CgogICAgICAgIC8qKgogICAgICAgICAqIFNldHMgdGhlIGVsZW1lbnQgYXQgdGhlIHNwZWNpZmllZCBpbmRleCB0byBhIGRpZmZlcmVudCB2YWx1ZS4KICAgICAgICAgKiBJZiB0aGVyZSB3YXMgYXJlYWR5IGFuIG9iamVjdCBzdG9yZWQgYXQgdGhpcyBpbmRleCwgaXQgaXMgZGVsZXRlZC4KICAgICAgICAgKiBAcGFyYW0gaW5kZXggdGhlIHNwZWNpZmllZCBpbmRleC4KICAgICAgICAgKiBAcGFyYW0gdmFsdWUgdGhlIG5ldyB2YWx1ZS4KICAgICAgICAgKi8KICAgICAgICB2b2lkICAgICAgICAgICAgICAgIGF0UHV0KCAgaW50MzJfdCAgICAgICAgIGluZGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFbnRyeVBhaXIqICAgICAgdmFsdWUpOwogICAgICAgIC8qKgogICAgICAgICAqIEluc2VydHMgYSB2YWx1ZSBhdCB0aGUgc3BlY2lmaWVkIGluZGV4LCBzbGlkaW5nIHRoZSByZXN0IG9mCiAgICAgICAgICogdGhlIGVsZW1lbnRzIGluIHRoZSBhcnJheSBvdmVyIHRvIG1ha2Ugcm9vbS4KICAgICAgICAgKiBAcGFyYW0gaW5kZXggdGhlIHNwZWNpZmllZCBpbmRleC4KICAgICAgICAgKiBAcGFyYW0gdmFsdWUgdGhlIHZhbHVlLgogICAgICAgICAqLwogICAgICAgIHZvaWQgICAgICAgICAgICAgICAgYXRJbnNlcnQoICAgaW50MzJfdCAgICAgaW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFbnRyeVBhaXIqICB2YWx1ZSk7CiAgICAgICAgLyoqCiAgICAgICAgICogIk9ycGhhbiIgdGhlIHBvaW50ZXIgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4gIFRoZSBhcnJheSB3aWxsIG5vCiAgICAgICAgICogbG9uZ2VyIGNvbnRhaW4gYSByZWZlcmVuY2UgdG8gdGhlIG9iamVjdCwgYW5kIHRoZSBjYWxsZXIgaXMKICAgICAgICAgKiBub3cgcmVzcG9uc2libGUgZm9yIGRlbGV0aW5nIGl0cyBzdG9yYWdlLgogICAgICAgICAqLwogICAgICAgIEVudHJ5UGFpciogICAgICAgICAgb3JwaGFuQXQoaW50MzJfdCAgICBpbmRleCk7CgogICAgICAgIC8qKgogICAgICAgICAqIFJldHVybnMgdGhlIG51bWJlciBvZiBlbGVtZW50cyBpbiB0aGUgdmVjdG9yLgogICAgICAgICAqIEByZXR1cm4gdGhlIHNpemUgb2YgdmVjdG9yLgogICAgICAgICAqLwogICAgICAgIGludDMyX3QgICAgICAgICAgICAgc2l6ZSh2b2lkKSBjb25zdDsKCiAgICAgICAgLyoqCiAgICAgICAgICogQ2hlY2tzIGlmIHRoaXMgdmVjdG9yIG9iamVjdCBpcyB2YWxpZC4KICAgICAgICAgKiBAcmV0dXJuIFRSVUUgaWYgdGhlIHZlY3RvciBvYmplY3QgaXMgdmFsaWQsIEZBTFNFIG90aGVyd2lzZS4KICAgICAgICAgKi8KICAgICAgICBVQm9vbCAgICAgICAgICAgICAgaXNCb2d1cyh2b2lkKSBjb25zdDsKCiAgICAgICAgLyoqCiAgICAgICAgICogVGhlIHN0cmVhbUluIGFuZCBzdHJlYW1PdXQgbWV0aG9kcyByZWFkIGFuZCB3cml0ZSBvYmplY3RzIG9mIHRoaXMKICAgICAgICAgKiBjbGFzcyBhcyBiaW5hcnksIHBsYXRmb3JtLWRlcGVuZGVudCBkYXRhIGluIHRoZSBpb3N0cmVhbS4gIFRoZSBzdHJlYW0KICAgICAgICAgKiBtdXN0IGJlIGluIGlvczo6YmluYXJ5IG1vZGUgZm9yIHRoaXMgdG8gd29yay4gIFRoZXNlIG1ldGhvZHMgYXJlIG5vdAogICAgICAgICAqIGludGVuZGVkIGZvciBnZW5lcmFsIHB1YmxpYyB1c2U7IHRoZXkgYXJlIHVzZWQgYnkgdGhlIGZyYW1ld29yayB0byBpbXByb3ZlCiAgICAgICAgICogcGVyZm9ybWFuY2UgYnkgc3RvcmluZyBjZXJ0YWluIG9iamVjdHMgaW4gYmluYXJ5IGZpbGVzLgogICAgICAgICAqLwogICAgICAgIHZvaWQgICAgICAgICAgICAgICAgc3RyZWFtT3V0KEZpbGVTdHJlYW0qIG9zKSBjb25zdDsKICAgICAgICB2b2lkICAgICAgICAgICAgICAgIHN0cmVhbUluKEZpbGVTdHJlYW0qIGlzKTsKICAgICAgICB2b2lkICAgICAgICAgICAgICAgIHN0cmVhbU91dChVTWVtb3J5U3RyZWFtKiBvcykgY29uc3Q7CiAgICAgICAgdm9pZCAgICAgICAgICAgICAgICBzdHJlYW1JbihVTWVtb3J5U3RyZWFtKiBpcyk7CgogICAgcHJpdmF0ZToKICAgICAgICAvKioKICAgICAgICAgKiBSZXNpemVzIHRoZSB2ZWN0b3IgaWYgbmVjZXNzYXJ5IHdoZW4gY29tcGFyZWQgdG8gYSBuZXcgc2l6ZS4KICAgICAgICAgKiBAcGFyYW0gbmV3U2l6ZSB0aGUgbmV3IHNpemUuCiAgICAgICAgICovCiAgICAgICAgdm9pZCAgICAgICAgICAgICAgICByZXNpemUoaW50MzJfdCAgICAgIG5ld1NpemUpOwoKICAgICAgICBpbnQzMl90ICAgICAgICAgICAgIGZTaXplOwogICAgICAgIGludDMyX3QgICAgICAgICAgICAgZkNhcGFjaXR5OwogICAgICAgIEVudHJ5UGFpcioqICAgICAgICAgZkVsZW1lbnRzOwogICAgICAgIFVCb29sICAgICAgICAgICAgICBmQm9ndXM7Cn07CgpjbGFzcyBWZWN0b3JPZlBUb0NvbnRyYWN0VGFibGU7CgovKioKICogUG9pbnRlciB0byBlYWNoIGNvbnRyYWNpbmcgZWxlbWVudCBsaXN0LgogKi8KY2xhc3MgUFRvQ29udHJhY3RUYWJsZSB7CiAgICBwdWJsaWM6CiAgICAgICAgLyoqCiAgICAgICAgICogRGVzdHJ1Y3Rvci4KICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB+UFRvQ29udHJhY3RUYWJsZSgpOwogICAgICAgIAogICAgICAgIC8qKgogICAgICAgICAqIEFzc2lnbm1lbnQgb3BlcmF0b3JzLgogICAgICAgICAqIDxQPgogICAgICAgICAqIFRoZSBjb250cmFjdGluZyBlbGVtZW50IGxpc3QgKGlmIGFueSkgdGhhdCB0aGlzIG9iamVjdCBhbHJlYWR5IHBvaW50cyB0bwogICAgICAgICAqIGlzIGRlbGV0ZWQuCiAgICAgICAgICovCiAgICAgICAgY29uc3QgUFRvQ29udHJhY3RUYWJsZSYgICAgICAgICAgICAgb3BlcmF0b3I9KFZlY3Rvck9mUFRvQ29udHJhY3RFbGVtZW50KiAgIG5ld1ZhbHVlKTsKICAgICAgICBjb25zdCBQVG9Db250cmFjdFRhYmxlJiAgICAgICAgICAgICBvcGVyYXRvcj0oY29uc3QgUFRvQ29udHJhY3RUYWJsZSYgICBwb2ludGVyVG9OZXdWYWx1ZSk7CgogICAgICAgIC8qKgogICAgICAgICAqIFBvaW50ZXIgb3BlcmF0b3Igb3ZlcnJpZGUKICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcGVyYXRvciBWZWN0b3JPZlBUb0NvbnRyYWN0RWxlbWVudCooKSBjb25zdDsKCiAgICBwcml2YXRlOgogICAgICAgIC8qKgogICAgICAgICAqIENvbnN0cnVjdG9yCiAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUFRvQ29udHJhY3RUYWJsZShWZWN0b3JPZlBUb0NvbnRyYWN0RWxlbWVudComICAgdmFsdWUpOwogICAgICAgIC8qKgogICAgICAgICAqIENvcHkgY29uc3RydWN0b3IuCiAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUFRvQ29udHJhY3RUYWJsZShjb25zdCBQVG9Db250cmFjdFRhYmxlJiAgICB0aGF0KTsKCiAgICAgICAgVmVjdG9yT2ZQVG9Db250cmFjdEVsZW1lbnQqJiAgICAgICAgICAgICAgICAgICAgICAgIGZWYWx1ZTsKCiAgICAgICAgZnJpZW5kIGNsYXNzIFZlY3Rvck9mUFRvQ29udHJhY3RUYWJsZTsKfTsKCi8qKgogKiBUaGUgdmVjdG9yIHRoYXQgY29udGFpbnMgYWxsIGNvbnRyYWN0aW5nIGxpc3QgdGFibGVzLgogKiAgPFA+CiAqICBUaGlzIGlzIGEgdmVjdG9yIGNsYXNzIHRoYXQgaXMgZGVzaWduZWQgdG8gYmUgdXNlZCB3aXRoIHBvaW50ZXIgdHlwZXMgYW5kIHdoaWNoIGltcGxlbWVudHMKICogIG93bmluZyBzZW1hbnRpY3MuICBUaGF0IGlzLCBvbmNlIGEgdmFsdWUgaXMgcGxhY2VkIGFuIGVsZW1lbnQgb2YgdGhlIHZlY3RvciwgdGhlIHZlY3RvciBpcwogKiAgY29uc2lkZXJlZCB0byBvd24gaXQgYW5kIGlzIHJlc3BvbnNpYmxlIGZvciBkaXNwb3NpbmcgaXQuICBUaGlzIHdpbGwgaGFwcGVuIGJvdGggd2hlbiB0aGUKICogIGVsZW1lbnQgaXMgY2hhbmdlZCB1c2luZyBhdFB1dCgpIG9yIHRocm91Z2ggYW4gUG9pbnRlclRvKioqKiwgYW5kIHdoZW4gdGhlIHZlY3RvciBpdHNlbGYgaXMKICogIGRpc3Bvc2VkLiAgCiAqICA8UD4KICogIFdBUk5JTkc6ICBUaGUgY2FsbGVyIG11c3QgYmUgY2FyZWZ1bCB0byBhdm9pZCBob2xkaW5nIG9udG8gYW55IGRhbmdsaW5nIHJlZmVyZW5jZXMKICogIGFmdGVyIHRoZSB2ZWN0b3IgaXMgZGlzcG9zZWQsIGFuZCB0aGUgY2FsbGVyIG11c3QgYWxzbyBiZSBjYXJlZnVsIG5vdCB0byBwdXQgdGhlIHNhbWUKICogIHZhbHVlIGludG8gbW9yZSB0aGFuIG9uZSBlbGVtZW50IGluIHRoZSB2ZWN0b3IgKHVubGVzcyB0aGUgdmFsdWUgaXMgTlVMTCkuCiAqICA8UD4KICogIEFzIHdpdGggVmVjdG9yT2YqKio+LCB0aGUgdmVjdG9yIGdyb3dzIGFzIG5lY2Vzc2FyeSB0byBhY2NvbW1vZGF0ZSBhbGwgZWxlbWVudHMsIHRoZQogKiAgc2l6ZSBpcyBvbmUgcGx1cyB0aGUgaW5kZXggb2YgdGhlIGhpZ2hlc3QgZWxlbWVudCB0aGF0J3MgYmVlbiBzZXQsIGFuZCBhbnkgZWxlbWVudHMgYmVsb3cKICogIHRoZSBoaWdoZXN0IGVsZW1lbnQgdGhhdCBhcmVuJ3QgZXhwbGljaXRseSBpbml0aWFsaXplZCBhcmUgaW5pdGlhbGl6ZWQgdG8gTlVMTC4KICovCmNsYXNzIFZlY3Rvck9mUFRvQ29udHJhY3RUYWJsZSB7CiAgICBwdWJsaWM6CiAgICAgICAgLyoqCiAgICAgICAgICogVGhlIGNodW5rIHNpemUgYnkgd2hpY2ggdGhlIGFycmF5IGlzIGdyb3duLgogICAgICAgICAqIFRoaXMgcHJvYmFibHkgc2hvdWxkbid0IGJlIGluIHRoZSBBUEkKICAgICAgICAgKi8KICAgICAgICBlbnVtIEVHcm93dGhSYXRlIHsgR1JPV1RIX1JBVEUgPSA0IH07CiAgICAgICAgLyoqCiAgICAgICAgICogQ3JlYXRlcyBhIHZlY3RvciB0aGF0IGNvbnRhaW5zIGVsZW1lbnRzIG9mIFBUb0NvbnRyYWN0VGFibGUuCiAgICAgICAgICogQHBhcmFtIGluaXRpYWxTaXplIHRoZSBpbml0aWFsIHNpemUgb2YgdGhlIHZlY3RvciBvYmplY3QuCiAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBWZWN0b3JPZlBUb0NvbnRyYWN0VGFibGUoaW50MzJfdCAgICBpbml0aWFsU2l6ZSA9IDApOwogICAgICAgIC8qKgogICAgICAgICAqIENvcHkgY29uc3RydWN0b3IuCiAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBWZWN0b3JPZlBUb0NvbnRyYWN0VGFibGUoY29uc3QgVmVjdG9yT2ZQVG9Db250cmFjdFRhYmxlJiAgICB0aGF0KTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB+VmVjdG9yT2ZQVG9Db250cmFjdFRhYmxlKCk7CgogICAgICAgIC8qKgogICAgICAgICAqIEFzc2lnbm1lbnQgb3BlcmF0b3IuCiAgICAgICAgICovCiAgICAgICAgY29uc3QgVmVjdG9yT2ZQVG9Db250cmFjdFRhYmxlJiAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wZXJhdG9yPShjb25zdCBWZWN0b3JPZlBUb0NvbnRyYWN0VGFibGUmICAgdGhhdCk7CgogICAgICAgIC8qKgogICAgICAgICAqIFJldHVybiBhIG1vZGlmaWFibGUgc21hcnQtcG9pbnRlciB0byB0aGUgY29udHJhY3Rpb24gdGFibGUKICAgICAgICAgKiBhdCB0aGUgZ2l2ZW4gaW5kZXguICBBc3NpZ25pbmcgdG8gdGhpcyBzbWFydCBwb2ludGVyIHdpbGwgd29yaywgZS5nLgogICAgICAgICAqIDxwcmU+CiAgICAgICAgICogIFZlY3Rvck9mUFRvQ29udHJhY3RUYWJsZSBmb28gPSAuLi4uOwogICAgICAgICAqICBmb29bNV0gPSAuLi47CiAgICAgICAgICogPC9wcmU+CiAgICAgICAgICogVGhpcyBkb2VzIHJhbmdlLWNoZWNraW5nOyBhY2Nlc3MgdG8gZWxlbWVudHMgYmV5b25kIHRoZSBlbmQgb2YgdGhlCiAgICAgICAgICogYXJyYXkgd2lsbCBjYXVzZSB0aGUgYXJyYXkgdG8gZ3Jvdy4KICAgICAgICAgKi8KICAgICAgICBQVG9Db250cmFjdFRhYmxlICAgICAgICBvcGVyYXRvcltdKGludDMyX3QgIGluZGV4KTsKICAgICAgICBQVG9Db250cmFjdFRhYmxlICAgICAgICBhdChpbnQzMl90ICBpbmRleCk7CgogICAgICAgIC8qKgogICAgICAgICAqIFJldHVybiBhIHBvaW50ZXIgdG8gdGhlIGNvbnRyYWN0aW9uIHRhYmxlIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICAgKiBUaGUgcG9pbnRlciBpdHNlbGYgY2Fubm90IGJlIG1vZGlmaWVkLCBidXQgdGhlIGVsZW1lbnRzIGl0IHBvaW50cyB0byBtYXk6CiAgICAgICAgICogPHByZT4KICAgICAgICAgKiAgY29uc3QgVmVjdG9yT2ZQVG9FeHBhbmRUYWJsZSBmb28gPSAuLi4uOwogICAgICAgICAqICBmb29bNV0gPSAuLi4uOyAgICAgICAgICAgICAgLy8gTk9UIEFMTE9XRUQKICAgICAgICAgKiAgZm9vWzVdWzBdID0gLi4uLjsgICAgICAgICAgIC8vIG9rCiAgICAgICAgICogPC9wcmU+CiAgICAgICAgICogVGhpcyBkb2VzIG5vdCBkbyByYW5nZS1jaGVja2luZzsgYW4gaW52YWxpZCBpbmRleCBtYXkgY2F1c2UgYSBjcmFzaC4KICAgICAgICAgKiBAcmV0dXJuIHRoZSBhY2Nlc3NlZCBlbGVtZW50LgogICAgICAgICAqLwogICAgICAgIFZlY3Rvck9mUFRvQ29udHJhY3RFbGVtZW50KiAgICAgb3BlcmF0b3JbXShpbnQzMl90ICBpbmRleCkgY29uc3Q7CiAgICAgICAgVmVjdG9yT2ZQVG9Db250cmFjdEVsZW1lbnQqICAgICBhdChpbnQzMl90ICBpbmRleCkgY29uc3Q7CgogICAgICAgIC8qKgogICAgICAgICAqIFNldHMgdGhlIGVsZW1lbnQgYXQgdGhlIHNwZWNpZmllZCBpbmRleCB0byBhIGRpZmZlcmVudCB2YWx1ZS4KICAgICAgICAgKiBJZiB0aGVyZSB3YXMgYXJlYWR5IGFuIG9iamVjdCBzdG9yZWQgYXQgdGhpcyBpbmRleCwgaXQgaXMgZGVsZXRlZC4KICAgICAgICAgKiBAcGFyYW0gaW5kZXggdGhlIHNwZWNpZmllZCBpbmRleC4KICAgICAgICAgKiBAcGFyYW0gdmFsdWUgdGhlIG5ldyB2YWx1ZS4KICAgICAgICAgKi8KICAgICAgICB2b2lkICAgICAgICAgICAgICAgIGF0UHV0KCAgaW50MzJfdCAgICAgICAgIGluZGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWZWN0b3JPZlBUb0NvbnRyYWN0RWxlbWVudCogdmFsdWUpOwogICAgICAgIC8qKgogICAgICAgICAqICJPcnBoYW4iIHRoZSBwb2ludGVyIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXguICBUaGUgYXJyYXkgd2lsbCBubwogICAgICAgICAqIGxvbmdlciBjb250YWluIGEgcmVmZXJlbmNlIHRvIHRoZSBvYmplY3QsIGFuZCB0aGUgY2FsbGVyIGlzCiAgICAgICAgICogbm93IHJlc3BvbnNpYmxlIGZvciBkZWxldGluZyBpdHMgc3RvcmFnZS4KICAgICAgICAgKi8KICAgICAgICBWZWN0b3JPZlBUb0NvbnRyYWN0RWxlbWVudCogICAgIG9ycGhhbkF0KGludDMyX3QgICAgaW5kZXgpOwoKICAgICAgICAvKioKICAgICAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgaW4gdGhlIHZlY3Rvci4KICAgICAgICAgKiBAcmV0dXJuIHRoZSBzaXplIG9mIHZlY3Rvci4KICAgICAgICAgKi8KICAgICAgICBpbnQzMl90ICAgICAgICAgICAgIHNpemUodm9pZCkgY29uc3Q7CgogICAgICAgIC8qKgogICAgICAgICAqIENoZWNrcyBpZiB0aGlzIHZlY3RvciBvYmplY3QgaXMgdmFsaWQuCiAgICAgICAgICogQHJldHVybiBUUlVFIGlmIHRoZSB2ZWN0b3Igb2JqZWN0IGlzIHZhbGlkLCBGQUxTRSBvdGhlcndpc2UuCiAgICAgICAgICovCiAgICAgICAgVUJvb2wgICAgICAgICAgICAgIGlzQm9ndXModm9pZCkgY29uc3Q7CiAgICAgICAgLyoqCiAgICAgICAgICogVGhlIHN0cmVhbUluIGFuZCBzdHJlYW1PdXQgbWV0aG9kcyByZWFkIGFuZCB3cml0ZSBvYmplY3RzIG9mIHRoaXMKICAgICAgICAgKiBjbGFzcyBhcyBiaW5hcnksIHBsYXRmb3JtLWRlcGVuZGVudCBkYXRhIGluIHRoZSBpb3N0cmVhbS4gIFRoZSBzdHJlYW0KICAgICAgICAgKiBtdXN0IGJlIGluIGlvczo6YmluYXJ5IG1vZGUgZm9yIHRoaXMgdG8gd29yay4gIFRoZXNlIG1ldGhvZHMgYXJlIG5vdAogICAgICAgICAqIGludGVuZGVkIGZvciBnZW5lcmFsIHB1YmxpYyB1c2U7IHRoZXkgYXJlIHVzZWQgYnkgdGhlIGZyYW1ld29yayB0byBpbXByb3ZlCiAgICAgICAgICogcGVyZm9ybWFuY2UgYnkgc3RvcmluZyBjZXJ0YWluIG9iamVjdHMgaW4gYmluYXJ5IGZpbGVzLgogICAgICAgICAqLwogICAgICAgIHZvaWQgICAgICAgICAgICAgICAgc3RyZWFtT3V0KEZpbGVTdHJlYW0qIG9zKSBjb25zdDsKICAgICAgICB2b2lkICAgICAgICAgICAgICAgIHN0cmVhbUluKEZpbGVTdHJlYW0qIGlzKTsKCiAgICAgICAgdm9pZCAgICAgICAgICAgICAgICBzdHJlYW1PdXQoVU1lbW9yeVN0cmVhbSogb3MpIGNvbnN0OwogICAgICAgIHZvaWQgICAgICAgICAgICAgICAgc3RyZWFtSW4oVU1lbW9yeVN0cmVhbSogaXMpOwoKICAgIHByaXZhdGU6CiAgICAgICAgLyoqCiAgICAgICAgICogUmVzaXplcyB0aGUgdmVjdG9yIGlmIG5lY2Vzc2FyeSB3aGVuIGNvbXBhcmVkIHRvIGEgbmV3IHNpemUuCiAgICAgICAgICogQHBhcmFtIG5ld1NpemUgdGhlIG5ldyBzaXplLgogICAgICAgICAqLwogICAgICAgIHZvaWQgICAgICAgICAgICAgICAgcmVzaXplKGludDMyX3QgICAgICBuZXdTaXplKTsKCiAgICAgICAgaW50MzJfdCAgICAgICAgICAgICBmU2l6ZTsKICAgICAgICBpbnQzMl90ICAgICAgICAgICAgIGZDYXBhY2l0eTsKICAgICAgICBWZWN0b3JPZlBUb0NvbnRyYWN0RWxlbWVudCoqICAgICAgICBmRWxlbWVudHM7CiAgICAgICAgVUJvb2wgICAgICAgICAgICAgIGZCb2d1czsKfTsKCmNsYXNzIFBhdHRlcm5FbnRyeTsKY2xhc3MgVmVjdG9yT2ZQb2ludGVyc1RvUGF0dGVybkVudHJ5OwoKLyoqCiAqICBQcm94eSBjbGFzcyBmb3IgYWNjZXNzaW5nIGVsZW1lbnRzIG9mIGEgVmVjdG9yT2ZQb2ludGVyc1RvUGF0dGVybkVudHJ5CiAqICA8UD4KICogIFRoaXMgY2xhc3MgaXMgYSBzaW1wbGUgcHJveHkgY2xhc3MgdGhhdCBpbXBsZW1lbnRzIHRoZSBvd25pbmcgc2VtYW50aWNzIGZvciB0aGUKICogIG9wZXJhdG9yW10gYW5kIGF0KCkgZnVuY3Rpb25zIG9uIFZlY3Rvck9mUG9pbnRlcnNUb1BhdHRlcm5FbnRyeS4gIEl0IGVuYWJsZXMKICogIGV4cHJlc3Npb25zIGxpa2UgInZbM10gPSBzb21lTmV3VmFsdWUiLiAgT25lIG5ldmVyIGNyZWF0ZXMgYSBQb2ludGVyVG9QYXR0ZXJuRW50cnkKICogIGRpcmVjdGx5LCBhbmQgb25lIG5ldmVyIGRlY2xhcmVzIHZhcmlhYmxlcyBvZiB0aGlzIHR5cGUuICBJdCBqdXN0IGV4aXN0cyB0bwogKiAgaW1wbGVtZW50IHRoZSBBUEkgb2YgVmVjdG9yT2ZQb2ludGVyc1RvUGF0dGVybkVudHJ5LgogKi8KCmNsYXNzIFBvaW50ZXJUb1BhdHRlcm5FbnRyeSB7CiAgICBwdWJsaWM6CiAgICAgICAgLyoqCiAgICAgICAgICogRGVzdHJ1Y3Rvci4KICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB+UG9pbnRlclRvUGF0dGVybkVudHJ5KCk7CiAgICAgICAgCiAgICAgICAgLyoqCiAgICAgICAgICogQXNzaWdubWVudCBvcGVyYXRvcnMKICAgICAgICAgKiBUaGUgUGF0dGVybkVudHJ5IHRoYXQgdGhpcyBvYmplY3QgYWxyZWFkeSBwb2ludHMgdG8gKGlmIGFueSkgaXMgZGVsZXRlZC4KICAgICAgICAgKi8KICAgICAgICBjb25zdCBQb2ludGVyVG9QYXR0ZXJuRW50cnkmICAgICAgICBvcGVyYXRvcj0oUGF0dGVybkVudHJ5KiBuZXdWYWx1ZSk7CiAgICAgICAgY29uc3QgUG9pbnRlclRvUGF0dGVybkVudHJ5JiAgICAgICAgb3BlcmF0b3I9KGNvbnN0IFBvaW50ZXJUb1BhdHRlcm5FbnRyeSYgIHBvaW50ZXJUb05ld1ZhbHVlKTsKCiAgICAgICAgLyoqCiAgICAgICAgICogUG9pbnRlciBvcGVyYXRvciBvdmVycmlkZQogICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wZXJhdG9yIFBhdHRlcm5FbnRyeSooKSBjb25zdDsKCiAgICBwcml2YXRlOgogICAgICAgIC8qKgogICAgICAgICAqIENvbnN0cnVjdG9yCiAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUG9pbnRlclRvUGF0dGVybkVudHJ5KFBhdHRlcm5FbnRyeSomICAgIHZhbHVlKTsKICAgICAgICAvKioKICAgICAgICAgKiBDb3B5IGNvbnN0cnVjdG9yLgogICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBvaW50ZXJUb1BhdHRlcm5FbnRyeShjb25zdCBQb2ludGVyVG9QYXR0ZXJuRW50cnkmICB0aGF0KTsKCiAgICAgICAgUGF0dGVybkVudHJ5KiYgICAgICAgICAgICAgICAgICAgICAgZlZhbHVlOwoKICAgICAgICBmcmllbmQgY2xhc3MgVmVjdG9yT2ZQb2ludGVyc1RvUGF0dGVybkVudHJ5Owp9OwoKLyoqCiAqICBTaW1wbGUgb3duaW5nLXZlY3RvciBjbGFzcwogKiAgVGhpcyBpcyBhIHZlY3RvciBjbGFzcyB0aGF0IGlzIGRlc2lnbmVkIHRvIGJlIHVzZWQgd2l0aCBwb2ludGVyIHR5cGVzIGFuZCB3aGljaCBpbXBsZW1lbnRzCiAqICBvd25pbmcgc2VtYW50aWNzLiAgVGhhdCBpcywgb25jZSBhIHZhbHVlIGlzIHBsYWNlZCBhbiBlbGVtZW50IG9mIHRoZSB2ZWN0b3IsIHRoZSB2ZWN0b3IgaXMKICogIGNvbnNpZGVyZWQgdG8gb3duIGl0IGFuZCBpcyByZXNwb25zaWJsZSBmb3IgZGlzcG9zaW5nIGl0LiAgVGhpcyB3aWxsIGhhcHBlbiBib3RoIHdoZW4gdGhlCiAqICBlbGVtZW50IGlzIGNoYW5nZWQgdXNpbmcgYXRQdXQoKSBvciB0aHJvdWdoIGFuIFBvaW50ZXJUbyoqKiosIGFuZCB3aGVuIHRoZSB2ZWN0b3IgaXRzZWxmIGlzCiAqICBkaXNwb3NlZC4gIAogKiAgPFA+CiAqICBXQVJOSU5HOiAgVGhlIGNhbGxlciBtdXN0IGJlIGNhcmVmdWwgdG8gYXZvaWQgaG9sZGluZyBvbnRvIGFueSBkYW5nbGluZyByZWZlcmVuY2VzCiAqICBhZnRlciB0aGUgdmVjdG9yIGlzIGRpc3Bvc2VkLCBhbmQgdGhlIGNhbGxlciBtdXN0IGFsc28gYmUgY2FyZWZ1bCBub3QgdG8gcHV0IHRoZSBzYW1lCiAqICB2YWx1ZSBpbnRvIG1vcmUgdGhhbiBvbmUgZWxlbWVudCBpbiB0aGUgdmVjdG9yICh1bmxlc3MgdGhlIHZhbHVlIGlzIE5VTEwpLgogKiAgPFA+CiAqICBBcyB3aXRoIFZlY3Rvck9mKioqPiwgdGhlIHZlY3RvciBncm93cyBhcyBuZWNlc3NhcnkgdG8gYWNjb21tb2RhdGUgYWxsIGVsZW1lbnRzLCB0aGUKICogIHNpemUgaXMgb25lIHBsdXMgdGhlIGluZGV4IG9mIHRoZSBoaWdoZXN0IGVsZW1lbnQgdGhhdCdzIGJlZW4gc2V0LCBhbmQgYW55IGVsZW1lbnRzIGJlbG93CiAqICB0aGUgaGlnaGVzdCBlbGVtZW50IHRoYXQgYXJlbid0IGV4cGxpY2l0bHkgaW5pdGlhbGl6ZWQgYXJlIGluaXRpYWxpemVkIHRvIE5VTEwuCiAqLwoKY2xhc3MgVmVjdG9yT2ZQb2ludGVyc1RvUGF0dGVybkVudHJ5IHsKICAgIHB1YmxpYzoKICAgICAgICAvKioKICAgICAgICAgKiBUaGUgY2h1bmsgc2l6ZSBieSB3aGljaCB0aGUgYXJyYXkgaXMgZ3Jvd24uCiAgICAgICAgICogVGhpcyBwcm9iYWJseSBzaG91bGRuJ3QgYmUgaW4gdGhlIEFQSQogICAgICAgICAqLwogICAgICAgIGVudW0gRUdyb3d0aFJhdGUgeyBHUk9XVEhfUkFURSA9IDQgfTsKICAgICAgICAvKioKICAgICAgICAgKiBDcmVhdGVzIGEgdmVjdG9yIHRoYXQgY29udGFpbnMgZWxlbWVudHMgb2YgUG9pbnRlclRvUGF0dGVybkVudHJ5LgogICAgICAgICAqIEBwYXJhbSBpbml0aWFsU2l6ZSB0aGUgaW5pdGlhbCBzaXplIG9mIHRoZSB2ZWN0b3Igb2JqZWN0LgogICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlY3Rvck9mUG9pbnRlcnNUb1BhdHRlcm5FbnRyeShpbnQzMl90ICBpbml0aWFsU2l6ZSA9IDApOwogICAgICAgIC8qKgogICAgICAgICAqIENvcHkgY29uc3RydWN0b3IuCiAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVmVjdG9yT2ZQb2ludGVyc1RvUGF0dGVybkVudHJ5KGNvbnN0IFZlY3Rvck9mUG9pbnRlcnNUb1BhdHRlcm5FbnRyeSYgdGhhdCk7CgogICAgICAgIC8qKgogICAgICAgICAqIERlc3RydWN0b3IuCiAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgflZlY3Rvck9mUG9pbnRlcnNUb1BhdHRlcm5FbnRyeSgpOwoKICAgICAgICAvKioKICAgICAgICAgKiBBc3NpZ25tZW50IG9wZXJhdG9yLgogICAgICAgICAqLwogICAgICAgIGNvbnN0IFZlY3Rvck9mUG9pbnRlcnNUb1BhdHRlcm5FbnRyeSYgb3BlcmF0b3I9KGNvbnN0IFZlY3Rvck9mUG9pbnRlcnNUb1BhdHRlcm5FbnRyeSYgdGhhdCk7CgogICAgICAgIC8qKgogICAgICAgICAqIFJldHVybiBhIG1vZGlmaWFibGUgc21hcnQtcG9pbnRlciB0byB0aGUgY29udHJhY3Rpb24gdGFibGUKICAgICAgICAgKiBhdCB0aGUgZ2l2ZW4gaW5kZXguICBBc3NpZ25pbmcgdG8gdGhpcyBzbWFydCBwb2ludGVyIHdpbGwgd29yaywgZS5nLgogICAgICAgICAqIDxwcmU+CiAgICAgICAgICogIFZlY3Rvck9mUG9pbnRlcnNUb1BhdHRlcm5FbnRyeSBmb28gPSAuLi4uOwogICAgICAgICAqICBmb29bNV0gPSAuLi47CiAgICAgICAgICogPC9wcmU+CiAgICAgICAgICogVGhpcyBkb2VzIHJhbmdlLWNoZWNraW5nOyBhY2Nlc3MgdG8gZWxlbWVudHMgYmV5b25kIHRoZSBlbmQgb2YgdGhlCiAgICAgICAgICogYXJyYXkgd2lsbCBjYXVzZSB0aGUgYXJyYXkgdG8gZ3Jvdy4KICAgICAgICAgKi8KICAgICAgICBQb2ludGVyVG9QYXR0ZXJuRW50cnkgICAgICAgICAgICAgICBvcGVyYXRvcltdKGludDMyX3QgIGluZGV4KTsKICAgICAgICBpbmxpbmUgUG9pbnRlclRvUGF0dGVybkVudHJ5ICAgICAgICBhdChpbnQzMl90ICBpbmRleCkgeyByZXR1cm4gKCp0aGlzKVtpbmRleF07IH0KCiAgICAgICAgLyoqCiAgICAgICAgICogUmV0dXJuIGEgcG9pbnRlciB0byB0aGUgRW50cnlQYWlyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICAgKiBUaGUgcG9pbnRlciBpdHNlbGYgY2Fubm90IGJlIG1vZGlmaWVkLCBidXQgdGhlIGVsZW1lbnRzIGl0IHBvaW50cyB0byBtYXk6CiAgICAgICAgICogPHByZT4KICAgICAgICAgKiAgY29uc3QgVmVjdG9yT2ZQb2ludGVyc1RvUGF0dGVybkVudHJ5Zm9vID0gLi4uLjsKICAgICAgICAgKiAgZm9vWzVdID0gLi4uLjsgICAgICAgICAgICAgIC8vIE5PVCBBTExPV0VECiAgICAgICAgICogIGZvb1s1XS0+Z2V0U3RyZW5ndGgoKTsgICAgICAvLyBvawogICAgICAgICAqIDwvcHJlPgogICAgICAgICAqIFRoaXMgZG9lcyBub3QgZG8gcmFuZ2UtY2hlY2tpbmc7IGFuIGludmFsaWQgaW5kZXggbWF5IGNhdXNlIGEgY3Jhc2guCiAgICAgICAgICogQHJldHVybiB0aGUgYWNjZXNzZWQgZWxlbWVudC4KICAgICAgICAgKi8KICAgICAgICBQYXR0ZXJuRW50cnkqICAgICAgICAgICAgICAgICAgICAgICBvcGVyYXRvcltdKGludDMyX3QgIGluZGV4KSBjb25zdDsKICAgICAgICBpbmxpbmUgUGF0dGVybkVudHJ5KiAgICAgICAgICAgICAgICBhdChpbnQzMl90ICBpbmRleCkgY29uc3QgeyByZXR1cm4gKCp0aGlzKVtpbmRleF07IH0KCiAgICAgICAgLyoqCiAgICAgICAgICogU2V0cyB0aGUgZWxlbWVudCBhdCB0aGUgc3BlY2lmaWVkIGluZGV4IHRvIGEgZGlmZmVyZW50IHZhbHVlLgogICAgICAgICAqIElmIHRoZXJlIHdhcyBhcmVhZHkgYW4gb2JqZWN0IHN0b3JlZCBhdCB0aGlzIGluZGV4LCBpdCBpcyBkZWxldGVkLgogICAgICAgICAqIEBwYXJhbSBpbmRleCB0aGUgc3BlY2lmaWVkIGluZGV4LgogICAgICAgICAqIEBwYXJhbSB2YWx1ZSB0aGUgbmV3IHZhbHVlLgogICAgICAgICAqLwogICAgICAgIHZvaWQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0UHV0KCAgaW50MzJfdCAgICAgaW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQYXR0ZXJuRW50cnkqICAgdmFsdWUpOwogICAgICAgIC8qKgogICAgICAgICAqIEluc2VydHMgYSB2YWx1ZSBhdCB0aGUgc3BlY2lmaWVkIGluZGV4LCBzbGlkaW5nIHRoZSByZXN0IG9mCiAgICAgICAgICogdGhlIGVsZW1lbnRzIGluIHRoZSBhcnJheSBvdmVyIHRvIG1ha2Ugcm9vbS4KICAgICAgICAgKiBAcGFyYW0gaW5kZXggdGhlIHNwZWNpZmllZCBpbmRleC4KICAgICAgICAgKiBAcGFyYW0gdmFsdWUgdGhlIHZhbHVlLgogICAgICAgICAqLwogICAgICAgIHZvaWQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0SW5zZXJ0KCAgIGludDMyX3QgICAgIGluZGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBhdHRlcm5FbnRyeSogICB2YWx1ZSk7CiAgICAgICAgLyoqCiAgICAgICAgICogIk9ycGhhbiIgdGhlIHBvaW50ZXIgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4gIFRoZSBhcnJheSB3aWxsIG5vCiAgICAgICAgICogbG9uZ2VyIGNvbnRhaW4gYSByZWZlcmVuY2UgdG8gdGhlIG9iamVjdCwgYW5kIHRoZSBjYWxsZXIgaXMKICAgICAgICAgKiBub3cgcmVzcG9uc2libGUgZm9yIGRlbGV0aW5nIGl0cyBzdG9yYWdlLgogICAgICAgICAqLwogICAgICAgIFBhdHRlcm5FbnRyeSogICAgICAgICAgICAgICAgICAgICAgIG9ycGhhbkF0KGludDMyX3QgICAgaW5kZXgpOwoKICAgICAgICAvKioKICAgICAgICAgKiBSZW1vdmUgYWxsIGVsZW1lbnRzIGZyb20gdGhlIHZlY3Rvci4KICAgICAgICAgKi8KICAgICAgICB2b2lkICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGVhcih2b2lkKTsKCiAgICAgICAgLyoqCiAgICAgICAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzIGluIHRoZSB2ZWN0b3IuCiAgICAgICAgICogQHJldHVybiB0aGUgc2l6ZSBvZiB2ZWN0b3IuCiAgICAgICAgICovCiAgICAgICAgaW50MzJfdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZSh2b2lkKSBjb25zdDsKCiAgICAgICAgLyoqCiAgICAgICAgICogSWYgdGhlIHNwZWNpZmllZCB2YWx1ZSBleGlzdHMgaW4gdGhlIHZlY3RvciwgcmV0dXJuIGl0cyBpbmRleC4KICAgICAgICAgKiBJZiBub3QsIHJldHVybiAtMS4KICAgICAgICAgKi8KICAgICAgICBpbnQzMl90ICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmRleE9mKGNvbnN0IFBhdHRlcm5FbnRyeSogdmFsdWUpIGNvbnN0OwoKICAgICAgICAvKioKICAgICAgICAgKiBSZXR1cm4gdGhlIGluZGV4IG9mIHRoZSBsYXN0IG9jY3VyYW5jZSBvZiB2YWx1ZSBpbiB0aGUgdmVjdG9yLAogICAgICAgICAqIG9yIC0xIGlmIHRoZSB2ZWN0b3IgZG9lc24ndCBjb250YWluIHZhbHVlLgogICAgICAgICAqLwogICAgICAgIGludDMyX3QgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhc3RJbmRleE9mKGNvbnN0IFBhdHRlcm5FbnRyeSogdmFsdWUpIGNvbnN0OwoKICAgICAgICAvKioKICAgICAgICAgKiBDaGVja3MgaWYgdGhpcyB2ZWN0b3Igb2JqZWN0IGlzIHZhbGlkLgogICAgICAgICAqIEByZXR1cm4gVFJVRSBpZiB0aGUgdmVjdG9yIG9iamVjdCBpcyB2YWxpZCwgRkFMU0Ugb3RoZXJ3aXNlLgogICAgICAgICAqLwogICAgICAgIFVCb29sICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNCb2d1cyh2b2lkKSBjb25zdDsKICAgIHByaXZhdGU6CiAgICAgICAgLyoqCiAgICAgICAgICogUmVzaXplcyB0aGUgdmVjdG9yIGlmIG5lY2Vzc2FyeSB3aGVuIGNvbXBhcmVkIHRvIGEgbmV3IHNpemUuCiAgICAgICAgICogQHBhcmFtIG5ld1NpemUgdGhlIG5ldyBzaXplLgogICAgICAgICAqLwogICAgICAgIHZvaWQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc2l6ZShpbnQzMl90ICAgICAgbmV3U2l6ZSk7CgogICAgICAgIGludDMyX3QgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZTaXplOwogICAgICAgIGludDMyX3QgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZDYXBhY2l0eTsKICAgICAgICBQYXR0ZXJuRW50cnkqKiAgICAgICAgICAgICAgICAgICAgICBmRWxlbWVudHM7CiAgICAgICAgVUJvb2wgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmQm9ndXM7Cn07CgppbmxpbmUKRW50cnlQYWlyOjpFbnRyeVBhaXIoY29uc3QgVW5pY29kZVN0cmluZyYgc3RyLCBpbnQzMl90IGFWYWx1ZSwgVUJvb2wgYUZ3ZCkKOiB2YWx1ZShhVmFsdWUpLCBmd2QoYUZ3ZCksIHN0b3JhZ2UobmV3IFVuaWNvZGVTdHJpbmcoc3RyKSkKewogICAgbmFtZUNoYXJzID0gc3RvcmFnZS0+Z2V0VUNoYXJzKCk7CiAgICBuYW1lTGVuID0gc3RvcmFnZS0+c2l6ZSgpOwp9CgppbmxpbmUKRW50cnlQYWlyOjpFbnRyeVBhaXIoKQogIDogdmFsdWUoMHhmZmZmZmZmZiksIGZ3ZChUUlVFKSwgc3RvcmFnZShOVUxMKSwgbmFtZUNoYXJzKE5VTEwpLCBuYW1lTGVuKDApCnsKfQoKaW5saW5lCkVudHJ5UGFpcjo6RW50cnlQYWlyKGNvbnN0IFVDaGFyICpuYW1lLCBpbnQzMl90IG5hbWVMZW5ndGgsIGludDMyX3QgYVZhbHVlLCBVQm9vbCBhRndkKQogIDogdmFsdWUoYVZhbHVlKSwgZndkKGFGd2QpLCBzdG9yYWdlKE5VTEwpLCBuYW1lQ2hhcnMobmFtZSksIG5hbWVMZW4obmFtZUxlbmd0aCkKewp9CgppbmxpbmUKRW50cnlQYWlyOjp+RW50cnlQYWlyKCkKewogICAgaWYoc3RvcmFnZSkgewogICAgICAgIGRlbGV0ZShzdG9yYWdlKTsKICAgICAgICBzdG9yYWdlID0gTlVMTDsKICAgIH0KfQoKaW5saW5lIFVCb29sIEVudHJ5UGFpcjo6ZXF1YWxUbyhjb25zdCBVQ2hhciAqYU5hbWUsIGludDMyX3QgYUxlbikgICAKewogICAgcmV0dXJuKCAoYUxlbj09bmFtZUxlbik/ISh1X3N0cm5jbXAoYU5hbWUsbmFtZUNoYXJzLGFMZW4pKTowICk7Cn0KCmlubGluZSBjb25zdCBVbmljb2RlU3RyaW5nJiAKRW50cnlQYWlyOjpnZXRFbnRyeU5hbWUoKQp7CiAgICBpZihzdG9yYWdlICE9IE5VTEwpIHsKICAgICAgICByZXR1cm4gKnN0b3JhZ2U7CiAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAqKHN0b3JhZ2UgPSBuZXcgVW5pY29kZVN0cmluZyhuYW1lQ2hhcnMsIG5hbWVMZW4pKTsKICAgIH0KfQovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBNRVRIT0RTIE9OIFZlY3Rvck9mSW50Ci8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgppbmxpbmUgaW50MzJfdApWZWN0b3JPZkludDo6b3BlcmF0b3JbXShpbnQzMl90IGluZGV4KSBjb25zdAp7CiAgICByZXR1cm4gKGluZGV4IDwgZkNhcGFjaXR5KSA/IGZFbGVtZW50c1tpbmRleF0gOiAwOwp9CgoKaW5saW5lIGludDMyX3QKVmVjdG9yT2ZJbnQ6OmF0KGludDMyX3QgaW5kZXgpIGNvbnN0CnsKICAgIHJldHVybiAoKnRoaXMpW2luZGV4XTsKfQoKaW5saW5lIGludDMyX3QmClZlY3Rvck9mSW50OjphdChpbnQzMl90IGluZGV4KQp7CiAgICByZXR1cm4gKCp0aGlzKVtpbmRleF07Cn0KCmlubGluZSBpbnQzMl90ClZlY3Rvck9mSW50OjpzaXplKCkgY29uc3QKewogICAgcmV0dXJuIGZTaXplOwp9CgovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBNRVRIT0RTIE9OIFZlY3Rvck9mUG9pbnRlcgovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKaW5saW5lIHZvaWQqClZlY3Rvck9mUG9pbnRlcjo6b3BlcmF0b3JbXShpbnQzMl90IGluZGV4KSBjb25zdAp7CiAgICByZXR1cm4gKGluZGV4IDwgZkNhcGFjaXR5KSA/IGZFbGVtZW50c1tpbmRleF0gOiAwOwp9CgoKaW5saW5lIHZvaWQqClZlY3Rvck9mUG9pbnRlcjo6YXQoaW50MzJfdCBpbmRleCkgY29uc3QKewogICAgcmV0dXJuICgqdGhpcylbaW5kZXhdOwp9CgppbmxpbmUgdm9pZComClZlY3Rvck9mUG9pbnRlcjo6YXQoaW50MzJfdCBpbmRleCkKewogICAgcmV0dXJuICgqdGhpcylbaW5kZXhdOwp9CgppbmxpbmUgaW50MzJfdApWZWN0b3JPZlBvaW50ZXI6OnNpemUoKSBjb25zdAp7CiAgICByZXR1cm4gZlNpemU7Cn0KLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8gTUVUSE9EUyBPTiBQVG9FeHBhbmRUYWJsZQovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKaW5saW5lClBUb0V4cGFuZFRhYmxlOjpvcGVyYXRvciBWZWN0b3JPZkludCooKSBjb25zdAp7CiAgICByZXR1cm4gZlZhbHVlOwp9CgppbmxpbmUKUFRvRXhwYW5kVGFibGU6OlBUb0V4cGFuZFRhYmxlKFZlY3Rvck9mSW50KiYgICAgdmFsdWUpCjogZlZhbHVlKHZhbHVlKQp7Cn0KCmlubGluZQpQVG9FeHBhbmRUYWJsZTo6UFRvRXhwYW5kVGFibGUoY29uc3QgUFRvRXhwYW5kVGFibGUmICAgIHRoYXQpCjogZlZhbHVlKHRoYXQuZlZhbHVlKQp7Cn0KCmlubGluZQpQVG9FeHBhbmRUYWJsZTo6flBUb0V4cGFuZFRhYmxlKCkKewp9CgppbmxpbmUgY29uc3QgUFRvRXhwYW5kVGFibGUmClBUb0V4cGFuZFRhYmxlOjpvcGVyYXRvcj0oVmVjdG9yT2ZJbnQqICBuZXdWYWx1ZSkKewogICAgZGVsZXRlIGZWYWx1ZTsKICAgIGZWYWx1ZSA9IG5ld1ZhbHVlOwogICAgcmV0dXJuICp0aGlzOwp9CgppbmxpbmUgY29uc3QgUFRvRXhwYW5kVGFibGUmClBUb0V4cGFuZFRhYmxlOjpvcGVyYXRvcj0oY29uc3QgUFRvRXhwYW5kVGFibGUmIHBvaW50ZXJUb05ld1ZhbHVlKQp7CiAgICBkZWxldGUgZlZhbHVlOwogICAgZlZhbHVlID0gKFZlY3Rvck9mSW50KikocG9pbnRlclRvTmV3VmFsdWUpOwogICAgcmV0dXJuICp0aGlzOwp9CgovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBNRVRIT0RTIE9OIFZlY3Rvck9mUFRvRXhwYW5kVGFibGUKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KaW5saW5lIFZlY3Rvck9mSW50KgpWZWN0b3JPZlBUb0V4cGFuZFRhYmxlOjpvcGVyYXRvcltdKGludDMyX3QgIGluZGV4KSBjb25zdAp7CiAgICByZXR1cm4gKGluZGV4IDwgZkNhcGFjaXR5KSA/IGZFbGVtZW50c1tpbmRleF0gOiAwOwp9CgppbmxpbmUgVmVjdG9yT2ZJbnQqClZlY3Rvck9mUFRvRXhwYW5kVGFibGU6OmF0KGludDMyX3QgIGluZGV4KSBjb25zdAp7CiAgICByZXR1cm4gKCp0aGlzKVtpbmRleF07Cn0KCmlubGluZSBQVG9FeHBhbmRUYWJsZQpWZWN0b3JPZlBUb0V4cGFuZFRhYmxlOjphdChpbnQzMl90ICBpbmRleCkKewogICAgcmV0dXJuICgqdGhpcylbaW5kZXhdOwp9CgppbmxpbmUgaW50MzJfdApWZWN0b3JPZlBUb0V4cGFuZFRhYmxlOjpzaXplKCkgY29uc3QKewogICAgcmV0dXJuIGZTaXplOwp9CgovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBNRVRIT0RTIE9OIFBUb0NvbnRyYWN0RWxlbWVudAovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKaW5saW5lClBUb0NvbnRyYWN0RWxlbWVudDo6b3BlcmF0b3IgRW50cnlQYWlyKigpIGNvbnN0CnsKICAgIHJldHVybiBmVmFsdWU7Cn0KCmlubGluZQpQVG9Db250cmFjdEVsZW1lbnQ6OlBUb0NvbnRyYWN0RWxlbWVudChFbnRyeVBhaXIqJiAgdmFsdWUpCjogZlZhbHVlKHZhbHVlKQp7Cn0KCmlubGluZQpQVG9Db250cmFjdEVsZW1lbnQ6OlBUb0NvbnRyYWN0RWxlbWVudChjb25zdCBQVG9Db250cmFjdEVsZW1lbnQmICAgIHRoYXQpCjogZlZhbHVlKHRoYXQuZlZhbHVlKQp7Cn0KCmlubGluZQpQVG9Db250cmFjdEVsZW1lbnQ6On5QVG9Db250cmFjdEVsZW1lbnQoKQp7Cn0KCmlubGluZSBjb25zdCBQVG9Db250cmFjdEVsZW1lbnQmClBUb0NvbnRyYWN0RWxlbWVudDo6b3BlcmF0b3I9KEVudHJ5UGFpciogICAgbmV3VmFsdWUpCnsKICAgIGRlbGV0ZSBmVmFsdWU7CiAgICBmVmFsdWUgPSBuZXdWYWx1ZTsKICAgIHJldHVybiAqdGhpczsKfQoKaW5saW5lIGNvbnN0IFBUb0NvbnRyYWN0RWxlbWVudCYKUFRvQ29udHJhY3RFbGVtZW50OjpvcGVyYXRvcj0oY29uc3QgUFRvQ29udHJhY3RFbGVtZW50JiBwb2ludGVyVG9OZXdWYWx1ZSkKewogICAgZGVsZXRlIGZWYWx1ZTsKICAgIGZWYWx1ZSA9IChFbnRyeVBhaXIqKShwb2ludGVyVG9OZXdWYWx1ZSk7CiAgICByZXR1cm4gKnRoaXM7Cn0KCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vIE1FVEhPRFMgT04gVmVjdG9yT2ZQVG9Db250cmFjdEVsZW1lbnQKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCmlubGluZSBFbnRyeVBhaXIqClZlY3Rvck9mUFRvQ29udHJhY3RFbGVtZW50OjpvcGVyYXRvcltdKGludDMyX3QgIGluZGV4KSBjb25zdAp7CiAgICByZXR1cm4gKGluZGV4IDwgZkNhcGFjaXR5KSA/IGZFbGVtZW50c1tpbmRleF0gOiAwOwp9CgppbmxpbmUgRW50cnlQYWlyKgpWZWN0b3JPZlBUb0NvbnRyYWN0RWxlbWVudDo6YXQoaW50MzJfdCAgaW5kZXgpIGNvbnN0CnsKICAgIHJldHVybiAoKnRoaXMpW2luZGV4XTsKfQoKaW5saW5lIFBUb0NvbnRyYWN0RWxlbWVudApWZWN0b3JPZlBUb0NvbnRyYWN0RWxlbWVudDo6YXQoaW50MzJfdCAgaW5kZXgpCnsKICAgIHJldHVybiAoKnRoaXMpW2luZGV4XTsKfQoKaW5saW5lIGludDMyX3QKVmVjdG9yT2ZQVG9Db250cmFjdEVsZW1lbnQ6OnNpemUoKSBjb25zdAp7CiAgICByZXR1cm4gZlNpemU7Cn0KCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vIE1FVEhPRFMgT04gUFRvQ29udHJhY3RUYWJsZQovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKaW5saW5lClBUb0NvbnRyYWN0VGFibGU6Om9wZXJhdG9yIFZlY3Rvck9mUFRvQ29udHJhY3RFbGVtZW50KigpIGNvbnN0CnsKICAgIHJldHVybiBmVmFsdWU7Cn0KCmlubGluZQpQVG9Db250cmFjdFRhYmxlOjpQVG9Db250cmFjdFRhYmxlKFZlY3Rvck9mUFRvQ29udHJhY3RFbGVtZW50KiYgdmFsdWUpCjogZlZhbHVlKHZhbHVlKQp7Cn0KCmlubGluZQpQVG9Db250cmFjdFRhYmxlOjpQVG9Db250cmFjdFRhYmxlKGNvbnN0IFBUb0NvbnRyYWN0VGFibGUmICB0aGF0KQo6IGZWYWx1ZSh0aGF0LmZWYWx1ZSkKewp9CgppbmxpbmUKUFRvQ29udHJhY3RUYWJsZTo6flBUb0NvbnRyYWN0VGFibGUoKQp7Cn0KCmlubGluZSBjb25zdCBQVG9Db250cmFjdFRhYmxlJgpQVG9Db250cmFjdFRhYmxlOjpvcGVyYXRvcj0oVmVjdG9yT2ZQVG9Db250cmFjdEVsZW1lbnQqIG5ld1ZhbHVlKQp7CiAgICBkZWxldGUgZlZhbHVlOwogICAgZlZhbHVlID0gbmV3VmFsdWU7CiAgICByZXR1cm4gKnRoaXM7Cn0KCmlubGluZSBjb25zdCBQVG9Db250cmFjdFRhYmxlJgpQVG9Db250cmFjdFRhYmxlOjpvcGVyYXRvcj0oY29uc3QgUFRvQ29udHJhY3RUYWJsZSYgcG9pbnRlclRvTmV3VmFsdWUpCnsKICAgIGRlbGV0ZSBmVmFsdWU7CiAgICBmVmFsdWUgPSAoVmVjdG9yT2ZQVG9Db250cmFjdEVsZW1lbnQqKShwb2ludGVyVG9OZXdWYWx1ZSk7CiAgICByZXR1cm4gKnRoaXM7Cn0KCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vIE1FVEhPRFMgT04gVmVjdG9yT2ZQVG9Db250cmFjdFRhYmxlCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgppbmxpbmUgVmVjdG9yT2ZQVG9Db250cmFjdEVsZW1lbnQqClZlY3Rvck9mUFRvQ29udHJhY3RUYWJsZTo6b3BlcmF0b3JbXShpbnQzMl90ICAgIGluZGV4KSBjb25zdAp7CiAgICByZXR1cm4gKGluZGV4IDwgZkNhcGFjaXR5KSA/IGZFbGVtZW50c1tpbmRleF0gOiAwOwp9CgppbmxpbmUgVmVjdG9yT2ZQVG9Db250cmFjdEVsZW1lbnQqClZlY3Rvck9mUFRvQ29udHJhY3RUYWJsZTo6YXQoaW50MzJfdCAgICBpbmRleCkgY29uc3QKewogICAgcmV0dXJuICgqdGhpcylbaW5kZXhdOwp9CgppbmxpbmUgUFRvQ29udHJhY3RUYWJsZQpWZWN0b3JPZlBUb0NvbnRyYWN0VGFibGU6OmF0KGludDMyX3QgICAgaW5kZXgpCnsKICAgIHJldHVybiAoKnRoaXMpW2luZGV4XTsKfQoKaW5saW5lIGludDMyX3QKVmVjdG9yT2ZQVG9Db250cmFjdFRhYmxlOjpzaXplKCkgY29uc3QKewogICAgcmV0dXJuIGZTaXplOwp9CgojZW5kaWYK