LyogQm9vc3QgaW50ZXJ2YWwvY29uc3RhbnRzLmhwcCB0ZW1wbGF0ZSBpbXBsZW1lbnRhdGlvbiBmaWxlCiAqCiAqIENvcHlyaWdodCAyMDAyIEhlcnbpIEJy9m5uaW1hbm4sIEd1aWxsYXVtZSBNZWxxdWlvbmQsIFN5bHZhaW4gUGlvbgogKgogKiBEaXN0cmlidXRlZCB1bmRlciB0aGUgQm9vc3QgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjAuCiAqIChTZWUgYWNjb21wYW55aW5nIGZpbGUgTElDRU5TRV8xXzAudHh0IG9yCiAqIGNvcHkgYXQgaHR0cDovL3d3dy5ib29zdC5vcmcvTElDRU5TRV8xXzAudHh0KQogKi8KCiNpZm5kZWYgQk9PU1RfTlVNRVJJQ19JTlRFUlZBTF9DT05TVEFOVFNfSFBQCiNkZWZpbmUgQk9PU1RfTlVNRVJJQ19JTlRFUlZBTF9DT05TVEFOVFNfSFBQCgpuYW1lc3BhY2UgYm9vc3QgewpuYW1lc3BhY2UgbnVtZXJpYyB7Cm5hbWVzcGFjZSBpbnRlcnZhbF9saWIgewpuYW1lc3BhY2UgY29uc3RhbnRzIHsKCi8vIFRoZXNlIGNvbnN0YW50cyBzaG91bGQgYmUgZXhhY3RseSBjb21wdXRlZC4KLy8gRGVjaW1hbCByZXByZXNlbnRhdGlvbnMgd291bGRuJ3QgZG8gaXQgc2luY2UgdGhlIHN0YW5kYXJkIGRvZXNuJ3QKLy8gc3BlY2lmeSB0aGUgcm91bmRpbmcgKGV2ZW4gbmVhcmVzdCkgdGhhdCBzaG91bGQgYmUgdXNlZC4KCnN0YXRpYyBjb25zdCBmbG9hdCBwaV9mX2wgPSAxMzE3Njc5NC4wZi8oMTw8MjIpOwpzdGF0aWMgY29uc3QgZmxvYXQgcGlfZl91ID0gMTMxNzY3OTUuMGYvKDE8PDIyKTsKc3RhdGljIGNvbnN0IGRvdWJsZSBwaV9kX2wgPSAoMzM3MzI1OTQyNi4wICsgMjczNjg4LjAgLyAoMTw8MjEpKSAvICgxPDwzMCk7CnN0YXRpYyBjb25zdCBkb3VibGUgcGlfZF91ID0gKDMzNzMyNTk0MjYuMCArIDI3MzY4OS4wIC8gKDE8PDIxKSkgLyAoMTw8MzApOwoKdGVtcGxhdGU8Y2xhc3MgVD4gaW5saW5lIFQgcGlfbG93ZXIoKSB7IHJldHVybiAzOyB9CnRlbXBsYXRlPGNsYXNzIFQ+IGlubGluZSBUIHBpX3VwcGVyKCkgeyByZXR1cm4gNDsgfQp0ZW1wbGF0ZTxjbGFzcyBUPiBpbmxpbmUgVCBwaV9oYWxmX2xvd2VyKCkgeyByZXR1cm4gMTsgfQp0ZW1wbGF0ZTxjbGFzcyBUPiBpbmxpbmUgVCBwaV9oYWxmX3VwcGVyKCkgeyByZXR1cm4gMjsgfQp0ZW1wbGF0ZTxjbGFzcyBUPiBpbmxpbmUgVCBwaV90d2ljZV9sb3dlcigpIHsgcmV0dXJuIDY7IH0KdGVtcGxhdGU8Y2xhc3MgVD4gaW5saW5lIFQgcGlfdHdpY2VfdXBwZXIoKSB7IHJldHVybiA3OyB9Cgp0ZW1wbGF0ZTw+IGlubGluZSBmbG9hdCBwaV9sb3dlcjxmbG9hdD4oKSB7IHJldHVybiBwaV9mX2w7IH0KdGVtcGxhdGU8PiBpbmxpbmUgZmxvYXQgcGlfdXBwZXI8ZmxvYXQ+KCkgeyByZXR1cm4gcGlfZl91OyB9CnRlbXBsYXRlPD4gaW5saW5lIGZsb2F0IHBpX2hhbGZfbG93ZXI8ZmxvYXQ+KCkgeyByZXR1cm4gcGlfZl9sIC8gMjsgfQp0ZW1wbGF0ZTw+IGlubGluZSBmbG9hdCBwaV9oYWxmX3VwcGVyPGZsb2F0PigpIHsgcmV0dXJuIHBpX2ZfdSAvIDI7IH0KdGVtcGxhdGU8PiBpbmxpbmUgZmxvYXQgcGlfdHdpY2VfbG93ZXI8ZmxvYXQ+KCkgeyByZXR1cm4gcGlfZl9sICogMjsgfQp0ZW1wbGF0ZTw+IGlubGluZSBmbG9hdCBwaV90d2ljZV91cHBlcjxmbG9hdD4oKSB7IHJldHVybiBwaV9mX3UgKiAyOyB9Cgp0ZW1wbGF0ZTw+IGlubGluZSBkb3VibGUgcGlfbG93ZXI8ZG91YmxlPigpIHsgcmV0dXJuIHBpX2RfbDsgfQp0ZW1wbGF0ZTw+IGlubGluZSBkb3VibGUgcGlfdXBwZXI8ZG91YmxlPigpIHsgcmV0dXJuIHBpX2RfdTsgfQp0ZW1wbGF0ZTw+IGlubGluZSBkb3VibGUgcGlfaGFsZl9sb3dlcjxkb3VibGU+KCkgeyByZXR1cm4gcGlfZF9sIC8gMjsgfQp0ZW1wbGF0ZTw+IGlubGluZSBkb3VibGUgcGlfaGFsZl91cHBlcjxkb3VibGU+KCkgeyByZXR1cm4gcGlfZF91IC8gMjsgfQp0ZW1wbGF0ZTw+IGlubGluZSBkb3VibGUgcGlfdHdpY2VfbG93ZXI8ZG91YmxlPigpIHsgcmV0dXJuIHBpX2RfbCAqIDI7IH0KdGVtcGxhdGU8PiBpbmxpbmUgZG91YmxlIHBpX3R3aWNlX3VwcGVyPGRvdWJsZT4oKSB7IHJldHVybiBwaV9kX3UgKiAyOyB9Cgp0ZW1wbGF0ZTw+IGlubGluZSBsb25nIGRvdWJsZSBwaV9sb3dlcjxsb25nIGRvdWJsZT4oKSB7IHJldHVybiBwaV9kX2w7IH0KdGVtcGxhdGU8PiBpbmxpbmUgbG9uZyBkb3VibGUgcGlfdXBwZXI8bG9uZyBkb3VibGU+KCkgeyByZXR1cm4gcGlfZF91OyB9CnRlbXBsYXRlPD4gaW5saW5lIGxvbmcgZG91YmxlIHBpX2hhbGZfbG93ZXI8bG9uZyBkb3VibGU+KCkgeyByZXR1cm4gcGlfZF9sIC8gMjsgfQp0ZW1wbGF0ZTw+IGlubGluZSBsb25nIGRvdWJsZSBwaV9oYWxmX3VwcGVyPGxvbmcgZG91YmxlPigpIHsgcmV0dXJuIHBpX2RfdSAvIDI7IH0KdGVtcGxhdGU8PiBpbmxpbmUgbG9uZyBkb3VibGUgcGlfdHdpY2VfbG93ZXI8bG9uZyBkb3VibGU+KCkgeyByZXR1cm4gcGlfZF9sICogMjsgfQp0ZW1wbGF0ZTw+IGlubGluZSBsb25nIGRvdWJsZSBwaV90d2ljZV91cHBlcjxsb25nIGRvdWJsZT4oKSB7IHJldHVybiBwaV9kX3UgKiAyOyB9Cgp9IC8vIG5hbWVzcGFjZSBjb25zdGFudHMKCnRlbXBsYXRlPGNsYXNzIEk+IGlubGluZQpJIHBpKCkKewogIHR5cGVkZWYgdHlwZW5hbWUgSTo6YmFzZV90eXBlIFQ7CiAgcmV0dXJuIEkoY29uc3RhbnRzOjpwaV9sb3dlcjxUPigpLAogICAgICAgICAgIGNvbnN0YW50czo6cGlfdXBwZXI8VD4oKSwgdHJ1ZSk7Cn0KCnRlbXBsYXRlPGNsYXNzIEk+IGlubGluZQpJIHBpX2hhbGYoKQp7CiAgdHlwZWRlZiB0eXBlbmFtZSBJOjpiYXNlX3R5cGUgVDsKICByZXR1cm4gSShjb25zdGFudHM6OnBpX2hhbGZfbG93ZXI8VD4oKSwKICAgICAgICAgICBjb25zdGFudHM6OnBpX2hhbGZfdXBwZXI8VD4oKSwgdHJ1ZSk7Cn0KCnRlbXBsYXRlPGNsYXNzIEk+IGlubGluZQpJIHBpX3R3aWNlKCkKewogIHR5cGVkZWYgdHlwZW5hbWUgSTo6YmFzZV90eXBlIFQ7CiAgcmV0dXJuIEkoY29uc3RhbnRzOjpwaV90d2ljZV9sb3dlcjxUPigpLAogICAgICAgICAgIGNvbnN0YW50czo6cGlfdHdpY2VfdXBwZXI8VD4oKSwgdHJ1ZSk7Cn0KCn0gLy8gbmFtZXNwYWNlIGludGVydmFsX2xpYgp9IC8vIG5hbWVzcGFjZSBudW1lcmljCn0gLy8gbmFtZXNwYWNlIGJvb3N0CgojZW5kaWYgLy8gQk9PU1RfTlVNRVJJQ19JTlRFUlZBTF9DT05TVEFOVFNfSFBQCg==