LyogbW9kdWxlLmMgLSB0aGUgbW9kdWxlIGl0c2VsZgogKgogKiBDb3B5cmlnaHQgKEMpIDIwMDQtMjAwNiBHZXJoYXJkIEjkcmluZyA8Z2hAZ2hhZXJpbmcuZGU+CiAqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHB5c3FsaXRlLgogKgogKiBUaGlzIHNvZnR3YXJlIGlzIHByb3ZpZGVkICdhcy1pcycsIHdpdGhvdXQgYW55IGV4cHJlc3Mgb3IgaW1wbGllZAogKiB3YXJyYW50eS4gIEluIG5vIGV2ZW50IHdpbGwgdGhlIGF1dGhvcnMgYmUgaGVsZCBsaWFibGUgZm9yIGFueSBkYW1hZ2VzCiAqIGFyaXNpbmcgZnJvbSB0aGUgdXNlIG9mIHRoaXMgc29mdHdhcmUuCiAqCiAqIFBlcm1pc3Npb24gaXMgZ3JhbnRlZCB0byBhbnlvbmUgdG8gdXNlIHRoaXMgc29mdHdhcmUgZm9yIGFueSBwdXJwb3NlLAogKiBpbmNsdWRpbmcgY29tbWVyY2lhbCBhcHBsaWNhdGlvbnMsIGFuZCB0byBhbHRlciBpdCBhbmQgcmVkaXN0cmlidXRlIGl0CiAqIGZyZWVseSwgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIHJlc3RyaWN0aW9uczoKICoKICogMS4gVGhlIG9yaWdpbiBvZiB0aGlzIHNvZnR3YXJlIG11c3Qgbm90IGJlIG1pc3JlcHJlc2VudGVkOyB5b3UgbXVzdCBub3QKICogICAgY2xhaW0gdGhhdCB5b3Ugd3JvdGUgdGhlIG9yaWdpbmFsIHNvZnR3YXJlLiBJZiB5b3UgdXNlIHRoaXMgc29mdHdhcmUKICogICAgaW4gYSBwcm9kdWN0LCBhbiBhY2tub3dsZWRnbWVudCBpbiB0aGUgcHJvZHVjdCBkb2N1bWVudGF0aW9uIHdvdWxkIGJlCiAqICAgIGFwcHJlY2lhdGVkIGJ1dCBpcyBub3QgcmVxdWlyZWQuCiAqIDIuIEFsdGVyZWQgc291cmNlIHZlcnNpb25zIG11c3QgYmUgcGxhaW5seSBtYXJrZWQgYXMgc3VjaCwgYW5kIG11c3Qgbm90IGJlCiAqICAgIG1pc3JlcHJlc2VudGVkIGFzIGJlaW5nIHRoZSBvcmlnaW5hbCBzb2Z0d2FyZS4KICogMy4gVGhpcyBub3RpY2UgbWF5IG5vdCBiZSByZW1vdmVkIG9yIGFsdGVyZWQgZnJvbSBhbnkgc291cmNlIGRpc3RyaWJ1dGlvbi4KICovCgojaW5jbHVkZSAiY29ubmVjdGlvbi5oIgojaW5jbHVkZSAic3RhdGVtZW50LmgiCiNpbmNsdWRlICJjdXJzb3IuaCIKI2luY2x1ZGUgImNhY2hlLmgiCiNpbmNsdWRlICJwcmVwYXJlX3Byb3RvY29sLmgiCiNpbmNsdWRlICJtaWNyb3Byb3RvY29scy5oIgojaW5jbHVkZSAicm93LmgiCgojaWYgU1FMSVRFX1ZFUlNJT05fTlVNQkVSID49IDMwMDMwMDMKI2RlZmluZSBIQVZFX1NIQVJFRF9DQUNIRQojZW5kaWYKCi8qIHN0YXRpYyBvYmplY3RzIGF0IG1vZHVsZS1sZXZlbCAqLwoKUHlPYmplY3QqIEVycm9yLCAqV2FybmluZywgKkludGVyZmFjZUVycm9yLCAqRGF0YWJhc2VFcnJvciwgKkludGVybmFsRXJyb3IsCiAgICAqT3BlcmF0aW9uYWxFcnJvciwgKlByb2dyYW1taW5nRXJyb3IsICpJbnRlZ3JpdHlFcnJvciwgKkRhdGFFcnJvciwKICAgICpOb3RTdXBwb3J0ZWRFcnJvciwgKk9wdGltaXplZFVuaWNvZGU7CgpQeU9iamVjdCogY29udmVydGVyczsKCnN0YXRpYyBQeU9iamVjdCogbW9kdWxlX2Nvbm5lY3QoUHlPYmplY3QqIHNlbGYsIFB5T2JqZWN0KiBhcmdzLCBQeU9iamVjdCoKICAgICAgICBrd2FyZ3MpCnsKICAgIC8qIFB5dGhvbiBzZWVtcyB0byBoYXZlIG5vIHdheSBvZiBleHRyYWN0aW5nIGEgc2luZ2xlIGtleXdvcmQtYXJnIGF0CiAgICAgKiBDLWxldmVsLCBzbyB0aGlzIGNvZGUgaXMgcmVkdW5kYW50IHdpdGggdGhlIG9uZSBpbiBjb25uZWN0aW9uX2luaXQgaW4KICAgICAqIGNvbm5lY3Rpb24uYyBhbmQgbXVzdCBhbHdheXMgYmUgY29waWVkIGZyb20gdGhlcmUgLi4uICovCgogICAgc3RhdGljIGNoYXIgKmt3bGlzdFtdID0geyJkYXRhYmFzZSIsICJ0aW1lb3V0IiwgImRldGVjdF90eXBlcyIsICJpc29sYXRpb25fbGV2ZWwiLCAiY2hlY2tfc2FtZV90aHJlYWQiLCAiZmFjdG9yeSIsICJjYWNoZWRfc3RhdGVtZW50cyIsIE5VTEwsIE5VTEx9OwogICAgY2hhciogZGF0YWJhc2U7CiAgICBpbnQgZGV0ZWN0X3R5cGVzID0gMDsKICAgIFB5T2JqZWN0KiBpc29sYXRpb25fbGV2ZWw7CiAgICBQeU9iamVjdCogZmFjdG9yeSA9IE5VTEw7CiAgICBpbnQgY2hlY2tfc2FtZV90aHJlYWQgPSAxOwogICAgaW50IGNhY2hlZF9zdGF0ZW1lbnRzOwogICAgZG91YmxlIHRpbWVvdXQgPSA1LjA7CgogICAgUHlPYmplY3QqIHJlc3VsdDsKCiAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGVBbmRLZXl3b3JkcyhhcmdzLCBrd2FyZ3MsICJzfGRpT2lPaSIsIGt3bGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZkYXRhYmFzZSwgJnRpbWVvdXQsICZkZXRlY3RfdHlwZXMsICZpc29sYXRpb25fbGV2ZWwsICZjaGVja19zYW1lX3RocmVhZCwgJmZhY3RvcnksICZjYWNoZWRfc3RhdGVtZW50cykpCiAgICB7CiAgICAgICAgcmV0dXJuIE5VTEw7IAogICAgfQoKICAgIGlmIChmYWN0b3J5ID09IE5VTEwpIHsKICAgICAgICBmYWN0b3J5ID0gKFB5T2JqZWN0KikmQ29ubmVjdGlvblR5cGU7CiAgICB9CgogICAgcmVzdWx0ID0gUHlPYmplY3RfQ2FsbChmYWN0b3J5LCBhcmdzLCBrd2FyZ3MpOwoKICAgIHJldHVybiByZXN1bHQ7Cn0KCnN0YXRpYyBQeU9iamVjdCogbW9kdWxlX2NvbXBsZXRlKFB5T2JqZWN0KiBzZWxmLCBQeU9iamVjdCogYXJncywgUHlPYmplY3QqCiAgICAgICAga3dhcmdzKQp7CiAgICBzdGF0aWMgY2hhciAqa3dsaXN0W10gPSB7InN0YXRlbWVudCIsIE5VTEwsIE5VTEx9OwogICAgY2hhciogc3RhdGVtZW50OwoKICAgIFB5T2JqZWN0KiByZXN1bHQ7CgogICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlQW5kS2V5d29yZHMoYXJncywga3dhcmdzLCAicyIsIGt3bGlzdCwgJnN0YXRlbWVudCkpCiAgICB7CiAgICAgICAgcmV0dXJuIE5VTEw7IAogICAgfQoKICAgIGlmIChzcWxpdGUzX2NvbXBsZXRlKHN0YXRlbWVudCkpIHsKICAgICAgICByZXN1bHQgPSBQeV9UcnVlOwogICAgfSBlbHNlIHsKICAgICAgICByZXN1bHQgPSBQeV9GYWxzZTsKICAgIH0KCiAgICBQeV9JTkNSRUYocmVzdWx0KTsKCiAgICByZXR1cm4gcmVzdWx0Owp9CgojaWZkZWYgSEFWRV9TSEFSRURfQ0FDSEUKc3RhdGljIFB5T2JqZWN0KiBtb2R1bGVfZW5hYmxlX3NoYXJlZF9jYWNoZShQeU9iamVjdCogc2VsZiwgUHlPYmplY3QqIGFyZ3MsIFB5T2JqZWN0KgogICAgICAgIGt3YXJncykKewogICAgc3RhdGljIGNoYXIgKmt3bGlzdFtdID0geyJkb19lbmFibGUiLCBOVUxMLCBOVUxMfTsKICAgIGludCBkb19lbmFibGU7CiAgICBpbnQgcmM7CgogICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlQW5kS2V5d29yZHMoYXJncywga3dhcmdzLCAiaSIsIGt3bGlzdCwgJmRvX2VuYWJsZSkpCiAgICB7CiAgICAgICAgcmV0dXJuIE5VTEw7IAogICAgfQoKICAgIHJjID0gc3FsaXRlM19lbmFibGVfc2hhcmVkX2NhY2hlKGRvX2VuYWJsZSk7CgogICAgaWYgKHJjICE9IFNRTElURV9PSykgewogICAgICAgIFB5RXJyX1NldFN0cmluZyhPcGVyYXRpb25hbEVycm9yLCAiQ2hhbmdpbmcgdGhlIHNoYXJlZF9jYWNoZSBmbGFnIGZhaWxlZCIpOwogICAgICAgIHJldHVybiBOVUxMOwogICAgfSBlbHNlIHsKICAgICAgICBQeV9JTkNSRUYoUHlfTm9uZSk7CiAgICAgICAgcmV0dXJuIFB5X05vbmU7CiAgICB9Cn0KI2VuZGlmIC8qIEhBVkVfU0hBUkVEX0NBQ0hFICovCgpzdGF0aWMgUHlPYmplY3QqIG1vZHVsZV9yZWdpc3Rlcl9hZGFwdGVyKFB5T2JqZWN0KiBzZWxmLCBQeU9iamVjdCogYXJncywgUHlPYmplY3QqIGt3YXJncykKewogICAgUHlUeXBlT2JqZWN0KiB0eXBlOwogICAgUHlPYmplY3QqIGNhc3RlcjsKCiAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgIk9PIiwgJnR5cGUsICZjYXN0ZXIpKSB7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgbWljcm9wcm90b2NvbHNfYWRkKHR5cGUsIChQeU9iamVjdCopJlNRTGl0ZVByZXBhcmVQcm90b2NvbFR5cGUsIGNhc3Rlcik7CgogICAgUHlfSU5DUkVGKFB5X05vbmUpOwogICAgcmV0dXJuIFB5X05vbmU7Cn0KCnN0YXRpYyBQeU9iamVjdCogbW9kdWxlX3JlZ2lzdGVyX2NvbnZlcnRlcihQeU9iamVjdCogc2VsZiwgUHlPYmplY3QqIGFyZ3MsIFB5T2JqZWN0KiBrd2FyZ3MpCnsKICAgIFB5T2JqZWN0KiBuYW1lOwogICAgUHlPYmplY3QqIGNhbGxhYmxlOwoKICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZShhcmdzLCAiT08iLCAmbmFtZSwgJmNhbGxhYmxlKSkgewogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIGlmIChQeURpY3RfU2V0SXRlbShjb252ZXJ0ZXJzLCBuYW1lLCBjYWxsYWJsZSkgIT0gMCkgewogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsKICAgIHJldHVybiBQeV9Ob25lOwp9Cgp2b2lkIGNvbnZlcnRlcnNfaW5pdChQeU9iamVjdCogZGljdCkKewogICAgY29udmVydGVycyA9IFB5RGljdF9OZXcoKTsKICAgIGlmICghY29udmVydGVycykgewogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBQeURpY3RfU2V0SXRlbVN0cmluZyhkaWN0LCAiY29udmVydGVycyIsIGNvbnZlcnRlcnMpOwp9CgpzdGF0aWMgUHlNZXRob2REZWYgbW9kdWxlX21ldGhvZHNbXSA9IHsKICAgIHsiY29ubmVjdCIsICAoUHlDRnVuY3Rpb24pbW9kdWxlX2Nvbm5lY3QsICBNRVRIX1ZBUkFSR1N8TUVUSF9LRVlXT1JEUywgUHlEb2NfU1RSKCJDcmVhdGVzIGEgY29ubmVjdGlvbi4iKX0sCiAgICB7ImNvbXBsZXRlX3N0YXRlbWVudCIsICAoUHlDRnVuY3Rpb24pbW9kdWxlX2NvbXBsZXRlLCAgTUVUSF9WQVJBUkdTfE1FVEhfS0VZV09SRFMsIFB5RG9jX1NUUigiQ2hlY2tzIGlmIGEgc3RyaW5nIGNvbnRhaW5zIGEgY29tcGxldGUgU1FMIHN0YXRlbWVudC4gTm9uLXN0YW5kYXJkLiIpfSwKI2lmZGVmIEhBVkVfU0hBUkVEX0NBQ0hFCiAgICB7ImVuYWJsZV9zaGFyZWRfY2FjaGUiLCAgKFB5Q0Z1bmN0aW9uKW1vZHVsZV9lbmFibGVfc2hhcmVkX2NhY2hlLCAgTUVUSF9WQVJBUkdTfE1FVEhfS0VZV09SRFMsIFB5RG9jX1NUUigiRW5hYmxlIG9yIGRpc2FibGUgc2hhcmVkIGNhY2hlIG1vZGUgZm9yIHRoZSBjYWxsaW5nIHRocmVhZC4gRXhwZXJpbWVudGFsL05vbi1zdGFuZGFyZC4iKX0sCiNlbmRpZgogICAgeyJyZWdpc3Rlcl9hZGFwdGVyIiwgKFB5Q0Z1bmN0aW9uKW1vZHVsZV9yZWdpc3Rlcl9hZGFwdGVyLCBNRVRIX1ZBUkFSR1MsIFB5RG9jX1NUUigiUmVnaXN0ZXJzIGFuIGFkYXB0ZXIgd2l0aCBweXNxbGl0ZSdzIGFkYXB0ZXIgcmVnaXN0cnkuIE5vbi1zdGFuZGFyZC4iKX0sCiAgICB7InJlZ2lzdGVyX2NvbnZlcnRlciIsIChQeUNGdW5jdGlvbiltb2R1bGVfcmVnaXN0ZXJfY29udmVydGVyLCBNRVRIX1ZBUkFSR1MsIFB5RG9jX1NUUigiUmVnaXN0ZXJzIGEgY29udmVydGVyIHdpdGggcHlzcWxpdGUuIE5vbi1zdGFuZGFyZC4iKX0sCiAgICB7ImFkYXB0IiwgIChQeUNGdW5jdGlvbilwc3ljb19taWNyb3Byb3RvY29sc19hZGFwdCwgTUVUSF9WQVJBUkdTLCBwc3ljb19taWNyb3Byb3RvY29sc19hZGFwdF9kb2N9LAogICAge05VTEwsIE5VTEx9Cn07CgpQeU1PRElOSVRfRlVOQyBpbml0X3NxbGl0ZTModm9pZCkKewogICAgUHlPYmplY3QgKm1vZHVsZSwgKmRpY3Q7CiAgICBQeU9iamVjdCAqdG1wX29iajsKCiAgICBtb2R1bGUgPSBQeV9Jbml0TW9kdWxlKCJfc3FsaXRlMyIsIG1vZHVsZV9tZXRob2RzKTsKCiAgICBpZiAoIW1vZHVsZSB8fAogICAgICAgIChyb3dfc2V0dXBfdHlwZXMoKSA8IDApIHx8CiAgICAgICAgKGN1cnNvcl9zZXR1cF90eXBlcygpIDwgMCkgfHwKICAgICAgICAoY29ubmVjdGlvbl9zZXR1cF90eXBlcygpIDwgMCkgfHwKICAgICAgICAoY2FjaGVfc2V0dXBfdHlwZXMoKSA8IDApIHx8CiAgICAgICAgKHN0YXRlbWVudF9zZXR1cF90eXBlcygpIDwgMCkgfHwKICAgICAgICAocHJlcGFyZV9wcm90b2NvbF9zZXR1cF90eXBlcygpIDwgMCkKICAgICAgICkgewogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBQeV9JTkNSRUYoJkNvbm5lY3Rpb25UeXBlKTsKICAgIFB5TW9kdWxlX0FkZE9iamVjdChtb2R1bGUsICJDb25uZWN0aW9uIiwgKFB5T2JqZWN0KikgJkNvbm5lY3Rpb25UeXBlKTsKICAgIFB5X0lOQ1JFRigmQ3Vyc29yVHlwZSk7CiAgICBQeU1vZHVsZV9BZGRPYmplY3QobW9kdWxlLCAiQ3Vyc29yIiwgKFB5T2JqZWN0KikgJkN1cnNvclR5cGUpOwogICAgUHlfSU5DUkVGKCZDYWNoZVR5cGUpOwogICAgUHlNb2R1bGVfQWRkT2JqZWN0KG1vZHVsZSwgIlN0YXRlbWVudCIsIChQeU9iamVjdCopJlN0YXRlbWVudFR5cGUpOwogICAgUHlfSU5DUkVGKCZTdGF0ZW1lbnRUeXBlKTsKICAgIFB5TW9kdWxlX0FkZE9iamVjdChtb2R1bGUsICJDYWNoZSIsIChQeU9iamVjdCopICZDYWNoZVR5cGUpOwogICAgUHlfSU5DUkVGKCZTUUxpdGVQcmVwYXJlUHJvdG9jb2xUeXBlKTsKICAgIFB5TW9kdWxlX0FkZE9iamVjdChtb2R1bGUsICJQcmVwYXJlUHJvdG9jb2wiLCAoUHlPYmplY3QqKSAmU1FMaXRlUHJlcGFyZVByb3RvY29sVHlwZSk7CiAgICBQeV9JTkNSRUYoJlJvd1R5cGUpOwogICAgUHlNb2R1bGVfQWRkT2JqZWN0KG1vZHVsZSwgIlJvdyIsIChQeU9iamVjdCopICZSb3dUeXBlKTsKCiAgICBpZiAoIShkaWN0ID0gUHlNb2R1bGVfR2V0RGljdChtb2R1bGUpKSkgewogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgLyoqKiBDcmVhdGUgREItQVBJIEV4Y2VwdGlvbiBoaWVyYXJjaHkgKi8KCiAgICBpZiAoIShFcnJvciA9IFB5RXJyX05ld0V4Y2VwdGlvbihNT0RVTEVfTkFNRSAiLkVycm9yIiwgUHlFeGNfU3RhbmRhcmRFcnJvciwgTlVMTCkpKSB7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KICAgIFB5RGljdF9TZXRJdGVtU3RyaW5nKGRpY3QsICJFcnJvciIsIEVycm9yKTsKCiAgICBpZiAoIShXYXJuaW5nID0gUHlFcnJfTmV3RXhjZXB0aW9uKE1PRFVMRV9OQU1FICIuV2FybmluZyIsIFB5RXhjX1N0YW5kYXJkRXJyb3IsIE5VTEwpKSkgewogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CiAgICBQeURpY3RfU2V0SXRlbVN0cmluZyhkaWN0LCAiV2FybmluZyIsIFdhcm5pbmcpOwoKICAgIC8qIEVycm9yIHN1YmNsYXNzZXMgKi8KCiAgICBpZiAoIShJbnRlcmZhY2VFcnJvciA9IFB5RXJyX05ld0V4Y2VwdGlvbihNT0RVTEVfTkFNRSAiLkludGVyZmFjZUVycm9yIiwgRXJyb3IsIE5VTEwpKSkgewogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CiAgICBQeURpY3RfU2V0SXRlbVN0cmluZyhkaWN0LCAiSW50ZXJmYWNlRXJyb3IiLCBJbnRlcmZhY2VFcnJvcik7CgogICAgaWYgKCEoRGF0YWJhc2VFcnJvciA9IFB5RXJyX05ld0V4Y2VwdGlvbihNT0RVTEVfTkFNRSAiLkRhdGFiYXNlRXJyb3IiLCBFcnJvciwgTlVMTCkpKSB7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KICAgIFB5RGljdF9TZXRJdGVtU3RyaW5nKGRpY3QsICJEYXRhYmFzZUVycm9yIiwgRGF0YWJhc2VFcnJvcik7CgogICAgLyogRGF0YWJhc2VFcnJvciBzdWJjbGFzc2VzICovCgogICAgaWYgKCEoSW50ZXJuYWxFcnJvciA9IFB5RXJyX05ld0V4Y2VwdGlvbihNT0RVTEVfTkFNRSAiLkludGVybmFsRXJyb3IiLCBEYXRhYmFzZUVycm9yLCBOVUxMKSkpIHsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQogICAgUHlEaWN0X1NldEl0ZW1TdHJpbmcoZGljdCwgIkludGVybmFsRXJyb3IiLCBJbnRlcm5hbEVycm9yKTsKCiAgICBpZiAoIShPcGVyYXRpb25hbEVycm9yID0gUHlFcnJfTmV3RXhjZXB0aW9uKE1PRFVMRV9OQU1FICIuT3BlcmF0aW9uYWxFcnJvciIsIERhdGFiYXNlRXJyb3IsIE5VTEwpKSkgewogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CiAgICBQeURpY3RfU2V0SXRlbVN0cmluZyhkaWN0LCAiT3BlcmF0aW9uYWxFcnJvciIsIE9wZXJhdGlvbmFsRXJyb3IpOwoKICAgIGlmICghKFByb2dyYW1taW5nRXJyb3IgPSBQeUVycl9OZXdFeGNlcHRpb24oTU9EVUxFX05BTUUgIi5Qcm9ncmFtbWluZ0Vycm9yIiwgRGF0YWJhc2VFcnJvciwgTlVMTCkpKSB7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KICAgIFB5RGljdF9TZXRJdGVtU3RyaW5nKGRpY3QsICJQcm9ncmFtbWluZ0Vycm9yIiwgUHJvZ3JhbW1pbmdFcnJvcik7CgogICAgaWYgKCEoSW50ZWdyaXR5RXJyb3IgPSBQeUVycl9OZXdFeGNlcHRpb24oTU9EVUxFX05BTUUgIi5JbnRlZ3JpdHlFcnJvciIsIERhdGFiYXNlRXJyb3IsTlVMTCkpKSB7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KICAgIFB5RGljdF9TZXRJdGVtU3RyaW5nKGRpY3QsICJJbnRlZ3JpdHlFcnJvciIsIEludGVncml0eUVycm9yKTsKCiAgICBpZiAoIShEYXRhRXJyb3IgPSBQeUVycl9OZXdFeGNlcHRpb24oTU9EVUxFX05BTUUgIi5EYXRhRXJyb3IiLCBEYXRhYmFzZUVycm9yLCBOVUxMKSkpIHsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQogICAgUHlEaWN0X1NldEl0ZW1TdHJpbmcoZGljdCwgIkRhdGFFcnJvciIsIERhdGFFcnJvcik7CgogICAgaWYgKCEoTm90U3VwcG9ydGVkRXJyb3IgPSBQeUVycl9OZXdFeGNlcHRpb24oTU9EVUxFX05BTUUgIi5Ob3RTdXBwb3J0ZWRFcnJvciIsIERhdGFiYXNlRXJyb3IsIE5VTEwpKSkgewogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CiAgICBQeURpY3RfU2V0SXRlbVN0cmluZyhkaWN0LCAiTm90U3VwcG9ydGVkRXJyb3IiLCBOb3RTdXBwb3J0ZWRFcnJvcik7CgogICAgLyogV2UganVzdCBuZWVkICJzb21ldGhpbmciIHVuaXF1ZSBmb3IgT3B0aW1pemVkVW5pY29kZS4gSXQgZG9lcyBub3QgcmVhbGx5CiAgICAgKiBuZWVkIHRvIGJlIGEgc3RyaW5nIHN1YmNsYXNzLiBKdXN0IGFueXRoaW5nIHRoYXQgY2FuIGFjdCBhcyBhIHNwZWNpYWwKICAgICAqIG1hcmtlciBmb3IgdXMuIFNvIEkgcHVsbGVkIFB5Q2VsbF9UeXBlIG91dCBvZiBteSBtYWdpYyBoYXQuCiAgICAgKi8KICAgIFB5X0lOQ1JFRigoUHlPYmplY3QqKSZQeUNlbGxfVHlwZSk7CiAgICBPcHRpbWl6ZWRVbmljb2RlID0gKFB5T2JqZWN0KikmUHlDZWxsX1R5cGU7CiAgICBQeURpY3RfU2V0SXRlbVN0cmluZyhkaWN0LCAiT3B0aW1pemVkVW5pY29kZSIsIE9wdGltaXplZFVuaWNvZGUpOwoKICAgIGlmICghKHRtcF9vYmogPSBQeUludF9Gcm9tTG9uZyhQQVJTRV9ERUNMVFlQRVMpKSkgewogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CiAgICBQeURpY3RfU2V0SXRlbVN0cmluZyhkaWN0LCAiUEFSU0VfREVDTFRZUEVTIiwgdG1wX29iaik7CiAgICBQeV9ERUNSRUYodG1wX29iaik7CgogICAgaWYgKCEodG1wX29iaiA9IFB5SW50X0Zyb21Mb25nKFBBUlNFX0NPTE5BTUVTKSkpIHsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQogICAgUHlEaWN0X1NldEl0ZW1TdHJpbmcoZGljdCwgIlBBUlNFX0NPTE5BTUVTIiwgdG1wX29iaik7CiAgICBQeV9ERUNSRUYodG1wX29iaik7CgogICAgaWYgKCEodG1wX29iaiA9IFB5U3RyaW5nX0Zyb21TdHJpbmcoUFlTUUxJVEVfVkVSU0lPTikpKSB7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KICAgIFB5RGljdF9TZXRJdGVtU3RyaW5nKGRpY3QsICJ2ZXJzaW9uIiwgdG1wX29iaik7CiAgICBQeV9ERUNSRUYodG1wX29iaik7CgogICAgaWYgKCEodG1wX29iaiA9IFB5U3RyaW5nX0Zyb21TdHJpbmcoc3FsaXRlM19saWJ2ZXJzaW9uKCkpKSkgewogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CiAgICBQeURpY3RfU2V0SXRlbVN0cmluZyhkaWN0LCAic3FsaXRlX3ZlcnNpb24iLCB0bXBfb2JqKTsKICAgIFB5X0RFQ1JFRih0bXBfb2JqKTsKCiAgICAvKiBpbml0aWFsaXplIG1pY3JvcHJvdG9jb2xzIGxheWVyICovCiAgICBtaWNyb3Byb3RvY29sc19pbml0KGRpY3QpOwoKICAgIC8qIGluaXRpYWxpemUgdGhlIGRlZmF1bHQgY29udmVydGVycyAqLwogICAgY29udmVydGVyc19pbml0KGRpY3QpOwoKICAgIC8qIE9yaWdpbmFsIGNvbW1lbnQgZm9ybSBfYnNkZGIuYyBpbiB0aGUgUHl0aG9uIGNvcmUuIFRoaXMgaXMgYWxzbyBzdGlsbAogICAgICogbmVlZGVkIG5vd2FkYXlzIGZvciBQeXRob24gMi4zLzIuNC4KICAgICAqIAogICAgICogUHlFdmFsX0luaXRUaHJlYWRzIGlzIGNhbGxlZCBoZXJlIGR1ZSB0byBhIHF1aXJrIGluIHB5dGhvbiAxLjUKICAgICAqIC0gMi4yLjEgKGF0IGxlYXN0KSBhY2NvcmRpbmcgdG8gUnVzc2VsbCBXaWxsaWFtc29uIDxtZXJlbEB3dC5uZXQ+OgogICAgICogVGhlIGdsb2JhbCBpbnRlcmVwcmV0ZXIgbG9jayBpcyBub3QgaW5pdGlhbGl6ZWQgdW50aWwgdGhlIGZpcnN0CiAgICAgKiB0aHJlYWQgaXMgY3JlYXRlZCB1c2luZyB0aHJlYWQuc3RhcnRfbmV3X3RocmVhZCgpIG9yIGZvcmsoKSBpcwogICAgICogY2FsbGVkLiAgdGhhdCB3b3VsZCBjYXVzZSB0aGUgQUxMT1dfVEhSRUFEUyBoZXJlIHRvIHNlZ2ZhdWx0IGR1ZQogICAgICogdG8gYSBudWxsIHBvaW50ZXIgcmVmZXJlbmNlIGlmIG5vIHRocmVhZHMgb3IgY2hpbGQgcHJvY2Vzc2VzCiAgICAgKiBoYXZlIGJlZW4gY3JlYXRlZC4gIFRoaXMgd29ya3MgYXJvdW5kIHRoYXQgYW5kIGlzIGEgbm8tb3AgaWYKICAgICAqIHRocmVhZHMgaGF2ZSBhbHJlYWR5IGJlZW4gaW5pdGlhbGl6ZWQuCiAgICAgKiAgKHNlZSBweWJzZGRiLXVzZXJzIG1haWxpbmcgbGlzdCBwb3N0IG9uIDIwMDItMDgtMDcpCiAgICAgKi8KICAgIFB5RXZhbF9Jbml0VGhyZWFkcygpOwoKZXJyb3I6CiAgICBpZiAoUHlFcnJfT2NjdXJyZWQoKSkKICAgIHsKICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfSW1wb3J0RXJyb3IsIE1PRFVMRV9OQU1FICI6IGluaXQgZmFpbGVkIik7CiAgICB9Cn0K