PCFET0NUWVBFIEhUTUwgUFVCTElDICItLy9XM0MvL0RURCBIVE1MIDQuMDEgVHJhbnNpdGlvbmFsLy9FTiI+CjxodG1sPgoKPGhlYWQ+CjxtZXRhIGh0dHAtZXF1aXY9IkNvbnRlbnQtVHlwZSIKCWNvbnRlbnQ9InRleHQvaHRtbDsgY2hhcnNldD13aW5kb3dzLTEyNTIiPgo8dGl0bGU+VW5kZXJzdGFuZGluZyBMYXlvdXRzIGluIFNXVDwvdGl0bGU+CjxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iLi4vYXJ0aWNsZS5jc3MiIHR5cGU9InRleHQvY3NzIiAvPgo8L2hlYWQ+Cjxib2R5Pgo8aDE+VW5kZXJzdGFuZGluZyBMYXlvdXRzIGluIFNXVDwvaDE+Cgo8ZGl2IGNsYXNzPSJzdW1tYXJ5Ij4KPGgyPlN1bW1hcnk8L2gyPgo8cD5XaGVuIHdyaXRpbmcgYXBwbGljYXRpb25zIGluIFNXVCwgeW91IG1heSBuZWVkIHRvIHVzZSA8aT5sYXlvdXRzPC9pPgp0byBnaXZlIHlvdXIgd2luZG93cyBhIHNwZWNpZmljIGxvb2suIEEgbGF5b3V0IGNvbnRyb2xzIHRoZSBwb3NpdGlvbiBhbmQKc2l6ZSBvZiBjaGlsZHJlbiBpbiBhIDxjb2RlPkNvbXBvc2l0ZTwvY29kZT4uIExheW91dCBjbGFzc2VzIGFyZQpzdWJjbGFzc2VzIG9mIHRoZSBhYnN0cmFjdCBjbGFzcyA8Y29kZT5MYXlvdXQ8L2NvZGU+LiBUaGlzIGFydGljbGUgc2hvd3MKeW91IGhvdyB0byB3b3JrIHdpdGggc3RhbmRhcmQgbGF5b3V0cywgYW5kIHdyaXRlIHlvdXIgb3duIGN1c3RvbSBsYXlvdXQKY2xhc3MuPC9wPgoKPGRpdiBjbGFzcz0iYXV0aG9yIj5CeSBDYXJvbHluIE1hY0xlb2QsIE9USTwvZGl2Pgo8ZGl2IGNsYXNzPSJjb3B5cmlnaHQiPkNvcHlyaWdodCAmY29weTsgMjAwMSwgMjAwMiBPYmplY3QKVGVjaG5vbG9neSBJbnRlcm5hdGlvbmFsLCBJbmMuPC9kaXY+CjxkaXYgY2xhc3M9ImRhdGUiPk1hcmNoIDIyLCAyMDAxPC9kaXY+Cgo8ZGl2IGNsYXNzPSJhdXRob3IiPlJldmlzZWQgYnkgU2hhbnRoYSBSYW1hY2hhbmRyYW4sIE9USTwvZGl2Pgo8ZGl2IGNsYXNzPSJkYXRlIj5NYXkgMDIsIDIwMDI8L2Rpdj4KCjxkaXYgY2xhc3M9ImF1dGhvciI+UmV2aXNlZCBieSBXYXluZSBCZWF0b24sIFRoZSBFY2xpcHNlCkZvdW5kYXRpb248L2Rpdj4KPGRpdiBjbGFzcz0iY29weXJpZ2h0Ij5Db3B5cmlnaHQgJmNvcHk7IDIwMDggVGhlIEVjbGlwc2UKRm91bmRhdGlvbiwgSW5jLjwvZGl2Pgo8ZGl2IGNsYXNzPSJkYXRlIj5NYXkgMzAsIDIwMDg8L2Rpdj4KPC9kaXY+Cgo8ZGl2IGNsYXNzPSJjb250ZW50Ij4KCjxoMj5PdmVydmlldzwvaDI+Cgo8cD5XaGVuIHdyaXRpbmcgYXBwbGljYXRpb25zIGluIHRoZSA8YQoJaHJlZj0iaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9zd3QiPlN0YW5kYXJkIFdpZGdldCBUb29sa2l0PC9hPiAoU1dUKSwKeW91IG1heSBuZWVkIHRvIHVzZSA8aT5sYXlvdXRzPC9pPiB0byBnaXZlIHlvdXIgd2luZG93cyBhIHNwZWNpZmljIGxvb2suCkEgbGF5b3V0IGNvbnRyb2xzIHRoZSBwb3NpdGlvbiBhbmQgc2l6ZSBvZiBjaGlsZHJlbiBpbiBhIDxjb2RlPkNvbXBvc2l0ZTwvY29kZT4uCkxheW91dCBjbGFzc2VzIGFyZSBzdWJjbGFzc2VzIG9mIHRoZSBhYnN0cmFjdCBjbGFzcyA8Y29kZT5MYXlvdXQ8L2NvZGU+LgpTV1QgcHJvdmlkZXMgc2V2ZXJhbCBzdGFuZGFyZCBsYXlvdXQgY2xhc3NlcywgYW5kIHlvdSBjYW4gd3JpdGUgY3VzdG9tCmxheW91dCBjbGFzc2VzLjwvcD4KCjxwPkluIFNXVCwgcG9zaXRpb25pbmcgYW5kIHNpemluZyBkb2VzIG5vdCBoYXBwZW4gYXV0b21hdGljYWxseS4KQXBwbGljYXRpb25zIGNhbiBkZWNpZGUgdG8gc2l6ZSBhbmQgcGxhY2UgYSA8Y29kZT5Db21wb3NpdGU8L2NvZGU+J3MKY2hpbGRyZW4gaW5pdGlhbGx5LCBvciBpbiBhIHJlc2l6ZSBsaXN0ZW5lci4gQW5vdGhlciBvcHRpb24gaXMgdG8Kc3BlY2lmeSBhIGxheW91dCBjbGFzcyB0byBwb3NpdGlvbiBhbmQgc2l6ZSB0aGUgY2hpbGRyZW4uIElmIGNoaWxkcmVuCmFyZSBub3QgZ2l2ZW4gYSBzaXplLCB0aGV5IHdpbGwgaGF2ZSB6ZXJvIHNpemUgYW5kIHRoZXkgY2Fubm90IGJlIHNlZW4uPC9wPgoKPHA+VGhlIGRpYWdyYW0gYmVsb3cgaWxsdXN0cmF0ZXMgYSBmZXcgZ2VuZXJhbCB0ZXJtcyB0aGF0IGFyZSB1c2VkCndoZW4gZGlzY3Vzc2luZyBsYXlvdXRzLiBUaGUgPGNvZGU+Q29tcG9zaXRlPC9jb2RlPiAoaW4gdGhpcyBjYXNlLCBhIDxjb2RlPlRhYkZvbGRlcjwvY29kZT4pCmhhcyBhIDxpPmxvY2F0aW9uPC9pPiwgPGk+Y2xpZW50QXJlYTwvaT4gYW5kIDxpPnRyaW08L2k+LiBUaGUgc2l6ZSBvZgp0aGUgPGNvZGU+Q29tcG9zaXRlPC9jb2RlPiBpcyB0aGUgc2l6ZSBvZiB0aGUgPGk+Y2xpZW50QXJlYTwvaT4gcGx1cyB0aGUKc2l6ZSBvZiB0aGUgPGNvZGU+dHJpbTwvY29kZT4uIFRoaXMgPGNvZGU+Q29tcG9zaXRlPC9jb2RlPiBoYXMgdHdvCmNoaWxkcmVuIHRoYXQgYXJlIGxhaWQgb3V0IHNpZGUgYnkgc2lkZS4gQSA8Y29kZT5MYXlvdXQ8L2NvZGU+IGlzCm1hbmFnaW5nIHRoZSBzaXplIGFuZCBwb3NpdGlvbiBvZiB0aGUgY2hpbGRyZW4uIFRoaXMgPGNvZGU+TGF5b3V0PC9jb2RlPgphbGxvd3MgPGNvZGU+c3BhY2luZzwvY29kZT4gYmV0d2VlbiB0aGUgY2hpbGRyZW4sIGFuZCBhIDxpPm1hcmdpbjwvaT4KYmV0d2VlbiB0aGUgY2hpbGRyZW4gYW5kIHRoZSBlZGdlcyBvZiB0aGUgPGNvZGU+TGF5b3V0PC9jb2RlPi4gVGhlIHNpemUKb2YgdGhlIDxjb2RlPkxheW91dDwvY29kZT4gaXMgdGhlIHNhbWUgYXMgdGhlIHNpemUgb2YgdGhlIDxjb2RlPkNvbXBvc2l0ZTwvY29kZT4ncwo8aT5jbGllbnRBcmVhPC9pPi48L3A+Cgo8aW1nIHNyYz0iaW1hZ2VzL0dlbmVyYWxUZXJtcy5qcGciIC8+Cgo8cD5UaGUgPGk+cHJlZmVycmVkIHNpemU8L2k+IG9mIGEgd2lkZ2V0IGlzIHRoZSBtaW5pbXVtIHNpemUgbmVlZGVkCnRvIHNob3cgaXRzIGNvbnRlbnQuIEluIHRoZSBjYXNlIG9mIGEgPGNvZGU+Q29tcG9zaXRlPC9jb2RlPiwgdGhlCnByZWZlcnJlZCBzaXplIGlzIHRoZSBzbWFsbGVzdCByZWN0YW5nbGUgdGhhdCBjb250YWlucyBhbGwgb2YgaXRzCmNoaWxkcmVuLiBJZiBjaGlsZHJlbiBoYXZlIGJlZW4gcG9zaXRpb25lZCBieSB0aGUgYXBwbGljYXRpb24sIHRoZSA8Y29kZT5Db21wb3NpdGU8L2NvZGU+CmNvbXB1dGVzIGl0cyBvd24gcHJlZmVycmVkIHNpemUgYmFzZWQgb24gdGhlIHNpemUgYW5kIHBvc2l0aW9uIG9mIHRoZQpjaGlsZHJlbi4gSWYgYSA8Y29kZT5Db21wb3NpdGU8L2NvZGU+IGlzIHVzaW5nIGEgbGF5b3V0IGNsYXNzIHRvCnBvc2l0aW9uIGl0cyBjaGlsZHJlbiwgaXQgYXNrcyB0aGUgPGNvZGU+TGF5b3V0PC9jb2RlPiB0byBjb21wdXRlIHRoZQpzaXplIG9mIGl0cyA8Y29kZT5jbGllbnRBcmVhPC9jb2RlPiwgYW5kIHRoZW4gaXQgYWRkcyBpbiB0aGUgPGNvZGU+dHJpbTwvY29kZT4KdG8gZGV0ZXJtaW5lIGl0cyBwcmVmZXJyZWQgc2l6ZS48L3A+Cgo8aDM+U3RhbmRhcmQgTGF5b3V0czwvaDM+Cgo8cD5UaGUgc3RhbmRhcmQgbGF5b3V0IGNsYXNzZXMgaW4gdGhlIFNXVCBsaWJyYXJ5IGFyZTo8L3A+Cgo8dWw+Cgk8bGk+PGNvZGU+RmlsbExheW91dDwvY29kZT4gbGF5cyBvdXQgZXF1YWwtc2l6ZWQgd2lkZ2V0cyBpbiBhCglzaW5nbGUgcm93IG9yIGNvbHVtbjwvbGk+Cgk8bGk+PGNvZGU+Um93TGF5b3V0PC9jb2RlPiBsYXlzIG91dCB3aWRnZXRzIGluIGEgcm93IG9yIHJvd3MsIHdpdGgKCWZpbGwsIHdyYXAsIGFuZCBzcGFjaW5nIG9wdGlvbnM8L2xpPgoJPGxpPjxjb2RlPkdyaWRMYXlvdXQ8L2NvZGU+IGxheXMgb3V0IHdpZGdldHMgaW4gYSBncmlkPC9saT4KCTxsaT48Y29kZT5Gb3JtTGF5b3V0PC9jb2RlPiBsYXlzIG91dCB3aWRnZXRzIGJ5IGNyZWF0aW5nCglhdHRhY2htZW50cyBmb3IgZWFjaCBvZiB0aGVpciBzaWRlczwvbGk+CjwvdWw+Cgo8cD5UbyB1c2UgdGhlIHN0YW5kYXJkIGxheW91dHMsIHlvdSBuZWVkIHRvIGltcG9ydCB0aGUgU1dUIGxheW91dApwYWNrYWdlOjwvcD4KCjxwcmU+aW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5sYXlvdXQuKjs8L3ByZT4KCjxwPkxheW91dHMgYXJlIHBsdWdnYWJsZS4gVG8gc2V0IGEgPGNvZGU+Q29tcG9zaXRlPC9jb2RlPiB3aWRnZXQncwpsYXlvdXQsIHlvdSB1c2UgdGhlIHdpZGdldCdzIDxjb2RlPnNldExheW91dChMYXlvdXQpPC9jb2RlPiBtZXRob2QuIEluCnRoZSBmb2xsb3dpbmcgY29kZSwgYSA8Y29kZT5TaGVsbDwvY29kZT4gKGEgc3ViY2xhc3Mgb2YgPGNvZGU+Q29tcG9zaXRlPC9jb2RlPikKaXMgdG9sZCB0byBwb3NpdGlvbiBpdHMgY2hpbGRyZW4gdXNpbmcgYSA8Y29kZT5Sb3dMYXlvdXQ8L2NvZGU+OjwvcD4KCjxwcmU+U2hlbGwgc2hlbGwgPSBuZXcgU2hlbGwoKTsNCnNoZWxsLnNldExheW91dChuZXcgUm93TGF5b3V0KCkpOzwvcHJlPgoKPHA+QSBsYXlvdXQgY2xhc3MgbWF5IGhhdmUgYSBjb3JyZXNwb25kaW5nIGxheW91dCBkYXRhIGNsYXNzOiBhCnN1YmNsYXNzIG9mIDxjb2RlPk9iamVjdDwvY29kZT4gdGhhdCBjb250YWlucyBsYXlvdXQgZGF0YSBmb3IgYSBzcGVjaWZpYwpjaGlsZC4gQnkgY29udmVudGlvbiwgbGF5b3V0IGRhdGEgY2xhc3NlcyBhcmUgaWRlbnRpZmllZCBieSBzdWJzdGl0dXRpbmcKJnF1b3Q7RGF0YSZxdW90OyBmb3IgJnF1b3Q7TGF5b3V0JnF1b3Q7IGluIHRoZSBjbGFzcyBuYW1lLiBGb3IgZXhhbXBsZSwKdGhlIHN0YW5kYXJkIGxheW91dCBjbGFzcyA8Y29kZT5Sb3dMYXlvdXQ8L2NvZGU+IGhhcyBhIGxheW91dCBkYXRhIGNsYXNzCmNhbGxlZCA8Y29kZT5Sb3dEYXRhPC9jb2RlPiwgdGhlIGxheW91dCBjbGFzcyA8Y29kZT5HcmlkTGF5b3V0PC9jb2RlPgp1c2VzIGEgbGF5b3V0IGRhdGEgY2xhc3MgY2FsbGVkIDxjb2RlPkdyaWREYXRhPC9jb2RlPiwgYW5kIHRoZSBsYXlvdXQKY2xhc3MgPGNvZGU+Rm9ybUxheW91dDwvY29kZT4gaGFzIGEgbGF5b3V0IGRhdGEgY2xhc3MgY2FsbGVkIDxjb2RlPkZvcm1EYXRhPC9jb2RlPi4KQSB3aWRnZXQncyBsYXlvdXQgZGF0YSBjbGFzcyBpcyBzZXQgYXMgZm9sbG93czo8L3A+Cgo8cHJlPkJ1dHRvbiBidXR0b24gPSBuZXcgQnV0dG9uKHNoZWxsLCBTV1QuUFVTSCk7DQpidXR0b24uc2V0TGF5b3V0RGF0YShuZXcgUm93RGF0YSg1MCwgNDApKTs8L3ByZT4KCjxoMz5FeGFtcGxlcyBpbiB0aGlzIERvY3VtZW50PC9oMz4KCjxwPk1vc3Qgb2YgdGhlIHNuYXBzaG90cyBpbiB0aGlzIGRvY3VtZW50IHdlcmUgdGFrZW4gYnkgcnVubmluZwp2YXJpYXRpb25zIG9uIHRoZSBmb2xsb3dpbmcgZXhhbXBsZSBjb2RlLiBXZSBtYXkgY2hhbmdlIHRoZSB0eXBlIG9mCmxheW91dCwgdGhlIG9wdGlvbnMgdXNlZCwgb3IgdGhlIHR5cGUgb3IgbnVtYmVyIG9mIGNoaWxkcmVuLjwvcD4KCjxwcmU+aW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5TV1Q7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QubGF5b3V0LlJvd0xheW91dDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkJ1dHRvbjsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkRpc3BsYXk7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5TaGVsbDsKCnB1YmxpYyBjbGFzcyBMYXlvdXRFeGFtcGxlIHsKICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpIHsKICAgICAgICBEaXNwbGF5IGRpc3BsYXkgPSBuZXcgRGlzcGxheSgpOwogICAgICAgIFNoZWxsIHNoZWxsID0gbmV3IFNoZWxsKGRpc3BsYXkpOwogICAgICAgIC8vIENyZWF0ZSB0aGUgbGF5b3V0LgogICAgICAgIFJvd0xheW91dCBsYXlvdXQgPSBuZXcgUm93TGF5b3V0KCk7CiAgICAgICAgLy8gT3B0aW9uYWxseSBzZXQgbGF5b3V0IGZpZWxkcy4KICAgICAgICBsYXlvdXQud3JhcCA9IHRydWU7CiAgICAgICAgLy8gU2V0IHRoZSBsYXlvdXQgaW50byB0aGUgY29tcG9zaXRlLgogICAgICAgIHNoZWxsLnNldExheW91dChsYXlvdXQpOwogICAgICAgIC8vIENyZWF0ZSB0aGUgY2hpbGRyZW4gb2YgdGhlIGNvbXBvc2l0ZS4KICAgICAgICBuZXcgQnV0dG9uKHNoZWxsLCBTV1QuUFVTSCkuc2V0VGV4dCgiQjEiKTsKICAgICAgICBuZXcgQnV0dG9uKHNoZWxsLCBTV1QuUFVTSCkuc2V0VGV4dCgiV2lkZSBCdXR0b24gMiIpOwogICAgICAgIG5ldyBCdXR0b24oc2hlbGwsIFNXVC5QVVNIKS5zZXRUZXh0KCJCdXR0b24gMyIpOwogICAgICAgIHNoZWxsLnBhY2soKTsKICAgICAgICBzaGVsbC5vcGVuKCk7CiAgICAgICAgCiAgICAgICAgd2hpbGUgKCFzaGVsbC5pc0Rpc3Bvc2VkKCkpIHsKICAgICAgICAgICAgaWYgKCFkaXNwbGF5LnJlYWRBbmREaXNwYXRjaCgpKSBkaXNwbGF5LnNsZWVwKCk7CiAgICAgICAgfQogICAgfQp9PC9wcmU+Cgo8cD5SdW5uaW5nIHRoZSBhYm92ZSBjb2RlIHJlc3VsdHMgaW4gdGhlIGZvbGxvd2luZzo8L3A+Cgo8aW1nIHNyYz0iaW1hZ2VzL0xheW91dEV4YW1wbGUuanBnIiAvPgoKPHA+SWYgdGhlIHVzZXIgcmVzaXplcyB0aGUgc2hlbGwgc28gdGhhdCB0aGVyZSBpcyBubyBsb25nZXIgcm9vbSBmb3IKQnV0dG9uIDMgb24gdGhlIHJpZ2h0LCB0aGUgPGNvZGU+Um93TGF5b3V0PC9jb2RlPiB3cmFwcyBCdXR0b24gMyB0byB0aGUKbmV4dCByb3csIGFzIGZvbGxvd3M6PC9wPgoKPGltZyBzcmM9ImltYWdlcy9MYXlvdXRFeGFtcGxlUmVzaXplZC5qcGciIC8+Cgo8cD5Vc2luZyBsYXlvdXRzIGlzIGNsb3NlbHkgdGllZCB3aXRoIHJlc2l6ZSwgYXMgd2Ugc2hhbGwgc2VlLgpDb25zZXF1ZW50bHksIG1vc3Qgb2YgdGhlIGV4YW1wbGVzIGluIHRoaXMgZG9jdW1lbnQgc2hvdyB3aGF0IHdvdWxkCmhhcHBlbiBpZiB0aGUgPGNvZGU+Q29tcG9zaXRlPC9jb2RlPiBiZWNvbWVzIHNtYWxsZXIgb3IgbGFyZ2VyLCBpbiBvcmRlcgp0byBpbGx1c3RyYXRlIGhvdyB0aGUgPGNvZGU+TGF5b3V0PC9jb2RlPiB3b3Jrcy48L3A+Cgo8aDI+RmlsbExheW91dDwvaDI+Cgo8cD48Y29kZT5GaWxsTGF5b3V0PC9jb2RlPiBpcyB0aGUgc2ltcGxlc3QgbGF5b3V0IGNsYXNzLiBJdCBsYXlzIG91dAp3aWRnZXRzIGluIGEgc2luZ2xlIHJvdyBvciBjb2x1bW4sIGZvcmNpbmcgdGhlbSB0byBiZSB0aGUgc2FtZSBzaXplLgpJbml0aWFsbHksIHRoZSB3aWRnZXRzIHdpbGwgYWxsIGJlIGFzIHRhbGwgYXMgdGhlIHRhbGxlc3Qgd2lkZ2V0LCBhbmQgYXMKd2lkZSBhcyB0aGUgd2lkZXN0LiA8Y29kZT5GaWxsTGF5b3V0PC9jb2RlPiBkb2VzIG5vdCB3cmFwLCBhbmQgeW91CmNhbm5vdCBzcGVjaWZ5IG1hcmdpbnMgb3Igc3BhY2luZy4gWW91IG1pZ2h0IHVzZSBpdCB0byBsYXkgb3V0IGJ1dHRvbnMKaW4gYSB0YXNrIGJhciBvciB0b29sIGJhciwgb3IgdG8gc3RhY2sgY2hlY2tib3hlcyBpbiBhIDxjb2RlPkdyb3VwPC9jb2RlPi4KPGNvZGU+RmlsbExheW91dDwvY29kZT4gY2FuIGFsc28gYmUgdXNlZCB3aGVuIGEgPGNvZGU+Q29tcG9zaXRlPC9jb2RlPgpvbmx5IGhhcyBvbmUgY2hpbGQuIEZvciBleGFtcGxlLCBpZiBhIDxjb2RlPlNoZWxsPC9jb2RlPiBoYXMgYSBzaW5nbGUgPGNvZGU+R3JvdXA8L2NvZGU+CmNoaWxkLCA8Y29kZT5GaWxsTGF5b3V0PC9jb2RlPiB3aWxsIGNhdXNlIHRoZSA8Y29kZT5Hcm91cDwvY29kZT4gdG8KY29tcGxldGVseSBmaWxsIHRoZSA8Y29kZT5TaGVsbDwvY29kZT4uPC9wPgoKPHA+SGVyZSBpcyB0aGUgcmVsZXZhbnQgcG9ydGlvbiBvZiB0aGUgZXhhbXBsZSBjb2RlLiBGaXJzdCB3ZSBjcmVhdGUKYSA8Y29kZT5GaWxsTGF5b3V0PC9jb2RlPiwgdGhlbiAoaWYgd2Ugd2FudCB2ZXJ0aWNhbCkgd2Ugc2V0IGl0cyA8Y29kZT50eXBlPC9jb2RlPgpmaWVsZCB0byA8Y29kZT5TV1QuVkVSVElDQUw8L2NvZGU+LCBhbmQgc2V0IGl0IGludG8gdGhlIDxjb2RlPkNvbXBvc2l0ZTwvY29kZT4KKGEgPGNvZGU+U2hlbGw8L2NvZGU+KS4gVGhlIDxjb2RlPlNoZWxsPC9jb2RlPiBoYXMgdGhyZWUgcHVzaCBidXR0b24KY2hpbGRyZW4sICZxdW90O0IxJnF1b3Q7LCAmcXVvdDtXaWRlIEJ1dHRvbiAyJnF1b3Q7LCBhbmQgJnF1b3Q7QnV0dG9uCjMmcXVvdDsuIE5vdGUgdGhhdCBpbiBhIDxjb2RlPkZpbGxMYXlvdXQ8L2NvZGU+LCBjaGlsZHJlbiBhcmUgYWx3YXlzIHRoZQpzYW1lIHNpemUsIGFuZCB0aGV5IGZpbGwgYWxsIGF2YWlsYWJsZSBzcGFjZS48L3A+Cgo8cHJlPkZpbGxMYXlvdXQgZmlsbExheW91dCA9IG5ldyBGaWxsTGF5b3V0KCk7DQpmaWxsTGF5b3V0LnR5cGUgPSBTV1QuVkVSVElDQUw7DQpzaGVsbC5zZXRMYXlvdXQoZmlsbExheW91dCk7DQpuZXcgQnV0dG9uKHNoZWxsLCBTV1QuUFVTSCkuc2V0VGV4dCgmcXVvdDtCMSZxdW90Oyk7DQpuZXcgQnV0dG9uKHNoZWxsLCBTV1QuUFVTSCkuc2V0VGV4dCgmcXVvdDtXaWRlIEJ1dHRvbiAyJnF1b3Q7KTsNCm5ldyBCdXR0b24oc2hlbGwsIFNXVC5QVVNIKS5zZXRUZXh0KCZxdW90O0J1dHRvbiAzJnF1b3Q7KTs8L3ByZT4KCjxwPlRoZSBmb2xsb3dpbmcgdGFibGUgc2hvd3MgdGhlIGRpZmZlcmVuY2VzIGJldHdlZW4gYSBob3Jpem9udGFsCmFuZCB2ZXJ0aWNhbCA8Y29kZT5GaWxsTGF5b3V0PC9jb2RlPiwgaW5pdGlhbGx5IGFuZCBhZnRlciB0aGUgcGFyZW50IGhhcwpncm93bi48L3A+Cgo8dGFibGU+Cgk8dHI+CgkJPHRkPiZuYnNwOzwvdGQ+CgkJPHRkPgoJCTxwPkluaXRpYWw8L3A+CgkJPC90ZD4KCQk8dGQ+CgkJPHA+QWZ0ZXIgcmVzaXplPC9wPgoJCTwvdGQ+Cgk8L3RyPgoJPHRyPgoJCTx0ZD48Y29kZT5maWxsTGF5b3V0LnR5cGUgPSBTV1QuSE9SSVpPTlRBTDwvY29kZT4KCQk8cD4oZGVmYXVsdCk8L3A+CgkJPC90ZD4KCQk8dGQ+PGltZyBzcmM9ImltYWdlcy9GaWxsTGF5b3V0U2FtcGxlSG9yaXpvbnRhbC5qcGciIC8+PC90ZD4KCQk8dGQ+PGltZyBzcmM9ImltYWdlcy9GaWxsTGF5b3V0U2FtcGxlSG9yaXpvbnRhbFJlc2l6ZWQuanBnIiAvPjwvdGQ+Cgk8L3RyPgoJPHRyPgoJCTx0ZD48Y29kZT5maWxsTGF5b3V0LnR5cGUgPSBTV1QuVkVSVElDQUw8L2NvZGU+PC90ZD4KCQk8dGQ+PGltZyBzcmM9ImltYWdlcy9GaWxsTGF5b3V0U2FtcGxlVmVydGljYWwuanBnIiAvPjwvdGQ+CgkJPHRkPjxpbWcgc3JjPSJpbWFnZXMvRmlsbExheW91dFNhbXBsZVZlcnRpY2FsUmVzaXplZC5qcGciIC8+PC90ZD4KCTwvdHI+CjwvdGFibGU+Cgo8aDI+Um93TGF5b3V0PC9oMj4KCjxwPjxjb2RlPlJvd0xheW91dDwvY29kZT4gaXMgbW9yZSBjb21tb25seSB1c2VkIHRoYW4gPGNvZGU+RmlsbExheW91dDwvY29kZT4KYmVjYXVzZSBvZiBpdHMgYWJpbGl0eSB0byB3cmFwLCBhbmQgYmVjYXVzZSBpdCBwcm92aWRlcyBjb25maWd1cmFibGUKbWFyZ2lucyBhbmQgc3BhY2luZy4gPGNvZGU+Um93TGF5b3V0PC9jb2RlPiBoYXMgYSBudW1iZXIgb2YKY29uZmlndXJhdGlvbiBmaWVsZHMuIEluIGFkZGl0aW9uLCB0aGUgaGVpZ2h0IGFuZCB3aWR0aCBvZiBlYWNoIHdpZGdldAppbiBhIDxjb2RlPlJvd0xheW91dDwvY29kZT4gY2FuIGJlIHNwZWNpZmllZCBieSBzZXR0aW5nIHRoZSB3aWRnZXQncyA8Y29kZT5Sb3dEYXRhPC9jb2RlPgpvYmplY3QgdXNpbmcgPGNvZGU+c2V0TGF5b3V0RGF0YTwvY29kZT4uPC9wPgoKPGgzPlJvd0xheW91dENvbmZpZ3VyYXRpb24gRmllbGRzPC9oMz4KCjxwPlRoZSA8Y29kZT50eXBlPC9jb2RlPiBmaWVsZCBjb250cm9scyB3aGV0aGVyIHRoZSA8Y29kZT5Sb3dMYXlvdXQ8L2NvZGU+CmxheXMgb3V0IHdpZGdldHMgaW4gaG9yaXpvbnRhbCByb3dzLCBvciB2ZXJ0aWNhbCBjb2x1bW5zLiA8Y29kZT5Sb3dMYXlvdXRzPC9jb2RlPgphcmUgaG9yaXpvbnRhbCBieSBkZWZhdWx0LjwvcD4KCjxwPlRoZSA8Y29kZT53cmFwPC9jb2RlPiBmaWVsZCBjb250cm9scyB3aGV0aGVyIG9yIG5vdCB0aGUgPGNvZGU+Um93TGF5b3V0PC9jb2RlPgp3aWxsIHdyYXAgd2lkZ2V0cyBpbnRvIHRoZSBuZXh0IHJvdyBpZiB0aGVyZSBpc24ndCBlbm91Z2ggc3BhY2UgaW4gdGhlCmN1cnJlbnQgcm93LiA8Y29kZT5Sb3dMYXlvdXRzPC9jb2RlPiB3cmFwIGJ5IGRlZmF1bHQuPC9wPgoKPHA+SWYgdGhlIDxjb2RlPnBhY2s8L2NvZGU+IGZpZWxkIGlzIHRydWUsIHdpZGdldHMgaW4gYSA8Y29kZT5Sb3dMYXlvdXQ8L2NvZGU+CndpbGwgdGFrZSB0aGVpciBuYXR1cmFsIHNpemUgKCZxdW90O25hdHVyYWwgc2l6ZSZxdW90OyB2YXJpZXMgYnkgd2lkZ2V0Owp0aGUgbmF0dXJhbCBzaXplIGZvciBhIGxhYmVsIG9yIHB1c2ggYnV0dG9uLCBmb3IgZXhhbXBsZSwgaXMgbGFyZ2UgZW5vdWdoIHRvCmRpc3BsYXkgaXRzIHRleHR1YWwgY29udGVudHMpLCBhbmQgdGhleSB3aWxsIGJlIGFsaWduZWQgYXMgZmFyIHRvIHRoZQpsZWZ0IGFzIHBvc3NpYmxlLiBJZiBwYWNrIGlzIGZhbHNlLCB3aWRnZXRzIHdpbGwgZmlsbCB0aGUgYXZhaWxhYmxlCnNwYWNlLCBzaW1pbGFyIHRvIHRoZSB3aWRnZXRzIGluIGEgPGNvZGU+RmlsbExheW91dDwvY29kZT4uIDxjb2RlPlJvd0xheW91dHM8L2NvZGU+CnBhY2sgYnkgZGVmYXVsdC48L3A+Cgo8cD5JZiB0aGUgPGNvZGU+anVzdGlmeTwvY29kZT4gZmllbGQgaXMgdHJ1ZSwgd2lkZ2V0cyBpbiBhIDxjb2RlPlJvd0xheW91dDwvY29kZT4KYXJlIHNwcmVhZCBhY3Jvc3MgdGhlIGF2YWlsYWJsZSBzcGFjZSBmcm9tIGxlZnQgdG8gcmlnaHQuIElmIHRoZSBwYXJlbnQKPGNvZGU+Q29tcG9zaXRlPC9jb2RlPiBncm93cyB3aWRlciwgdGhlIGV4dHJhIHNwYWNlIGlzIGRpc3RyaWJ1dGVkCmV2ZW5seSBhbW9uZyB0aGUgd2lkZ2V0cy4gSWYgYm90aCA8Y29kZT5wYWNrPC9jb2RlPiBhbmQgPGNvZGU+anVzdGlmeTwvY29kZT4KYXJlIHRydWUsIHdpZGdldHMgdGFrZSB0aGVpciBuYXR1cmFsIHNpemUsIGFuZCB0aGUgZXh0cmEgc3BhY2UgaXMgcGxhY2VkCmJldHdlZW4gdGhlIHdpZGdldHMgaW4gb3JkZXIgdG8ga2VlcCB0aGVtIGZ1bGx5IGp1c3RpZmllZC4gQnkgZGVmYXVsdCwgPGNvZGU+Um93TGF5b3V0czwvY29kZT4KZG8gbm90IGp1c3RpZnkuPC9wPgoKPHA+VGhlIDxjb2RlPm1hcmdpbkxlZnQ8L2NvZGU+LCA8Y29kZT5tYXJnaW5Ub3A8L2NvZGU+LCA8Y29kZT5tYXJnaW5SaWdodDwvY29kZT4sCjxjb2RlPm1hcmdpbkJvdHRvbTwvY29kZT4gYW5kIDxjb2RlPnNwYWNpbmc8L2NvZGU+IGZpZWxkcyBjb250cm9sIHRoZQpudW1iZXIgb2YgcGl4ZWxzIGJldHdlZW4gd2lkZ2V0cyAoPGNvZGU+c3BhY2luZzwvY29kZT4pIGFuZCB0aGUgbnVtYmVyCm9mIHBpeGVscyBiZXR3ZWVuIGEgd2lkZ2V0IGFuZCB0aGUgc2lkZSBvZiB0aGUgcGFyZW50IDxjb2RlPkNvbXBvc2l0ZTwvY29kZT4KKG1hcmdpbikuIEJ5IGRlZmF1bHQsIDxjb2RlPlJvd0xheW91dHM8L2NvZGU+IGxlYXZlIDMgcGl4ZWxzIGZvciBtYXJnaW5zCmFuZCBzcGFjaW5nLiBUaGUgbWFyZ2luIGFuZCBzcGFjaW5nIGZpZWxkcyBhcmUgc2hvd24gaW4gdGhlIGZvbGxvd2luZwpkaWFncmFtLjwvcD4KCjxpbWcgc3JjPSJpbWFnZXMvUm93TGF5b3V0TWFyZ2lucy5qcGciIC8+Cgo8aDM+Um93TGF5b3V0IEV4YW1wbGVzPC9oMz4KCjxwPlRoZSBmb2xsb3dpbmcgZXhhbXBsZSBjb2RlIGNyZWF0ZXMgYSA8Y29kZT5Sb3dMYXlvdXQ8L2NvZGU+LCBzZXRzCmFsbCBvZiBpdHMgZmllbGRzIHRvIG5vbi1kZWZhdWx0IHZhbHVlcywgYW5kIHRoZW4gc2V0cyBpdCBpbnRvIGEgPGNvZGU+U2hlbGw8L2NvZGU+LjwvcD4KCjxwcmU+Um93TGF5b3V0IHJvd0xheW91dCA9IG5ldyBSb3dMYXlvdXQoKTsNCnJvd0xheW91dC53cmFwID0gZmFsc2U7DQpyb3dMYXlvdXQucGFjayA9IGZhbHNlOw0Kcm93TGF5b3V0Lmp1c3RpZnkgPSB0cnVlOw0Kcm93TGF5b3V0LnR5cGUgPSBTV1QuVkVSVElDQUw7DQpyb3dMYXlvdXQubWFyZ2luTGVmdCA9IDU7DQpyb3dMYXlvdXQubWFyZ2luVG9wID0gNTsNCnJvd0xheW91dC5tYXJnaW5SaWdodCA9IDU7DQpyb3dMYXlvdXQubWFyZ2luQm90dG9tID0gNTsNCnJvd0xheW91dC5zcGFjaW5nID0gMDsNCnNoZWxsLnNldExheW91dChyb3dMYXlvdXQpOzwvcHJlPgoKPHA+SWYgeW91IGFyZSB1c2luZyB0aGUgZGVmYXVsdCBmaWVsZCB2YWx1ZXMsIHlvdSBvbmx5IG5lZWQgb25lIGxpbmUKb2YgY29kZTo8L3A+Cgo8cHJlPnNoZWxsLnNldExheW91dChuZXcgUm93TGF5b3V0KCkpOzwvcHJlPgoKPHA+VGhlIHJlc3VsdHMgb2Ygc2V0dGluZyBzcGVjaWZpYyBmaWVsZHMgaXMgc2hvd24gYmVsb3c6PC9wPgoKPHRhYmxlPgoJPHRyPgoJCTx0ZCB3aWR0aD0iMTUwIj4mbmJzcDs8L3RkPgoJCTx0ZD4KCQk8cD5Jbml0aWFsPC9wPgoJCTwvdGQ+CgkJPHRkPgoJCTxwPkFmdGVyIHJlc2l6ZTwvcD4KCQk8L3RkPgoJPC90cj4KCTx0cj4KCQk8dGQ+PHByZT5yb3dMYXlvdXQud3JhcCA9IHRydWU7CnJvd0xheW91dC5wYWNrID0gdHJ1ZTsKcm93TGF5b3V0Lmp1c3RpZnkgPSBmYWxzZTsKcm93TGF5b3V0LnR5cGUgPSBTV1QuSE9SSVpPTlRBTDs8L3ByZT4KCQk8cD4oZGVmYXVsdHMpPC9wPgoJCTwvdGQ+CgkJPHRkPjxpbWcgc3JjPSJpbWFnZXMvUm93TGF5b3V0U2FtcGxlMDEuanBnIiAvPjwvdGQ+CgkJPHRkPjxpbWcgc3JjPSJpbWFnZXMvUm93TGF5b3V0U2FtcGxlMDFSZXNpemVkLmpwZyIgLz48cD5hbmQ8L3A+PGltZyBzcmM9ImltYWdlcy9Sb3dMYXlvdXRTYW1wbGUwMVJlc2l6ZWROYXJyb3dlci5qcGciIC8+PC90ZD4KCTwvdHI+Cgk8dHI+CgkJPHRkPjxwcmU+d3JhcCA9IGZhbHNlPC9wcmU+CgkJPHA+KGNsaXBzIGlmIG5vdCBlbm91Z2ggc3BhY2UpPC9wPgoJCTwvdGQ+CgkJPHRkPjxpbWcgc3JjPSJpbWFnZXMvUm93TGF5b3V0U2FtcGxlMDIuanBnIiAvPjwvdGQ+CgkJPHRkPjxpbWcgc3JjPSJpbWFnZXMvUm93TGF5b3V0U2FtcGxlMDJSZXNpemVkLmpwZyIgLz48L3RkPgoJPC90cj4KCTx0cj4KCQk8dGQ+PHByZT5wYWNrID0gZmFsc2U8L3ByZT4KCQk8cD4oYWxsIHdpZGdldHMgYXJlIHRoZSBzYW1lIHNpemUpPC9wPgoJCTwvdGQ+CgkJPHRkPjxpbWcgc3JjPSJpbWFnZXMvUm93TGF5b3V0U2FtcGxlMDMuanBnIiAvPjwvdGQ+CgkJPHRkPjxpbWcgc3JjPSJpbWFnZXMvUm93TGF5b3V0U2FtcGxlMDNSZXNpemVkLmpwZyIgLz48L3RkPgoJPC90cj4KCTx0cj4KCQk8dGQ+PHByZT5qdXN0aWZ5ID0gdHJ1ZTwvcHJlPgoJCTxwPih3aWRnZXRzIGFyZSBzcHJlYWQgYWNyb3NzIHRoZSBhdmFpbGFibGUgc3BhY2UpPC9wPgoJCTwvdGQ+CgkJPHRkPjxpbWcgc3JjPSJpbWFnZXMvUm93TGF5b3V0U2FtcGxlMDQuanBnIiAvPjwvdGQ+CgkJPHRkPjxpbWcgc3JjPSJpbWFnZXMvUm93TGF5b3V0U2FtcGxlMDRSZXNpemVkLmpwZyIgLz48L3RkPgoJPC90cj4KCTx0cj4KCQk8dGQ+PHByZT50eXBlID0gU1dULlZFUlRJQ0FMPC9wcmU+CgkJPHA+KHdpZGdldHMgYXJlIGFycmFuZ2VkIHZlcnRpY2FsbHkgaW4gY29sdW1ucyk8L3A+CgkJPC90ZD4KCQk8dGQ+PGltZyBzcmM9ImltYWdlcy9Sb3dMYXlvdXRTYW1wbGUwNS5qcGciIC8+PC90ZD4KCQk8dGQ+PGltZyBzcmM9ImltYWdlcy9Sb3dMYXlvdXRTYW1wbGUwNVJlc2l6ZWQuanBnIiAvPjwvdGQ+Cgk8L3RyPgo8L3RhYmxlPgoKPGgzPlVzaW5nIFJvd0RhdGEgT2JqZWN0cyB3aXRoIFJvd0xheW91dDwvaDM+Cgo8cD5FYWNoIHdpZGdldCBjb250cm9sbGVkIGJ5IGEgPGNvZGU+Um93TGF5b3V0PC9jb2RlPiBjYW4gaGF2ZSBpdHMKaW5pdGlhbCB3aWR0aCBhbmQgaGVpZ2h0IHNwZWNpZmllZCBieSBzZXR0aW5nIGl0cyA8Y29kZT5Sb3dEYXRhPC9jb2RlPgpvYmplY3QuIFRoZSBmb2xsb3dpbmcgY29kZSB1c2VzIDxjb2RlPlJvd0RhdGE8L2NvZGU+IG9iamVjdHMgdG8gY2hhbmdlCnRoZSBpbml0aWFsIHNpemUgb2YgdGhlIDxjb2RlPkJ1dHRvbnM8L2NvZGU+IGluIGEgPGNvZGU+U2hlbGw8L2NvZGU+LjwvcD4KCjxwcmU+aW1wb3J0IG9yZy5lY2xpcHNlLnN3dC4qOw0KaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLio7DQppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmxheW91dC4qOw0KDQpwdWJsaWMgY2xhc3MgUm93RGF0YUV4YW1wbGUgew0KDQqgoCBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKSB7DQqgoKCgoKAgRGlzcGxheSBkaXNwbGF5ID0gbmV3IERpc3BsYXkoKTsNCqCgoKCgoCBTaGVsbCBzaGVsbCA9IG5ldyBTaGVsbChkaXNwbGF5KTsNCqCgoKCgoCBzaGVsbC5zZXRMYXlvdXQobmV3IFJvd0xheW91dCgpKTsNCqCgoKCgoCBCdXR0b24gYnV0dG9uMSA9IG5ldyBCdXR0b24oc2hlbGwsIFNXVC5QVVNIKTsNCqCgoKCgoCBidXR0b24xLnNldFRleHQoJnF1b3Q7QnV0dG9uIDEmcXVvdDspOw0KoKCgoKCgIGJ1dHRvbjEuc2V0TGF5b3V0RGF0YShuZXcgUm93RGF0YSg1MCwgNDApKTsNCqCgoKCgoCBCdXR0b24gYnV0dG9uMiA9IG5ldyBCdXR0b24oc2hlbGwsIFNXVC5QVVNIKTsNCqCgoKCgoCBidXR0b24yLnNldFRleHQoJnF1b3Q7QnV0dG9uIDImcXVvdDspOw0KoKCgoKCgIGJ1dHRvbjIuc2V0TGF5b3V0RGF0YShuZXcgUm93RGF0YSg1MCwgMzApKTsNCqCgoKCgoCBCdXR0b24gYnV0dG9uMyA9IG5ldyBCdXR0b24oc2hlbGwsIFNXVC5QVVNIKTsNCqCgoKCgoCBidXR0b24zLnNldFRleHQoJnF1b3Q7QnV0dG9uIDMmcXVvdDspOw0KoKCgoKCgIGJ1dHRvbjMuc2V0TGF5b3V0RGF0YShuZXcgUm93RGF0YSg1MCwgMjApKTsNCqCgoKCgoCBzaGVsbC5wYWNrKCk7DQqgoKCgoKAgc2hlbGwub3BlbigpOwoNCqCgoKCgoCB3aGlsZSAoIXNoZWxsLmlzRGlzcG9zZWQoKSkgew0KoKCgoKCgoKCgIGlmICghZGlzcGxheS5yZWFkQW5kRGlzcGF0Y2goKSkgZGlzcGxheS5zbGVlcCgpOw0KoKCgoKCgIH0NCqCgIH0NCn08L3ByZT4KCjxwPkhlcmUgaXMgd2hhdCB5b3Ugc2VlIHdoZW4geW91IHJ1biB0aGlzIGNvZGUuPC9wPgoKPGltZyBzcmM9ImltYWdlcy9Sb3dEYXRhRXhhbXBsZS5qcGciIC8+Cgo8aDI+R3JpZExheW91dDwvaDI+Cgo8cD5XaXRoIGEgPGNvZGU+R3JpZExheW91dDwvY29kZT4sCnRoZSB3aWRnZXQgY2hpbGRyZW4gb2YgYSA8Y29kZT5Db21wb3NpdGU8L2NvZGU+IGFyZSBsYWlkIG91dCBpbiBhIGdyaWQuCjxjb2RlPkdyaWRMYXlvdXQ8L2NvZGU+IGhhcyBhIG51bWJlciBvZiBjb25maWd1cmF0aW9uIGZpZWxkcywgYW5kJm1kYXNoO2xpa2UKPGNvZGU+Um93TGF5b3V0PC9jb2RlPiZtZGFzaDt0aGUgd2lkZ2V0cyBpdCBsYXlzIG91dCBjYW4gaGF2ZSBhbiBhc3NvY2lhdGVkCmxheW91dCBkYXRhIG9iamVjdCwgY2FsbGVkIDxjb2RlPkdyaWREYXRhPC9jb2RlPi4gVGhlIHBvd2VyIG9mIDxjb2RlPkdyaWRMYXlvdXQ8L2NvZGU+CmxpZXMgaW4gdGhlIGFiaWxpdHkgdG8gY29uZmlndXJlIDxjb2RlPkdyaWREYXRhPC9jb2RlPiBmb3IgZWFjaCB3aWRnZXQKY29udHJvbGxlZCBieSB0aGUgPGNvZGU+R3JpZExheW91dDwvY29kZT4uPC9wPgoKPGgzPkdyaWRMYXlvdXQgQ29uZmlndXJhdGlvbiBGaWVsZHM8L2gzPgoKPHA+VGhlIDxjb2RlPm51bUNvbHVtbnM8L2NvZGU+IGZpZWxkIGlzIHRoZSBtb3N0IGltcG9ydGFudCBmaWVsZCBpbgphIDxjb2RlPkdyaWRMYXlvdXQ8L2NvZGU+LCBhbmQgaXQgaXMgdXN1YWxseSB0aGUgZmlyc3QgZmllbGQgYW4KYXBwbGljYXRpb24gd2lsbCBzZXQuIFdpZGdldHMgYXJlIGxhaWQgb3V0IGluIGNvbHVtbnMgZnJvbSBsZWZ0IHRvCnJpZ2h0LCBhbmQgYSBuZXcgcm93IGlzIGNyZWF0ZWQgd2hlbiA8Y29kZT5udW1Db2x1bW5zPC9jb2RlPiArIDEgd2lkZ2V0cwphcmUgYWRkZWQgdG8gdGhlIDxjb2RlPkNvbXBvc2l0ZTwvY29kZT4uIFRoZSBkZWZhdWx0IGlzIHRvIGhhdmUgb25seSAxCmNvbHVtbi4gVGhlIGZvbGxvd2luZyBjb2RlIGNyZWF0ZXMgYSA8Y29kZT5TaGVsbDwvY29kZT4gd2l0aCBmaXZlIDxjb2RlPkJ1dHRvbjwvY29kZT4KY2hpbGRyZW4gb2YgdmFyaW91cyB3aWR0aHMsIG1hbmFnZWQgYnkgYSA8Y29kZT5HcmlkTGF5b3V0PC9jb2RlPi4gVGhlCnRhYmxlIGJlbG93IHNob3dzIHRoZSBncmlkIHdoZW4gPGNvZGU+bnVtQ29sdW1uczwvY29kZT4gaXMgc2V0IHRvIG9uZSwgdHdvLApvciB0aHJlZS48L3A+Cgo8cHJlPkRpc3BsYXkgZGlzcGxheSA9IG5ldyBEaXNwbGF5KCk7DQpTaGVsbCBzaGVsbCA9IG5ldyBTaGVsbChkaXNwbGF5KTsNCkdyaWRMYXlvdXQgZ3JpZExheW91dCA9IG5ldyBHcmlkTGF5b3V0KCk7DQpncmlkTGF5b3V0Lm51bUNvbHVtbnMgPSAzOw0Kc2hlbGwuc2V0TGF5b3V0KGdyaWRMYXlvdXQpOw0KbmV3IEJ1dHRvbihzaGVsbCwgU1dULlBVU0gpLnNldFRleHQoJnF1b3Q7QjEmcXVvdDspOw0KbmV3IEJ1dHRvbihzaGVsbCwgU1dULlBVU0gpLnNldFRleHQoJnF1b3Q7V2lkZSBCdXR0b24gMiZxdW90Oyk7DQpuZXcgQnV0dG9uKHNoZWxsLCBTV1QuUFVTSCkuc2V0VGV4dCgmcXVvdDtCdXR0b24gMyZxdW90Oyk7DQpuZXcgQnV0dG9uKHNoZWxsLCBTV1QuUFVTSCkuc2V0VGV4dCgmcXVvdDtCNCZxdW90Oyk7DQpuZXcgQnV0dG9uKHNoZWxsLCBTV1QuUFVTSCkuc2V0VGV4dCgmcXVvdDtCdXR0b24gNSZxdW90Oyk7DQpzaGVsbC5wYWNrKCk7DQpzaGVsbC5vcGVuKCk7Cg0Kd2hpbGUgKCFzaGVsbC5pc0Rpc3Bvc2VkKCkpIHsNCglpZiAoIWRpc3BsYXkucmVhZEFuZERpc3BhdGNoKCkpIGRpc3BsYXkuc2xlZXAoKTsNCn08L3ByZT4KCjx0YWJsZT4KCTx0cj4KCQk8dGQ+PHByZT5udW1Db2x1bW5zID0gMTwvcHJlPjwvdGQ+CgkJPHRkPjxwcmU+bnVtQ29sdW1ucyA9IDI8L3ByZT48L3RkPgoJCTx0ZD48cHJlPm51bUNvbHVtbnMgPSAzPC9wcmU+PC90ZD4KCTwvdHI+Cgk8dHI+CgkJPHRkPjxpbWcgc3JjPSJpbWFnZXMvR3JpZExheW91dFNhbXBsZU51bUNvbHVtbnMxLmpwZyIgLz48L3RkPgoJCTx0ZD48aW1nIHNyYz0iaW1hZ2VzL0dyaWRMYXlvdXRTYW1wbGVOdW1Db2x1bW5zMi5qcGciIC8+PC90ZD4KCQk8dGQ+PGltZyBzcmM9ImltYWdlcy9HcmlkTGF5b3V0U2FtcGxlTnVtQ29sdW1uczMuanBnIiAvPjwvdGQ+Cgk8L3RyPgo8L3RhYmxlPgoKPHA+VGhlIDxjb2RlPm1ha2VDb2x1bW5zRXF1YWxXaWR0aDwvY29kZT4gZmllbGQgZm9yY2VzIHRoZSBjb2x1bW5zCnRvIGJlIHRoZSBzYW1lIHdpZHRoLiBUaGUgZGVmYXVsdCBpcyA8Y29kZT5mYWxzZTwvY29kZT4uIElmIHdlIGNoYW5nZSB0aGUgZXhhbXBsZQphYm92ZSB0byBoYXZlIHRocmVlIGNvbHVtbnMgb2YgZXF1YWwgd2lkdGgsIHRoaXMgaXMgd2hhdCB3ZSB3b3VsZCBnZXQgKG5vdGUKdGhhdCBpbiB0aGUgYWJzZW5jZSBvZiBmdXJ0aGVyIGluc3RydWN0aW9uLCB3aWRnZXRzIGFyZSBsZWZ0LWp1c3RpZmllZAppbiB0aGVpciBjb2x1bW5zKS48L3A+Cgo8aW1nIHNyYz0iaW1hZ2VzL0dyaWRMYXlvdXRTYW1wbGVFcXVhbFdpZHRoLmpwZyIgLz4KCjxwPlRoZSA8Y29kZT5tYXJnaW5XaWR0aDwvY29kZT4sIDxjb2RlPm1hcmdpbkhlaWdodDwvY29kZT4sIDxjb2RlPmhvcml6b250YWxTcGFjaW5nPC9jb2RlPiwKYW5kIDxjb2RlPnZlcnRpY2FsU3BhY2luZzwvY29kZT4gZmllbGRzIGluIGEgPGNvZGU+R3JpZExheW91dDwvY29kZT4gYXJlCnNpbWlsYXIgdG8gdGhvc2UgaW4gYSA8Y29kZT5Sb3dMYXlvdXQ8L2NvZGU+LiBUaGUgZGlmZmVyZW5jZSBpcyB0aGF0IHRoZQpsZWZ0IGFuZCByaWdodCBtYXJnaW5zIGFyZSBncm91cGVkIGludG8gPGNvZGU+bWFyZ2luV2lkdGg8L2NvZGU+LCBhbmQKdGhlIHRvcCBhbmQgYm90dG9tIG1hcmdpbnMgYXJlIGdyb3VwZWQgaW50byA8Y29kZT5tYXJnaW5IZWlnaHQ8L2NvZGU+LgpBbHNvLCBpbiBhIDxjb2RlPkdyaWRMYXlvdXQ8L2NvZGU+IHlvdSBjYW4gc3BlY2lmeSA8Y29kZT5ob3Jpem9udGFsU3BhY2luZzwvY29kZT4KYW5kIDxjb2RlPnZlcnRpY2FsU3BhY2luZzwvY29kZT4gaW5kZXBlbmRlbnRseSwgd2hlcmVhcyBpbiBhIDxjb2RlPlJvd0xheW91dDwvY29kZT4sCjxjb2RlPnNwYWNpbmc8L2NvZGU+IGFwcGxpZXMgdG8gaG9yaXpvbnRhbCBvciB2ZXJ0aWNhbCBkZXBlbmRpbmcgb24gdGhlCnR5cGUgb2YgdGhlIDxjb2RlPlJvd0xheW91dDwvY29kZT4uPC9wPgoKPGgzPkdyaWREYXRhIE9iamVjdCBGaWVsZHM8L2gzPgoKPHA+PGNvZGU+R3JpZERhdGE8L2NvZGU+IGlzIHRoZSBsYXlvdXQgZGF0YSBvYmplY3QgYXNzb2NpYXRlZCB3aXRoIDxjb2RlPkdyaWRMYXlvdXQ8L2NvZGU+LgpUbyBzZXQgYSB3aWRnZXQncyA8Y29kZT5HcmlkRGF0YTwvY29kZT4gb2JqZWN0LCB5b3UgdXNlIHRoZSA8Y29kZT5zZXRMYXlvdXREYXRhPC9jb2RlPgptZXRob2QuIEZvciBleGFtcGxlLCB0byBzZXQgdGhlIDxjb2RlPkdyaWREYXRhPC9jb2RlPiBmb3IgYSA8Y29kZT5CdXR0b248L2NvZGU+LAp3ZSBjb3VsZCBkbyB0aGUgZm9sbG93aW5nOjwvcD4KCjxwcmU+QnV0dG9uIGJ1dHRvbjEgPSBuZXcgQnV0dG9uKHNoZWxsLCBTV1QuUFVTSCk7DQpidXR0b24xLnNldFRleHQoIkIxIik7DQpidXR0b24xLnNldExheW91dERhdGEobmV3IEdyaWREYXRhKCkpOzwvcHJlPgoKPHA+T2YgY291cnNlLCB0aGlzIGNvZGUganVzdCBjcmVhdGVzIGEgPGNvZGU+R3JpZERhdGE8L2NvZGU+IG9iamVjdAp3aXRoIGFsbCBvZiBpdHMgZmllbGRzIHNldCB0byB0aGVpciBkZWZhdWx0IHZhbHVlcywgd2hpY2ggaXMgdGhlIHNhbWUgYXMKbm90IHNldHRpbmcgdGhlIGxheW91dCBkYXRhIGF0IGFsbC4gVGhlcmUgYXJlIHR3byB3YXlzIHRvIGNyZWF0ZSBhIDxjb2RlPkdyaWREYXRhPC9jb2RlPgpvYmplY3Qgd2l0aCBjZXJ0YWluIGZpZWxkcyBzZXQuIFRoZSBmaXJzdCBpcyB0byBzZXQgdGhlIGZpZWxkcyBkaXJlY3RseTo8L3A+Cgo8cHJlPkdyaWREYXRhIGdyaWREYXRhID0gbmV3IEdyaWREYXRhKCk7DQpncmlkRGF0YS5ob3Jpem9udGFsQWxpZ25tZW50ID0gR3JpZERhdGEuRklMTDsNCmdyaWREYXRhLmdyYWJFeGNlc3NIb3Jpem9udGFsU3BhY2UgPSB0cnVlOw0KYnV0dG9uMS5zZXRMYXlvdXREYXRhKGdyaWREYXRhKTs8L3ByZT4gPGltZwoJc3JjPSJpbWFnZXMvR3JpZERhdGFTYW1wbGVIb3Jpem9udGFsRmlsbC5qcGciIC8+Cgo8cD5PbmUgZmluYWwgbm90ZSBhYm91dCA8Y29kZT5HcmlkRGF0YTwvY29kZT4gb2JqZWN0cyBiZWZvcmUgd2UgZ2V0CmludG8gdGhlaXIgZmllbGRzOiBkbyBub3QgcmV1c2UgPGNvZGU+R3JpZERhdGE8L2NvZGU+IG9iamVjdHMuIEV2ZXJ5CndpZGdldCBpbiBhIDxjb2RlPkNvbXBvc2l0ZTwvY29kZT4gdGhhdCBpcyBtYW5hZ2VkIGJ5IGEgPGNvZGU+R3JpZExheW91dDwvY29kZT4KbXVzdCBoYXZlIGEgdW5pcXVlIDxjb2RlPkdyaWREYXRhPC9jb2RlPiBvYmplY3QuIElmIHRoZSBsYXlvdXQgZGF0YSBmb3IKYSB3aWRnZXQgaW4gYSA8Y29kZT5HcmlkTGF5b3V0PC9jb2RlPiBpcyBudWxsIGF0IGxheW91dCB0aW1lLCBhIHVuaXF1ZSA8Y29kZT5HcmlkRGF0YTwvY29kZT4Kb2JqZWN0IGlzIGNyZWF0ZWQgZm9yIGl0LjwvcD4KCjxwPlRoZSA8Y29kZT5ob3Jpem9udGFsQWxpZ25tZW50PC9jb2RlPiBhbmQgPGNvZGU+dmVydGljYWxBbGlnbm1lbnQ8L2NvZGU+CmZpZWxkcyBzcGVjaWZ5IHdoZXJlIHRvIHBsYWNlIGEgd2lkZ2V0IGhvcml6b250YWxseSBhbmQvb3IgdmVydGljYWxseQp3aXRoaW4gaXRzIGdyaWQgY2VsbC4gRWFjaCBhbGlnbm1lbnQgZmllbGQgY2FuIGhhdmUgb25lIG9mIHRoZSBmb2xsb3dpbmcKdmFsdWVzOjwvcD4KCjx1bD4KCTxsaT48Y29kZT5CRUdJTk5JTkc8L2NvZGU+PC9saT4KCTxsaT48Y29kZT5DRU5URVI8L2NvZGU+PC9saT4KCTxsaT48Y29kZT5FTkQ8L2NvZGU+PC9saT4KCTxsaT48Y29kZT5GSUxMPC9jb2RlPjwvbGk+CjwvdWw+Cgo8cD5UaGUgZGVmYXVsdCBob3Jpem9udGFsQWxpZ25tZW50IGlzIEJFR0lOTklORyAob3IgbGVmdC1hbGlnbmVkKS4KVGhlIGRlZmF1bHQgdmVydGljYWxBbGlnbm1lbnQgaXMgQ0VOVEVSLjwvcD4KCjxwPkxldCdzIGdvIGJhY2sgdG8gb3VyIGZpdmUtYnV0dG9uIGV4YW1wbGUgd2l0aCB0aHJlZSBjb2x1bW5zLCBhbmQKd2Ugd2lsbCB2YXJ5IHRoZSA8Y29kZT5ob3Jpem9udGFsQWxpZ25tZW50PC9jb2RlPiBvZiBCdXR0b24gNS48L3A+Cgo8dGFibGU+Cgk8dHI+CgkJPHRkPjxwcmU+aG9yaXpvbnRhbEFsaWdubWVudCA9IEdyaWREYXRhLkJFR0lOTklORzwvcHJlPgoJCTxwPihkZWZhdWx0KTwvcD4KCQk8L3RkPgoJCTx0ZD48aW1nIHNyYz0iaW1hZ2VzL0dyaWREYXRhU2FtcGxlQmVnaW5uaW5nLmpwZyIgLz48L3RkPgoJPC90cj4KCTx0cj4KCQk8dGQ+PHByZT5ob3Jpem9udGFsQWxpZ25tZW50ID0gR3JpZERhdGEuQ0VOVEVSPC9wcmU+PC90ZD4KCQk8dGQ+PGltZyBzcmM9ImltYWdlcy9HcmlkRGF0YVNhbXBsZUNlbnRlci5qcGciIC8+PC90ZD4KCTwvdHI+Cgk8dHI+CgkJPHRkPjxwcmU+aG9yaXpvbnRhbEFsaWdubWVudCA9IEdyaWREYXRhLkVORDwvcHJlPjwvdGQ+CgkJPHRkPjxpbWcgc3JjPSJpbWFnZXMvR3JpZERhdGFTYW1wbGVFbmQuanBnIiAvPjwvdGQ+Cgk8L3RyPgoJPHRyPgoJCTx0ZD48cHJlPmhvcml6b250YWxBbGlnbm1lbnQgPSBHcmlkRGF0YS5GSUxMPC9wcmU+PC90ZD4KCQk8dGQ+PGltZyBzcmM9ImltYWdlcy9HcmlkRGF0YVNhbXBsZUZpbGwuanBnIiAvPjwvdGQ+Cgk8L3RyPgo8L3RhYmxlPgoKPHA+VGhlIDxjb2RlPmhvcml6b250YWxJbmRlbnQ8L2NvZGU+IGZpZWxkIGFsbG93cyB5b3UgdG8gbW92ZSBhCndpZGdldCB0byB0aGUgcmlnaHQgYnkgYSBzcGVjaWZpZWQgbnVtYmVyIG9mIHBpeGVscy4gVGhpcyBmaWVsZCBpcwp0eXBpY2FsbHkgb25seSB1c2VmdWwgd2hlbiB0aGUgPGNvZGU+aG9yaXpvbnRhbEFsaWdubWVudDwvY29kZT4gaXMgPGNvZGU+QkVHSU5OSU5HPC9jb2RlPi4KV2UgY2Fubm90IHVzZSBhIHN0eWxlIGJpdCB0byBzZXQgdGhlIGluZGVudCwgc28gd2Ugd2lsbCBpbmRlbnQgJnF1b3Q7QnV0dG9uIDUmcXVvdDsKaW4gb3VyIGV4YW1wbGUgYnkgZm91ciBwaXhlbHMgYXMgZm9sbG93czo8L3A+Cgo8cHJlPkdyaWREYXRhIGdyaWREYXRhID0gbmV3IEdyaWREYXRhKCk7CmdyaWREYXRhLmhvcml6b250YWxJbmRlbnQgPSA0OwpidXR0b241LnNldExheW91dERhdGEoZ3JpZERhdGEpOzwvcHJlPiA8aW1nCglzcmM9ImltYWdlcy9HcmlkRGF0YVNhbXBsZUluZGVudC5qcGciIC8+Cgo8cD5UaGUgPGNvZGU+aG9yaXpvbnRhbFNwYW48L2NvZGU+IGFuZCA8Y29kZT52ZXJ0aWNhbFNwYW48L2NvZGU+CmZpZWxkcyBsZXQgd2lkZ2V0cyBvY2N1cHkgbW9yZSB0aGFuIG9uZSBncmlkIGNlbGwuIFRoZXkgYXJlIG9mdGVuIHVzZWQKaW4gY29uanVuY3Rpb24gd2l0aCA8Y29kZT5GSUxMPC9jb2RlPiBhbGlnbm1lbnQuIFdlIGNhbiBtYWtlICZxdW90O0J1dHRvbiA1JnF1b3Q7IGluIG91ciBleGFtcGxlCnNwYW4gdGhlIGxhc3QgdHdvIGNlbGxzIGFzIGZvbGxvd3M6PC9wPgoKPHByZT5HcmlkRGF0YSBncmlkRGF0YSA9IG5ldyBHcmlkRGF0YSgpOwpncmlkRGF0YS5ob3Jpem9udGFsQWxpZ25tZW50ID0gR3JpZERhdGEuRklMTDsKZ3JpZERhdGEuaG9yaXpvbnRhbFNwYW4gPSAyOwpidXR0b241LnNldExheW91dERhdGEoZ3JpZERhdGEpOzwvcHJlPiA8aW1nCglzcmM9ImltYWdlcy9HcmlkRGF0YVNhbXBsZVNwYW4wMS5qcGciIC8+Cgo8cD5JZiB3ZSBkZWNpZGUgdG8gbWFrZSAmcXVvdDtXaWRlIEJ1dHRvbiAyJnF1b3Q7IHNwYW4gdHdvIGNlbGxzIGluc3RlYWQsIHdlCndvdWxkIGVuZCB1cCB3aXRoIHRoaXM6PC9wPgoKPHByZT5HcmlkRGF0YSBncmlkRGF0YSA9IG5ldyBHcmlkRGF0YSgpOwpncmlkRGF0YS5ob3Jpem9udGFsQWxpZ25tZW50ID0gR3JpZERhdGEuRklMTDsKZ3JpZERhdGEuaG9yaXpvbnRhbFNwYW4gPSAyOwpidXR0b24yLnNldExheW91dERhdGEoZ3JpZERhdGEpOzwvcHJlPiA8aW1nCglzcmM9ImltYWdlcy9HcmlkRGF0YVNhbXBsZVNwYW4wMi5qcGciIC8+Cgo8cD5PciB3ZSBjb3VsZCBtYWtlICZxdW90O0J1dHRvbiAzJnF1b3Q7IHNwYW4gdHdvIGNlbGxzIHZlcnRpY2FsbHk6PC9wPgoKPHByZT5HcmlkRGF0YSBncmlkRGF0YSA9IG5ldyBHcmlkRGF0YSgpOwpncmlkRGF0YS52ZXJ0aWNhbEFsaWdubWVudCA9IEdyaWREYXRhLkZJTEw7CmdyaWREYXRhLnZlcnRpY2FsU3BhbiA9IDI7CmJ1dHRvbjMuc2V0TGF5b3V0RGF0YShncmlkRGF0YSk7PC9wcmU+IDxpbWcKCXNyYz0iaW1hZ2VzL0dyaWREYXRhU2FtcGxlU3BhbjAzLmpwZyIgLz4KCjxwPlRoZSA8Y29kZT5ncmFiRXhjZXNzSG9yaXpvbnRhbFNwYWNlPC9jb2RlPiBhbmQgPGNvZGU+Z3JhYkV4Y2Vzc1ZlcnRpY2FsU3BhY2U8L2NvZGU+CmZpZWxkcyBhcmUgdHlwaWNhbGx5IHVzZWQgZm9yIGxhcmdlciB3aWRnZXRzIHN1Y2ggYXMgPGNvZGU+VGV4dCw8L2NvZGU+Cjxjb2RlPkxpc3Q8L2NvZGU+IG9yIDxjb2RlPkNhbnZhczwvY29kZT4gdG8gYWxsb3cgdGhlbSB0byBncm93IGlmIHRoZWlyCmNvbnRhaW5pbmcgPGNvZGU+Q29tcG9zaXRlPC9jb2RlPiBncm93cy4gSWYgYSA8Y29kZT5UZXh0PC9jb2RlPiBpcwpncmFiYmluZyBleGNlc3MgaG9yaXpvbnRhbCBzcGFjZSBhbmQgdGhlIHVzZXIgcmVzaXplcyB0aGUgPGNvZGU+U2hlbGw8L2NvZGU+CndpZGVyLCB0aGVuIHRoZSA8Y29kZT5UZXh0PC9jb2RlPiB3aWxsIGdldCBhbGwgb2YgdGhlIG5ldyBob3Jpem9udGFsCnNwYWNlIGFuZCBvdGhlciB3aWRnZXRzIGluIHRoZSBzYW1lIHJvdyB3aWxsIHN0YXkgdGhlaXIgb3JpZ2luYWwgd2lkdGguCk9mIGNvdXJzZSwgdGhlIHdpZGdldCB0aGF0IGlzIGdyYWJiaW5nIGV4Y2VzcyBzcGFjZSBpcyBhbHNvIHRoZSBmaXJzdApvbmUgdG8gc2hyaW5rIHdoZW4gdGhlIDxjb2RlPlNoZWxsPC9jb2RlPiBnZXRzIHNtYWxsZXIuIEl0IGlzIGVhc2llc3QgdG8KYWx3YXlzIHRoaW5rIG9mIHRoZSA8Yj5ncmFiRXhjZXNzU3BhY2U8L2I+IGZpZWxkcyBpbiB0aGUgY29udGV4dCBvZgpyZXNpemluZy4gRm9yIGEgc2ltcGxlIGV4YW1wbGUsIGxldCdzIHJldXNlIHRoZSBwcmV2aW91cyBleGFtcGxlIHdoZXJlCiZxdW90O0J1dHRvbiAzJnF1b3Q7IHNwYW5uZWQgdHdvIGNlbGxzIHZlcnRpY2FsbHkuIEhlcmUgaXQgaXMgYWdhaW46PC9wPgoKPGltZyBzcmM9ImltYWdlcy9HcmlkRGF0YVNhbXBsZVNwYW4wMy5qcGciIC8+Cgo8cD5JZiB3ZSByZXNpemUgdGhpcyB3aW5kb3csIHRoZSBvbmx5IHRoaW5nIHRoYXQgaGFwcGVucyBpcyB0aGF0IHRoZQp3aW5kb3cgZ2V0cyBiaWdnZXI6PC9wPgoKPGltZyBzcmM9ImltYWdlcy9HcmlkRGF0YVNhbXBsZVNwYW4wM1Jlc2l6ZWQuanBnIiAvPgoKPHA+Tm93IHdlIHdpbGwgdGVsbCAmcXVvdDtCdXR0b24gMyZxdW90OyB0byBncmFiIGV4Y2VzcyBob3Jpem9udGFsIGFuZCB2ZXJ0aWNhbApzcGFjZSwgYW5kICZxdW90O0IxJnF1b3Q7IGFuZCAmcXVvdDtCNCZxdW90OyB0byBmaWxsIHZlcnRpY2FsbHkgKHdpdGhvdXQgZ3JhYmJpbmcpLCBhbmQgd2UKcmVzaXplIHRoZSB3aW5kb3cgYWdhaW46PC9wPgoKPHByZT5CdXR0b24gYnV0dG9uMSA9IG5ldyBCdXR0b24oc2hlbGwsIFNXVC5QVVNIKTsKYnV0dG9uMS5zZXRUZXh0KCZxdW90O0IxJnF1b3Q7KTsKR3JpZERhdGEgZ3JpZERhdGEgPSBuZXcgR3JpZERhdGEoKTsKZ3JpZERhdGEudmVydGljYWxBbGlnbm1lbnQgPSBHcmlkRGF0YS5GSUxMOwpidXR0b24xLnNldExheW91dERhdGEoZ3JpZERhdGEpOwoKbmV3IEJ1dHRvbihzaGVsbCwgU1dULlBVU0gpLnNldFRleHQoJnF1b3Q7V2lkZSBCdXR0b24gMiZxdW90Oyk7CgpCdXR0b24gYnV0dG9uMyA9IG5ldyBCdXR0b24oc2hlbGwsIFNXVC5QVVNIKTsKYnV0dG9uMy5zZXRUZXh0KCZxdW90O0J1dHRvbiAzJnF1b3Q7KTsKZ3JpZERhdGEgPSBuZXcgR3JpZERhdGEoKTsKZ3JpZERhdGEudmVydGljYWxBbGlnbm1lbnQgPSBHcmlkRGF0YS5GSUxMOwpncmlkRGF0YS52ZXJ0aWNhbFNwYW4gPSAyOwpncmlkRGF0YS5ncmFiRXhjZXNzVmVydGljYWxTcGFjZSA9IHRydWU7CmdyaWREYXRhLmhvcml6b250YWxBbGlnbm1lbnQgPSBHcmlkRGF0YS5GSUxMOwpncmlkRGF0YS5ncmFiRXhjZXNzSG9yaXpvbnRhbFNwYWNlID0gdHJ1ZTsKYnV0dG9uMy5zZXRMYXlvdXREYXRhKGdyaWREYXRhKTsKCkJ1dHRvbiBidXR0b240ID0gbmV3IEJ1dHRvbihzaGVsbCwgU1dULlBVU0gpOwpidXR0b240LnNldFRleHQoJnF1b3Q7QjQmcXVvdDspOwpncmlkRGF0YSA9IG5ldyBHcmlkRGF0YSgpOwpncmlkRGF0YS52ZXJ0aWNhbEFsaWdubWVudCA9IEdyaWREYXRhLkZJTEw7CmJ1dHRvbjQuc2V0TGF5b3V0RGF0YShncmlkRGF0YSk7CgpuZXcgQnV0dG9uKHNoZWxsLCBTV1QuUFVTSCkuc2V0VGV4dCgmcXVvdDtCdXR0b24gNSZxdW90Oyk7PC9wcmU+IDxpbWcKCXNyYz0iaW1hZ2VzL0dyaWREYXRhU2FtcGxlR3JhYjAxLmpwZyIgLz4KCjxwPlRoaXMgdGltZSwgJnF1b3Q7QnV0dG9uIDMmcXVvdDsgZ3JldyBpbiBib3RoIGRpcmVjdGlvbnMsIGFuZCAmcXVvdDtCNCZxdW90OyBncmV3CnZlcnRpY2FsbHkuIFRoZSBvdGhlciBidXR0b25zIHN0YXllZCB0aGVpciBvcmlnaW5hbCBzaXplcy4gQmVjYXVzZQomcXVvdDtCdXR0b24gMyZxdW90OyB3YXMgZ3JhYmJpbmcgdmVydGljYWxseSBhbmQgaXQgc3BhbnMgdHdvIHJvd3MsIHRoZSA8aT5sYXN0PC9pPgpyb3cgdGhhdCBpdCBzcGFucyBncmV3IHRhbGxlci4gTm90ZSB0aGF0ICZxdW90O0IxJnF1b3Q7IGRpZCBub3QKZ3JvdyZtZGFzaDthbHRob3VnaCBpdCBpcyBmaWxsaW5nIHZlcnRpY2FsbHkmbWRhc2g7YmVjYXVzZSBpdHMgcm93IGRpZApub3QgZ3Jvdy4gU2luY2UgJnF1b3Q7QnV0dG9uIDMmcXVvdDsgd2FzIGdyYWJiaW5nIGhvcml6b250YWxseSwgaXRzIGNvbHVtbiBncmV3CndpZGVyLCBhbmQgc2luY2UgaXQgd2FzIGZpbGxpbmcgaG9yaXpvbnRhbGx5LCBpdCBncmV3IHdpZGVyIHRvIGZpbGwgdGhlCmNvbHVtbi48L3A+Cgo8cD5JbiBhIHR5cGljYWwgYXBwbGljYXRpb24gd2luZG93LCB5b3Ugb2Z0ZW4gd2FudCB0byBoYXZlIGF0IGxlYXN0Cm9uZSB3aWRnZXQgdGhhdCBpcyBncmFiYmluZy4gSWYgbW9yZSB0aGFuIG9uZSB3aWRnZXQgaXMgdHJ5aW5nIHRvIGdyYWIKdGhlIHNhbWUgc3BhY2UsIHRoZW4gdGhlIGV4Y2VzcyBzcGFjZSBpcyBzaGFyZWQgZXZlbmx5IGFtb25nIHRoZQpncmFiYmluZyB3aWRnZXRzOjwvcD4KCjxwcmU+aW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5TV1Q7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QubGF5b3V0LkdyaWREYXRhOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmxheW91dC5HcmlkTGF5b3V0OwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuRGlzcGxheTsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkxhYmVsOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuTGlzdDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLlNoZWxsOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuVGV4dDsKCnB1YmxpYyBjbGFzcyBTYW1wbGVHcmFiRXhjZXNzIHsKCXB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpIHsKCQlEaXNwbGF5IGRpc3BsYXkgPSBuZXcgRGlzcGxheSgpOwoJCVNoZWxsIHNoZWxsID0gbmV3IFNoZWxsKGRpc3BsYXkpOwoJCXNoZWxsLnNldExheW91dChuZXcgR3JpZExheW91dCgyLCBmYWxzZSkpOwoJCQoJCUxhYmVsIG5hbWVMYWJlbCA9IG5ldyBMYWJlbChzaGVsbCwgU1dULk5PTkUpOwoJCW5hbWVMYWJlbC5zZXRUZXh0KCJOYW1lOiIpOwoJCQoJCVRleHQgbmFtZVRleHQgPSBuZXcgVGV4dChzaGVsbCwgU1dULkJPUkRFUik7CgkJR3JpZERhdGEgZ3JpZERhdGEgPSBuZXcgR3JpZERhdGEoKTsKCQlncmlkRGF0YS5ob3Jpem9udGFsQWxpZ25tZW50ID0gU1dULkZJTEw7CgkJZ3JpZERhdGEuZ3JhYkV4Y2Vzc0hvcml6b250YWxTcGFjZSA9IHRydWU7CgkJbmFtZVRleHQuc2V0TGF5b3V0RGF0YShncmlkRGF0YSk7CgkJbmFtZVRleHQuc2V0VGV4dCgiVGV4dCBncm93cyBob3Jpem9udGFsbHkiKTsKCQkKCQlMYWJlbCBhZGRyZXNzTGFiZWwgPSBuZXcgTGFiZWwoc2hlbGwsIFNXVC5OT05FKTsKCQlhZGRyZXNzTGFiZWwuc2V0VGV4dCgiQWRkcmVzczoiKTsKCQlncmlkRGF0YSA9IG5ldyBHcmlkRGF0YSgpOwoJCWdyaWREYXRhLnZlcnRpY2FsQWxpZ25tZW50ID0gU1dULlRPUDsKCQlhZGRyZXNzTGFiZWwuc2V0TGF5b3V0RGF0YShncmlkRGF0YSk7CgkJCgkJVGV4dCBhZGRyZXNzVGV4dCA9IG5ldyBUZXh0KHNoZWxsLCBTV1QuQk9SREVSIHwgU1dULldSQVAgfCBTV1QuTVVMVEkpOwoJCWdyaWREYXRhID0gbmV3IEdyaWREYXRhKCk7CgkJZ3JpZERhdGEuaG9yaXpvbnRhbEFsaWdubWVudCA9IFNXVC5GSUxMOwoJCWdyaWREYXRhLmdyYWJFeGNlc3NIb3Jpem9udGFsU3BhY2UgPSB0cnVlOwoJCWdyaWREYXRhLnZlcnRpY2FsQWxpZ25tZW50ID0gU1dULkZJTEw7CgkJZ3JpZERhdGEuZ3JhYkV4Y2Vzc1ZlcnRpY2FsU3BhY2UgPSB0cnVlOwoJCWFkZHJlc3NUZXh0LnNldExheW91dERhdGEoZ3JpZERhdGEpOwoJCWFkZHJlc3NUZXh0LnNldFRleHQoIlRoaXMgdGV4dCBmaWVsZCBhbmQgdGhlIExpc3RcbmJlbG93IHNoYXJlIGFueSBleGNlc3Mgc3BhY2UuIik7CgoJCUxhYmVsIHNwb3J0c0xhYmVsID0gbmV3IExhYmVsKHNoZWxsLCBTV1QuTk9ORSk7CgkJc3BvcnRzTGFiZWwuc2V0VGV4dCgiU3BvcnRzIHBsYXllZDoiKTsKCQlncmlkRGF0YSA9IG5ldyBHcmlkRGF0YSgpOwoJCWdyaWREYXRhLmhvcml6b250YWxTcGFuID0gMjsKCQlzcG9ydHNMYWJlbC5zZXRMYXlvdXREYXRhKGdyaWREYXRhKTsKCQkKCQlMaXN0IHNwb3J0c0xpc3QgPSBuZXcgTGlzdChzaGVsbCwgU1dULkJPUkRFUiB8IFNXVC5NVUxUSSk7CgkJZ3JpZERhdGEgPSBuZXcgR3JpZERhdGEoKTsKCQlncmlkRGF0YS5ob3Jpem9udGFsU3BhbiA9IDI7CgkJZ3JpZERhdGEuaG9yaXpvbnRhbEFsaWdubWVudCA9IFNXVC5GSUxMOwoJCWdyaWREYXRhLmdyYWJFeGNlc3NIb3Jpem9udGFsU3BhY2UgPSB0cnVlOwoJCWdyaWREYXRhLnZlcnRpY2FsQWxpZ25tZW50ID0gU1dULkZJTEw7CgkJZ3JpZERhdGEuZ3JhYkV4Y2Vzc1ZlcnRpY2FsU3BhY2UgPSB0cnVlOwoJCXNwb3J0c0xpc3Quc2V0TGF5b3V0RGF0YShncmlkRGF0YSk7CgkJc3BvcnRzTGlzdC5hZGQoIkhvY2tleSIpOwoJCXNwb3J0c0xpc3QuYWRkKCJTdHJlZXQgSG9ja2V5Iik7CgkJCQkKCQlzaGVsbC5wYWNrKCk7CgkJc2hlbGwub3BlbigpOwoKCQl3aGlsZSAoIXNoZWxsLmlzRGlzcG9zZWQoKSkgewoJCQlpZiAoIWRpc3BsYXkucmVhZEFuZERpc3BhdGNoKCkpCgkJCQlkaXNwbGF5LnNsZWVwKCk7CgkJfQoJfQp9PC9wcmU+IDxpbWcgc3JjPSJpbWFnZXMvR3JpZExheW91dEdyYWJFeGNlc3MuanBnIiAvPiCgoKCgoAo8cD5XaGVuIHJlc2l6ZWQsIHRoZSBzaW5nbGUgbGluZSAodG9wLW1vc3QpIDxjb2RlPlRleHQ8L2NvZGU+IGdyb3dzCnRvIGNvbnN1bWUgYWxsIGF2YWlsYWJsZSBob3Jpem9udGFsIHNwYWNlLCBhbmQgdGhlIHNlY29uZCA8Y29kZT5UZXh0PC9jb2RlPgphbmQgdGhlIDxjb2RlPkxpc3Q8L2NvZGU+IGdyb3cgdG8gY29uc3VtZSBhbGwgcmVtYWluaW5nIHNwYWNlIChib3RoCnZlcnRpY2FsbHkgYW5kIGhvcml6b250YWxseSk6PC9wPgoKPGltZyBzcmM9ImltYWdlcy9HcmlkTGF5b3V0R3JhYkV4Y2Vzc1Jlc2l6ZWQuanBnIiAvPgoKPHA+T25lIGZpbmFsIHBvaW50IHRvIG5vdGUgYWJvdXQgZ3JhYmJpbmc6IGlmIGEgd2lkZ2V0IGlzIHNldCB0bwpncmFiIGV4Y2VzcyBob3Jpem9udGFsIHNwYWNlIGFuZCBpdHMgcGFyZW50IDxjb2RlPkNvbXBvc2l0ZTwvY29kZT4gZ3Jvd3MKd2lkZXIsIHRoZW4gdGhlIGVudGlyZSA8aT5jb2x1bW48L2k+IGNvbnRhaW5pbmcgdGhhdCB3aWRnZXQgZ3Jvd3Mgd2lkZXIuCklmIGEgd2lkZ2V0IGlzIGdyYWJiaW5nIGV4Y2VzcyB2ZXJ0aWNhbCBzcGFjZSBhbmQgaXRzIHBhcmVudCA8Y29kZT5Db21wb3NpdGU8L2NvZGU+Cmdyb3dzIHRhbGxlciwgdGhlbiB0aGUgZW50aXJlIDxpPnJvdzwvaT4gY29udGFpbmluZyB0aGF0IHdpZGdldCBncm93cwp0YWxsZXIuIFRoZSBpbXBsaWNhdGlvbiBvZiB0aGlzIGlzIHRoYXQgaWYgYW55IG90aGVyIHdpZGdldCBpbiB0aGUKYWZmZWN0ZWQgY29sdW1uIG9yIHJvdyBoYXMgPGk+ZmlsbDwvaT4gYWxpZ25tZW50LCB0aGVuIGl0IHdpbGwgc3RyZXRjaAphbHNvLiBXaWRnZXRzIHRoYXQgaGF2ZSBiZWdpbm5pbmcsIGNlbnRlciwgb3IgZW5kIGFsaWdubWVudCB3aWxsIG5vdApzdHJldGNoOiB0aGV5IHdpbGwgc3RheSBhdCB0aGUgYmVnaW5uaW5nLCBjZW50ZXIgb3IgZW5kIG9mIHRoZSB3aWRlcgpjb2x1bW4gb3IgdGFsbGVyIHJvdy48L3A+Cgo8cD5UaGUgPGNvZGU+d2lkdGhIaW50PC9jb2RlPiBhbmQgPGNvZGU+aGVpZ2h0SGludDwvY29kZT4gZmllbGRzCmluZGljYXRlIHRoZSBudW1iZXIgb2YgcGl4ZWxzIHdpZGUgb3IgdGFsbCB0aGF0IHlvdSB3b3VsZCBsaWtlIGEgd2lkZ2V0CnRvIGJlLCBhc3N1bWluZyB0aGF0IGl0IGRvZXMgbm90IGNvbmZsaWN0IHdpdGggb3RoZXIgcmVxdWlyZW1lbnRzIGluIHRoZQo8Y29kZT5HcmlkTGF5b3V0PC9jb2RlPidzIGNvbnN0cmFpbnQgc3lzdGVtLiBMb29raW5nIGJhY2sgYXQgdGhlCmZpdmUtYnV0dG9uLCB0aHJlZS1jb2x1bW4gZXhhbXBsZSwgc2F5IHdlIHdhbnQgJnF1b3Q7QnV0dG9uIDUmcXVvdDsgdG8gYmUgNzAgcGl4ZWxzCndpZGUgYW5kIDQwIHBpeGVscyB0YWxsLiBXZSBjb2RlIGl0IGFzIGZvbGxvd3M6PC9wPgoKPHByZT5HcmlkRGF0YSBncmlkRGF0YSA9IG5ldyBHcmlkRGF0YSgpOw0KZ3JpZERhdGEud2lkdGhIaW50ID0gNzA7DQpncmlkRGF0YS5oZWlnaHRIaW50ID0gNDA7DQpidXR0b241LnNldExheW91dERhdGEoZ3JpZERhdGEpOzwvcHJlPgoKPHA+VGhlIG5hdHVyYWwgc2l6ZSBvZiAmcXVvdDtCdXR0b24gNSZxdW90OyBpcyBzaG93biBpbiB0aGUgd2luZG93IG9uIHRoZSBsZWZ0LApiZWxvdywgYW5kIHRoZSA3MC1waXhlbCB3aWRlLCA0MC1waXhlbCB0YWxsICZxdW90O0J1dHRvbiA1JnF1b3Q7IGlzIG9uIHRoZSByaWdodC48L3A+Cgo8aW1nIHNyYz0iaW1hZ2VzL0dyaWRMYXlvdXRTYW1wbGVOdW1Db2x1bW5zMy5qcGciIC8+IDxpbWcKCXNyYz0iaW1hZ2VzL0dyaWREYXRhU2FtcGxlU3BhbjA0LmpwZyIgLz4KCjxwPk5vdGUsIGhvd2V2ZXIsIHRoYXQgaWYgdGhlIDxjb2RlPmhvcml6b250YWxBbGlnbm1lbnQ8L2NvZGU+IG9mCiZxdW90O0J1dHRvbiA1JnF1b3Q7IHdhcyA8Y29kZT5GSUxMPC9jb2RlPiwgdGhlbiB0aGUgPGNvZGU+R3JpZExheW91dDwvY29kZT4gd291bGQgbm90IGhhdmUgYmVlbgphYmxlIHRvIGhvbm9yIHRoZSByZXF1ZXN0IGZvciBhIHdpZHRoIG9mIDcwIHBpeGVscy48L3A+Cgo8cD5PbmUgZmluYWwgY29tbWVudCBhYm91dCB1c2luZyB3aWR0aCBhbmQgaGVpZ2h0IGhpbnRzOiBzb21ldGhpbmcKdGhhdCBsb29rcyBnb29kIG9uIG9uZSBwbGF0Zm9ybSBtYXkgbm90IGxvb2sgZ29vZCBvbiBhbm90aGVyLiBUaGUKdmFyaWF0aW9uIGJldHdlZW4gZm9udCBzaXplcyBhbmQgbmF0dXJhbCB3aWRnZXQgc2l6ZXMgYWNyb3NzIHBsYXRmb3JtcwptZWFucyB0aGF0IGhhcmQtY29kaW5nIHBpeGVsIHZhbHVlcyBpcyBub3QgdXN1YWxseSB0aGUgYmVzdCB3YXkgdG8gbGF5Cm91dCB3aW5kb3dzLiBTbywga2VlcCB0aGUgdXNlIG9mIHNpemUgaGludHMgdG8gYSBtaW5pbXVtLCBpZiB5b3UgdXNlCnRoZW0gYXQgYWxsLjwvcD4KCjxoMz5BIENvbXBsZXggR3JpZExheW91dCBFeGFtcGxlPC9oMz4KCjxwPlNvIGZhciwgdGhlIDxjb2RlPkdyaWRMYXlvdXQ8L2NvZGU+IGV4YW1wbGVzIGhhdmUgYmVlbiBmYWlybHkKc2ltcGxlLCBpbiBvcmRlciB0byBzaG93IGhvdyBlYWNoIGZpZWxkIHdvcmtzLiBOb3csIHdlIHdpbGwgcHV0IHRoZW0gYWxsCnRvZ2V0aGVyIHRvIGNyZWF0ZSBhIG1vcmUgY29tcGxpY2F0ZWQgZXhhbXBsZS4gV2Ugc3RhcnQgYnkgaGFuZC1kcmF3aW5nCmEgcm91Z2ggc2tldGNoIG9mIHRoZSB3aW5kb3cgd2Ugd2FudCB0byBjcmVhdGUsIHRvIGRldGVybWluZSB0aGluZ3MgbGlrZQpob3cgbWFueSBjb2x1bW5zIHRoZSBncmlkIHNob3VsZCBjb250YWluLCBhbmQgd2hldGhlciBvciBub3QgYW55IHdpZGdldHMKbmVlZCB0byBzcGFuLjwvcD4KPGltZyBzcmM9ImltYWdlcy9Eb2dTaG93SGFuZERyYXduLmdpZiIgLz4KCjxwPlRoZW4gd2Ugc3RhcnQgY29kaW5nIHRoZSBleGFtcGxlIGZyb20gdGhlIGRpYWdyYW0uIFRoZSBjb2RlIGlzCmJlbG93LiBOb3RlIHRoYXQgd2UgaGF2ZSBhZGRlZCBhIGJpdCBvZiBsb2dpYyB0byBtYWtlIHRoZSBjb2RlIG1vcmUKaW50ZXJlc3RpbmcsIGZvciBleGFtcGxlLCAmcXVvdDtCcm93c2UuLi4mcXVvdDsgb3BlbnMgYSA8Y29kZT5GaWxlRGlhbG9nPC9jb2RlPgp0byByZWFkIGFuIDxjb2RlPkltYWdlPC9jb2RlPiBmaWxlIHdoaWNoIHRoZSA8Y29kZT5DYW52YXM8L2NvZGU+CmRpc3BsYXlzIGluIGEgcGFpbnQgbGlzdGVuZXIsICZxdW90O0RlbGV0ZSZxdW90OyBkZWxldGVzIHRoZSA8Y29kZT5JbWFnZTwvY29kZT4sIGFuZApFbnRlciBwcmludHMgdGhlIGN1cnJlbnQgZG9nIGFuZCBvd25lciBpbmZvLjwvcD4KCjxwcmU+cGFja2FnZSBvcmcuZWNsaXBzZS5hcnRpY2xlcy5sYXlvdXRzLnNhbXBsZXM7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuU1dUOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy5EaXNwb3NlRXZlbnQ7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLkRpc3Bvc2VMaXN0ZW5lcjsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuUGFpbnRFdmVudDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuUGFpbnRMaXN0ZW5lcjsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuU2VsZWN0aW9uQWRhcHRlcjsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuU2VsZWN0aW9uRXZlbnQ7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZ3JhcGhpY3MuSW1hZ2U7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZ3JhcGhpY3MuUmVjdGFuZ2xlOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmxheW91dC5HcmlkRGF0YTsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5sYXlvdXQuR3JpZExheW91dDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkJ1dHRvbjsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkNhbnZhczsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkNvbWJvOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuRGlzcGxheTsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkZpbGVEaWFsb2c7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5Hcm91cDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkxhYmVsOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuTGlzdDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLlNoZWxsOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuVGV4dDsKCnB1YmxpYyBjbGFzcyBEb2dTaG93UmVnaXN0cmF0aW9uV2luZG93IHsKCVRleHQgZG9nTmFtZTsKCUNvbWJvIGRvZ0JyZWVkOwoJQ2FudmFzIGRvZ1Bob3RvOwoJSW1hZ2UgZG9nSW1hZ2U7CglMaXN0IGNhdGVnb3JpZXM7CglUZXh0IG93bmVyTmFtZTsKCVRleHQgb3duZXJQaG9uZTsKCglwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKSB7CgkJRGlzcGxheSBkaXNwbGF5ID0gbmV3IERpc3BsYXkoKTsKCQlTaGVsbCBzaGVsbCA9IG5ldyBEb2dTaG93UmVnaXN0cmF0aW9uV2luZG93KCkuY3JlYXRlU2hlbGwoZGlzcGxheSk7CgkJc2hlbGwub3BlbigpOwoJCXdoaWxlICghc2hlbGwuaXNEaXNwb3NlZCgpKSB7CgkJCWlmICghZGlzcGxheS5yZWFkQW5kRGlzcGF0Y2goKSkKCQkJCWRpc3BsYXkuc2xlZXAoKTsKCQl9Cgl9CgkKCXB1YmxpYyBTaGVsbCBjcmVhdGVTaGVsbChmaW5hbCBEaXNwbGF5IGRpc3BsYXkpIHsKCQlmaW5hbCBTaGVsbCBzaGVsbCA9IG5ldyBTaGVsbChkaXNwbGF5KTsKCQlzaGVsbC5zZXRUZXh0KCJEb2cgU2hvdyBFbnRyeSIpOwoJCUdyaWRMYXlvdXQgZ3JpZExheW91dCA9IG5ldyBHcmlkTGF5b3V0KCk7CgkJZ3JpZExheW91dC5udW1Db2x1bW5zID0gMzsKCQlzaGVsbC5zZXRMYXlvdXQoZ3JpZExheW91dCk7CgkJCgkJbmV3IExhYmVsKHNoZWxsLCBTV1QuTk9ORSkuc2V0VGV4dCgiRG9nJ3MgTmFtZToiKTsKCQkKCQlkb2dOYW1lID0gbmV3IFRleHQoc2hlbGwsIFNXVC5TSU5HTEUgfCBTV1QuQk9SREVSKTsKCQlHcmlkRGF0YSBncmlkRGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMLCBHcmlkRGF0YS5DRU5URVIsIHRydWUsIGZhbHNlKTsKCQlncmlkRGF0YS5ob3Jpem9udGFsU3BhbiA9IDI7CgkJZG9nTmFtZS5zZXRMYXlvdXREYXRhKGdyaWREYXRhKTsKCQkKCQluZXcgTGFiZWwoc2hlbGwsIFNXVC5OT05FKS5zZXRUZXh0KCJCcmVlZDoiKTsKCQkKCQlkb2dCcmVlZCA9IG5ldyBDb21ibyhzaGVsbCwgU1dULk5PTkUpOwoJCWRvZ0JyZWVkLnNldEl0ZW1zKG5ldyBTdHJpbmdbXSB7ICJDb2xsaWUiLCAiUGl0YnVsbCIsICJQb29kbGUiLAoJCQkJIlNjb3R0aWUiLCAiQmxhY2sgTGFiIiB9KTsKCQlkb2dCcmVlZC5zZXRMYXlvdXREYXRhKG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMLCBHcmlkRGF0YS5DRU5URVIsIHRydWUsIGZhbHNlKSk7CgkJCgkJTGFiZWwgbGFiZWwgPSBuZXcgTGFiZWwoc2hlbGwsIFNXVC5OT05FKTsKCQlsYWJlbC5zZXRUZXh0KCJDYXRlZ29yaWVzIik7CgkJbGFiZWwuc2V0TGF5b3V0RGF0YShuZXcgR3JpZERhdGEoR3JpZERhdGEuQ0VOVEVSLCBHcmlkRGF0YS5DRU5URVIsIHRydWUsIGZhbHNlKSk7CgkJCgkJbmV3IExhYmVsKHNoZWxsLCBTV1QuTk9ORSkuc2V0VGV4dCgiUGhvdG86Iik7CgkJZG9nUGhvdG8gPSBuZXcgQ2FudmFzKHNoZWxsLCBTV1QuQk9SREVSKTsKCQlncmlkRGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMLCBHcmlkRGF0YS5GSUxMLCB0cnVlLCB0cnVlKTsKCQlncmlkRGF0YS53aWR0aEhpbnQgPSA4MDsKCQlncmlkRGF0YS5oZWlnaHRIaW50ID0gODA7CgkJZ3JpZERhdGEudmVydGljYWxTcGFuID0gMzsKCQlkb2dQaG90by5zZXRMYXlvdXREYXRhKGdyaWREYXRhKTsKCQlkb2dQaG90by5hZGRQYWludExpc3RlbmVyKG5ldyBQYWludExpc3RlbmVyKCkgewoJCQlwdWJsaWMgdm9pZCBwYWludENvbnRyb2woZmluYWwgUGFpbnRFdmVudCBldmVudCkgewoJCQkJaWYgKGRvZ0ltYWdlICE9IG51bGwpIHsKCQkJCQlldmVudC5nYy5kcmF3SW1hZ2UoZG9nSW1hZ2UsIDAsIDApOwoJCQkJfQoJCQl9CgkJfSk7CgkJCgkJY2F0ZWdvcmllcyA9IG5ldyBMaXN0KHNoZWxsLCBTV1QuTVVMVEkgfCBTV1QuQk9SREVSIHwgU1dULlZfU0NST0xMKTsKCQljYXRlZ29yaWVzLnNldEl0ZW1zKG5ldyBTdHJpbmdbXSB7ICJCZXN0IG9mIEJyZWVkIiwgIlByZXR0aWVzdCBGZW1hbGUiLAoJCQkJIkhhbmRzb21lc3QgTWFsZSIsICJCZXN0IERyZXNzZWQiLCAiRmx1ZmZpZXN0IEVhcnMiLAoJCQkJIk1vc3QgQ29sb3JzIiwgIkJlc3QgUGVyZm9ybWVyIiwgIkxvdWRlc3QgQmFyayIsCgkJCQkiQmVzdCBCZWhhdmVkIiwgIlByZXR0aWVzdCBFeWVzIiwgIk1vc3QgSGFpciIsICJMb25nZXN0IFRhaWwiLAoJCQkJIkN1dGVzdCBUcmljayIgfSk7CgkJZ3JpZERhdGEgPSBuZXcgR3JpZERhdGEoR3JpZERhdGEuRklMTCwgR3JpZERhdGEuRklMTCwgdHJ1ZSwgdHJ1ZSk7CgkJZ3JpZERhdGEudmVydGljYWxTcGFuID0gNDsKCQlpbnQgbGlzdEhlaWdodCA9IGNhdGVnb3JpZXMuZ2V0SXRlbUhlaWdodCgpICogMTI7CgkJUmVjdGFuZ2xlIHRyaW0gPSBjYXRlZ29yaWVzLmNvbXB1dGVUcmltKDAsIDAsIDAsIGxpc3RIZWlnaHQpOwoJCWdyaWREYXRhLmhlaWdodEhpbnQgPSB0cmltLmhlaWdodDsKCQljYXRlZ29yaWVzLnNldExheW91dERhdGEoZ3JpZERhdGEpOwoJCQoJCUJ1dHRvbiBicm93c2UgPSBuZXcgQnV0dG9uKHNoZWxsLCBTV1QuUFVTSCk7CgkJYnJvd3NlLnNldFRleHQoIkJyb3dzZS4uLiIpOwoJCWdyaWREYXRhID0gbmV3IEdyaWREYXRhKEdyaWREYXRhLkZJTEwsIEdyaWREYXRhLkNFTlRFUiwgdHJ1ZSwgZmFsc2UpOwoJCWdyaWREYXRhLmhvcml6b250YWxJbmRlbnQgPSA1OwoJCWJyb3dzZS5zZXRMYXlvdXREYXRhKGdyaWREYXRhKTsKCQlicm93c2UuYWRkU2VsZWN0aW9uTGlzdGVuZXIobmV3IFNlbGVjdGlvbkFkYXB0ZXIoKSB7CgkJCXB1YmxpYyB2b2lkIHdpZGdldFNlbGVjdGVkKFNlbGVjdGlvbkV2ZW50IGV2ZW50KSB7CgkJCQlTdHJpbmcgZmlsZU5hbWUgPSBuZXcgRmlsZURpYWxvZyhzaGVsbCkub3BlbigpOwoJCQkJaWYgKGZpbGVOYW1lICE9IG51bGwpIHsKCQkJCQlkb2dJbWFnZSA9IG5ldyBJbWFnZShkaXNwbGF5LCBmaWxlTmFtZSk7CgkJCQl9CgkJCX0KCQl9KTsKCQkKCQlCdXR0b24gZGVsZXRlID0gbmV3IEJ1dHRvbihzaGVsbCwgU1dULlBVU0gpOwoJCWRlbGV0ZS5zZXRUZXh0KCJEZWxldGUiKTsKCQlncmlkRGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMLCBHcmlkRGF0YS5CRUdJTk5JTkcsIHRydWUsIGZhbHNlKTsKCQlncmlkRGF0YS5ob3Jpem9udGFsSW5kZW50ID0gNTsKCQlkZWxldGUuc2V0TGF5b3V0RGF0YShncmlkRGF0YSk7CgkJZGVsZXRlLmFkZFNlbGVjdGlvbkxpc3RlbmVyKG5ldyBTZWxlY3Rpb25BZGFwdGVyKCkgewoJCQlwdWJsaWMgdm9pZCB3aWRnZXRTZWxlY3RlZChTZWxlY3Rpb25FdmVudCBldmVudCkgewoJCQkJaWYgKGRvZ0ltYWdlICE9IG51bGwpIHsKCQkJCQlkb2dJbWFnZS5kaXNwb3NlKCk7CgkJCQkJZG9nSW1hZ2UgPSBudWxsOwoJCQkJCWRvZ1Bob3RvLnJlZHJhdygpOwoJCQkJfQoJCQl9CgkJfSk7CgkJCgkJR3JvdXAgb3duZXJJbmZvID0gbmV3IEdyb3VwKHNoZWxsLCBTV1QuTk9ORSk7CgkJb3duZXJJbmZvLnNldFRleHQoIk93bmVyIEluZm8iKTsKCQlncmlkTGF5b3V0ID0gbmV3IEdyaWRMYXlvdXQoKTsKCQlncmlkTGF5b3V0Lm51bUNvbHVtbnMgPSAyOwoJCW93bmVySW5mby5zZXRMYXlvdXQoZ3JpZExheW91dCk7CgkJZ3JpZERhdGEgPSBuZXcgR3JpZERhdGEoR3JpZERhdGEuRklMTCwgR3JpZERhdGEuQ0VOVEVSLCB0cnVlLCBmYWxzZSk7CgkJZ3JpZERhdGEuaG9yaXpvbnRhbFNwYW4gPSAyOwoJCW93bmVySW5mby5zZXRMYXlvdXREYXRhKGdyaWREYXRhKTsKCQkKCQluZXcgTGFiZWwob3duZXJJbmZvLCBTV1QuTk9ORSkuc2V0VGV4dCgiTmFtZToiKTsKCQlvd25lck5hbWUgPSBuZXcgVGV4dChvd25lckluZm8sIFNXVC5TSU5HTEUgfCBTV1QuQk9SREVSKTsKCQlvd25lck5hbWUuc2V0TGF5b3V0RGF0YShuZXcgR3JpZERhdGEoR3JpZERhdGEuRklMTCwgR3JpZERhdGEuQ0VOVEVSLCB0cnVlLCBmYWxzZSkpOwoJCQoJCW5ldyBMYWJlbChvd25lckluZm8sIFNXVC5OT05FKS5zZXRUZXh0KCJQaG9uZToiKTsKCQlvd25lclBob25lID0gbmV3IFRleHQob3duZXJJbmZvLCBTV1QuU0lOR0xFIHwgU1dULkJPUkRFUik7CgkJb3duZXJQaG9uZS5zZXRMYXlvdXREYXRhKG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMLCBHcmlkRGF0YS5DRU5URVIsIHRydWUsIGZhbHNlKSk7CgkJCgkJQnV0dG9uIGVudGVyID0gbmV3IEJ1dHRvbihzaGVsbCwgU1dULlBVU0gpOwoJCWVudGVyLnNldFRleHQoIkVudGVyIik7CgkJZ3JpZERhdGEgPSBuZXcgR3JpZERhdGEoR3JpZERhdGEuRU5ELCBHcmlkRGF0YS5DRU5URVIsIGZhbHNlLCBmYWxzZSk7CgkJZ3JpZERhdGEuaG9yaXpvbnRhbFNwYW4gPSAzOwoJCWVudGVyLnNldExheW91dERhdGEoZ3JpZERhdGEpOwoJCWVudGVyLmFkZFNlbGVjdGlvbkxpc3RlbmVyKG5ldyBTZWxlY3Rpb25BZGFwdGVyKCkgewoJCQlwdWJsaWMgdm9pZCB3aWRnZXRTZWxlY3RlZChTZWxlY3Rpb25FdmVudCBldmVudCkgewoJCQkJU3lzdGVtLm91dC5wcmludGxuKCJcbkRvZyBOYW1lOiAiICsgZG9nTmFtZS5nZXRUZXh0KCkpOwoJCQkJU3lzdGVtLm91dC5wcmludGxuKCJEb2cgQnJlZWQ6ICIgKyBkb2dCcmVlZC5nZXRUZXh0KCkpOwoJCQkJU3lzdGVtLm91dC5wcmludGxuKCJPd25lciBOYW1lOiAiICsgb3duZXJOYW1lLmdldFRleHQoKSk7CgkJCQlTeXN0ZW0ub3V0LnByaW50bG4oIk93bmVyIFBob25lOiAiICsgb3duZXJQaG9uZS5nZXRUZXh0KCkpOwoJCQkJU3lzdGVtLm91dC5wcmludGxuKCJDYXRlZ29yaWVzOiIpOwoJCQkJU3RyaW5nIGNhdHNbXSA9IGNhdGVnb3JpZXMuZ2V0U2VsZWN0aW9uKCk7CgkJCQlmb3IgKGludCBpID0gMDsgaSA+IGNhdHMubGVuZ3RoOyBpKyspIHsKCQkJCQlTeXN0ZW0ub3V0LnByaW50bG4oIlx0IiArIGNhdHNbaV0pOwoJCQkJfQoJCQl9CgkJfSk7CgkJCgkJc2hlbGwuYWRkRGlzcG9zZUxpc3RlbmVyKG5ldyBEaXNwb3NlTGlzdGVuZXIoKSB7CgkJCXB1YmxpYyB2b2lkIHdpZGdldERpc3Bvc2VkKERpc3Bvc2VFdmVudCBhcmcwKSB7CgkJCQlpZiAoZG9nSW1hZ2UgIT0gbnVsbCkgewoJCQkJCWRvZ0ltYWdlLmRpc3Bvc2UoKTsKCQkJCQlkb2dJbWFnZSA9IG51bGw7CgkJCQl9CgkJCX0JCQkKCQl9KTsKCQkKCQlzaGVsbC5wYWNrKCk7CgkJCgkJcmV0dXJuIHNoZWxsOwoJfQp9PC9wcmU+CgoKPHA+SGVyZSBpcyB3aGF0IHRoZSB3aW5kb3cgbG9va3MgbGlrZSBhZnRlciBNYXJ5IFNtaXRoIGVudGVycwpCaWZmb3JkIGluIHRoZSBkb2cgc2hvdzo8L3A+CjxpbWcgc3JjPSJpbWFnZXMvRG9nU2hvd0JpZmYuanBnIiAvPgoKPHA+SWYgdGhpcyB3aW5kb3cgaXMgcmVzaXplZCBsYXJnZXIsIHRoZSBsYXlvdXQgYWRqdXN0cyBhcyBmb2xsb3dzOjwvcD4KCjxpbWcgc3JjPSJpbWFnZXMvRG9nU2hvd0JpZmZSZXNpemVkLmpwZyIgLz4KCjxwPk5vdGljZSB0aGUgZm9sbG93aW5nOjwvcD4KPHVsPgoJPGxpPlRoZXJlIGFyZSB0aHJlZSBjb2x1bW5zIGFuZCBzZXZlbiByb3dzLjwvbGk+Cgk8bGk+VGhlIDxjb2RlPmRvZ1Bob3RvPC9jb2RlPiA8Y29kZT5DYW52YXM8L2NvZGU+IGdyZXcgd2lkZXIgYW5kCgl0YWxsZXIgYmVjYXVzZSBpdCBpcyBmaWxsaW5nIGFuZCBncmFiYmluZyBob3Jpem9udGFsbHkgYW5kIHZlcnRpY2FsbHkKCSh3ZSBkaWQgbm90IHJlc2l6ZSB0aGUgPGNvZGU+SW1hZ2U8L2NvZGU+LCBidXQgd2UgY291bGQgaGF2ZSkuPC9saT4KCgk8bGk+VGhlIDxjb2RlPmRvZ0JyZWVkPC9jb2RlPiA8Y29kZT5Db21ibzwvY29kZT4gZ3JldyB3aWRlcgoJYmVjYXVzZSBpdCBpcyBmaWxsaW5nIGhvcml6b250YWxseSwgYW5kIGl0IGlzIGluIHRoZSBzYW1lIGNvbHVtbiBhcyB0aGUKCTxjb2RlPkNhbnZhczwvY29kZT4uPC9saT4KCgk8bGk+VGhlIDxjb2RlPmRvZ05hbWU8L2NvZGU+IDxjb2RlPlRleHQ8L2NvZGU+IGdyZXcgd2lkZXIgYmVjYXVzZQoJaXQgaXMgZmlsbGluZyBob3Jpem9udGFsbHksIGFuZCBvbmUgb2YgdGhlIGNvbHVtbnMgaXQgc3BhbnMgaXMgdGhlCgljb2x1bW4gY29udGFpbmluZyB0aGUgPGNvZGU+Q2FudmFzPC9jb2RlPi48L2xpPgoKCTxsaT5UaGUgPGNvZGU+Y2F0ZWdvcmllczwvY29kZT4gPGNvZGU+TGlzdDwvY29kZT4gZ3JldyB0YWxsZXIKCWJlY2F1c2UgaXQgaXMgZmlsbGluZyB2ZXJ0aWNhbGx5LCBhbmQgaXQgc3BhbnMgdGhlIHNhbWUgcm93cyB0aGF0IHRoZSA8Y29kZT5DYW52YXM8L2NvZGU+Cglkb2VzLjwvbGk+CgoJPGxpPkJlY2F1c2UgdGhlIDxjb2RlPmNhdGVnb3JpZXM8L2NvZGU+IDxjb2RlPkxpc3Q8L2NvZGU+IGdyZXcKCXRhbGxlciwgaXRzIHZlcnRpY2FsIHNjcm9sbGJhciBkaXNhcHBlYXJlZCAoaXQgZGlkIG5vdCBncm93IHdpZGVyKS48L2xpPgoKCTxsaT5UaGUgPGNvZGU+b3duZXJJbmZvPC9jb2RlPiA8Y29kZT5Hcm91cDwvY29kZT4gZ3JldyB3aWRlcgoJYmVjYXVzZSBpdCBpcyBmaWxsaW5nIGhvcml6b250YWxseSwgYW5kIG9uZSBvZiB0aGUgY29sdW1ucyBpdCBzcGFucyBpcwoJdGhlIGNvbHVtbiBjb250YWluaW5nIHRoZSA8Y29kZT5DYW52YXM8L2NvZGU+LjwvbGk+CgoJPGxpPlRoZSA8Y29kZT5vd25lckluZm88L2NvZGU+IDxjb2RlPkdyb3VwPC9jb2RlPiwgYXMgYSBzdWJjbGFzcwoJb2YgPGNvZGU+Q29tcG9zaXRlPC9jb2RlPiwgaGFzIGl0cyBvd24gPGNvZGU+R3JpZExheW91dDwvY29kZT4gd2l0aCAyCgljb2x1bW5zIGFuZCAyIHJvd3MuPC9saT4KCgk8bGk+VGhlIDxjb2RlPm93bmVyTmFtZTwvY29kZT4gYW5kIDxjb2RlPm93bmVyUGhvbmU8L2NvZGU+IDxjb2RlPlRleHRzPC9jb2RlPgoJZ3JldyB3aWRlciBiZWNhdXNlIHRoZSA8Y29kZT5Hcm91cDwvY29kZT4gZ3JldyB3aWRlciwgYW5kIHRoZXkgYXJlCglmaWxsaW5nIGFuZCBncmFiYmluZyBob3Jpem9udGFsbHkgaW4gdGhlIDxjb2RlPkdyb3VwPC9jb2RlPidzIDxjb2RlPkdyaWRMYXlvdXQ8L2NvZGU+LjwvbGk+CgoJPGxpPlRoZSA8Y29kZT5icm93c2U8L2NvZGU+IGFuZCA8Y29kZT5kZWxldGU8L2NvZGU+IDxjb2RlPkJ1dHRvbnM8L2NvZGU+CglhcmUgaW5kZW50ZWQgc2xpZ2h0bHksIGFuZCBiZWNhdXNlIHRoZXkgYm90aCBmaWxsIGhvcml6b250YWxseSwgdGhleQoJYXJlIHRoZSBzYW1lIHdpZHRoLjwvbGk+CgoJPGxpPlRoZSA8Y29kZT5kZWxldGU8L2NvZGU+IDxjb2RlPkJ1dHRvbjwvY29kZT4gaXMgdmVydGljYWxseQoJYWxpZ25lZCBhdCB0aGUgdG9wIG9mIGl0cyByb3cuPC9saT4KCgk8bGk+VGhlICZxdW90O0NhdGVnb3JpZXMmcXVvdDsgPGNvZGU+TGFiZWw8L2NvZGU+IGlzIGNlbnRlcmVkIG92ZXIKCXRoZSA8Y29kZT5jYXRlZ29yaWVzPC9jb2RlPiA8Y29kZT5MaXN0PC9jb2RlPi4KCTwvcD4KCTxsaT5UaGUgPGNvZGU+ZW50ZXI8L2NvZGU+IDxjb2RlPkJ1dHRvbjwvY29kZT4gaXMgaG9yaXpvbnRhbGx5CglhbGlnbmVkIHRvIHRoZSByaWdodCBvZiB0aGUgMyBjb2x1bW5zIGl0IHNwYW5zLjwvbGk+CgoJPGxpPlRoZSA8Y29kZT5kb2dQaG90bzwvY29kZT4gPGNvZGU+Q2FudmFzPC9jb2RlPiB3YXMgY3JlYXRlZCB3aXRoCgl3aWR0aCBhbmQgaGVpZ2h0IGhpbnRzIGJlY2F1c2Ugd2Ugd2FudCB0aGUgPGNvZGU+SW1hZ2U8L2NvZGU+IHRvIGJlIDgwCglwaXhlbHMgeCA4MCBwaXhlbHMsIGlmIHBvc3NpYmxlLjwvbGk+CgoJPGxpPlRoZSA8Y29kZT5jYXRlZ29yaWVzPC9jb2RlPiA8Y29kZT5MaXN0PC9jb2RlPiB3YXMgY3JlYXRlZCB3aXRoCglhIGhlaWdodCBoaW50IHRoYXQgd2FzIGJhc2VkIG9uIHRoZSA8Y29kZT5MaXN0PC9jb2RlPidzIGZvbnQgdGltZXMgMTIsCgliZWNhdXNlIHdlIHdhbnQgdHJ5IHRvIGdldCB0aGUgPGNvZGU+TGlzdDwvY29kZT4gdG8gc2hvdyAxMiBpdGVtcwoJaW5pdGlhbGx5LjwvbGk+CjwvdWw+Cgo8aDI+Rm9ybUxheW91dDwvaDI+Cgo8cD48Y29kZT5Gb3JtTGF5b3V0PC9jb2RlPiB3b3JrcyBieSBjcmVhdGluZyA8Y29kZT5Gb3JtQXR0YWNobWVudDwvY29kZT5zCmZvciBlYWNoIHNpZGUgb2YgdGhlIHdpZGdldCwgYW5kIHN0b3JpbmcgdGhlbSBpbiB0aGUgbGF5b3V0IGRhdGEuIEFuCmF0dGFjaG1lbnQgJ2F0dGFjaGVzJyBhIHNwZWNpZmljIHNpZGUgb2YgdGhlIHdpZGdldCBlaXRoZXIgdG8gYSBwb3NpdGlvbgppbiB0aGUgcGFyZW50IDxjb2RlPkNvbXBvc2l0ZTwvY29kZT4gb3IgdG8gYW5vdGhlciB3aWRnZXQgd2l0aGluIHRoZQpsYXlvdXQuIFRoaXMgcHJvdmlkZXMgdHJlbWVuZG91cyBmbGV4aWJpbGl0eSB3aGVuIGxheWluZyBvdXQsIGFzIGl0CmFsbG93cyB5b3UgdG8gc3BlY2lmeSB0aGUgcGxhY2VtZW50IG9mIGluZGl2aWR1YWwgd2lkZ2V0cyB3aXRoaW4gdGhlCmxheW91dC48L3A+Cgo8aDM+Rm9ybUxheW91dCBDb25maWd1cmF0aW9uIEZpZWxkczwvaDM+Cgo8cD5UaGUgPGNvZGU+bWFyZ2luV2lkdGg8L2NvZGU+LCBhbmQgPGNvZGU+TWFyZ2luSGVpZ2h0PC9jb2RlPgpmaWVsZHMgaW4gPGNvZGU+Rm9ybUxheW91dDwvY29kZT4gYXJlIHNpbWlsYXIgdG8gdGhvc2UgaW4gPGNvZGU+R3JpZExheW91dDwvY29kZT4uCkxlZnQgYW5kIHJpZ2h0IG1hcmdpbnMgYXJlIGRlZmluZWQgYnkgPGNvZGU+bWFyZ2luV2lkdGg8L2NvZGU+LCBhbmQgdG9wCmFuZCBib3R0b20gbWFyZ2lucyBhcmUgZGVmaW5lZCBieSA8Y29kZT5tYXJnaW5IZWlnaHQ8L2NvZGU+LiBNYXJnaW5zIGNhbgphbHNvIGJlIGRlZmluZWQgb24gYSBwZXItd2lkZ2V0IGJhc2lzIGluIHRoZSBhdHRhY2htZW50cy4gPGNvZGU+Rm9ybUxheW91dDwvY29kZT4KbWFyZ2lucyBhcmUgemVybyBieSBkZWZhdWx0LjwvcD4KCjxwPlRvIHNldCB0aGUgbWFyZ2lucywgd2UgY3JlYXRlIGEgPGNvZGU+Rm9ybUxheW91dDwvY29kZT4sIGFuZCBzZXQKdGhlIG1hcmdpbiBmaWVsZHMuIFRoZSBmb2xsb3dpbmcgY29kZSB3aWxsIHNldCBhIG1hcmdpbiBvZiBmaXZlIHBpeGVscwphcm91bmQgYWxsIGZvdXIgc2lkZXMgb2YgdGhlIHBhcmVudCA8Y29kZT5Db21wb3NpdGU8L2NvZGU+OjwvcD4KCjxwcmU+RGlzcGxheSBkaXNwbGF5ID0gbmV3IERpc3BsYXkgKCk7ClNoZWxsIHNoZWxsID0gbmV3IFNoZWxsIChkaXNwbGF5KTsKRm9ybUxheW91dCBsYXlvdXQ9IG5ldyBGb3JtTGF5b3V0ICgpOwpsYXlvdXQubWFyZ2luSGVpZ2h0ID0gNTsKbGF5b3V0Lm1hcmdpbldpZHRoID0gNTsKc2hlbGwuc2V0TGF5b3V0KGxheW91dCk7PC9wcmU+Cgo8aDM+Rm9ybURhdGEgT2JqZWN0IEZpZWxkczwvaDM+Cgo8cD48Y29kZT5Gb3JtRGF0YTwvY29kZT4gb2JqZWN0cyBzcGVjaWZ5IGhvdyBlYWNoIHdpZGdldCBpbiBhIDxjb2RlPkZvcm1MYXlvdXQ8L2NvZGU+CndpbGwgYmUgbGFpZCBvdXQuIEVhY2ggPGNvZGU+Rm9ybURhdGE8L2NvZGU+IG9iamVjdCBkZWZpbmVzIHRoZQphdHRhY2htZW50cyBmb3IgYWxsIGZvdXIgc2lkZXMgb2YgdGhlIHdpZGdldC4gVGhlc2UgYXR0YWNobWVudHMgdGVsbAp3aGVyZSB0byBwb3NpdGlvbiBlYWNoIHNpZGUgb2YgdGhlIHdpZGdldC4gVG8gc2V0IGEgd2lkZ2V0J3MgPGNvZGU+Rm9ybURhdGE8L2NvZGU+Cm9iamVjdCwgeW91IHVzZSB0aGUgPGNvZGU+c2V0TGF5b3V0RGF0YShPYmplY3QpPC9jb2RlPiBtZXRob2QsIGZvciBleGFtcGxlOjwvcD4KCjxwcmU+QnV0dG9uIGJ1dHRvbjEgPSBuZXcgQnV0dG9uKHNoZWxsLCBTV1QuUFVTSCk7CmJ1dHRvbjEuc2V0VGV4dCgmcXVvdDtCMSZxdW90Oyk7CmJ1dHRvbjEuc2V0TGF5b3V0RGF0YShuZXcgRm9ybURhdGEoKSk7PC9wcmU+Cgo8cD5UaGlzIGNvZGUgY3JlYXRlcyBhIDxjb2RlPkZvcm1EYXRhPC9jb2RlPiBvYmplY3Qgd2l0aCBubwphdHRhY2htZW50cy4gSW4gdGhpcyBjYXNlLCBkZWZhdWx0IGF0dGFjaG1lbnRzIGFyZSBkZWZpbmVkLCB3aGljaApkZWZlYXRzIHRoZSB3aG9sZSBwdXJwb3NlIGFuZCB1dGlsaXR5IG9mIDxjb2RlPkZvcm1MYXlvdXQ8L2NvZGU+LiBUaGUKZGVmYXVsdCBhdHRhY2htZW50cyBhdHRhY2ggdGhlIHdpZGdldCB0byB0aGUgdG9wIGFuZCBsZWZ0IGVkZ2VzIG9mIHRoZQpwYXJlbnQgPGNvZGU+Q29tcG9zaXRlPC9jb2RlPi4gSWYgZXZlcnkgd2lkZ2V0IGluIGEgPGNvZGU+Rm9ybUxheW91dDwvY29kZT4KdXNlZCB0aGUgZGVmYXVsdCBhdHRhY2htZW50cywgdGhleSB3b3VsZCBhbGwgYmUgbGFpZCBvdXQgb25lIG9uIHRvcCBvZgphbm90aGVyIGluIHRoZSB0b3AgbGVmdCBjb3JuZXIgb2YgdGhlIHBhcmVudCA8Y29kZT5Db21wb3NpdGU8L2NvZGU+LjwvcD4KCjxwPlRoZSA8Y29kZT5sZWZ0PC9jb2RlPiwgPGNvZGU+cmlnaHQ8L2NvZGU+LCA8Y29kZT50b3A8L2NvZGU+LCBhbmQKPGNvZGU+Ym90dG9tPC9jb2RlPiBmaWVsZHMgb2YgPGNvZGU+Rm9ybURhdGE8L2NvZGU+IHNwZWNpZnkgdGhlIDxjb2RlPkZvcm1BdHRhY2htZW50PC9jb2RlPgpvYmplY3RzIHRoYXQgYXJlIGFzc29jaWF0ZWQgd2l0aCB0aGUgbGVmdCwgcmlnaHQsIHRvcCBhbmQgYm90dG9tIHNpZGVzCm9mIHRoZSB3aWRnZXQsIHJlc3BlY3RpdmVseS4gVGhlc2UgZmllbGRzIGFyZSBzZXQgaW4gdGhlIGZvbGxvd2luZwpleGFtcGxlOjwvcD4KCjxwcmU+Rm9ybURhdGEgZm9ybURhdGEgPSBuZXcgRm9ybURhdGEoKTsKZm9ybURhdGEudG9wID0gbmV3IEZvcm1BdHRhY2htZW50KDAsNjApOwpmb3JtRGF0YS5ib3R0b20gPSBuZXcgRm9ybUF0dGFjaG1lbnQoMTAwLC01KTsKZm9ybURhdGEubGVmdCA9IG5ldyBGb3JtQXR0YWNobWVudCgyMCwwKTsKZm9ybURhdGEucmlnaHQgPSBuZXcgRm9ybUF0dGFjaG1lbnQoMTAwLC0zKTsKYnV0dG9uMS5zZXRMYXlvdXREYXRhKGZvcm1EYXRhKTs8L3ByZT4gPGltZwoJc3JjPSJpbWFnZXMvRm9ybUxheW91dFNhbXBsZTAxLmpwZyIgLz4KCjxwPkEgPGNvZGU+Rm9ybUF0dGFjaG1lbnQ8L2NvZGU+IG9iamVjdCBkZWZpbmVzIHRoZSBhdHRhY2htZW50IG9mIGEKc3BlY2lmaWMgc2lkZSBvZiBhIHdpZGdldC4gVGhlcmUgYXJlIG1hbnkgd2F5cyB0aGF0IGEgc2lkZSBjYW4gYmUKYXR0YWNoZWQ6IHRvIGEgcG9zaXRpb24gaW4gdGhlIHBhcmVudCA8Y29kZT5Db21wb3NpdGU8L2NvZGU+LCB0byBhbiBlZGdlCm9mIHRoZSA8Y29kZT5Db21wb3NpdGU8L2NvZGU+LCB0byB0aGUgYWRqYWNlbnQgc2lkZSBvZiBhbm90aGVyIHdpZGdldCwKdG8gdGhlIG9wcG9zaXRlIHNpZGUgb2YgYW5vdGhlciB3aWRnZXQsIG9yIGNlbnRlcmVkIG9uIGFub3RoZXIgd2lkZ2V0LgpBdHRhY2hpbmcgdG8gYSBwb3NpdGlvbiBwbGFjZXMgdGhlIHNpZGUgb2YgdGhlIHdpZGdldCBzbyB0aGF0IGl0IGlzCmFsd2F5cyBhdCBhIHBlcmNlbnRhZ2Ugb2YgdGhlIDxjb2RlPkNvbXBvc2l0ZTwvY29kZT4uIFRvIGF0dGFjaCB0byBhbgplZGdlIG9mIHRoZSA8Y29kZT5Db21wb3NpdGU8L2NvZGU+LCB0aGUgcGVyY2VudGFnZSBpcyBlaXRoZXIgMCUgb3IgMTAwJS4KQXR0YWNoaW5nIHRvIHRoZSBhZGphY2VudCBzaWRlIG9mIGFub3RoZXIgd2lkZ2V0IGVuc3VyZXMgdGhhdCB0aGUKc3BlY2lmaWVkIHNpZGUgb2YgdGhlIHdpZGdldCBpcyBhbHdheXMgbmV4dCB0byB0aGUgY2xvc2VzdCBzaWRlIG9mIHRoZQpvdGhlciB3aWRnZXQuIEF0dGFjaGluZyB0byB0aGUgb3Bwb3NpdGUgc2lkZSBvZiBhbm90aGVyIHdpZGdldCBlbnN1cmVzCnRoYXQgdGhlIHNwZWNpZmljIHNpZGUgb2YgdGhlIHdpZGdldCBpcyBhbGlnbmVkIHdpdGggdGhlIGZ1cnRoZXN0IHNpZGUKb2YgdGhlIG90aGVyIHdpZGdldC4gRmluYWxseSwgYXR0YWNoaW5nIHRvIHRoZSBjZW50ZXIgb2YgYW5vdGhlciB3aWRnZXQKY2VudGVycyB0aGUgd2lkZ2V0IG9uIHRoZSBvdGhlciB3aWRnZXQuIEFueSBvZiB0aGVzZSB3YXlzIGNhbiBiZSBkb25lCndpdGggb3Igd2l0aG91dCBhbiBvZmZzZXQuPC9wPgoKPHA+VGhlIDxjb2RlPndpZHRoPC9jb2RlPiBhbmQgPGNvZGU+aGVpZ2h0PC9jb2RlPiBmaWVsZHMgb2YgPGNvZGU+Rm9ybURhdGE8L2NvZGU+CnNwZWNpZnkgdGhlIHJlcXVlc3RlZCB3aWR0aCBhbmQgdGhlIGhlaWdodCBvZiB0aGUgd2lkZ2V0LiBJZiBhIHJlcXVlc3RlZAp3aWR0aCBvciBoZWlnaHQgY29uZmxpY3RzIHdpdGggY29uc3RyYWludHMgc2V0IGJ5IHRoZSBhdHRhY2htZW50cywgdGhlbgp0aGF0IHdpZHRoIG9yIGhlaWdodCB3aWxsIG5vdCBiZSBob25vcmVkLiBBbHRob3VnaCBzZXR0aW5nIGF0dGFjaG1lbnRzIGNhbgphbHNvIGRldGVybWluZSB3aWR0aCBhbmQgaGVpZ2h0LCB0aGVyZSBhcmUgc29tZSBjYXNlcyB3aGVuIHlvdSBkbyBub3QKd2FudCB0byBkZWZpbmUgYXR0YWNobWVudHMgZm9yIGFsbCBzaWRlcyBvZiB0aGUgd2lkZ2V0LiBJbiB0aGlzIGNhc2UsIGl0Cm1heSBiZSB1c2VmdWwgdG8gc2V0IHRoZSB3aWR0aCBhbmQgaGVpZ2h0IG9mIHRoZSB3aWRnZXQgYXMgZm9sbG93czo8L3A+Cgo8cHJlPkZvcm1EYXRhIGZvcm1EYXRhID0gbmV3IEZvcm1EYXRhKDIwLDMwKTsKZm9ybURhdGEudG9wID0gbmV3IEZvcm1BdHRhY2htZW50KDAsNjApOwpmb3JtRGF0YS5sZWZ0ID0gbmV3IEZvcm1BdHRhY2htZW50KDIwLDApOwpidXR0b24xLnNldExheW91dERhdGEoZm9ybURhdGEpOzwvcHJlPiAKCjxwPklmIHlvdSB3aXNoIHRvIHNldCBvbmx5IHRoZSB3aWR0aCBvciB0aGUgaGVpZ2h0LCB5b3UgY2FuIGRpcmVjdGx5CnNldCB0aGUgd2lkdGggb3IgaGVpZ2h0IGZpZWxkIGluIHRoZSA8Y29kZT5Gb3JtRGF0YTwvY29kZT4gb2JqZWN0OjwvcD4KCjxwcmU+Rm9ybURhdGEgZm9ybURhdGEgPSBuZXcgRm9ybURhdGEoKTsKZm9ybURhdGEud2lkdGggPSAzMDsKZm9ybURhdGEudG9wID0gbmV3IEZvcm1BdHRhY2htZW50KDAsNjApOw0KZm9ybURhdGEuYm90dG9tID0gbmV3IEZvcm1BdHRhY2htZW50KDEwMCwtNSk7CmZvcm1EYXRhLmxlZnQgPSBuZXcgRm9ybUF0dGFjaG1lbnQoMjAsMCk7CmJ1dHRvbjEuc2V0TGF5b3V0RGF0YShmb3JtRGF0YSk7PC9wcmU+IAoKPHA+Tm90ZSB0aGF0IGlmIGEgYnV0dG9uIGlzIGF0dGFjaGVkIHRvIHRoZSBwYXJlbnQgPGNvZGU+Q29tcG9zaXRlPC9jb2RlPgpvbiBib3RoIHNpZGVzLCB3aGVuIHRoZSA8Y29kZT5Db21wb3NpdGU8L2NvZGU+IGlzIHJlc2l6ZWQsIHRoZSBidXR0b24Kd2lsbCBncm93IG9yIHNocmluayBhbG9uZyB3aXRoIGl0LjwvcD4KCjxoMz5Gb3JtQXR0YWNobWVudCBPYmplY3RzPC9oMz4KCjxwPkEgPGNvZGU+Rm9ybUF0dGFjaG1lbnQ8L2NvZGU+IGlzIGFuIG9iamVjdCB0aGF0IGRlZmluZXMgdGhlCmF0dGFjaG1lbnQgZm9yIGEgc3BlY2lmaWMgc2lkZSBvZiBhIHdpZGdldC4gSXQgaXMgbm90IGFsd2F5cyBuZWNlc3NhcnkKdG8gc2V0IGFuIGF0dGFjaG1lbnQgZm9yIGFsbCBmb3VyIHNpZGVzIG9mIGEgd2lkZ2V0LiBPZnRlbiwgc3BlY2lmeWluZwpvbmUgb3IgbW9yZSBzaWRlcyBvZiBhIHdpZGdldCBjYW4gZnVsbHkgc3BlY2lmeSBpdHMgcGxhY2VtZW50IGluIHRoZQpsYXlvdXQuIEluIG9yZGVyIHRvIHByb3Blcmx5IHBsYWNlIHlvdXIgd2lkZ2V0cywgeW91IHNob3VsZCBkZWZpbmUgYW4KYXR0YWNobWVudCBmb3IgYXQgbGVhc3Qgb25lIG9mIDxjb2RlPmxlZnQ8L2NvZGU+IG9yIDxjb2RlPnJpZ2h0PC9jb2RlPgppbiB0aGUgPGNvZGU+Rm9ybURhdGE8L2NvZGU+LCBhbmQgYXQgbGVhc3Qgb25lIG9mIDxjb2RlPnRvcDwvY29kZT4gb3IgPGNvZGU+Ym90dG9tPC9jb2RlPi4KSWYgeW91IG9ubHkgd2lzaCB0byBhdHRhY2ggdGhlIGxlZnQgc2lkZSBvZiBhIHdpZGdldCBhbmQgbm90IHRoZSByaWdodCwKdGhlbiB0aGUgd2lkZ2V0IHdpbGwgYmUgcG9zaXRpb25lZCBiYXNlZCBvbiBpdHMgbGVmdCBzaWRlLCBhbmQgdGhlCndpZGdldCB3aWxsIHRha2UgaXRzIG5hdHVyYWwgc2l6ZSAob3IgaXRzIHJlcXVlc3RlZCBzaXplLCBpZiBvbmUgd2FzIHNldApmb3IgaXQpLiBJZiB5b3UgZG8gbm90IGF0dGFjaCB0aGUgbGVmdCBvciB0aGUgcmlnaHQsIGRlZmF1bHQgcG9zaXRpb25pbmcKd2lsbCBhdHRhY2ggeW91ciB3aWRnZXQgdG8gdGhlIGxlZnQgc2lkZSBvZiB0aGUgZm9ybS4gVGhlIHNhbWUgbG9naWMKYXBwbGllcyBmb3IgdGhlIHRvcCBhbmQgYm90dG9tIHNpZGVzLjwvcD4KCjxoMz5BdHRhY2hpbmcgdG8gYSBQb3NpdGlvbjwvaDM+CjxwPlRoZXJlIGFyZSBtYW55IHR5cGVzIG9mIGF0dGFjaG1lbnQuIFRoZSBmaXJzdCBpcyB0byBhdHRhY2ggdGhlCndpZGdldCB0byBhIHBvc2l0aW9uIGluIHRoZSBwYXJlbnQgPGNvZGU+Q29tcG9zaXRlPC9jb2RlPi4gVGhpcyBjYW4gYmUKZG9uZSBieSBkZWZpbmluZyBhIHBlcmNlbnRhZ2UgdmFsdWUgb3V0IG9mIDEwMCwgZm9yIGV4YW1wbGU6PC9wPgoKPHByZT5Gb3JtRGF0YSBmb3JtRGF0YSA9IG5ldyBGb3JtRGF0YSgpOwpmb3JtRGF0YS50b3AgPSBuZXcgRm9ybUF0dGFjaG1lbnQoNTAsMCk7CmJ1dHRvbjEuc2V0TGF5b3V0RGF0YShmb3JtRGF0YSk7PC9wcmU+IDxpbWcKCXNyYz0iaW1hZ2VzL0Zvcm1MYXlvdXRTYW1wbGVQb3NpdGlvbjUwLmpwZyIgLz4KCjxwPlRoaXMgc2V0cyB0aGUgdG9wIG9mIHRoZSA8Y29kZT5CdXR0b248L2NvZGU+IHRvIGEgcG9zaXRpb24gdGhhdApyZXByZXNlbnRzIDUwJSBvZiB0aGUgaGVpZ2h0IG9mIHRoZSBwYXJlbnQgPGNvZGU+Q29tcG9zaXRlPC9jb2RlPiAoYSA8Y29kZT5TaGVsbDwvY29kZT4pLAp3aXRoIGFuIG9mZnNldCBvZiAwLiBXaGVuIHRoZSBzaGVsbCBpcyByZXNpemVkLCB0aGUgdG9wIHNpZGUgb2YgdGhlIDxjb2RlPkJ1dHRvbjwvY29kZT4Kd2lsbCBzdGlsbCBiZSBhdCA1MCUsIGxpa2Ugc286PC9wPgoKPGltZyBzcmM9ImltYWdlcy9Gb3JtTGF5b3V0U2FtcGxlUG9zaXRpb241MFJlc2l6ZWQuanBnIiAvPgoKPHA+SWYgd2UgY2hvc2UgdG8gc2V0IGFuIG9mZnNldCB2YWx1ZSwgdGhlIHRvcCBzaWRlIG9mIHRoZSA8Y29kZT5CdXR0b248L2NvZGU+CndvdWxkIGhhdmUgYmVlbiBzZXQgdG8gNTAlIG9mIHRoZSA8Y29kZT5Db21wb3NpdGU8L2NvZGU+IHBsdXMgb3IgbWludXMKdGhlIG51bWJlciBvZiBwaXhlbHMgc2V0IGZvciB0aGUgb2Zmc2V0LjwvcD4KCjxwPldlIGNhbiBhbHNvIGRlZmluZSB0aGUgcG9zaXRpb24gb2YgdGhlIGJ1dHRvbiB1c2luZyBhbiBhcmJpdHJhcnkgc2NhbGUsIGZvciBleGFtcGxlOjwvcD4KCjxwcmU+Rm9ybURhdGEgZm9ybURhdGEgPSBuZXcgRm9ybURhdGEoKTsKZm9ybURhdGEudG9wID0gbmV3IEZvcm1BdHRhY2htZW50KDMwLDcwLDEwKTsKYnV0dG9uMS5zZXRMYXlvdXREYXRhKGZvcm1EYXRhKTs8L3ByZT4KCjxwPklmIHRoZSBoZWlnaHQgb2YgdGhlIDxjb2RlPkNvbXBvc2l0ZTwvY29kZT4gaXMgZGVmaW5lZCBhcyBiZWluZwo3MCB1bml0cywgdGhpcyBzZXRzIHRoZSB0b3Agb2YgdGhlIDxjb2RlPkJ1dHRvbjwvY29kZT4gdG8gYSBwb3NpdGlvbgpyZXByZXNlbnRpbmcgMzAgdW5pdHMgZG93biBmcm9tIHRoZSB0b3Agb2YgdGhlIDxjb2RlPkNvbXBvc2l0ZTwvY29kZT4sCnBsdXMgMTAgcGl4ZWxzIChpLmUuIDMvN3RocyBvZiB0aGUgaGVpZ2h0IG9mIHRoZSBjb21wb3NpdGUgcGx1cyAxMCBwaXhlbHMpLjwvcD4KCjxwPlRvIGF0dGFjaCBhIHNpZGUgb2YgYSB3aWRnZXQgdG8gYW4gZWRnZSBvZgp0aGUgcGFyZW50IDxjb2RlPkNvbXBvc2l0ZTwvY29kZT4sIHNldCB0aGUgcG9zaXRpb24gdG8gZWl0aGVyIDAlIG9yIDEwMCUuIFRoZSAwCnBvc2l0aW9uIGlzIGRlZmluZWQgYXMgdGhlIHRvcCBvZiB0aGUgPGNvZGU+Q29tcG9zaXRlPC9jb2RlPiB3aGVuIGdvaW5nCnZlcnRpY2FsbHksIGFuZCB0aGUgbGVmdCB3aGVuIGdvaW5nIGhvcml6b250YWxseS4gVGhlIHJpZ2h0IGFuZCBib3R0b20KZWRnZXMgb2YgdGhlIDxjb2RlPkNvbXBvc2l0ZTwvY29kZT4gYXJlIGRlZmluZWQgYXMgdGhlIDEwMCBwb3NpdGlvbi4KVGhlcmVmb3JlLCBpZiB3ZSB3YW50IHRvIGF0dGFjaCBhIHdpZGdldCB0byB0aGUgcmlnaHQgZWRnZSBvZiB0aGUgPGNvZGU+Q29tcG9zaXRlPC9jb2RlPiwKd2Ugc2ltcGx5IGhhdmUgdG8gY3JlYXRlIGFuIGF0dGFjaG1lbnQgdGhhdCBzZXRzIHRoZSBwb3NpdGlvbiB0byAxMDA6PC9wPgoKPHByZT5Gb3JtRGF0YSBmb3JtRGF0YSA9IG5ldyBGb3JtRGF0YSgpOwpmb3JtRGF0YS5yaWdodCA9IG5ldyBGb3JtQXR0YWNobWVudCgxMDAsLTUpOwpidXR0b24xLnNldExheW91dERhdGEoZm9ybURhdGEpOzwvcHJlPiA8aW1nCglzcmM9ImltYWdlcy9Gb3JtTGF5b3V0U2FtcGxlUGFyZW50MTAwLmpwZyIgLz4KCjxwPlRoaXMgYXR0YWNoZXMgdGhlIHJpZ2h0IHNpZGUgb2YgdGhlIDxjb2RlPkJ1dHRvbjwvY29kZT4gdG8gdGhlCnJpZ2h0IGVkZ2Ugb2YgdGhlIHBhcmVudCAoYSA8Y29kZT5TaGVsbDwvY29kZT4pLCB3aXRoIGFuIG9mZnNldCBvZiBmaXZlCnBpeGVscy4gTm90ZSB0aGF0IHRoZSBvZmZzZXRzIGdvIGluIG9uZSBkaXJlY3Rpb24gb25seS4gSWYgeW91IHdhbnQgYQp3aWRnZXQgb2Zmc2V0IGRvd24gb3IgdG8gdGhlIHJpZ2h0LCB0aGUgb2Zmc2V0IHNob3VsZCBiZSBwb3NpdGl2ZS4gRm9yCm9mZnNldHMgdGhhdCBzaGlmdCB0aGUgd2lkZ2V0IHVwIG9yIHRvIHRoZSBsZWZ0LCB0aGUgb2Zmc2V0IHNob3VsZCBiZQpuZWdhdGl2ZS4gV2hlbiB0aGUgPGNvZGU+U2hlbGw8L2NvZGU+IGlzIHJlc2l6ZWQsIHRoZSA8Y29kZT5CdXR0b248L2NvZGU+CndpbGwgYWx3YXlzIGJlIGZpdmUgcGl4ZWxzIGF3YXkgZnJvbSB0aGUgcmlnaHQgZWRnZTo8L3A+Cgo8aW1nIHNyYz0iaW1hZ2VzL0Zvcm1MYXlvdXRTYW1wbGVQYXJlbnQxMDBSZXNpemVkLmpwZyIgLz4KCjxoMz5BdHRhY2hpbmcgdG8gQW5vdGhlciBXaWRnZXQ8L2gzPgo8cD5UaGUgdGhpcmQgdHlwZSBvZiBhdHRhY2htZW50IGlzIHRvIGF0dGFjaCB0aGUgc2lkZSBvZiB0aGUgd2lkZ2V0CnRvIGFub3RoZXIgY29udHJvbCB3aXRoaW4gdGhlIHBhcmVudCA8Y29kZT5Db21wb3NpdGU8L2NvZGU+LiBUaGUgc2lkZQpjYW4gYmUgYXR0YWNoZWQgdG8gdGhlIGFkamFjZW50IHNpZGUgb2YgdGhlIG90aGVyIGNvbnRyb2wgKHRoZSBkZWZhdWx0KSwKdG8gdGhlIG9wcG9zaXRlIHNpZGUgb2YgdGhlIG90aGVyIGNvbnRyb2wsIG9yIHRoZSB3aWRnZXQgY2FuIGJlIGNlbnRlcmVkCm9uIHRoZSBvdGhlciBjb250cm9sLCBhbGwgd2l0aCBvciB3aXRob3V0IGFuZCBvZmZzZXQuPC9wPgoKPHA+VGhlIG1vc3QgY29tbW9uIHdheSB0byBhdHRhY2ggdG8gYW5vdGhlciBjb250cm9sIGlzIHRvIGF0dGFjaCB0bwppdHMgYWRqYWNlbnQgc2lkZS4gRm9yIGV4YW1wbGUsIHRoZSBmb2xsb3dpbmcgY29kZTo8L3A+Cgo8cHJlPkZvcm1EYXRhIGZvcm1EYXRhID0gbmV3IEZvcm1EYXRhKCk7CmZvcm1EYXRhLnRvcCA9IG5ldyBGb3JtQXR0YWNobWVudCgyMCwwKTsKYnV0dG9uMS5zZXRMYXlvdXREYXRhKGZvcm1EYXRhKTsKCkZvcm1EYXRhIGZvcm1EYXRhMiA9IG5ldyBGb3JtRGF0YSgpOwpmb3JtRGF0YTIudG9wID0gbmV3IEZvcm1BdHRhY2htZW50KGJ1dHRvbjEsMTApOwpidXR0b24yLnNldExheW91dERhdGEoZm9ybURhdGEyKTs8L3ByZT4gPGltZwoJc3JjPSJpbWFnZXMvRm9ybUxheW91dFNhbXBsZUF0dGFjaFdpZGdldDAxLmpwZyIgLz4KCjxwPlRoaXMgZXhhbXBsZSBhdHRhY2hlcyB0aGUgdG9wIG9mIGJ1dHRvbjIgdG8gdGhlIGJvdHRvbSBvZgpidXR0b24xLiBOb3RlIHRoYXQgd2hlbiB0aGUgd2luZG93IGlzIHJlc2l6ZWQsIGJ1dHRvbjEgd2lsbCBtb3ZlIHNvIHRoYXQKaXRzIHRvcCBzaWRlIGlzIGFsd2F5cyBwb3NpdGlvbmVkIGF0IDIwJSBvZiB0aGUgPGNvZGU+U2hlbGw8L2NvZGU+LCBhbmQKYnV0dG9uMiB3aWxsIG1vdmUgc28gdGhhdCBpdHMgdG9wIHNpZGUgaXMgYWx3YXlzIDEwIHBpeGVscyBiZWxvdyB0aGUKYWRqYWNlbnQgKGJvdHRvbSkgc2lkZSBvZiBidXR0b24xLjwvcD4KCjxpbWcgc3JjPSJpbWFnZXMvRm9ybUxheW91dFNhbXBsZUF0dGFjaFdpZGdldDAxUmVzaXplZC5qcGciIC8+Cgo8cD5XaGlsZSB0aGUgZGVmYXVsdCBpcyB0byBhdHRhY2ggdGhlIHNpZGUgb2YgYSB3aWRnZXQgdG8gdGhlCmFkamFjZW50IHNpZGUgb2YgYSBjb250cm9sLCA8Y29kZT5Gb3JtQXR0YWNobWVudDwvY29kZT5zIGNhbiBhbHNvIGJlCmNyZWF0ZWQgdG8gYXR0YWNoIHRvIHRoZSBvcHBvc2l0ZSBzaWRlIG9mIGEgY29udHJvbC4gVGhpcyBpcyB1c2VmdWwgd2hlbgpsaW5pbmcgdXAgd2lkZ2V0cy4gSW4gdGhpcyBjYXNlLCB5b3UgY3JlYXRlIHRoZSBhdHRhY2htZW50IHRvIHRoZSBvdGhlcgpjb250cm9sIHVzaW5nIDxjb2RlPlRPUDwvY29kZT4sIDxjb2RlPkJPVFRPTTwvY29kZT4sIDxjb2RlPkxFRlQ8L2NvZGU+Cm9yIDxjb2RlPlJJR0hUPC9jb2RlPiBhbGlnbm1lbnQsIGZvciBleGFtcGxlOjwvcD4KCjxwcmU+Zm9ybURhdGEyLnRvcCA9IG5ldyBGb3JtQXR0YWNobWVudChidXR0b24xLDAsU1dULlRPUCk7PC9wcmU+Cgo8cD5JbiB0aGUgZm9sbG93aW5nIGV4YW1wbGUsIHRoZSB0b3Agc2lkZSBvZiA8Y29kZT5idXR0b24xPC9jb2RlPiBpcyBwb3NpdGlvbmVkCmF0IDIwJSBvZiB0aGUgPGNvZGU+U2hlbGw8L2NvZGU+LiA8Y29kZT5idXR0b24yPC9jb2RlPidzIHRvcCBzaWRlIGlzIGFsaWduZWQgd2l0aAo8Y29kZT5idXR0b24xPC9jb2RlPidzIHRvcCBzaWRlLCB1c2luZyA8Y29kZT5UT1A8L2NvZGU+IGFsaWdubWVudC4gVGhpcyBtZWFucyB0aGF0IHRoZSB0b3Agc2lkZSBvZgo8Y29kZT5idXR0b24yPC9jb2RlPiBpcyBhbHNvIHBvc2l0aW9uZWQgYXQgMjAlIG9mIHRoZSA8Y29kZT5TaGVsbDwvY29kZT4uIE5vdGUgdGhhdAp3aGVuIHNwZWNpZnlpbmcgdGhlIHRvcCBhdHRhY2htZW50LCBvbmx5IHRoZSB2ZXJ0aWNhbCBwbGFjZW1lbnQgb2YgdGhlCndpZGdldCBpcyBiZWluZyBkZWZpbmVkLiBJdCBpcyBzdGlsbCBuZWNlc3NhcnkgdG8gc2V0IHRoZSBsZWZ0CmF0dGFjaG1lbnQgZm9yIDxjb2RlPmJ1dHRvbjI8L2NvZGU+IHNvIHRoYXQgdGhlIDxjb2RlPkJ1dHRvbjwvY29kZT5zIGFyZSBub3Qgc3RhY2tlZApvbiB0b3Agb2YgZWFjaCBvdGhlci48L3A+Cgo8cHJlPkZvcm1EYXRhIGZvcm1EYXRhID0gbmV3IEZvcm1EYXRhKDUwLDUwKTsKZm9ybURhdGEudG9wID0gbmV3IEZvcm1BdHRhY2htZW50KDIwLDApOwpidXR0b24xLnNldExheW91dERhdGEoZm9ybURhdGEpOwoNCkZvcm1EYXRhIGZvcm1EYXRhMiA9IG5ldyBGb3JtRGF0YSgpOwpmb3JtRGF0YTIubGVmdCA9IG5ldyBGb3JtQXR0YWNobWVudChidXR0b24xLDUpOwpmb3JtRGF0YTIudG9wID0gbmV3IEZvcm1BdHRhY2htZW50KGJ1dHRvbjEsMCxTV1QuVE9QKTsgCmJ1dHRvbjIuc2V0TGF5b3V0RGF0YShmb3JtRGF0YTIpOzwvcHJlPiA8aW1nCglzcmM9ImltYWdlcy9Gb3JtTGF5b3V0U2FtcGxlQXR0YWNoV2lkZ2V0MDIuanBnIiAvPgoKPHA+VGhlIGZpbmFsIHdheSB0byBhdHRhY2ggYSB3aWRnZXQgdG8gYW5vdGhlciBjb250cm9sIGlzIHRvIGNlbnRlcgppdCBvbiB0aGUgb3RoZXIgY29udHJvbC4gVGhpcyBpcyB1c2VmdWwgd2hlbiB0aGUgd2lkZ2V0cyBhcmUgZGlmZmVyZW50CnNpemVzLiBJbiB0aGlzIGNhc2UsIHlvdSBjcmVhdGUgdGhlIGF0dGFjaG1lbnQgdG8gdGhlIG90aGVyIGNvbnRyb2wgd2l0aAo8Y29kZT5DRU5URVI8L2NvZGU+IGFsaWdubWVudCwgZm9yIGV4YW1wbGU6PC9wPgoKPHByZT5mb3JtRGF0YS50b3AgPSBuZXcgRm9ybUF0dGFjaG1lbnQoYnV0dG9uMSwwLFNXVC5DRU5URVIpOzwvcHJlPgoKPHA+VGhpcyB3aWxsIHBsYWNlIHRoZSB0b3Agb2YgdGhlIHdpZGdldCBpbiBhIHBvc2l0aW9uIHRoYXQgd2lsbAphbGxvdyB0aGUgd2lkZ2V0IHRvIGJlIGNlbnRlcmVkIG9uIHRoZSBvdGhlciBjb250cm9sLCB3aXRoIGFuIG9mZnNldCBvZgowLiBTZXR0aW5nIG9ubHkgdGhlIHRvcCwgb3IgdGhlIGJvdHRvbSwgb3IgYm90aCBhcyBhIGNlbnRlciBhdHRhY2htZW50CndpbGwgcHJvZHVjZSB0aGUgc2FtZSByZXN1bHQuIFRoZSB0b3Agc2lkZSBvZiB0aGUgd2lkZ2V0IGlzIG5vdApjZW50ZXJlZCwgYnV0IHRoZSBlbnRpcmUgd2lkZ2V0IGlzIGNlbnRlcmVkLCBzbyB0aGlzIG9ubHkgbmVlZHMgdG8gYmUKc3BlY2lmaWVkIG9uY2UuIEhlcmUgaXMgYW4gZXhhbXBsZTo8L3A+Cgo8cHJlPkZvcm1EYXRhIGZvcm1EYXRhMSA9IG5ldyBGb3JtRGF0YSAoNTAsNTApOw0KYnV0dG9uMS5zZXRMYXlvdXREYXRhKGZvcm1EYXRhMSk7CgpGb3JtRGF0YSBmb3JtRGF0YTIgPSBuZXcgRm9ybURhdGEgKCk7CmZvcm1EYXRhMi5sZWZ0ID0gbmV3IEZvcm1BdHRhY2htZW50IChidXR0b24xLDUpOwpmb3JtRGF0YTIudG9wID0gbmV3IEZvcm1BdHRhY2htZW50IChidXR0b24xLDAsU1dULkNFTlRFUik7CmJ1dHRvbjIuc2V0TGF5b3V0RGF0YShmb3JtRGF0YTIpOzwvcHJlPiA8aW1nCglzcmM9ImltYWdlcy9Gb3JtTGF5b3V0U2FtcGxlQXR0YWNoV2lkZ2V0MDMuanBnIiAvPgoKPHA+VXNpbmcgdGhlIGRpZmZlcmVudCB0eXBlcyBvZiA8Y29kZT5Gb3JtQXR0YWNobWVudDwvY29kZT4gYWxsb3dzCmxheW91dHMgdG8gYmUgZGVmaW5lZCBpbiBtYW55IGRpZmZlcmVudCB3YXlzLiA8Y29kZT5Gb3JtTGF5b3V0PC9jb2RlPgpjb3ZlcnMgY2VydGFpbiBjYXNlcyB0aGF0IGNhbm5vdCBiZSBzb2x2ZWQgdXNpbmcgPGNvZGU+RmlsbExheW91dDwvY29kZT4sCjxjb2RlPlJvd0xheW91dDwvY29kZT4gb3IgPGNvZGU+R3JpZExheW91dDwvY29kZT4sIG1ha2luZyBpdCBhIHZlcnkKdXNlZnVsIGNsYXNzIGZvciBkZWZpbmluZyBsYXlvdXRzLjwvcD4KCjxwPjxiPkltcG9ydGFudDogPC9iPkRvIDxiPm5vdDwvYj4gZGVmaW5lIGNpcmN1bGFyCmF0dGFjaG1lbnRzLiBGb3IgZXhhbXBsZSwgZG8gbm90IGF0dGFjaCB0aGUgcmlnaHQgZWRnZSBvZiBidXR0b24xCnRvIHRoZSBsZWZ0IGVkZ2Ugb2YgYnV0dG9uMiBhbmQgdGhlbiBhdHRhY2ggdGhlIGxlZnQgZWRnZSBidXR0b24yIHRvIHRoZQpyaWdodCBlZGdlIG9mIGJ1dHRvbjEuIFRoaXMgd2lsbCBvdmVyLWNvbnN0cmFpbiB0aGUgbGF5b3V0LCBjYXVzaW5nCnVuZGVmaW5lZCBiZWhhdmlvci4gVGhlIGFsZ29yaXRobSB3aWxsIHRlcm1pbmF0ZSwgYnV0IHRoZSByZXN1bHRzCmFyZSB1bmRlZmluZWQuIFRoZXJlZm9yZSwgbWFrZSBzdXJlIHRoYXQgeW91IGRvIG5vdCBvdmVyLWNvbnN0cmFpbiB5b3VyCndpZGdldHMuIE9ubHkgcHJvdmlkZSB0aGUgYXR0YWNobWVudHMgbmVjZXNzYXJ5IHRvIHByb3Blcmx5IGxheSBvdXQgdGhlCndpZGdldHMuPC9wPgoKPGgzPkEgRm9ybUxheW91dCBFeGFtcGxlPC9oMz4KCjxwPlNvIGZhciwgYWxsIHRoZSBleGFtcGxlcyB1c2luZyA8Y29kZT5Gb3JtTGF5b3V0PC9jb2RlPiBoYXZlCmludm9sdmVkIG9uZSBvciB0d28gPGNvZGU+QnV0dG9uPC9jb2RlPnMsIHRvIHNob3cgaG93IDxjb2RlPkZvcm1BdHRhY2htZW50PC9jb2RlPnMKd29yay4gTmV4dCwgd2Ugd2lsbCBkbyBhIHNpbXBsZSBleGFtcGxlIHVzaW5nIG1vcmUgPGNvZGU+QnV0dG9uPC9jb2RlPnMKdG8gc2hvdyBob3cgYSBsYXlvdXQgY2FuIGJlIGFycmFuZ2VkIHVzaW5nIHRoZSBhdHRhY2htZW50cy4gV2UnbGwgc3RhcnQKYnkgZHJhd2luZyBhIGJhc2ljIGRpYWdyYW0gb3V0bGluaW5nIHRoZSBhdHRhY2htZW50cyB0aGF0IHdlIHdpc2ggdG8KY3JlYXRlLjwvcD4KoKCgoCA8aW1nIHNyYz0iaW1hZ2VzL0Zvcm1FeGFtcGxlSGFuZERyYXduLmpwZyIgLz4gCgo8cHJlPkZvcm1EYXRhIGRhdGExID0gbmV3IEZvcm1EYXRhKCk7CmRhdGExLmxlZnQgPSBuZXcgRm9ybUF0dGFjaG1lbnQoMCw1KTsKZGF0YTEucmlnaHQgPSBuZXcgRm9ybUF0dGFjaG1lbnQoMjUsMCk7CmJ1dHRvbjEuc2V0TGF5b3V0RGF0YShkYXRhMSk7CgpGb3JtRGF0YSBkYXRhMiA9IG5ldyBGb3JtRGF0YSgpOwpkYXRhMi5sZWZ0ID0gbmV3IEZvcm1BdHRhY2htZW50KGJ1dHRvbjEsNSk7CmRhdGEyLnJpZ2h0ID0gbmV3IEZvcm1BdHRhY2htZW50KDEwMCwtNSk7CmJ1dHRvbjIuc2V0TGF5b3V0RGF0YShkYXRhMik7CgpGb3JtRGF0YSBkYXRhMyA9IG5ldyBGb3JtRGF0YSg2MCw2MCk7CmRhdGEzLnRvcCA9IG5ldyBGb3JtQXR0YWNobWVudChidXR0b24xLDUpOwpkYXRhMy5sZWZ0ID0gbmV3IEZvcm1BdHRhY2htZW50KDUwLC0zMCk7CmRhdGEzLnJpZ2h0ID0gbmV3IEZvcm1BdHRhY2htZW50KDUwLDMwKTsKYnV0dG9uMy5zZXRMYXlvdXREYXRhKGRhdGEzKTsKCkZvcm1EYXRhIGRhdGE0ID0gbmV3IEZvcm1EYXRhKCk7CmRhdGE0LnRvcCA9IG5ldyBGb3JtQXR0YWNobWVudChidXR0b24zLDUpOwpkYXRhNC5ib3R0b20gPSBuZXcgRm9ybUF0dGFjaG1lbnQoMTAwLC01KTsKZGF0YTQubGVmdCA9IG5ldyBGb3JtQXR0YWNobWVudCgyNSwwKTsKYnV0dG9uNC5zZXRMYXlvdXREYXRhKGRhdGE0KTsKCkZvcm1EYXRhIGRhdGE1ID0gbmV3IEZvcm1EYXRhKCk7CmRhdGE1LmJvdHRvbSA9IG5ldyBGb3JtQXR0YWNobWVudCgxMDAsLTUpOwpkYXRhNS5sZWZ0ID0gbmV3IEZvcm1BdHRhY2htZW50KGJ1dHRvbjQsNSk7CmJ1dHRvbjUuc2V0TGF5b3V0RGF0YShkYXRhNSk7PC9wcmU+Cgo8cD5JbiB0aGlzIGNhc2UsIHNpbmNlIG5vIHRvcCBhdHRhY2htZW50IHdhcyBkZWZpbmVkIGZvciA8Y29kZT5idXR0b24xPC9jb2RlPiBvcgo8Y29kZT5idXR0b24yPC9jb2RlPiwgdGhleSBhcmUgYXR0YWNoZWQgdG8gdGhlIHRvcCBvZiB0aGUgbGF5b3V0LiA8Y29kZT5idXR0b24zPC9jb2RlPiBpcyBjZW50cmVkCmluIHRoZSBsYXlvdXQgdXNpbmcgcGVyY2VudGFnZXMgYW5kIG9mZnNldHMgb24gdGhlIGxlZnQgYW5kIHJpZ2h0IHNpZGVzLgo8Y29kZT5idXR0b240PC9jb2RlPiBhbmQgPGNvZGU+YnV0dG9uNTwvY29kZT4gYXJlIGF0dGFjaGVkIHRvIHRoZSBib3R0b20gb2YgdGhlIGxheW91dCB3aXRoIGEgZml2ZQpwaXhlbCBvZmZzZXQuPC9wPgoKPGltZyBzcmM9ImltYWdlcy9Gb3JtTGF5b3V0U2FtcGxlNUJ1dHRvbnMwMS5qcGciIC8+Cgo8cD5XaGVuIHdlIHJlc2l6ZSwgdGhlIGF0dGFjaG1lbnRzIGJlY29tZSBtb3JlIHZpc2libGUuIDxjb2RlPmJ1dHRvbjE8L2NvZGU+IGlzCmF0dGFjaGVkIG9uIHRoZSBsZWZ0IGFuZCB0aGUgcmlnaHQgc2lkZSwgc28gd2hlbiB0aGUgd2luZG93IGlzIHJlc2l6ZWQsCml0IGdyb3dzLiBOb3RlIHRoYXQgdGhlIHJpZ2h0IHNpZGUgd2lsbCBhbHdheXMgYmUgYXQgMjUlIG9mIHRoZSB3aW5kb3cuoApUaGUgc2FtZSByZXNpemUgcmVzdWx0cyBhcHBseSBmb3IgPGNvZGU+YnV0dG9uMjwvY29kZT4sIGFzIGJvdGggc2lkZXMgYXJlIGF0dGFjaGVkLgpUaGUgbGVmdCBzaWRlIGlzIGF0dGFjaGVkIHRvIDxjb2RlPmJ1dHRvbjE8L2NvZGU+LCBzbyBpdCB3aWxsIGFsd2F5cyBiZSBhdCAyNSUgcGx1cyBmaXZlCnBpeGVscy4gPGNvZGU+YnV0dG9uMzwvY29kZT4gc3RheXMgaW4gdGhlIGNlbnRlciBvZiB0aGUgd2luZG93LCBob3Jpem9udGFsbHkuIDxjb2RlPmJ1dHRvbjQ8L2NvZGU+CmlzIGF0dGFjaGVkIGF0IHRoZSB0b3AgYW5kIHRoZSBib3R0b20sIHNvIGl0IGdyb3dzIHZlcnRpY2FsbHkgd2hlbiB0aGUKd2luZG93IGlzIHJlc2l6ZWQsIGJ1dCBpdCBpcyBvbmx5IGF0dGFjaGVkIG9uIHRoZSBsZWZ0IGFuZCBub3QgdGhlCnJpZ2h0LCBzbyBpdCBkb2VzIG5vdCBncm93IGhvcml6b250YWxseS4gPGNvZGU+YnV0dG9uNTwvY29kZT4gd2lsbCBub3QgZ3JvdyBvcgpzaHJpbmssIGJ1dCBpdCB3aWxsIGFsd2F5cyBzdGF5IGZpdmUgcGl4ZWxzIGF3YXkgZnJvbSA8Y29kZT5idXR0b240PC9jb2RlPiBvbiB0aGUgbGVmdCwKYW5kIGZpdmUgcGl4ZWxzIGF3YXkgZnJvbSB0aGUgYm90dG9tIG9mIHRoZSB3aW5kb3cuPC9wPgoKPGltZyBzcmM9ImltYWdlcy9Gb3JtTGF5b3V0U2FtcGxlNUJ1dHRvbnMwMVJlc2l6ZWQuanBnIiAvPgoKPGgzPkEgQ29tcGxleCBGb3JtTGF5b3V0IEV4YW1wbGU8L2gzPgoKPHA+VG8gaWxsdXN0cmF0ZSBob3cgPGNvZGU+Rm9ybUxheW91dDwvY29kZT4gY2FuIGJlIHVzZWQgZm9yIG1vcmUKY29tcGxpY2F0ZWQgYXJyYW5nZW1lbnRzLCB0aGUgRG9nIFNob3cgRW50cnkgZXhhbXBsZSBkb25lIHByZXZpb3VzbHkgZm9yCjxjb2RlPkdyaWRMYXlvdXQ8L2NvZGU+IGlzIHJlZG9uZSB1c2luZyA8Y29kZT5Gb3JtTGF5b3V0PC9jb2RlPi4gVGhpcwpjb2RlIHByb2R1Y2VzIGFuIGlkZW50aWNhbCBsYXlvdXQsIGJ1dCB1c2VzIGRpZmZlcmVudCBjb25jZXB0cyB0bwphY2hpZXZlIGl0LjwvcD4KCjxwcmU+aW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5TV1Q7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLlBhaW50RXZlbnQ7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLlBhaW50TGlzdGVuZXI7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLlNlbGVjdGlvbkFkYXB0ZXI7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLlNlbGVjdGlvbkV2ZW50OwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmdyYXBoaWNzLkltYWdlOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmxheW91dC5Gb3JtQXR0YWNobWVudDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5sYXlvdXQuRm9ybURhdGE7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QubGF5b3V0LkZvcm1MYXlvdXQ7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5CdXR0b247CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5DYW52YXM7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5Db21ibzsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkRpc3BsYXk7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5GaWxlRGlhbG9nOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuR3JvdXA7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5MYWJlbDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkxpc3Q7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5TaGVsbDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLlRleHQ7CgpwdWJsaWMgY2xhc3MgRG9nU2hvd1JlZ2lzdHJhdGlvbldpbmRvd1dpdGhGb3JtTGF5b3V0IHsKCUltYWdlIGRvZ0ltYWdlOwoJVGV4dCBkb2dOYW1lVGV4dDsKCUNvbWJvIGRvZ0JyZWVkQ29tYm87CglDYW52YXMgZG9nUGhvdG87CglMaXN0IGNhdGVnb3JpZXM7CglUZXh0IG5hbWVUZXh0OwoJVGV4dCBwaG9uZVRleHQ7CgoJcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nW10gYXJncykgewoJCURpc3BsYXkgZGlzcGxheSA9IG5ldyBEaXNwbGF5KCk7CgkJU2hlbGwgc2hlbGwgPSBuZXcgRG9nU2hvd1JlZ2lzdHJhdGlvbldpbmRvdygpLmNyZWF0ZVNoZWxsKGRpc3BsYXkpOwoJCXNoZWxsLm9wZW4oKTsKCQl3aGlsZSAoIXNoZWxsLmlzRGlzcG9zZWQoKSkgewoJCQlpZiAoIWRpc3BsYXkucmVhZEFuZERpc3BhdGNoKCkpCgkJCQlkaXNwbGF5LnNsZWVwKCk7CgkJfQoJfQoJCglwdWJsaWMgU2hlbGwgY3JlYXRlU2hlbGwoZmluYWwgRGlzcGxheSBkaXNwbGF5KSB7CgkJZmluYWwgU2hlbGwgc2hlbGwgPSBuZXcgU2hlbGwoZGlzcGxheSk7CgkJRm9ybUxheW91dCBsYXlvdXQgPSBuZXcgRm9ybUxheW91dCgpOwoJCWxheW91dC5tYXJnaW5XaWR0aCA9IDU7CgkJbGF5b3V0Lm1hcmdpbkhlaWdodCA9IDU7CgkJc2hlbGwuc2V0TGF5b3V0KGxheW91dCk7CgkJc2hlbGwuc2V0VGV4dCgiRG9nIFNob3cgRW50cnkiKTsKCQkKCQlHcm91cCBvd25lckluZm8gPSBuZXcgR3JvdXAoc2hlbGwsIFNXVC5OT05FKTsKCQlvd25lckluZm8uc2V0VGV4dCgiT3duZXIgSW5mbyIpOwoJCUZvcm1MYXlvdXQgb3duZXJMYXlvdXQgPSBuZXcgRm9ybUxheW91dCgpOwoJCW93bmVyTGF5b3V0Lm1hcmdpbldpZHRoID0gNTsKCQlvd25lckxheW91dC5tYXJnaW5IZWlnaHQgPSA1OwoJCW93bmVySW5mby5zZXRMYXlvdXQob3duZXJMYXlvdXQpOwoJCQoJCUxhYmVsIGRvZ05hbWUgPSBuZXcgTGFiZWwoc2hlbGwsIFNXVC5OT05FKTsKCQlkb2dOYW1lLnNldFRleHQoIkRvZydzIE5hbWU6Iik7CgkJZG9nTmFtZVRleHQgPSBuZXcgVGV4dChzaGVsbCwgU1dULlNJTkdMRSB8IFNXVC5CT1JERVIpOwoJCQoJCUxhYmVsIGRvZ0JyZWVkID0gbmV3IExhYmVsKHNoZWxsLCBTV1QuTk9ORSk7CgkJZG9nQnJlZWQuc2V0VGV4dCgiQnJlZWQ6Iik7CgkJCgkJZG9nQnJlZWRDb21ibyA9IG5ldyBDb21ibyhzaGVsbCwgU1dULk5PTkUpOwoJCWRvZ0JyZWVkQ29tYm8uc2V0SXRlbXMobmV3IFN0cmluZ1tdIHsgIkNvbGxpZSIsICJQaXRidWxsIiwgIlBvb2RsZSIsCgkJCQkiU2NvdHRpZSIsICJCbGFjayBMYWIiIH0pOwoJCQoJCUxhYmVsIHBob3RvID0gbmV3IExhYmVsKHNoZWxsLCBTV1QuTk9ORSk7CgkJcGhvdG8uc2V0VGV4dCgiUGhvdG86Iik7CgkJZG9nUGhvdG8gPSBuZXcgQ2FudmFzKHNoZWxsLCBTV1QuQk9SREVSKTsKCQkKCQlCdXR0b24gYnJvd3NlID0gbmV3IEJ1dHRvbihzaGVsbCwgU1dULlBVU0gpOwoJCWJyb3dzZS5zZXRUZXh0KCJCcm93c2UuLi4iKTsKCQkKCQlCdXR0b24gZGVsZXRlID0gbmV3IEJ1dHRvbihzaGVsbCwgU1dULlBVU0gpOwoJCWRlbGV0ZS5zZXRUZXh0KCJEZWxldGUiKTsKCQkKCQlMYWJlbCBjYXRzID0gbmV3IExhYmVsKHNoZWxsLCBTV1QuTk9ORSk7CgkJY2F0cy5zZXRUZXh0KCJDYXRlZ29yaWVzIik7CgkJY2F0ZWdvcmllcyA9IG5ldyBMaXN0KHNoZWxsLCBTV1QuTVVMVEkgfCBTV1QuQk9SREVSIHwgU1dULlZfU0NST0xMCgkJCQl8IFNXVC5IX1NDUk9MTCk7CgkJY2F0ZWdvcmllcy5zZXRJdGVtcyhuZXcgU3RyaW5nW10geyAiQmVzdCBvZiBCcmVlZCIsICJQcmV0dGllc3QgRmVtYWxlIiwKCQkJCSJIYW5kc29tZXN0IE1hbGUiLCAiQmVzdCBEcmVzc2VkIiwgIkZsdWZmaWVzdCBFYXJzIiwKCQkJCSJNb3N0IENvbG9ycyIsICJCZXN0IFBlcmZvcm1lciIsICJMb3VkZXN0IEJhcmsiLAoJCQkJIkJlc3QgQmVoYXZlZCIsICJQcmV0dGllc3QgRXllcyIsICJNb3N0IEhhaXIiLCAiTG9uZ2VzdCBUYWlsIiwKCQkJCSJDdXRlc3QgVHJpY2siIH0pOwoJCQoJCUJ1dHRvbiBlbnRlciA9IG5ldyBCdXR0b24oc2hlbGwsIFNXVC5QVVNIKTsKCQllbnRlci5zZXRUZXh0KCJFbnRlciIpOwoJCUZvcm1EYXRhIGRhdGEgPSBuZXcgRm9ybURhdGEoKTsKCQlkYXRhLnRvcCA9IG5ldyBGb3JtQXR0YWNobWVudChkb2dOYW1lVGV4dCwgMCwgU1dULkNFTlRFUik7CgkJZG9nTmFtZS5zZXRMYXlvdXREYXRhKGRhdGEpOwoJCWRhdGEgPSBuZXcgRm9ybURhdGEoKTsKCQlkYXRhLmxlZnQgPSBuZXcgRm9ybUF0dGFjaG1lbnQoZG9nTmFtZSwgNSk7CgkJZGF0YS5yaWdodCA9IG5ldyBGb3JtQXR0YWNobWVudCgxMDAsIDApOwoJCWRvZ05hbWVUZXh0LnNldExheW91dERhdGEoZGF0YSk7CgkJCgkJZGF0YSA9IG5ldyBGb3JtRGF0YSgpOwoJCWRhdGEudG9wID0gbmV3IEZvcm1BdHRhY2htZW50KGRvZ0JyZWVkQ29tYm8sIDAsIFNXVC5DRU5URVIpOwoJCWRvZ0JyZWVkLnNldExheW91dERhdGEoZGF0YSk7CgkJZGF0YSA9IG5ldyBGb3JtRGF0YSgpOwoJCWRhdGEudG9wID0gbmV3IEZvcm1BdHRhY2htZW50KGRvZ05hbWVUZXh0LCA1KTsKCQlkYXRhLmxlZnQgPSBuZXcgRm9ybUF0dGFjaG1lbnQoZG9nTmFtZVRleHQsIDAsIFNXVC5MRUZUKTsKCQlkYXRhLnJpZ2h0ID0gbmV3IEZvcm1BdHRhY2htZW50KGNhdGVnb3JpZXMsIC01KTsKCQlkb2dCcmVlZENvbWJvLnNldExheW91dERhdGEoZGF0YSk7CgkJCgkJZGF0YSA9IG5ldyBGb3JtRGF0YSg4MCwgODApOwoJCWRhdGEudG9wID0gbmV3IEZvcm1BdHRhY2htZW50KGRvZ0JyZWVkQ29tYm8sIDUpOwoJCWRhdGEubGVmdCA9IG5ldyBGb3JtQXR0YWNobWVudChkb2dOYW1lVGV4dCwgMCwgU1dULkxFRlQpOwoJCWRhdGEucmlnaHQgPSBuZXcgRm9ybUF0dGFjaG1lbnQoY2F0ZWdvcmllcywgLTUpOwoJCWRhdGEuYm90dG9tID0gbmV3IEZvcm1BdHRhY2htZW50KG93bmVySW5mbywgLTUpOwoJCWRvZ1Bob3RvLnNldExheW91dERhdGEoZGF0YSk7CgkJZG9nUGhvdG8uYWRkUGFpbnRMaXN0ZW5lcihuZXcgUGFpbnRMaXN0ZW5lcigpIHsKCQkJcHVibGljIHZvaWQgcGFpbnRDb250cm9sKGZpbmFsIFBhaW50RXZlbnQgZXZlbnQpIHsKCQkJCWlmIChkb2dJbWFnZSAhPSBudWxsKSB7CgkJCQkJZXZlbnQuZ2MuZHJhd0ltYWdlKGRvZ0ltYWdlLCAwLCAwKTsKCQkJCX0KCQkJfQoJCX0pOwoJCWRhdGEgPSBuZXcgRm9ybURhdGEoKTsKCQlkYXRhLnRvcCA9IG5ldyBGb3JtQXR0YWNobWVudChkb2dQaG90bywgMCwgU1dULlRPUCk7CgkJcGhvdG8uc2V0TGF5b3V0RGF0YShkYXRhKTsKCQlkYXRhID0gbmV3IEZvcm1EYXRhKCk7CgkJZGF0YS50b3AgPSBuZXcgRm9ybUF0dGFjaG1lbnQocGhvdG8sIDUpOwoJCWRhdGEucmlnaHQgPSBuZXcgRm9ybUF0dGFjaG1lbnQoZG9nUGhvdG8sIC01KTsKCQlicm93c2Uuc2V0TGF5b3V0RGF0YShkYXRhKTsKCQlicm93c2UuYWRkU2VsZWN0aW9uTGlzdGVuZXIobmV3IFNlbGVjdGlvbkFkYXB0ZXIoKSB7CgkJCXB1YmxpYyB2b2lkIHdpZGdldFNlbGVjdGVkKFNlbGVjdGlvbkV2ZW50IGV2ZW50KSB7CgkJCQlTdHJpbmcgZmlsZU5hbWUgPSBuZXcgRmlsZURpYWxvZyhzaGVsbCkub3BlbigpOwoJCQkJaWYgKGZpbGVOYW1lICE9IG51bGwpIHsKCQkJCQlkb2dJbWFnZSA9IG5ldyBJbWFnZShkaXNwbGF5LCBmaWxlTmFtZSk7CgkJCQl9CgkJCX0KCQl9KTsKCQkKCQlkYXRhID0gbmV3IEZvcm1EYXRhKCk7CgkJZGF0YS5sZWZ0ID0gbmV3IEZvcm1BdHRhY2htZW50KGJyb3dzZSwgMCwgU1dULkxFRlQpOwoJCWRhdGEudG9wID0gbmV3IEZvcm1BdHRhY2htZW50KGJyb3dzZSwgNSk7CgkJZGF0YS5yaWdodCA9IG5ldyBGb3JtQXR0YWNobWVudChkb2dQaG90bywgLTUpOwoJCWRlbGV0ZS5zZXRMYXlvdXREYXRhKGRhdGEpOwoJCWRlbGV0ZS5hZGRTZWxlY3Rpb25MaXN0ZW5lcihuZXcgU2VsZWN0aW9uQWRhcHRlcigpIHsKCQkJcHVibGljIHZvaWQgd2lkZ2V0U2VsZWN0ZWQoU2VsZWN0aW9uRXZlbnQgZXZlbnQpIHsKCQkJCWlmIChkb2dJbWFnZSAhPSBudWxsKSB7CgkJCQkJZG9nSW1hZ2UuZGlzcG9zZSgpOwoJCQkJCWRvZ0ltYWdlID0gbnVsbDsKCQkJCQlkb2dQaG90by5yZWRyYXcoKTsKCQkJCX0KCQkJfQoJCX0pOwoJCQoJCWRhdGEgPSBuZXcgRm9ybURhdGEoOTAsIDE0MCk7CgkJZGF0YS50b3AgPSBuZXcgRm9ybUF0dGFjaG1lbnQoZG9nUGhvdG8sIDAsIFNXVC5UT1ApOwoJCWRhdGEucmlnaHQgPSBuZXcgRm9ybUF0dGFjaG1lbnQoMTAwLCAwKTsKCQlkYXRhLmJvdHRvbSA9IG5ldyBGb3JtQXR0YWNobWVudChlbnRlciwgLTUpOwoJCWNhdGVnb3JpZXMuc2V0TGF5b3V0RGF0YShkYXRhKTsKCQkKCQlkYXRhID0gbmV3IEZvcm1EYXRhKCk7CgkJZGF0YS5ib3R0b20gPSBuZXcgRm9ybUF0dGFjaG1lbnQoY2F0ZWdvcmllcywgLTUpOwoJCWRhdGEubGVmdCA9IG5ldyBGb3JtQXR0YWNobWVudChjYXRlZ29yaWVzLCAwLCBTV1QuQ0VOVEVSKTsKCQljYXRzLnNldExheW91dERhdGEoZGF0YSk7CgkJCgkJZGF0YSA9IG5ldyBGb3JtRGF0YSgpOwoJCWRhdGEucmlnaHQgPSBuZXcgRm9ybUF0dGFjaG1lbnQoMTAwLCAwKTsKCQlkYXRhLmJvdHRvbSA9IG5ldyBGb3JtQXR0YWNobWVudCgxMDAsIDApOwoJCWVudGVyLnNldExheW91dERhdGEoZGF0YSk7CgkJZW50ZXIuYWRkU2VsZWN0aW9uTGlzdGVuZXIobmV3IFNlbGVjdGlvbkFkYXB0ZXIoKSB7CgkJCXB1YmxpYyB2b2lkIHdpZGdldFNlbGVjdGVkKFNlbGVjdGlvbkV2ZW50IGV2ZW50KSB7CgkJCQlTeXN0ZW0ub3V0LnByaW50bG4oIlxuRG9nIE5hbWU6ICIgKyBkb2dOYW1lVGV4dC5nZXRUZXh0KCkpOwoJCQkJU3lzdGVtLm91dC5wcmludGxuKCJEb2cgQnJlZWQ6ICIgKyBkb2dCcmVlZENvbWJvLmdldFRleHQoKSk7CgkJCQlTeXN0ZW0ub3V0LnByaW50bG4oIk93bmVyIE5hbWU6ICIgKyBuYW1lVGV4dC5nZXRUZXh0KCkpOwoJCQkJU3lzdGVtLm91dC5wcmludGxuKCJPd25lciBQaG9uZTogIiArIHBob25lVGV4dC5nZXRUZXh0KCkpOwoJCQkJU3lzdGVtLm91dC5wcmludGxuKCJDYXRlZ29yaWVzOiIpOwoJCQkJU3RyaW5nIGNhdHNbXSA9IGNhdGVnb3JpZXMuZ2V0U2VsZWN0aW9uKCk7CgkJCQlmb3IgKGludCBpID0gMDsgaSA8IGNhdHMubGVuZ3RoOyBpKyspIHsKCQkJCQlTeXN0ZW0ub3V0LnByaW50bG4oIlx0IiArIGNhdHNbaV0pOwoJCQkJfQoJCQl9CgkJfSk7CgkJCgkJZGF0YSA9IG5ldyBGb3JtRGF0YSgpOwoJCWRhdGEuYm90dG9tID0gbmV3IEZvcm1BdHRhY2htZW50KGVudGVyLCAtNSk7CgkJZGF0YS5sZWZ0ID0gbmV3IEZvcm1BdHRhY2htZW50KDAsIDApOwoJCWRhdGEucmlnaHQgPSBuZXcgRm9ybUF0dGFjaG1lbnQoY2F0ZWdvcmllcywgLTUpOwoJCW93bmVySW5mby5zZXRMYXlvdXREYXRhKGRhdGEpOwoJCQoJCUxhYmVsIG5hbWUgPSBuZXcgTGFiZWwob3duZXJJbmZvLCBTV1QuTlVMTCk7CgkJbmFtZS5zZXRUZXh0KCJOYW1lOiIpOwoJCQoJCUxhYmVsIHBob25lID0gbmV3IExhYmVsKG93bmVySW5mbywgU1dULlBVU0gpOwoJCXBob25lLnNldFRleHQoIlBob25lOiIpOwoJCQoJCW5hbWVUZXh0ID0gbmV3IFRleHQob3duZXJJbmZvLCBTV1QuU0lOR0xFIHwgU1dULkJPUkRFUik7CgkJcGhvbmVUZXh0ID0gbmV3IFRleHQob3duZXJJbmZvLCBTV1QuU0lOR0xFIHwgU1dULkJPUkRFUik7CgkJCgkJZGF0YSA9IG5ldyBGb3JtRGF0YSgpOwoJCWRhdGEudG9wID0gbmV3IEZvcm1BdHRhY2htZW50KG5hbWVUZXh0LCAwLCBTV1QuQ0VOVEVSKTsKCQluYW1lLnNldExheW91dERhdGEoZGF0YSk7CgkJCgkJZGF0YSA9IG5ldyBGb3JtRGF0YSgpOwoJCWRhdGEudG9wID0gbmV3IEZvcm1BdHRhY2htZW50KHBob25lVGV4dCwgMCwgU1dULkNFTlRFUik7CgkJcGhvbmUuc2V0TGF5b3V0RGF0YShkYXRhKTsKCQkKCQlkYXRhID0gbmV3IEZvcm1EYXRhKCk7CgkJZGF0YS5sZWZ0ID0gbmV3IEZvcm1BdHRhY2htZW50KHBob25lLCA1KTsKCQlkYXRhLnJpZ2h0ID0gbmV3IEZvcm1BdHRhY2htZW50KDEwMCwgMCk7CgkJbmFtZVRleHQuc2V0TGF5b3V0RGF0YShkYXRhKTsKCQkKCQlkYXRhID0gbmV3IEZvcm1EYXRhKCk7CgkJZGF0YS5sZWZ0ID0gbmV3IEZvcm1BdHRhY2htZW50KG5hbWVUZXh0LCAwLCBTV1QuTEVGVCk7CgkJZGF0YS5yaWdodCA9IG5ldyBGb3JtQXR0YWNobWVudCgxMDAsIDApOwoJCWRhdGEudG9wID0gbmV3IEZvcm1BdHRhY2htZW50KDU1LCAwKTsKCQlwaG9uZVRleHQuc2V0TGF5b3V0RGF0YShkYXRhKTsKCQkKCQlzaGVsbC5wYWNrKCk7CgkJCgkJcmV0dXJuIHNoZWxsOwoJfQkKfTwvcHJlPgoKPHA+VGhpcyBpcyB3aGF0IHRoZSBsYXlvdXQgbG9va3MgbGlrZSBhZnRlciBNYXJ5IFNtaXRoIGVudGVycwpCaWZmb3JkIGluIHRoZSBkb2cgc2hvdzo8L3A+Cgo8aW1nIHNyYz0iaW1hZ2VzL0RvZ1Nob3dCaWZmV2l0aEZvcm1MYXlvdXQuanBnIiAvPgoKPC9wPgo8cD5XaGVuIHRoZSB3aW5kb3cgaXMgcmVzaXplZCwgdGhlIHNhbWUgY29udHJvbHMgYXJlIHJlc2l6ZWQgYXMgaW4KdGhlIDxjb2RlPkdyaWRMYXlvdXQ8L2NvZGU+IGV4YW1wbGUuPC9wPgoKPGltZyBzcmM9ImltYWdlcy9Eb2dTaG93QmlmZldpdGhGb3JtTGF5b3V0UmVzaXplZC5qcGciIC8+Cgo8aDI+V3JpdGluZyBZb3VyIE93biBMYXlvdXQgQ2xhc3M8L2gyPgoKPHA+T2NjYXNpb25hbGx5LCB5b3UgbWF5IHdhbnQgdG8gd3JpdGUgeW91ciBvd24gPGNvZGU+TGF5b3V0PC9jb2RlPgpjbGFzcy4gUGVyaGFwcyB5b3VyIGxheW91dCBuZWVkcyBhcmUgdmVyeSBjb21wbGV4LiBNYXliZSB5b3UgaGF2ZSB0aGUKc2FtZSBsb29rIGluIG1hbnkgcGxhY2VzLCBhbmQgeW91IHdhbnQgdG8gdGFrZSBhZHZhbnRhZ2Ugb2YgY29kZSByZXVzZS4KT3IgeW91IHdhbnQgdG8gbGV2ZXJhZ2UgZG9tYWluIGtub3dsZWRnZSB0byBjcmVhdGUgYSB2ZXJ5IGVmZmljaWVudApsYXlvdXQgY2xhc3MuIFdoYXRldmVyIHRoZSByZWFzb24sIHRoZXJlIGFyZSB0aGluZ3MgdG8gY29uc2lkZXIgYmVmb3JlCndyaXRpbmcgYSBuZXcgY2xhc3M6PC9wPgoKPHVsPgoJPGxpPkNhbiB0aGUgbGF5b3V0IGJlIGRvbmUgdXNpbmcgYSA8Y29kZT5HcmlkTGF5b3V0PC9jb2RlPiBvciA8Y29kZT5Gb3JtTGF5b3V0PC9jb2RlPiwKCXdpdGggbWF5YmUgYSBmZXcgbmVzdGVkIGxheW91dHM/PC9saT4KCTxsaT5DYW4gdGhlIGRlc2lyZWQgZWZmZWN0IGJlIG1vcmUgZWFzaWx5IGFjaGlldmVkIHdpdGggYSByZXNpemUKCWxpc3RlbmVyPzwvbGk+Cgk8bGk+QXJlIHlvdSBkZWZpbmluZyBhIGdlbmVyYWwgbGF5b3V0IGFsZ29yaXRobSBvciBqdXN0Cglwb3NpdGlvbmluZyB3aWRnZXRzPzwvbGk+CjwvdWw+Cgo8cD5Vbmxlc3MgeW91IGFyZSB3cml0aW5nIGEgdmVyeSBnZW5lcmljIDxjb2RlPkxheW91dDwvY29kZT4gdHlwZQp0aGF0IHdpbGwgYmUgdXNlZCBieSBzZXZlcmFsIDxjb2RlPkNvbXBvc2l0ZTwvY29kZT4gd2lkZ2V0cywgaXQgaXMgb2Z0ZW4KYmV0dGVyIGFuZCBlYXNpZXIgdG8gc2ltcGx5IGNhbGN1bGF0ZSBzaXplcyBhbmQgcG9zaXRpb24gY2hpbGRyZW4gaW4gYQpyZXNpemUgbGlzdGVuZXIuIE1hbnkgb2YgdGhlIFNXVCBjdXN0b20gd2lkZ2V0cyB3ZXJlIHdyaXR0ZW4gdGhpcyB3YXkuCkFsdGhvdWdoIGEgbmV3IHdpZGdldCBjYW4gYmUgaW1wbGVtZW50ZWQgYXMgYSA8Y29kZT5Db21wb3NpdGU8L2NvZGU+Lzxjb2RlPkxheW91dDwvY29kZT4KcGFpciwgaW1wbGVtZW50aW5nIGl0IGFzIGEgPGNvZGU+Q29tcG9zaXRlPC9jb2RlPiB0aGF0IGRvZXMgaXRzIGxheW91dAppbiBhIHJlc2l6ZSBsaXN0ZW5lciBhbmQgY29tcHV0ZXMgaXRzIHByZWZlcnJlZCBzaXplIGluIDxjb2RlPmNvbXB1dGVTaXplPC9jb2RlPgppcyBjbGVhcmVyLCBhbmQgZG9lcyBub3QgaW52b2x2ZSB3cml0aW5nIGFuIGV4dHJhIGNsYXNzLjwvcD4KCjxwPkZpcnN0LCB3ZSB3aWxsIGxvb2sgYXQgaG93IGxheW91dHMgd29yaywgYW5kIHRoZW4gd2Ugd2lsbCBjcmVhdGUKYSBuZXcgPGNvZGU+TGF5b3V0PC9jb2RlPiBjbGFzcy4gQW5vdGhlciBleGFtcGxlIG9mIHdyaXRpbmcgeW91ciBvd24gPGNvZGU+TGF5b3V0PC9jb2RlPgpjYW4gYmUgZm91bmQgaW4gdGhlIDxpPkNvbXBvdW5kIFdpZGdldCBFeGFtcGxlPC9pPiBzZWN0aW9uIG9mIDxhCglocmVmPSJodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2FydGljbGVzL0FydGljbGUtV3JpdGluZyUyMFlvdXIlMjBPd24lMjBXaWRnZXQvV3JpdGluZyUyMFlvdXIlMjBPd24lMjBXaWRnZXQuaHRtIj5DcmVhdGluZwpZb3VyIE93biBXaWRnZXRzIFVzaW5nIFNXVDwvYT4sIHdoaWNoIHNob3dzIGhvdyB0byBhY2hpZXZlIHRoZSBzYW1lIGxvb2sKdXNpbmcgZWl0aGVyIGEgcmVzaXplIGxpc3RlbmVyIG9yIGEgbmV3IDxjb2RlPkxheW91dDwvY29kZT4gY2xhc3MuPC9wPgoKPGgzPkhvdyBMYXlvdXRzIFdvcms8L2gzPgoKPHA+PGNvZGU+TGF5b3V0PC9jb2RlPiBpcyB0aGUgYWJzdHJhY3Qgc3VwZXJjbGFzcyBvZiBhbGwgbGF5b3V0cy4gSXQKb25seSBoYXMgdHdvIG1ldGhvZHM6IDxjb2RlPmNvbXB1dGVTaXplPC9jb2RlPiBhbmQgPGNvZGU+bGF5b3V0PC9jb2RlPi4KVGhlIGNsYXNzIGlzIGRlZmluZWQgYXMgZm9sbG93czo8L3A+Cgo8cHJlPnB1YmxpYyBhYnN0cmFjdCBjbGFzcyBMYXlvdXQgewogICAgcHJvdGVjdGVkIGFic3RyYWN0IFBvaW50IGNvbXB1dGVTaXplKENvbXBvc2l0ZSBjb21wb3NpdGUsIGludCB3aWR0aEhpbnQsIGludCBoZWlnaHRIaW50LCBib29sZWFuIGZsdXNoQ2FjaGUpOwogICAgcHJvdGVjdGVkIGFic3RyYWN0IHZvaWQgbGF5b3V0KENvbXBvc2l0ZSBjb21wb3NpdGUsIGJvb2xlYW4gZmx1c2hDYWNoZSk7Cn08L3ByZT4KCjxwPlRoZSA8Y29kZT5jb21wdXRlU2l6ZTwvY29kZT4gbWV0aG9kIGNhbGN1bGF0ZXMgdGhlIHdpZHRoIGFuZApoZWlnaHQgb2YgYSByZWN0YW5nbGUgdGhhdCBlbmNsb3NlcyBhbGwgb2YgdGhlIDxjb2RlPkNvbXBvc2l0ZTwvY29kZT4ncwpjaGlsZHJlbiBvbmNlIHRoZXkgaGF2ZSBiZWVuIHNpemVkIGFuZCBwbGFjZWQgYWNjb3JkaW5nIHRvIHRoZSBsYXlvdXQKYWxnb3JpdGhtIGVuY29kZWQgaW4gdGhlIDxjb2RlPkxheW91dDwvY29kZT4gY2xhc3MuIFRoZSBoaW50IHBhcmFtZXRlcnMKYWxsb3cgdGhlIHdpZHRoIGFuZC9vciBoZWlnaHQgdG8gYmUgY29uc3RyYWluZWQuIEZvciBleGFtcGxlLCBhIGxheW91dAptYXkgY2hvb3NlIHRvIGdyb3cgaW4gb25lIGRpbWVuc2lvbiBpZiBjb25zdHJhaW5lZCBpbiBhbm90aGVyLiBBIGhpbnQgb2YKU1dULkRFRkFVTFQgbWVhbnMgdG8gdXNlIHRoZSBwcmVmZXJyZWQgc2l6ZS48L3A+Cgo8cD5UaGUgPGNvZGU+bGF5b3V0PC9jb2RlPiBtZXRob2QgcG9zaXRpb25zIGFuZCBzaXplcyB0aGUgPGNvZGU+Q29tcG9zaXRlPC9jb2RlPidzCmNoaWxkcmVuLiBBIDxjb2RlPkxheW91dDwvY29kZT4gY2FuIGNob29zZSB0byBjYWNoZSBsYXlvdXQtcmVsYXRlZAppbmZvcm1hdGlvbiwgc3VjaCBhcyB0aGUgcHJlZmVycmVkIGV4dGVudCBvZiBlYWNoIG9mIHRoZSBjaGlsZHJlbi4gVGhlIDxjb2RlPmZsdXNoQ2FjaGU8L2NvZGU+CnBhcmFtZXRlciB0ZWxscyB0aGUgPGNvZGU+TGF5b3V0PC9jb2RlPiB0byBmbHVzaCBjYWNoZWQgZGF0YS48L3A+Cgo8cD5TaW5jZSBhIDxjb2RlPkxheW91dDwvY29kZT4gY29udHJvbHMgdGhlIHNpemUgYW5kIHBsYWNlbWVudCBvZgp3aWRnZXRzIGluIGEgPGNvZGU+Q29tcG9zaXRlPC9jb2RlPiwgdGhlcmUgYXJlIHNldmVyYWwgbWV0aG9kcyBpbiA8Y29kZT5Db21wb3NpdGU8L2NvZGU+CnRoYXQgYXJlIHVzZWQgd2l0aCA8Y29kZT5MYXlvdXQ8L2NvZGU+cy48L3A+Cgo8cD5UaGUgZmlyc3QgdHdvIG1ldGhvZHMgYWxsb3cgc2V0dGluZyBhbmQgZ2V0dGluZyBhIDxjb2RlPkxheW91dDwvY29kZT4Kb2JqZWN0IGluIGEgPGNvZGU+Q29tcG9zaXRlPC9jb2RlPi48L3A+Cgo8cHJlPnB1YmxpYyB2b2lkIHNldExheW91dChMYXlvdXQgbGF5b3V0KTsKcHVibGljIExheW91dCBnZXRMYXlvdXQoKTs8L3ByZT4KCjxwPkFuIGFwcGxpY2F0aW9uIGNhbiBmb3JjZSBhIDxjb2RlPkxheW91dDwvY29kZT4gdG8gcmVjYWxjdWxhdGUgdGhlCnNpemVzIG9mIGFuZCByZXBvc2l0aW9uIGNoaWxkcmVuIGJ5IHNlbmRpbmcgPGNvZGU+bGF5b3V0KCk8L2NvZGU+IHRvIHRoZQpwYXJlbnQgPGNvZGU+Q29tcG9zaXRlPC9jb2RlPi48L3A+Cgo8cHJlPnB1YmxpYyB2b2lkIGxheW91dChib29sZWFuIGNoYW5nZWQpOw0KcHVibGljIHZvaWQgbGF5b3V0KCk7CiAgICAvLyBjYWxscyBsYXlvdXQodHJ1ZSk7PC9wcmU+Cgo8cD5Zb3Ugd291bGQgZG8gdGhpcyBhZnRlciBjaGFuZ2luZyBhbnl0aGluZyBhYm91dCB0aGUgY2hpbGRyZW4gdGhhdAptaWdodCBhZmZlY3QgdGhlaXIgc2l6ZSBvciBwb3NpdGlvbiwgc3VjaCBhcyBjaGFuZ2luZyB0aGUgZm9udCBvZiBhCmNoaWxkLCBjaGFuZ2luZyB0aGUgdGV4dCBvciBpbWFnZSBvZiBhIGNoaWxkLCBhZGRpbmcgYSBuZXcgY2hpbGQsIG9yCmFkZGluZyBjaGlsZHJlbiB0byBhIGNoaWxkIChJZiB0aGUgY2hpbGQgY2FuIGFjY29tbW9kYXRlIHRoZSBjaGFuZ2UsCnRoZW4gbGF5b3V0IG1heSBub3QgYmUgbmVjZXNzYXJ5IJYgZm9yIGV4YW1wbGUsIGNoYW5naW5nIHRoZSBmb250IG9yCnRleHQgb2YgYSBzY3JvbGxhYmxlIG11bHRpLWxpbmUgPGNvZGU+VGV4dDwvY29kZT4pLiBTaW5jZSB0aGVzZSBjaGFuZ2VzCmFyZSBkb25lIHByb2dyYW1tYXRpY2FsbHksIHRoZXkgZG8gbm90IGNhdXNlIGV2ZW50cyB0byBoYXBwZW4uCkNvbnNlcXVlbnRseSwgdGhlIHBhcmVudCBkb2Vzbid0IGtub3cgYWJvdXQgdGhlIGNoYW5nZXMsIGFuZCBoYXMgdG8gYmUKdG9sZCB0aHJvdWdoIHRoZSA8Y29kZT5sYXlvdXQ8L2NvZGU+IG1ldGhvZC4gVGhpcyBzdHJhdGVneSByZWR1Y2VzIGZsYXNoCmJlY2F1c2UgdGhlIGFwcGxpY2F0aW9uIGNhbiBtYWtlIHNldmVyYWwgY2hhbmdlcyBhbmQgdGhlbiB0ZWxsIHRoZQpwYXJlbnQgdG8gbGF5b3V0LCBhbmQgdGhlIGNoaWxkcmVuIGFyZSBvbmx5IHJlZHJhd24gb25jZSBpbnN0ZWFkIG9mIG9uY2UKcGVyIGNoYW5nZS4gSWYgPGNvZGU+bGF5b3V0KCk8L2NvZGU+IGlzIG5vdCBjYWxsZWQgYW5kIGNoYW5nZXMgYXJlIG1hZGUKYWZ0ZXIgdGhlIHNoZWxsIGlzIG9wZW5lZCwgdGhlbiB0aGUgY2hpbGRyZW4gbWF5IG5vdCBiZSBjb3JyZWN0bHkgbGFpZApvdXQgdW50aWwgdGhlIHNoZWxsIGlzIHNvbWVob3cgcmVzaXplZC4gTm90ZSB0aGF0IDxjb2RlPnNoZWxsLm9wZW4oKTwvY29kZT4KY2F1c2VzIGEgbGF5b3V0IHRvIG9jY3VyLjwvcD4KCjxwPlRoZSA8Y29kZT5jb21wdXRlU2l6ZTwvY29kZT4gbWV0aG9kcyBvZiBhIDxjb2RlPkNvbXBvc2l0ZTwvY29kZT4KY2FsY3VsYXRlIHRoZSBDb21wb3NpdGUncyBwcmVmZXJyZWQgc2l6ZSwgd2hpY2ggaXMgdGhlIHNpemUgb2YgaXRzCmNsaWVudCBhcmVhIGFzIGRldGVybWluZWQgYnkgdGhlIDxjb2RlPkxheW91dDwvY29kZT4sIHBsdXMgaXRzIHRyaW0uPC9wPgoKPHByZT5wdWJsaWMgUG9pbnQgY29tcHV0ZVNpemUoaW50IHdpZHRoSGludCwgaW50IGhlaWdodEhpbnQsIGJvb2xlYW4gY2hhbmdlZCk7CnB1YmxpYyBQb2ludCBjb21wdXRlU2l6ZShpbnQgd2lkdGhIaW50LCBpbnQgaGVpZ2h0SGludCk7CiAgICAvLyBjYWxscyBjb21wdXRlU2l6ZSh3aWR0aEhpbnQsIGhlaWdodEhpbnQsIHRydWUpOzwvcHJlPgoKPHA+VGhlIDxiPmNsaWVudEFyZWE8L2I+IG9mIGEgPGNvZGU+Q29tcG9zaXRlPC9jb2RlPiBpcyB0aGUKcmVjdGFuZ2xlIHRoYXQgd2lsbCBjb250YWluIGFsbCBvZiB0aGUgY2hpbGRyZW4uIEEgPGNvZGU+TGF5b3V0PC9jb2RlPgpwb3NpdGlvbnMgdGhlIGNoaWxkcmVuIGluc2lkZSB0aGUgY2xpZW50IGFyZWEuPC9wPgoKPHByZT5wdWJsaWMgUmVjdGFuZ2xlIGdldENsaWVudEFyZWEgKCk7PC9wcmU+Cgo8cD5UaGUgPGI+dHJpbTwvYj4gb2YgYSA8Y29kZT5Db21wb3NpdGU8L2NvZGU+IGlzIHRoZSBhcmVhIG91dHNpZGUKdGhlIGNsaWVudCBhcmVhLiBGb3Igc29tZSBjb21wb3NpdGVzLCB0aGUgc2l6ZSBvZiB0aGUgdHJpbSBpcyB6ZXJvLiBUaGUKdHJpbSBjYW4gYmUgY29tcHV0ZWQgYnkgcGFzc2luZyB0aGUgZGltZW5zaW9ucyBvZiB0aGUgY2xpZW50IGFyZWEgaW50bwp0aGUgbWV0aG9kIDxjb2RlPmNvbXB1dGVUcmltPC9jb2RlPi48L3A+Cgo8cHJlPnB1YmxpYyBSZWN0YW5nbGUgY29tcHV0ZVRyaW0gKGludCB4LCBpbnQgeSwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0KTs8L3ByZT4KCjxwPlNlbmRpbmcgPGNvZGU+cGFjazwvY29kZT4gdG8gYSA8Y29kZT5Db21wb3NpdGU8L2NvZGU+IHJlc2l6ZXMgaXQKdG8gaXRzIHByZWZlcnJlZCBzaXplLjwvcD4KCjxwcmU+cHVibGljIHZvaWQgcGFjayhib29sZWFuIGNoYW5nZWQpOwogICAgLy8gY2FsbHMgc2V0U2l6ZShjb21wdXRlU2l6ZShTV1QuREVGQVVMVCwgU1dULkRFRkFVTFQsIGNoYW5nZWQpKTsKcHVibGljIHZvaWQgcGFjaygpOwogICAgLy8gY2FsbHMgcGFjayh0cnVlKTs8L3ByZT4KCjxwPlRoZSBib29sZWFuIHBhcmFtZXRlciB0byB0aGUgPGNvZGU+bGF5b3V0PC9jb2RlPiwgPGNvZGU+Y29tcHV0ZVNpemU8L2NvZGU+LAphbmQgPGNvZGU+cGFjazwvY29kZT4gbWV0aG9kcyBpcyB0aGUgPGNvZGU+Y2hhbmdlZDwvY29kZT4gZmxhZy4gSWYgPGNvZGU+dHJ1ZTwvY29kZT4sCml0IGluZGljYXRlcyB0aGF0IHRoZSA8Y29kZT5Db21wb3NpdGU8L2NvZGU+J3MgY29udGVudHMgaGF2ZSBjaGFuZ2VkIGluCnNvbWUgd2F5IHRoYXQgYWZmZWN0cyBpdHMgcHJlZmVycmVkIHNpemUsIHRoZXJlZm9yZSBhbnkgY2FjaGVzIHRoYXQgdGhlCjxjb2RlPkxheW91dDwvY29kZT4gbWF5IGhhdmUgYmVlbiBrZWVwaW5nIG5lZWQgdG8gYmUgZmx1c2hlZC4gV2hlbiBhIDxjb2RlPkNvbXBvc2l0ZTwvY29kZT4KaXMgcmVzaXplZCwgaXQgYXNrcyBpdHMgPGNvZGU+TGF5b3V0PC9jb2RlPiB0byBsYXkgb3V0IGl0cyBjaGlsZHJlbiBieQpjYWxsaW5nIGxheW91dChmYWxzZSk7IHRoZXJlZm9yZSB3aWRnZXQgY29udGVudCBjYWNoZXMgYXJlIDxpPm5vdDwvaT4KZmx1c2hlZC4gVGhpcyBsZXRzIHRoZSA8Y29kZT5MYXlvdXQ8L2NvZGU+IHBlcmZvcm0gYW55IGV4cGVuc2l2ZQpjYWxjdWxhdGlvbnMgb25seSB3aGVuIG5lY2Vzc2FyeS48L3A+Cgo8cD5DYWNoaW5nIGNhbiBpbmNyZWFzZSBwZXJmb3JtYW5jZSwgYnV0IGl0IGNhbiBhbHNvIGJlIHRyaWNreS4gWW91CmNhbiBjaG9vc2Ugbm90IHRvIGNhY2hlIGF0IGFsbDogaW4gZmFjdCwgaXQgaXMgYmVzdCBub3QgdG8gdHJ5IGNhY2hpbmcKdW50aWwgeW91ciBjb2RlIGlzIHN0YWJsZS4gV2hlbiBjb25zaWRlcmluZyB3aGF0IHRvIGNhY2hlLCBiZSBjZXJ0YWluCm5vdCB0byBzdG9yZSBhbnkgd2lkZ2V0IHN0YXRlLCBzdWNoIGFzIHRoZSB0ZXh0IG9mIGEgbGFiZWwsIG9yIHRoZQpudW1iZXIgb2YgaXRlbXMgaW4gYSBsaXN0LjwvcD4KCjxoMz5DdXN0b20gTGF5b3V0IEV4YW1wbGU8L2gzPgoKPHA+SWYgeW91IGhhdmUgc2V2ZXJhbCB2ZXJ0aWNhbGx5IG9yaWVudGVkIDxjb2RlPkNvbXBvc2l0ZTwvY29kZT4Kd2lkZ2V0cyBpbiB5b3VyIGFwcGxpY2F0aW9uLCB5b3UgbWlnaHQgY2hvb3NlIHRvIHdyaXRlIDxjb2RlPkNvbHVtbkxheW91dDwvY29kZT4uCldlIHdpbGwgc2hvdyBhIHNpbXBsZSB2ZXJzaW9uIG9mIGEgPGNvZGU+TGF5b3V0PC9jb2RlPiBjbGFzcyB0aGF0IGxheXMKb3V0IDxjb2RlPkNvbXBvc2l0ZTwvY29kZT4gY2hpbGRyZW4gaW50byBhIHNpbmdsZSBjb2x1bW4uIFRoZSBjbGFzcyBoYXMKZml4ZWQgbWFyZ2lucyBhbmQgc3BhY2luZy4gQ2hpbGRyZW4gYXJlIGdpdmVuIHRoZSBzYW1lIHdpZHRoLCBidXQgdGhleQp0YWtlIHRoZWlyIG5hdHVyYWwgaGVpZ2h0LiAoTm90ZSB0aGF0IDxjb2RlPlJvd0xheW91dDwvY29kZT4gd2lsbCBoYXZlIDxjb2RlPkNvbHVtbkxheW91dDwvY29kZT4KYmVoYXZpb3VyIGlmIGl0cyB0eXBlIGlzIHNldCB0byA8Y29kZT5TV1QuVkVSVElDQUw8L2NvZGU+LiBUaGlzIGV4YW1wbGUgaXMsCnRoZXJlZm9yZSwganVzdCBhbiBleGFtcGxlLiBJbiBwcmFjdGljZSwgaWYgeW91IG5lZWQgdG8gbGF5IHdpZGdldHMgb3V0CmluIGEgY29sdW1uLCB5b3Ugd291bGQgdXNlIDxjb2RlPlJvd0xheW91dC48L2NvZGU+KTwvcD4KCjxwPlRoZSBjb2RlIGZvciB0aGUgPGNvZGU+Q29sdW1uTGF5b3V0PC9jb2RlPiBjbGFzcyBpcyBiZWxvdy4gTm90ZQp0aGF0IHdlIGNhY2hlIHRoZSB3aWR0aCBvZiB0aGUgd2lkZXN0IGNoaWxkLCBhbmQgdGhlIHN1bSBvZiB0aGUgY2hpbGQKaGVpZ2h0cyAocGx1cyBzcGFjaW5nKSwgYW5kIHRoZXNlIHZhbHVlcyBhcmUgdXNlZCB0byBjb21wdXRlIHRoZSBzaXplCmFuZCBsaWUgb3V0IHRoZSBjaGlsZHJlbi4gVGhleSBhcmUgcmVjYWxjdWxhdGVkIGlmIDxjb2RlPmZsdXNoQ2FjaGU8L2NvZGU+CmlzIDxjb2RlPnRydWU8L2NvZGU+LjwvcD4KCjxwcmU+aW1wb3J0IG9yZy5lY2xpcHNlLnN3dC4qOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmdyYXBoaWNzLio7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy4qOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmxheW91dC4qOwoKcHVibGljIGNsYXNzIENvbHVtbkxheW91dCBleHRlbmRzIExheW91dCB7CiAgICAvLyBmaXhlZCBtYXJnaW4gYW5kIHNwYWNpbmcKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BUkdJTiA9IDQ7CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTUEFDSU5HID0gMjsKICAgIC8vIGNhY2hlCiAgICBQb2ludFtdIHNpemVzOwogICAgaW50IG1heFdpZHRoLCB0b3RhbEhlaWdodDsKCiAgICBwcm90ZWN0ZWQgUG9pbnQgY29tcHV0ZVNpemUoQ29tcG9zaXRlIGNvbXBvc2l0ZSwgaW50IHdIaW50LCBpbnQgaEhpbnQsCiAgICAgICAgICAgIGJvb2xlYW4gZmx1c2hDYWNoZSkgewogICAgICAgIENvbnRyb2wgY2hpbGRyZW5bXSA9IGNvbXBvc2l0ZS5nZXRDaGlsZHJlbigpOwogICAgICAgIGlmIChmbHVzaENhY2hlIHx8IHNpemVzID09IG51bGwgfHwgc2l6ZXMubGVuZ3RoICE9IGNoaWxkcmVuLmxlbmd0aCkgewogICAgICAgICAgICBpbml0aWFsaXplKGNoaWxkcmVuKTsKICAgICAgICB9CiAgICAgICAgaW50IHdpZHRoID0gd0hpbnQsIGhlaWdodCA9IGhIaW50OwogICAgICAgIGlmICh3SGludCA9PSBTV1QuREVGQVVMVCkKICAgICAgICAgICAgd2lkdGggPSBtYXhXaWR0aDsKICAgICAgICBpZiAoaEhpbnQgPT0gU1dULkRFRkFVTFQpCiAgICAgICAgICAgIGhlaWdodCA9IHRvdGFsSGVpZ2h0OwogICAgICAgIHJldHVybiBuZXcgUG9pbnQod2lkdGggKyAyICogTUFSR0lOLCBoZWlnaHQgKyAyICogTUFSR0lOKTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgdm9pZCBsYXlvdXQoQ29tcG9zaXRlIGNvbXBvc2l0ZSwgYm9vbGVhbiBmbHVzaENhY2hlKSB7CiAgICAgICAgQ29udHJvbCBjaGlsZHJlbltdID0gY29tcG9zaXRlLmdldENoaWxkcmVuKCk7CiAgICAgICAgaWYgKGZsdXNoQ2FjaGUgfHwgc2l6ZXMgPT0gbnVsbCB8fCBzaXplcy5sZW5ndGggIT0gY2hpbGRyZW4ubGVuZ3RoKSB7CiAgICAgICAgICAgIGluaXRpYWxpemUoY2hpbGRyZW4pOwogICAgICAgIH0KICAgICAgICBSZWN0YW5nbGUgcmVjdCA9IGNvbXBvc2l0ZS5nZXRDbGllbnRBcmVhKCk7CiAgICAgICAgaW50IHggPSBNQVJHSU4sIHkgPSBNQVJHSU47CiAgICAgICAgaW50IHdpZHRoID0gTWF0aC5tYXgocmVjdC53aWR0aCAtIDIgKiBNQVJHSU4sIG1heFdpZHRoKTsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgIGludCBoZWlnaHQgPSBzaXplc1tpXS55OwogICAgICAgICAgICBjaGlsZHJlbltpXS5zZXRCb3VuZHMoeCwgeSwgd2lkdGgsIGhlaWdodCk7CiAgICAgICAgICAgIHkgKz0gaGVpZ2h0ICsgU1BBQ0lORzsKICAgICAgICB9CiAgICB9CgogICAgdm9pZCBpbml0aWFsaXplKENvbnRyb2wgY2hpbGRyZW5bXSkgewogICAgICAgIG1heFdpZHRoID0gMDsKICAgICAgICB0b3RhbEhlaWdodCA9IDA7CiAgICAgICAgc2l6ZXMgPSBuZXcgUG9pbnRbY2hpbGRyZW4ubGVuZ3RoXTsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgIHNpemVzW2ldID0gY2hpbGRyZW5baV0uY29tcHV0ZVNpemUoU1dULkRFRkFVTFQsIFNXVC5ERUZBVUxULCB0cnVlKTsKICAgICAgICAgICAgbWF4V2lkdGggPSBNYXRoLm1heChtYXhXaWR0aCwgc2l6ZXNbaV0ueCk7CiAgICAgICAgICAgIHRvdGFsSGVpZ2h0ICs9IHNpemVzW2ldLnk7CiAgICAgICAgfQogICAgICAgIHRvdGFsSGVpZ2h0ICs9IChjaGlsZHJlbi5sZW5ndGggLSAxKSAqIFNQQUNJTkc7CiAgICB9Cn08L3ByZT4KCjxwPkhlcmUgaXMgc29tZSBzaW1wbGUgdGVzdCBjb2RlIHRvIHRlc3QgdGhlIDxjb2RlPkNvbHVtbkxheW91dDwvY29kZT4uClRoZSA8Yj5ncm93PC9iPiBhbmQgPGI+c2hyaW5rPC9iPiA8Y29kZT5CdXR0b25zPC9jb2RlPiBzaG93IGEgY2FsbCB0bwp0aGUgPGNvZGU+U2hlbGw8L2NvZGU+J3MgPGNvZGU+bGF5b3V0KCk8L2NvZGU+IG1ldGhvZCB0byBmb3JjZSBhCnJlLWxheW91dCBhZnRlciBjaGFuZ2luZyB0aGUgd2lkdGggb2Ygb25lIG9mIHRoZSBjaGlsZHJlbi4gQ2FsbGluZyA8Y29kZT5sYXlvdXQoKTwvY29kZT4KaXMgdGhlIHNhbWUgYXMgY2FsbGluZyA8Y29kZT5sYXlvdXQodHJ1ZTwvY29kZT4pIHdoaWNoIHRlbGxzIHRoZSA8Y29kZT5Db2x1bW5MYXlvdXQ8L2NvZGU+CnRvIGZsdXNoIGl0cyBjYWNoZXMgYmVmb3JlIHNldHRpbmcgdGhlIGJvdW5kcyBvZiB0aGUgY2hpbGRyZW4uIFRoZSA8Y29kZT5TaGVsbDwvY29kZT4KaXMgYWxzbyB0b2xkIHRvIDxjb2RlPnBhY2soKTwvY29kZT4gYWZ0ZXIgbGF5aW5nIG91dCB0aGUgY2hpbGRyZW4uIFRoaXMKZm9yY2VzIHRoZSA8Y29kZT5TaGVsbDwvY29kZT4gdG8gdGFrZSB0aGUgbmV3IHNpemUuPC9wPgoKPHByZT5pbXBvcnQgb3JnLmVjbGlwc2Uuc3d0Lio7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy4qOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmxheW91dC4qOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy4qOwoKcHVibGljIGNsYXNzIENvbHVtbkxheW91dFRlc3QgewogICAgc3RhdGljIFNoZWxsIHNoZWxsOwogICAgc3RhdGljIEJ1dHRvbiBidXR0b24zOwoKICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpIHsKICAgICAgICBEaXNwbGF5IGRpc3BsYXkgPSBuZXcgRGlzcGxheSgpOwogICAgICAgIHNoZWxsID0gbmV3IFNoZWxsKGRpc3BsYXkpOwogICAgICAgIHNoZWxsLnNldExheW91dChuZXcgQ29sdW1uTGF5b3V0KCkpOwogICAgICAgIG5ldyBCdXR0b24oc2hlbGwsIFNXVC5QVVNIKS5zZXRUZXh0KCJCMSIpOwogICAgICAgIG5ldyBCdXR0b24oc2hlbGwsIFNXVC5QVVNIKS5zZXRUZXh0KCJWZXJ5IFdpZGUgQnV0dG9uIDIiKTsKICAgICAgICAoYnV0dG9uMyA9IG5ldyBCdXR0b24oc2hlbGwsIFNXVC5QVVNIKSkuc2V0VGV4dCgiQnV0dG9uIDMiKTsKICAgICAgICBCdXR0b24gZ3JvdyA9IG5ldyBCdXR0b24oc2hlbGwsIFNXVC5QVVNIKTsKICAgICAgICBncm93LnNldFRleHQoIkdyb3cgQnV0dG9uIDMiKTsKICAgICAgICBncm93LmFkZFNlbGVjdGlvbkxpc3RlbmVyKG5ldyBTZWxlY3Rpb25BZGFwdGVyKCkgewogICAgICAgICAgICBwdWJsaWMgdm9pZCB3aWRnZXRTZWxlY3RlZChTZWxlY3Rpb25FdmVudCBlKSB7CiAgICAgICAgICAgICAgICBidXR0b24zLnNldFRleHQoIkV4dHJlZW1lbHkgV2lkZSBCdXR0b24gMyIpOwogICAgICAgICAgICAgICAgc2hlbGwubGF5b3V0KCk7CiAgICAgICAgICAgICAgICBzaGVsbC5wYWNrKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9KTsKICAgICAgICBCdXR0b24gc2hyaW5rID0gbmV3IEJ1dHRvbihzaGVsbCwgU1dULlBVU0gpOwogICAgICAgIHNocmluay5zZXRUZXh0KCJTaHJpbmsgQnV0dG9uIDMiKTsKICAgICAgICBzaHJpbmsuYWRkU2VsZWN0aW9uTGlzdGVuZXIobmV3IFNlbGVjdGlvbkFkYXB0ZXIoKSB7CiAgICAgICAgICAgIHB1YmxpYyB2b2lkIHdpZGdldFNlbGVjdGVkKFNlbGVjdGlvbkV2ZW50IGUpIHsKICAgICAgICAgICAgICAgIGJ1dHRvbjMuc2V0VGV4dCgiQnV0dG9uIDMiKTsKICAgICAgICAgICAgICAgIHNoZWxsLmxheW91dCgpOwogICAgICAgICAgICAgICAgc2hlbGwucGFjaygpOwogICAgICAgICAgICB9CiAgICAgICAgfSk7CiAgICAgICAgc2hlbGwucGFjaygpOwogICAgICAgIHNoZWxsLm9wZW4oKTsKICAgICAgICB3aGlsZSAoIXNoZWxsLmlzRGlzcG9zZWQoKSkgewogICAgICAgICAgICBpZiAoIWRpc3BsYXkucmVhZEFuZERpc3BhdGNoKCkpCiAgICAgICAgICAgICAgICBkaXNwbGF5LnNsZWVwKCk7CiAgICAgICAgfQogICAgfQp9PC9wcmU+Cgo8cD5JZiB3ZSBydW4gdGhlIHRlc3QgY29kZSwgdGhlIHdpbmRvdyBvbiB0aGUgbGVmdCBhcHBlYXJzLiBQcmVzc2luZwp0aGUgR3JvdyBCdXR0b24gMyBidXR0b24gcmVzdWx0cyBpbiB0aGUgd2luZG93IG9uIHRoZSByaWdodC4gUmVzaXppbmcKdGhlIHdpbmRvdyB3aXRoIHRoZSBtb3VzZSB3aWxsIGFsc28gbWFrZSB0aGUgYnV0dG9ucyB3aWRlciAob3IgbmFycm93ZXIpCmJ1dCB0aGV5IGRvIG5vdCBncm93IHRhbGxlci48L3A+Cgo8aW1nIHNyYz0iaW1hZ2VzL0N1c3RvbUxheW91dC5qcGciIC8+IDxpbWcKCXNyYz0iaW1hZ2VzL0N1c3RvbUxheW91dFJlc2l6ZWQuanBnIiAvPgoKPGgzPk92ZXJyaWRpbmcgQ29tcG9zaXRlPC9oMz4KCjxwPklmIHlvdSBhcmUgd3JpdGluZyB5b3VyIG93biB3aWRnZXQsIGFzIG91dGxpbmVkIGluIDxhCglocmVmPSJodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2FydGljbGVzL0FydGljbGUtV3JpdGluZyUyMFlvdXIlMjBPd24lMjBXaWRnZXQvV3JpdGluZyUyMFlvdXIlMjBPd24lMjBXaWRnZXQuaHRtIj5DcmVhdGluZwpZb3VyIE93biBXaWRnZXRzIFVzaW5nIFNXVDwvYT4sIGFuZCB5b3Ugc3ViY2xhc3MgQ29tcG9zaXRlLCB0aGVuIGhlcmUgYXJlIGEKZmV3IHBvaW50cyB0byBjb25zaWRlciBmb3IgeW91ciBpbXBsZW1lbnRhdGlvbjo8L2E+PC9wPgoKPHVsPgoJPGxpPklmIHlvdSBhcmUgcHJvdmlkaW5nIHRyaW1taW5ncyBpbiB5b3VyIG5ldyA8Y29kZT5Db21wb3NpdGU8L2NvZGU+LAoJbWFrZSBzdXJlIHRvIG92ZXJyaWRlIGJvdGggPGNvZGU+Y29tcHV0ZVRyaW0oKTwvY29kZT4gYW5kIDxjb2RlPmdldENsaWVudEFyZWEoKTwvY29kZT4uPC9saT4KCTxsaT5OZXZlciBvdmVycmlkZSA8Y29kZT5sYXlvdXQoKTwvY29kZT4sIGJ1dCB5b3UgbWF5IG92ZXJyaWRlIDxjb2RlPmxheW91dChib29sZWFuKTwvY29kZT4uPC9saT4KPC91bD4KCjxwPlNvbWV0aW1lcyB5b3Ugd2FudCB5b3VyIG5ldyA8Y29kZT5Db21wb3NpdGU8L2NvZGU+IHRvIGhhdmUgYQpzcGVjaWZpYyBsb29rLCBhbmQgeW91IGRvbid0IHdhbnQgdGhlIGFwcGxpY2F0aW9uIHRvIGJlIGFibGUgdG8gc3BlY2lmeQphIGxheW91dC4gWW91ciBuZXcgPGNvZGU+Q29tcG9zaXRlPC9jb2RlPiB3b3VsZCBlaXRoZXIgZG8gaXRzIGxheW91dCBpbgphIHJlc2l6ZSBoYW5kbGVyIG9yIHVzaW5nIGEgcHJpdmF0ZSBjdXN0b20gbGF5b3V0LiBJbiBlaXRoZXIgY2FzZSwgeW91CndpbGwgcHJvYmFibHkgd2FudCB0byBkbyB0aGUgZm9sbG93aW5nOjwvcD4KCjx1bD4KCTxsaT5PdmVycmlkZSA8Y29kZT5zZXRMYXlvdXQoKTwvY29kZT4gdG8gZG8gbm90aGluZy48L2xpPgoJPGxpPk92ZXJyaWRlIDxjb2RlPmxheW91dChib29sZWFuKTwvY29kZT4gdG8gY2FsbCB5b3VyIGxheW91dAoJY29kZS48L2xpPgoJPGxpPk92ZXJyaWRlIDxjb2RlPmNvbXB1dGVTaXplKCk8L2NvZGU+IHRvIGNvcnJlY3RseSBjb21wdXRlIHRoZQoJc2l6ZSBvZiB5b3VyIDxjb2RlPkNvbXBvc2l0ZTwvY29kZT4uPC9saT4KPC91bD4KCgo8aDI+U3VtbWFyeTwvaDI+Cgo8cD5TV1QgcHJvdmlkZXMgc2V2ZXJhbCBkaWZmZXJlbnQgd2F5cyB0byBsYXkgb3V0IHdpZGdldHMuIFRoZQpzaW1wbGVzdCBtZXRob2QsIGFuZCB0aGUgb25lIHlvdSB3aWxsIHR5cGljYWxseSB1c2UsIGlzIHRvIHVzZSBvbmUgb2YKdGhlIHN0YW5kYXJkIDxjb2RlPkxheW91dDwvY29kZT4gY2xhc3NlczogPGNvZGU+RmlsbExheW91dDwvY29kZT4sIDxjb2RlPlJvd0xheW91dDwvY29kZT4sCjxjb2RlPkdyaWRMYXlvdXQ8L2NvZGU+IG9yIDxjb2RlPkZvcm1MYXlvdXQ8L2NvZGU+LjwvcD4KCgo8cD5JbiBjZXJ0YWluIGNhc2VzIHlvdSBtYXkgd2FudCB0byB3cml0ZSB5b3VyIG93biA8Y29kZT5MYXlvdXQ8L2NvZGU+CmNsYXNzIHRvIHByb3ZpZGUgYSB2ZXJ5IHNwZWNpZmljIGxvb2sgb3IgdG8gcmV1c2UgdmVyeSBzaW1pbGFyIGxheW91dApjb2RlLCBidXQgb2Z0ZW4gYSByZXNpemUgbGlzdGVuZXIgb24gdGhlIHBhcmVudCB3aWRnZXQgd2lsbCBzdWZmaWNlLjwvcD4KCgoKPHA+Rm9yIGZ1cnRoZXIgYXNzaXN0YW5jZSBpbiB1bmRlcnN0YW5kaW5nIHRoZSBzdGFuZGFyZCBTV1QgPGNvZGU+TGF5b3V0PC9jb2RlPgpjbGFzc2VzLCBzZWUgdGhlIDxhIGhyZWY9Imh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvc3d0L3NuaXBwZXRzIj5TV1QgU25pcHBldHM8L2E+LjwvcD4KPC9kaXY+Cgo8L2JvZHk+CgoKCgo8L2h0bWw+