LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAogKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCiAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgogKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCiAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQogKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqIAogKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKiAKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAogKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgogKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKICogdW5kZXIgdGhlIExpY2Vuc2UuCiAqIAogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgoKLy8gTUFSS0VSKHVwZGF0ZV9wcmVjb21wLnB5KTogYXV0b2dlbiBpbmNsdWRlIHN0YXRlbWVudCwgZG8gbm90IHJlbW92ZQojaW5jbHVkZSAicHJlY29tcGlsZWRfY29ubmVjdGl2aXR5Lmh4eCIKI2luY2x1ZGUgImNvbm5lY3Rpdml0eS9zcWxpdGVyYXRvci5oeHgiCiNpbmNsdWRlICJjb25uZWN0aXZpdHkvc2RiY3gvVlRhYmxlLmh4eCIKI2luY2x1ZGUgPGNvbm5lY3Rpdml0eS9zcWxwYXJzZS5oeHg+CiNpbmNsdWRlIDxjb25uZWN0aXZpdHkvZGJ0b29scy5oeHg+CiNpbmNsdWRlIDxjb25uZWN0aXZpdHkvc3FsZXJyb3IuaHh4PgojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL3NkYmMvQ29sdW1uVmFsdWUuaHBwPgojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL3NkYmMvRGF0YVR5cGUuaHBwPgojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL3NkYmMvWFJvdy5ocHA+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvc2RiL1hRdWVyaWVzU3VwcGxpZXIuaHBwPgojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL3NkYi9FcnJvckNvbmRpdGlvbi5ocHA+CiNpZmRlZiBTUUxfVEVTVF9QQVJTRVRSRUVJVEVSQVRPUgojaW5jbHVkZSA8aW9zdHJlYW0+CiNlbmRpZgojaW5jbHVkZSAiY29ubmVjdGl2aXR5L1BDb2x1bW4uaHh4IgojaW5jbHVkZSAiY29ubmVjdGl2aXR5L2RidG9vbHMuaHh4IgojaW5jbHVkZSA8dG9vbHMvZGlhZ25vc2VfZXguaD4KI2luY2x1ZGUgIlRDb25uZWN0aW9uLmh4eCIKI2luY2x1ZGUgPGNvbXBoZWxwZXIvdHlwZXMuaHh4PgojaW5jbHVkZSA8Y29ubmVjdGl2aXR5L2RibWV0YWRhdGEuaHh4PgojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL3NkYi9TUUxGaWx0ZXJPcGVyYXRvci5ocHA+CiNpbmNsdWRlICJkaWFnbm9zZV9leC5oIgojaW5jbHVkZSA8cnRsL2xvZ2ZpbGUuaHh4PgoKI2RlZmluZSBTUUxfSVNSVUxFT1IyKHBQYXJzZU5vZGUsIGUxLGUyKSAJKChwUGFyc2VOb2RlKS0+aXNSdWxlKCkgJiYgKFwKCQkJCQkJCQkJCQkocFBhcnNlTm9kZSktPmdldFJ1bGVJRCgpID09IE9TUUxQYXJzZXI6OlJ1bGVJRChPU1FMUGFyc2VOb2RlOjplMSkgfHwgXAoJCQkJCQkJCQkJCShwUGFyc2VOb2RlKS0+Z2V0UnVsZUlEKCkgPT0gT1NRTFBhcnNlcjo6UnVsZUlEKE9TUUxQYXJzZU5vZGU6OmUyKSkpCgp1c2luZyBuYW1lc3BhY2UgOjpjb21waGVscGVyOwp1c2luZyBuYW1lc3BhY2UgOjpjb25uZWN0aXZpdHk7CnVzaW5nIG5hbWVzcGFjZSA6OmNvbm5lY3Rpdml0eTo6c2RiY3g7CnVzaW5nIG5hbWVzcGFjZSA6OmRidG9vbHM7CnVzaW5nIG5hbWVzcGFjZSA6OmNvbm5lY3Rpdml0eTo6cGFyc2U7CnVzaW5nIG5hbWVzcGFjZSA6OmNvbTo6c3VuOjpzdGFyOwp1c2luZyBuYW1lc3BhY2UgOjpjb206OnN1bjo6c3Rhcjo6dW5vOwp1c2luZyBuYW1lc3BhY2UgOjpjb206OnN1bjo6c3Rhcjo6Y29udGFpbmVyOwp1c2luZyBuYW1lc3BhY2UgOjpjb206OnN1bjo6c3Rhcjo6c2RiY3g7CnVzaW5nIG5hbWVzcGFjZSA6OmNvbTo6c3VuOjpzdGFyOjpiZWFuczsKdXNpbmcgbmFtZXNwYWNlIDo6Y29tOjpzdW46OnN0YXI6OnNkYmM7CnVzaW5nIG5hbWVzcGFjZSA6OmNvbTo6c3VuOjpzdGFyOjpzZGI7CgpuYW1lc3BhY2UgY29ubmVjdGl2aXR5CnsKCXN0cnVjdCBPU1FMUGFyc2VUcmVlSXRlcmF0b3JJbXBsCgl7CiAgICAgICAgOjpzdGQ6OnZlY3RvcjwgVE5vZGVQYWlyID4gICAgICBtX2FKb2luQ29uZGl0aW9uczsKCQlSZWZlcmVuY2U8IFhDb25uZWN0aW9uID4gICAgICAgIG1feENvbm5lY3Rpb247CgkJUmVmZXJlbmNlPCBYRGF0YWJhc2VNZXRhRGF0YSA+ICBtX3hEYXRhYmFzZU1ldGFEYXRhOwoJCVJlZmVyZW5jZTwgWE5hbWVBY2Nlc3MgPiAgICAgICAgbV94VGFibGVDb250YWluZXI7CiAgICAgICAgUmVmZXJlbmNlPCBYTmFtZUFjY2VzcyA+ICAgICAgICBtX3hRdWVyeUNvbnRhaW5lcjsKCiAgICAgICAgOjpib29zdDo6c2hhcmVkX3B0cjwgT1NRTFRhYmxlcyA+ICAgbV9wVGFibGVzOyAgICAgIC8vLyBhbGwgdGFibGVzIHdoaWNoIHBhcnRpY2lwYXRlIGluIHRoZSBTUUwgc3RhdGVtZW50CiAgICAgICAgOjpib29zdDo6c2hhcmVkX3B0cjwgT1NRTFRhYmxlcyA+ICAgbV9wU3ViVGFibGVzOyAgIC8vLyBhbGwgdGFibGVzIGZyb20gc3ViIHF1ZXJpZXMgbm90IHRoZSB0YWJsZXMgZnJvbSB0aGUgc2VsZWN0IHRhYmxlcwogICAgICAgIDo6Ym9vc3Q6OnNoYXJlZF9wdHI8IFF1ZXJ5TmFtZVNldCA+IG1fcEZvcmJpZGRlblF1ZXJ5TmFtZXM7CgogICAgICAgIHNhbF91SW50MzIgICAgICAgICAgICAgICAgICAgICAgbV9uSW5jbHVkZU1hc2s7CgogICAgICAgIGJvb2wgICAgICAgICAgICAgICAgICAgICAgICAgICAgbV9iSXNDYXNlU2Vuc2l0aXZlOwoKICAgICAgICBPU1FMUGFyc2VUcmVlSXRlcmF0b3JJbXBsKCBjb25zdCBSZWZlcmVuY2U8IFhDb25uZWN0aW9uID4mIF9yeENvbm5lY3Rpb24sIGNvbnN0IFJlZmVyZW5jZTwgWE5hbWVBY2Nlc3MgPiYgX3J4VGFibGVzICkgCiAgICAgICAgICAgIDptX3hDb25uZWN0aW9uKCBfcnhDb25uZWN0aW9uICkKICAgICAgICAgICAgLG1fbkluY2x1ZGVNYXNrKCBPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OkFsbCApCiAgICAgICAgICAgICxtX2JJc0Nhc2VTZW5zaXRpdmUoIHRydWUgKQoJCXsKICAgICAgICAgICAgT1NMX1BSRUNPTkQoIG1feENvbm5lY3Rpb24uaXMoKSwgIk9TUUxQYXJzZVRyZWVJdGVyYXRvckltcGw6Ok9TUUxQYXJzZVRyZWVJdGVyYXRvckltcGw6IGludmFsaWQgY29ubmVjdGlvbiEiICk7CiAgICAgICAgICAgIG1feERhdGFiYXNlTWV0YURhdGEgPSBtX3hDb25uZWN0aW9uLT5nZXRNZXRhRGF0YSgpOwoKICAgICAgICAgICAgbV9iSXNDYXNlU2Vuc2l0aXZlID0gbV94RGF0YWJhc2VNZXRhRGF0YS5pcygpICYmIG1feERhdGFiYXNlTWV0YURhdGEtPnN1cHBvcnRzTWl4ZWRDYXNlUXVvdGVkSWRlbnRpZmllcnMoKTsKICAgICAgICAgICAgbV9wVGFibGVzLnJlc2V0KCBuZXcgT1NRTFRhYmxlcyggbV9iSXNDYXNlU2Vuc2l0aXZlICkgKTsKICAgICAgICAgICAgbV9wU3ViVGFibGVzLnJlc2V0KCBuZXcgT1NRTFRhYmxlcyggbV9iSXNDYXNlU2Vuc2l0aXZlICkgKTsKCiAgICAgICAgICAgIG1feFRhYmxlQ29udGFpbmVyID0gX3J4VGFibGVzOwoKICAgICAgICAgICAgRGF0YWJhc2VNZXRhRGF0YSBhTWV0YURhdGEoIG1feENvbm5lY3Rpb24gKTsKICAgICAgICAgICAgaWYgKCBhTWV0YURhdGEuc3VwcG9ydHNTdWJxdWVyaWVzSW5Gcm9tKCkgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyBjb25uZWN0aW9ucyBtaWdodCBzdXBwb3J0IHRoZSBYUXVlcmllc1N1cHBsaWVyIGludGVyZmFjZSwgaWYgdGhleSBpbXBsZW1lbnQgdGhlIGNzcy5zZGIuQ29ubmVjdGlvbgogICAgICAgICAgICAgICAgLy8gc2VydmljZQogICAgICAgICAgICAgICAgUmVmZXJlbmNlPCBYUXVlcmllc1N1cHBsaWVyID4geFN1cHBRdWVyaWVzKCBtX3hDb25uZWN0aW9uLCBVTk9fUVVFUlkgKTsKICAgICAgICAgICAgICAgIGlmICggeFN1cHBRdWVyaWVzLmlzKCkgKQogICAgICAgICAgICAgICAgICAgIG1feFF1ZXJ5Q29udGFpbmVyID0geFN1cHBRdWVyaWVzLT5nZXRRdWVyaWVzKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgcHVibGljOgogICAgICAgIGlubGluZSAgYm9vbCAgICBpc1F1ZXJ5QWxsb3dlZCggY29uc3QgOjpydGw6Ok9VU3RyaW5nJiBfclF1ZXJ5TmFtZSApCiAgICAgICAgewogICAgICAgICAgICBpZiAoICFtX3BGb3JiaWRkZW5RdWVyeU5hbWVzLmdldCgpICkKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICBpZiAoIG1fcEZvcmJpZGRlblF1ZXJ5TmFtZXMtPmZpbmQoIF9yUXVlcnlOYW1lICkgPT0gbV9wRm9yYmlkZGVuUXVlcnlOYW1lcy0+ZW5kKCkgKQogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9Cgl9OwoKICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgLyoqIGhlbHBlciBjbGFzcyBmb3IgdGVtcG9yYXJpbHkgYWRkaW5nIGEgcXVlcnkgbmFtZSB0byBhIGxpc3Qgb2YgZm9yYmlkZGVuIHF1ZXJ5IG5hbWVzCiAgICAqLwogICAgY2xhc3MgRm9yYmlkUXVlcnlOYW1lCiAgICB7CiAgICAgICAgOjpib29zdDo6c2hhcmVkX3B0cjwgUXVlcnlOYW1lU2V0ID4mICAgIG1fcnBBbGxGb3JiaWRkZW5OYW1lczsKICAgICAgICA6OnJ0bDo6T1VTdHJpbmcgICAgICAgICAgICAgICAgICAgICAgICAgbV9zRm9yYmlkZGVuUXVlcnlOYW1lOwoKICAgIHB1YmxpYzoKICAgICAgICBGb3JiaWRRdWVyeU5hbWUoIE9TUUxQYXJzZVRyZWVJdGVyYXRvckltcGwmIF9ySXRlcmF0b3JJbXBsLCBjb25zdCA6OnJ0bDo6T1VTdHJpbmcgX3JGb3JiaWRkZW5RdWVyeU5hbWUgKQogICAgICAgICAgICA6bV9ycEFsbEZvcmJpZGRlbk5hbWVzKCBfckl0ZXJhdG9ySW1wbC5tX3BGb3JiaWRkZW5RdWVyeU5hbWVzICkKICAgICAgICAgICAgLG1fc0ZvcmJpZGRlblF1ZXJ5TmFtZSggX3JGb3JiaWRkZW5RdWVyeU5hbWUgKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKCAhbV9ycEFsbEZvcmJpZGRlbk5hbWVzLmdldCgpICkKICAgICAgICAgICAgICAgIG1fcnBBbGxGb3JiaWRkZW5OYW1lcy5yZXNldCggbmV3IFF1ZXJ5TmFtZVNldCApOwogICAgICAgICAgICBtX3JwQWxsRm9yYmlkZGVuTmFtZXMtPmluc2VydCggbV9zRm9yYmlkZGVuUXVlcnlOYW1lICk7CiAgICAgICAgfQoKICAgICAgICB+Rm9yYmlkUXVlcnlOYW1lKCkKICAgICAgICB7CiAgICAgICAgICAgIG1fcnBBbGxGb3JiaWRkZW5OYW1lcy0+ZXJhc2UoIG1fc0ZvcmJpZGRlblF1ZXJ5TmFtZSApOwogICAgICAgIH0KICAgIH07Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpPU1FMUGFyc2VUcmVlSXRlcmF0b3I6Ok9TUUxQYXJzZVRyZWVJdGVyYXRvcihjb25zdCBSZWZlcmVuY2U8IFhDb25uZWN0aW9uID4mIF9yeENvbm5lY3Rpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFJlZmVyZW5jZTwgWE5hbWVBY2Nlc3MgPiYgX3J4VGFibGVzLAoJCQkJCQkJCQkJCSBjb25zdCBPU1FMUGFyc2VyJiBfclBhcnNlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgT1NRTFBhcnNlTm9kZSogcFJvb3QgKQogICAgOm1fclBhcnNlciggX3JQYXJzZXIgKQogICAgLG1fcEltcGwoIG5ldyBPU1FMUGFyc2VUcmVlSXRlcmF0b3JJbXBsKCBfcnhDb25uZWN0aW9uLCBfcnhUYWJsZXMgKSApCnsKICAgIFJUTF9MT0dGSUxFX0NPTlRFWFRfQVVUSE9SKCBhTG9nZ2VyLCAicGFyc2UiLCAiT2NrZS5KYW5zc2VuQHN1bi5jb20iLCAiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjpPU1FMUGFyc2VUcmVlSXRlcmF0b3IiICk7CglzZXRQYXJzZVRyZWUocFJvb3QpOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCk9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6T1NRTFBhcnNlVHJlZUl0ZXJhdG9yKCBjb25zdCBPU1FMUGFyc2VUcmVlSXRlcmF0b3ImIF9yUGFyZW50SXRlcmF0b3IsIGNvbnN0IE9TUUxQYXJzZXImIF9yUGFyc2VyLCBjb25zdCBPU1FMUGFyc2VOb2RlKiBwUm9vdCApCgk6bV9yUGFyc2VyKCBfclBhcnNlciApCiAgICAsbV9wSW1wbCggbmV3IE9TUUxQYXJzZVRyZWVJdGVyYXRvckltcGwoIF9yUGFyZW50SXRlcmF0b3IubV9wSW1wbC0+bV94Q29ubmVjdGlvbiwgX3JQYXJlbnRJdGVyYXRvci5tX3BJbXBsLT5tX3hUYWJsZUNvbnRhaW5lciApICkKewogICAgUlRMX0xPR0ZJTEVfQ09OVEVYVF9BVVRIT1IoIGFMb2dnZXIsICJwYXJzZSIsICJPY2tlLkphbnNzZW5Ac3VuLmNvbSIsICJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6Ok9TUUxQYXJzZVRyZWVJdGVyYXRvciIgKTsKICAgIG1fcEltcGwtPm1fcEZvcmJpZGRlblF1ZXJ5TmFtZXMgPSBfclBhcmVudEl0ZXJhdG9yLm1fcEltcGwtPm1fcEZvcmJpZGRlblF1ZXJ5TmFtZXM7CglzZXRQYXJzZVRyZWUoIHBSb290ICk7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjp+T1NRTFBhcnNlVHJlZUl0ZXJhdG9yKCkKewoJZGlzcG9zZSgpOwp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpjb25zdCBPU1FMVGFibGVzJiBPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OmdldFRhYmxlcygpIGNvbnN0CnsKICAgIFJUTF9MT0dGSUxFX0NPTlRFWFRfQVVUSE9SKCBhTG9nZ2VyLCAicGFyc2UiLCAiT2NrZS5KYW5zc2VuQHN1bi5jb20iLCAiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjpnZXRUYWJsZXMiICk7CiAgICByZXR1cm4gKm1fcEltcGwtPm1fcFRhYmxlczsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KYm9vbCBPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OmlzQ2FzZVNlbnNpdGl2ZSgpIGNvbnN0CnsKICAgIFJUTF9MT0dGSUxFX0NPTlRFWFRfQVVUSE9SKCBhTG9nZ2VyLCAicGFyc2UiLCAiT2NrZS5KYW5zc2VuQHN1bi5jb20iLCAiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjppc0Nhc2VTZW5zaXRpdmUiICk7CiAgICByZXR1cm4gbV9wSW1wbC0+bV9iSXNDYXNlU2Vuc2l0aXZlOwp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIE9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6ZGlzcG9zZSgpCnsKICAgIFJUTF9MT0dGSUxFX0NPTlRFWFRfQVVUSE9SKCBhTG9nZ2VyLCAicGFyc2UiLCAiT2NrZS5KYW5zc2VuQHN1bi5jb20iLCAiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjpkaXNwb3NlIiApOwoJbV9hU2VsZWN0Q29sdW1ucwk9IE5VTEw7CgltX2FHcm91cENvbHVtbnMJCT0gTlVMTDsKCW1fYU9yZGVyQ29sdW1ucwkJPSBOVUxMOwoJbV9hUGFyYW1ldGVycwkJPSBOVUxMOwoJbV9wSW1wbC0+bV94VGFibGVDb250YWluZXIJPSBOVUxMOwoJbV9wSW1wbC0+bV94RGF0YWJhc2VNZXRhRGF0YSA9IE5VTEw7CgltX2FDcmVhdGVDb2x1bW5zCT0gTlVMTDsKCW1fcEltcGwtPm1fcFRhYmxlcy0+Y2xlYXIoKTsKCW1fcEltcGwtPm1fcFN1YlRhYmxlcy0+Y2xlYXIoKTsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjpzZXRQYXJzZVRyZWUoY29uc3QgT1NRTFBhcnNlTm9kZSAqIHBOZXdQYXJzZVRyZWUpCnsKICAgIFJUTF9MT0dGSUxFX0NPTlRFWFRfQVVUSE9SKCBhTG9nZ2VyLCAicGFyc2UiLCAiT2NrZS5KYW5zc2VuQHN1bi5jb20iLCAiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjpzZXRQYXJzZVRyZWUiICk7CgltX3BJbXBsLT5tX3BUYWJsZXMtPmNsZWFyKCk7CgltX3BJbXBsLT5tX3BTdWJUYWJsZXMtPmNsZWFyKCk7CgoJbV9hU2VsZWN0Q29sdW1ucyA9IG5ldyBPU1FMQ29sdW1ucygpOwoJbV9hR3JvdXBDb2x1bW5zID0gbmV3IE9TUUxDb2x1bW5zKCk7CgltX2FPcmRlckNvbHVtbnMgPSBuZXcgT1NRTENvbHVtbnMoKTsKCW1fYVBhcmFtZXRlcnMJID0gbmV3IE9TUUxDb2x1bW5zKCk7CgltX2FDcmVhdGVDb2x1bW5zID0gbmV3IE9TUUxDb2x1bW5zKCk7CgoJbV9wUGFyc2VUcmVlID0gcE5ld1BhcnNlVHJlZTsKCWlmICghbV9wUGFyc2VUcmVlKQoJewoJCW1fZVN0YXRlbWVudFR5cGUgPSBTUUxfU1RBVEVNRU5UX1VOS05PV047CgkJcmV0dXJuOwoJfQoKCS8vIGZhbGxzIG1fcFBhcnNlVHJlZSBhYmVyIGtlaW5lIENvbm5lY3Rpb24sIGRhbm4gRmVobGVyCglpZiAoICFtX3BJbXBsLT5tX3hUYWJsZUNvbnRhaW5lci5pcygpICkKCQlyZXR1cm47CgoJbV9hRXJyb3JzID0gU1FMRXhjZXB0aW9uKCk7CgoKCS8vIFN0YXRlbWVudC1UeXAgZXJtaXR0ZWxuIC4uLgoJaWYgKFNRTF9JU1JVTEUobV9wUGFyc2VUcmVlLHNlbGVjdF9zdGF0ZW1lbnQpIHx8IFNRTF9JU1JVTEUobV9wUGFyc2VUcmVlLHVuaW9uX3N0YXRlbWVudCkgKQoJewoJCW1fZVN0YXRlbWVudFR5cGUgPSBTUUxfU1RBVEVNRU5UX1NFTEVDVDsKCX0KCWVsc2UgaWYgKFNRTF9JU1JVTEUobV9wUGFyc2VUcmVlLGluc2VydF9zdGF0ZW1lbnQpKQoJewoJCW1fZVN0YXRlbWVudFR5cGUgPSBTUUxfU1RBVEVNRU5UX0lOU0VSVDsKCX0KCWVsc2UgaWYgKFNRTF9JU1JVTEUobV9wUGFyc2VUcmVlLHVwZGF0ZV9zdGF0ZW1lbnRfc2VhcmNoZWQpKQoJewoJCW1fZVN0YXRlbWVudFR5cGUgPSBTUUxfU1RBVEVNRU5UX1VQREFURTsKCX0KCWVsc2UgaWYgKFNRTF9JU1JVTEUobV9wUGFyc2VUcmVlLGRlbGV0ZV9zdGF0ZW1lbnRfc2VhcmNoZWQpKQoJewoJCW1fZVN0YXRlbWVudFR5cGUgPSBTUUxfU1RBVEVNRU5UX0RFTEVURTsKCX0KCWVsc2UgaWYgKG1fcFBhcnNlVHJlZS0+Y291bnQoKSA9PSAzICYmIFNRTF9JU1JVTEUobV9wUGFyc2VUcmVlLT5nZXRDaGlsZCgxKSxvZGJjX2NhbGxfc3BlYykpCgl7CgkJbV9lU3RhdGVtZW50VHlwZSA9IFNRTF9TVEFURU1FTlRfT0RCQ19DQUxMOwoJfQoJZWxzZSBpZiAoU1FMX0lTUlVMRShtX3BQYXJzZVRyZWUtPmdldENoaWxkKDApLGJhc2VfdGFibGVfZGVmKSkKCXsKICAgICAgICBtX2VTdGF0ZW1lbnRUeXBlID0gU1FMX1NUQVRFTUVOVF9DUkVBVEVfVEFCTEU7CgkJbV9wUGFyc2VUcmVlID0gbV9wUGFyc2VUcmVlLT5nZXRDaGlsZCgwKTsKCX0KCWVsc2UKCXsKCQltX2VTdGF0ZW1lbnRUeXBlID0gU1FMX1NUQVRFTUVOVF9VTktOT1dOOwoJCS8vYUl0ZXJhdG9yU3RhdHVzLnNldEludmFsaWRTdGF0ZW1lbnQoKTsKCQlyZXR1cm47Cgl9Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KbmFtZXNwYWNlCnsKICAgIC8vLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLgogICAgc3RhdGljIHZvaWQgaW1wbF9nZXRSb3dTdHJpbmcoIGNvbnN0IFJlZmVyZW5jZTwgWFJvdyA+JiBfcnhSb3csIGNvbnN0IHNhbF9JbnQzMiBfbkNvbHVtbkluZGV4LCA6OnJ0bDo6T1VTdHJpbmcmIF9vdXRfclN0cmluZyApCiAgICB7CgkJX291dF9yU3RyaW5nID0gX3J4Um93LT5nZXRTdHJpbmcoIF9uQ29sdW1uSW5kZXggKTsKCQlpZiAoIF9yeFJvdy0+d2FzTnVsbCgpICkKCQkJX291dF9yU3RyaW5nPSA6OnJ0bDo6T1VTdHJpbmcoKTsKICAgIH0KCiAgICAvLy4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4KICAgIHN0YXRpYyA6OnJ0bDo6T1VTdHJpbmcgbGNsX2ZpbmRUYWJsZUluTWV0YURhdGEoCiAgICAgICAgY29uc3QgUmVmZXJlbmNlPCBYRGF0YWJhc2VNZXRhRGF0YSA+JiBfcnhEQk1ldGEsIGNvbnN0IDo6cnRsOjpPVVN0cmluZyYgX3JDYXRhbG9nLAogICAgICAgIGNvbnN0IDo6cnRsOjpPVVN0cmluZyYgX3JTY2hlbWEsIGNvbnN0IDo6cnRsOjpPVVN0cmluZyYgX3JUYWJsZU5hbWUgKQogICAgewogICAgICAgIDo6cnRsOjpPVVN0cmluZyBzQ29tcG9zZWROYW1lOwoKCQlzdGF0aWMgY29uc3QgOjpydGw6Ok9VU3RyaW5nIHNfc1RhYmxlVHlwZVZpZXcoUlRMX0NPTlNUQVNDSUlfVVNUUklOR1BBUkFNKCJWSUVXIikpOwoJCXN0YXRpYyBjb25zdCA6OnJ0bDo6T1VTdHJpbmcgc19zVGFibGVUeXBlVGFibGUoUlRMX0NPTlNUQVNDSUlfVVNUUklOR1BBUkFNKCJUQUJMRSIpKTsKCQlzdGF0aWMgY29uc3QgOjpydGw6Ok9VU3RyaW5nIHNfc1dpbGRjYXJkID0gOjpydGw6Ok9VU3RyaW5nOjpjcmVhdGVGcm9tQXNjaWkoIiUiKTsKCgkJLy8gd2Ugd2FudCBhbGwgY2F0YWxvZ3VlcywgYWxsIHNjaGVtYXMsIGFsbCB0YWJsZXMKCQlTZXF1ZW5jZTwgOjpydGw6Ok9VU3RyaW5nID4gc1RhYmxlVHlwZXMoMyk7CgkJc1RhYmxlVHlwZXNbMF0gPSBzX3NUYWJsZVR5cGVWaWV3OwoJCXNUYWJsZVR5cGVzWzFdID0gc19zVGFibGVUeXBlVGFibGU7CgkJc1RhYmxlVHlwZXNbMl0gPSBzX3NXaWxkY2FyZDsJLy8ganVzdCB0byBiZSBzdXJlIHRvIGluY2x1ZGUgYW55dGhpbmcgZWxzZSAuLi4uCgoJCWlmICggX3J4REJNZXRhLmlzKCkgKQoJCXsKCQkJc0NvbXBvc2VkTmFtZSA9IDo6cnRsOjpPVVN0cmluZygpOwoKICAgICAgICAgICAgUmVmZXJlbmNlPCBYUmVzdWx0U2V0PiB4UmVzID0gX3J4REJNZXRhLT5nZXRUYWJsZXMoCiAgICAgICAgICAgICAgICBfckNhdGFsb2cuZ2V0TGVuZ3RoKCkgPyBtYWtlQW55KCBfckNhdGFsb2cgKSA6IEFueSgpLCBfclNjaGVtYS5nZXRMZW5ndGgoKSA/IF9yU2NoZW1hIDogc19zV2lsZGNhcmQsIF9yVGFibGVOYW1lLCBzVGFibGVUeXBlcyApOwoKCQkJUmVmZXJlbmNlPCBYUm93ID4geEN1cnJlbnRSb3coIHhSZXMsIFVOT19RVUVSWSApOwogICAgICAgICAgICBpZiAoIHhDdXJyZW50Um93LmlzKCkgJiYgeFJlcy0+bmV4dCgpICkKCQkJewoJCQkJOjpydGw6Ok9VU3RyaW5nIHNDYXRhbG9nLCBzU2NoZW1hLCBzTmFtZTsKCiAgICAgICAgICAgICAgICBpbXBsX2dldFJvd1N0cmluZyggeEN1cnJlbnRSb3csIDEsIHNDYXRhbG9nICk7CiAgICAgICAgICAgICAgICBpbXBsX2dldFJvd1N0cmluZyggeEN1cnJlbnRSb3csIDIsIHNTY2hlbWEgKTsKICAgICAgICAgICAgICAgIGltcGxfZ2V0Um93U3RyaW5nKCB4Q3VycmVudFJvdywgMywgc05hbWUgKTsKCgkJCQlzQ29tcG9zZWROYW1lID0gOjpkYnRvb2xzOjpjb21wb3NlVGFibGVOYW1lKAogICAgICAgICAgICAgICAgICAgIF9yeERCTWV0YSwKICAgICAgICAgICAgICAgICAgICBzQ2F0YWxvZywKCQkJCQlzU2NoZW1hLAoJCQkJCXNOYW1lLAoJCQkJCXNhbF9GYWxzZSwKCQkJCQk6OmRidG9vbHM6OmVJbkRhdGFNYW5pcHVsYXRpb24KICAgICAgICAgICAgICAgICk7CgkJCX0KCQl9CiAgICAgICAgcmV0dXJuIHNDb21wb3NlZE5hbWU7CiAgICB9Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OmltcGxfZ2V0UXVlcnlQYXJhbWV0ZXJDb2x1bW5zKCBjb25zdCBPU1FMVGFibGUmIF9yUXVlcnkgICkKewogICAgUlRMX0xPR0ZJTEVfQ09OVEVYVF9BVVRIT1IoIGFMb2dnZXIsICJwYXJzZSIsICJPY2tlLkphbnNzZW5Ac3VuLmNvbSIsICJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OmltcGxfZ2V0UXVlcnlQYXJhbWV0ZXJDb2x1bW5zIiApOwogICAgaWYgKCAoIG1fcEltcGwtPm1fbkluY2x1ZGVNYXNrICYgUGFyYW1ldGVycyApICE9IFBhcmFtZXRlcnMgKQogICAgICAgIC8vIHBhcmFtZXRlcnMgbm90IHRvIGJlIGluY2x1ZGVkIGluIHRoZSB0cmF2ZXJzYWwKICAgICAgICByZXR1cm47CgogICAgOjp2b3M6Ok9SZWY8IE9TUUxDb2x1bW5zID4gcFN1YlF1ZXJ5UGFyYW1ldGVyQ29sdW1ucyggbmV3IE9TUUxDb2x1bW5zKCkgKTsKCiAgICAvLyBnZXQgdGhlIGNvbW1hbmQgYW5kIHRoZSBFc2NhcGVQcm9jZXNzaW5nIHByb3BlcnRpZXMgZnJvbSB0aGUgc3ViIHF1ZXJ5CiAgICA6OnJ0bDo6T1VTdHJpbmcgc1N1YlF1ZXJ5Q29tbWFuZDsKICAgIHNhbF9Cb29sIGJFc2NhcGVQcm9jZXNzaW5nID0gc2FsX0ZhbHNlOwogICAgdHJ5CiAgICB7CiAgICAgICAgUmVmZXJlbmNlPCBYUHJvcGVydHlTZXQgPiB4UXVlcnlQcm9wZXJ0aWVzKCBfclF1ZXJ5LCBVTk9fUVVFUllfVEhST1cgKTsKICAgICAgICBPU0xfVkVSSUZZKCB4UXVlcnlQcm9wZXJ0aWVzLT5nZXRQcm9wZXJ0eVZhbHVlKCBPTWV0YUNvbm5lY3Rpb246OmdldFByb3BNYXAoKS5nZXROYW1lQnlJbmRleCggUFJPUEVSVFlfSURfQ09NTUFORCApICkgPj49IHNTdWJRdWVyeUNvbW1hbmQgKTsKICAgICAgICBPU0xfVkVSSUZZKCB4UXVlcnlQcm9wZXJ0aWVzLT5nZXRQcm9wZXJ0eVZhbHVlKCBPTWV0YUNvbm5lY3Rpb246OmdldFByb3BNYXAoKS5nZXROYW1lQnlJbmRleCggUFJPUEVSVFlfSURfRVNDQVBFUFJPQ0VTU0lORyApICkgPj49IGJFc2NhcGVQcm9jZXNzaW5nICk7CiAgICB9CiAgICBjYXRjaCggY29uc3QgRXhjZXB0aW9uJiApCiAgICB7CiAgICAgICAgREJHX1VOSEFORExFRF9FWENFUFRJT04oKTsKICAgIH0KCiAgICAvLyBwYXJzZSB0aGUgc3ViIHF1ZXJ5CiAgICBkbyB7CgogICAgaWYgKCAhYkVzY2FwZVByb2Nlc3NpbmcgfHwgKCBzU3ViUXVlcnlDb21tYW5kLmdldExlbmd0aCgpID09IDAgKSApCiAgICAgICAgYnJlYWs7CgogICAgOjpydGw6Ok9VU3RyaW5nIHNFcnJvcjsKICAgIDo6c3RkOjphdXRvX3B0cjwgT1NRTFBhcnNlTm9kZSA+IHBTdWJRdWVyeU5vZGUoIGNvbnN0X2Nhc3Q8IE9TUUxQYXJzZXImID4oIG1fclBhcnNlciApLnBhcnNlVHJlZSggc0Vycm9yLCBzU3ViUXVlcnlDb21tYW5kLCBzYWxfRmFsc2UgKSApOwogICAgaWYgKCAhcFN1YlF1ZXJ5Tm9kZS5nZXQoKSApCiAgICAgICAgYnJlYWs7CgogICAgT1NRTFBhcnNlVHJlZUl0ZXJhdG9yIGFTdWJRdWVyeUl0ZXJhdG9yKCAqdGhpcywgbV9yUGFyc2VyLCBwU3ViUXVlcnlOb2RlLmdldCgpICk7CiAgICBhU3ViUXVlcnlJdGVyYXRvci50cmF2ZXJzZVNvbWUoIFBhcmFtZXRlcnMgfCBTZWxlY3RDb2x1bW5zICk7CiAgICAgICAgLy8gU2VsZWN0Q29sdW1ucyBtaWdodCBhbHNvIGNvbnRhaW4gcGFyYW1ldGVycwogICAgICAgIC8vICNpNzc2MzUjIC0gMjAwNy0wNy0yMyAvIGZyYW5rLnNjaG9lbmhlaXRAc3VuLmNvbQogICAgcFN1YlF1ZXJ5UGFyYW1ldGVyQ29sdW1ucyA9IGFTdWJRdWVyeUl0ZXJhdG9yLmdldFBhcmFtZXRlcnMoKTsKICAgIGFTdWJRdWVyeUl0ZXJhdG9yLmRpc3Bvc2UoKTsKCiAgICB9IHdoaWxlICggZmFsc2UgKTsKCiAgICAvLyBjb3B5IHRoZSBwYXJhbWV0ZXJzIG9mIHRoZSBzdWIgcXVlcnkgdG8gb3VyIG93biBwYXJhbWV0ZXIgYXJyYXkKICAgIDo6c3RkOjpjb3B5KCBwU3ViUXVlcnlQYXJhbWV0ZXJDb2x1bW5zLT5nZXQoKS5iZWdpbigpLCBwU3ViUXVlcnlQYXJhbWV0ZXJDb2x1bW5zLT5nZXQoKS5lbmQoKSwKICAgICAgICA6OnN0ZDo6aW5zZXJ0X2l0ZXJhdG9yPCBPU1FMQ29sdW1uczo6VmVjdG9yID4oIG1fYVBhcmFtZXRlcnMtPmdldCgpLCBtX2FQYXJhbWV0ZXJzLT5nZXQoKS5lbmQoKSApICk7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KT1NRTFRhYmxlIE9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6aW1wbF9sb2NhdGVSZWNvcmRTb3VyY2UoIGNvbnN0IDo6cnRsOjpPVVN0cmluZyYgX3JDb21wb3NlZE5hbWUgKQp7CiAgICBSVExfTE9HRklMRV9DT05URVhUX0FVVEhPUiggYUxvZ2dlciwgInBhcnNlIiwgIk9ja2UuSmFuc3NlbkBzdW4uY29tIiwgIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6aW1wbF9sb2NhdGVSZWNvcmRTb3VyY2UiICk7CiAgICBpZiAoICFfckNvbXBvc2VkTmFtZS5nZXRMZW5ndGgoKSApCiAgICB7CiAgICAgICAgT1NMX0VOU1VSRSggZmFsc2UsICJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OmltcGxfbG9jYXRlUmVjb3JkU291cmNlOiBubyBvYmplY3QgbmFtZSBhdCBhbGw/IiApOwogICAgICAgIHJldHVybiBPU1FMVGFibGUoKTsKICAgIH0KCiAgICBPU1FMVGFibGUgYVJldHVybjsKICAgIDo6cnRsOjpPVVN0cmluZyBzQ29tcG9zZWROYW1lKCBfckNvbXBvc2VkTmFtZSApOwoKCXRyeQoJewogICAgICAgIDo6cnRsOjpPVVN0cmluZyBzQ2F0YWxvZywgc1NjaGVtYSwgc05hbWU7CiAgICAgICAgcXVhbGlmaWVkTmFtZUNvbXBvbmVudHMoIG1fcEltcGwtPm1feERhdGFiYXNlTWV0YURhdGEsIHNDb21wb3NlZE5hbWUsIHNDYXRhbG9nLCBzU2NoZW1hLCBzTmFtZSwgOjpkYnRvb2xzOjplSW5EYXRhTWFuaXB1bGF0aW9uICk7CgogICAgICAgIC8vIGNoZWNrIHdoZXRoZXIgdGhlcmUgaXMgYSBxdWVyeSB3aXRoIHRoZSBnaXZlbiBuYW1lCiAgICAgICAgYm9vbCBiUXVlcnlEb2VzRXhpc3QgPSBtX3BJbXBsLT5tX3hRdWVyeUNvbnRhaW5lci5pcygpICYmIG1fcEltcGwtPm1feFF1ZXJ5Q29udGFpbmVyLT5oYXNCeU5hbWUoIHNDb21wb3NlZE5hbWUgKTsKCiAgICAgICAgLy8gY2hlY2sgd2hldGhlciB0aGUgdGFibGUgY29udGFpbmVyIGNvbnRhaW5zIGFuIG9iamVjdCB3aXRoIHRoZSBnaXZlbiBuYW1lCgkJaWYgKCAhYlF1ZXJ5RG9lc0V4aXN0ICYmICFtX3BJbXBsLT5tX3hUYWJsZUNvbnRhaW5lci0+aGFzQnlOYW1lKCBzQ29tcG9zZWROYW1lICkgKQogICAgICAgICAgICBzQ29tcG9zZWROYW1lID0gbGNsX2ZpbmRUYWJsZUluTWV0YURhdGEoIG1fcEltcGwtPm1feERhdGFiYXNlTWV0YURhdGEsIHNDYXRhbG9nLCBzU2NoZW1hLCBzTmFtZSApOwogICAgICAgIGJvb2wgYlRhYmxlRG9lc0V4aXN0ID0gbV9wSW1wbC0+bV94VGFibGVDb250YWluZXItPmhhc0J5TmFtZSggc0NvbXBvc2VkTmFtZSApOwoKICAgICAgICAvLyBub3cgb2J0YWluIHRoZSBvYmplY3QKCiAgICAgICAgLy8gaWYgd2UncmUgY3JlYXRpbmcgYSB0YWJsZSwgYW5kIHRoZXJlIGFscmVhZHkgaXMgYSB0YWJsZSBvciBxdWVyeSB3aXRoIHRoZSBzYW1lIG5hbWUsCiAgICAgICAgLy8gdGhpcyBpcyB3b3J0aCBhbiBlcnJvcgogICAgICAgIGlmICggU1FMX1NUQVRFTUVOVF9DUkVBVEVfVEFCTEUgPT0gbV9lU3RhdGVtZW50VHlwZSApCiAgICAgICAgewogICAgICAgICAgICBpZiAoIGJRdWVyeURvZXNFeGlzdCApCiAgICAgICAgICAgICAgICBpbXBsX2FwcGVuZEVycm9yKCBJUGFyc2VDb250ZXh0OjpFUlJPUl9JTlZBTElEX1FVRVJZX0VYSVNULCAmc05hbWUgKTsKICAgICAgICAgICAgZWxzZSBpZiAoIGJUYWJsZURvZXNFeGlzdCApCiAgICAgICAgICAgICAgICBpbXBsX2FwcGVuZEVycm9yKCBJUGFyc2VDb250ZXh0OjpFUlJPUl9JTlZBTElEX1RBQkxFX0VYSVNULCAmc05hbWUgKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgYVJldHVybiA9IGltcGxfY3JlYXRlVGFibGVPYmplY3QoIHNOYW1lLCBzQ2F0YWxvZywgc1NjaGVtYSApOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICAvLyBxdWVyaWVzIHdpbiBvdmVyIHRhYmxlcywgc28gaWYgdGhlcmUncyBhIHF1ZXJ5IHdpdGggdGhpcyBuYW1lLCB0YWtlIHRoaXMsIG5vIG1hdHRlciBpZgogICAgICAgICAgICAvLyB0aGVyZSdzIGEgdGFibGUsIHRvbwogICAgICAgICAgICBpZiAoIGJRdWVyeURvZXNFeGlzdCApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICAoICFtX3BJbXBsLT5pc1F1ZXJ5QWxsb3dlZCggc0NvbXBvc2VkTmFtZSApICkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpbXBsX2FwcGVuZEVycm9yKCBtX3JQYXJzZXIuZ2V0RXJyb3JIZWxwZXIoKS5nZXRTUUxFeGNlcHRpb24oIHNkYjo6RXJyb3JDb25kaXRpb246OlBBUlNFUl9DWUNMSUNfU1VCX1FVRVJJRVMsIE5VTEwgKSApOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIG1fcEltcGwtPm1feFF1ZXJ5Q29udGFpbmVyLT5nZXRCeU5hbWUoIHNDb21wb3NlZE5hbWUgKSA+Pj0gYVJldHVybjsKCiAgICAgICAgICAgICAgICAvLyBjb2xsZWN0IHRoZSBwYXJhbWV0ZXJzIGZyb20gdGhlIHN1YiBxdWVyeQogICAgICAgICAgICAgICAgRm9yYmlkUXVlcnlOYW1lIGFGb3JiaWROYW1lKCAqbV9wSW1wbCwgc0NvbXBvc2VkTmFtZSApOwogICAgICAgICAgICAgICAgaW1wbF9nZXRRdWVyeVBhcmFtZXRlckNvbHVtbnMoIGFSZXR1cm4gKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmICggYlRhYmxlRG9lc0V4aXN0ICkKICAgICAgICAgICAgICAgIG1fcEltcGwtPm1feFRhYmxlQ29udGFpbmVyLT5nZXRCeU5hbWUoIHNDb21wb3NlZE5hbWUgKSA+Pj0gYVJldHVybjsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoIG1fcEltcGwtPm1feFF1ZXJ5Q29udGFpbmVyLmlzKCkgKQogICAgICAgICAgICAgICAgICAgIC8vIHRoZSBjb25uZWN0aW9uIG9uIHdoaWNoIHdlJ3JlIHdvcmtpbmcgc3VwcG9ydHMgc3ViIHF1ZXJpZXMgaW4gZnJvbSAoZWxzZQogICAgICAgICAgICAgICAgICAgIC8vIG1feFF1ZXJ5Q29udGFpbmVyIHdvdWxkIG5vdCBoYXZlIGJlZW4gc2V0KSwgc28gZW1pdCBhIGJldHRlciBlcnJvciBtZXNzYWdlCiAgICAgICAgICAgICAgICAgICAgaW1wbF9hcHBlbmRFcnJvciggSVBhcnNlQ29udGV4dDo6RVJST1JfSU5WQUxJRF9UQUJMRV9PUl9RVUVSWSwgJnNOYW1lICk7CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgaW1wbF9hcHBlbmRFcnJvciggSVBhcnNlQ29udGV4dDo6RVJST1JfSU5WQUxJRF9UQUJMRSwgJnNOYW1lICk7CiAgICAgICAgICAgIH0KICAgICAgICB9Cgl9CgljYXRjaChFeGNlcHRpb24mKQoJewogICAgICAgIGltcGxfYXBwZW5kRXJyb3IoIElQYXJzZUNvbnRleHQ6OkVSUk9SX0lOVkFMSURfVEFCTEUsICZzQ29tcG9zZWROYW1lICk7Cgl9CgogICAgcmV0dXJuIGFSZXR1cm47Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OnRyYXZlcnNlT25lVGFibGVOYW1lKCBPU1FMVGFibGVzJiBfclRhYmxlcyxjb25zdCBPU1FMUGFyc2VOb2RlICogcFRhYmxlTmFtZSwgY29uc3QgOjpydGw6Ok9VU3RyaW5nICYgclRhYmxlUmFuZ2UgKQp7CiAgICBSVExfTE9HRklMRV9DT05URVhUX0FVVEhPUiggYUxvZ2dlciwgInBhcnNlIiwgIk9ja2UuSmFuc3NlbkBzdW4uY29tIiwgIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6dHJhdmVyc2VPbmVUYWJsZU5hbWUiICk7CiAgICBpZiAoICggbV9wSW1wbC0+bV9uSW5jbHVkZU1hc2sgJiBUYWJsZU5hbWVzICkgIT0gVGFibGVOYW1lcyApCiAgICAgICAgLy8gdGFibGVzIHNob3VsZCBub3QgYmUgaW5jbHVkZWQgaW4gdGhlIHRyYXZlcnNhbAogICAgICAgIHJldHVybjsKCglPU0xfRU5TVVJFKHBUYWJsZU5hbWUgIT0gTlVMTCwiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjp0cmF2ZXJzZU9uZVRhYmxlTmFtZTogcFRhYmxlTmFtZSA9PSBOVUxMIik7CgoJQW55IGFDYXRhbG9nOwoJOjpydGw6Ok9VU3RyaW5nIGFTY2hlbWEsYVRhYmxlTmFtZSxhQ29tcG9zZWROYW1lOwoJOjpydGw6Ok9VU3RyaW5nIGFUYWJsZVJhbmdlKHJUYWJsZVJhbmdlKTsKCgkvLyBUYWJlbGxlbm5hbWUgYWJob2xlbgoJT1NRTFBhcnNlTm9kZTo6Z2V0VGFibGVDb21wb25lbnRzKHBUYWJsZU5hbWUsYUNhdGFsb2csYVNjaGVtYSxhVGFibGVOYW1lLG1fcEltcGwtPm1feERhdGFiYXNlTWV0YURhdGEpOwoJCgkvLyBjcmVhdGUgdGhlIGNvbXBvc2VkIG5hbWUgbGlrZSBET01BSU4uVVNFUi5UQUJMRTEKCWFDb21wb3NlZE5hbWUgPSA6OmRidG9vbHM6OmNvbXBvc2VUYWJsZU5hbWUobV9wSW1wbC0+bV94RGF0YWJhc2VNZXRhRGF0YSwKCQkJCQkJCQlhQ2F0YWxvZy5oYXNWYWx1ZSgpID8gOjpjb21waGVscGVyOjpnZXRTdHJpbmcoYUNhdGFsb2cpIDogOjpydGw6Ok9VU3RyaW5nKCksCgkJCQkJCQkJYVNjaGVtYSwKCQkJCQkJCQlhVGFibGVOYW1lLAoJCQkJCQkJCXNhbF9GYWxzZSwKCQkJCQkJCQk6OmRidG9vbHM6OmVJbkRhdGFNYW5pcHVsYXRpb24pOwoKICAgIC8vIGlmIHRoZXJlIGlzIG5vIGFsaWFzIGZvciB0aGUgdGFibGUgbmFtZSBhc3NpZ24gdGhlIG9yaWduYWwgbmFtZSB0byBpdAoJaWYgKCAhYVRhYmxlUmFuZ2UuZ2V0TGVuZ3RoKCkgKQoJCWFUYWJsZVJhbmdlID0gYUNvbXBvc2VkTmFtZTsKCiAgICAvLyBnZXQgdGhlIG9iamVjdCByZXByZXNlbnRpbmcgdGhpcyB0YWJsZS9xdWVyeQogICAgT1NRTFRhYmxlIGFUYWJsZSA9IGltcGxfbG9jYXRlUmVjb3JkU291cmNlKCBhQ29tcG9zZWROYW1lICk7CiAgICBpZiAoIGFUYWJsZS5pcygpICkKICAgICAgICBfclRhYmxlc1sgYVRhYmxlUmFuZ2UgXSA9IGFUYWJsZTsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjppbXBsX2ZpbGxKb2luQ29uZGl0aW9ucyhjb25zdCBPU1FMUGFyc2VOb2RlKiBpX3BKb2luQ29uZGl0aW9uKQp7CiAgICBpZiAoaV9wSm9pbkNvbmRpdGlvbi0+Y291bnQoKSA9PSAzICYmCS8vIEF1c2RydWNrIGlzIGdla2xhbW1lcnQKCQlTUUxfSVNQVU5DVFVBVElPTihpX3BKb2luQ29uZGl0aW9uLT5nZXRDaGlsZCgwKSwiKCIpICYmCgkJU1FMX0lTUFVOQ1RVQVRJT04oaV9wSm9pbkNvbmRpdGlvbi0+Z2V0Q2hpbGQoMiksIikiKSkKCXsKICAgICAgICBpbXBsX2ZpbGxKb2luQ29uZGl0aW9ucyhpX3BKb2luQ29uZGl0aW9uLT5nZXRDaGlsZCgxKSk7Cgl9CgllbHNlIGlmIChTUUxfSVNSVUxFT1IyKGlfcEpvaW5Db25kaXRpb24sc2VhcmNoX2NvbmRpdGlvbixib29sZWFuX3Rlcm0pCSYmCQkJLy8gQU5EL09SLVZlcmtudWVwZnVuZzoKCQkJIGlfcEpvaW5Db25kaXRpb24tPmNvdW50KCkgPT0gMykKCXsKCQkvLyBudXIgQU5EIFZlcmtu/HBmdW5nIHp1bGFzc2VuCgkJaWYgKCBTUUxfSVNUT0tFTihpX3BKb2luQ29uZGl0aW9uLT5nZXRDaGlsZCgxKSxBTkQpICkKICAgICAgICB7CiAgICAgICAgICAgIGltcGxfZmlsbEpvaW5Db25kaXRpb25zKGlfcEpvaW5Db25kaXRpb24tPmdldENoaWxkKDApKTsKICAgICAgICAgICAgaW1wbF9maWxsSm9pbkNvbmRpdGlvbnMoaV9wSm9pbkNvbmRpdGlvbi0+Z2V0Q2hpbGQoMSkpOwogICAgICAgIH0KCX0KCWVsc2UgaWYgKFNRTF9JU1JVTEUoaV9wSm9pbkNvbmRpdGlvbixjb21wYXJpc29uX3ByZWRpY2F0ZSkpCgl7CgkJLy8gb25seSB0aGUgY29tcGFyaXNvbiBvZiBjb2x1bW5zIGlzIGFsbG93ZWQKCQlPU0xfRU5TVVJFKGlfcEpvaW5Db25kaXRpb24tPmNvdW50KCkgPT0gMywiT1F1ZXJ5RGVzaWduVmlldzo6SW5zZXJ0Sm9pbkNvbm5lY3Rpb246IEZlaGxlciBpbSBQYXJzZSBUcmVlIik7CgkJaWYgKFNRTF9JU1JVTEUoaV9wSm9pbkNvbmRpdGlvbi0+Z2V0Q2hpbGQoMCksY29sdW1uX3JlZikgJiYKCQkJICBTUUxfSVNSVUxFKGlfcEpvaW5Db25kaXRpb24tPmdldENoaWxkKDIpLGNvbHVtbl9yZWYpICYmCgkJCSAgIGlfcEpvaW5Db25kaXRpb24tPmdldENoaWxkKDEpLT5nZXROb2RlVHlwZSgpID09IFNRTF9OT0RFX0VRVUFMKQogICAgICAgIHsKICAgICAgICAgICAgbV9wSW1wbC0+bV9hSm9pbkNvbmRpdGlvbnMucHVzaF9iYWNrKCBUTm9kZVBhaXIoaV9wSm9pbkNvbmRpdGlvbi0+Z2V0Q2hpbGQoMCksaV9wSm9pbkNvbmRpdGlvbi0+Z2V0Q2hpbGQoMikpICk7CiAgICAgICAgfQogICAgfQp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KOjpzdGQ6OnZlY3RvcjwgVE5vZGVQYWlyID4mIE9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6Z2V0Sm9pbkNvbmRpdGlvbnMoKSBjb25zdAp7CiAgICByZXR1cm4gbV9wSW1wbC0+bV9hSm9pbkNvbmRpdGlvbnM7Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIE9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6Z2V0UXVhbGlmaWVkX2pvaW4oIE9TUUxUYWJsZXMmIF9yVGFibGVzLCBjb25zdCBPU1FMUGFyc2VOb2RlICpwVGFibGVSZWYsIDo6cnRsOjpPVVN0cmluZyYgYVRhYmxlUmFuZ2UgKQp7CiAgICBSVExfTE9HRklMRV9DT05URVhUX0FVVEhPUiggYUxvZ2dlciwgInBhcnNlIiwgIk9ja2UuSmFuc3NlbkBzdW4uY29tIiwgIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6Z2V0UXVhbGlmaWVkX2pvaW4iICk7CiAgICBPU0xfUFJFQ09ORCggU1FMX0lTUlVMRSggcFRhYmxlUmVmLCBjcm9zc191bmlvbiApIHx8IFNRTF9JU1JVTEUoIHBUYWJsZVJlZiwgcXVhbGlmaWVkX2pvaW4gKSAsCiAgICAgICAgIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6Z2V0UXVhbGlmaWVkX2pvaW46IGlsbGVnYWwgbm9kZSEiICk7CgoJYVRhYmxlUmFuZ2UgPSA6OnJ0bDo6T1VTdHJpbmcoKTsKCgljb25zdCBPU1FMUGFyc2VOb2RlKiBwTm9kZSA9IGdldFRhYmxlTm9kZShfclRhYmxlcyxwVGFibGVSZWYtPmdldENoaWxkKDApLGFUYWJsZVJhbmdlKTsKCWlmICggaXNUYWJsZU5vZGUoIHBOb2RlICkgKQoJCXRyYXZlcnNlT25lVGFibGVOYW1lKCBfclRhYmxlcywgcE5vZGUsIGFUYWJsZVJhbmdlICk7CgoJc2FsX3VJbnQzMiBuUG9zID0gNDsKCWlmKCBTUUxfSVNSVUxFKHBUYWJsZVJlZixjcm9zc191bmlvbikgfHwgcFRhYmxlUmVmLT5nZXRDaGlsZCgxKS0+Z2V0VG9rZW5JRCgpICE9IFNRTF9UT0tFTl9OQVRVUkFMKQogICAgewogICAgICAgIG5Qb3MgPSAzOwogICAgICAgIC8vIGpvaW5fY29uZGl0aW9uLG5hbWVkX2NvbHVtbnNfam9pbgogICAgICAgIGlmICggU1FMX0lTUlVMRSggcFRhYmxlUmVmLCBxdWFsaWZpZWRfam9pbiApICkKICAgICAgICB7CiAgICAgICAgICAgIGNvbnN0IE9TUUxQYXJzZU5vZGUqIHBKb2luX3NwZWMgPSBwVGFibGVSZWYtPmdldENoaWxkKDQpOwogICAgICAgICAgICBpZiAoIFNRTF9JU1JVTEUoIHBKb2luX3NwZWMsIGpvaW5fY29uZGl0aW9uICkgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpbXBsX2ZpbGxKb2luQ29uZGl0aW9ucyhwSm9pbl9zcGVjLT5nZXRDaGlsZCgxKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjb25zdCBPU1FMUGFyc2VOb2RlKiBwQ29sdW1uQ29tbWFsaXN0ID0gcEpvaW5fc3BlYy0+Z2V0Q2hpbGQoMik7CiAgICAgICAgICAgICAgICAvLyBBbGxlIENvbHVtbnMgaW4gZGVyIGNvbHVtbl9jb21tYWxpc3QgLi4uCgkJCSAgICBmb3IgKHNhbF91SW50MzIgaSA9IDA7IGkgPCBwQ29sdW1uQ29tbWFsaXN0LT5jb3VudCgpOyBpKyspCgkJCSAgICB7CgkJCQkgICAgY29uc3QgT1NRTFBhcnNlTm9kZSAqIHBDb2wgPSBwQ29sdW1uQ29tbWFsaXN0LT5nZXRDaGlsZChpKTsKICAgICAgICAgICAgICAgICAgICAvLyBhZGQgdHdpY2UgYmVjYXVzZSB0aGUgY29sdW1uIG11c3QgZXhpc3RzIGluIGJvdGggdGFibGVzCiAgICAgICAgICAgICAgICAgICAgbV9wSW1wbC0+bV9hSm9pbkNvbmRpdGlvbnMucHVzaF9iYWNrKCBUTm9kZVBhaXIocENvbCxwQ29sKSApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKCXBOb2RlID0gZ2V0VGFibGVOb2RlKF9yVGFibGVzLHBUYWJsZVJlZi0+Z2V0Q2hpbGQoblBvcyksYVRhYmxlUmFuZ2UpOwoJaWYgKCBpc1RhYmxlTm9kZSggcE5vZGUgKSApCgkJdHJhdmVyc2VPbmVUYWJsZU5hbWUoIF9yVGFibGVzLCBwTm9kZSwgYVRhYmxlUmFuZ2UgKTsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCmNvbnN0IE9TUUxQYXJzZU5vZGUqIE9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6Z2V0VGFibGVOb2RlKCBPU1FMVGFibGVzJiBfclRhYmxlcywgY29uc3QgT1NRTFBhcnNlTm9kZSAqcFRhYmxlUmVmLDo6cnRsOjpPVVN0cmluZyYgclRhYmxlUmFuZ2UgKQp7CiAgICBSVExfTE9HRklMRV9DT05URVhUX0FVVEhPUiggYUxvZ2dlciwgInBhcnNlIiwgIk9ja2UuSmFuc3NlbkBzdW4uY29tIiwgIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6Z2V0VGFibGVOb2RlIiApOwogICAgT1NMX1BSRUNPTkQoIFNRTF9JU1JVTEUoIHBUYWJsZVJlZiwgdGFibGVfcmVmICkgfHwgU1FMX0lTUlVMRSggcFRhYmxlUmVmLCBqb2luZWRfdGFibGUgKQogICAgICAgICAgICAgIHx8IFNRTF9JU1JVTEUoIHBUYWJsZVJlZiwgcXVhbGlmaWVkX2pvaW4gKSB8fCBTUUxfSVNSVUxFKCBwVGFibGVSZWYsIGNyb3NzX3VuaW9uICksCiAgICAgICAgIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6Z2V0VGFibGVOb2RlOiBvbmx5IHRvIGJlIGNhbGxlZCBmb3IgdGFibGVfcmVmIG5vZGVzISIgKTsKCQoJY29uc3QgT1NRTFBhcnNlTm9kZSogcFRhYmxlTmFtZU5vZGUgPSBOVUxMOwoKICAgIGlmICggU1FMX0lTUlVMRSggcFRhYmxlUmVmLCBqb2luZWRfdGFibGUgKSApCiAgICB7CiAgICAgICAgZ2V0UXVhbGlmaWVkX2pvaW4oIF9yVGFibGVzLCBwVGFibGVSZWYtPmdldENoaWxkKDEpLCByVGFibGVSYW5nZSApOwogICAgfQogICAgaWYgKCBTUUxfSVNSVUxFKCBwVGFibGVSZWYsIHF1YWxpZmllZF9qb2luICkgfHwgU1FMX0lTUlVMRSggcFRhYmxlUmVmLCBjcm9zc191bmlvbiApICkKICAgIHsKICAgICAgICBnZXRRdWFsaWZpZWRfam9pbiggX3JUYWJsZXMsIHBUYWJsZVJlZiwgclRhYmxlUmFuZ2UgKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICByVGFibGVSYW5nZSA9IE9TUUxQYXJzZU5vZGU6OmdldFRhYmxlUmFuZ2UocFRhYmxlUmVmKTsKICAgICAgICBpZiAgKCAgICggcFRhYmxlUmVmLT5jb3VudCgpID09IDQgKSAvLyAneycgU1FMX1RPS0VOX09KIGpvaW5lZF90YWJsZSAnfScKICAgICAgICAgICAgfHwgICggcFRhYmxlUmVmLT5jb3VudCgpID09IDUgKSAvLyAnKCcgam9pbmVkX3RhYmxlICcpJyByYW5nZV92YXJpYWJsZSBvcF9jb2x1bW5fY29tbWFsaXN0CiAgICAgICAgICAgICkKICAgICAgICB7CiAgICAgICAgICAgIGdldFF1YWxpZmllZF9qb2luKCBfclRhYmxlcywgcFRhYmxlUmVmLT5nZXRDaGlsZCg2IC0gcFRhYmxlUmVmLT5jb3VudCgpKSwgclRhYmxlUmFuZ2UgKTsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAoIHBUYWJsZVJlZi0+Y291bnQoKSA9PSAzICkgLy8gc3VicXVlcnkgcmFuZ2VfdmFyaWFibGUgb3BfY29sdW1uX2NvbW1hbGlzdCB8fCAnKCcgam9pbmVkX3RhYmxlICcpJwogICAgICAgIHsKICAgICAgICAgICAgY29uc3QgT1NRTFBhcnNlTm9kZSogcFN1YlF1ZXJ5ID0gcFRhYmxlUmVmLT5nZXRDaGlsZCgwKTsKICAgICAgICAgICAgaWYgKCBwU3ViUXVlcnktPmlzVG9rZW4oKSApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGdldFF1YWxpZmllZF9qb2luKCBfclRhYmxlcywgcFRhYmxlUmVmLT5nZXRDaGlsZCgxKSwgclRhYmxlUmFuZ2UgKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIE9TTF9FTlNVUkUoIHBTdWJRdWVyeS0+Y291bnQoKSA9PSAzLCAic3ViIHF1ZXJpZXMgc2hvdWxkIGhhdmUgMyBjaGlsZHJlbiEiICk7CiAgICAgICAgICAgICAgICBjb25zdCBPU1FMUGFyc2VOb2RlKiBwUXVlcnlFeHByZXNzaW9uID0gcFN1YlF1ZXJ5LT5nZXRDaGlsZCgxKTsKICAgICAgICAgICAgICAgIGlmICggU1FMX0lTUlVMRSggcFF1ZXJ5RXhwcmVzc2lvbiwgc2VsZWN0X3N0YXRlbWVudCApICkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBnZXRTZWxlY3Rfc3RhdGVtZW50KCAqbV9wSW1wbC0+bV9wU3ViVGFibGVzLCBwUXVlcnlFeHByZXNzaW9uICk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgT1NMX0VOU1VSRSggZmFsc2UsICJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OmdldFRhYmxlTm9kZTogc3VicXVlcnkgd2hpY2ggaXMgbm8gc2VsZWN0X3N0YXRlbWVudDogbm90IHlldCBpbXBsZW1lbnRlZCEiICk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAoIHBUYWJsZVJlZi0+Y291bnQoKSA9PSAyICkgLy8gdGFibGVfbm9kZSB0YWJsZV9wcmltYXJ5X2FzX3JhbmdlX2NvbHVtbgogICAgICAgIHsKICAgICAgICAgICAgcFRhYmxlTmFtZU5vZGUgPSBwVGFibGVSZWYtPmdldENoaWxkKDApOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgICAgIE9TTF9FTlNVUkUoIGZhbHNlLCAiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjpnZXRUYWJsZU5vZGU6IHVuaGFuZGxlZCBjYXNlISIgKTsKICAgIH0KCglyZXR1cm4gcFRhYmxlTmFtZU5vZGU7Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIE9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6Z2V0U2VsZWN0X3N0YXRlbWVudChPU1FMVGFibGVzJiBfclRhYmxlcyxjb25zdCBPU1FMUGFyc2VOb2RlKiBwU2VsZWN0KQp7CiAgICBSVExfTE9HRklMRV9DT05URVhUX0FVVEhPUiggYUxvZ2dlciwgInBhcnNlIiwgIk9ja2UuSmFuc3NlbkBzdW4uY29tIiwgIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6Z2V0U2VsZWN0X3N0YXRlbWVudCIgKTsKCWlmKFNRTF9JU1JVTEUocFNlbGVjdCx1bmlvbl9zdGF0ZW1lbnQpKQoJewoJCWdldFNlbGVjdF9zdGF0ZW1lbnQoX3JUYWJsZXMscFNlbGVjdC0+Z2V0Q2hpbGQoMCkpOwoJCS8vZ2V0U2VsZWN0X3N0YXRlbWVudChwU2VsZWN0LT5nZXRDaGlsZCgzKSk7CgkJcmV0dXJuOwoJfQoJT1NRTFBhcnNlTm9kZSAqIHBUYWJsZVJlZkNvbW1hbGlzdCA9IHBTZWxlY3QtPmdldENoaWxkKDMpLT5nZXRDaGlsZCgwKS0+Z2V0Q2hpbGQoMSk7CgoJT1NMX0VOU1VSRShwVGFibGVSZWZDb21tYWxpc3QgIT0gTlVMTCwiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOiBlcnJvciBpbiBwYXJzZSB0cmVlISIpOwoJT1NMX0VOU1VSRShTUUxfSVNSVUxFKHBUYWJsZVJlZkNvbW1hbGlzdCx0YWJsZV9yZWZfY29tbWFsaXN0KSwiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOiBlcnJvciBpbiBwYXJzZSB0cmVlISIpOwoKCWNvbnN0IE9TUUxQYXJzZU5vZGUqIHBUYWJsZU5hbWUgPSBOVUxMOwoJOjpydGw6Ok9VU3RyaW5nIGFUYWJsZVJhbmdlOwoJZm9yIChzYWxfdUludDMyIGkgPSAwOyBpIDwgcFRhYmxlUmVmQ29tbWFsaXN0LT5jb3VudCgpOyBpKyspCgl7IC8vIGZyb20gY2xhdXNlIGR1cmNobGF1ZmVuCgkJYVRhYmxlUmFuZ2UgPSA6OnJ0bDo6T1VTdHJpbmcoKTsKCiAgICAgICAgY29uc3QgT1NRTFBhcnNlTm9kZSogcFRhYmxlTGlzdEVsZW1lbnQgPSBwVGFibGVSZWZDb21tYWxpc3QtPmdldENoaWxkKGkpOwoJCWlmICggaXNUYWJsZU5vZGUoIHBUYWJsZUxpc3RFbGVtZW50ICkgKQoJCXsKCQkJdHJhdmVyc2VPbmVUYWJsZU5hbWUoIF9yVGFibGVzLCBwVGFibGVMaXN0RWxlbWVudCwgYVRhYmxlUmFuZ2UgKTsKCQl9CgkJZWxzZSBpZiAoIFNRTF9JU1JVTEUoIHBUYWJsZUxpc3RFbGVtZW50LCB0YWJsZV9yZWYgKSApCgkJewoJCQkvLyBUYWJlbGxlbnJlZmVyZW56IGthbm4gYXVzIFRhYmVsbGVubmFtZW4sIFRhYmVsbGVubmFtZW4gKCspLCcoJ2pvaW5lZF90YWJsZScpJygrKSBiZXN0ZWhlbgoJCQlwVGFibGVOYW1lID0gcFRhYmxlTGlzdEVsZW1lbnQtPmdldENoaWxkKDApOwoJCQlpZiggaXNUYWJsZU5vZGUoIHBUYWJsZU5hbWUgKSApCgkJCXsJLy8gVGFiZWxsZW5uYW1lbiBnZWZ1bmRlbgogICAgICAgICAgICAgICAgYVRhYmxlUmFuZ2UgPSBPU1FMUGFyc2VOb2RlOjpnZXRUYWJsZVJhbmdlKHBUYWJsZUxpc3RFbGVtZW50KTsKCQkJCXRyYXZlcnNlT25lVGFibGVOYW1lKCBfclRhYmxlcywgcFRhYmxlTmFtZSwgYVRhYmxlUmFuZ2UgKTsKCQkJfQoJCQllbHNlIGlmKFNRTF9JU1BVTkNUVUFUSU9OKHBUYWJsZU5hbWUsInsiKSkKICAgICAgICAgICAgeyAgIC8vICd7JyBTUUxfVE9LRU5fT0ogam9pbmVkX3RhYmxlICd9JwogICAgICAgICAgICAgICAgZ2V0UXVhbGlmaWVkX2pvaW4oIF9yVGFibGVzLCBwVGFibGVMaXN0RWxlbWVudC0+Z2V0Q2hpbGQoMiksIGFUYWJsZVJhbmdlICk7CiAgICAgICAgICAgIH0KCQkJZWxzZQogICAgICAgICAgICB7ICAgLy8gJygnIGpvaW5lZF90YWJsZSAnKScgcmFuZ2VfdmFyaWFibGUgb3BfY29sdW1uX2NvbW1hbGlzdAoJCQkJZ2V0VGFibGVOb2RlKCBfclRhYmxlcywgcFRhYmxlTGlzdEVsZW1lbnQsIGFUYWJsZVJhbmdlICk7CiAgICAgICAgICAgIH0KCQl9CgkJZWxzZSBpZiAoU1FMX0lTUlVMRSggcFRhYmxlTGlzdEVsZW1lbnQsIHF1YWxpZmllZF9qb2luICkgfHwgU1FMX0lTUlVMRSggcFRhYmxlTGlzdEVsZW1lbnQsIGNyb3NzX3VuaW9uICkgKQoJCXsKCQkJZ2V0UXVhbGlmaWVkX2pvaW4oIF9yVGFibGVzLCBwVGFibGVMaXN0RWxlbWVudCwgYVRhYmxlUmFuZ2UgKTsKCQl9CiAgICAgICAgZWxzZSBpZiAoIFNRTF9JU1JVTEUoIHBUYWJsZUxpc3RFbGVtZW50LCBqb2luZWRfdGFibGUgKSApCiAgICAgICAgewogICAgICAgICAgICBnZXRRdWFsaWZpZWRfam9pbiggX3JUYWJsZXMsIHBUYWJsZUxpc3RFbGVtZW50LT5nZXRDaGlsZCgxKSwgYVRhYmxlUmFuZ2UgKTsKICAgICAgICB9CgoJCS8vCWlmICghIGFJdGVyYXRvclN0YXR1cy5Jc1N1Y2Nlc3NmdWwoKSkgYnJlYWs7Cgl9Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpib29sIE9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6dHJhdmVyc2VUYWJsZU5hbWVzKE9TUUxUYWJsZXMmIF9yVGFibGVzKQp7CiAgICBSVExfTE9HRklMRV9DT05URVhUX0FVVEhPUiggYUxvZ2dlciwgInBhcnNlIiwgIk9ja2UuSmFuc3NlbkBzdW4uY29tIiwgIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6dHJhdmVyc2VUYWJsZU5hbWVzIiApOwoJaWYgKCBtX3BQYXJzZVRyZWUgPT0gTlVMTCApCgkJcmV0dXJuIGZhbHNlOwoKCU9TUUxQYXJzZU5vZGUqIHBUYWJsZU5hbWUgPSBOVUxMOwoKICAgIHN3aXRjaCAoIG1fZVN0YXRlbWVudFR5cGUgKQogICAgewogICAgICAgIGNhc2UgU1FMX1NUQVRFTUVOVF9TRUxFQ1Q6CgkJICAgIGdldFNlbGVjdF9zdGF0ZW1lbnQoIF9yVGFibGVzLCBtX3BQYXJzZVRyZWUgKTsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgU1FMX1NUQVRFTUVOVF9DUkVBVEVfVEFCTEU6CiAgICAgICAgY2FzZSBTUUxfU1RBVEVNRU5UX0lOU0VSVDoKICAgICAgICBjYXNlIFNRTF9TVEFURU1FTlRfREVMRVRFOgoJCSAgICBwVGFibGVOYW1lID0gbV9wUGFyc2VUcmVlLT5nZXRDaGlsZCgyKTsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgU1FMX1NUQVRFTUVOVF9VUERBVEU6CgkJICAgIHBUYWJsZU5hbWUgPSBtX3BQYXJzZVRyZWUtPmdldENoaWxkKDEpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBicmVhazsKICAgIH0KCiAgICBpZiAoIHBUYWJsZU5hbWUgKQogICAgewogICAgICAgIDo6cnRsOjpPVVN0cmluZyBzVGFibGVSYW5nZTsKCSAgICB0cmF2ZXJzZU9uZVRhYmxlTmFtZSggX3JUYWJsZXMsIHBUYWJsZU5hbWUsIHNUYWJsZVJhbmdlICk7CiAgICB9CgogICAgcmV0dXJuICFoYXNFcnJvcnMoKTsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCjo6cnRsOjpPVVN0cmluZyBPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OmdldENvbHVtbkFsaWFzKGNvbnN0IE9TUUxQYXJzZU5vZGUqIF9wRGVyaXZlZENvbHVtbikKewogICAgUlRMX0xPR0ZJTEVfQ09OVEVYVF9BVVRIT1IoIGFMb2dnZXIsICJwYXJzZSIsICJPY2tlLkphbnNzZW5Ac3VuLmNvbSIsICJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OmdldENvbHVtbkFsaWFzIiApOwoJT1NMX0VOU1VSRShTUUxfSVNSVUxFKF9wRGVyaXZlZENvbHVtbixkZXJpdmVkX2NvbHVtbiksIk5vIGRlcml2ZWQgY29sdW1uISIpOwoJOjpydGw6Ok9VU3RyaW5nIHNDb2x1bW5BbGlhczsKCWlmKF9wRGVyaXZlZENvbHVtbi0+Z2V0Q2hpbGQoMSktPmNvdW50KCkgPT0gMikKCQlzQ29sdW1uQWxpYXMgPSBfcERlcml2ZWRDb2x1bW4tPmdldENoaWxkKDEpLT5nZXRDaGlsZCgxKS0+Z2V0VG9rZW5WYWx1ZSgpOwoJZWxzZSBpZighX3BEZXJpdmVkQ29sdW1uLT5nZXRDaGlsZCgxKS0+aXNSdWxlKCkpCgkJc0NvbHVtbkFsaWFzID0gX3BEZXJpdmVkQ29sdW1uLT5nZXRDaGlsZCgxKS0+Z2V0VG9rZW5WYWx1ZSgpOwoJcmV0dXJuIHNDb2x1bW5BbGlhczsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KbmFtZXNwYWNlCnsKICAgIHZvaWQgbGNsX2dldENvbHVtblJhbmdlKCBjb25zdCBPU1FMUGFyc2VOb2RlKiBfcENvbHVtblJlZiwgY29uc3QgUmVmZXJlbmNlPCBYQ29ubmVjdGlvbiA+JiBfcnhDb25uZWN0aW9uLAogICAgICAgIDo6cnRsOjpPVVN0cmluZyYgX291dF9yQ29sdW1uTmFtZSwgOjpydGw6Ok9VU3RyaW5nJiBfb3V0X3JUYWJsZVJhbmdlLAogICAgICAgIGNvbnN0IE9TUUxDb2x1bW5zKiBfcFNlbGVjdENvbHVtbnMsIDo6cnRsOjpPVVN0cmluZyYgX291dF9yQ29sdW1uQWxpYXNJZlByZXNlbnQgKQogICAgewoJICAgIF9vdXRfckNvbHVtbk5hbWUgPSBfb3V0X3JUYWJsZVJhbmdlID0gX291dF9yQ29sdW1uQWxpYXNJZlByZXNlbnQgPSA6OnJ0bDo6T1VTdHJpbmcoKTsKCSAgICBpZiAoIFNRTF9JU1JVTEUoIF9wQ29sdW1uUmVmLCBjb2x1bW5fcmVmICkgKQoJICAgIHsKCQkgICAgaWYoIF9wQ29sdW1uUmVmLT5jb3VudCgpID4gMSApCgkJICAgIHsKCQkJICAgIGZvciAoIHNhbF9JbnQzMiBpPTA7IGk8KChzYWxfSW50MzIpX3BDb2x1bW5SZWYtPmNvdW50KCkpLTI7ICsraSApCgkJCQkgICAgX3BDb2x1bW5SZWYtPmdldENoaWxkKGkpLT5wYXJzZU5vZGVUb1N0ciggX291dF9yVGFibGVSYW5nZSwgX3J4Q29ubmVjdGlvbiwgTlVMTCwgc2FsX0ZhbHNlLCBzYWxfRmFsc2UgKTsKICAgICAgICAgICAgICAgIF9vdXRfckNvbHVtbk5hbWUgPSBfcENvbHVtblJlZi0+Z2V0Q2hpbGQoIF9wQ29sdW1uUmVmLT5jb3VudCgpLTEgKS0+Z2V0Q2hpbGQoMCktPmdldFRva2VuVmFsdWUoKTsKCQkgICAgfQoJCSAgICBlbHNlCgkJCSAgICBfb3V0X3JDb2x1bW5OYW1lID0gX3BDb2x1bW5SZWYtPmdldENoaWxkKDApLT5nZXRUb2tlblZhbHVlKCk7CgogICAgICAgICAgICAvLyBsb29rIHVwIHRoZSBjb2x1bW4gaW4gdGhlIHNlbGVjdCBjb2x1bW4sIHRvIGZpbmQgYW4gcG9zc2libGUgYWxpYXMKICAgICAgICAgICAgaWYgKCBfcFNlbGVjdENvbHVtbnMgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBmb3IgKCAgIE9TUUxDb2x1bW5zOjpWZWN0b3I6OmNvbnN0X2l0ZXJhdG9yIGxvb2t1cENvbHVtbiA9IF9wU2VsZWN0Q29sdW1ucy0+Z2V0KCkuYmVnaW4oKTsKICAgICAgICAgICAgICAgICAgICAgICAgbG9va3VwQ29sdW1uICE9IF9wU2VsZWN0Q29sdW1ucy0+Z2V0KCkuZW5kKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICsrbG9va3VwQ29sdW1uCiAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFJlZmVyZW5jZTwgWFByb3BlcnR5U2V0ID4geENvbHVtbiggKmxvb2t1cENvbHVtbiApOwogICAgICAgICAgICAgICAgICAgIHRyeQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgOjpydGw6Ok9VU3RyaW5nIHNOYW1lLCBzVGFibGVOYW1lOwogICAgICAgICAgICAgICAgICAgICAgICB4Q29sdW1uLT5nZXRQcm9wZXJ0eVZhbHVlKCBPTWV0YUNvbm5lY3Rpb246OmdldFByb3BNYXAoKS5nZXROYW1lQnlJbmRleCggUFJPUEVSVFlfSURfUkVBTE5BTUUgKSApID4+PSBzTmFtZTsKICAgICAgICAgICAgICAgICAgICAgICAgeENvbHVtbi0+Z2V0UHJvcGVydHlWYWx1ZSggT01ldGFDb25uZWN0aW9uOjpnZXRQcm9wTWFwKCkuZ2V0TmFtZUJ5SW5kZXgoIFBST1BFUlRZX0lEX1RBQkxFTkFNRSApICkgPj49IHNUYWJsZU5hbWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICggc05hbWUgPT0gX291dF9yQ29sdW1uTmFtZSAmJiBzVGFibGVOYW1lID09IF9vdXRfclRhYmxlUmFuZ2UgKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgeENvbHVtbi0+Z2V0UHJvcGVydHlWYWx1ZSggT01ldGFDb25uZWN0aW9uOjpnZXRQcm9wTWFwKCkuZ2V0TmFtZUJ5SW5kZXgoIFBST1BFUlRZX0lEX05BTUUgKSApID4+PSBfb3V0X3JDb2x1bW5BbGlhc0lmUHJlc2VudDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgY2F0Y2goIGNvbnN0IEV4Y2VwdGlvbiYgKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgCSAgICAgICAgREJHX1VOSEFORExFRF9FWENFUFRJT04oKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCSAgICB9CgkgICAgZWxzZSBpZihTUUxfSVNSVUxFKF9wQ29sdW1uUmVmLGdlbmVyYWxfc2V0X2ZjdCkgfHwgU1FMX0lTUlVMRShfcENvbHVtblJlZixzZXRfZmN0X3NwZWMpKQoJICAgIHsgLy8gRnVua3Rpb24KCQkgICAgX3BDb2x1bW5SZWYtPnBhcnNlTm9kZVRvU3RyKCBfb3V0X3JDb2x1bW5OYW1lLCBfcnhDb25uZWN0aW9uICk7CgkgICAgfQoJICAgIGVsc2UgIGlmKF9wQ29sdW1uUmVmLT5nZXROb2RlVHlwZSgpID09IFNRTF9OT0RFX05BTUUpCgkJICAgIF9vdXRfckNvbHVtbk5hbWUgPSBfcENvbHVtblJlZi0+Z2V0VG9rZW5WYWx1ZSgpOwogICAgfQp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIE9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6Z2V0Q29sdW1uUmFuZ2UoCWNvbnN0IE9TUUxQYXJzZU5vZGUqIF9wQ29sdW1uUmVmLAoJCQkJCQk6OnJ0bDo6T1VTdHJpbmcmIF9yQ29sdW1uTmFtZSwKCQkJCQkJOjpydGw6Ok9VU3RyaW5nJiBfclRhYmxlUmFuZ2UpIGNvbnN0CnsKICAgIFJUTF9MT0dGSUxFX0NPTlRFWFRfQVVUSE9SKCBhTG9nZ2VyLCAicGFyc2UiLCAiT2NrZS5KYW5zc2VuQHN1bi5jb20iLCAiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjpnZXRDb2x1bW5SYW5nZSIgKTsKICAgIDo6cnRsOjpPVVN0cmluZyBzRHVtbXk7CglsY2xfZ2V0Q29sdW1uUmFuZ2UoCV9wQ29sdW1uUmVmLCBtX3BJbXBsLT5tX3hDb25uZWN0aW9uLCBfckNvbHVtbk5hbWUsIF9yVGFibGVSYW5nZSwgTlVMTCwgc0R1bW15ICk7Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjpnZXRDb2x1bW5SYW5nZSgJY29uc3QgT1NRTFBhcnNlTm9kZSogX3BDb2x1bW5SZWYsCgkJCQkJCTo6cnRsOjpPVVN0cmluZyYgX3JDb2x1bW5OYW1lLAoJCQkJCQk6OnJ0bDo6T1VTdHJpbmcmIF9yVGFibGVSYW5nZSwKICAgICAgICAgICAgICAgICAgICAgICAgOjpydGw6Ok9VU3RyaW5nJiBfb3V0X3JDb2x1bW5BbGlhc0lmUHJlc2VudCApIGNvbnN0CnsKICAgIFJUTF9MT0dGSUxFX0NPTlRFWFRfQVVUSE9SKCBhTG9nZ2VyLCAicGFyc2UiLCAiT2NrZS5KYW5zc2VuQHN1bi5jb20iLCAiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjpnZXRDb2x1bW5SYW5nZSIgKTsKCWxjbF9nZXRDb2x1bW5SYW5nZSgJX3BDb2x1bW5SZWYsIG1fcEltcGwtPm1feENvbm5lY3Rpb24sIF9yQ29sdW1uTmFtZSwgX3JUYWJsZVJhbmdlLCAmKm1fYVNlbGVjdENvbHVtbnMsIF9vdXRfckNvbHVtbkFsaWFzSWZQcmVzZW50ICk7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OmdldENvbHVtblJhbmdlKCBjb25zdCBPU1FMUGFyc2VOb2RlKiBfcENvbHVtblJlZiwKICAgIGNvbnN0IFJlZmVyZW5jZTwgWENvbm5lY3Rpb24gPiYgX3J4Q29ubmVjdGlvbiwgOjpydGw6Ok9VU3RyaW5nJiBfb3V0X3JDb2x1bW5OYW1lLCA6OnJ0bDo6T1VTdHJpbmcmIF9vdXRfclRhYmxlUmFuZ2UgKQp7CiAgICBSVExfTE9HRklMRV9DT05URVhUX0FVVEhPUiggYUxvZ2dlciwgInBhcnNlIiwgIk9ja2UuSmFuc3NlbkBzdW4uY29tIiwgIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6Z2V0Q29sdW1uUmFuZ2UiICk7CiAgICA6OnJ0bDo6T1VTdHJpbmcgc0R1bW15OwogICAgbGNsX2dldENvbHVtblJhbmdlKCBfcENvbHVtblJlZiwgX3J4Q29ubmVjdGlvbiwgX291dF9yQ29sdW1uTmFtZSwgX291dF9yVGFibGVSYW5nZSwgTlVMTCwgc0R1bW15ICk7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kc2FsX0Jvb2wgT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjpnZXRDb2x1bW5UYWJsZVJhbmdlKGNvbnN0IE9TUUxQYXJzZU5vZGUqIHBOb2RlLCA6OnJ0bDo6T1VTdHJpbmcgJnJUYWJsZVJhbmdlKSBjb25zdAp7CiAgICBSVExfTE9HRklMRV9DT05URVhUX0FVVEhPUiggYUxvZ2dlciwgInBhcnNlIiwgIk9ja2UuSmFuc3NlbkBzdW4uY29tIiwgIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6Z2V0Q29sdW1uVGFibGVSYW5nZSIgKTsKCS8vIEVybWl0dGVsbiBvYiBhbGxlIFNwYWx0ZW4genUgZWluZXIgVGFiZWxsZSBnZWhvZXJlbgoJaWYgKFNRTF9JU1JVTEUocE5vZGUsY29sdW1uX3JlZikpCgl7CgkJOjpydGw6Ok9VU3RyaW5nIGFDb2xOYW1lLCBhVGFibGVSYW5nZTsKCQlnZXRDb2x1bW5SYW5nZShwTm9kZSwgYUNvbE5hbWUsIGFUYWJsZVJhbmdlKTsKCQlpZiAoIWFUYWJsZVJhbmdlLmdldExlbmd0aCgpKQkvLyBrZWluZW4gZ2VmdW5kZW4KCQl7CgkJCS8vIGRhbm4gZGllIFNwYWx0ZSBpbiBkZW4gVGFiZWxsZW4gc3VjaGVuCgkJCWZvciAoQ29uc3RPU1FMVGFibGVzSXRlcmF0b3IgYUl0ZXIgPSBtX3BJbXBsLT5tX3BUYWJsZXMtPmJlZ2luKCk7IGFJdGVyICE9IG1fcEltcGwtPm1fcFRhYmxlcy0+ZW5kKCk7ICsrYUl0ZXIpCgkJCXsKCQkJCWlmIChhSXRlci0+c2Vjb25kLmlzKCkpCgkJCQl7CgkJCQkJdHJ5CgkJCQkJewoJCQkJCQlSZWZlcmVuY2U8IFhOYW1lQWNjZXNzID4geENvbHVtbnMgPSBhSXRlci0+c2Vjb25kLT5nZXRDb2x1bW5zKCk7CgkJCQkJCWlmKHhDb2x1bW5zLT5oYXNCeU5hbWUoYUNvbE5hbWUpKQoJCQkJCQl7CgkJCQkJCQlSZWZlcmVuY2U8IFhQcm9wZXJ0eVNldCA+IHhDb2x1bW47CgkJCQkJCQlpZiAoeENvbHVtbnMtPmdldEJ5TmFtZShhQ29sTmFtZSkgPj49IHhDb2x1bW4pCgkJCQkJCQl7CgkJCQkJCQkJT1NMX0VOU1VSRSh4Q29sdW1uLmlzKCksIkNvbHVtbiBpc24ndCBhIHByb3BlcnR5c2V0ISIpOwoJCQkJCQkJCWFUYWJsZVJhbmdlID0gYUl0ZXItPmZpcnN0OwoJCQkJCQkJCWJyZWFrOwoJCQkJCQkJfQoJCQkJCQl9CgkJCQkJfQoJCQkJCWNhdGNoKEV4Y2VwdGlvbiYpCgkJCQkJewoJCQkJCX0KCQkJCX0KCQkJfQoJCQlpZiAoIWFUYWJsZVJhbmdlLmdldExlbmd0aCgpKQoJCQkJcmV0dXJuIHNhbF9GYWxzZTsKCQl9CgoKCQlpZiAoIXJUYWJsZVJhbmdlLmdldExlbmd0aCgpKQoJCQlyVGFibGVSYW5nZSA9IGFUYWJsZVJhbmdlOwoJCWVsc2UgaWYgKHJUYWJsZVJhbmdlICE9IGFUYWJsZVJhbmdlKQoJCQlyZXR1cm4gc2FsX0ZhbHNlOwoJfQoJZWxzZQoJewoJCWZvciAoc2FsX3VJbnQzMiBpID0gMCwgbmNvdW50ID0gcE5vZGUtPmNvdW50KCk7IGkgPCBuY291bnQ7IGkrKykKCQl7CgkJCWlmICghZ2V0Q29sdW1uVGFibGVSYW5nZShwTm9kZS0+Z2V0Q2hpbGQoaSksIHJUYWJsZVJhbmdlKSkKCQkJCXJldHVybiBzYWxfRmFsc2U7CgkJfQoJfQoJcmV0dXJuIHNhbF9UcnVlOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjp0cmF2ZXJzZUNyZWF0ZUNvbHVtbnMoY29uc3QgT1NRTFBhcnNlTm9kZSogcFNlbGVjdE5vZGUpCnsKICAgIFJUTF9MT0dGSUxFX0NPTlRFWFRfQVVUSE9SKCBhTG9nZ2VyLCAicGFyc2UiLCAiT2NrZS5KYW5zc2VuQHN1bi5jb20iLCAiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjp0cmF2ZXJzZUNyZWF0ZUNvbHVtbnMiICk7CgkvLwlhSXRlcmF0b3JTdGF0dXMuQ2xlYXIoKTsKCglpZiAoIXBTZWxlY3ROb2RlIHx8IG1fZVN0YXRlbWVudFR5cGUgIT0gU1FMX1NUQVRFTUVOVF9DUkVBVEVfVEFCTEUgfHwgbV9wSW1wbC0+bV9wVGFibGVzLT5lbXB0eSgpKQoJewoJCWltcGxfYXBwZW5kRXJyb3IoIElQYXJzZUNvbnRleHQ6OkVSUk9SX0dFTkVSQUwgKTsKCQlyZXR1cm47Cgl9CiAgICBpZiAoIVNRTF9JU1JVTEUocFNlbGVjdE5vZGUsYmFzZV90YWJsZV9lbGVtZW50X2NvbW1hbGlzdCkpCiAgICAgICAgcmV0dXJuIDsKCglmb3IgKHNhbF91SW50MzIgaSA9IDA7IGkgPCBwU2VsZWN0Tm9kZS0+Y291bnQoKTsgaSsrKQoJewoJCU9TUUxQYXJzZU5vZGUgKnBDb2x1bW5SZWYgPSBwU2VsZWN0Tm9kZS0+Z2V0Q2hpbGQoaSk7CgoJCWlmIChTUUxfSVNSVUxFKHBDb2x1bW5SZWYsY29sdW1uX2RlZikpCgkJewoJCQk6OnJ0bDo6T1VTdHJpbmcgYUNvbHVtbk5hbWU7CiAgICAgICAgICAgIDo6cnRsOjpPVVN0cmluZyBhVHlwZU5hbWU7CgkJCTo6cnRsOjpPVVN0cmluZyBhVGFibGVSYW5nZTsKCQkJc2FsX0ludDMyIG5UeXBlID0gRGF0YVR5cGU6OlZBUkNIQVI7CiAgICAgICAgICAgIHNhbF9JbnQzMiBuTGVuICA9IDA7CgkJCWFDb2x1bW5OYW1lID0gcENvbHVtblJlZi0+Z2V0Q2hpbGQoMCktPmdldFRva2VuVmFsdWUoKTsKCQkJCiAgICAgICAgICAgIE9TUUxQYXJzZU5vZGUgKnBEYXRhdHlwZSA9IHBDb2x1bW5SZWYtPmdldENoaWxkKDEpOwogICAgICAgICAgICBpZiAocERhdGF0eXBlICYmIFNRTF9JU1JVTEUocERhdGF0eXBlLGNoYXJhY3Rlcl9zdHJpbmdfdHlwZSkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGNvbnN0IE9TUUxQYXJzZU5vZGUgKnBUeXBlID0gcERhdGF0eXBlLT5nZXRDaGlsZCgwKTsKICAgICAgICAgICAgICAgIGFUeXBlTmFtZSA9IHBUeXBlLT5nZXRUb2tlblZhbHVlKCk7CiAgICAgICAgICAgICAgICBpZiAocERhdGF0eXBlLT5jb3VudCgpID09IDIgJiYgKHBUeXBlLT5nZXRUb2tlbklEKCkgPT0gU1FMX1RPS0VOX0NIQVIgfHwgcFR5cGUtPmdldFRva2VuSUQoKSA9PSBTUUxfVE9LRU5fQ0hBUkFDVEVSICkpCiAgICAgICAgICAgICAgICAgICAgblR5cGUgPSBEYXRhVHlwZTo6Q0hBUjsKCiAgICAgICAgICAgICAgICBjb25zdCBPU1FMUGFyc2VOb2RlICpwUGFyYW1zID0gcERhdGF0eXBlLT5nZXRDaGlsZChwRGF0YXR5cGUtPmNvdW50KCktMSk7CiAgICAgICAgICAgICAgICBpZiAoIHBQYXJhbXMtPmNvdW50KCkgKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIG5MZW4gPSBwUGFyYW1zLT5nZXRDaGlsZCgxKS0+Z2V0VG9rZW5WYWx1ZSgpLnRvSW50MzIoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmKHBEYXRhdHlwZSAmJiBwRGF0YXR5cGUtPmdldE5vZGVUeXBlKCkgPT0gU1FMX05PREVfS0VZV09SRCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgYVR5cGVOYW1lID0gOjpydGw6Ok9VU3RyaW5nOjpjcmVhdGVGcm9tQXNjaWkoIlZBUkNIQVIiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKGFUeXBlTmFtZS5nZXRMZW5ndGgoKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy9UT0RPOkNyZWF0ZSBhIG5ldyBjbGFzcyBmb3IgY3JlYXRlIHN0YXRlbWVudCB0byBoYW5kbGUgZmllbGQgbGVuZ3RoCgkJCSAgICBPUGFyc2VDb2x1bW4qIHBDb2x1bW4gPSBuZXcgT1BhcnNlQ29sdW1uKGFDb2x1bW5OYW1lLGFUeXBlTmFtZSw6OnJ0bDo6T1VTdHJpbmcoKSw6OnJ0bDo6T1VTdHJpbmcoKSwKCQkJCQlDb2x1bW5WYWx1ZTo6TlVMTEFCTEVfVU5LTk9XTiwwLDAsblR5cGUsc2FsX0ZhbHNlLHNhbF9GYWxzZSxpc0Nhc2VTZW5zaXRpdmUoKSk7CgkJCQlwQ29sdW1uLT5zZXRGdW5jdGlvbihzYWxfRmFsc2UpOwoJCQkJcENvbHVtbi0+c2V0UmVhbE5hbWUoYUNvbHVtbk5hbWUpOwoKCQkJCVJlZmVyZW5jZTwgWFByb3BlcnR5U2V0PiB4Q29sID0gcENvbHVtbjsKCQkJCW1fYUNyZWF0ZUNvbHVtbnMtPmdldCgpLnB1c2hfYmFjayh4Q29sKTsKICAgICAgICAgICAgfQoJCX0KCgl9IAp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KYm9vbCBPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OnRyYXZlcnNlU2VsZWN0Q29sdW1uTmFtZXMoY29uc3QgT1NRTFBhcnNlTm9kZSogcFNlbGVjdE5vZGUpCnsKICAgIFJUTF9MT0dGSUxFX0NPTlRFWFRfQVVUSE9SKCBhTG9nZ2VyLCAicGFyc2UiLCAiT2NrZS5KYW5zc2VuQHN1bi5jb20iLCAiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjp0cmF2ZXJzZVNlbGVjdENvbHVtbk5hbWVzIiApOwogICAgaWYgKCAoIG1fcEltcGwtPm1fbkluY2x1ZGVNYXNrICYgU2VsZWN0Q29sdW1ucyApICE9IFNlbGVjdENvbHVtbnMgKQogICAgICAgIHJldHVybiB0cnVlOwoKCWlmICghcFNlbGVjdE5vZGUgfHwgbV9lU3RhdGVtZW50VHlwZSAhPSBTUUxfU1RBVEVNRU5UX1NFTEVDVCB8fCBtX3BJbXBsLT5tX3BUYWJsZXMtPmVtcHR5KCkpCgl7CgkJaW1wbF9hcHBlbmRFcnJvciggSVBhcnNlQ29udGV4dDo6RVJST1JfR0VORVJBTCApOwoJCXJldHVybiBmYWxzZTsKCX0KCglpZihTUUxfSVNSVUxFKHBTZWxlY3ROb2RlLHVuaW9uX3N0YXRlbWVudCkpCgl7CgkJcmV0dXJuICB0cmF2ZXJzZVNlbGVjdENvbHVtbk5hbWVzKCBwU2VsZWN0Tm9kZS0+Z2V0Q2hpbGQoIDAgKSApCiAgICAgICAgICAgIC8qJiYgIHRyYXZlcnNlU2VsZWN0Q29sdW1uTmFtZXMoIHBTZWxlY3ROb2RlLT5nZXRDaGlsZCggMyApICkqLzsKCX0KCiAgICBzdGF0aWMgOjpydGw6Ok9VU3RyaW5nIGFFbXB0eVN0cmluZzsKCS8vIG55aTogbWVociBQcnVlZnVuZyBhdWYga29ycmVrdGUgU3RydWt0dXIhCglpZiAocFNlbGVjdE5vZGUtPmdldENoaWxkKDIpLT5pc1J1bGUoKSAmJiBTUUxfSVNQVU5DVFVBVElPTihwU2VsZWN0Tm9kZS0+Z2V0Q2hpbGQoMiktPmdldENoaWxkKDApLCIqIikpCgl7CgkJLy8gU0VMRUNUICogLi4uCgkJc2V0U2VsZWN0Q29sdW1uTmFtZShtX2FTZWxlY3RDb2x1bW5zLDo6cnRsOjpPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCIqIiksIGFFbXB0eVN0cmluZyxhRW1wdHlTdHJpbmcpOwoJfQoJZWxzZSBpZiAoU1FMX0lTUlVMRShwU2VsZWN0Tm9kZS0+Z2V0Q2hpbGQoMiksc2NhbGFyX2V4cF9jb21tYWxpc3QpKQoJewoJCS8vIFNFTEVDVCBjb2x1bW5bLGNvbHVtbl0gb2RlciBTRUxFQ1QgQ09VTlQoKikgLi4uCgkJT1NRTFBhcnNlTm9kZSAqIHBTZWxlY3Rpb24gPSBwU2VsZWN0Tm9kZS0+Z2V0Q2hpbGQoMik7CgoJCWZvciAoc2FsX3VJbnQzMiBpID0gMDsgaSA8IHBTZWxlY3Rpb24tPmNvdW50KCk7IGkrKykKCQl7CgkJCU9TUUxQYXJzZU5vZGUgKnBDb2x1bW5SZWYgPSBwU2VsZWN0aW9uLT5nZXRDaGlsZChpKTsKCgkJCS8vaWYgKFNRTF9JU1JVTEUocENvbHVtblJlZixzZWxlY3Rfc3VibGlzdCkpCgkJCWlmIChTUUxfSVNSVUxFKHBDb2x1bW5SZWYsZGVyaXZlZF9jb2x1bW4pICYmIAoJCQkJU1FMX0lTUlVMRShwQ29sdW1uUmVmLT5nZXRDaGlsZCgwKSxjb2x1bW5fcmVmKSAmJiAKCQkJCXBDb2x1bW5SZWYtPmdldENoaWxkKDApLT5jb3VudCgpID09IDMgJiYgCgkJCQlTUUxfSVNQVU5DVFVBVElPTihwQ29sdW1uUmVmLT5nZXRDaGlsZCgwKS0+Z2V0Q2hpbGQoMiksIioiKSkKCQkJewoJCQkJLy8gYWxsZSBTcGFsdGVuIGRlciBUYWJlbGxlCgkJCQk6OnJ0bDo6T1VTdHJpbmcgYVRhYmxlUmFuZ2U7CgkJCQlwQ29sdW1uUmVmLT5nZXRDaGlsZCgwKS0+cGFyc2VOb2RlVG9TdHIoIGFUYWJsZVJhbmdlLCBtX3BJbXBsLT5tX3hDb25uZWN0aW9uLCBOVUxMLCBzYWxfRmFsc2UsIHNhbF9GYWxzZSApOwoJCQkJc2V0U2VsZWN0Q29sdW1uTmFtZShtX2FTZWxlY3RDb2x1bW5zLDo6cnRsOjpPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCIqIiksIGFFbXB0eVN0cmluZyxhVGFibGVSYW5nZSk7CgkJCQljb250aW51ZTsKCQkJfQoJCQllbHNlIGlmIChTUUxfSVNSVUxFKHBDb2x1bW5SZWYsZGVyaXZlZF9jb2x1bW4pKQoJCQl7CgkJCQk6OnJ0bDo6T1VTdHJpbmcgYUNvbHVtbkFsaWFzKGdldENvbHVtbkFsaWFzKHBDb2x1bW5SZWYpKTsgLy8ga2FubiBsZWVyIHNlaW4KCQkJCTo6cnRsOjpPVVN0cmluZyBzQ29sdW1uTmFtZTsKCQkJCTo6cnRsOjpPVVN0cmluZyBhVGFibGVSYW5nZTsKCQkJCXNhbF9JbnQzMiBuVHlwZSA9IERhdGFUeXBlOjpWQVJDSEFSOwoJCQkJc2FsX0Jvb2wgYkZrdChzYWxfRmFsc2UpOwoJCQkJcENvbHVtblJlZiA9IHBDb2x1bW5SZWYtPmdldENoaWxkKDApOwoJCQkJaWYgKAkKCQkJCQkJcENvbHVtblJlZi0+Y291bnQoKSA9PSAzICYmCgkJCQkJCVNRTF9JU1BVTkNUVUFUSU9OKHBDb2x1bW5SZWYtPmdldENoaWxkKDApLCIoIikgJiYKCQkJCQkJU1FMX0lTUFVOQ1RVQVRJT04ocENvbHVtblJlZi0+Z2V0Q2hpbGQoMiksIikiKQoJCQkJCSkKCQkJCQlwQ29sdW1uUmVmID0gcENvbHVtblJlZi0+Z2V0Q2hpbGQoMSk7CgoJCQkJaWYgKFNRTF9JU1JVTEUocENvbHVtblJlZixjb2x1bW5fcmVmKSkKCQkJCXsKCQkJCQlnZXRDb2x1bW5SYW5nZShwQ29sdW1uUmVmLHNDb2x1bW5OYW1lLGFUYWJsZVJhbmdlKTsKCQkJCQlPU0xfRU5TVVJFKHNDb2x1bW5OYW1lLmdldExlbmd0aCgpLCJDb2x1bW5uYW1lIGRhcmYgbmljaHQgbGVlciBzZWluIik7CgkJCQl9CgkJCQllbHNlIC8qaWYgKFNRTF9JU1JVTEUocENvbHVtblJlZixnZW5lcmFsX3NldF9mY3QpIHx8IFNRTF9JU1JVTEUocENvbHVtblJlZixzZXRfZmN0X3NwZWMpCXx8CgkJCQkJCSBTUUxfSVNSVUxFKHBDb2x1bW5SZWYscG9zaXRpb25fZXhwKQl8fCBTUUxfSVNSVUxFKHBDb2x1bW5SZWYsZXh0cmFjdF9leHApCXx8CgkJCQkJCSBTUUxfSVNSVUxFKHBDb2x1bW5SZWYsbGVuZ3RoX2V4cCkJCXx8IFNRTF9JU1JVTEUocENvbHVtblJlZixjaGFyX3ZhbHVlX2ZjdCl8fAoJCQkJCQkgU1FMX0lTUlVMRShwQ29sdW1uUmVmLG51bV92YWx1ZV9leHApCXx8IFNRTF9JU1JVTEUocENvbHVtblJlZix0ZXJtKSkqLwoJCQkJewoJCQkJCS8qIEZ1bmt0aW9uc2F1ZnJ1ZiB2b3JoYW5kZW4gKi8KCQkJCQlwQ29sdW1uUmVmLT5wYXJzZU5vZGVUb1N0ciggc0NvbHVtbk5hbWUsIG1fcEltcGwtPm1feENvbm5lY3Rpb24sIE5VTEwsIHNhbF9GYWxzZSwgc2FsX1RydWUgKTsKCQkJCQk6OnJ0bDo6T1VTdHJpbmcgc1RhYmxlUmFuZ2U7CgkJCQkJLy8gY2hlY2sgaWYgdGhlIGNvbHVtbiBpcyBhbHNvIGEgcGFyYW1ldGVyCgkJCQkJdHJhdmVyc2VPUkNyaXRlcmlhKHBDb2x1bW5SZWYpOyAvLyBudW1fdmFsdWVfZXhwCQkJCQkKCgkJCQkJLy8gZ2Vob2VyZW4gYWxsZSBiZXRlaWxpZ3RlbiBTcGFsdGVuIGRlciBGdW5rdGlvbiB6dSBlaW5lciBUYWJlbGxlCgkJCQkJaWYgKG1fcEltcGwtPm1fcFRhYmxlcy0+c2l6ZSgpID09IDEpCgkJCQkJewoJCQkJCQlhVGFibGVSYW5nZSA9IG1fcEltcGwtPm1fcFRhYmxlcy0+YmVnaW4oKS0+Zmlyc3Q7CgkJCQkJfQoJCQkJCWVsc2UKCQkJCQl7CgkJCQkJCWdldENvbHVtblRhYmxlUmFuZ2UocENvbHVtblJlZixhVGFibGVSYW5nZSk7CgkJCQkJfQoJCQkJCWlmICggcENvbHVtblJlZi0+aXNSdWxlKCkgKQoJCQkJCXsKCQkJCQkJYkZrdCA9IHNhbF9UcnVlOwoJCQkJCQluVHlwZSA9IGdldEZ1bmN0aW9uUmV0dXJuVHlwZShwQ29sdW1uUmVmKTsgCgkJCQkJfQoJCQkJfQoJCQkJLyoKCQkJCWVsc2UKCQkJCXsKCQkJCQlhSXRlcmF0b3JTdGF0dXMuc2V0U3RhdGVtZW50VG9vQ29tcGxleCgpOwoJCQkJCXJldHVybjsKCQkJCX0KCQkJCSovCgkJCQlpZighYUNvbHVtbkFsaWFzLmdldExlbmd0aCgpKQoJCQkJCWFDb2x1bW5BbGlhcyA9IHNDb2x1bW5OYW1lOwoJCQkJc2V0U2VsZWN0Q29sdW1uTmFtZShtX2FTZWxlY3RDb2x1bW5zLHNDb2x1bW5OYW1lLGFDb2x1bW5BbGlhcyxhVGFibGVSYW5nZSxiRmt0LG5UeXBlLFNRTF9JU1JVTEUocENvbHVtblJlZixnZW5lcmFsX3NldF9mY3QpIHx8IFNRTF9JU1JVTEUocENvbHVtblJlZixzZXRfZmN0X3NwZWMpKTsKCQkJfQoJCX0KCX0KCiAgICByZXR1cm4gIWhhc0Vycm9ycygpOwp9CgoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpib29sIE9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6dHJhdmVyc2VPcmRlckJ5Q29sdW1uTmFtZXMoY29uc3QgT1NRTFBhcnNlTm9kZSogcFNlbGVjdE5vZGUpCnsKICAgIFJUTF9MT0dGSUxFX0NPTlRFWFRfQVVUSE9SKCBhTG9nZ2VyLCAicGFyc2UiLCAiT2NrZS5KYW5zc2VuQHN1bi5jb20iLCAiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjp0cmF2ZXJzZU9yZGVyQnlDb2x1bW5OYW1lcyIgKTsKCXRyYXZlcnNlQnlDb2x1bW5OYW1lcyggcFNlbGVjdE5vZGUsIHNhbF9UcnVlICk7CiAgICByZXR1cm4gIWhhc0Vycm9ycygpOwp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OnRyYXZlcnNlQnlDb2x1bW5OYW1lcyhjb25zdCBPU1FMUGFyc2VOb2RlKiBwU2VsZWN0Tm9kZSxzYWxfQm9vbCBfYk9yZGVyKQp7CiAgICBSVExfTE9HRklMRV9DT05URVhUX0FVVEhPUiggYUxvZ2dlciwgInBhcnNlIiwgIk9ja2UuSmFuc3NlbkBzdW4uY29tIiwgIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6dHJhdmVyc2VCeUNvbHVtbk5hbWVzIiApOwoJLy8JYUl0ZXJhdG9yU3RhdHVzLkNsZWFyKCk7CgoJaWYgKHBTZWxlY3ROb2RlID09IE5VTEwpIAoJewoJCS8vYUl0ZXJhdG9yU3RhdHVzLnNldEludmFsaWRTdGF0ZW1lbnQoKTsKCQlyZXR1cm47Cgl9CgoJaWYgKG1fZVN0YXRlbWVudFR5cGUgIT0gU1FMX1NUQVRFTUVOVF9TRUxFQ1QpCgl7CgkJLy9hSXRlcmF0b3JTdGF0dXMuc2V0SW52YWxpZFN0YXRlbWVudCgpOwoJCXJldHVybjsKCX0KCglpZihTUUxfSVNSVUxFKHBTZWxlY3ROb2RlLHVuaW9uX3N0YXRlbWVudCkpCgl7CgkJdHJhdmVyc2VCeUNvbHVtbk5hbWVzKHBTZWxlY3ROb2RlLT5nZXRDaGlsZCgwKSxfYk9yZGVyKTsKCQlyZXR1cm47Cgl9CgoJT1NMX0VOU1VSRShwU2VsZWN0Tm9kZS0+Y291bnQoKSA+PSA0LCJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6IGVycm9yIGluIHBhcnNlIHRyZWUhIik7CgoJT1NRTFBhcnNlTm9kZSAqIHBUYWJsZUV4cCA9IHBTZWxlY3ROb2RlLT5nZXRDaGlsZCgzKTsKCU9TTF9FTlNVUkUocFRhYmxlRXhwICE9IE5VTEwsIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjogZXJyb3IgaW4gcGFyc2UgdHJlZSEiKTsKCU9TTF9FTlNVUkUoU1FMX0lTUlVMRShwVGFibGVFeHAsdGFibGVfZXhwKSwiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOnRhYmxlX2V4cCBlcnJvciBpbiBwYXJzZSB0cmVlISIpOwoJT1NMX0VOU1VSRShwVGFibGVFeHAtPmNvdW50KCkgPT0gVEFCTEVfRVhQUkVTU0lPTl9DSElMRF9DT1VOVCwiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOiBlcnJvciBpbiBwYXJzZSB0cmVlISIpOwoKCXNhbF91SW50MzIgblBvcyA9ICggX2JPcmRlciA/IE9SREVSX0JZX0NISUxEX1BPUyA6IDIgKTsKCglPU1FMUGFyc2VOb2RlICogcE9wdEJ5Q2xhdXNlID0gcFRhYmxlRXhwLT5nZXRDaGlsZChuUG9zKTsKCU9TTF9FTlNVUkUocE9wdEJ5Q2xhdXNlICE9IE5VTEwsIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjogZXJyb3IgaW4gcGFyc2UgdHJlZSEiKTsKCWlmICggcE9wdEJ5Q2xhdXNlLT5jb3VudCgpID09IDAgKQoJCXJldHVybjsKCglPU0xfRU5TVVJFKHBPcHRCeUNsYXVzZS0+Y291bnQoKSA9PSAzLCJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6IGVycm9yIGluIHBhcnNlIHRyZWUhIik7CgoJT1NRTFBhcnNlTm9kZSAqIHBPcmRlcmluZ1NwZWNDb21tYWxpc3QgPSBwT3B0QnlDbGF1c2UtPmdldENoaWxkKDIpOwoJT1NMX0VOU1VSRShwT3JkZXJpbmdTcGVjQ29tbWFsaXN0ICE9IE5VTEwsIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjogZXJyb3IgaW4gcGFyc2UgdHJlZSEiKTsKCU9TTF9FTlNVUkUoIV9iT3JkZXIgfHwgU1FMX0lTUlVMRShwT3JkZXJpbmdTcGVjQ29tbWFsaXN0LG9yZGVyaW5nX3NwZWNfY29tbWFsaXN0KSwiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOm9yZGVyaW5nX3NwZWNfY29tbWFsaXN0IGVycm9yIGluIHBhcnNlIHRyZWUhIik7CglPU0xfRU5TVVJFKHBPcmRlcmluZ1NwZWNDb21tYWxpc3QtPmNvdW50KCkgPiAwLCJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6IGVycm9yIGluIHBhcnNlIHRyZWUhIik7CgoJOjpydGw6Ok9VU3RyaW5nIHNDb2x1bW5OYW1lLGFDb2x1bW5BbGlhczsKCTo6cnRsOjpPVVN0cmluZyBhVGFibGVSYW5nZTsKCXNhbF91SW50MzIgbkNvdW50ID0gcE9yZGVyaW5nU3BlY0NvbW1hbGlzdC0+Y291bnQoKTsKCWZvciAoc2FsX3VJbnQzMiBpID0gMDsgaSA8IG5Db3VudDsgKytpKQoJewoJCU9TUUxQYXJzZU5vZGUqIHBDb2x1bW5SZWYgID0gcE9yZGVyaW5nU3BlY0NvbW1hbGlzdC0+Z2V0Q2hpbGQoaSk7CgkJT1NMX0VOU1VSRShwQ29sdW1uUmVmICAhPSBOVUxMLCJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6IGVycm9yIGluIHBhcnNlIHRyZWUhIik7CgkJaWYgKCBfYk9yZGVyICkKCQl7CgkJCU9TTF9FTlNVUkUoU1FMX0lTUlVMRShwQ29sdW1uUmVmLG9yZGVyaW5nX3NwZWMpLCJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6b3JkZXJpbmdfc3BlYyBlcnJvciBpbiBwYXJzZSB0cmVlISIpOwoJCQlPU0xfRU5TVVJFKHBDb2x1bW5SZWYtPmNvdW50KCkgPT0gMiwiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOiBlcnJvciBpbiBwYXJzZSB0cmVlISIpOwoKCQkJcENvbHVtblJlZiA9IHBDb2x1bW5SZWYtPmdldENoaWxkKDApOwoJCX0KCQlhVGFibGVSYW5nZSA9IDo6cnRsOjpPVVN0cmluZygpOwoJCXNDb2x1bW5OYW1lID0gOjpydGw6Ok9VU3RyaW5nKCk7CgkJaWYgKCBTUUxfSVNSVUxFKHBDb2x1bW5SZWYsY29sdW1uX3JlZikgKQoJCXsKCQkJLy8gQ29sdW1uLU5hbWUgKHVuZCBUYWJsZVJhbmdlKToKCQkJaWYoU1FMX0lTUlVMRShwQ29sdW1uUmVmLGNvbHVtbl9yZWYpKQoJCQkJZ2V0Q29sdW1uUmFuZ2UocENvbHVtblJlZixzQ29sdW1uTmFtZSxhVGFibGVSYW5nZSk7CgkJCWVsc2UgLy8gZWluZSBFeHByZXNzaW9uCgkJCQlwQ29sdW1uUmVmLT5wYXJzZU5vZGVUb1N0ciggc0NvbHVtbk5hbWUsIG1fcEltcGwtPm1feENvbm5lY3Rpb24sIE5VTEwsIHNhbF9GYWxzZSwgc2FsX0ZhbHNlICk7CgoJCQlPU0xfRU5TVVJFKHNDb2x1bW5OYW1lLmdldExlbmd0aCgpLCJzQ29sdW1uTmFtZSBkYXJmIG5pY2h0IGxlZXIgc2VpbiIpOwoJCX0KCQllbHNlCgkJewkvLyBoZXJlIEkgZm91bmQgYSBwcmVkaWNhdGUKCQkJcENvbHVtblJlZi0+cGFyc2VOb2RlVG9TdHIoIHNDb2x1bW5OYW1lLCBtX3BJbXBsLT5tX3hDb25uZWN0aW9uLCBOVUxMLCBzYWxfRmFsc2UsIHNhbF9GYWxzZSApOwoJCX0KCQlPU0xfRU5TVVJFKHBDb2x1bW5SZWYgIT0gTlVMTCwiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOiBlcnJvciBpbiBwYXJzZSB0cmVlISIpOwoJCWlmICggX2JPcmRlciApCgkJewoJCQkvLyBBc2NlbmRpbmcvRGVzY2VuZGluZwoJCQlPU1FMUGFyc2VOb2RlICogcE9wdEFzY0Rlc2MgPSBwQ29sdW1uUmVmLT5nZXRQYXJlbnQoKS0+Z2V0Q2hpbGQoMSk7CgkJCU9TTF9FTlNVUkUocE9wdEFzY0Rlc2MgIT0gTlVMTCwiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOiBlcnJvciBpbiBwYXJzZSB0cmVlISIpOwoKCQkJc2FsX0Jvb2wgYkFzY2VuZGluZyA9IHBPcHRBc2NEZXNjICYmIFNRTF9JU1RPS0VOKHBPcHRBc2NEZXNjLEFTQyk7CgkJCXNldE9yZGVyQnlDb2x1bW5OYW1lKHNDb2x1bW5OYW1lLCBhVGFibGVSYW5nZSxiQXNjZW5kaW5nKTsKCQl9CgkJZWxzZQoJCQlzZXRHcm91cEJ5Q29sdW1uTmFtZShzQ29sdW1uTmFtZSwgYVRhYmxlUmFuZ2UpOwoJfQp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KYm9vbCBPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OnRyYXZlcnNlR3JvdXBCeUNvbHVtbk5hbWVzKGNvbnN0IE9TUUxQYXJzZU5vZGUqIHBTZWxlY3ROb2RlKQp7CiAgICBSVExfTE9HRklMRV9DT05URVhUX0FVVEhPUiggYUxvZ2dlciwgInBhcnNlIiwgIk9ja2UuSmFuc3NlbkBzdW4uY29tIiwgIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6dHJhdmVyc2VHcm91cEJ5Q29sdW1uTmFtZXMiICk7Cgl0cmF2ZXJzZUJ5Q29sdW1uTmFtZXMoIHBTZWxlY3ROb2RlLCBzYWxfRmFsc2UgKTsKICAgIHJldHVybiAhaGFzRXJyb3JzKCk7Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCm5hbWVzcGFjZQp7CiAgICA6OnJ0bDo6T1VTdHJpbmcgbGNsX2dlbmVyYXRlUGFyYW1ldGVyTmFtZSggY29uc3QgT1NRTFBhcnNlTm9kZSYgX3JQYXJlbnROb2RlLCBjb25zdCBPU1FMUGFyc2VOb2RlJiBfclBhcmFtTm9kZSApCiAgICB7CiAgICAgICAgOjpydGw6Ok9VU3RyaW5nIHNDb2x1bW5OYW1lKCBSVExfQ09OU1RBU0NJSV9VU1RSSU5HUEFSQU0oICJwYXJhbSIgKSApOwogICAgICAgIGNvbnN0IHNhbF9JbnQzMiBuQ291bnQgPSAoc2FsX0ludDMyKV9yUGFyZW50Tm9kZS5jb3VudCgpOwogICAgICAgIGZvciAoIHNhbF9JbnQzMiBpID0gMDsgaSA8IG5Db3VudDsgKytpICkKICAgICAgICB7CiAgICAgICAgICAgIGlmICggX3JQYXJlbnROb2RlLmdldENoaWxkKGkpID09ICZfclBhcmFtTm9kZSApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHNDb2x1bW5OYW1lICs9IDo6cnRsOjpPVVN0cmluZzo6dmFsdWVPZiggaSsxICk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gc0NvbHVtbk5hbWU7CiAgICB9Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjp0cmF2ZXJzZVBhcmFtZXRlcnMoY29uc3QgT1NRTFBhcnNlTm9kZSogX3BOb2RlKQp7CiAgICBSVExfTE9HRklMRV9DT05URVhUX0FVVEhPUiggYUxvZ2dlciwgInBhcnNlIiwgIk9ja2UuSmFuc3NlbkBzdW4uY29tIiwgIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6dHJhdmVyc2VQYXJhbWV0ZXJzIiApOwogICAgaWYgKCBfcE5vZGUgPT0gTlVMTCApCiAgICAgICAgcmV0dXJuOwoKICAgIDo6cnRsOjpPVVN0cmluZyBzQ29sdW1uTmFtZSwgc1RhYmxlUmFuZ2UsIGFDb2x1bW5BbGlhczsKICAgIGNvbnN0IE9TUUxQYXJzZU5vZGUqIHBQYXJlbnQgPSBfcE5vZGUtPmdldFBhcmVudCgpOwogICAgaWYgKCBwUGFyZW50ICE9IE5VTEwgKQogICAgewogICAgICAgIGlmICggU1FMX0lTUlVMRShwUGFyZW50LGNvbXBhcmlzb25fcHJlZGljYXRlKSApIC8vIHggPSBYCiAgICAgICAgewogICAgICAgICAgICBzYWxfdUludDMyIG5Qb3MgPSAwOwogICAgICAgICAgICBpZiAoIHBQYXJlbnQtPmdldENoaWxkKG5Qb3MpID09IF9wTm9kZSApCiAgICAgICAgICAgICAgICBuUG9zID0gMjsKICAgICAgICAgICAgY29uc3QgT1NRTFBhcnNlTm9kZSogcE90aGVyID0gcFBhcmVudC0+Z2V0Q2hpbGQoblBvcyk7CiAgICAgICAgICAgIGlmICggU1FMX0lTUlVMRSggcE90aGVyLCBjb2x1bW5fcmVmICkgKQogICAgICAgICAgICAgICAgZ2V0Q29sdW1uUmFuZ2UoIHBPdGhlciwgc0NvbHVtbk5hbWUsIHNUYWJsZVJhbmdlLCBhQ29sdW1uQWxpYXMpOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBwT3RoZXItPnBhcnNlTm9kZVRvU3RyKCBzQ29sdW1uTmFtZSwgbV9wSW1wbC0+bV94Q29ubmVjdGlvbiwgTlVMTCwgc2FsX0ZhbHNlLCBzYWxfRmFsc2UgKTsKICAgICAgICB9IC8vIGlmICggU1FMX0lTUlVMRShwUGFyZW50LGNvbXBhcmlzb25fcHJlZGljYXRlKSApIC8vIHggPSBYCiAgICAgICAgZWxzZSBpZiAoIFNRTF9JU1JVTEUocFBhcmVudCxvdGhlcl9saWtlX3ByZWRpY2F0ZV9wYXJ0XzIpICkKICAgICAgICB7CiAgICAgICAgICAgIGNvbnN0IE9TUUxQYXJzZU5vZGUqIHBPdGhlciA9IHBQYXJlbnQtPmdldFBhcmVudCgpLT5nZXRDaGlsZCgwKTsKICAgICAgICAgICAgaWYgKCBTUUxfSVNSVUxFKCBwT3RoZXIsIGNvbHVtbl9yZWYgKSApCiAgICAgICAgICAgICAgICBnZXRDb2x1bW5SYW5nZSggcE90aGVyLCBzQ29sdW1uTmFtZSwgc1RhYmxlUmFuZ2UsIGFDb2x1bW5BbGlhcyk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHBPdGhlci0+cGFyc2VOb2RlVG9TdHIoIHNDb2x1bW5OYW1lLCBtX3BJbXBsLT5tX3hDb25uZWN0aW9uLCBOVUxMLCBzYWxfRmFsc2UsIHNhbF9GYWxzZSApOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmICggU1FMX0lTUlVMRShwUGFyZW50LGJldHdlZW5fcHJlZGljYXRlX3BhcnRfMikgKQogICAgICAgIHsKICAgICAgICAgICAgY29uc3QgT1NRTFBhcnNlTm9kZSogcE90aGVyID0gcFBhcmVudC0+Z2V0UGFyZW50KCktPmdldENoaWxkKDApOwogICAgICAgICAgICBpZiAoIFNRTF9JU1JVTEUoIHBPdGhlciwgY29sdW1uX3JlZiApICkKICAgICAgICAgICAgICAgIGdldENvbHVtblJhbmdlKCBwT3RoZXIsIHNDb2x1bW5OYW1lLCBzVGFibGVSYW5nZSwgYUNvbHVtbkFsaWFzKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBwT3RoZXItPnBhcnNlTm9kZVRvU3RyKCBzQ29sdW1uTmFtZSwgbV9wSW1wbC0+bV94Q29ubmVjdGlvbiwgTlVMTCwgc2FsX0ZhbHNlLCBzYWxfRmFsc2UgKTsKICAgICAgICAgICAgICAgIGxjbF9nZW5lcmF0ZVBhcmFtZXRlck5hbWUoICpwUGFyZW50LCAqX3BOb2RlICk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAoIHBQYXJlbnQtPmdldE5vZGVUeXBlKCkgPT0gU1FMX05PREVfQ09NTUFMSVNUUlVMRSApCiAgICAgICAgewogICAgICAgICAgICBsY2xfZ2VuZXJhdGVQYXJhbWV0ZXJOYW1lKCAqcFBhcmVudCwgKl9wTm9kZSApOwogICAgICAgIH0KICAgIH0KICAgIHRyYXZlcnNlUGFyYW1ldGVyKCBfcE5vZGUsIHBQYXJlbnQsIHNDb2x1bW5OYW1lLCBzVGFibGVSYW5nZSwgYUNvbHVtbkFsaWFzICk7CiAgICBjb25zdCBzYWxfdUludDMyIG5Db3VudCA9IF9wTm9kZS0+Y291bnQoKTsKICAgIGZvciAoc2FsX3VJbnQzMiBpID0gMDsgaSA8IG5Db3VudDsgKytpKQogICAgewogICAgICAgIGNvbnN0IE9TUUxQYXJzZU5vZGUqIHBDaGlsZCAgPSBfcE5vZGUtPmdldENoaWxkKGkpOwogICAgICAgIHRyYXZlcnNlUGFyYW1ldGVycyggcENoaWxkICk7CiAgICB9Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpib29sIE9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6dHJhdmVyc2VTZWxlY3Rpb25Dcml0ZXJpYShjb25zdCBPU1FMUGFyc2VOb2RlKiBwU2VsZWN0Tm9kZSkKewogICAgUlRMX0xPR0ZJTEVfQ09OVEVYVF9BVVRIT1IoIGFMb2dnZXIsICJwYXJzZSIsICJPY2tlLkphbnNzZW5Ac3VuLmNvbSIsICJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OnRyYXZlcnNlU2VsZWN0aW9uQ3JpdGVyaWEiICk7CglpZiAoIHBTZWxlY3ROb2RlID09IE5VTEwgKQoJCXJldHVybiBmYWxzZTsKCgoJLy8gUGFyc2UgVHJlZSBhbmFseXNpZXJlbiAoamUgbmFjaCBTdGF0ZW1lbnQtVHlwKQoJLy8gdW5kIFplaWdlciBhdWYgV0hFUkUtS2xhdXNlbCBzZXR6ZW46CglPU1FMUGFyc2VOb2RlICogcFdoZXJlQ2xhdXNlID0gTlVMTDsKCglpZiAobV9lU3RhdGVtZW50VHlwZSA9PSBTUUxfU1RBVEVNRU5UX1NFTEVDVCkgCgl7CgkJaWYoU1FMX0lTUlVMRShwU2VsZWN0Tm9kZSx1bmlvbl9zdGF0ZW1lbnQpKQoJCXsKCQkJcmV0dXJuICB0cmF2ZXJzZVNlbGVjdGlvbkNyaXRlcmlhKCBwU2VsZWN0Tm9kZS0+Z2V0Q2hpbGQoIDAgKSApCiAgICAgICAgICAgICAgICAmJiAgdHJhdmVyc2VTZWxlY3Rpb25Dcml0ZXJpYSggcFNlbGVjdE5vZGUtPmdldENoaWxkKCAzICkgKTsKCQl9CgkJT1NMX0VOU1VSRShwU2VsZWN0Tm9kZS0+Y291bnQoKSA+PSA0LCJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6IGVycm9yIGluIHBhcnNlIHRyZWUhIik7CgoJCU9TUUxQYXJzZU5vZGUgKiBwVGFibGVFeHAgPSBwU2VsZWN0Tm9kZS0+Z2V0Q2hpbGQoMyk7CgkJT1NMX0VOU1VSRShwVGFibGVFeHAgIT0gTlVMTCwiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOiBlcnJvciBpbiBwYXJzZSB0cmVlISIpOwoJCU9TTF9FTlNVUkUoU1FMX0lTUlVMRShwVGFibGVFeHAsdGFibGVfZXhwKSwiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOiBlcnJvciBpbiBwYXJzZSB0cmVlISIpOwoJCU9TTF9FTlNVUkUocFRhYmxlRXhwLT5jb3VudCgpID09IFRBQkxFX0VYUFJFU1NJT05fQ0hJTERfQ09VTlQsIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjogZXJyb3IgaW4gcGFyc2UgdHJlZSEiKTsKCgkJcFdoZXJlQ2xhdXNlID0gcFRhYmxlRXhwLT5nZXRDaGlsZCgxKTsKCX0gZWxzZSBpZiAoU1FMX0lTUlVMRShwU2VsZWN0Tm9kZSx1cGRhdGVfc3RhdGVtZW50X3NlYXJjaGVkKSkgewoJCU9TTF9FTlNVUkUocFNlbGVjdE5vZGUtPmNvdW50KCkgPT0gNSwiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOiBlcnJvciBpbiBwYXJzZSB0cmVlISIpOwoJCXBXaGVyZUNsYXVzZSA9IHBTZWxlY3ROb2RlLT5nZXRDaGlsZCg0KTsKCX0gZWxzZSBpZiAoU1FMX0lTUlVMRShwU2VsZWN0Tm9kZSxkZWxldGVfc3RhdGVtZW50X3NlYXJjaGVkKSkgewoJCU9TTF9FTlNVUkUocFNlbGVjdE5vZGUtPmNvdW50KCkgPT0gNCwiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOiBlcnJvciBpbiBwYXJzZSB0cmVlISIpOwoJCXBXaGVyZUNsYXVzZSA9IHBTZWxlY3ROb2RlLT5nZXRDaGlsZCgzKTsKCX0gZWxzZSBpZiAoU1FMX0lTUlVMRShwU2VsZWN0Tm9kZSxkZWxldGVfc3RhdGVtZW50X3Bvc2l0aW9uZWQpKSB7CgkJLy8gbnlpCgkJT1NMX0FTU0VSVCgiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjpnZXRTZWxlY3Rpb25Dcml0ZXJpYTogcG9zaXRpb25lZCBueWkiKTsKCX0gZWxzZSB7CgkJLy8gQW5kZXJlcyBTdGF0ZW1lbnQuIEtlaW5lIFNlbGVrdGlvbnNrcml0ZXJpZW4uCgkJcmV0dXJuIGZhbHNlOwoJfQoKCWlmICghIFNRTF9JU1JVTEUocFdoZXJlQ2xhdXNlLHdoZXJlX2NsYXVzZSkpIHsKCQkvLyBEaWUgV2hlcmUgQ2xhdXNlIGlzdCBtZWlzdGVucyBvcHRpb25hbCwgZC4gaC4gZXMga29lbm50ZSBzaWNoIGF1Y2gKCQkvLyB1bSAib3B0aW9uYWxfd2hlcmVfY2xhdXNlIiBoYW5kZWxuLgoJCU9TTF9FTlNVUkUoU1FMX0lTUlVMRShwV2hlcmVDbGF1c2Usb3B0X3doZXJlX2NsYXVzZSksIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjogZXJyb3IgaW4gcGFyc2UgdHJlZSEiKTsKCQlyZXR1cm4gZmFsc2U7Cgl9CgoJLy8gV2VubiBlcyBhYmVyIGVpbmUgd2hlcmVfY2xhdXNlIGlzdCwgZGFubiBkYXJmIHNpZSBuaWNodCBsZWVyIHNlaW46CglPU0xfRU5TVVJFKHBXaGVyZUNsYXVzZS0+Y291bnQoKSA9PSAyLCJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6IGVycm9yIGluIHBhcnNlIHRyZWUhIik7CgoJT1NRTFBhcnNlTm9kZSAqIHBDb21wYXJpc29uUHJlZGljYXRlID0gcFdoZXJlQ2xhdXNlLT5nZXRDaGlsZCgxKTsKCU9TTF9FTlNVUkUocENvbXBhcmlzb25QcmVkaWNhdGUgIT0gTlVMTCwiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOiBlcnJvciBpbiBwYXJzZSB0cmVlISIpOwoKCS8vCgkvLyBVbmQgbnVuIGRpZSBWZXJnbGVpY2hza3JpdGVyaWVuIGFiYXJiZWl0ZW4gKHJla3Vyc2l2LCBhbGxlcyBpc3QgZXJzdG1hbCBlaW4gT1ItS3JpdGVyaXVtKToKCS8vCgoJdHJhdmVyc2VPUkNyaXRlcmlhKHBDb21wYXJpc29uUHJlZGljYXRlKTsKCiAgICByZXR1cm4gIWhhc0Vycm9ycygpOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjp0cmF2ZXJzZU9SQ3JpdGVyaWEoT1NRTFBhcnNlTm9kZSAqIHBTZWFyY2hDb25kaXRpb24pCnsKICAgIFJUTF9MT0dGSUxFX0NPTlRFWFRfQVVUSE9SKCBhTG9nZ2VyLCAicGFyc2UiLCAiT2NrZS5KYW5zc2VuQHN1bi5jb20iLCAiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjp0cmF2ZXJzZU9SQ3JpdGVyaWEiICk7CgkKCglpZiAoCgkJCXBTZWFyY2hDb25kaXRpb24tPmNvdW50KCkgPT0gMyAmJgoJCQlTUUxfSVNQVU5DVFVBVElPTihwU2VhcmNoQ29uZGl0aW9uLT5nZXRDaGlsZCgwKSwiKCIpICYmCgkJCVNRTF9JU1BVTkNUVUFUSU9OKHBTZWFyY2hDb25kaXRpb24tPmdldENoaWxkKDIpLCIpIikKCQkpCgl7CgkJLy8gUnVuZGUgS2xhbW1lcm4gdW0gZGVuIEF1c2RydWNrCgkJdHJhdmVyc2VPUkNyaXRlcmlhKHBTZWFyY2hDb25kaXRpb24tPmdldENoaWxkKDEpKTsKCX0gZWxzZSBpZiAoU1FMX0lTUlVMRShwU2VhcmNoQ29uZGl0aW9uLHNlYXJjaF9jb25kaXRpb24pICYmCgkJcFNlYXJjaENvbmRpdGlvbi0+Y291bnQoKSA9PSAzICYmCgkJU1FMX0lTVE9LRU4ocFNlYXJjaENvbmRpdGlvbi0+Z2V0Q2hpbGQoMSksT1IpKQoJewoJCS8vIE9SLVZlcmtudWVwZnVuZzoKCgkJZm9yIChpbnQgaSA9IDA7IGkgPCAzOyBpKyspIHsKCQkJaWYgKGkgPT0gMSkgY29udGludWU7CQkvLyBTY2hsdWVzc2Vsd29ydCBPUiB1ZWJlcnNwcmluZ2VuCgoJCQkvLyBJc3QgZGFzIGVyc3RlIEVsZW1lbnQgd2llZGVyIGVpbmUgT1ItVmVya251ZXBmdW5nPwoJCQlpZiAoaSA9PSAwICYmCgkJCQlTUUxfSVNSVUxFKHBTZWFyY2hDb25kaXRpb24tPmdldENoaWxkKDApLHNlYXJjaF9jb25kaXRpb24pICYmCgkJCQlwU2VhcmNoQ29uZGl0aW9uLT5nZXRDaGlsZCgwKS0+Y291bnQoKSA9PSAzICYmCgkJCQlTUUxfSVNUT0tFTihwU2VhcmNoQ29uZGl0aW9uLT5nZXRDaGlsZCgwKS0+Z2V0Q2hpbGQoMSksT1IpKQoJCQl7CgkJCQkvLyBEYW5uIHJla3Vyc2l2IGFic3RlaWdlbiAuLi4KCQkJCXRyYXZlcnNlT1JDcml0ZXJpYShwU2VhcmNoQ29uZGl0aW9uLT5nZXRDaGlsZCgwKSk7CgoJCQl9IGVsc2UgewoJCQkJLy8gQU5ELUtyaXRlcmllbiAuLi4KCQkJCXRyYXZlcnNlQU5EQ3JpdGVyaWEocFNlYXJjaENvbmRpdGlvbi0+Z2V0Q2hpbGQoaSkpOwoJCQkJLy8JaWYgKCEgYUl0ZXJhdG9yU3RhdHVzLklzU3VjY2Vzc2Z1bCgpKSBicmVhazsKCQkJfQoKCQkJLy8JaWYgKCEgYUl0ZXJhdG9yU3RhdHVzLklzU3VjY2Vzc2Z1bCgpKSBicmVhazsKCQl9Cgl9IGVsc2UgewoJCS8vIE51ciAqZWluKiBLcml0ZXJpdW0gb2RlciBlaW5lIEFORC1WZXJrbnVlcGZ1bmcgdm9uIEtyaXRlcmllbi4KCQkvLyBEaXJla3QgZGllIEFORC1Lcml0ZXJpZW4gYmVoYW5kZWxuLgoJCXRyYXZlcnNlQU5EQ3JpdGVyaWEocFNlYXJjaENvbmRpdGlvbik7CgkJLy8JaWYgKCEgYUl0ZXJhdG9yU3RhdHVzLklzU3VjY2Vzc2Z1bCgpKSByZXR1cm47Cgl9CgoJLy8gRmVobGVyIGVpbmZhY2ggd2VpdGVycmVpY2hlbi4KfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIE9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6dHJhdmVyc2VBTkRDcml0ZXJpYShPU1FMUGFyc2VOb2RlICogcFNlYXJjaENvbmRpdGlvbikKewogICAgUlRMX0xPR0ZJTEVfQ09OVEVYVF9BVVRIT1IoIGFMb2dnZXIsICJwYXJzZSIsICJPY2tlLkphbnNzZW5Ac3VuLmNvbSIsICJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OnRyYXZlcnNlQU5EQ3JpdGVyaWEiICk7CgkKCglpZiAoCgkJCVNRTF9JU1JVTEUocFNlYXJjaENvbmRpdGlvbixib29sZWFuX3ByaW1hcnkpICYmCgkJCXBTZWFyY2hDb25kaXRpb24tPmNvdW50KCkgPT0gMyAmJgoJCQlTUUxfSVNQVU5DVFVBVElPTihwU2VhcmNoQ29uZGl0aW9uLT5nZXRDaGlsZCgwKSwiKCIpICYmCgkJCVNRTF9JU1BVTkNUVUFUSU9OKHBTZWFyY2hDb25kaXRpb24tPmdldENoaWxkKDIpLCIpIikKCQkpCgl7CgkJLy8gUnVuZGUgS2xhbW1lcm4KCQl0cmF2ZXJzZUFORENyaXRlcmlhKHBTZWFyY2hDb25kaXRpb24tPmdldENoaWxkKDEpKTsKCX0KCS8vIERhcyBlcnN0ZSBFbGVtZW50IGlzdCBlaW5lIE9SLVZlcmtudWVwZnVuZwoJZWxzZSAgaWYgKCBTUUxfSVNSVUxFKHBTZWFyY2hDb25kaXRpb24sc2VhcmNoX2NvbmRpdGlvbikgJiYgcFNlYXJjaENvbmRpdGlvbi0+Y291bnQoKSA9PSAzICkKCXsKCQkvLyBEYW5uIHJla3Vyc2l2IGFic3RlaWdlbiAoZGllc2VsYmUgUm93IGJlbnV0emVuKSAuLi4KCQl0cmF2ZXJzZU9SQ3JpdGVyaWEocFNlYXJjaENvbmRpdGlvbi0+Z2V0Q2hpbGQoMCkpOwovLwkJaWYgKCEgYUl0ZXJhdG9yU3RhdHVzLklzU3VjY2Vzc2Z1bCgpKQovLwkJCXJldHVybjsKCgkJLy8gVW5kIG1pdCBkZW0gcmVjaHRlbiBDaGlsZCB3ZWl0ZXJtYWNoZW46CgkJdHJhdmVyc2VBTkRDcml0ZXJpYShwU2VhcmNoQ29uZGl0aW9uLT5nZXRDaGlsZCgyKSk7Cgl9CgkvLyBEYXMgZXJzdGUgRWxlbWVudCBpc3QgKHdpZWRlcikgZWluZSBBTkQtVmVya251ZXBmdW5nCgllbHNlIGlmICggU1FMX0lTUlVMRShwU2VhcmNoQ29uZGl0aW9uLGJvb2xlYW5fdGVybSkgJiYgcFNlYXJjaENvbmRpdGlvbi0+Y291bnQoKSA9PSAzICkKCXsKCQkvLyBEYW5uIHJla3Vyc2l2IGFic3RlaWdlbiAoZGllc2VsYmUgUm93IGJlbnV0emVuKSAuLi4KCQl0cmF2ZXJzZUFORENyaXRlcmlhKHBTZWFyY2hDb25kaXRpb24tPmdldENoaWxkKDApKTsKLy8JCWlmICghIGFJdGVyYXRvclN0YXR1cy5Jc1N1Y2Nlc3NmdWwoKSkKLy8JCQlyZXR1cm47CgoJCS8vIFVuZCBtaXQgZGVtIHJlY2h0ZW4gQ2hpbGQgd2VpdGVybWFjaGVuOgoJCXRyYXZlcnNlQU5EQ3JpdGVyaWEocFNlYXJjaENvbmRpdGlvbi0+Z2V0Q2hpbGQoMikpOwoJfQoJIC8vIFNvbnN0IGVpbnplbG5lIFN1Y2hrcml0ZXJpZW4gd2llID0sICE9LCAuLi4sIExJS0UsIElTIE5VTEwgdXN3LiBiZWhhbmRlbG46CgllbHNlIGlmIChTUUxfSVNSVUxFKHBTZWFyY2hDb25kaXRpb24sY29tcGFyaXNvbl9wcmVkaWNhdGUpICkKCXsKCQk6OnJ0bDo6T1VTdHJpbmcgYVZhbHVlOwoJCXBTZWFyY2hDb25kaXRpb24tPmdldENoaWxkKDIpLT5wYXJzZU5vZGVUb1N0ciggYVZhbHVlLCBtX3BJbXBsLT5tX3hDb25uZWN0aW9uLCBOVUxMLCBzYWxfRmFsc2UsIHNhbF9GYWxzZSApOwoJCXRyYXZlcnNlT25lUHJlZGljYXRlKHBTZWFyY2hDb25kaXRpb24tPmdldENoaWxkKDApLGFWYWx1ZSxwU2VhcmNoQ29uZGl0aW9uLT5nZXRDaGlsZCgyKSk7CiAgICAgICAgaW1wbF9maWxsSm9pbkNvbmRpdGlvbnMocFNlYXJjaENvbmRpdGlvbik7Ci8vCQlpZiAoISBhSXRlcmF0b3JTdGF0dXMuSXNTdWNjZXNzZnVsKCkpCi8vCQkJcmV0dXJuOwoJfQoJZWxzZSBpZiAoU1FMX0lTUlVMRShwU2VhcmNoQ29uZGl0aW9uLGxpa2VfcHJlZGljYXRlKSAvKiYmIFNRTF9JU1JVTEUocFNlYXJjaENvbmRpdGlvbi0+Z2V0Q2hpbGQoMCksY29sdW1uX3JlZikqLykKCXsKCQlPU0xfRU5TVVJFKHBTZWFyY2hDb25kaXRpb24tPmNvdW50KCkgPT0gMiwiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOiBlcnJvciBpbiBwYXJzZSB0cmVlISIpOwogICAgICAgIGNvbnN0IE9TUUxQYXJzZU5vZGUqIHBQYXJ0MiA9IHBTZWFyY2hDb25kaXRpb24tPmdldENoaWxkKDEpOwoKCQlzYWxfSW50MzIgbkN1cmVudFBvcyA9IHBQYXJ0Mi0+Y291bnQoKS0yOwoKCQlPU1FMUGFyc2VOb2RlICogcE51bV92YWx1ZV9leHAJPSBwUGFydDItPmdldENoaWxkKG5DdXJlbnRQb3MpOwoJCU9TUUxQYXJzZU5vZGUgKiBwT3B0RXNjYXBlCQk9IHBQYXJ0Mi0+Z2V0Q2hpbGQobkN1cmVudFBvcysxKTsKCgkJT1NMX0VOU1VSRShwTnVtX3ZhbHVlX2V4cCAhPSBOVUxMLCJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6IGVycm9yIGluIHBhcnNlIHRyZWUhIik7CgkJT1NMX0VOU1VSRShwT3B0RXNjYXBlICE9IE5VTEwsIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjogZXJyb3IgaW4gcGFyc2UgdHJlZSEiKTsKCgkJaWYgKHBPcHRFc2NhcGUtPmNvdW50KCkgIT0gMCkKCQl7CgkJCS8vCWFJdGVyYXRvclN0YXR1cy5zZXRTdGF0ZW1lbnRUb29Db21wbGV4KCk7CgkJCXJldHVybjsKCQl9CgoJCTo6cnRsOjpPVVN0cmluZyBhVmFsdWU7CgkJT1NRTFBhcnNlTm9kZSAqIHBQYXJhbSA9IE5VTEw7CgkJaWYgKFNRTF9JU1JVTEUocE51bV92YWx1ZV9leHAscGFyYW1ldGVyKSkKCQkJcFBhcmFtID0gcE51bV92YWx1ZV9leHA7CgkJZWxzZSBpZihwTnVtX3ZhbHVlX2V4cC0+aXNUb2tlbigpKQoJCQkvLyBOb3JtYWxlciBXZXJ0CgkJCWFWYWx1ZSA9IHBOdW1fdmFsdWVfZXhwLT5nZXRUb2tlblZhbHVlKCk7CgkJZWxzZQoJCXsKCQkJcE51bV92YWx1ZV9leHAtPnBhcnNlTm9kZVRvU3RyKCBhVmFsdWUsIG1fcEltcGwtPm1feENvbm5lY3Rpb24sIE5VTEwsIHNhbF9GYWxzZSwgc2FsX0ZhbHNlICk7CgkJCXBQYXJhbSA9IHBOdW1fdmFsdWVfZXhwOwoJCX0KCgkJdHJhdmVyc2VPbmVQcmVkaWNhdGUocFNlYXJjaENvbmRpdGlvbi0+Z2V0Q2hpbGQoMCksYVZhbHVlLHBQYXJhbSk7Ci8vCQlpZiAoISBhSXRlcmF0b3JTdGF0dXMuSXNTdWNjZXNzZnVsKCkpCi8vCQkJcmV0dXJuOwoJfQoJZWxzZSBpZiAoU1FMX0lTUlVMRShwU2VhcmNoQ29uZGl0aW9uLGluX3ByZWRpY2F0ZSkpCgl7CgkJT1NMX0VOU1VSRShwU2VhcmNoQ29uZGl0aW9uLT5jb3VudCgpID09IDIsIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjogZXJyb3IgaW4gcGFyc2UgdHJlZSEiKTsKICAgICAgICBjb25zdCBPU1FMUGFyc2VOb2RlKiBwUGFydDIgPSBwU2VhcmNoQ29uZGl0aW9uLT5nZXRDaGlsZCgxKTsKCgkJdHJhdmVyc2VPUkNyaXRlcmlhKHBTZWFyY2hDb25kaXRpb24tPmdldENoaWxkKDApKTsKCQkvLwlpZiAoISBhSXRlcmF0b3JTdGF0dXMuSXNTdWNjZXNzZnVsKCkpIHJldHVybjsKCgkJT1NRTFBhcnNlTm9kZSogcENoaWxkID0gcFBhcnQyLT5nZXRDaGlsZCgyKTsKCQlpZiAoIFNRTF9JU1JVTEUocENoaWxkLT5nZXRDaGlsZCgwKSxzdWJxdWVyeSkgKQoJCXsKCQkJdHJhdmVyc2VUYWJsZU5hbWVzKCAqbV9wSW1wbC0+bV9wU3ViVGFibGVzICk7CgkJCXRyYXZlcnNlU2VsZWN0aW9uQ3JpdGVyaWEocENoaWxkLT5nZXRDaGlsZCgwKS0+Z2V0Q2hpbGQoMSkpOwoJCX0KCQllbHNlCgkJeyAvLyAnKCcgdmFsdWVfZXhwX2NvbW1hbGlzdCAnKScKCQkJcENoaWxkID0gcENoaWxkLT5nZXRDaGlsZCgxKTsKCQkJc2FsX0ludDMyIG5Db3VudCA9IHBDaGlsZC0+Y291bnQoKTsKCQkJZm9yIChzYWxfSW50MzIgaT0wOyBpIDwgbkNvdW50OyArK2kpCgkJCXsKCQkJCXRyYXZlcnNlQU5EQ3JpdGVyaWEocENoaWxkLT5nZXRDaGlsZChpKSk7CgkJCX0KCQl9Cgl9CgllbHNlIGlmIChTUUxfSVNSVUxFKHBTZWFyY2hDb25kaXRpb24sdGVzdF9mb3JfbnVsbCkgLyomJiBTUUxfSVNSVUxFKHBTZWFyY2hDb25kaXRpb24tPmdldENoaWxkKDApLGNvbHVtbl9yZWYpKi8pCgl7CgkJT1NMX0VOU1VSRShwU2VhcmNoQ29uZGl0aW9uLT5jb3VudCgpID09IDIsIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjogZXJyb3IgaW4gcGFyc2UgdHJlZSEiKTsKICAgICAgICBjb25zdCBPU1FMUGFyc2VOb2RlKiBwUGFydDIgPSBwU2VhcmNoQ29uZGl0aW9uLT5nZXRDaGlsZCgxKTsKICAgICAgICAodm9pZClwUGFydDI7CgkJT1NMX0VOU1VSRShTUUxfSVNUT0tFTihwUGFydDItPmdldENoaWxkKDApLElTKSwiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOiBlcnJvciBpbiBwYXJzZSB0cmVlISIpOwoKCQk6OnJ0bDo6T1VTdHJpbmcgYVN0cmluZzsKCQl0cmF2ZXJzZU9uZVByZWRpY2F0ZShwU2VhcmNoQ29uZGl0aW9uLT5nZXRDaGlsZCgwKSxhU3RyaW5nLE5VTEwpOwoJCS8vCWlmICghIGFJdGVyYXRvclN0YXR1cy5Jc1N1Y2Nlc3NmdWwoKSkgcmV0dXJuOwoJfSAKCWVsc2UgaWYgKFNRTF9JU1JVTEUocFNlYXJjaENvbmRpdGlvbixudW1fdmFsdWVfZXhwKSB8fCBTUUxfSVNSVUxFKHBTZWFyY2hDb25kaXRpb24sdGVybSkpCgl7CgkJOjpydGw6Ok9VU3RyaW5nIGFTdHJpbmc7CgkJdHJhdmVyc2VPbmVQcmVkaWNhdGUocFNlYXJjaENvbmRpdGlvbi0+Z2V0Q2hpbGQoMCksYVN0cmluZyxwU2VhcmNoQ29uZGl0aW9uLT5nZXRDaGlsZCgwKSk7CgkJdHJhdmVyc2VPbmVQcmVkaWNhdGUocFNlYXJjaENvbmRpdGlvbi0+Z2V0Q2hpbGQoMiksYVN0cmluZyxwU2VhcmNoQ29uZGl0aW9uLT5nZXRDaGlsZCgyKSk7Cgl9CgkvLyBGZWhsZXIgZWluZmFjaCB3ZWl0ZXJyZWljaGVuLgp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OnRyYXZlcnNlUGFyYW1ldGVyKGNvbnN0IE9TUUxQYXJzZU5vZGUqIF9wUGFyc2VOb2RlCgkJCQkJCQkJCQkJICAsY29uc3QgT1NRTFBhcnNlTm9kZSogX3BQYXJlbnROb2RlCgkJCQkJCQkJCQkJICAsY29uc3QgOjpydGw6Ok9VU3RyaW5nJiBfYUNvbHVtbk5hbWUKCQkJCQkJCQkJCQkgICxjb25zdCA6OnJ0bDo6T1VTdHJpbmcmIF9hVGFibGVSYW5nZQoJCQkJCQkJCQkJCSAgLGNvbnN0IDo6cnRsOjpPVVN0cmluZyYgX3JDb2x1bW5BbGlhcykKewogICAgUlRMX0xPR0ZJTEVfQ09OVEVYVF9BVVRIT1IoIGFMb2dnZXIsICJwYXJzZSIsICJPY2tlLkphbnNzZW5Ac3VuLmNvbSIsICJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OnRyYXZlcnNlUGFyYW1ldGVyIiApOwoJaWYgKCAhU1FMX0lTUlVMRSggX3BQYXJzZU5vZGUsIHBhcmFtZXRlciApICkKICAgICAgICByZXR1cm47CgogICAgaWYgKCAoIG1fcEltcGwtPm1fbkluY2x1ZGVNYXNrICYgUGFyYW1ldGVycyApICE9IFBhcmFtZXRlcnMgKQogICAgICAgIC8vIHBhcmFtZXRlcnMgbm90IHRvIGJlIGluY2x1ZGVkIGluIHRoZSB0cmF2ZXJzYWwKICAgICAgICByZXR1cm47CgoJT1NMX0VOU1VSRShfcFBhcnNlTm9kZS0+Y291bnQoKSA+IDAsIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjogZXJyb3IgaW4gcGFyc2UgdHJlZSEiKTsKCU9TUUxQYXJzZU5vZGUgKiBwTWFyayA9IF9wUGFyc2VOb2RlLT5nZXRDaGlsZCgwKTsKCTo6cnRsOjpPVVN0cmluZyBzUGFyYW1ldGVyTmFtZTsKCglpZiAoU1FMX0lTUFVOQ1RVQVRJT04ocE1hcmssIj8iKSkKCXsKICAgICAgICBzUGFyYW1ldGVyTmFtZSA9ICAgIF9yQ29sdW1uQWxpYXMuZ2V0TGVuZ3RoKCkKICAgICAgICAgICAgICAgICAgICAgICAgPyAgIF9yQ29sdW1uQWxpYXMKICAgICAgICAgICAgICAgICAgICAgICAgOiAgIF9hQ29sdW1uTmFtZS5nZXRMZW5ndGgoKQogICAgICAgICAgICAgICAgICAgICAgICA/ICAgX2FDb2x1bW5OYW1lCiAgICAgICAgICAgICAgICAgICAgICAgIDogICA6OnJ0bDo6T1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSgiPyIpOwoJfQoJZWxzZSBpZiAoU1FMX0lTUFVOQ1RVQVRJT04ocE1hcmssIjoiKSkKCXsKCQlzUGFyYW1ldGVyTmFtZSA9IF9wUGFyc2VOb2RlLT5nZXRDaGlsZCgxKS0+Z2V0VG9rZW5WYWx1ZSgpOwoJfQoJZWxzZSBpZiAoU1FMX0lTUFVOQ1RVQVRJT04ocE1hcmssIlsiKSkKCXsKCQlzUGFyYW1ldGVyTmFtZSA9IF9wUGFyc2VOb2RlLT5nZXRDaGlsZCgxKS0+Z2V0VG9rZW5WYWx1ZSgpOwoJfQoJZWxzZQoJewoJCU9TTF9BU1NFUlQoIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjogZXJyb3IgaW4gcGFyc2UgdHJlZSEiKTsKCX0KCgkvLyBmb3VuZCBhIHBhcmFtZXRlcgoJaWYgKCBfcFBhcmVudE5vZGUgJiYgKFNRTF9JU1JVTEUoX3BQYXJlbnROb2RlLGdlbmVyYWxfc2V0X2ZjdCkgfHwgU1FMX0lTUlVMRShfcFBhcmVudE5vZGUsc2V0X2ZjdF9zcGVjKSkgKQoJey8vIGZvdW5kIGEgZnVuY3Rpb24gYXMgY29sdW1uX3JlZgoJCTo6cnRsOjpPVVN0cmluZyBzRnVuY3Rpb25OYW1lOwoJCV9wUGFyZW50Tm9kZS0+Z2V0Q2hpbGQoMCktPnBhcnNlTm9kZVRvU3RyKCBzRnVuY3Rpb25OYW1lLCBtX3BJbXBsLT5tX3hDb25uZWN0aW9uLCBOVUxMLCBzYWxfRmFsc2UsIHNhbF9GYWxzZSApOwogICAgICAgIGNvbnN0IHNhbF91SW50MzIgbkNvdW50ID0gX3BQYXJlbnROb2RlLT5jb3VudCgpOwogICAgICAgIHNhbF91SW50MzIgaSA9IDA7CiAgICAgICAgZm9yKDsgaSA8IG5Db3VudDsrK2kpCiAgICAgICAgewogICAgICAgICAgICBpZiAoIF9wUGFyZW50Tm9kZS0+Z2V0Q2hpbGQoaSkgPT0gX3BQYXJzZU5vZGUgKQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIHNhbF9JbnQzMiBuVHlwZSA9IDo6Y29ubmVjdGl2aXR5OjpPU1FMUGFyc2VyOjpnZXRGdW5jdGlvblBhcmFtZXRlclR5cGUoIF9wUGFyZW50Tm9kZS0+Z2V0Q2hpbGQoMCktPmdldFRva2VuSUQoKSwgaS0xKTsKCgkJT1BhcnNlQ29sdW1uKiBwQ29sdW1uID0gbmV3IE9QYXJzZUNvbHVtbigJc1BhcmFtZXRlck5hbWUsCgkJCQkJCQkJCQkJCQk6OnJ0bDo6T1VTdHJpbmcoKSwKCQkJCQkJCQkJCQkJCTo6cnRsOjpPVVN0cmluZygpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOjpydGw6Ok9VU3RyaW5nKCksCgkJCQkJCQkJCQkJCQlDb2x1bW5WYWx1ZTo6TlVMTEFCTEVfVU5LTk9XTiwKCQkJCQkJCQkJCQkJCTAsCgkJCQkJCQkJCQkJCQkwLAoJCQkJCQkJCQkJCQkJblR5cGUsCgkJCQkJCQkJCQkJCQlzYWxfRmFsc2UsCgkJCQkJCQkJCQkJCQlzYWxfRmFsc2UsCgkJCQkJCQkJCQkJCQlpc0Nhc2VTZW5zaXRpdmUoKSk7CgkJcENvbHVtbi0+c2V0RnVuY3Rpb24oc2FsX1RydWUpOwoJCXBDb2x1bW4tPnNldEFnZ3JlZ2F0ZUZ1bmN0aW9uKHNhbF9UcnVlKTsKCQlwQ29sdW1uLT5zZXRSZWFsTmFtZShzRnVuY3Rpb25OYW1lKTsKCQltX2FQYXJhbWV0ZXJzLT5nZXQoKS5wdXNoX2JhY2socENvbHVtbik7Cgl9CgllbHNlCgl7CgkJc2FsX0Jvb2wgYk5vdEZvdW5kID0gc2FsX1RydWU7CgkJT1NRTENvbHVtbnM6OlZlY3Rvcjo6Y29uc3RfaXRlcmF0b3IgYUl0ZXIgPSA6OmNvbm5lY3Rpdml0eTo6ZmluZCgKICAgICAgICAgICAgbV9hU2VsZWN0Q29sdW1ucy0+Z2V0KCkuYmVnaW4oKSwKICAgICAgICAgICAgbV9hU2VsZWN0Q29sdW1ucy0+Z2V0KCkuZW5kKCksCiAgICAgICAgICAgIF9hQ29sdW1uTmFtZSw6OmNvbXBoZWxwZXI6OlVTdHJpbmdNaXhFcXVhbCggaXNDYXNlU2Vuc2l0aXZlKCkgKSAKICAgICAgICApOwoJCWlmKGFJdGVyICE9IG1fYVNlbGVjdENvbHVtbnMtPmdldCgpLmVuZCgpKQoJCXsKCQkJT1BhcnNlQ29sdW1uKiBwTmV3Q29sdW1uID0gbmV3IE9QYXJzZUNvbHVtbigqYUl0ZXIsaXNDYXNlU2Vuc2l0aXZlKCkpOwogICAgICAgICAgICBwTmV3Q29sdW1uLT5zZXROYW1lKHNQYXJhbWV0ZXJOYW1lKTsKCQkJcE5ld0NvbHVtbi0+c2V0UmVhbE5hbWUoX2FDb2x1bW5OYW1lKTsKCQkJbV9hUGFyYW1ldGVycy0+Z2V0KCkucHVzaF9iYWNrKHBOZXdDb2x1bW4pOwoJCQliTm90Rm91bmQgPSBzYWxfRmFsc2U7CgkJfQoJCWVsc2UgaWYoX2FDb2x1bW5OYW1lLmdldExlbmd0aCgpKS8vIHNlYXJjaCBpbiB0aGUgdGFibGVzIGZvciB0aGUgcmlnaHQgb25lCgkJewoKCQkJUmVmZXJlbmNlPFhQcm9wZXJ0eVNldD4geENvbHVtbiA9IGZpbmRDb2x1bW4oIF9hQ29sdW1uTmFtZSwgX2FUYWJsZVJhbmdlLCB0cnVlICk7CgoJCQlpZiAoIHhDb2x1bW4uaXMoKSApCgkJCXsKCQkJCU9QYXJzZUNvbHVtbiogcE5ld0NvbHVtbiA9IG5ldyBPUGFyc2VDb2x1bW4oeENvbHVtbixpc0Nhc2VTZW5zaXRpdmUoKSk7CgkJCQlwTmV3Q29sdW1uLT5zZXROYW1lKHNQYXJhbWV0ZXJOYW1lKTsKCQkJCXBOZXdDb2x1bW4tPnNldFJlYWxOYW1lKF9hQ29sdW1uTmFtZSk7CgkJCQltX2FQYXJhbWV0ZXJzLT5nZXQoKS5wdXNoX2JhY2socE5ld0NvbHVtbik7CgkJCQliTm90Rm91bmQgPSBzYWxfRmFsc2U7CgkJCX0KCQl9CgkJaWYgKCBiTm90Rm91bmQgKQoJCXsKICAgICAgICAgICAgc2FsX0ludDMyIG5UeXBlID0gRGF0YVR5cGU6OlZBUkNIQVI7CiAgICAgICAgICAgIE9TUUxQYXJzZU5vZGUqIHBQYXJlbnQgPSBfcFBhcmVudE5vZGUgPyBfcFBhcmVudE5vZGUtPmdldFBhcmVudCgpIDogTlVMTDsKICAgICAgICAgICAgaWYgKCBwUGFyZW50ICYmIChTUUxfSVNSVUxFKHBQYXJlbnQsZ2VuZXJhbF9zZXRfZmN0KSB8fCBTUUxfSVNSVUxFKHBQYXJlbnQsc2V0X2ZjdF9zcGVjKSkgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjb25zdCBzYWxfdUludDMyIG5Db3VudCA9IF9wUGFyZW50Tm9kZS0+Y291bnQoKTsKICAgICAgICAgICAgICAgIHNhbF91SW50MzIgaSA9IDA7CiAgICAgICAgICAgICAgICBmb3IoOyBpIDwgbkNvdW50OysraSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoIF9wUGFyZW50Tm9kZS0+Z2V0Q2hpbGQoaSkgPT0gX3BQYXJzZU5vZGUgKQogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIG5UeXBlID0gOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZXI6OmdldEZ1bmN0aW9uUGFyYW1ldGVyVHlwZSggcFBhcmVudC0+Z2V0Q2hpbGQoMCktPmdldFRva2VuSUQoKSwgaSsxKTsKICAgICAgICAgICAgfQoKCQkJOjpydGw6Ok9VU3RyaW5nIGFOZXdDb2xOYW1lKCBnZXRVbmlxdWVDb2x1bW5OYW1lKCBzUGFyYW1ldGVyTmFtZSApICk7CgoJCQlPUGFyc2VDb2x1bW4qIHBDb2x1bW4gPSBuZXcgT1BhcnNlQ29sdW1uKGFOZXdDb2xOYW1lLAoJCQkJCQkJCQkJCQkJOjpydGw6Ok9VU3RyaW5nKCksCgkJCQkJCQkJCQkJCQk6OnJ0bDo6T1VTdHJpbmcoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDo6cnRsOjpPVVN0cmluZygpLAoJCQkJCQkJCQkJCQkJQ29sdW1uVmFsdWU6Ok5VTExBQkxFX1VOS05PV04sCgkJCQkJCQkJCQkJCQkwLAoJCQkJCQkJCQkJCQkJMCwKCQkJCQkJCQkJCQkJCW5UeXBlLAoJCQkJCQkJCQkJCQkJc2FsX0ZhbHNlLAoJCQkJCQkJCQkJCQkJc2FsX0ZhbHNlLAoJCQkJCQkJCQkJCQkJaXNDYXNlU2Vuc2l0aXZlKCkgKTsKCQkJcENvbHVtbi0+c2V0TmFtZShhTmV3Q29sTmFtZSk7CgkJCXBDb2x1bW4tPnNldFJlYWxOYW1lKHNQYXJhbWV0ZXJOYW1lKTsKCQkJbV9hUGFyYW1ldGVycy0+Z2V0KCkucHVzaF9iYWNrKHBDb2x1bW4pOwoJCX0KCX0KfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjp0cmF2ZXJzZU9uZVByZWRpY2F0ZSgKCQkJCQkJCQlPU1FMUGFyc2VOb2RlICogcENvbHVtblJlZiwKCQkJCQkJCQk6OnJ0bDo6T1VTdHJpbmcmIHJWYWx1ZSwKCQkJCQkJCQlPU1FMUGFyc2VOb2RlICogcFBhcnNlTm9kZSkKewogICAgUlRMX0xPR0ZJTEVfQ09OVEVYVF9BVVRIT1IoIGFMb2dnZXIsICJwYXJzZSIsICJPY2tlLkphbnNzZW5Ac3VuLmNvbSIsICJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OnRyYXZlcnNlT25lUHJlZGljYXRlIiApOwoJaWYgKCAhcFBhcnNlTm9kZSApCiAgICAgICAgcmV0dXJuOwoKCS8vIENvbHVtbi1OYW1lICh1bmQgVGFibGVSYW5nZSk6Cgk6OnJ0bDo6T1VTdHJpbmcgYUNvbHVtbk5hbWUsIGFUYWJsZVJhbmdlLCBzQ29sdW1uQWxpYXM7CglnZXRDb2x1bW5SYW5nZSggcENvbHVtblJlZiwgYUNvbHVtbk5hbWUsIGFUYWJsZVJhbmdlLCBzQ29sdW1uQWxpYXMpOwoKCTo6cnRsOjpPVVN0cmluZyBhTmFtZTsKCiAgICAvKmlmIChTUUxfSVNSVUxFKHBQYXJzZU5vZGUscGFyYW1ldGVyKSkKCQl0cmF2ZXJzZVBhcmFtZXRlciggcFBhcnNlTm9kZSwgcENvbHVtblJlZiwgYUNvbHVtbk5hbWUsIGFUYWJsZVJhbmdlLCBzQ29sdW1uQWxpYXMgKTsKCWVsc2UgKi9pZiAoU1FMX0lTUlVMRShwUGFyc2VOb2RlLGNvbHVtbl9yZWYpKS8vIENvbHVtbi1OYW1lICh1bmQgVGFibGVSYW5nZSk6CgkJZ2V0Q29sdW1uUmFuZ2UocFBhcnNlTm9kZSxhTmFtZSxyVmFsdWUpOwoJZWxzZQoJewoJCXRyYXZlcnNlT1JDcml0ZXJpYShwUGFyc2VOb2RlKTsKCQkvLwlpZiAoISBhSXRlcmF0b3JTdGF0dXMuSXNTdWNjZXNzZnVsKCkpIHJldHVybjsKCX0KfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIE9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6dHJhdmVyc2VTb21lKCBzYWxfdUludDMyIF9uSW5jbHVkZU1hc2sgKQp7CiAgICBSVExfTE9HRklMRV9DT05URVhUX0FVVEhPUiggYUxvZ2dlciwgInBhcnNlIiwgIk9ja2UuSmFuc3NlbkBzdW4uY29tIiwgIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6dHJhdmVyc2VTb21lIiApOwogICAgaW1wbF90cmF2ZXJzZSggX25JbmNsdWRlTWFzayApOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjp0cmF2ZXJzZUFsbCgpCnsKICAgIFJUTF9MT0dGSUxFX0NPTlRFWFRfQVVUSE9SKCBhTG9nZ2VyLCAicGFyc2UiLCAiT2NrZS5KYW5zc2VuQHN1bi5jb20iLCAiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjp0cmF2ZXJzZUFsbCIgKTsKICAgIGltcGxfdHJhdmVyc2UoIEFsbCApOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjppbXBsX3RyYXZlcnNlKCBzYWxfdUludDMyIF9uSW5jbHVkZU1hc2sgKQp7CiAgICBSVExfTE9HRklMRV9DT05URVhUX0FVVEhPUiggYUxvZ2dlciwgInBhcnNlIiwgIk9ja2UuSmFuc3NlbkBzdW4uY29tIiwgIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6aW1wbF90cmF2ZXJzZSIgKTsKICAgIGltcGxfcmVzZXRFcnJvcnMoKTsKICAgIG1fcEltcGwtPm1fbkluY2x1ZGVNYXNrID0gX25JbmNsdWRlTWFzazsKCglpZiAoICF0cmF2ZXJzZVRhYmxlTmFtZXMoICptX3BJbXBsLT5tX3BUYWJsZXMgKSApCiAgICAgICAgcmV0dXJuOwoKICAgIHN3aXRjaCAoIG1fZVN0YXRlbWVudFR5cGUgKQogICAgewogICAgY2FzZSBTUUxfU1RBVEVNRU5UX1NFTEVDVDoKCXsKCQljb25zdCBPU1FMUGFyc2VOb2RlKiBwU2VsZWN0Tm9kZSA9IG1fcFBhcnNlVHJlZTsKICAgICAgICB0cmF2ZXJzZVBhcmFtZXRlcnMoIHBTZWxlY3ROb2RlICk7CgkJaWYgICggICAhdHJhdmVyc2VTZWxlY3RDb2x1bW5OYW1lcyggcFNlbGVjdE5vZGUgKQogICAgICAgICAgICB8fCAgIXRyYXZlcnNlT3JkZXJCeUNvbHVtbk5hbWVzKCBwU2VsZWN0Tm9kZSApCiAgICAgICAgICAgIHx8ICAhdHJhdmVyc2VHcm91cEJ5Q29sdW1uTmFtZXMoIHBTZWxlY3ROb2RlICkKICAgICAgICAgICAgfHwgICF0cmF2ZXJzZVNlbGVjdGlvbkNyaXRlcmlhKCBwU2VsZWN0Tm9kZSApCiAgICAgICAgICAgICkKICAgICAgICAgICAgcmV0dXJuOwoJfQogICAgYnJlYWs7CiAgICBjYXNlIFNRTF9TVEFURU1FTlRfQ1JFQVRFX1RBQkxFOgogICAgewogICAgICAgIC8vMCAgICAgfCAgMSAgfCAgMiAgIHwzfCAgICAgICAgNCAgICAgICAgIHw1IAogICAgICAgIC8vY3JlYXRlIHRhYmxlIHNjLmZvbyAoIGEgY2hhcigyMCksIGIgY2hhciApICAKCQljb25zdCBPU1FMUGFyc2VOb2RlKiBwQ3JlYXRlTm9kZSA9IG1fcFBhcnNlVHJlZS0+Z2V0Q2hpbGQoNCk7CgkJdHJhdmVyc2VDcmVhdGVDb2x1bW5zKHBDcmVhdGVOb2RlKTsKCX0KICAgIGJyZWFrOwogICAgY2FzZSBTUUxfU1RBVEVNRU5UX0lOU0VSVDoKICAgICAgICBicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgICAgYnJlYWs7CiAgICB9Cn0KCi8vIER1bW15LUltcGxlbWVudGF0aW9uZW46CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCk9TUUxUYWJsZSBPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OmltcGxfY3JlYXRlVGFibGVPYmplY3QoIGNvbnN0IDo6cnRsOjpPVVN0cmluZyYgclRhYmxlTmFtZSwKICAgIGNvbnN0IDo6cnRsOjpPVVN0cmluZyYgckNhdGFsb2dOYW1lLCBjb25zdCA6OnJ0bDo6T1VTdHJpbmcmIHJTY2hlbWFOYW1lICkKewogICAgUlRMX0xPR0ZJTEVfQ09OVEVYVF9BVVRIT1IoIGFMb2dnZXIsICJwYXJzZSIsICJPY2tlLkphbnNzZW5Ac3VuLmNvbSIsICJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OmltcGxfY3JlYXRlVGFibGVPYmplY3QiICk7CiAgICBPU0xfUFJFQ09ORCggbV9lU3RhdGVtZW50VHlwZSA9PSBTUUxfU1RBVEVNRU5UX0NSRUFURV9UQUJMRSwKICAgICAgICAiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjppbXBsX2NyZWF0ZVRhYmxlT2JqZWN0OiBvbmx5IHRvIGJlIGNhbGxlZCBmb3IgQ1JFQVRFIFRBQkxFIHN0YXRlbWVudHMhIiApOwogICAgICAgIC8vIChpbiBhbGwgb3RoZXIgY2FzZXMsIG1fcFRhYmxlcyBpcyB0byBjb250YWluIHRoZSB0YWJsZSBvYmplY3RzIGFzIG9idGFpbmVkIGZyb20gdGhlIHRhYmxlcwogICAgICAgIC8vIGNvbnRhaW5lciBvZiB0aGUgY29ubmVjdGlvbiAobV94VGFibGVzQ29udGFpbmVyKQoJCiAgICBPU1FMVGFibGUgYVJldHVyblRhYmxlID0gbmV3IE9UYWJsZSgKICAgICAgICBOVUxMLAogICAgICAgIHNhbF9GYWxzZSwKICAgICAgICByVGFibGVOYW1lLAogICAgICAgIDo6cnRsOjpPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCJUYWJsZSIpLAogICAgICAgIDo6cnRsOjpPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCJOZXcgQ3JlYXRlZCBUYWJsZSIpLAogICAgICAgIHJTY2hlbWFOYW1lLAogICAgICAgIHJDYXRhbG9nTmFtZQogICAgKTsKICAgIHJldHVybiBhUmV0dXJuVGFibGU7Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIE9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6YXBwZW5kQ29sdW1ucyg6OnZvczo6T1JlZjxPU1FMQ29sdW1ucz4mIF9yQ29sdW1ucyxjb25zdCA6OnJ0bDo6T1VTdHJpbmcmIF9yVGFibGVBbGlhcyxjb25zdCBPU1FMVGFibGUmIF9yVGFibGUpCnsKICAgIFJUTF9MT0dGSUxFX0NPTlRFWFRfQVVUSE9SKCBhTG9nZ2VyLCAicGFyc2UiLCAiT2NrZS5KYW5zc2VuQHN1bi5jb20iLCAiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjphcHBlbmRDb2x1bW5zIiApOwoJCglpZiAoIV9yVGFibGUuaXMoKSkKCQlyZXR1cm47CgoJUmVmZXJlbmNlPFhOYW1lQWNjZXNzPiB4Q29sdW1ucyA9IF9yVGFibGUtPmdldENvbHVtbnMoKTsKCWlmICggIXhDb2x1bW5zLmlzKCkgKQoJCXJldHVybjsKCglTZXF1ZW5jZTwgOjpydGw6Ok9VU3RyaW5nID4gYUNvbE5hbWVzID0gIHhDb2x1bW5zLT5nZXRFbGVtZW50TmFtZXMoKTsKCWNvbnN0IDo6cnRsOjpPVVN0cmluZyogcEJlZ2luID0gYUNvbE5hbWVzLmdldENvbnN0QXJyYXkoKTsKCWNvbnN0IDo6cnRsOjpPVVN0cmluZyogcEVuZCA9IHBCZWdpbiArIGFDb2xOYW1lcy5nZXRMZW5ndGgoKTsKCglmb3IoO3BCZWdpbiAhPSBwRW5kOysrcEJlZ2luKQoJewoJCQoJCTo6cnRsOjpPVVN0cmluZyBhTmFtZShnZXRVbmlxdWVDb2x1bW5OYW1lKCpwQmVnaW4pKTsKCQlSZWZlcmVuY2U8IFhQcm9wZXJ0eVNldCA+IHhDb2x1bW47CgkJaWYoeENvbHVtbnMtPmhhc0J5TmFtZSgqcEJlZ2luKSAmJiAoeENvbHVtbnMtPmdldEJ5TmFtZSgqcEJlZ2luKSA+Pj0geENvbHVtbikgJiYgeENvbHVtbi5pcygpKQoJCXsKCQkJT1BhcnNlQ29sdW1uKiBwQ29sdW1uID0gbmV3IE9QYXJzZUNvbHVtbihhTmFtZQoJCQkJCQkJCQkJCQksCWdldFN0cmluZyh4Q29sdW1uLT5nZXRQcm9wZXJ0eVZhbHVlKE9NZXRhQ29ubmVjdGlvbjo6Z2V0UHJvcE1hcCgpLmdldE5hbWVCeUluZGV4KFBST1BFUlRZX0lEX1RZUEVOQU1FKSkpCgkJCQkJCQkJCQkJCSwJZ2V0U3RyaW5nKHhDb2x1bW4tPmdldFByb3BlcnR5VmFsdWUoT01ldGFDb25uZWN0aW9uOjpnZXRQcm9wTWFwKCkuZ2V0TmFtZUJ5SW5kZXgoUFJPUEVSVFlfSURfREVGQVVMVFZBTFVFKSkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICwJZ2V0U3RyaW5nKHhDb2x1bW4tPmdldFByb3BlcnR5VmFsdWUoT01ldGFDb25uZWN0aW9uOjpnZXRQcm9wTWFwKCkuZ2V0TmFtZUJ5SW5kZXgoUFJPUEVSVFlfSURfREVTQ1JJUFRJT04pKSkKCQkJCQkJCQkJCQkJLAlnZXRJTlQzMih4Q29sdW1uLT5nZXRQcm9wZXJ0eVZhbHVlKE9NZXRhQ29ubmVjdGlvbjo6Z2V0UHJvcE1hcCgpLmdldE5hbWVCeUluZGV4KFBST1BFUlRZX0lEX0lTTlVMTEFCTEUpKSkKCQkJCQkJCQkJCQkJLAlnZXRJTlQzMih4Q29sdW1uLT5nZXRQcm9wZXJ0eVZhbHVlKE9NZXRhQ29ubmVjdGlvbjo6Z2V0UHJvcE1hcCgpLmdldE5hbWVCeUluZGV4KFBST1BFUlRZX0lEX1BSRUNJU0lPTikpKQoJCQkJCQkJCQkJCQksCWdldElOVDMyKHhDb2x1bW4tPmdldFByb3BlcnR5VmFsdWUoT01ldGFDb25uZWN0aW9uOjpnZXRQcm9wTWFwKCkuZ2V0TmFtZUJ5SW5kZXgoUFJPUEVSVFlfSURfU0NBTEUpKSkKCQkJCQkJCQkJCQkJLAlnZXRJTlQzMih4Q29sdW1uLT5nZXRQcm9wZXJ0eVZhbHVlKE9NZXRhQ29ubmVjdGlvbjo6Z2V0UHJvcE1hcCgpLmdldE5hbWVCeUluZGV4KFBST1BFUlRZX0lEX1RZUEUpKSkKCQkJCQkJCQkJCQkJLAlnZXRCT09MKHhDb2x1bW4tPmdldFByb3BlcnR5VmFsdWUoT01ldGFDb25uZWN0aW9uOjpnZXRQcm9wTWFwKCkuZ2V0TmFtZUJ5SW5kZXgoUFJPUEVSVFlfSURfSVNBVVRPSU5DUkVNRU5UKSkpCgkJCQkJCQkJCQkJCSwJZ2V0Qk9PTCh4Q29sdW1uLT5nZXRQcm9wZXJ0eVZhbHVlKE9NZXRhQ29ubmVjdGlvbjo6Z2V0UHJvcE1hcCgpLmdldE5hbWVCeUluZGV4KFBST1BFUlRZX0lEX0lTQ1VSUkVOQ1kpKSkKCQkJCQkJCQkJCQkJLAlpc0Nhc2VTZW5zaXRpdmUoKSApOwoKCQkJcENvbHVtbi0+c2V0VGFibGVOYW1lKF9yVGFibGVBbGlhcyk7CgkJCXBDb2x1bW4tPnNldFJlYWxOYW1lKCpwQmVnaW4pOwoJCQlSZWZlcmVuY2U8IFhQcm9wZXJ0eVNldD4geENvbCA9IHBDb2x1bW47CgkJCV9yQ29sdW1ucy0+Z2V0KCkucHVzaF9iYWNrKHhDb2wpOwoJCX0KCQllbHNlCiAgICAgICAgICAgIGltcGxfYXBwZW5kRXJyb3IoIElQYXJzZUNvbnRleHQ6OkVSUk9SX0lOVkFMSURfQ09MVU1OLCBwQmVnaW4sICZfclRhYmxlQWxpYXMgKTsKCX0JIAp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OnNldFNlbGVjdENvbHVtbk5hbWUoOjp2b3M6Ok9SZWY8T1NRTENvbHVtbnM+JiBfckNvbHVtbnMsY29uc3QgOjpydGw6Ok9VU3RyaW5nICYgckNvbHVtbk5hbWUsY29uc3QgOjpydGw6Ok9VU3RyaW5nICYgckNvbHVtbkFsaWFzLCBjb25zdCA6OnJ0bDo6T1VTdHJpbmcgJiByVGFibGVSYW5nZSxzYWxfQm9vbCBiRmt0LHNhbF9JbnQzMiBfblR5cGUsc2FsX0Jvb2wgYkFnZ0ZrdCkKewogICAgUlRMX0xPR0ZJTEVfQ09OVEVYVF9BVVRIT1IoIGFMb2dnZXIsICJwYXJzZSIsICJPY2tlLkphbnNzZW5Ac3VuLmNvbSIsICJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OnNldFNlbGVjdENvbHVtbk5hbWUiICk7CglpZihyQ29sdW1uTmFtZS50b0NoYXIoKSA9PSAnKicgJiYgIXJUYWJsZVJhbmdlLmdldExlbmd0aCgpKQoJeyAgIC8vIFNFTEVDVCAqIC4uLgoJCU9TTF9FTlNVUkUoX3JDb2x1bW5zID09IG1fYVNlbGVjdENvbHVtbnMsIkludmFsaWQgY29sdW1ucyB1c2VkIGhlcmUhIik7CgkJZm9yKENvbnN0T1NRTFRhYmxlc0l0ZXJhdG9yIGFJdGVyID0gbV9wSW1wbC0+bV9wVGFibGVzLT5iZWdpbigpOyBhSXRlciAhPSBtX3BJbXBsLT5tX3BUYWJsZXMtPmVuZCgpOysrYUl0ZXIpCgkJCWFwcGVuZENvbHVtbnMoX3JDb2x1bW5zLGFJdGVyLT5maXJzdCxhSXRlci0+c2Vjb25kKTsKCX0KCWVsc2UgaWYoIHJDb2x1bW5OYW1lLnRvQ2hhcigpID09ICcqJyAmJiByVGFibGVSYW5nZS5nZXRMZW5ndGgoKSApCgl7ICAgLy8gU0VMRUNUIDx0YWJsZT4uKgoJCU9TTF9FTlNVUkUoX3JDb2x1bW5zID09IG1fYVNlbGVjdENvbHVtbnMsIkludmFsaWQgY29sdW1ucyB1c2VkIGhlcmUhIik7CgkJQ29uc3RPU1FMVGFibGVzSXRlcmF0b3IgYUZpbmQgPSBtX3BJbXBsLT5tX3BUYWJsZXMtPmZpbmQoclRhYmxlUmFuZ2UpOwoKCQlpZihhRmluZCAhPSBtX3BJbXBsLT5tX3BUYWJsZXMtPmVuZCgpKQoJCQlhcHBlbmRDb2x1bW5zKF9yQ29sdW1ucyxyVGFibGVSYW5nZSxhRmluZC0+c2Vjb25kKTsKCX0KCWVsc2UgaWYgKCAhclRhYmxlUmFuZ2UuZ2V0TGVuZ3RoKCkgKQoJeyAgIC8vIFNFTEVDVCA8c29tZXRoaW5nPiAuLi4KICAgICAgICAvLyB3aXRob3V0IHRhYmxlIHNwZWNpZmllZAoJCWlmICggIWJGa3QgKQoJCXsKCQkJUmVmZXJlbmNlPCBYUHJvcGVydHlTZXQ+IHhOZXdDb2x1bW47CgogICAgICAgICAgICBmb3IgKCBPU1FMVGFibGVzSXRlcmF0b3IgYUl0ZXIgPSBtX3BJbXBsLT5tX3BUYWJsZXMtPmJlZ2luKCk7IGFJdGVyICE9IG1fcEltcGwtPm1fcFRhYmxlcy0+ZW5kKCk7ICsrYUl0ZXIgKQoJCQl7CgkJCQlpZiAoICFhSXRlci0+c2Vjb25kLmlzKCkgKQogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwoKICAgICAgICAgICAgICAgIFJlZmVyZW5jZTxYTmFtZUFjY2Vzcz4geENvbHVtbnMgPSBhSXRlci0+c2Vjb25kLT5nZXRDb2x1bW5zKCk7CgkJCQlSZWZlcmVuY2U8IFhQcm9wZXJ0eVNldCA+IHhDb2x1bW47IAoJCQkJaWYgICggICAheENvbHVtbnMtPmhhc0J5TmFtZSggckNvbHVtbk5hbWUgKQogICAgICAgICAgICAgICAgICAgIHx8ICAhKCB4Q29sdW1ucy0+Z2V0QnlOYW1lKCByQ29sdW1uTmFtZSApID4+PSB4Q29sdW1uICkKICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CgogICAgICAgICAgICAgICAgOjpydGw6Ok9VU3RyaW5nIGFOZXdDb2xOYW1lKGdldFVuaXF1ZUNvbHVtbk5hbWUockNvbHVtbkFsaWFzKSk7CgoJCQkJT1BhcnNlQ29sdW1uKiBwQ29sdW1uID0gbmV3IE9QYXJzZUNvbHVtbih4Q29sdW1uLGlzQ2FzZVNlbnNpdGl2ZSgpKTsKCQkJCXhOZXdDb2x1bW4gPSBwQ29sdW1uOwoJCQkJcENvbHVtbi0+c2V0VGFibGVOYW1lKGFJdGVyLT5maXJzdCk7CgkJCQlwQ29sdW1uLT5zZXROYW1lKGFOZXdDb2xOYW1lKTsKCQkJCXBDb2x1bW4tPnNldFJlYWxOYW1lKHJDb2x1bW5OYW1lKTsKCgkJCQlicmVhazsKCQkJfQoKICAgICAgICAgICAgaWYgKCAheE5ld0NvbHVtbi5pcygpICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy8gbm8gZnVuY3Rpb24gKGR1ZSB0byB0aGUgYWJvdmUgIWJGa3QpLCBubyBleGlzdGluZyBjb2x1bW4KICAgICAgICAgICAgICAgIC8vID0+IGFzc3VtZSBhbiBleHByZXNzaW9uCiAgICAgICAgICAgICAgICA6OnJ0bDo6T1VTdHJpbmcgYU5ld0NvbE5hbWUoIGdldFVuaXF1ZUNvbHVtbk5hbWUoIHJDb2x1bW5BbGlhcyApICk7CiAgICAgICAgICAgICAgICAvLyBkaWQgbm90IGZpbmQgYSBjb2x1bW4gd2l0aCB0aGlzIG5hbWUgaW4gYW55IG9mIHRoZSB0YWJsZXMKCQkJICAgIE9QYXJzZUNvbHVtbiogcENvbHVtbiA9IG5ldyBPUGFyc2VDb2x1bW4oCiAgICAgICAgICAgICAgICAgICAgYU5ld0NvbE5hbWUsCiAgICAgICAgICAgICAgICAgICAgOjpydGw6Ok9VU3RyaW5nOjpjcmVhdGVGcm9tQXNjaWkoICJWQVJDSEFSIiApLAogICAgICAgICAgICAgICAgICAgICAgICAvLyBUT0RPOiBkb2VzIHRoaXMgbWF0Y2ggd2l0aCBfblR5cGU/CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9yIHNob3VsZCBiZSBmaWxsIHRoaXMgZnJvbSB0aGUgZ2V0VHlwZUluZm8gb2YgdGhlIGNvbm5lY3Rpb24/CiAgICAgICAgICAgICAgICAgICAgOjpydGw6Ok9VU3RyaW5nKCksCiAgICAgICAgICAgICAgICAgICAgOjpydGw6Ok9VU3RyaW5nKCksCiAgICAgICAgICAgICAgICAgICAgQ29sdW1uVmFsdWU6Ok5VTExBQkxFX1VOS05PV04sCiAgICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICAgIF9uVHlwZSwKICAgICAgICAgICAgICAgICAgICBzYWxfRmFsc2UsCiAgICAgICAgICAgICAgICAgICAgc2FsX0ZhbHNlLAogICAgICAgICAgICAgICAgICAgIGlzQ2FzZVNlbnNpdGl2ZSgpCiAgICAgICAgICAgICAgICApOwoKICAgICAgICAgICAgICAgIHhOZXdDb2x1bW4gPSBwQ29sdW1uOwoJCQkgICAgcENvbHVtbi0+c2V0UmVhbE5hbWUoIHJDb2x1bW5OYW1lICk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIF9yQ29sdW1ucy0+Z2V0KCkucHVzaF9iYWNrKCB4TmV3Q29sdW1uICk7CgkJfQoJCWVsc2UKCQl7CgkJCTo6cnRsOjpPVVN0cmluZyBhTmV3Q29sTmFtZShnZXRVbmlxdWVDb2x1bW5OYW1lKHJDb2x1bW5BbGlhcykpOwoKCQkJT1BhcnNlQ29sdW1uKiBwQ29sdW1uID0gbmV3IE9QYXJzZUNvbHVtbihhTmV3Q29sTmFtZSw6OnJ0bDo6T1VTdHJpbmcoKSw6OnJ0bDo6T1VTdHJpbmcoKSw6OnJ0bDo6T1VTdHJpbmcoKSwKCQkJCUNvbHVtblZhbHVlOjpOVUxMQUJMRV9VTktOT1dOLDAsMCxfblR5cGUsc2FsX0ZhbHNlLHNhbF9GYWxzZSxpc0Nhc2VTZW5zaXRpdmUoKSk7CgkJCXBDb2x1bW4tPnNldEZ1bmN0aW9uKHNhbF9UcnVlKTsKCQkJcENvbHVtbi0+c2V0QWdncmVnYXRlRnVuY3Rpb24oYkFnZ0ZrdCk7CgkJCXBDb2x1bW4tPnNldFJlYWxOYW1lKHJDb2x1bW5OYW1lKTsKCgkJCVJlZmVyZW5jZTwgWFByb3BlcnR5U2V0PiB4Q29sID0gcENvbHVtbjsKCQkJX3JDb2x1bW5zLT5nZXQoKS5wdXNoX2JhY2soeENvbCk7CgkJfQoJfQoJZWxzZQkvLyBDb2x1bW5OYW1lIHVuZCBUYWJsZW5hbWUgdm9yaGFuZGVuCgl7CgkJQ29uc3RPU1FMVGFibGVzSXRlcmF0b3IgYUZpbmQgPSBtX3BJbXBsLT5tX3BUYWJsZXMtPmZpbmQoclRhYmxlUmFuZ2UpOwoKCQlzYWxfQm9vbCBiRXJyb3IgPSBzYWxfRmFsc2U7CgkJaWYgKGFGaW5kICE9IG1fcEltcGwtPm1fcFRhYmxlcy0+ZW5kKCkgJiYgYUZpbmQtPnNlY29uZC5pcygpKQoJCXsKCQkJaWYgKGJGa3QpCgkJCXsKCQkJCTo6cnRsOjpPVVN0cmluZyBhTmV3Q29sTmFtZShnZXRVbmlxdWVDb2x1bW5OYW1lKHJDb2x1bW5BbGlhcykpOwoKCQkJCU9QYXJzZUNvbHVtbiogcENvbHVtbiA9IG5ldyBPUGFyc2VDb2x1bW4oYU5ld0NvbE5hbWUsOjpydGw6Ok9VU3RyaW5nKCksOjpydGw6Ok9VU3RyaW5nKCksOjpydGw6Ok9VU3RyaW5nKCksCgkJCQkJQ29sdW1uVmFsdWU6Ok5VTExBQkxFX1VOS05PV04sMCwwLF9uVHlwZSxzYWxfRmFsc2Usc2FsX0ZhbHNlLGlzQ2FzZVNlbnNpdGl2ZSgpKTsKCQkJCXBDb2x1bW4tPnNldEZ1bmN0aW9uKHNhbF9UcnVlKTsKCQkJCXBDb2x1bW4tPnNldEFnZ3JlZ2F0ZUZ1bmN0aW9uKGJBZ2dGa3QpOwoJCQkJcENvbHVtbi0+c2V0UmVhbE5hbWUockNvbHVtbk5hbWUpOwoJCQkJcENvbHVtbi0+c2V0VGFibGVOYW1lKGFGaW5kLT5maXJzdCk7CgoJCQkJUmVmZXJlbmNlPCBYUHJvcGVydHlTZXQ+IHhDb2wgPSBwQ29sdW1uOwoJCQkJX3JDb2x1bW5zLT5nZXQoKS5wdXNoX2JhY2soeENvbCk7CgkJCX0KCQkJZWxzZQoJCQl7CgkJCQlSZWZlcmVuY2U8IFhQcm9wZXJ0eVNldCA+IHhDb2x1bW47CgkJCQlpZiAoYUZpbmQtPnNlY29uZC0+Z2V0Q29sdW1ucygpLT5oYXNCeU5hbWUockNvbHVtbk5hbWUpICYmIChhRmluZC0+c2Vjb25kLT5nZXRDb2x1bW5zKCktPmdldEJ5TmFtZShyQ29sdW1uTmFtZSkgPj49IHhDb2x1bW4pKQoJCQkJewoJCQkJCTo6cnRsOjpPVVN0cmluZyBhTmV3Q29sTmFtZShnZXRVbmlxdWVDb2x1bW5OYW1lKHJDb2x1bW5BbGlhcykpOwoKCQkJCQlPUGFyc2VDb2x1bW4qIHBDb2x1bW4gPSBuZXcgT1BhcnNlQ29sdW1uKHhDb2x1bW4saXNDYXNlU2Vuc2l0aXZlKCkpOwoJCQkJCXBDb2x1bW4tPnNldE5hbWUoYU5ld0NvbE5hbWUpOwoJCQkJCXBDb2x1bW4tPnNldFJlYWxOYW1lKHJDb2x1bW5OYW1lKTsKCQkJCQlwQ29sdW1uLT5zZXRUYWJsZU5hbWUoYUZpbmQtPmZpcnN0KTsKCgkJCQkJUmVmZXJlbmNlPCBYUHJvcGVydHlTZXQ+IHhDb2wgPSBwQ29sdW1uOwoJCQkJCV9yQ29sdW1ucy0+Z2V0KCkucHVzaF9iYWNrKHhDb2wpOwoJCQkJfQoJCQkJZWxzZQoJCQkJCWJFcnJvciA9IHNhbF9UcnVlOwoJCQl9CgkJfQoJCWVsc2UKCQkJYkVycm9yID0gc2FsX1RydWU7CgoJCS8vIFRhYmVsbGUgZXhpc3RpZXJ0IG5pY2h0IG9kZXIgRmVsZCBuaWNodCB2b3JoYW5kZW4KCQlpZiAoYkVycm9yKQoJCXsKCQkJOjpydGw6Ok9VU3RyaW5nIGFOZXdDb2xOYW1lKGdldFVuaXF1ZUNvbHVtbk5hbWUockNvbHVtbkFsaWFzKSk7CgoJCQlPUGFyc2VDb2x1bW4qIHBDb2x1bW4gPSBuZXcgT1BhcnNlQ29sdW1uKGFOZXdDb2xOYW1lLDo6cnRsOjpPVVN0cmluZygpLDo6cnRsOjpPVVN0cmluZygpLDo6cnRsOjpPVVN0cmluZygpLAoJCQkJQ29sdW1uVmFsdWU6Ok5VTExBQkxFX1VOS05PV04sMCwwLERhdGFUeXBlOjpWQVJDSEFSLHNhbF9GYWxzZSxzYWxfRmFsc2UsaXNDYXNlU2Vuc2l0aXZlKCkpOwoJCQlwQ29sdW1uLT5zZXRGdW5jdGlvbihzYWxfVHJ1ZSk7CgkJCXBDb2x1bW4tPnNldEFnZ3JlZ2F0ZUZ1bmN0aW9uKGJBZ2dGa3QpOwkJCQoKCQkJUmVmZXJlbmNlPCBYUHJvcGVydHlTZXQ+IHhDb2wgPSBwQ29sdW1uOwoJCQlfckNvbHVtbnMtPmdldCgpLnB1c2hfYmFjayh4Q29sKTsKCQl9Cgl9Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQo6OnJ0bDo6T1VTdHJpbmcgT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjpnZXRVbmlxdWVDb2x1bW5OYW1lKGNvbnN0IDo6cnRsOjpPVVN0cmluZyAmIHJDb2x1bW5OYW1lKQljb25zdAp7CiAgICBSVExfTE9HRklMRV9DT05URVhUX0FVVEhPUiggYUxvZ2dlciwgInBhcnNlIiwgIk9ja2UuSmFuc3NlbkBzdW4uY29tIiwgIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6Z2V0VW5pcXVlQ29sdW1uTmFtZSIgKTsKCTo6cnRsOjpPVVN0cmluZyBhQWxpYXMockNvbHVtbk5hbWUpOwoKCU9TUUxDb2x1bW5zOjpWZWN0b3I6OmNvbnN0X2l0ZXJhdG9yIGFJdGVyID0gZmluZCgKICAgICAgICBtX2FTZWxlY3RDb2x1bW5zLT5nZXQoKS5iZWdpbigpLAogICAgICAgIG1fYVNlbGVjdENvbHVtbnMtPmdldCgpLmVuZCgpLAogICAgICAgIGFBbGlhcywKICAgICAgICA6OmNvbXBoZWxwZXI6OlVTdHJpbmdNaXhFcXVhbCggaXNDYXNlU2Vuc2l0aXZlKCkgKQogICAgKTsKCXNhbF9JbnQzMiBpPTE7Cgl3aGlsZShhSXRlciAhPSBtX2FTZWxlY3RDb2x1bW5zLT5nZXQoKS5lbmQoKSkKCXsKCQkoYUFsaWFzID0gckNvbHVtbk5hbWUpICs9IDo6cnRsOjpPVVN0cmluZzo6dmFsdWVPZihpKyspOwoJCWFJdGVyID0gZmluZCgKICAgICAgICAgICAgbV9hU2VsZWN0Q29sdW1ucy0+Z2V0KCkuYmVnaW4oKSwKICAgICAgICAgICAgbV9hU2VsZWN0Q29sdW1ucy0+Z2V0KCkuZW5kKCksCiAgICAgICAgICAgIGFBbGlhcywKICAgICAgICAgICAgOjpjb21waGVscGVyOjpVU3RyaW5nTWl4RXF1YWwoIGlzQ2FzZVNlbnNpdGl2ZSgpICkKICAgICAgICApOwoJfQoJcmV0dXJuIGFBbGlhczsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjpzZXRPcmRlckJ5Q29sdW1uTmFtZShjb25zdCA6OnJ0bDo6T1VTdHJpbmcgJiByQ29sdW1uTmFtZSwgY29uc3QgOjpydGw6Ok9VU3RyaW5nICYgclRhYmxlUmFuZ2Usc2FsX0Jvb2wgYkFzY2VuZGluZykKewogICAgUlRMX0xPR0ZJTEVfQ09OVEVYVF9BVVRIT1IoIGFMb2dnZXIsICJwYXJzZSIsICJPY2tlLkphbnNzZW5Ac3VuLmNvbSIsICJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OnNldE9yZGVyQnlDb2x1bW5OYW1lIiApOwoJUmVmZXJlbmNlPFhQcm9wZXJ0eVNldD4geENvbHVtbiA9IGZpbmRDb2x1bW4oIHJDb2x1bW5OYW1lLCByVGFibGVSYW5nZSwgZmFsc2UgKTsKCWlmICggeENvbHVtbi5pcygpICkKCQltX2FPcmRlckNvbHVtbnMtPmdldCgpLnB1c2hfYmFjayhuZXcgT09yZGVyQ29sdW1uKCB4Q29sdW1uLCByVGFibGVSYW5nZSwgaXNDYXNlU2Vuc2l0aXZlKCksIGJBc2NlbmRpbmcgKSApOwoJZWxzZSAKCXsKCQlzYWxfSW50MzIgbklkID0gckNvbHVtbk5hbWUudG9JbnQzMigpOwoJCWlmICggbklkID4gMCAmJiBuSWQgPCBzdGF0aWNfY2FzdDxzYWxfSW50MzI+KG1fYVNlbGVjdENvbHVtbnMtPmdldCgpLnNpemUoKSkgKQogICAgICAgICAgICBtX2FPcmRlckNvbHVtbnMtPmdldCgpLnB1c2hfYmFjayggbmV3IE9PcmRlckNvbHVtbiggKCBtX2FTZWxlY3RDb2x1bW5zLT5nZXQoKSApW25JZC0xXSwgaXNDYXNlU2Vuc2l0aXZlKCksIGJBc2NlbmRpbmcgKSApOwoJfQoKI2lmZGVmIFNRTF9URVNUX1BBUlNFVFJFRUlURVJBVE9SCgljb3V0IDw8ICJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OnNldE9yZGVyQnlDb2x1bW5OYW1lOiAiCgkJIDw8IChjb25zdCBjaGFyICopIHJDb2x1bW5OYW1lIDw8ICIsICIKCQkgPDwgKGNvbnN0IGNoYXIgKikgclRhYmxlUmFuZ2UgPDwgIiwgIgoJCSA8PCAoYkFzY2VuZGluZyA/ICJzYWxfVHJ1ZSIgOiAic2FsX0ZhbHNlIikKCQkgPDwgIlxuIjsKI2VuZGlmCn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIE9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6c2V0R3JvdXBCeUNvbHVtbk5hbWUoY29uc3QgOjpydGw6Ok9VU3RyaW5nICYgckNvbHVtbk5hbWUsIGNvbnN0IDo6cnRsOjpPVVN0cmluZyAmIHJUYWJsZVJhbmdlKQp7CiAgICBSVExfTE9HRklMRV9DT05URVhUX0FVVEhPUiggYUxvZ2dlciwgInBhcnNlIiwgIk9ja2UuSmFuc3NlbkBzdW4uY29tIiwgIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6c2V0R3JvdXBCeUNvbHVtbk5hbWUiICk7CglSZWZlcmVuY2U8WFByb3BlcnR5U2V0PiB4Q29sdW1uID0gZmluZENvbHVtbiggckNvbHVtbk5hbWUsIHJUYWJsZVJhbmdlLCBmYWxzZSApOwoJaWYgKCB4Q29sdW1uLmlzKCkgKQoJCW1fYUdyb3VwQ29sdW1ucy0+Z2V0KCkucHVzaF9iYWNrKG5ldyBPUGFyc2VDb2x1bW4oeENvbHVtbixpc0Nhc2VTZW5zaXRpdmUoKSkpOwoJZWxzZSAKCXsKCQlzYWxfSW50MzIgbklkID0gckNvbHVtbk5hbWUudG9JbnQzMigpOwoJCWlmICggbklkID4gMCAmJiBuSWQgPCBzdGF0aWNfY2FzdDxzYWxfSW50MzI+KG1fYVNlbGVjdENvbHVtbnMtPmdldCgpLnNpemUoKSkgKQoJCQltX2FHcm91cENvbHVtbnMtPmdldCgpLnB1c2hfYmFjayhuZXcgT1BhcnNlQ29sdW1uKChtX2FTZWxlY3RDb2x1bW5zLT5nZXQoKSlbbklkLTFdLGlzQ2FzZVNlbnNpdGl2ZSgpKSk7Cgl9CgojaWZkZWYgU1FMX1RFU1RfUEFSU0VUUkVFSVRFUkFUT1IKCWNvdXQgPDwgIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6c2V0T3JkZXJCeUNvbHVtbk5hbWU6ICIKCQkgPDwgKGNvbnN0IGNoYXIgKikgckNvbHVtbk5hbWUgPDwgIiwgIgoJCSA8PCAoY29uc3QgY2hhciAqKSByVGFibGVSYW5nZSA8PCAiLCAiCgkJIDw8IChiQXNjZW5kaW5nID8gInNhbF9UcnVlIiA6ICJzYWxfRmFsc2UiKQoJCSA8PCAiXG4iOwojZW5kaWYKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpjb25zdCBPU1FMUGFyc2VOb2RlKiBPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OmdldFdoZXJlVHJlZSgpIGNvbnN0CnsKICAgIFJUTF9MT0dGSUxFX0NPTlRFWFRfQVVUSE9SKCBhTG9nZ2VyLCAicGFyc2UiLCAiT2NrZS5KYW5zc2VuQHN1bi5jb20iLCAiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjpnZXRXaGVyZVRyZWUiICk7CgkKCglpZiAoIW1fcFBhcnNlVHJlZSkKCQlyZXR1cm4gTlVMTDsKCgkvLyBQYXJzZSBUcmVlIGFuYWx5c2llcmVuIChqZSBuYWNoIFN0YXRlbWVudC1UeXApCgkvLyB1bmQgWmVpZ2VyIGF1ZiBXSEVSRS1LbGF1c2VsIHNldHplbjoKCU9TUUxQYXJzZU5vZGUgKiBwV2hlcmVDbGF1c2UgPSBOVUxMOwoJaWYoZ2V0U3RhdGVtZW50VHlwZSgpID09IFNRTF9TVEFURU1FTlRfU0VMRUNUKQoJewoJCU9TTF9FTlNVUkUobV9wUGFyc2VUcmVlLT5jb3VudCgpID49IDQsIlBhcnNlVHJlZUl0ZXJhdG9yOiBlcnJvciBpbiBwYXJzZSB0cmVlISIpOwoJCU9TUUxQYXJzZU5vZGUgKiBwVGFibGVFeHAgPSBtX3BQYXJzZVRyZWUtPmdldENoaWxkKDMpOwoJCU9TTF9FTlNVUkUocFRhYmxlRXhwICE9IE5VTEwsIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjogZXJyb3IgaW4gcGFyc2UgdHJlZSEiKTsKCQlPU0xfRU5TVVJFKFNRTF9JU1JVTEUocFRhYmxlRXhwLHRhYmxlX2V4cCksIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjogZXJyb3IgaW4gcGFyc2UgdHJlZSEiKTsKCQlPU0xfRU5TVVJFKHBUYWJsZUV4cC0+Y291bnQoKSA9PSBUQUJMRV9FWFBSRVNTSU9OX0NISUxEX0NPVU5ULCJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6IGVycm9yIGluIHBhcnNlIHRyZWUhIik7CgoJCXBXaGVyZUNsYXVzZSA9IHBUYWJsZUV4cC0+Z2V0Q2hpbGQoMSk7Cgl9CgllbHNlIGlmIChTUUxfSVNSVUxFKG1fcFBhcnNlVHJlZSx1cGRhdGVfc3RhdGVtZW50X3NlYXJjaGVkKSB8fAoJCQkgU1FMX0lTUlVMRShtX3BQYXJzZVRyZWUsZGVsZXRlX3N0YXRlbWVudF9zZWFyY2hlZCkpCgl7CgkJcFdoZXJlQ2xhdXNlID0gbV9wUGFyc2VUcmVlLT5nZXRDaGlsZChtX3BQYXJzZVRyZWUtPmNvdW50KCktMSk7Cgl9CglpZihwV2hlcmVDbGF1c2UtPmNvdW50KCkgIT0gMikKCQlwV2hlcmVDbGF1c2UgPSBOVUxMOwoJcmV0dXJuIHBXaGVyZUNsYXVzZTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpjb25zdCBPU1FMUGFyc2VOb2RlKiBPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OmdldE9yZGVyVHJlZSgpIGNvbnN0CnsKICAgIFJUTF9MT0dGSUxFX0NPTlRFWFRfQVVUSE9SKCBhTG9nZ2VyLCAicGFyc2UiLCAiT2NrZS5KYW5zc2VuQHN1bi5jb20iLCAiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjpnZXRPcmRlclRyZWUiICk7CgkKCglpZiAoIW1fcFBhcnNlVHJlZSB8fCBnZXRTdGF0ZW1lbnRUeXBlKCkgIT0gU1FMX1NUQVRFTUVOVF9TRUxFQ1QpCgkJcmV0dXJuIE5VTEw7CgoJLy8gUGFyc2UgVHJlZSBhbmFseXNpZXJlbiAoamUgbmFjaCBTdGF0ZW1lbnQtVHlwKQoJLy8gdW5kIFplaWdlciBhdWYgT1JERVItS2xhdXNlbCBzZXR6ZW46CglPU1FMUGFyc2VOb2RlICogcE9yZGVyQ2xhdXNlID0gTlVMTDsKCU9TTF9FTlNVUkUobV9wUGFyc2VUcmVlLT5jb3VudCgpID49IDQsIlBhcnNlVHJlZUl0ZXJhdG9yOiBlcnJvciBpbiBwYXJzZSB0cmVlISIpOwoJT1NRTFBhcnNlTm9kZSAqIHBUYWJsZUV4cCA9IG1fcFBhcnNlVHJlZS0+Z2V0Q2hpbGQoMyk7CglPU0xfRU5TVVJFKHBUYWJsZUV4cCAhPSBOVUxMLCJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6IGVycm9yIGluIHBhcnNlIHRyZWUhIik7CglPU0xfRU5TVVJFKFNRTF9JU1JVTEUocFRhYmxlRXhwLHRhYmxlX2V4cCksIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjogZXJyb3IgaW4gcGFyc2UgdHJlZSEiKTsKCU9TTF9FTlNVUkUocFRhYmxlRXhwLT5jb3VudCgpID09IFRBQkxFX0VYUFJFU1NJT05fQ0hJTERfQ09VTlQsIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjogZXJyb3IgaW4gcGFyc2UgdHJlZSEiKTsKCglwT3JkZXJDbGF1c2UgPSBwVGFibGVFeHAtPmdldENoaWxkKE9SREVSX0JZX0NISUxEX1BPUyk7CgkvLyBXZW5uIGVzIGFiZXIgZWluZSBvcmRlcl9ieSBpc3QsIGRhbm4gZGFyZiBzaWUgbmljaHQgbGVlciBzZWluOgoJaWYocE9yZGVyQ2xhdXNlLT5jb3VudCgpICE9IDMpCgkJcE9yZGVyQ2xhdXNlID0gTlVMTDsKCXJldHVybiBwT3JkZXJDbGF1c2U7Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpjb25zdCBPU1FMUGFyc2VOb2RlKiBPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OmdldEdyb3VwQnlUcmVlKCkgY29uc3QKewogICAgUlRMX0xPR0ZJTEVfQ09OVEVYVF9BVVRIT1IoIGFMb2dnZXIsICJwYXJzZSIsICJPY2tlLkphbnNzZW5Ac3VuLmNvbSIsICJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OmdldEdyb3VwQnlUcmVlIiApOwoJaWYgKCFtX3BQYXJzZVRyZWUgfHwgZ2V0U3RhdGVtZW50VHlwZSgpICE9IFNRTF9TVEFURU1FTlRfU0VMRUNUKQoJCXJldHVybiBOVUxMOwoKCS8vIFBhcnNlIFRyZWUgYW5hbHlzaWVyZW4gKGplIG5hY2ggU3RhdGVtZW50LVR5cCkKCS8vIHVuZCBaZWlnZXIgYXVmIE9SREVSLUtsYXVzZWwgc2V0emVuOgoJT1NRTFBhcnNlTm9kZSAqIHBHcm91cENsYXVzZSA9IE5VTEw7CglPU0xfRU5TVVJFKG1fcFBhcnNlVHJlZS0+Y291bnQoKSA+PSA0LCJQYXJzZVRyZWVJdGVyYXRvcjogZXJyb3IgaW4gcGFyc2UgdHJlZSEiKTsKCU9TUUxQYXJzZU5vZGUgKiBwVGFibGVFeHAgPSBtX3BQYXJzZVRyZWUtPmdldENoaWxkKDMpOwoJT1NMX0VOU1VSRShwVGFibGVFeHAgIT0gTlVMTCwiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOiBlcnJvciBpbiBwYXJzZSB0cmVlISIpOwoJT1NMX0VOU1VSRShTUUxfSVNSVUxFKHBUYWJsZUV4cCx0YWJsZV9leHApLCJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6IGVycm9yIGluIHBhcnNlIHRyZWUhIik7CglPU0xfRU5TVVJFKHBUYWJsZUV4cC0+Y291bnQoKSA9PSBUQUJMRV9FWFBSRVNTSU9OX0NISUxEX0NPVU5ULCJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6IGVycm9yIGluIHBhcnNlIHRyZWUhIik7CgoJcEdyb3VwQ2xhdXNlID0gcFRhYmxlRXhwLT5nZXRDaGlsZCgyKTsKCS8vIFdlbm4gZXMgYWJlciBlaW5lIG9yZGVyX2J5IGlzdCwgZGFubiBkYXJmIHNpZSBuaWNodCBsZWVyIHNlaW46CglpZihwR3JvdXBDbGF1c2UtPmNvdW50KCkgIT0gMykKCQlwR3JvdXBDbGF1c2UgPSBOVUxMOwoJcmV0dXJuIHBHcm91cENsYXVzZTsKfQkJCSAgIAovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCmNvbnN0IE9TUUxQYXJzZU5vZGUqIE9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6Z2V0SGF2aW5nVHJlZSgpIGNvbnN0CnsKCWlmICghbV9wUGFyc2VUcmVlIHx8IGdldFN0YXRlbWVudFR5cGUoKSAhPSBTUUxfU1RBVEVNRU5UX1NFTEVDVCkKCQlyZXR1cm4gTlVMTDsKCgkvLyBQYXJzZSBUcmVlIGFuYWx5c2llcmVuIChqZSBuYWNoIFN0YXRlbWVudC1UeXApCgkvLyB1bmQgWmVpZ2VyIGF1ZiBPUkRFUi1LbGF1c2VsIHNldHplbjoKCU9TUUxQYXJzZU5vZGUgKiBwSGF2aW5nQ2xhdXNlID0gTlVMTDsKCU9TTF9FTlNVUkUobV9wUGFyc2VUcmVlLT5jb3VudCgpID49IDQsIlBhcnNlVHJlZUl0ZXJhdG9yOiBlcnJvciBpbiBwYXJzZSB0cmVlISIpOwoJT1NRTFBhcnNlTm9kZSAqIHBUYWJsZUV4cCA9IG1fcFBhcnNlVHJlZS0+Z2V0Q2hpbGQoMyk7CglPU0xfRU5TVVJFKHBUYWJsZUV4cCAhPSBOVUxMLCJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6IGVycm9yIGluIHBhcnNlIHRyZWUhIik7CglPU0xfRU5TVVJFKFNRTF9JU1JVTEUocFRhYmxlRXhwLHRhYmxlX2V4cCksIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjogZXJyb3IgaW4gcGFyc2UgdHJlZSEiKTsKCU9TTF9FTlNVUkUocFRhYmxlRXhwLT5jb3VudCgpID09IFRBQkxFX0VYUFJFU1NJT05fQ0hJTERfQ09VTlQsIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjogZXJyb3IgaW4gcGFyc2UgdHJlZSEiKTsKCglwSGF2aW5nQ2xhdXNlID0gcFRhYmxlRXhwLT5nZXRDaGlsZCgzKTsKCS8vIFdlbm4gZXMgYWJlciBlaW5lIG9yZGVyX2J5IGlzdCwgZGFubiBkYXJmIHNpZSBuaWNodCBsZWVyIHNlaW46CglpZihwSGF2aW5nQ2xhdXNlLT5jb3VudCgpIDwgMSkKCQlwSGF2aW5nQ2xhdXNlID0gTlVMTDsKCXJldHVybiBwSGF2aW5nQ2xhdXNlOwp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnNhbF9Cb29sIE9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6aXNUYWJsZU5vZGUoY29uc3QgT1NRTFBhcnNlTm9kZSogX3BUYWJsZU5vZGUpIGNvbnN0IAp7CiAgICBSVExfTE9HRklMRV9DT05URVhUX0FVVEhPUiggYUxvZ2dlciwgInBhcnNlIiwgIk9ja2UuSmFuc3NlbkBzdW4uY29tIiwgIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6aXNUYWJsZU5vZGUiICk7CglyZXR1cm4gX3BUYWJsZU5vZGUgJiYgKFNRTF9JU1JVTEUoX3BUYWJsZU5vZGUsY2F0YWxvZ19uYW1lKSB8fAoJCQkJCQkgICBTUUxfSVNSVUxFKF9wVGFibGVOb2RlLHNjaGVtYV9uYW1lKSAgfHwKCQkJCQkJICAgU1FMX0lTUlVMRShfcFRhYmxlTm9kZSx0YWJsZV9uYW1lKSk7Cn0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KY29uc3QgT1NRTFBhcnNlTm9kZSogT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjpnZXRTaW1wbGVXaGVyZVRyZWUoKSBjb25zdAp7CiAgICBSVExfTE9HRklMRV9DT05URVhUX0FVVEhPUiggYUxvZ2dlciwgInBhcnNlIiwgIk9ja2UuSmFuc3NlbkBzdW4uY29tIiwgIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6Z2V0U2ltcGxlV2hlcmVUcmVlIiApOwoJY29uc3QgT1NRTFBhcnNlTm9kZSogcE5vZGUgPSBnZXRXaGVyZVRyZWUoKTsKCXJldHVybiBwTm9kZSA/IHBOb2RlLT5nZXRDaGlsZCgxKSA6IE5VTEw7Cn0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KY29uc3QgT1NRTFBhcnNlTm9kZSogT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjpnZXRTaW1wbGVPcmRlclRyZWUoKSBjb25zdAp7CiAgICBSVExfTE9HRklMRV9DT05URVhUX0FVVEhPUiggYUxvZ2dlciwgInBhcnNlIiwgIk9ja2UuSmFuc3NlbkBzdW4uY29tIiwgIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6Z2V0U2ltcGxlT3JkZXJUcmVlIiApOwoJY29uc3QgT1NRTFBhcnNlTm9kZSogcE5vZGUgPSBnZXRPcmRlclRyZWUoKTsKCXJldHVybiBwTm9kZSA/IHBOb2RlLT5nZXRDaGlsZCgyKSA6IE5VTEw7Cn0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KY29uc3QgT1NRTFBhcnNlTm9kZSogT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjpnZXRTaW1wbGVHcm91cEJ5VHJlZSgpIGNvbnN0CnsKICAgIFJUTF9MT0dGSUxFX0NPTlRFWFRfQVVUSE9SKCBhTG9nZ2VyLCAicGFyc2UiLCAiT2NrZS5KYW5zc2VuQHN1bi5jb20iLCAiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjpnZXRTaW1wbGVHcm91cEJ5VHJlZSIgKTsKCWNvbnN0IE9TUUxQYXJzZU5vZGUqIHBOb2RlID0gZ2V0R3JvdXBCeVRyZWUoKTsKCXJldHVybiBwTm9kZSA/IHBOb2RlLT5nZXRDaGlsZCgyKSA6IE5VTEw7Cn0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KY29uc3QgT1NRTFBhcnNlTm9kZSogT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjpnZXRTaW1wbGVIYXZpbmdUcmVlKCkgY29uc3QKewogICAgUlRMX0xPR0ZJTEVfQ09OVEVYVF9BVVRIT1IoIGFMb2dnZXIsICJwYXJzZSIsICJPY2tlLkphbnNzZW5Ac3VuLmNvbSIsICJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OmdldFNpbXBsZUhhdmluZ1RyZWUiICk7Cgljb25zdCBPU1FMUGFyc2VOb2RlKiBwTm9kZSA9IGdldEhhdmluZ1RyZWUoKTsKCXJldHVybiBwTm9kZSA/IHBOb2RlLT5nZXRDaGlsZCgxKSA6IE5VTEw7Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClJlZmVyZW5jZTwgWFByb3BlcnR5U2V0ID4gT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjpmaW5kQ29sdW1uKCBjb25zdCA6OnJ0bDo6T1VTdHJpbmcgJiByQ29sdW1uTmFtZSwgY29uc3QgOjpydGw6Ok9VU3RyaW5nICYgclRhYmxlUmFuZ2UsIGJvb2wgX2JMb29rSW5TdWJUYWJsZXMgKQp7CiAgICBSVExfTE9HRklMRV9DT05URVhUX0FVVEhPUiggYUxvZ2dlciwgInBhcnNlIiwgIk9ja2UuSmFuc3NlbkBzdW4uY29tIiwgIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6ZmluZENvbHVtbiIgKTsKICAgIFJlZmVyZW5jZTwgWFByb3BlcnR5U2V0ID4geENvbHVtbiA9IGZpbmRDb2x1bW4oICptX3BJbXBsLT5tX3BUYWJsZXMsIHJDb2x1bW5OYW1lLCByVGFibGVSYW5nZSApOwogICAgaWYgKCAheENvbHVtbi5pcygpICYmIF9iTG9va0luU3ViVGFibGVzICkKICAgICAgICB4Q29sdW1uID0gZmluZENvbHVtbiggKm1fcEltcGwtPm1fcFN1YlRhYmxlcywgckNvbHVtbk5hbWUsIHJUYWJsZVJhbmdlICk7CiAgICByZXR1cm4geENvbHVtbjsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KUmVmZXJlbmNlPCBYUHJvcGVydHlTZXQgPiBPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OmZpbmRDb2x1bW4oY29uc3QgT1NRTFRhYmxlcyYgX3JUYWJsZXMsY29uc3QgOjpydGw6Ok9VU3RyaW5nICYgckNvbHVtbk5hbWUsIGNvbnN0IDo6cnRsOjpPVVN0cmluZyAmIHJUYWJsZVJhbmdlKQp7CiAgICBSVExfTE9HRklMRV9DT05URVhUX0FVVEhPUiggYUxvZ2dlciwgInBhcnNlIiwgIk9ja2UuSmFuc3NlbkBzdW4uY29tIiwgIk9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6ZmluZENvbHVtbiIgKTsKCVJlZmVyZW5jZTwgWFByb3BlcnR5U2V0ID4geENvbHVtbjsgCglpZiAoIHJUYWJsZVJhbmdlLmdldExlbmd0aCgpICkKCXsKCQlDb25zdE9TUUxUYWJsZXNJdGVyYXRvciBhRmluZCA9IF9yVGFibGVzLmZpbmQoclRhYmxlUmFuZ2UpOwoKCQlpZiAoIGFGaW5kICE9IF9yVGFibGVzLmVuZCgpIAoJCQkmJiBhRmluZC0+c2Vjb25kLmlzKCkgCgkJCSYmIGFGaW5kLT5zZWNvbmQtPmdldENvbHVtbnMoKS5pcygpIAoJCQkmJiBhRmluZC0+c2Vjb25kLT5nZXRDb2x1bW5zKCktPmhhc0J5TmFtZShyQ29sdW1uTmFtZSkgKQoJCQlhRmluZC0+c2Vjb25kLT5nZXRDb2x1bW5zKCktPmdldEJ5TmFtZShyQ29sdW1uTmFtZSkgPj49IHhDb2x1bW47Cgl9CglpZiAoICF4Q29sdW1uLmlzKCkgKQoJewoJCU9TUUxUYWJsZXM6OmNvbnN0X2l0ZXJhdG9yIGFFbmQgPSBfclRhYmxlcy5lbmQoKTsKCQlmb3IoT1NRTFRhYmxlczo6Y29uc3RfaXRlcmF0b3IgYUl0ZXIgPSBfclRhYmxlcy5iZWdpbigpOyBhSXRlciAhPSBhRW5kOyArK2FJdGVyKQoJCXsKCQkJaWYgKCBhSXRlci0+c2Vjb25kLmlzKCkgKQoJCQl7CgkJCQlSZWZlcmVuY2U8WE5hbWVBY2Nlc3M+IHhDb2x1bW5zID0gYUl0ZXItPnNlY29uZC0+Z2V0Q29sdW1ucygpOwoJCQkJaWYoIHhDb2x1bW5zLmlzKCkgJiYgeENvbHVtbnMtPmhhc0J5TmFtZShyQ29sdW1uTmFtZSkgJiYgKHhDb2x1bW5zLT5nZXRCeU5hbWUockNvbHVtbk5hbWUpID4+PSB4Q29sdW1uKSApCgkJCQl7CgkJCQkJT1NMX0VOU1VSRSh4Q29sdW1uLmlzKCksIkNvbHVtbiBpc24ndCBhIHByb3BlcnR5c2V0ISIpOwoJCQkJCWJyZWFrOyAvLyBkaWVzZSBDb2x1bW4gZGFyZiBudXIgZWlubWFsIHZvcmtvbW1lbgoJCQkJfQoJCQl9CgkJfQoJfQoJcmV0dXJuIHhDb2x1bW47Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjppbXBsX2FwcGVuZEVycm9yKCBJUGFyc2VDb250ZXh0OjpFcnJvckNvZGUgX2VFcnJvciwgY29uc3QgOjpydGw6Ok9VU3RyaW5nKiBfcFJlcGxhY2VUb2tlbjEsIGNvbnN0IDo6cnRsOjpPVVN0cmluZyogX3BSZXBsYWNlVG9rZW4yICkKewogICAgUlRMX0xPR0ZJTEVfQ09OVEVYVF9BVVRIT1IoIGFMb2dnZXIsICJwYXJzZSIsICJPY2tlLkphbnNzZW5Ac3VuLmNvbSIsICJPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OmltcGxfYXBwZW5kRXJyb3IiICk7CiAgICA6OnJ0bDo6T1VTdHJpbmcgc0Vycm9yTWVzc2FnZSA9IG1fclBhcnNlci5nZXRDb250ZXh0KCkuZ2V0RXJyb3JNZXNzYWdlKCBfZUVycm9yICk7CiAgICBpZiAoIF9wUmVwbGFjZVRva2VuMSApCiAgICB7CiAgICAgICAgYm9vbCBiVHdvVG9rZW5zID0gKCBfcFJlcGxhY2VUb2tlbjIgIT0gTlVMTCApOwogICAgICAgIGNvbnN0IHNhbF9DaGFyKiBwUGxhY2VIb2xkZXIxID0gYlR3b1Rva2VucyA/ICIjMSIgOiAiIyI7CiAgICAgICAgY29uc3QgOjpydGw6Ok9VU3RyaW5nIHNQbGFjZUhvbGRlcjEgPSA6OnJ0bDo6T1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSggcFBsYWNlSG9sZGVyMSApOwoKICAgICAgICBzRXJyb3JNZXNzYWdlID0gc0Vycm9yTWVzc2FnZS5yZXBsYWNlQXQoIHNFcnJvck1lc3NhZ2UuaW5kZXhPZiggc1BsYWNlSG9sZGVyMSApLCBzUGxhY2VIb2xkZXIxLmdldExlbmd0aCgpLCAqX3BSZXBsYWNlVG9rZW4xICk7CiAgICAgICAgaWYgKCBfcFJlcGxhY2VUb2tlbjIgKQogICAgICAgICAgICBzRXJyb3JNZXNzYWdlID0gc0Vycm9yTWVzc2FnZS5yZXBsYWNlQXQoIHNFcnJvck1lc3NhZ2UuaW5kZXhPZiggOjpydGw6Ok9VU3RyaW5nOjpjcmVhdGVGcm9tQXNjaWkoICIjMiIgKSApLCAyLCAqX3BSZXBsYWNlVG9rZW4yICk7CiAgICB9CgogICAgaW1wbF9hcHBlbmRFcnJvciggU1FMRXhjZXB0aW9uKAogICAgICAgIHNFcnJvck1lc3NhZ2UsIE5VTEwsIGdldFN0YW5kYXJkU1FMU3RhdGUoIFNRTF9HRU5FUkFMX0VSUk9SICksIDEwMDAsIEFueSgpICkgKTsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBPU1FMUGFyc2VUcmVlSXRlcmF0b3I6OmltcGxfYXBwZW5kRXJyb3IoIGNvbnN0IFNRTEV4Y2VwdGlvbiYgX3JFcnJvciApCnsKICAgIFJUTF9MT0dGSUxFX0NPTlRFWFRfQVVUSE9SKCBhTG9nZ2VyLCAicGFyc2UiLCAiT2NrZS5KYW5zc2VuQHN1bi5jb20iLCAiT1NRTFBhcnNlVHJlZUl0ZXJhdG9yOjppbXBsX2FwcGVuZEVycm9yIiApOwogICAgaWYgKCBtX2FFcnJvcnMuTWVzc2FnZS5nZXRMZW5ndGgoKSApCgl7CiAgICAgICAgU1FMRXhjZXB0aW9uKiBwRXJyb3JDaGFpbiA9ICZtX2FFcnJvcnM7CgkJd2hpbGUgKCBwRXJyb3JDaGFpbi0+TmV4dEV4Y2VwdGlvbi5oYXNWYWx1ZSgpICkKICAgICAgICAgICAgcEVycm9yQ2hhaW4gPSBzdGF0aWNfY2FzdDwgU1FMRXhjZXB0aW9uKiA+KCBwRXJyb3JDaGFpbi0+TmV4dEV4Y2VwdGlvbi5wRGF0YSApOwoJCXBFcnJvckNoYWluLT5OZXh0RXhjZXB0aW9uIDw8PSBfckVycm9yOwoJfQoJZWxzZQoJCW1fYUVycm9ycyA9IF9yRXJyb3I7Cn0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kc2FsX0ludDMyIE9TUUxQYXJzZVRyZWVJdGVyYXRvcjo6Z2V0RnVuY3Rpb25SZXR1cm5UeXBlKGNvbnN0IE9TUUxQYXJzZU5vZGUqIF9wTm9kZSApCnsKICAgIHNhbF9JbnQzMiBuVHlwZSA9IERhdGFUeXBlOjpPVEhFUjsKICAgIDo6cnRsOjpPVVN0cmluZyBzRnVuY3Rpb25OYW1lOwoJaWYgKCBTUUxfSVNSVUxFKF9wTm9kZSxsZW5ndGhfZXhwKSApCiAgICB7CgkJX3BOb2RlLT5nZXRDaGlsZCgwKS0+Z2V0Q2hpbGQoMCktPnBhcnNlTm9kZVRvU3RyKHNGdW5jdGlvbk5hbWUsIG1fcEltcGwtPm1feENvbm5lY3Rpb24sIE5VTEwsIHNhbF9GYWxzZSwgc2FsX0ZhbHNlICk7CiAgICAgICAgblR5cGUgPSA6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlcjo6Z2V0RnVuY3Rpb25SZXR1cm5UeXBlKCBzRnVuY3Rpb25OYW1lLCAmbV9yUGFyc2VyLmdldENvbnRleHQoKSApOyAKICAgIH0KICAgIGVsc2UgaWYgKCBTUUxfSVNSVUxFKF9wTm9kZSxudW1fdmFsdWVfZXhwKSB8fCBTUUxfSVNSVUxFKF9wTm9kZSx0ZXJtKSB8fCBTUUxfSVNSVUxFKF9wTm9kZSxmYWN0b3IpICkKCXsKCQluVHlwZSA9IERhdGFUeXBlOjpET1VCTEU7Cgl9CgllbHNlCiAgICB7CgkJX3BOb2RlLT5nZXRDaGlsZCgwKS0+cGFyc2VOb2RlVG9TdHIoc0Z1bmN0aW9uTmFtZSwgbV9wSW1wbC0+bV94Q29ubmVjdGlvbiwgTlVMTCwgc2FsX0ZhbHNlLCBzYWxfRmFsc2UgKTsKCiAgICAgICAgLy8gTUlOIGFuZCBNQVggaGF2ZSBhbm90aGVyIHJldHVybiB0eXBlLCB3ZSBoYXZlIHRvIGNoZWNrIHRoZSBleHByZXNzaW9uIGl0c2VsZi4KICAgICAgICAvLyBAc2VlIGh0dHA6Ly9xYS5vcGVub2ZmaWNlLm9yZy9pc3N1ZXMvc2hvd19idWcuY2dpP2lkPTk5NTY2CiAgICAgICAgaWYgKCBTUUxfSVNSVUxFKF9wTm9kZSxnZW5lcmFsX3NldF9mY3QpICYmIChTUUxfSVNUT0tFTihfcE5vZGUtPmdldENoaWxkKDApLE1JTikgfHwgU1FMX0lTVE9LRU4oX3BOb2RlLT5nZXRDaGlsZCgwKSxNQVgpICkpCiAgICAgICAgewogICAgICAgICAgICBjb25zdCBPU1FMUGFyc2VOb2RlKiBwVmFsdWVFeHAgPSBfcE5vZGUtPmdldENoaWxkKDMpOwogICAgICAgICAgICBpZiAoU1FMX0lTUlVMRShwVmFsdWVFeHAsY29sdW1uX3JlZikpCgkgICAgICAgIHsKCQkgICAgICAgIDo6cnRsOjpPVVN0cmluZyBzQ29sdW1uTmFtZTsKCQkgICAgICAgIDo6cnRsOjpPVVN0cmluZyBhVGFibGVSYW5nZTsKCQkgICAgICAgIGdldENvbHVtblJhbmdlKHBWYWx1ZUV4cCxzQ29sdW1uTmFtZSxhVGFibGVSYW5nZSk7CgkJICAgICAgICBPU0xfRU5TVVJFKHNDb2x1bW5OYW1lLmdldExlbmd0aCgpLCJDb2x1bW5uYW1lIGRhcmYgbmljaHQgbGVlciBzZWluIik7CiAgICAgICAgICAgICAgICBSZWZlcmVuY2U8WFByb3BlcnR5U2V0PiB4Q29sdW1uID0gZmluZENvbHVtbiggc0NvbHVtbk5hbWUsIGFUYWJsZVJhbmdlLCB0cnVlICk7CgoJCSAgICAgICAgaWYgKCB4Q29sdW1uLmlzKCkgKQoJCSAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHhDb2x1bW4tPmdldFByb3BlcnR5VmFsdWUoT01ldGFDb25uZWN0aW9uOjpnZXRQcm9wTWFwKCkuZ2V0TmFtZUJ5SW5kZXgoIFBST1BFUlRZX0lEX1RZUEUpKSA+Pj0gblR5cGU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoIFNRTF9JU1JVTEUocFZhbHVlRXhwLG51bV92YWx1ZV9leHApIHx8IFNRTF9JU1JVTEUocFZhbHVlRXhwLHRlcm0pIHx8IFNRTF9JU1JVTEUocFZhbHVlRXhwLGZhY3RvcikgKQoJCQkJewoJCQkJCW5UeXBlID0gRGF0YVR5cGU6OkRPVUJMRTsKCQkJCX0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKCBTUUxfSVNSVUxFKHBWYWx1ZUV4cCxkYXRldGltZV9wcmltYXJ5KSApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc3dpdGNoKHBWYWx1ZUV4cC0+Z2V0Q2hpbGQoMCktPmdldFRva2VuSUQoKSApCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFNRTF9UT0tFTl9DVVJSRU5UX0RBVEU6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuVHlwZSA9IERhdGFUeXBlOjpEQVRFOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgU1FMX1RPS0VOX0NVUlJFTlRfVElNRToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5UeXBlID0gRGF0YVR5cGU6OlRJTUU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBTUUxfVE9LRU5fQ1VSUkVOVF9USU1FU1RBTVA6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuVHlwZSA9IERhdGFUeXBlOjpUSU1FU1RBTVA7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIGlmICggU1FMX0lTUlVMRShwVmFsdWVFeHAsdmFsdWVfZXhwX3ByaW1hcnkpICkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBuVHlwZSA9IGdldEZ1bmN0aW9uUmV0dXJuVHlwZShwVmFsdWVFeHAtPmdldENoaWxkKDEpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKCBTUUxfSVNSVUxFKHBWYWx1ZUV4cCxjb25jYXRlbmF0aW9uKSAKICAgICAgICAgICAgICAgICAgICAgICAgfHwgU1FMX0lTUlVMRShwVmFsdWVFeHAsY2hhcl9mYWN0b3IpIAogICAgICAgICAgICAgICAgICAgICAgICB8fCBTUUxfSVNSVUxFKHBWYWx1ZUV4cCxiaXRfdmFsdWVfZmN0KSAKICAgICAgICAgICAgICAgICAgICAgICAgfHwgU1FMX0lTUlVMRShwVmFsdWVFeHAsY2hhcl92YWx1ZV9mY3QpCiAgICAgICAgICAgICAgICAgICAgICAgIHx8IFNRTF9JU1JVTEUocFZhbHVlRXhwLGNoYXJfc3Vic3RyaW5nX2ZjdCkKICAgICAgICAgICAgICAgICAgICAgICAgfHwgU1FMX0lTUlVMRShwVmFsdWVFeHAsZm9sZCkKICAgICAgICAgICAgICAgICAgICAgICAgfHwgU1FMX0lTVE9LRU4ocFZhbHVlRXhwLFNUUklORykgKQoJCQkJewoJCQkJCW5UeXBlID0gRGF0YVR5cGU6OlZBUkNIQVI7CgkJCQl9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCBuVHlwZSA9PSBEYXRhVHlwZTo6T1RIRVIgKQogICAgICAgICAgICAgICAgblR5cGUgPSBEYXRhVHlwZTo6RE9VQkxFOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgICAgIG5UeXBlID0gOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZXI6OmdldEZ1bmN0aW9uUmV0dXJuVHlwZSggc0Z1bmN0aW9uTmFtZSwgJm1fclBhcnNlci5nZXRDb250ZXh0KCkgKTsgCiAgICB9CiAgICAKICAgIHJldHVybiBuVHlwZTsKfQoK