memoscan
← all memos

Memo 0x3e25e370…fed4fa on Ethereum

k7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChtZXNzYWdlLnR5cGUgPT09ICd3YXJuaW5nJykgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxvZygnd2FybicsIGBGcmFnbWVudCBzaGFkZXIgd2FybmluZzogJHttZXNzYWdlLm1lc3NhZ2V9YCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICAvLyBCdWlsZCBiaW5kIGdyb3VwIGxheW91dHMgYXJyYXkKICAgICAgICAgICAgY29uc3QgYmluZEdyb3VwTGF5b3V0cyA9IFtdOwogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKG5lZWRzVGV4dHVyZUlucHV0KSB7CiAgICAgICAgICAgICAgICAvLyBHcm91cCAwOiBUZXh0dXJlIGlucHV0IChmb3IgcG9zdC1wcm9jZXNzaW5nIGVmZmVjdHMpCiAgICAgICAgICAgICAgICBjb25zdCB0ZXh0dXJlQmluZEdyb3VwTGF5b3V0ID0gdGhpcy5zdGF0ZS5kZXZpY2UuY3JlYXRlQmluZEdyb3VwTGF5b3V0KHsKICAgICAgICAgICAgICAgICAgICBlbnRyaWVzOiBbCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJpbmRpbmc6IDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aXNpYmlsaXR5OiBHUFVTaGFkZXJTdGFnZS5GUkFHTUVOVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleHR1cmU6IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzYW1wbGVUeXBlOiAnZmxvYXQnCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJpbmRpbmc6IDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aXNpYmlsaXR5OiBHUFVTaGFkZXJTdGFnZS5GUkFHTUVOVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNhbXBsZXI6IHt9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBdLAogICAgICAgICAgICAgICAgICAgIGxhYmVsOiBgJHtlZmZlY3QubmFtZX0gVGV4dHVyZSBCaW5kIEdyb3VwIExheW91dGAKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgYmluZEdyb3VwTGF5b3V0cy5wdXNoKHRleHR1cmVCaW5kR3JvdXBMYXlvdXQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICAvLyBHcm91cCAxIChvciAwIGlmIG5vIHRleHR1cmUpOiBFZmZlY3QgcGFyYW1ldGVycwogICAgICAgICAgICBiaW5kR3JvdXBMYXlvdXRzLnB1c2goZWZmZWN0LmdldEJpbmRHcm91cExheW91dCgpKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIGNvbnN0IHBpcGVsaW5lTGF5b3V0ID0gdGhpcy5zdGF0ZS5kZXZpY2UuY3JlYXRlUGlwZWxpbmVMYXlvdXQoewogICAgICAgICAgICAgICAgYmluZEdyb3VwTGF5b3V0cywKICAgICAgICAgICAgICAgIGxhYmVsOiBgJHtlZmZlY3QubmFtZX0gUGlwZWxpbmUgTGF5b3V0YAogICAgICAgICAgICB9KTsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIENyZWF0ZSByZW5kZXIgcGlwZWxpbmUKICAgICAgICAgICAgY29uc3QgcGlwZWxpbmUgPSB0aGlzLnN0YXRlLmRldmljZS5jcmVhdGVSZW5kZXJQaXBlbGluZSh7CiAgICAgICAgICAgICAgICBsYXlvdXQ6IHBpcGVsaW5lTGF5b3V0LAogICAgICAgICAgICAgICAgdmVydGV4OiB7CiAgICAgICAgICAgICAgICAgICAgbW9kdWxlOiB2ZXJ0ZXhNb2R1bGUsCiAgICAgICAgICAgICAgICAgICAgZW50cnlQb2ludDogJ3ZzX21haW4nCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgZnJhZ21lbnQ6IHsKICAgICAgICAgICAgICAgICAgICBtb2R1bGU6IGZyYWdtZW50TW9kdWxlLAogICAgICAgICAgICAgICAgICAgIGVudHJ5UG9pbnQ6ICdmc19tYWluJywKICAgICAgICAgICAgICAgICAgICB0YXJnZXRzOiBbewogICAgICAgICAgICAgICAgICAgICAgICBmb3JtYXQ6IHRoaXMuc3RhdGUuZm9ybWF0CiAgICAgICAgICAgICAgICAgICAgfV0KICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBwcmltaXRpdmU6IHsKICAgICAgICAgICAgICAgICAgICB0b3BvbG9neTogJ3RyaWFuZ2xlLWxpc3QnCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgbGFiZWw6IGAke2VmZmVjdC5uYW1lfSBQaXBlbGluZWAKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIAogICAgICAgICAgICAvLyBTdG9yZSBwaXBlbGluZQogICAgICAgICAgICB0aGlzLnN0YXRlLnBpcGVsaW5lcy5zZXQoZWZmZWN0LmlkLCBwaXBlbGluZSk7CiAgICAgICAgICAgIAogICAgICAgICAgICB0aGlzLmxvZygnaW5mbycsIGBQaXBlbGluZSBjcmVhdGVkIGZvciAke2VmZmVjdC5uYW1lfWApOwogICAgICAgICAgICAKICAgICAgICAgICAgcmV0dXJuIHBpcGVsaW5lOwogICAgICAgICAgICAKICAgICAgICB9IGNhdGNoIChlcnJvcikgewogICAgICAgICAgICB0aGlzLmxvZygnZXJyb3InLCBgRmFpbGVkIHRvIGNyZWF0ZSBwaXBlbGluZSBmb3IgJHtlZmZlY3QubmFtZX06YCwgZXJyb3IpOwogICAgICAgICAgICB0aHJvdyBlcnJvcjsKICAgICAgICB9CiAgICB9CiAgICAKICAgIC8qKgogICAgICogQ3JlYXRlIGludGVybWVkaWF0ZSB0ZXh0dXJlIGZvciBtdWx0aS1wYXNzIHJlbmRlcmluZwogICAgICogQHBhcmFtIHtudW1iZXJ9IHdpZHRoIC0gVGV4dHVyZSB3aWR0aAogICAgICogQHBhcmFtIHtudW1iZXJ9IGhlaWdodCAtIFRleHR1cmUgaGVpZ2h0CiAgICAgKi8KICAgIGNyZWF0ZUludGVybWVkaWF0ZVRleHR1cmUod2lkdGgsIGhlaWdodCkgewogICAgICAgIGlmICghdGhpcy5zdGF0ZS5pc0luaXRpYWxpemVkKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignUmVuZGVyZXIgbm90IGluaXRpYWxpemVkJyk7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIC8vIERlc3Ryb3kgZXhpc3RpbmcgdGV4dHVyZSBpZiByZXNpemluZwogICAgICAgIGlmICh0aGlzLnN0YXRlLm11bHRpcGFzcy5pbnRlcm1lZGlhdGVUZXh0dXJlKSB7CiAgICAgICAgICAgIHRoaXMuc3RhdGUubXVsdGlwYXNzLmludGVybWVkaWF0ZVRleHR1cmUuZGVzdHJveSgpOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAvLyBDcmVhdGUgdGV4dHVyZSBmb3Igc3RvcmluZyBmaXJzdCBwYXNzIChUViBzdGF0aWMpCiAgICAgICAgdGhpcy5zdGF0ZS5tdWx0aXBhc3MuaW50ZXJtZWRpYXRlVGV4dHVyZSA9IHRoaXMuc3RhdGUuZGV2aWNlLmNyZWF0ZVRleHR1cmUoewogICAgICAgICAgICBzaXplOiB7IHdpZHRoLCBoZWlnaHQgfSwKICAgICAgICAgICAgZm9ybWF0OiB0aGlzLnN0YXRlLmZvcm1hdCwKICAgICAgICAgICAgdXNhZ2U6IEdQVVRleHR1cmVVc2FnZS5SRU5ERVJfQVRUQUNITUVOVCB8IEdQVVRleHR1cmVVc2FnZS5URVhUVVJFX0JJTkRJTkcKICAgICAgICB9KTsKICAgICAgICAKICAgICAgICAvLyBDcmVhdGUgdGV4dHVyZSB2aWV3CiAgICAgICAgdGhpcy5zdGF0ZS5tdWx0aXBhc3MuaW50ZXJtZWRpYXRlVGV4dHVyZVZpZXcgPSB0aGlzLnN0YXRlLm11bHRpcGFzcy5pbnRlcm1lZGlhdGVUZXh0dXJlLmNyZWF0ZVZpZXcoKTsKICAgICAgICAKICAgICAgICAvLyBDcmVhdGUgc2FtcGxlciBvbmNlIChyZXVzZWQgYWNyb3NzIHJlc2l6ZXMpCiAgICAgICAgaWYgKCF0aGlzLnN0YXRlLm11bHRpcGFzcy5zYW1wbGVyKSB7CiAgICAgICAgICAgIHRoaXMuc3RhdGUubXVsdGlwYXNzLnNhbXBsZXIgPSB0aGlzLnN0YXRlLmRldmljZS5jcmVhdGVTYW1wbGVyKHsKICAgICAgICAgICAgICAgIG1hZ0ZpbHRlcjogJ2xpbmVhcicsCiAgICAgICAgICAgICAgICBtaW5GaWx0ZXI6ICdsaW5lYXInCiAgICAgICAgICAgIH0pOwogICAgICAgIH0KCiAgICAgICAgLy8gQ2FjaGUgdGhlIHRleHR1cmUgYmluZCBncm91cCDigJQgcmVidWlsdCBoZXJlIG9uIHJlc2l6ZSwgcmV1c2VkIGV2ZXJ5IGZyYW1lCiAgICAgICAgLy8gUmVxdWlyZXMgdGhlIHBpeGVsaXphdGlvbiBwaXBlbGluZSB0byBleGlzdDsgaWYgbm90IHlldCBjcmVhdGVkLCByZW5kZXJNdWx0aVBhc3MKICAgICAgICAvLyB3aWxsIGZhbGwgYmFjayB0byBidWlsZGluZyBpdCBvbiBmaXJzdCB1c2UuCiAgICAgICAgY29uc3QgcGl4ZWxpemF0aW9uUGlwZWxpbmUgPSB0aGlzLnN0YXRlLnBpcGVsaW5lcy5nZXQoMSk7CiAgICAgICAgaWYgKHBpeGVsaXphdGlvblBpcGVsaW5lKSB7CiAgICAgICAgICAgIHRoaXMuc3RhdGUubXVsdGlwYXNzLnRleHR1cmVCaW5kR3JvdXAgPSB0aGlzLnN0YXRlLmRldmljZS5jcmVhdGVCaW5kR3JvdXAoewogICAgICAgICAgICAgICAgbGF5b3V0OiBwaXhlbGl6YXRpb25QaXBlbGluZS5nZXRCaW5kR3JvdXBMYXlvdXQoMCksCiAgICAgICAgICAgICAgICBlbnRyaWVzOiBbCiAgICAgICAgICAgICAgICAgICAgeyBiaW5kaW5nOiAwLCByZXNvdXJjZTogdGhpcy5zdGF0ZS5tdWx0aXBhc3MuaW50ZXJtZWRpYXRlVGV4dHVyZVZpZXcgfSwKICAgICAgICAgICAgICAgICAgICB7IGJpbmRpbmc6IDEsIHJlc291cmNlOiB0aGlzLnN0YXRlLm11bHRpcGFzcy5zYW1wbGVyIH0KICAgICAgICAgICAgICAgIF0sCiAgICAgICAgICAgICAgICBsYWJlbDogJ0NhY2hlZCBUZXh0dXJlIEJpbmQgR3JvdXAnCiAgICAgICAgICAgIH0pOwogICAgICAgICAgICB0aGlzLmxvZygnZGVidWcnLCAnVGV4dHVyZSBiaW5kIGdyb3VwIGNhY2hlZCcpOwogICAgICAgIH0KCiAgICAgICAgdGhpcy5sb2coJ2luZm8nLCBgSW50ZXJtZWRpYXRlIHRleHR1cmUgY3JlYXRlZDogJHt3aWR0aH14JHtoZWlnaHR9YCk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogR2V0IHBpcGVsaW5lIGZvciBlZmZlY3QKICAgICAqIEBwYXJhbSB7bnVtYmVyfSBlZmZlY3RJZCAtIEVmZmVjdCBJRAogICAgICogQHJldHVybnMge0dQVVJlbmRlclBpcGVsaW5lfG51bGx9IFBpcGVsaW5lIG9yIG51bGwKICAgICAqLwogICAgZ2V0UGlwZWxpbmUoZWZmZWN0SWQpIHsKICAgICAgICByZXR1cm4gdGhpcy5zdGF0ZS5waXBlbGluZXMuZ2V0KGVmZmVjdElkKSB8fCBudWxsOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFNpbmdsZS1wYXNzIHJlbmRlcmluZzogRWZmZWN0IGRpcmVjdGx5IHRvIHNjcmVlbgogICAgICogQHBhcmFtIHtFZmZlY3R9IGVmZmVjdCAtIEVmZmVjdCB0byByZW5kZXIKICAgICAqIEBwYXJhbSB7bnVtYmVyfSB0aW1lc3RhbXAgLSBDdXJyZW50IHRpbWVzdGFtcAogICAgICogQHBhcmFtIHtudW1iZXJ9IHdpZHRoIC0gQ2FudmFzIHdpZHRoCiAgICAgKiBAcGFyYW0ge251bWJlcn0gaGVpZ2h0IC0gQ2FudmFzIGhlaWdodAogICAgICovCiAgICByZW5kZXJTaW5nbGVQYXNzKGVmZmVjdCwgdGltZXN0YW1wLCB3aWR0aCwgaGVpZ2h0KSB7CiAgICAgICAgY29uc3QgcGlwZWxpbmUgPSB0aGlzLmdldFBpcGVsaW5lKGVmZmVjdC5pZCk7CiAgICAgICAgaWYgKCFwaXBlbGluZSkgewogICAgICAgICAgICB0aGlzLmxvZygnd2FybicsIGBObyBwaXBlbGluZSBmb3IgZWZmZWN0ICR7ZWZmZWN0LmlkfWApOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIAogICAgICAgIC8vIFVwZGF0ZSBlZmZlY3QgdW5pZm9ybXMKICAgICAgICBjb25zdCBtYXBwZWRQYXJhbXMgPSBlZmZlY3QuZ2V0TWFwcGVkUGFyYW1ldGVycygpOwogICAgICAgIG1hcHBlZFBhcmFtcy5yZXNvbHV0aW9uWCA9IHdpZHRoOwogICAgICAgIG1hcHBlZFBhcmFtcy5yZXNvbHV0aW9uWSA9IGhlaWdodDsKICAgICAgICBlZmZlY3Qud3JpdGVVbmlmb3Jtcyh0aGlzLnN0YXRlLmRldmljZSwgbWFwcGVkUGFyYW1zKTsKICAgICAgICAKICAgICAgICAvLyBDcmVhdGUgY29tbWFuZCBlbmNvZGVyCiAgICAgICAgY29uc3QgY29tbWFuZEVuY29kZXIgPSB0aGlzLnN0YXRlLmRldmljZS5jcmVhdGVDb21tYW5kRW5jb2Rlcih7CiAgICAgICAgICAgIGxhYmVsOiAnU2luZ2xlIFBhc3MgQ29tbWFuZCBFbmNvZGVyJwogICAgICAgIH0pOwogICAgICAgIAogICAgICAgIC8vIEdldCBzY3JlZW4gdGV4dHVyZQogICAgICAgIGNvbnN0IHNjcmVlblZpZXcgPSB0aGlzLnN0YXRlLmNvbnRleHQuZ2V0Q3VycmVudFRleHR1cmUoKS5jcmVhdGVWaWV3KCk7CiAgICAgICAgCiAgICAgICAgLy8gUmVuZGVyIGVmZmVjdCB0byBzY3JlZW4KICAgICAgICBjb25zdCByZW5kZXJQYXNzID0gY29tbWFuZEVuY29kZXIuYmVnaW5SZW5kZXJQYXNzKHsKICAgICAgICAgICAgY29sb3JBdHRhY2htZW50czogW3sKICAgICAgICAgICAgICAgIHZpZXc6IHNjcmVlblZpZXcsCiAgICAgICAgICAgICAgICBjbGVhclZhbHVlOiB7IHI6IDAuMCwgZzogMC4wLCBiOiAwLjAsIGE6IDEuMCB9LAogICAgICAgICAgICAgICAgbG9hZE9wOiAnY2xlYXInLAogICAgICAgICAgICAgICAgc3RvcmVPcDogJ3N0b3JlJwogICAgICAgICAgICB9XSwKICAgICAgICAgICAgbGFiZWw6ICdFZmZlY3QgdG8gU2NyZWVuJwogICAgICAgIH0pOwogICAgICAgIAogICAgICAgIHJlbmRlclBhc3Muc2V0UGlwZWxpbmUocGlwZWxpbmUpOwogICAgICAgIHJlbmRlclBhc3Muc2V0QmluZEdyb3VwKDAsIGVmZmVjdC5nZXRCaW5kR3JvdXAoKSk7CiAgICAgICAgcmVuZGVyUGFzcy5kcmF3KDMpOwogICAgICAgIHJlbmRlclBhc3MuZW5kKCk7CiAgICAgICAgCiAgICAgICAgLy8gU3VibWl0CiAgICAgICAgdGhpcy5zdGF0ZS5kZXZpY2UucXVldWUuc3VibWl0KFtjb21tYW5kRW5jb2Rlci5maW5pc2goKV0pOwogICAgfQogICAgCiAgICAvKioKICAgICAqIE11bHRpLXBhc3MgcmVuZGVyaW5nOiBGaXJzdCBlZmZlY3Qg4oaSIFRleHR1cmUg4oaSIFNlY29uZCBlZmZlY3Qg4oaSIFNjcmVlbgogICAgICogQHBhcmFtIHtFZmZlY3R9IGZpcnN0RWZmZWN0IC0gRmlyc3QgZWZmZWN0IChlLmcuLCBUViBzdGF0aWMpCiAgICAgKiBAcGFyYW0ge0VmZmVjdH0gc2Vjb25kRWZmZWN0IC0gU2Vjb25kIGVmZmVjdCAoZS5nLiwgcGl4ZWxpemF0aW9uKQogICAgICogQHBhcmFtIHtudW1iZXJ9IHRpbWVzdGFtcCAtIEN1cnJlbnQgdGltZXN0YW1wCiAgICAgKiBAcGFyYW0ge251bWJlcn0gd2lkdGggLSBDYW52YXMgd2lkdGgKICAgICAqIEBwYXJhbSB7bnVtYmVyfSBoZWlnaHQgLSBDYW52YXMgaGVpZ2h0CiAgICAgKi8KICAgIHJlbmRlck11bHRpUGFzcyhmaXJzdEVmZmVjdCwgc2Vjb25kRWZmZWN0LCB0aW1lc3RhbXAsIHdpZHRoLCBoZWlnaHQpIHsKICAgICAgICBjb25zdCBmaXJzdFBpcGVsaW5lID0gdGhpcy5nZXRQaXBlbGluZShmaXJzdEVmZmVjdC5pZCk7CiAgICAgICAgY29uc3Qgc2Vjb25kUGlwZWxpbmUgPSB0aGlzLmdldFBpcGVsaW5lKHNlY29uZEVmZmVjdC5pZCk7CiAgICAgICAgCiAgICAgICAgaWYgKCFmaXJzdFBpcGVsaW5lIHx8ICFzZWNvbmRQaXBlbGluZSkgewogICAgICAgICAgICB0aGlzLmxvZygnd2FybicsICdNaXNzaW5nIHBpcGVsaW5lIGZvciBtdWx0aS1wYXNzIHJlbmRlcmluZycpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIAogICAgICAgIC8vIFVwZGF0ZSBmaXJzdCBlZmZlY3QgdW5pZm9ybXMKICAgICAgICBjb25zdCBmaXJzdFBhcmFtcyA9IGZpcnN0RWZmZWN0LmdldE1hcHBlZFBhcmFtZXRlcnMoKTsKICAgICAgICBmaXJzdFBhcmFtcy5yZXNvbHV0aW9uWCA9IHdpZHRoOwogICAgICAgIGZpcnN0UGFyYW1zLnJlc29sdXRpb25ZID0gaGVpZ2h0OwogICAgICAgIGZpcnN0RWZmZWN0LndyaXRlVW5pZm9ybXModGhpcy5zdGF0ZS5kZXZpY2UsIGZpcnN0UGFyYW1zKTsKICAgICAgICAKICAgICAgICAvLyBVcGRhdGUgc2Vjb25kIGVmZmVjdCB1bmlmb3JtcwogICAgICAgIGNvbnN0IHNlY29uZFBhcmFtcyA9IHNlY29uZEVmZmVjdC5nZXRNYXBwZWRQYXJhbWV0ZXJzKCk7CiAgICAgICAgaWYgKHNlY29uZEVmZmVjdC51cGRhdGVDYW52YXNEaW1lbnNpb25zKSB7CiAgICAgICAgICAgIHNlY29uZEVmZmVjdC51cGRhdGVDYW52YXNEaW1lbnNpb25zKHdpZHRoLCBoZWlnaHQpOwogICAgICAgIH0KICAgICAgICBzZWNvbmRFZmZlY3Qud3JpdGVVbmlmb3Jtcyh0aGlzLnN0YXRlLmRldmljZSwgc2Vjb25kUGFyYW1zKTsKICAgICAgICAKICAgICAgICAvLyBDcmVhdGUgY29tbWFuZCBlbmNvZGVyCiAgICAgICAgY29uc3QgY29tbWFuZEVuY29kZXIgPSB0aGlzLnN0YXRlLmRldmljZS5jcmVhdGVDb21tYW5kRW5jb2Rlcih7CiAgICAgICAgICAgIGxhYmVsOiAnTXVsdGkgUGFzcyBDb21tYW5kIEVuY29kZXInCiAgICAgICAgfSk7CiAgICAgICAgCiAgICAgICAgLy8gUEFTUyAxOiBSZW5kZXIgZmlyc3QgZWZmZWN0IHRvIGludGVybWVkaWF0ZSB0ZXh0dXJlCiAgICAgICAgY29uc3QgcGFzczEgPSBjb21tYW5kRW5jb2Rlci5iZWdpblJlbmRlclBhc3MoewogICAgICAgICAgICBjb2xvckF0dGFjaG1lbnRzOiBbewogICAgICAgICAgICAgICAgdmlldzogdGhpcy5zdGF0ZS5tdWx0aXBhc3MuaW50ZXJtZWRpYXRlVGV4dHVyZVZpZXcsCiAgICAgICAgICAgICAgICBjbGVhclZhbHVlOiB7IHI6IDAuMCwgZzogMC4wLCBiOiAwLjAsIGE6IDEuMCB9LAogICAgICAgICAgICAgICAgbG9hZE9wOiAnY2xlYXInLAogICAgICAgICAgICAgICAgc3RvcmVPcDogJ3N0b3JlJwogICAgICAgICAgICB9XSwKICAgICAgICAgICAgbGFiZWw6ICdQYXNzIDE6IEZpcnN0IEVmZmVjdCB0byBUZXh0dXJlJwogICAgICAgIH0pOwogICAgICAgIAogICAgICAgIHBhc3MxLnNldFBpcGVsaW5lKGZpcnN0UGlwZWxpbmUpOwogICAgICAgIHBhc3MxLnNldEJpbmRHcm91cCgwLCBmaXJzdEVmZmVjdC5nZXRCaW5kR3JvdXAoKSk7CiAgICAgICAgcGFzczEuZHJhdygzKTsKICAgICAgICBwYXNzMS5lbmQoKTsKICAgICAgICAKICAgICAgICAvLyBQQVNTIDI6IFJlbmRlciBzZWNvbmQgZWZmZWN0ICh3aXRoIHRleHR1cmUgaW5wdXQpIHRvIHNjcmVlbgogICAgICAgIGNvbnN0IHNjcmVlblZpZXcgPSB0aGlzLnN0YXRlLmNvbnRleHQuZ2V0Q3VycmVudFRleHR1cmUoKS5jcmVhdGVWaWV3KCk7CiAgICAgICAgCiAgICAgICAgY29uc3QgcGFzczIgPSBjb21tYW5kRW5jb2Rlci5iZWdpblJlbmRlclBhc3MoewogICAgICAgICAgICBjb2xvckF0dGFjaG1lbnRzOiBbewogICAgICAgICAgICAgICAgdmlldzogc2NyZWVuVmlldywKICAgICAgICAgICAgICAgIGNsZWFyVmFsdWU6IHsgcjogMC4wLCBnOiAwLjAsIGI6IDAuMCwgYTogMS4wIH0sCiAgICAgICAgICAgICAgICBsb2FkT3A6ICdjbGVhcicsCiAgICAgICAgICAgICAgICBzdG9yZU9wOiAnc3RvcmUnCiAgICAgICAgICAgIH1dLAogICAgICAgICAgICBsYWJlbDogJ1Bhc3MgMjogU2Vjb25kIEVmZmVjdCB0byBTY3JlZW4nCiAgICAgICAgfSk7CiAgICAgICAgCiAgICAgICAgcGFzczIuc2V0UGlwZWxpbmUoc2Vjb25kUGlwZWxpbmUpOwoKICAgICAgICAvLyBVc2UgY2FjaGVkIGJpbmQgZ3JvdXAg4oCUIGNyZWF0ZWQgb25jZSBpbiBjcmVhdGVJbnRlcm1lZGlhdGVUZXh0dXJlKCksIHJlYnVpbHQgb24gcmVzaXplCiAgICAgICAgLy8gRmFsbCBiYWNrIHRvIGJ1aWxkaW5nIGl0IGhlcmUgb25seSBvbiB0aGUgdmVyeSBmaXJzdCBmcmFtZSAocGlwZWxpbmUgY3JlYXRlZCBhZnRlciB0ZXh0dXJlKQogICAgICAgIGlmICghdGhpcy5zdGF0ZS5tdWx0aXBhc3MudGV4dHVyZUJpbmRHcm91cCkgewogICAgICAgICAgICB0aGlzLnN0YXRlLm11bHRpcGFzcy50ZXh0dXJlQmluZEdyb3VwID0gdGhpcy5zdGF0ZS5kZXZpY2UuY3JlYXRlQmluZEdyb3VwKHsKICAgICAgICAgICAgICAgIGxheW91dDogc2Vjb25kUGlwZWxpbmUuZ2V0QmluZEdyb3VwTGF5b3V0KDApLAogICAgICAgICAgICAgICAgZW50cmllczogWwogICAgICAgICAgICAgICAgICAgIHsgYmluZGluZzogMCwgcmVzb3VyY2U6IHRoaXMuc3RhdGUubXVsdGlwYXNzLmludGVybWVkaWF0ZVRleHR1cmVWaWV3IH0sCiAgICAgICAgICAgICAgICAgICAgeyBiaW5kaW5nOiAxLCByZXNvdXJjZTogdGhpcy5zdGF0ZS5tdWx0aXBhc3Muc2FtcGxlciB9CiAgICAgICAgICAgICAgICBdLAogICAgICAgICAgICAgICAgbGFiZWw6ICdDYWNoZWQgVGV4dHVyZSBCaW5kIEdyb3VwJwogICAgICAgICAgICB9KTsKICAgICAgICAgICAgdGhpcy5sb2coJ2RlYnVnJywgJ1RleHR1cmUgYmluZCBncm91cCBidWlsdCBvbiBmaXJzdCByZW5kZXIgKHBpcGVsaW5lIHdhcyBub3QgcmVhZHkgYXQgdGV4dHVyZSBjcmVhdGlvbiknKTsKICAgICAgICB9CgogICAgICAgIHBhc3MyLnNldEJpbmRHcm91cCgwLCB0aGlzLnN0YXRlLm11bHRpcGFzcy50ZXh0dXJlQmluZEdyb3VwKTsKICAgICAgICBwYXNzMi5zZXRCaW5kR3JvdXAoMSwgc2Vjb25kRWZmZWN0LmdldEJpbmRHcm91cCgpKTsKICAgICAgICBwYXNzMi5kcmF3KDMpOwogICAgICAgIHBhc3MyLmVuZCgpOwogICAgICAgIAogICAgICAgIC8vIFN1Ym1pdCBib3RoIHBhc3NlcwogICAgICAgIHRoaXMuc3RhdGUuZGV2aWNlLnF1ZXVlLnN1Ym1pdChbY29tbWFuZEVuY29kZXIuZmluaXNoKCldKTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBIYW5kbGUgY2FudmFzIHJlc2l6ZQogICAgICogQHBhcmFtIHtudW1iZXJ9IHdpZHRoIC0gTmV3IHdpZHRoCiAgICAgKiBAcGFyYW0ge251bWJlcn0gaGVpZ2h0IC0gTmV3IGhlaWdodAogICAgICovCiAgICByZXNpemUod2lkdGgsIGhlaWdodCkgewogICAgICAgIGlmICghdGhpcy5zdGF0ZS5pc0luaXRpYWxpemVkKSByZXR1cm47CiAgICAgICAgCiAgICAgICAgLy8gUmVjcmVhdGUgaW50ZXJtZWRpYXRlIHRleHR1cmUgd2l0aCBuZXcgc2l6ZQogICAgICAgIHRoaXMuY3JlYXRlSW50ZXJtZWRpYXRlVGV4dHVyZSh3aWR0aCwgaGVpZ2h0KTsKICAgICAgICAKICAgICAgICB0aGlzLmxvZygnZGVidWcnLCBgUmVzaXplZCB0byAke3dpZHRofXgke2hlaWdodH1gKTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBHZXQgcmVuZGVyZXIgc3RhdGUgZm9yIGRlYnVnZ2luZwogICAgICogQHJldHVybnMge09iamVjdH0gQ3VycmVudCBzdGF0ZQogICAgICovCiAgICBnZXRTdGF0ZSgpIHsKICAgICAgICByZXR1cm4gewogICAgICAgICAgICAuLi5zdXBlci5nZXRTdGF0ZSgpLAogICAgICAgICAgICBmb3JtYXQ6IHRoaXMuc3RhdGUuZm9ybWF0LAogICAgICAgICAgICBwaXBlbGluZXNDcmVhdGVkOiB0aGlzLnN0YXRlLnBpcGVsaW5lcy5zaXplLAogICAgICAgICAgICBlZmZlY3RzUmVnaXN0ZXJlZDogdGhpcy5zdGF0ZS5lZmZlY3RzLnNpemUsCiAgICAgICAgICAgIGhhc0ludGVybWVkaWF0ZVRleHR1cmU6IHRoaXMuc3RhdGUubXVsdGlwYXNzLmludGVybWVkaWF0ZVRleHR1cmUgIT09IG51bGwKICAgICAgICB9OwogICAgfQogICAgCiAgICAvKioKICAgICAqIENsZWFuIHVwIFdlYkdQVSByZXNvdXJjZXMKICAgICAqLwogICAgZGVzdHJveSgpIHsKICAgICAgICB0aGlzLmxvZygnaW5mbycsICdEZXN0cm95aW5nIFdlYkdQVSByZW5kZXJlci4uLicpOwogICAgICAgIAogICAgICAgIC8vIERlc3Ryb3kgaW50ZXJtZWRpYXRlIHRleHR1cmUKICAgICAgICBpZiAodGhpcy5zdGF0ZS5tdWx0aXBhc3MuaW50ZXJtZWRpYXRlVGV4dHVyZSkgewogICAgICAgICAgICB0aGlzLnN0YXRlLm11bHRpcGFzcy5pbnRlcm1lZGlhdGVUZXh0dXJlLmRlc3Ryb3koKTsKICAgICAgICAgICAgdGhpcy5zdGF0ZS5tdWx0aXBhc3MuaW50ZXJtZWRpYXRlVGV4dHVyZSA9IG51bGw7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIC8vIERlc3Ryb3kgZGV2aWNlCiAgICAgICAgaWYgKHRoaXMuc3RhdGUuZGV2aWNlKSB7CiAgICAgICAgICAgIHRoaXMuc3RhdGUuZGV2aWNlLmRlc3Ryb3koKTsKICAgICAgICAgICAgdGhpcy5zdGF0ZS5kZXZpY2UgPSBudWxsOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAvLyBDbGVhciBzdGF0ZQogICAgICAgIHRoaXMuc3RhdGUucGlwZWxpbmVzLmNsZWFyKCk7CiAgICAgICAgdGhpcy5zdGF0ZS5lZmZlY3RzLmNsZWFyKCk7CiAgICAgICAgdGhpcy5zdGF0ZS5pc0luaXRpYWxpemVkID0gZmFsc2U7CiAgICAgICAgCiAgICAgICAgdGhpcy5sb2coJ2luZm8nLCAnV2ViR1BVIHJlbmRlcmVyIGRlc3Ryb3llZCcpOwogICAgfQp9CgpXZWJHUFVSZW5kZXJlcjsKCgovLyBXZWJHTFJlbmRlcmVyLmpzIC0gV2ViR0wgMi4wIHJlbmRlcmluZyBpbXBsZW1lbnRhdGlvbgovLyBGYWxsYmFjayByZW5kZXJlciBmb3IgYnJvd3NlcnMgd2l0aG91dCBXZWJHUFUgc3VwcG9ydAovLyBJbXBsZW1lbnRzIElSZW5kZXJlciBpbnRlcmZhY2UgZm9yIHJlbmRlcmVyIGFic3RyYWN0aW9uCgpjbGFzcyBXZWJHTFJlbmRlcmVyIGV4dGVuZHMgSVJlbmRlcmVyIHsKICAgIGNvbnN0cnVjdG9yKCkgewogICAgICAgIHN1cGVyKCd3ZWJnbCcpOwogICAgICAgIAogICAgICAgIHRoaXMuc3RhdGUgPSB7CiAgICAgICAgICAgIC4uLnRoaXMuc3RhdGUsICAvLyBJbmhlcml0IGZyb20gSVJlbmRlcmVyCiAgICAgICAgICAgIAogICAgICAgICAgICAvLyBXZWJHTCByZXNvdXJjZXMKICAgICAgICAgICAgZ2w6IG51bGwsCiAgICAgICAgICAgIAogICAgICAgICAgICAvLyBQcm9ncmFtcyAoZXF1aXZhbGVudCB0byBwaXBlbGluZXMpCiAgICAgICAgICAgIHByb2dyYW1zOiBuZXcgTWFwKCksICAvLyBlZmZlY3RJZCDihpIgV2ViR0xQcm9ncmFtCiAgICAgICAgICAgIHByb2dyYW1JbmZvOiBuZXcgTWFwKCksICAvLyBlZmZlY3RJZCDihpIge3Byb2dyYW0sIHVuaWZvcm1Mb2NhdGlvbnMsIGF0dHJpYkxvY2F0aW9uc30KICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIE11bHRpLXBhc3MgcmVuZGVyaW5nCiAgICAgICAgICAgIG11bHRpcGFzczogewogICAgICAgICAgICAgICAgZnJhbWVidWZmZXI6IG51bGwsCiAgICAgICAgICAgICAgICB0ZXh0dXJlOiBudWxsLAogICAgICAgICAgICAgICAgd2lkdGg6IDAsCiAgICAgICAgICAgICAgICBoZWlnaHQ6IDAKICAgICAgICAgICAgfSwKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIEZ1bGxzY3JlZW4gcXVhZCAoZm9yIHJlbmRlcmluZykKICAgICAgICAgICAgcXVhZDogewogICAgICAgICAgICAgICAgdmFvOiBudWxsLAogICAgICAgICAgICAgICAgdmVydGV4QnVmZmVyOiBudWxsCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIAogICAgICAgICAgICAvLyBSZWdpc3RlcmVkIGVmZmVjdHMKICAgICAgICAgICAgZWZmZWN0czogbmV3IE1hcCgpICAvLyBlZmZlY3RJZCDihpIgRWZmZWN0IGluc3RhbmNlCiAgICAgICAgfTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBJbml0aWFsaXplIFdlYkdMIDIuMAogICAgICogQHBhcmFtIHtIVE1MQ2FudmFzRWxlbWVudH0gY2FudmFzIC0gVGFyZ2V0IGNhbnZhcwogICAgICogQHJldHVybnMge1Byb21pc2U8Ym9vbGVhbj59IFRydWUgaWYgc3VjY2Vzc2Z1bAogICAgICovCiAgICBhc3luYyBpbml0aWFsaXplKGNhbnZhcykgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHRoaXMuc3RhdGUuY2FudmFzID0gY2FudmFzOwogICAgICAgICAgICB0aGlzLmxvZygnaW5mbycsICdJbml0aWFsaXppbmcgV2ViR0wgMi4wLi4uJyk7CiAgICAgICAgICAgIAogICAgICAgICAgICAvLyBDaGVjayBjYW52YXMgdmFsaWRpdHkKICAgICAgICAgICAgaWYgKCFjYW52YXMgfHwgIShjYW52YXMgaW5zdGFuY2VvZiBIVE1MQ2FudmFzRWxlbWVudCkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBjYW52YXMgZWxlbWVudCBwcm92aWRlZCcpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICAvLyBHZXQgV2ViR0wyIGNvbnRleHQKICAgICAgICAgICAgY29uc3QgZ2wgPSBjYW52YXMuZ2V0Q29udGV4dCgnd2ViZ2wyJywgewogICAgICAgICAgICAgICAgYWxwaGE6IGZhbHNlLAogICAgICAgICAgICAgICAgZGVwdGg6IGZhbHNlLAogICAgICAgICAgICAgICAgc3RlbmNpbDogZmFsc2UsCiAgICAgICAgICAgICAgICBhbnRpYWxpYXM6IGZhbHNlLAogICAgICAgICAgICAgICAgcHJlbXVsdGlwbGllZEFscGhhOiBmYWxzZQogICAgICAgICAgICB9KTsKICAgICAgICAgICAgCiAgICAgICAgICAgIGlmICghZ2wpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignRmFpbGVkIHRvIGdldCBXZWJHTCAyLjAgY29udGV4dCcpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICB0aGlzLnN0YXRlLmdsID0gZ2w7CiAgICAgICAgICAgIHRoaXMubG9nKCdpbmZvJywgJ1dlYkdMIDIuMCBjb250ZXh0IGFjcXVpcmVkJyk7CiAgICAgICAgICAgIAogICAgICAgICAgICAvLyBTZXR1cCBXZWJHTCBzdGF0ZQogICAgICAgICAgICBnbC52aWV3cG9ydCgwLCAwLCBjYW52YXMud2lkdGgsIGNhbnZhcy5oZWlnaHQpOwogICAgICAgICAgICBnbC5jbGVhckNvbG9yKDAuMCwgMC4wLCAwLjAsIDEuMCk7CiAgICAgICAgICAgIAogICAgICAgICAgICAvLyBEaXNhYmxlIGRlcHRoIHRlc3QgKHdlJ3JlIGRvaW5nIDJEIHJlbmRlcmluZykKICAgICAgICAgICAgZ2wuZGlzYWJsZShnbC5ERVBUSF9URVNUKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIEVuYWJsZSBibGVuZGluZyBmb3IgdHJhbnNwYXJlbnQgZWZmZWN0cwogICAgICAgICAgICBnbC5lbmFibGUoZ2wuQkxFTkQpOwogICAgICAgICAgICBnbC5ibGVuZEZ1bmMoZ2wuU1JDX0FMUEhBLCBnbC5PTkVfTUlOVVNfU1JDX0FMUEhBKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIENyZWF0ZSBmdWxsc2NyZWVuIHF1YWQgZm9yIHJlbmRlcmluZwogICAgICAgICAgICB0aGlzLmNyZWF0ZUZ1bGxzY3JlZW5RdWFkKCk7CiAgICAgICAgICAgIAogICAgICAgICAgICB0aGlzLnN0YXRlLmlzSW5pdGlhbGl6ZWQgPSB0cnVlOwogICAgICAgICAgICB0aGlzLmxvZygnaW5mbycsICdXZWJHTCAyLjAgaW5pdGlhbGl6ZWQgc3VjY2Vzc2Z1bGx5Jyk7CiAgICAgICAgICAgIAogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgCiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHsKICAgICAgICAgICAgdGhpcy5sb2coJ2Vycm9yJywgJ0ZhaWxlZCB0byBpbml0aWFsaXplIFdlYkdMIDIuMDonLCBlcnJvcik7CiAgICAgICAgICAgIHRocm93IGVycm9yOwogICAgICAgIH0KICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBDcmVhdGUgZnVsbHNjcmVlbiBxdWFkIGdlb21ldHJ5CiAgICAgKi8KICAgIGNyZWF0ZUZ1bGxzY3JlZW5RdWFkKCkgewogICAgICAgIGNvbnN0IGdsID0gdGhpcy5zdGF0ZS5nbDsKICAgICAgICAKICAgICAgICAvLyBDcmVhdGUgVkFPCiAgICAgICAgdGhpcy5zdGF0ZS5xdWFkLnZhbyA9IGdsLmNyZWF0ZVZlcnRleEFycmF5KCk7CiAgICAgICAgZ2wuYmluZFZlcnRleEFycmF5KHRoaXMuc3RhdGUucXVhZC52YW8pOwogICAgICAgIAogICAgICAgIC8vIEZ1bGxzY3JlZW4gdHJpYW5nbGUgKG1vcmUgZWZmaWNpZW50IHRoYW4gcXVhZCkKICAgICAgICAvLyBVc2VzIHZlcnRleCBJRCBpbiBzaGFkZXIgdG8gZ2VuZXJhdGUgcG9zaXRpb25zCiAgICAgICAgLy8gTm8gdmVydGV4IGRhdGEgbmVlZGVkIQogICAgICAgIAogICAgICAgIGdsLmJpbmRWZXJ0ZXhBcnJheShudWxsKTsKICAgICAgICAKICAgICAgICB0aGlzLmxvZygnZGVidWcnLCAnRnVsbHNjcmVlbiBxdWFkIGNyZWF0ZWQnKTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZWdpc3RlciBhbiBlZmZlY3QgKGNyZWF0ZSBHUFUgcmVzb3VyY2VzKQogICAgICogQHBhcmFtIHtFZmZlY3R9IGVmZmVjdCAtIEVmZmVjdCBpbnN0YW5jZQogICAgICovCiAgICBhc3luYyByZWdpc3RlckVmZmVjdChlZmZlY3QpIHsKICAgICAgICBpZiAoIXRoaXMuc3RhdGUuaXNJbml0aWFsaXplZCkgewogICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1JlbmRlcmVyIG5vdCBpbml0aWFsaXplZCcpOwogICAgICAgIH0KICAgICAgICAKICAgICAgICB0cnkgewogICAgICAgICAgICAvLyBTdG9yZSBlZmZlY3QgcmVmZXJlbmNlCiAgICAgICAgICAgIHRoaXMuc3RhdGUuZWZmZWN0cy5zZXQoZWZmZWN0LmlkLCBlZmZlY3QpOwogICAgICAgICAgICAKICAgICAgICAgICAgdGhpcy5sb2coJ2RlYnVnJywgYEVmZmVjdCByZWdpc3RlcmVkOiAke2VmZmVjdC5uYW1lfSAoSUQ6ICR7ZWZmZWN0LmlkfSlgKTsKICAgICAgICAgICAgCiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHsKICAgICAgICAgICAgdGhpcy5sb2coJ2Vycm9yJywgYEZhaWxlZCB0byByZWdpc3RlciBlZmZlY3QgJHtlZmZlY3QubmFtZX06YCwgZXJyb3IpOwogICAgICAgICAgICB0aHJvdyBlcnJvcjsKICAgICAgICB9CiAgICB9CiAgICAKICAgIC8qKgogICAgICogQ3JlYXRlIFdlYkdMIHByb2dyYW0gKHBpcGVsaW5lKSBmb3IgYW4gZWZmZWN0CiAgICAgKiBAcGFyYW0ge0VmZmVjdH0gZWZmZWN0IC0gRWZmZWN0IHRvIGNyZWF0ZSBwcm9ncmFtIGZvcgogICAgICogQHBhcmFtIHtib29sZWFufSBuZWVkc1RleHR1cmVJbnB1dCAtIFdoZXRoZXIgZWZmZWN0IG5lZWRzIHRleHR1cmUgaW5wdXQKICAgICAqIEByZXR1cm5zIHtQcm9taXNlPFdlYkdMUHJvZ3JhbT59IENyZWF0ZWQgcHJvZ3JhbQogICAgICovCiAgICBhc3luYyBjcmVhdGVQaXBlbGluZShlZmZlY3QsIG5lZWRzVGV4dHVyZUlucHV0ID0gZmFsc2UpIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBjb25zdCBnbCA9IHRoaXMuc3RhdGUuZ2w7CiAgICAgICAgICAgIHRoaXMubG9nKCdkZWJ1ZycsIGBDcmVhdGluZyBXZWJHTCBwcm9ncmFtIGZvciAke2VmZmVjdC5uYW1lfWApOwogICAgICAgICAgICAKICAgICAgICAgICAgLy8gVXNlIGVtYmVkZGVkIHNoYWRlcnMKICAgICAgICAgICAgY29uc3QgdmVydGV4Q29kZSA9IFdFQkdMX1NIQURFUlMudmVydGV4X2Z1bGxzY3JlZW47CiAgICAgICAgICAgIGNvbnN0IGZyYWdtZW50Q29kZSA9IGVmZmVjdC5pZCA9PT0gMCA/IFdFQkdMX1NIQURFUlMudHZfc3RhdGljIDogV0VCR0xfU0hBREVSUy5waXhlbGl6YXRpb247CiAgICAgICAgICAgIAogICAgICAgICAgICAvLyBDb21waWxlIHNoYWRlcnMKICAgICAgICAgICAgY29uc3QgdmVydGV4U2hhZGVyID0gdGhpcy5jb21waWxlU2hhZGVyKGdsLCBnbC5WRVJURVhfU0hBREVSLCB2ZXJ0ZXhDb2RlLCBgJHtlZmZlY3QubmFtZX0gVmVydGV4YCk7CiAgICAgICAgICAgIGNvbnN0IGZyYWdtZW50U2hhZGVyID0gdGhpcy5jb21waWxlU2hhZGVyKGdsLCBnbC5GUkFHTUVOVF9TSEFERVIsIGZyYWdtZW50Q29kZSwgYCR7ZWZmZWN0Lm5hbWV9IEZyYWdtZW50YCk7CiAgICAgICAgICAgIAogICAgICAgICAgICAvLyBDcmVhdGUgcHJvZ3JhbQogICAgICAgICAgICBjb25zdCBwcm9ncmFtID0gZ2wuY3JlYXRlUHJvZ3JhbSgpOwogICAgICAgICAgICBnbC5hdHRhY2hTaGFkZXIocHJvZ3JhbSwgdmVydGV4U2hhZGVyKTsKICAgICAgICAgICAgZ2wuYXR0YWNoU2hhZGVyKHByb2dyYW0sIGZyYWdtZW50U2hhZGVyKTsKICAgICAgICAgICAgZ2wubGlua1Byb2dyYW0ocHJvZ3JhbSk7CiAgICAgICAgICAgIAogICAgICAgICAgICAvLyBDaGVjayBsaW5rIHN0YXR1cwogICAgICAgICAgICBpZiAoIWdsLmdldFByb2dyYW1QYXJhbWV0ZXIocHJvZ3JhbSwgZ2wuTElOS19TVEFUVVMpKSB7CiAgICAgICAgICAgICAgICBjb25zdCBpbmZvID0gZ2wuZ2V0UHJvZ3JhbUluZm9Mb2cocHJvZ3JhbSk7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFByb2dyYW0gbGluayBmYWlsZWQ6ICR7aW5mb31gKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgLy8gR2V0IHVuaWZvcm0gbG9jYXRpb25zCiAgICAgICAgICAgIGNvbnN0IHVuaWZvcm1Mb2NhdGlvbnMgPSB0aGlzLmdldFVuaWZvcm1Mb2NhdGlvbnMoZ2wsIHByb2dyYW0sIGVmZmVjdCwgbmVlZHNUZXh0dXJlSW5wdXQpOwogICAgICAgICAgICAKICAgICAgICAgICAgLy8gU3RvcmUgcHJvZ3JhbSBpbmZvCiAgICAgICAgICAgIGNvbnN0IHByb2dyYW1JbmZvID0gewogICAgICAgICAgICAgICAgcHJvZ3JhbSwKICAgICAgICAgICAgICAgIHVuaWZvcm1Mb2NhdGlvbnMsCiAgICAgICAgICAgICAgICBuZWVkc1RleHR1cmVJbnB1dAogICAgICAgICAgICB9OwogICAgICAgICAgICAKICAgICAgICAgICAgdGhpcy5zdGF0ZS5wcm9ncmFtcy5zZXQoZWZmZWN0LmlkLCBwcm9ncmFtKTsKICAgICAgICAgICAgdGhpcy5zdGF0ZS5wcm9ncmFtSW5mby5zZXQoZWZmZWN0LmlkLCBwcm9ncmFtSW5mbyk7CiAgICAgICAgICAgIAogICAgICAgICAgICB0aGlzLmxvZygnaW5mbycsIGBXZWJHTCBwcm9ncmFtIGNyZWF0ZWQgZm9yICR7ZWZmZWN0Lm5hbWV9YCk7CiAgICAgICAgICAgIAogICAgICAgICAgICByZXR1cm4gcHJvZ3JhbTsKICAgICAgICAgICAgCiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHsKICAgICAgICAgICAgdGhpcy5sb2coJ2Vycm9yJywgYEZhaWxlZCB0byBjcmVhdGUgcHJvZ3JhbSBmb3IgJHtlZmZlY3QubmFtZX06YCwgZ