LyogY29ubmVjdGlvbi5oIC0gZGVmaW5pdGlvbnMgZm9yIHRoZSBjb25uZWN0aW9uIHR5cGUKICoKICogQ29weXJpZ2h0IChDKSAyMDA0LTIwMDcgR2VyaGFyZCBI5HJpbmcgPGdoQGdoYWVyaW5nLmRlPgogKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBweXNxbGl0ZS4KICoKICogVGhpcyBzb2Z0d2FyZSBpcyBwcm92aWRlZCAnYXMtaXMnLCB3aXRob3V0IGFueSBleHByZXNzIG9yIGltcGxpZWQKICogd2FycmFudHkuICBJbiBubyBldmVudCB3aWxsIHRoZSBhdXRob3JzIGJlIGhlbGQgbGlhYmxlIGZvciBhbnkgZGFtYWdlcwogKiBhcmlzaW5nIGZyb20gdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLgogKgogKiBQZXJtaXNzaW9uIGlzIGdyYW50ZWQgdG8gYW55b25lIHRvIHVzZSB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZSwKICogaW5jbHVkaW5nIGNvbW1lcmNpYWwgYXBwbGljYXRpb25zLCBhbmQgdG8gYWx0ZXIgaXQgYW5kIHJlZGlzdHJpYnV0ZSBpdAogKiBmcmVlbHksIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyByZXN0cmljdGlvbnM6CiAqCiAqIDEuIFRoZSBvcmlnaW4gb2YgdGhpcyBzb2Z0d2FyZSBtdXN0IG5vdCBiZSBtaXNyZXByZXNlbnRlZDsgeW91IG11c3Qgbm90CiAqICAgIGNsYWltIHRoYXQgeW91IHdyb3RlIHRoZSBvcmlnaW5hbCBzb2Z0d2FyZS4gSWYgeW91IHVzZSB0aGlzIHNvZnR3YXJlCiAqICAgIGluIGEgcHJvZHVjdCwgYW4gYWNrbm93bGVkZ21lbnQgaW4gdGhlIHByb2R1Y3QgZG9jdW1lbnRhdGlvbiB3b3VsZCBiZQogKiAgICBhcHByZWNpYXRlZCBidXQgaXMgbm90IHJlcXVpcmVkLgogKiAyLiBBbHRlcmVkIHNvdXJjZSB2ZXJzaW9ucyBtdXN0IGJlIHBsYWlubHkgbWFya2VkIGFzIHN1Y2gsIGFuZCBtdXN0IG5vdCBiZQogKiAgICBtaXNyZXByZXNlbnRlZCBhcyBiZWluZyB0aGUgb3JpZ2luYWwgc29mdHdhcmUuCiAqIDMuIFRoaXMgbm90aWNlIG1heSBub3QgYmUgcmVtb3ZlZCBvciBhbHRlcmVkIGZyb20gYW55IHNvdXJjZSBkaXN0cmlidXRpb24uCiAqLwoKI2lmbmRlZiBQWVNRTElURV9DT05ORUNUSU9OX0gKI2RlZmluZSBQWVNRTElURV9DT05ORUNUSU9OX0gKI2luY2x1ZGUgIlB5dGhvbi5oIgojaW5jbHVkZSAicHl0aHJlYWQuaCIKI2luY2x1ZGUgInN0cnVjdG1lbWJlci5oIgoKI2luY2x1ZGUgImNhY2hlLmgiCiNpbmNsdWRlICJtb2R1bGUuaCIKCiNpbmNsdWRlICJzcWxpdGUzLmgiCgp0eXBlZGVmIHN0cnVjdAp7CiAgICBQeU9iamVjdF9IRUFECiAgICBzcWxpdGUzKiBkYjsKCiAgICAvKiAxIGlmIHdlIGFyZSBjdXJyZW50bHkgd2l0aGluIGEgdHJhbnNhY3Rpb24sIGkuIGUuIGlmIGEgQkVHSU4gaGFzIGJlZW4KICAgICAqIGlzc3VlZCAqLwogICAgaW50IGluVHJhbnNhY3Rpb247CgogICAgLyogdGhlIHR5cGUgZGV0ZWN0aW9uIG1vZGUuIE9ubHkgMCwgUEFSU0VfREVDTFRZUEVTLCBQQVJTRV9DT0xOQU1FUyBvciBhCiAgICAgKiBiaXR3aXNlIGNvbWJpbmF0aW9uIHRoZXJlb2YgbWFrZXMgc2Vuc2UgKi8KICAgIGludCBkZXRlY3RfdHlwZXM7CgogICAgLyogdGhlIHRpbWVvdXQgdmFsdWUgaW4gc2Vjb25kcyBmb3IgZGF0YWJhc2UgbG9ja3MgKi8KICAgIGRvdWJsZSB0aW1lb3V0OwoKICAgIC8qIGZvciBpbnRlcm5hbCB1c2UgaW4gdGhlIHRpbWVvdXQgaGFuZGxlcjogd2hlbiBkaWQgdGhlIHRpbWVvdXQgaGFuZGxlcgogICAgICogZmlyc3QgZ2V0IGNhbGxlZCB3aXRoIGNvdW50PTA/ICovCiAgICBkb3VibGUgdGltZW91dF9zdGFydGVkOwoKICAgIC8qIE5vbmUgZm9yIGF1dG9jb21taXQsIG90aGVyd2lzZSBhIFB5U3RyaW5nIHdpdGggdGhlIGlzb2xhdGlvbiBsZXZlbCAqLwogICAgUHlPYmplY3QqIGlzb2xhdGlvbl9sZXZlbDsKCiAgICAvKiBOVUxMIGZvciBhdXRvY29tbWl0LCBvdGhlcndpc2UgYSBzdHJpbmcgd2l0aCB0aGUgQkVHSU4gc3RhdGVtZW50OyB3aWxsIGJlCiAgICAgKiBmcmVlZCBpbiBjb25uZWN0aW9uIGRlc3RydWN0b3IgKi8KICAgIGNoYXIqIGJlZ2luX3N0YXRlbWVudDsKCiAgICAvKiAxIGlmIGEgY2hlY2sgc2hvdWxkIGJlIHBlcmZvcm1lZCBmb3IgZWFjaCBBUEkgY2FsbCBpZiB0aGUgY29ubmVjdGlvbiBpcwogICAgICogdXNlZCBmcm9tIHRoZSBzYW1lIHRocmVhZCBpdCB3YXMgY3JlYXRlZCBpbiAqLwogICAgaW50IGNoZWNrX3NhbWVfdGhyZWFkOwoKICAgIC8qIHRocmVhZCBpZGVudGlmaWNhdGlvbiBvZiB0aGUgdGhyZWFkIHRoZSBjb25uZWN0aW9uIHdhcyBjcmVhdGVkIGluICovCiAgICBsb25nIHRocmVhZF9pZGVudDsKCiAgICBweXNxbGl0ZV9DYWNoZSogc3RhdGVtZW50X2NhY2hlOwoKICAgIC8qIEEgbGlzdCBvZiB3ZWFrIHJlZmVyZW5jZXMgdG8gc3RhdGVtZW50cyB1c2VkIHdpdGhpbiB0aGlzIGNvbm5lY3Rpb24gKi8KICAgIFB5T2JqZWN0KiBzdGF0ZW1lbnRzOwoKICAgIC8qIGEgY291bnRlciBmb3IgaG93IG1hbnkgc3RhdGVtZW50cyB3ZXJlIGNyZWF0ZWQgaW4gdGhlIGNvbm5lY3Rpb24uIE1heSBiZQogICAgICogcmVzZXQgdG8gMCBhdCBjZXJ0YWluIGludGVydmFscyAqLwogICAgaW50IGNyZWF0ZWRfc3RhdGVtZW50czsKCiAgICBQeU9iamVjdCogcm93X2ZhY3Rvcnk7CgogICAgLyogRGV0ZXJtaW5lcyBob3cgYnl0ZXN0cmluZ3MgZnJvbSBTUUxpdGUgYXJlIGNvbnZlcnRlZCB0byBQeXRob24gb2JqZWN0czoKICAgICAqIC0gUHlVbmljb2RlX1R5cGU6ICAgICAgICBQeXRob24gVW5pY29kZSBvYmplY3RzIGFyZSBjb25zdHJ1Y3RlZCBmcm9tIFVURi04IGJ5dGVzdHJpbmdzCiAgICAgKiAtIE9wdGltaXplZFVuaWNvZGU6ICAgICAgTGlrZSBiZWZvcmUsIGJ1dCBmb3IgQVNDSUkgZGF0YSwgb25seSBQeVN0cmluZ3MgYXJlIGNyZWF0ZWQuCiAgICAgKiAtIFB5Qnl0ZXNfVHlwZTogICAgICAgICBQeVN0cmluZ3MgYXJlIGNyZWF0ZWQgYXMtaXMuCiAgICAgKiAtIEFueSBjdXN0b20gY2FsbGFibGU6ICAgQW55IG9iamVjdCByZXR1cm5lZCBmcm9tIHRoZSBjYWxsYWJsZSBjYWxsZWQgd2l0aCB0aGUgYnl0ZXN0cmluZwogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgIGFzIHNpbmdsZSBwYXJhbWV0ZXIuCiAgICAgKi8KICAgIFB5T2JqZWN0KiB0ZXh0X2ZhY3Rvcnk7CgogICAgLyogcmVtZW1iZXIgcmVmZXJlbmNlcyB0byBmdW5jdGlvbnMvY2xhc3NlcyB1c2VkIGluCiAgICAgKiBjcmVhdGVfZnVuY3Rpb24vY3JlYXRlL2FnZ3JlZ2F0ZSwgdXNlIHRoZXNlIGFzIGRpY3Rpb25hcnkga2V5cywgc28gd2UKICAgICAqIGNhbiBrZWVwIHRoZSB0b3RhbCBzeXN0ZW0gcmVmY291bnQgY29uc3RhbnQgYnkgY2xlYXJpbmcgdGhhdCBkaWN0aW9uYXJ5CiAgICAgKiBpbiBjb25uZWN0aW9uX2RlYWxsb2MgKi8KICAgIFB5T2JqZWN0KiBmdW5jdGlvbl9waW5ib2FyZDsKCiAgICAvKiBhIGRpY3Rpb25hcnkgb2YgcmVnaXN0ZXJlZCBjb2xsYXRpb24gbmFtZSA9PiBjb2xsYXRpb24gY2FsbGFibGUgbWFwcGluZ3MgKi8KICAgIFB5T2JqZWN0KiBjb2xsYXRpb25zOwoKICAgIC8qIEV4Y2VwdGlvbiBvYmplY3RzICovCiAgICBQeU9iamVjdCogV2FybmluZzsKICAgIFB5T2JqZWN0KiBFcnJvcjsKICAgIFB5T2JqZWN0KiBJbnRlcmZhY2VFcnJvcjsKICAgIFB5T2JqZWN0KiBEYXRhYmFzZUVycm9yOwogICAgUHlPYmplY3QqIERhdGFFcnJvcjsKICAgIFB5T2JqZWN0KiBPcGVyYXRpb25hbEVycm9yOwogICAgUHlPYmplY3QqIEludGVncml0eUVycm9yOwogICAgUHlPYmplY3QqIEludGVybmFsRXJyb3I7CiAgICBQeU9iamVjdCogUHJvZ3JhbW1pbmdFcnJvcjsKICAgIFB5T2JqZWN0KiBOb3RTdXBwb3J0ZWRFcnJvcjsKfSBweXNxbGl0ZV9Db25uZWN0aW9uOwoKZXh0ZXJuIFB5VHlwZU9iamVjdCBweXNxbGl0ZV9Db25uZWN0aW9uVHlwZTsKClB5T2JqZWN0KiBweXNxbGl0ZV9jb25uZWN0aW9uX2FsbG9jKFB5VHlwZU9iamVjdCogdHlwZSwgaW50IGF3YXJlKTsKdm9pZCBweXNxbGl0ZV9jb25uZWN0aW9uX2RlYWxsb2MocHlzcWxpdGVfQ29ubmVjdGlvbiogc2VsZik7ClB5T2JqZWN0KiBweXNxbGl0ZV9jb25uZWN0aW9uX2N1cnNvcihweXNxbGl0ZV9Db25uZWN0aW9uKiBzZWxmLCBQeU9iamVjdCogYXJncywgUHlPYmplY3QqIGt3YXJncyk7ClB5T2JqZWN0KiBweXNxbGl0ZV9jb25uZWN0aW9uX2Nsb3NlKHB5c3FsaXRlX0Nvbm5lY3Rpb24qIHNlbGYsIFB5T2JqZWN0KiBhcmdzKTsKUHlPYmplY3QqIF9weXNxbGl0ZV9jb25uZWN0aW9uX2JlZ2luKHB5c3FsaXRlX0Nvbm5lY3Rpb24qIHNlbGYpOwpQeU9iamVjdCogcHlzcWxpdGVfY29ubmVjdGlvbl9jb21taXQocHlzcWxpdGVfQ29ubmVjdGlvbiogc2VsZiwgUHlPYmplY3QqIGFyZ3MpOwpQeU9iamVjdCogcHlzcWxpdGVfY29ubmVjdGlvbl9yb2xsYmFjayhweXNxbGl0ZV9Db25uZWN0aW9uKiBzZWxmLCBQeU9iamVjdCogYXJncyk7ClB5T2JqZWN0KiBweXNxbGl0ZV9jb25uZWN0aW9uX25ldyhQeVR5cGVPYmplY3QqIHR5cGUsIFB5T2JqZWN0KiBhcmdzLCBQeU9iamVjdCoga3cpOwppbnQgcHlzcWxpdGVfY29ubmVjdGlvbl9pbml0KHB5c3FsaXRlX0Nvbm5lY3Rpb24qIHNlbGYsIFB5T2JqZWN0KiBhcmdzLCBQeU9iamVjdCoga3dhcmdzKTsKCmludCBweXNxbGl0ZV9jaGVja190aHJlYWQocHlzcWxpdGVfQ29ubmVjdGlvbiogc2VsZik7CmludCBweXNxbGl0ZV9jaGVja19jb25uZWN0aW9uKHB5c3FsaXRlX0Nvbm5lY3Rpb24qIGNvbik7CgppbnQgcHlzcWxpdGVfY29ubmVjdGlvbl9zZXR1cF90eXBlcyh2b2lkKTsKCiNlbmRpZgo=