Ly8gQ29weXJpZ2h0IChDKSAyMDAyLTIwMDUgTmlrb2xhdXMgR2ViaGFyZHQKLy8gVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlICJJcnJsaWNodCBFbmdpbmUiIGFuZCB0aGUgImlyclhNTCIgcHJvamVjdC4KLy8gRm9yIGNvbmRpdGlvbnMgb2YgZGlzdHJpYnV0aW9uIGFuZCB1c2UsIHNlZSBjb3B5cmlnaHQgbm90aWNlIGluIGlycmxpY2h0LmggYW5kIGlyclhNTC5oCgojaWZuZGVmIF9fSVJSX1NUUklOR19IX0lOQ0xVREVEX18KI2RlZmluZSBfX0lSUl9TVFJJTkdfSF9JTkNMVURFRF9fCgojaW5jbHVkZSAiaXJyVHlwZXMuaCIKCm5hbWVzcGFjZSBpcnIKewpuYW1lc3BhY2UgY29yZQp7CgovLyEJVmVyeSBzaW1wbGUgc3RyaW5nIGNsYXNzIHdpdGggc29tZSB1c2VmdWwgZmVhdHVyZXMuCi8qKglzdHJpbmc8Yzg+IGFuZCBzdHJpbmc8d2NoYXJfdD4gd29yayBib3RoIHdpdGggdW5pY29kZSBBTkQgYXNjaWksCnNvIHlvdSBjYW4gYXNzaWduIHVuaWNvZGUgdG8gc3RyaW5nPGM4PiBhbmQgYXNjaWkgdG8gc3RyaW5nPHdjaGFyX3Q+IAooYW5kIHRoZSBvdGhlciB3YXkgcm91bmQpIGlmIHlvdXIgZXZlciB3b3VsZCB3YW50IHRvLiAKTm90ZSB0aGF0IHRoZSBjb252ZXJzYXRpb24gYmV0d2VlbiBib3RoIGlzIG5vdCBkb25lIHVzaW5nIGFuIGVuY29kaW5nLgoKS25vd24gYnVnczoKU3BlY2lhbCBjaGFyYWN0ZXJzIGxpa2UgJ8QnLCAn3CcgYW5kICfWJyBhcmUgaWdub3JlZCBpbiB0aGUKbWV0aG9kcyBtYWtlX3VwcGVyLCBtYWtlX2xvd2VyIGFuZCBlcXVhbHNfaWdub3JlX2Nhc2UuCiovCnRlbXBsYXRlIDxjbGFzcyBUPgpjbGFzcyBzdHJpbmcKewpwdWJsaWM6CgoJLy8hIERlZmF1bHQgY29uc3RydWN0b3IKCXN0cmluZygpCgk6IGFycmF5KDApLCBhbGxvY2F0ZWQoMSksIHVzZWQoMSkKCXsKCQlhcnJheSA9IG5ldyBUWzFdOwoJCWFycmF5WzBdID0gMHgwOwoJfQoKCgoJLy8hIENvbnN0cnVjdG9yCglzdHJpbmcoY29uc3Qgc3RyaW5nPFQ+JiBvdGhlcikKCTogYXJyYXkoMCksIGFsbG9jYXRlZCgwKSwgdXNlZCgwKQoJewoJCSp0aGlzID0gb3RoZXI7Cgl9CgoKCS8vISBDb25zdHJ1Y3RzIGEgc3RyaW5nIGZyb20gYW4gaW50CglzdHJpbmcoaW50IG51bWJlcikKCTogYXJyYXkoMCksIGFsbG9jYXRlZCgwKSwgdXNlZCgwKQoJewoJCS8vIHN0b3JlIGlmIG5lZ2F0aXZlIGFuZCBtYWtlIHBvc2l0aXZlCgoJCWJvb2wgbmVnYXRpdmUgPSBmYWxzZTsKCQlpZiAobnVtYmVyIDwgMCkKCQl7CgkJCW51bWJlciAqPSAtMTsKCQkJbmVnYXRpdmUgPSB0cnVlOwoJCX0KCgkJLy8gdGVtcG9yYXJ5IGJ1ZmZlciBmb3IgMTYgbnVtYmVycwoKCQljOCB0bXBidWZbMTZdOwoJCXRtcGJ1ZlsxNV0gPSAwOwoJCXMzMiBpZHggPSAxNTsJCgoJCS8vIHNwZWNpYWwgY2FzZSAnMCcKCgkJaWYgKCFudW1iZXIpIAoJCXsKCQkJdG1wYnVmWzE0XSA9ICcwJzsKCQkJKnRoaXMgPSAmdG1wYnVmWzE0XTsKCQkJcmV0dXJuOwoJCX0KCgkJLy8gYWRkIG51bWJlcnMKCgkJd2hpbGUobnVtYmVyICYmIGlkeCkKCQl7CgkJCWlkeC0tOwkKCQkJdG1wYnVmW2lkeF0gPSAoYzgpKCcwJyArIChudW1iZXIgJSAxMCkpOwoJCQludW1iZXIgPSBudW1iZXIgLyAxMDsJCQkJCQoJCX0KCgkJLy8gYWRkIHNpZ24KCgkJaWYgKG5lZ2F0aXZlKQoJCXsKCQkJaWR4LS07CgkJCXRtcGJ1ZltpZHhdID0gJy0nOwkJCQoJCX0KCgkJKnRoaXMgPSAmdG1wYnVmW2lkeF07Cgl9CgoKCgkvLyEgQ29uc3RydWN0b3IgZm9yIGNvcHlpbmcgYSBzdHJpbmcgZnJvbSBhIHBvaW50ZXIgd2l0aCBhIGdpdmVuIGxlbmdodAoJdGVtcGxhdGUgPGNsYXNzIEI+CglzdHJpbmcoY29uc3QgQiogYywgczMyIGxlbmdodCkKCTogYXJyYXkoMCksIGFsbG9jYXRlZCgwKSwgdXNlZCgwKQoJewoJCWlmICghYykKCQkJcmV0dXJuOwoKICAgICAgICBhbGxvY2F0ZWQgPSB1c2VkID0gbGVuZ2h0KzE7CgkJYXJyYXkgPSBuZXcgVFt1c2VkXTsKCgkJZm9yIChzMzIgbCA9IDA7IGw8bGVuZ2h0OyArK2wpCgkJCWFycmF5W2xdID0gKFQpY1tsXTsKCgkJYXJyYXlbbGVuZ2h0XSA9IDA7Cgl9CgoKCgkvLyEgQ29uc3RydWN0b3IgZm9yIHVuaWNvZGUgYW5kIGFzY2lpIHN0cmluZ3MKCXRlbXBsYXRlIDxjbGFzcyBCPgoJc3RyaW5nKGNvbnN0IEIqIGMpCgk6IGFycmF5KDApLGFsbG9jYXRlZCgwKSwgdXNlZCgwKQoJewoJCSp0aGlzID0gYzsKCX0KCgoKCS8vISBkZXN0cnVjdG9yCgl+c3RyaW5nKCkKCXsKCQlkZWxldGUgW10gYXJyYXk7Cgl9CgoKCgkvLyEgQXNzaWdubWVudCBvcGVyYXRvcgoJc3RyaW5nPFQ+JiBvcGVyYXRvcj0oY29uc3Qgc3RyaW5nPFQ+JiBvdGhlcikgCgl7CgkJaWYgKHRoaXMgPT0gJm90aGVyKQoJCQlyZXR1cm4gKnRoaXM7CgoJCWRlbGV0ZSBbXSBhcnJheTsKCQlhbGxvY2F0ZWQgPSB1c2VkID0gb3RoZXIuc2l6ZSgpKzE7CgkJYXJyYXkgPSBuZXcgVFt1c2VkXTsKCgkJY29uc3QgVCogcCA9IG90aGVyLmNfc3RyKCk7CgkJZm9yIChzMzIgaT0wOyBpPHVzZWQ7ICsraSwgKytwKQoJCQlhcnJheVtpXSA9ICpwOwoKCQlyZXR1cm4gKnRoaXM7Cgl9CgoKCgkvLyEgQXNzaWdubWVudCBvcGVyYXRvciBmb3Igc3RyaW5ncywgYXNjaWkgYW5kIHVuaWNvZGUKCXRlbXBsYXRlIDxjbGFzcyBCPgoJc3RyaW5nPFQ+JiBvcGVyYXRvcj0oY29uc3QgQiogYykgCgl7CgkJaWYgKCFjKQoJCXsKCQkJaWYgKCFhcnJheSkKCQkJewoJCQkJYXJyYXkgPSBuZXcgVFsxXTsKCQkJCWFsbG9jYXRlZCA9IDE7CgkJCQl1c2VkID0gMTsKCQkJfQoJCQlhcnJheVswXSA9IDB4MDsKCQkJcmV0dXJuICp0aGlzOwoJCX0KCgkJaWYgKCh2b2lkKiljID09ICh2b2lkKilhcnJheSkKCQkJcmV0dXJuICp0aGlzOwoKCQlzMzIgbGVuID0gMDsKCQljb25zdCBCKiBwID0gYzsKCQl3aGlsZSgqcCkKCQl7CgkJCSsrbGVuOwoJCQkrK3A7CgkJfQoKCQkvLyB3ZSdsbCB0YWtlIHRoZSBvbGQgc3RyaW5nIGZvciBhIHdoaWxlLCBiZWNhdXNlIHRoZSBuZXcgc3RyaW5nIGNvdWxkIGJlCgkJLy8gYSBwYXJ0IG9mIHRoZSBjdXJyZW50IHN0cmluZy4KCQlUKiBvbGRBcnJheSA9IGFycmF5OwoKICAgICAgICBhbGxvY2F0ZWQgPSB1c2VkID0gbGVuKzE7CgkJYXJyYXkgPSBuZXcgVFt1c2VkXTsKCgkJZm9yIChzMzIgbCA9IDA7IGw8bGVuKzE7ICsrbCkKCQkJYXJyYXlbbF0gPSAoVCljW2xdOwoKCQlkZWxldGUgW10gb2xkQXJyYXk7CgkJcmV0dXJuICp0aGlzOwoJfQoKCS8vISBBZGQgb3BlcmF0b3IgZm9yIG90aGVyIHN0cmluZ3MKCXN0cmluZzxUPiBvcGVyYXRvcisoY29uc3Qgc3RyaW5nPFQ+JiBvdGhlcikgCgl7IAoJCXN0cmluZzxUPiBzdHIoKnRoaXMpOyAKCQlzdHIuYXBwZW5kKG90aGVyKTsgCgoJCXJldHVybiBzdHI7IAoJfSAKCgkvLyEgQWRkIG9wZXJhdG9yIGZvciBzdHJpbmdzLCBhc2NpaSBhbmQgdW5pY29kZSAKCXRlbXBsYXRlIDxjbGFzcyBCPiAKCXN0cmluZzxUPiBvcGVyYXRvcisoY29uc3QgQiogYykgCgl7IAoJCXN0cmluZzxUPiBzdHIoKnRoaXMpOyAKCQlzdHIuYXBwZW5kKGMpOyAKCgkJcmV0dXJuIHN0cjsgCgl9CgoKCgkvLyEgRGlyZWN0IGFjY2VzcyBvcGVyYXRvcgoJVCYgb3BlcmF0b3IgW10oY29uc3QgczMyIGluZGV4KSAgY29uc3QKCXsKCQlfSVJSX0RFQlVHX0JSRUFLX0lGKGluZGV4Pj11c2VkKSAvLyBiYWQgaW5kZXgKCgkJcmV0dXJuIGFycmF5W2luZGV4XTsKCX0KCgoJLy8hIENvbXBhcmlzb24gb3BlcmF0b3IKCWJvb2wgb3BlcmF0b3IgPT0oY29uc3QgVCogc3RyKSBjb25zdAoJewoJCWludCBpOwoJCWZvcihpPTA7IGFycmF5W2ldICYmIHN0cltpXTsgKytpKQoJCQlpZiAoYXJyYXlbaV0gIT0gc3RyW2ldKQoJCQkJcmV0dXJuIGZhbHNlOwoKCQlyZXR1cm4gIWFycmF5W2ldICYmICFzdHJbaV07Cgl9CgoKCgkvLyEgQ29tcGFyaXNvbiBvcGVyYXRvcgoJYm9vbCBvcGVyYXRvciA9PShjb25zdCBzdHJpbmc8VD4mIG90aGVyKSBjb25zdAoJewoJCWZvcihzMzIgaT0wOyBhcnJheVtpXSAmJiBvdGhlci5hcnJheVtpXTsgKytpKQoJCQlpZiAoYXJyYXlbaV0gIT0gb3RoZXIuYXJyYXlbaV0pCgkJCQlyZXR1cm4gZmFsc2U7CgoJCXJldHVybiB1c2VkID09IG90aGVyLnVzZWQ7Cgl9CgoKCgkvLyEgSXMgc21hbGxlciBvcGVyYXRvcgoJYm9vbCBvcGVyYXRvciA8KGNvbnN0IHN0cmluZzxUPiYgb3RoZXIpIGNvbnN0Cgl7CgkJZm9yKHMzMiBpPTA7IGFycmF5W2ldICYmIG90aGVyLmFycmF5W2ldOyArK2kpCgkJCWlmIChhcnJheVtpXSAhPSBvdGhlci5hcnJheVtpXSkKCQkJCXJldHVybiAoYXJyYXlbaV0gPCBvdGhlci5hcnJheVtpXSk7CgoJCXJldHVybiB1c2VkIDwgb3RoZXIudXNlZDsKCX0KCgoKCS8vISBFcXVhbHMgbm90IG9wZXJhdG9yCglib29sIG9wZXJhdG9yICE9KGNvbnN0IHN0cmluZzxUPiYgb3RoZXIpIGNvbnN0Cgl7CgkJcmV0dXJuICEoKnRoaXMgPT0gb3RoZXIpOwoJfQoKCiAgICAKCS8vISBSZXR1cm5zIGxlbmd0aCBvZiBzdHJpbmcKCS8qKiBccmV0dXJuIFJldHVybnMgbGVuZ3RoIG9mIHRoZSBzdHJpbmcgaW4gY2hhcmFjdGVycy4gKi8KCXMzMiBzaXplKCkgY29uc3QKCXsKCQlyZXR1cm4gdXNlZC0xOwoJfQoKCgoJLy8hIFJldHVybnMgY2hhcmFjdGVyIHN0cmluZwoJLyoqIFxyZXR1cm4gUmV0dXJucyBwb2ludGVyIHRvIEMtc3R5bGUgemVybyB0ZXJtaW5hdGVkIHN0cmluZy4gKi8KCWNvbnN0IFQqIGNfc3RyKCkgY29uc3QKCXsKCQlyZXR1cm4gYXJyYXk7Cgl9CgoKCgkvLyEgTWFrZXMgdGhlIHN0cmluZyBsb3dlciBjYXNlLgoJdm9pZCBtYWtlX2xvd2VyKCkKCXsKCQljb25zdCBUIEEgPSAoVCknQSc7CgkJY29uc3QgVCBaID0gKFQpJ1onOwoJCWNvbnN0IFQgZGlmZiA9IChUKSdhJyAtIEE7CgoJCWZvciAoczMyIGk9MDsgaTx1c2VkOyArK2kpCgkJewoJCQlpZiAoYXJyYXlbaV0+PUEgJiYgYXJyYXlbaV08PVopCgkJCQlhcnJheVtpXSArPSBkaWZmOwoJCX0KCX0KCgoKCS8vISBNYWtlcyB0aGUgc3RyaW5nIHVwcGVyIGNhc2UuCgl2b2lkIG1ha2VfdXBwZXIoKQoJewoJCWNvbnN0IFQgYSA9IChUKSdhJzsKCQljb25zdCBUIHogPSAoVCkneic7CgkJY29uc3QgVCBkaWZmID0gKFQpJ0EnIC0gYTsKCgkJZm9yIChzMzIgaT0wOyBpPHVzZWQ7ICsraSkKCQl7CgkJCWlmIChhcnJheVtpXT49YSAmJiBhcnJheVtpXTw9eikKCQkJCWFycmF5W2ldICs9IGRpZmY7CgkJfQoJfQoKCgoJLy8hIENvbXBhcmVzIHRoZSBzdHJpbmcgaWdub3JpbmcgY2FzZS4KCS8qKiBccGFyYW0gb3RoZXI6IE90aGVyIHN0cmluZyB0byBjb21wYXJlLgoJXHJldHVybiBSZXR1cm5zIHRydWUgaWYgdGhlIHN0cmluZyBhcmUgZXF1YWwgaWdub3JpbmcgY2FzZS4gKi8KCWJvb2wgZXF1YWxzX2lnbm9yZV9jYXNlKGNvbnN0IHN0cmluZzxUPiYgb3RoZXIpIGNvbnN0Cgl7CgkJZm9yKHMzMiBpPTA7IGFycmF5W2ldICYmIG90aGVyW2ldOyArK2kpCgkJCWlmICh0b0xvd2VyKGFycmF5W2ldKSAhPSB0b0xvd2VyKG90aGVyW2ldKSkKCQkJCXJldHVybiBmYWxzZTsKCgkJcmV0dXJuIHVzZWQgPT0gb3RoZXIudXNlZDsKCX0KCgoJLy8hIGNvbXBhcmVzIHRoZSBmaXJzdCBuIGNoYXJhY3RlcnMgb2YgdGhlIHN0cmluZ3MKCWJvb2wgZXF1YWxzbihjb25zdCBzdHJpbmc8VD4mIG90aGVyLCBpbnQgbGVuKQoJewoJCWludCBpOwoJCWZvcihpPTA7IGFycmF5W2ldICYmIG90aGVyW2ldICYmIGkgPCBsZW47ICsraSkKCQkJaWYgKGFycmF5W2ldICE9IG90aGVyW2ldKQoJCQkJcmV0dXJuIGZhbHNlOwoKCQkvLyBpZiBvbmUgKG9yIGJvdGgpIG9mIHRoZSBzdHJpbmdzIHdhcyBzbWFsbGVyIHRoZW4gdGhleQoJCS8vIGFyZSBvbmx5IGVxdWFsIGlmIHRoZXkgaGF2ZSB0aGUgc2FtZSBsZW5naHQKCQlyZXR1cm4gKGkgPT0gbGVuKSB8fCAodXNlZCA9PSBvdGhlci51c2VkKTsKCX0KCgoJLy8hIGNvbXBhcmVzIHRoZSBmaXJzdCBuIGNoYXJhY3RlcnMgb2YgdGhlIHN0cmluZ3MKCWJvb2wgZXF1YWxzbihjb25zdCBUKiBzdHIsIGludCBsZW4pCgl7CgkJaW50IGk7CQoJCWZvcihpPTA7IGFycmF5W2ldICYmIHN0cltpXSAmJiBpIDwgbGVuOyArK2kpCgkJCWlmIChhcnJheVtpXSAhPSBzdHJbaV0pCgkJCQlyZXR1cm4gZmFsc2U7CgoJCS8vIGlmIG9uZSAob3IgYm90aCkgb2YgdGhlIHN0cmluZ3Mgd2FzIHNtYWxsZXIgdGhlbiB0aGV5CgkJLy8gYXJlIG9ubHkgZXF1YWwgaWYgdGhleSBoYXZlIHRoZSBzYW1lIGxlbmdodAoJCXJldHVybiAoaSA9PSBsZW4pIHx8IChhcnJheVtpXSA9PSAwICYmIHN0cltpXSA9PSAwKTsKCX0KCgoJLy8hIEFwcGVuZHMgYSBjaGFyYWN0ZXIgdG8gdGhpcyBzdHJpbmcKCS8qKiBccGFyYW0gY2hhcmFjdGVyOiBDaGFyYWN0ZXIgdG8gYXBwZW5kLiAqLwoJdm9pZCBhcHBlbmQoVCBjaGFyYWN0ZXIpCgl7CgkJaWYgKHVzZWQgKyAxID4gYWxsb2NhdGVkKQoJCQlyZWFsbG9jYXRlKChzMzIpdXNlZCArIDEpOwoKCQl1c2VkICs9IDE7CgoJCWFycmF5W3VzZWQtMl0gPSBjaGFyYWN0ZXI7CgkJYXJyYXlbdXNlZC0xXSA9IDA7Cgl9CgoJLy8hIEFwcGVuZHMgYSBzdHJpbmcgdG8gdGhpcyBzdHJpbmcKCS8qKiBccGFyYW0gb3RoZXI6IFN0cmluZyB0byBhcHBlbmQuICovCgl2b2lkIGFwcGVuZChjb25zdCBzdHJpbmc8VD4mIG90aGVyKQoJewoJCS0tdXNlZDsKCgkJczMyIGxlbiA9IG90aGVyLnNpemUoKTsKCQkKCQlpZiAodXNlZCArIGxlbiArIDEgPiBhbGxvY2F0ZWQpCgkJCXJlYWxsb2NhdGUoKHMzMil1c2VkICsgKHMzMilsZW4gKyAxKTsKCgkJZm9yIChzMzIgbD0wOyBsPGxlbisxOyArK2wpCgkJCWFycmF5W2wrdXNlZF0gPSBvdGhlcltsXTsKCgkJdXNlZCA9IHVzZWQgKyBsZW4gKyAxOwoJfQoKCgkvLyEgQXBwZW5kcyBhIHN0cmluZyBvZiB0aGUgbGVuZ3RoIGwgdG8gdGhpcyBzdHJpbmcuCgkvKiogXHBhcmFtIG90aGVyOiBvdGhlciBTdHJpbmcgdG8gYXBwZW5kIHRvIHRoaXMgc3RyaW5nLgoJIFxwYXJhbSBsZW5ndGg6IEhvdyBtdWNoIGNoYXJhY3RlcnMgb2YgdGhlIG90aGVyIHN0cmluZyB0byBhZGQgdG8gdGhpcyBvbmUuICovCgl2b2lkIGFwcGVuZChjb25zdCBzdHJpbmc8VD4mIG90aGVyLCBzMzIgbGVuZ3RoKQoJewoJCXMzMiBsZW4gPSBvdGhlci5zaXplKCk7CgoJCWlmIChsZW4gPCBsZW5ndGgpCgkJewoJCQlhcHBlbmQob3RoZXIpOwoJCQlyZXR1cm47CgkJfQoKCQlsZW4gPSBsZW5ndGg7CgkJLS11c2VkOwoJCQoJCWlmICh1c2VkICsgbGVuID4gYWxsb2NhdGVkKQoJCQlyZWFsbG9jYXRlKChzMzIpdXNlZCArIChzMzIpbGVuKTsKCgkJZm9yIChzMzIgbD0wOyBsPGxlbjsgKytsKQoJCQlhcnJheVtsK3VzZWRdID0gb3RoZXJbbF07CgoJCXVzZWQgPSB1c2VkICsgbGVuOwoJfQoKCgkvLyEgUmVzZXJ2ZXMgc29tZSBtZW1vcnkuCgkvKiogXHBhcmFtIGNvdW50OiBBbW91bnQgb2YgY2hhcmFjdGVycyB0byByZXNlcnZlLiAqLwoJdm9pZCByZXNlcnZlKHMzMiBjb3VudCkKCXsKCQlpZiAoY291bnQgPCBhbGxvY2F0ZWQpCgkJCXJldHVybjsKCgkJcmVhbGxvY2F0ZShjb3VudCk7Cgl9CgoKCS8vISBmaW5kcyBmaXJzdCBvY2N1cnJlbmNlIG9mIGNoYXJhY3RlciBpbiBzdHJpbmcKCS8qKiBccGFyYW0gYzogQ2hhcmFjdGVyIHRvIHNlYXJjaCBmb3IuCglccmV0dXJuIFJldHVybnMgcG9zaXRpb24gd2hlcmUgdGhlIGNoYXJhY3RlciBoYXMgYmVlbiBmb3VuZCwKCW9yIC0xIGlmIG5vdCBmb3VuZC4gKi8KCXMzMiBmaW5kRmlyc3QoVCBjKSBjb25zdAoJewoJCWZvciAoczMyIGk9MDsgaTx1c2VkOyArK2kpCgkJCWlmIChhcnJheVtpXSA9PSBjKQoJCQkJcmV0dXJuIGk7CgoJCXJldHVybiAtMTsKCX0KCgkvLyEgZmluZHMgZmlyc3Qgb2NjdXJyZW5jZSBvZiBhIGNoYXJhY3RlciBvZiBhIGxpc3QgaW4gc3RyaW5nCgkvKiogXHBhcmFtIGM6IExpc3Qgb2Ygc3RyaW5ncyB0byBmaW5kLiBGb3IgZXhhbXBsZSBpZiB0aGUgbWV0aG9kCglzaG91bGQgZmluZCB0aGUgZmlyc3Qgb2NjdXJhbmNlIG9mICdhJyBvciAnYicsIHRoaXMgcGFyYW1ldGVyIHNob3VsZCBiZSAiYWIiLgoJXHBhcmFtIGNvdW50OiBBbW91bnQgb2YgY2hhcmFjdGVycyBpbiB0aGUgbGlzdC4gVXN1c2FsbHksIAoJdGhpcyBzaG91bGQgYmUgc3RybGVuKG9mUGFyYW1ldGVyMSkKCVxyZXR1cm4gUmV0dXJucyBwb3NpdGlvbiB3aGVyZSBvbmUgb2YgdGhlIGNoYXJhY3RlciBoYXMgYmVlbiBmb3VuZCwKCW9yIC0xIGlmIG5vdCBmb3VuZC4gKi8KCXMzMiBmaW5kRmlyc3RDaGFyKFQqIGMsIGludCBjb3VudCkgY29uc3QKCXsKCQlmb3IgKHMzMiBpPTA7IGk8dXNlZDsgKytpKQoJCQlmb3IgKGludCBqPTA7IGo8Y291bnQ7ICsraikKCQkJCWlmIChhcnJheVtpXSA9PSBjW2pdKQoJCQkJCXJldHVybiBpOwoKCQlyZXR1cm4gLTE7Cgl9CgoKCS8vISBGaW5kcyBmaXJzdCBwb3NpdGlvbiBvZiBhIGNoYXJhY3RlciBub3QgaW4gYSBnaXZlbiBsaXN0LgoJLyoqIFxwYXJhbSBjOiBMaXN0IG9mIGNoYXJhY3RlcnMgbm90IHRvIGZpbmQuIEZvciBleGFtcGxlIGlmIHRoZSBtZXRob2QKCSBzaG91bGQgZmluZCB0aGUgZmlyc3Qgb2NjdXJhbmNlIG9mIGEgY2hhcmFjdGVyIG5vdCAnYScgb3IgJ2InLCB0aGlzIHBhcmFtZXRlciBzaG91bGQgYmUgImFiIi4KCVxwYXJhbSBjb3VudDogQW1vdW50IG9mIGNoYXJhY3RlcnMgaW4gdGhlIGxpc3QuIFVzdXNhbGx5LCAKCXRoaXMgc2hvdWxkIGJlIHN0cmxlbihvZlBhcmFtZXRlcjEpCglccmV0dXJuIFJldHVybnMgcG9zaXRpb24gd2hlcmUgdGhlIGNoYXJhY3RlciBoYXMgYmVlbiBmb3VuZCwKCW9yIC0xIGlmIG5vdCBmb3VuZC4gKi8KCXRlbXBsYXRlIDxjbGFzcyBCPiAKCXMzMiBmaW5kRmlyc3RDaGFyTm90SW5MaXN0KEIqIGMsIGludCBjb3VudCkgY29uc3QKCXsKCQlmb3IgKGludCBpPTA7IGk8dXNlZDsgKytpKQoJCXsKICAgICAgICAgICAgaW50IGo7CgkJCWZvciAoaj0wOyBqPGNvdW50OyArK2opCgkJCQlpZiAoYXJyYXlbaV0gPT0gY1tqXSkKCQkJCQlicmVhazsKCgkJCWlmIChqPT1jb3VudCkKCQkJCXJldHVybiBpOwoJCX0KCgkJcmV0dXJuIC0xOwoJfQoKCS8vISBGaW5kcyBsYXN0IHBvc2l0aW9uIG9mIGEgY2hhcmFjdGVyIG5vdCBpbiBhIGdpdmVuIGxpc3QuCgkvKiogXHBhcmFtIGM6IExpc3Qgb2YgY2hhcmFjdGVycyBub3QgdG8gZmluZC4gRm9yIGV4YW1wbGUgaWYgdGhlIG1ldGhvZAoJIHNob3VsZCBmaW5kIHRoZSBmaXJzdCBvY2N1cmFuY2Ugb2YgYSBjaGFyYWN0ZXIgbm90ICdhJyBvciAnYicsIHRoaXMgcGFyYW1ldGVyIHNob3VsZCBiZSAiYWIiLgoJXHBhcmFtIGNvdW50OiBBbW91bnQgb2YgY2hhcmFjdGVycyBpbiB0aGUgbGlzdC4gVXN1c2FsbHksIAoJdGhpcyBzaG91bGQgYmUgc3RybGVuKG9mUGFyYW1ldGVyMSkKCVxyZXR1cm4gUmV0dXJucyBwb3NpdGlvbiB3aGVyZSB0aGUgY2hhcmFjdGVyIGhhcyBiZWVuIGZvdW5kLAoJb3IgLTEgaWYgbm90IGZvdW5kLiAqLwoJdGVtcGxhdGUgPGNsYXNzIEI+IAoJczMyIGZpbmRMYXN0Q2hhck5vdEluTGlzdChCKiBjLCBpbnQgY291bnQpIGNvbnN0Cgl7CgkJZm9yIChpbnQgaT11c2VkLTI7IGk+PTA7IC0taSkKCQl7CiAgICAgICAgICAgIGludCBqOwoJCQlmb3IgKGo9MDsgajxjb3VudDsgKytqKQoJCQkJaWYgKGFycmF5W2ldID09IGNbal0pCgkJCQkJYnJlYWs7CgoJCQlpZiAoaj09Y291bnQpCgkJCQlyZXR1cm4gaTsKCQl9CgoJCXJldHVybiAtMTsKCX0KCgkvLyEgZmluZHMgbmV4dCBvY2N1cnJlbmNlIG9mIGNoYXJhY3RlciBpbiBzdHJpbmcKCS8qKiBccGFyYW0gYzogQ2hhcmFjdGVyIHRvIHNlYXJjaCBmb3IuCglccGFyYW0gc3RhcnRQb3M6IFBvc2l0aW9uIGluIHN0cmluZyB0byBzdGFydCBzZWFyY2hpbmcuIAoJXHJldHVybiBSZXR1cm5zIHBvc2l0aW9uIHdoZXJlIHRoZSBjaGFyYWN0ZXIgaGFzIGJlZW4gZm91bmQsCglvciAtMSBpZiBub3QgZm91bmQuICovCglzMzIgZmluZE5leHQoVCBjLCBzMzIgc3RhcnRQb3MpIGNvbnN0Cgl7CgkJZm9yIChzMzIgaT1zdGFydFBvczsgaTx1c2VkOyArK2kpCgkJCWlmIChhcnJheVtpXSA9PSBjKQoJCQkJcmV0dXJuIGk7CgoJCXJldHVybiAtMTsKCX0KCgoJLy8hIGZpbmRzIGxhc3Qgb2NjdXJyZW5jZSBvZiBjaGFyYWN0ZXIgaW4gc3RyaW5nCgkvLyEgXHBhcmFtIGM6IENoYXJhY3RlciB0byBzZWFyY2ggZm9yLgoJLy8hIFxyZXR1cm4gUmV0dXJucyBwb3NpdGlvbiB3aGVyZSB0aGUgY2hhcmFjdGVyIGhhcyBiZWVuIGZvdW5kLAoJLy8hIG9yIC0xIGlmIG5vdCBmb3VuZC4KCXMzMiBmaW5kTGFzdChUIGMpIGNvbnN0Cgl7CgkJZm9yIChzMzIgaT11c2VkLTE7IGk+PTA7IC0taSkKCQkJaWYgKGFycmF5W2ldID09IGMpCgkJCQlyZXR1cm4gaTsKCgkJcmV0dXJuIC0xOwoJfQoKCgkvLyEgUmV0dXJucyBhIHN1YnN0cmluZwoJLy8hIFxwYXJhbSBiZWdpbjogU3RhcnQgb2Ygc3Vic3RyaW5nLgoJLy8hIFxwYXJhbSBsZW5ndGg6IExlbmd0aCBvZiBzdWJzdHJpbmcuCglzdHJpbmc8VD4gc3ViU3RyaW5nKHMzMiBiZWdpbiwgczMyIGxlbmd0aCkKCXsKCQlpZiAobGVuZ3RoIDw9IDApCgkJCXJldHVybiBzdHJpbmc8VD4oIiIpOwoKCQlzdHJpbmc8VD4gbzsKCQlvLnJlc2VydmUobGVuZ3RoKzEpOwoKCQlmb3IgKHMzMiBpPTA7IGk8bGVuZ3RoOyArK2kpCgkJCW8uYXJyYXlbaV0gPSBhcnJheVtpK2JlZ2luXTsKCgkJby5hcnJheVtsZW5ndGhdID0gMDsKCQlvLnVzZWQgPSBvLmFsbG9jYXRlZDsKCgkJcmV0dXJuIG87Cgl9CgoKCXZvaWQgb3BlcmF0b3IgKz0gKFQgYykKCXsKCQlhcHBlbmQoYyk7Cgl9CgoJdm9pZCBvcGVyYXRvciArPSAoY29uc3Qgc3RyaW5nPFQ+JiBvdGhlcikKCXsKCQlhcHBlbmQob3RoZXIpOwoJfQoKCXZvaWQgb3BlcmF0b3IgKz0gKGludCBpKQoJewoJCWFwcGVuZChzdHJpbmc8VD4oaSkpOwoJfQoKCS8vISByZXBsYWNlcyBhbGwgY2hhcmFjdGVycyBvZiBhIHNwZWNpYWwgdHlwZSB3aXRoIGFub3RoZXIgb25lCgl2b2lkIHJlcGxhY2UoVCB0b1JlcGxhY2UsIFQgcmVwbGFjZVdpdGgpCgl7CgkJZm9yIChzMzIgaT0wOyBpPHVzZWQ7ICsraSkKCQkJaWYgKGFycmF5W2ldID09IHRvUmVwbGFjZSkKCQkJCWFycmF5W2ldID0gcmVwbGFjZVdpdGg7Cgl9CgoJLy8hIHRyaW1zIHRoZSBzdHJpbmcuCgkvKiogUmVtb3ZlcyB3aGl0ZXNwYWNlIGZyb20gYmVnaW4gYW5kIGVuZCBvZiB0aGUgc3RyaW5nLiAqLwoJdm9pZCB0cmltKCkKCXsKCQljb25zdCBjaGFyIHdoaXRlc3BhY2VbXSA9ICIgXHRcbiI7CgkJY29uc3QgaW50IHdoaXRlc3BhY2Vjb3VudCA9IDM7CgoJCS8vIGZpbmQgc3RhcnQgYW5kIGVuZCBvZiByZWFsIHN0cmluZyB3aXRob3V0IHdoaXRlc3BhY2UKCQlpbnQgYmVnaW4gPSBmaW5kRmlyc3RDaGFyTm90SW5MaXN0KHdoaXRlc3BhY2UsIHdoaXRlc3BhY2Vjb3VudCk7CgkJaWYgKGJlZ2luID09IC0xKQoJCQlyZXR1cm47CgoJCWludCBlbmQgPSBmaW5kTGFzdENoYXJOb3RJbkxpc3Qod2hpdGVzcGFjZSwgd2hpdGVzcGFjZWNvdW50KTsKCQlpZiAoZW5kID09IC0xKQoJCQlyZXR1cm47CgoJCSp0aGlzID0gc3ViU3RyaW5nKGJlZ2luLCAoZW5kICsxKSAtIGJlZ2luKTsKCX0KCgoJLy8hIEVyYXNlcyBhIGNoYXJhY3RlciBmcm9tIHRoZSBzdHJpbmcuIE1heSBiZSBzbG93LCBiZWNhdXNlIGFsbCBlbGVtZW50cyAKCS8vISBmb2xsb3dpbmcgYWZ0ZXIgdGhlIGVyYXNlZCBlbGVtZW50IGhhdmUgdG8gYmUgY29waWVkLgoJLy8hIFxwYXJhbSBpbmRleDogSW5kZXggb2YgZWxlbWVudCB0byBiZSBlcmFzZWQuCgl2b2lkIGVyYXNlKGludCBpbmRleCkKCXsKCQlfSVJSX0RFQlVHX0JSRUFLX0lGKGluZGV4Pj11c2VkIHx8IGluZGV4PDApIC8vIGFjY2VzcyB2aW9sYXRpb24KCgkJZm9yIChpbnQgaT1pbmRleCsxOyBpPHVzZWQ7ICsraSkKCQkJYXJyYXlbaS0xXSA9IGFycmF5W2ldOwoKCQktLXVzZWQ7Cgl9CgogICAgCQoKcHJpdmF0ZToKCgkvLyEgUmV0dXJucyBhIGNoYXJhY3RlciBjb252ZXJ0ZWQgdG8gbG93ZXIgY2FzZQoJVCB0b0xvd2VyKGNvbnN0IFQmIHQpIGNvbnN0Cgl7CgkJaWYgKHQ+PShUKSdBJyAmJiB0PD0oVCknWicpCgkJCXJldHVybiB0ICsgKChUKSdhJyAtIChUKSdBJyk7CgkJZWxzZQoJCQlyZXR1cm4gdDsKCX0KCgkvLyEgUmVhbGxvY2F0ZSB0aGUgYXJyYXksIG1ha2UgaXQgYmlnZ2VyIG9yIHNtYWxlcgoJdm9pZCByZWFsbG9jYXRlKHMzMiBuZXdfc2l6ZSkKCXsKCQlUKiBvbGRfYXJyYXkgPSBhcnJheTsKCgkJYXJyYXkgPSBuZXcgVFtuZXdfc2l6ZV07CgkJYWxsb2NhdGVkID0gbmV3X3NpemU7CgkJCgkJczMyIGFtb3VudCA9IHVzZWQgPCBuZXdfc2l6ZSA/IHVzZWQgOiBuZXdfc2l6ZTsKCQlmb3IgKHMzMiBpPTA7IGk8YW1vdW50OyArK2kpCgkJCWFycmF5W2ldID0gb2xkX2FycmF5W2ldOwoKCQlpZiAoYWxsb2NhdGVkIDwgdXNlZCkKCQkJdXNlZCA9IGFsbG9jYXRlZDsKCQkKCQlkZWxldGUgW10gb2xkX2FycmF5OwoJfQoKCgkvLy0tLSBtZW1iZXIgdmFyaWFibGVzCgoJVCogYXJyYXk7CglzMzIgYWxsb2NhdGVkOwoJczMyIHVzZWQ7Cn07CgoKLy8hIFR5cGVkZWYgZm9yIGNoYXJhY3RlciBzdHJpbmdzCnR5cGVkZWYgc3RyaW5nPGlycjo6Yzg+IHN0cmluZ2M7CgovLyEgVHlwZWRlZiBmb3Igd2lkZSBjaGFyYWN0ZXIgc3RyaW5ncwp0eXBlZGVmIHN0cmluZzx3Y2hhcl90PiBzdHJpbmd3OwoKfSAvLyBlbmQgbmFtZXNwYWNlIGNvcmUKfSAvLyBlbmQgbmFtZXNwYWNlIGlycgoKI2VuZGlmCgo=