Ly89PT0tIFNQSVJWU3RyZWFtLmNwcCCWIENsYXNzIHRvIHJlcHJlc2VudCBhIFNQSVItViBTdHJlYW0gLS0tLS0tKi0gQysrIC0qLT09PS8vDQovLw0KLy8gICAgICAgICAgICAgICAgICAgICBUaGUgTExWTS9TUElSViBUcmFuc2xhdG9yDQovLw0KLy8gVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBVbml2ZXJzaXR5IG9mIElsbGlub2lzIE9wZW4gU291cmNlDQovLyBMaWNlbnNlLiBTZWUgTElDRU5TRS5UWFQgZm9yIGRldGFpbHMuDQovLw0KLy8gQ29weXJpZ2h0IChjKSAyMDE0IEFkdmFuY2VkIE1pY3JvIERldmljZXMsIEluYy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi8vDQovLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYQ0KLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSAiU29mdHdhcmUiKSwNCi8vIHRvIGRlYWwgd2l0aCB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbg0KLy8gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsDQovLyBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUNCi8vIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6DQovLw0KLy8gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLA0KLy8gdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcnMuDQovLyBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsDQovLyB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVycyBpbiB0aGUgZG9jdW1lbnRhdGlvbg0KLy8gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uDQovLyBOZWl0aGVyIHRoZSBuYW1lcyBvZiBBZHZhbmNlZCBNaWNybyBEZXZpY2VzLCBJbmMuLCBub3IgdGhlIG5hbWVzIG9mIGl0cw0KLy8gY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcw0KLy8gU29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uDQovLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUg0KLy8gSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksDQovLyBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUNCi8vIENPTlRSSUJVVE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUg0KLy8gTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwNCi8vIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgV0lUSA0KLy8gVEhFIFNPRlRXQVJFLg0KLy8NCi8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vDQovLy8gXGZpbGUNCi8vLw0KLy8vIFRoaXMgZmlsZSBpbXBsZW1lbnRzIFNQSVItViBzdHJlYW0gY2xhc3MuDQovLy8NCi8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vDQojaW5jbHVkZSAiU1BJUlZEZWJ1Zy5oIg0KI2luY2x1ZGUgIlNQSVJWU3RyZWFtLmgiDQojaW5jbHVkZSAiU1BJUlZGdW5jdGlvbi5oIg0KI2luY2x1ZGUgIlNQSVJWT3BDb2RlLmgiDQojaW5jbHVkZSAiU1BJUlZOYW1lTWFwRW51bS5oIg0KDQpuYW1lc3BhY2UgU1BJUlZ7DQoNCi8vLyBXcml0ZSBzdHJpbmcgd2l0aCBxdW90ZS4gUmVwbGFjZSAiIHdpdGggXCIuDQpzdGF0aWMgdm9pZCB3cml0ZVF1b3RlZFN0cmluZyhzcHZfb3N0cmVhbSYgTywgY29uc3Qgc3RkOjpzdHJpbmcmIFN0cikgew0KICBPIDw8ICciJzsNCiAgZm9yIChhdXRvIEkgOiBTdHIpIHsNCiAgICBpZiAoSSA9PSAnIicpDQogICAgICBPIDw8ICdcXCc7DQogICAgTyA8PCBJOw0KICB9DQogIE8gPDwgJyInOw0KfQ0KDQovLy8gUmVhZCBxdW90ZWQgc3RyaW5nLiBSZXBsYWNlIFwiIHdpdGggIi4NCnN0YXRpYyB2b2lkIHJlYWRRdW90ZWRTdHJpbmcoc3RkOjppc3RyZWFtICZJUywgc3RkOjpzdHJpbmcmIFN0cikgew0KICBjaGFyIENoID0gJyAnOw0KICBjaGFyIFByZUNoID0gJyAnOw0KICB3aGlsZSAoSVMgPj4gQ2ggJiYgQ2ggIT0gJyInKQ0KICAgIDsNCg0KICBpZiAoSVMgPj4gUHJlQ2ggJiYgUHJlQ2ggIT0gJyInKSB7DQogICAgd2hpbGUgKElTID4+IENoKSB7DQogICAgICBpZiAoQ2ggPT0gJyInKSB7DQogICAgICAgIGlmIChQcmVDaCAhPSAnXFwnKSB7DQogICAgICAgICAgU3RyICs9IFByZUNoOw0KICAgICAgICAgIGJyZWFrOw0KICAgICAgICB9DQogICAgICAgIGVsc2UNCiAgICAgICAgICBQcmVDaCA9IENoOw0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgU3RyICs9IFByZUNoOw0KICAgICAgICBQcmVDaCA9IENoOw0KICAgICAgfQ0KICAgIH0NCiAgfQ0KfQ0KDQojaWZkZWYgX1NQSVJWX1NVUFBPUlRfVEVYVF9GTVQNCmJvb2wgU1BJUlZVc2VUZXh0Rm9ybWF0ID0gZmFsc2U7DQojZW5kaWYNCg0KU1BJUlZEZWNvZGVyOjpTUElSVkRlY29kZXIoc3RkOjppc3RyZWFtICZJbnB1dFN0cmVhbSwgU1BJUlZGdW5jdGlvbiAmRikNCiAgOklTKElucHV0U3RyZWFtKSwgTSgqRi5nZXRNb2R1bGUoKSksIFdvcmRDb3VudCgwKSwgT3BDb2RlKE9wTm9wKSwNCiAgIFNjb3BlKCZGKXt9DQoNClNQSVJWRGVjb2Rlcjo6U1BJUlZEZWNvZGVyKHN0ZDo6aXN0cmVhbSAmSW5wdXRTdHJlYW0sIFNQSVJWQmFzaWNCbG9jayAmQkIpDQogIDpJUyhJbnB1dFN0cmVhbSksIE0oKkJCLmdldE1vZHVsZSgpKSwgV29yZENvdW50KDApLCBPcENvZGUoT3BOb3ApLA0KICAgU2NvcGUoJkJCKXt9DQoNCnZvaWQNClNQSVJWRGVjb2Rlcjo6c2V0U2NvcGUoU1BJUlZFbnRyeSAqVGhlU2NvcGUpIHsNCiAgYXNzZXJ0KFRoZVNjb3BlICYmIChUaGVTY29wZS0+Z2V0T3BDb2RlKCkgPT0gT3BGdW5jdGlvbiB8fA0KICAgICAgVGhlU2NvcGUtPmdldE9wQ29kZSgpID09IE9wTGFiZWwpKTsNCiAgU2NvcGUgPSBUaGVTY29wZTsNCn0NCg0KdGVtcGxhdGU8Y2xhc3MgVD4NCmNvbnN0IFNQSVJWRGVjb2RlciYNCmRlY29kZShjb25zdCBTUElSVkRlY29kZXImIEksIFQgJlYpIHsNCiNpZmRlZiBfU1BJUlZfU1VQUE9SVF9URVhUX0ZNVA0KICBpZiAoU1BJUlZVc2VUZXh0Rm9ybWF0KSB7DQogICAgc3RkOjpzdHJpbmcgVzsNCiAgICBJLklTID4+IFc7DQogICAgViA9IGdldE5hbWVNYXAoVikucm1hcChXKTsNCiAgICBTUElSVkRCRyhzcHZkYmdzKCkgPDwgIlJlYWQgd29yZDogVyA9ICIgPDwgVyA8PCAiIFYgPSAiIDw8IFYgPDwgJ1xuJyk7DQogICAgcmV0dXJuIEk7DQogIH0NCiNlbmRpZg0KICByZXR1cm4gRGVjb2RlQmluYXJ5KEksIFYpOw0KfQ0KDQp0ZW1wbGF0ZTxjbGFzcyBUPg0KY29uc3QgU1BJUlZFbmNvZGVyJg0KZW5jb2RlKGNvbnN0IFNQSVJWRW5jb2RlciYgTywgVCBWKSB7DQojaWZkZWYgX1NQSVJWX1NVUFBPUlRfVEVYVF9GTVQNCiAgaWYgKFNQSVJWVXNlVGV4dEZvcm1hdCkgew0KICAgIE8uT1MgPDwgZ2V0TmFtZU1hcChWKS5tYXAoVikgPDwgIiAiOw0KICAgIHJldHVybiBPOw0KICB9DQojZW5kaWYNCiAgcmV0dXJuIE8gPDwgc3RhdGljX2Nhc3Q8U1BJUlZXb3JkPihWKTsNCn0NCg0KI2RlZmluZSBTUElSVl9ERUZfRU5DREVDKFR5cGUpIFwNCmNvbnN0IFNQSVJWRGVjb2RlciYgXA0Kb3BlcmF0b3I+Pihjb25zdCBTUElSVkRlY29kZXImIEksIFR5cGUgJlYpIHsgXA0KICByZXR1cm4gZGVjb2RlKEksIFYpOyBcDQp9XA0KY29uc3QgU1BJUlZFbmNvZGVyJiBcDQpvcGVyYXRvcjw8KGNvbnN0IFNQSVJWRW5jb2RlciYgTywgVHlwZSBWKSB7IFwNCiAgcmV0dXJuIGVuY29kZShPLCBWKTsgXA0KfQ0KDQpTUElSVl9ERUZfRU5DREVDKE9wKQ0KU1BJUlZfREVGX0VOQ0RFQyhDYXBhYmlsaXR5KQ0KU1BJUlZfREVGX0VOQ0RFQyhEZWNvcmF0aW9uKQ0KU1BJUlZfREVGX0VOQ0RFQyhPQ0xFeHRPcEtpbmQpDQpTUElSVl9ERUZfRU5DREVDKExpbmthZ2VUeXBlKQ0KDQovLyBSZWFkIGEgc3RyaW5nIHdpdGggcGFkZGVkIDAncyBhdCB0aGUgZW5kIHNvIHRoYXQgdGhleSBmb3JtIGEgc3RyZWFtIG9mDQovLyB3b3Jkcy4NCmNvbnN0IFNQSVJWRGVjb2RlciYNCm9wZXJhdG9yPj4oY29uc3QgU1BJUlZEZWNvZGVyJkksIHN0ZDo6c3RyaW5nJiBTdHIpIHsNCiNpZmRlZiBfU1BJUlZfU1VQUE9SVF9URVhUX0ZNVA0KICBpZiAoU1BJUlZVc2VUZXh0Rm9ybWF0KSB7DQogICAgcmVhZFF1b3RlZFN0cmluZyhJLklTLCBTdHIpOw0KICAgIFNQSVJWREJHKHNwdmRiZ3MoKSA8PCAiUmVhZCBzdHJpbmc6IFwiIiA8PCBTdHIgPDwgIlwiXG4iKTsNCiAgICByZXR1cm4gSTsNCiAgfQ0KI2VuZGlmDQoNCiAgdWludDY0X3QgQ291bnQgPSAwOw0KICBjaGFyIENoOw0KICB3aGlsZSAoSS5JUy5nZXQoQ2gpICYmIENoICE9ICdcMCcpIHsNCiAgICBTdHIgKz0gQ2g7DQogICAgKytDb3VudDsNCiAgfQ0KICBDb3VudCA9IChDb3VudCArIDEpICUgNDsNCiAgQ291bnQgPSBDb3VudCA/IDQgLSBDb3VudCA6IDA7DQogIGZvciAoO0NvdW50OyAtLUNvdW50KSB7DQogICAgSS5JUyA+PiBDaDsNCiAgICBhc3NlcnQoQ2ggPT0gJ1wwJyAmJiAiSW52YWxpZCBzdHJpbmcgaW4gU1BJUlYiKTsNCiAgfQ0KICBTUElSVkRCRyhzcHZkYmdzKCkgPDwgIlJlYWQgc3RyaW5nOiBcIiIgPDwgU3RyIDw8ICJcIlxuIik7DQogIHJldHVybiBJOw0KfQ0KDQovLyBXcml0ZSBhIHN0cmluZyB3aXRoIHBhZGRlZCAwJ3MgYXQgdGhlIGVuZCBzbyB0aGF0IHRoZXkgZm9ybSBhIHN0cmVhbSBvZg0KLy8gd29yZHMuDQpjb25zdCBTUElSVkVuY29kZXImDQpvcGVyYXRvcjw8KGNvbnN0IFNQSVJWRW5jb2RlciZPLCBjb25zdCBzdGQ6OnN0cmluZyYgU3RyKSB7DQojaWZkZWYgX1NQSVJWX1NVUFBPUlRfVEVYVF9GTVQNCiAgaWYgKFNQSVJWVXNlVGV4dEZvcm1hdCkgew0KICAgIHdyaXRlUXVvdGVkU3RyaW5nKE8uT1MsIFN0cik7DQogICAgcmV0dXJuIE87DQogIH0NCiNlbmRpZg0KDQogIHNpemVfdCBMID0gU3RyLmxlbmd0aCgpOw0KICBPLk9TLndyaXRlKFN0ci5jX3N0cigpLCBMKTsNCiAgY2hhciBaZXJvc1s0XSA9IHswLCAwLCAwLCAwfTsNCiAgTy5PUy53cml0ZShaZXJvcywgNC1MJTQpOw0KICByZXR1cm4gTzsNCn0NCg0KYm9vbA0KU1BJUlZEZWNvZGVyOjpnZXRXb3JkQ291bnRBbmRPcENvZGUoKSB7DQogIGlmIChJUy5lb2YoKSkgew0KICAgIFdvcmRDb3VudCA9IDA7DQogICAgT3BDb2RlID0gT3BOb3A7DQogICAgU1BJUlZEQkcoc3B2ZGJncygpIDw8ICJbU1BJUlZEZWNvZGVyXSBnZXRXb3JkQ291bnRBbmRPcENvZGUgRU9GICIgPDwNCiAgICAgICAgV29yZENvdW50IDw8ICIgIiA8PCBPcENvZGUgPDwgJ1xuJyk7DQogICAgcmV0dXJuIGZhbHNlOw0KICB9DQojaWZkZWYgX1NQSVJWX1NVUFBPUlRfVEVYVF9GTVQNCiAgaWYgKFNQSVJWVXNlVGV4dEZvcm1hdCkgew0KICAgICp0aGlzID4+IFdvcmRDb3VudDsNCiAgICBhc3NlcnQoIUlTLmJhZCgpICYmICJTUElSViBzdHJlYW0gaXMgYmFkIik7DQogICAgaWYgKElTLmZhaWwoKSkgew0KICAgICAgV29yZENvdW50ID0gMDsNCiAgICAgIE9wQ29kZSA9IE9wTm9wOw0KICAgICAgU1BJUlZEQkcoc3B2ZGJncygpIDw8ICJbU1BJUlZEZWNvZGVyXSBnZXRXb3JkQ291bnRBbmRPcENvZGUgRkFJTCAiIDw8DQogICAgICAgICAgV29yZENvdW50IDw8ICIgIiA8PCBPcENvZGUgPDwgJ1xuJyk7DQogICAgICByZXR1cm4gZmFsc2U7DQogICAgfQ0KICAgICp0aGlzID4+IE9wQ29kZTsNCiAgfSBlbHNlIHsNCiNlbmRpZg0KICBTUElSVldvcmQgV29yZENvdW50QW5kT3BDb2RlOw0KICAqdGhpcyA+PiBXb3JkQ291bnRBbmRPcENvZGU7DQogIFdvcmRDb3VudCA9IFdvcmRDb3VudEFuZE9wQ29kZSA+PiAxNjsNCiAgT3BDb2RlID0gc3RhdGljX2Nhc3Q8T3A+KFdvcmRDb3VudEFuZE9wQ29kZSAmIDB4RkZGRik7DQojaWZkZWYgX1NQSVJWX1NVUFBPUlRfVEVYVF9GTVQNCiAgfQ0KI2VuZGlmDQogIGFzc2VydCghSVMuYmFkKCkgJiYgIlNQSVJWIHN0cmVhbSBpcyBiYWQiKTsNCiAgaWYgKElTLmZhaWwoKSkgew0KICAgIFdvcmRDb3VudCA9IDA7DQogICAgT3BDb2RlID0gT3BOb3A7DQogICAgU1BJUlZEQkcoc3B2ZGJncygpIDw8ICJbU1BJUlZEZWNvZGVyXSBnZXRXb3JkQ291bnRBbmRPcENvZGUgRkFJTCAiIDw8DQogICAgICAgIFdvcmRDb3VudCA8PCAiICIgPDwgT3BDb2RlIDw8ICdcbicpOw0KICAgIHJldHVybiBmYWxzZTsNCiAgfQ0KICBTUElSVkRCRyhzcHZkYmdzKCkgPDwgIltTUElSVkRlY29kZXJdIGdldFdvcmRDb3VudEFuZE9wQ29kZSAiIDw8IFdvcmRDb3VudCA8PA0KICAgICAgIiAiIDw8IE9wQ29kZU5hbWVNYXA6Om1hcChPcENvZGUpIDw8ICdcbicpOw0KICByZXR1cm4gdHJ1ZTsNCn0NCg0KU1BJUlZFbnRyeSAqDQpTUElSVkRlY29kZXI6OmdldEVudHJ5KCkgew0KICBpZiAoV29yZENvdW50ID09IDAgfHwgT3BDb2RlID09IE9wTm9wKQ0KICAgIHJldHVybiBOVUxMOw0KICBTUElSVkVudHJ5ICpFbnRyeSA9IFNQSVJWRW50cnk6OmNyZWF0ZShPcENvZGUpOw0KICBhc3NlcnQoRW50cnkpOwogIEVudHJ5LT5zZXRNb2R1bGUoJk0pOw0KICBpZiAoaXNNb2R1bGVTY29wZUFsbG93ZWRPcENvZGUoT3BDb2RlKSAmJiAhU2NvcGUpIHt9DQogIGVsc2UNCiAgICBFbnRyeS0+c2V0U2NvcGUoU2NvcGUpOw0KICBFbnRyeS0+c2V0V29yZENvdW50KFdvcmRDb3VudCk7DQogIElTID4+ICpFbnRyeTsNCiAgYXNzZXJ0KCFJUy5iYWQoKSAmJiAhSVMuZmFpbCgpICYmICJTUElSViBzdHJlYW0gZmFpbHMiKTsNCiAgTS5hZGQoRW50cnkpOw0KICByZXR1cm4gRW50cnk7DQp9DQoNCnZvaWQNClNQSVJWRGVjb2Rlcjo6dmFsaWRhdGUoKWNvbnN0IHsNCiAgYXNzZXJ0KE9wQ29kZSAhPSBPcE5vcCAmJiAiSW52YWxpZCBvcCBjb2RlIik7DQogIGFzc2VydChXb3JkQ291bnQgJiYgIkludmFsaWQgd29yZCBjb3VudCIpOw0KICBhc3NlcnQoIUlTLmJhZCgpICYmICJCYWQgaUlucHV0IHN0cmVhbSIpOw0KfQ0KDQpzcHZfb3N0cmVhbSAmDQpvcGVyYXRvcjw8KHNwdl9vc3RyZWFtICZPLCBjb25zdCBTUElSVk5MICZFKSB7DQojaWZkZWYgX1NQSVJWX1NVUFBPUlRfVEVYVF9GTVQNCiAgaWYgKFNQSVJWVXNlVGV4dEZvcm1hdCkNCiAgICBPIDw8ICdcbic7DQojZW5kaWYNCiAgcmV0dXJuIE87DQp9DQoNCn0gLy8gZW5kIG9mIFNQSVJWIG5hbWVzcGFjZQ0KDQo=