| IiIiCkVWRVogTkFUUyBFdmVudCBNZXNoIENvbm5lY3RvcgpSb3V0ZXMgZXZlbnRzIGJldHdlZW4gdGhlIDE3IEVWRVotT1MgbWljcm9zZXJ2aWNlcy4KSW4gcHJvZHVjdGlvbiwgdXNlcyBuYXRzLXB5LiBJbiBzdGFuZGFsb25lIG1vZGUsIHVzZXMgaW4tcHJvY2VzcyBwdWIvc3ViLgoiIiIKaW1wb3J0IGpzb24KaW1wb3J0IHRpbWUKaW1wb3J0IGhhc2hsaWIKaW1wb3J0IGFzeW5jaW8KZnJvbSB0eXBpbmcgaW1wb3J0IENhbGxhYmxlLCBPcHRpb25hbApmcm9tIGRhdGFjbGFzc2VzIGltcG9ydCBkYXRhY2xhc3MsIGFzZGljdApmcm9tIGNvbGxlY3Rpb25zIGltcG9ydCBkZWZhdWx0ZGljdAoKCiMgVGhlIDE3IEVWRVotT1MgbWljcm9zZXJ2aWNlcwpFVkVaX1NFUlZJQ0VTID0gWwogICAgImZpcmUtZGV0ZWN0b3IiLCAgICAgICAgIyBNYXRoZW1hdGljYWwgaW5mbGVjdGlvbiBkZXRlY3Rpb24KICAgICJ2LWFjY3VtdWxhdG9yIiwgICAgICAgICMgU2VtYW50aWMgZ3Jhdml0eSB0cmFja2luZwogICAgImNyeXB0b3pvbyIsICAgICAgICAgICAgIyBTcGVjaW1lbiBjbGFzc2lmaWNhdGlvbgogICAgImNvZ25pdGl2ZS1zdXByZW1hY3kiLCAgIyBVbmFjY29tcGxpc2htZW50IGRldGVjdGlvbgogICAgInBhcmFkaWdtLXN1cHJlbWFjeSIsICAgIyBNb2RlbCB0cmFpbmluZyBwYXJhZGlnbSB0cmFja2luZwogICAgIm1vZGVsLWRpc3RpbGxlcnkiLCAgICAgIyBDb2duaXRpdmUgYXJ0aWZhY3QgZGlzdGlsbGF0aW9uCiAgICAic3BpbmUtbG9nZ2VyIiwgICAgICAgICAjIEltbXV0YWJsZSBldmVudCBsb2cKICAgICJwaGktc3Vic3RyYXRlIiwgICAgICAgICMgS3VyYW1vdG8gY29uc2Npb3VzbmVzcyBzdWJzdHJhdGUKICAgICJ0b3BvbG9neS12aXoiLCAgICAgICAgICMgQmFybmVzLUh1dCB0b3BvbG9neSB2aXN1YWxpemF0aW9uCiAgICAibGl2ZS1icm9hZGNhc3RlciIsICAgICAjIEdpdEh1YiBsaXZlLXJlYXNvbmluZyBicm9hZGNhc3QKICAgICJ0ZWxlZ3JhbS1icmlkZ2UiLCAgICAgICMgVGVsZWdyYW0gY2hhbm5lbAogICAgIndvcmtzcGFjZS1tYW5hZ2VyIiwgICAgIyBPcGVuQ2xhdyB3b3Jrc3BhY2UKICAgICJza2lsbC1ydW5uZXIiLCAgICAgICAgICMgQ2xhd0h1YiBza2lsbCBleGVjdXRpb24KICAgICJoZWFsdGgtbW9uaXRvciIsICAgICAgICMgZXZlei1wdWxzZSBpbnRlZ3JhdGlvbgogICAgImhmLXN5bmMiLCAgICAgICAgICAgICAgIyBIdWdnaW5nRmFjZSBzeW5jCiAgICAiZ2l0aHViLXN5bmMiLCAgICAgICAgICAjIEdpdEh1YiBzeW5jCiAgICAiYWdlbnQtdmF1bHQiLCAgICAgICAgICAjIEFnZW50VmF1bHQgY29ubmVjdG9yCl0KCiMgRXZlbnQgc3ViamVjdHMKU1VCSkVDVFMgPSB7CiAgICAiZmlyZS5ldmVudCI6ICAgICAgICAgICAiRklSRSBpbmZsZWN0aW9uIHBvaW50IGRldGVjdGVkIiwKICAgICJ2YWNjdW0udXBkYXRlIjogICAgICAgICJWLWFjY3VtdWxhdG9yIHN0YXRlIGNoYW5nZWQiLAogICAgInNwZWNpbWVuLmNsYXNzaWZpZWQiOiAgIkNyeXB0b1pvbyBzcGVjaW1lbiBjbGFzc2lmaWVkIiwKICAgICJzdXByZW1hY3kudHJhbnNpdGlvbiI6ICJDb2duaXRpdmUgc3VwcmVtYWN5IHBoYXNlIHRyYW5zaXRpb24iLAogICAgInBhcmFkaWdtLm1pcmFjbGUiOiAgICAgIlRyYWluaW5nIG1pcmFjbGUgZ2VuZXJhdGVkIiwKICAgICJkaXN0aWxsZXJ5LmFydGlmYWN0IjogICJEaXN0aWxsZWQgYXJ0aWZhY3QgcHJvZHVjZWQiLAogICAgInNwaW5lLmFwcGVuZCI6ICAgICAgICAgIkltbXV0YWJsZSBsb2cgZW50cnkgYWRkZWQiLAogICAgInBoaS51cGRhdGUiOiAgICAgICAgICAgIkNvbnNjaW91c25lc3Mgc3Vic3RyYXRlIHN0YXRlIiwKICAgICJ0b3BvbG9neS5yZW5kZXIiOiAgICAgICJUb3BvbG9neSB2aXN1YWxpemF0aW9uIHJlcXVlc3RlZCIsCiAgICAiYnJvYWRjYXN0LnB1Ymxpc2giOiAgICAiTGl2ZS1yZWFzb25pbmcgYnJvYWRjYXN0IiwKICAgICJoZWFsdGguYWxlcnQiOiAgICAgICAgICJTZXJ2aWNlIGhlYWx0aCBhbGVydCIsCiAgICAic2tpbGwuaW52b2tlIjogICAgICAgICAiQ2xhd0h1YiBza2lsbCBpbnZvY2F0aW9uIiwKICAgICJzeW5jLmhmLnB1c2giOiAgICAgICAgICJIdWdnaW5nRmFjZSBzeW5jIiwKICAgICJzeW5jLmdpdGh1Yi5wdXNoIjogICAgICJHaXRIdWIgc3luYyIsCiAgICAidmF1bHQucm90YXRlIjogICAgICAgICAiVG9rZW4gcm90YXRpb24iLAp9CgoKQGRhdGFjbGFzcwpjbGFzcyBNZXNoRXZlbnQ6CiAgICBldmVudF9pZDogc3RyCiAgICBzdWJqZWN0OiBzdHIKICAgIHNvdXJjZV9zZXJ2aWNlOiBzdHIKICAgIHRhcmdldF9zZXJ2aWNlOiBPcHRpb25hbFtzdHJdICAjIE5vbmUgPSBicm9hZGNhc3QKICAgIHBheWxvYWQ6IGRpY3QKICAgIHRpbWVzdGFtcDogZmxvYXQKICAgIHR0bDogaW50ID0gNjAgICMgaG9wcyBiZWZvcmUgZHJvcAogICAgdHJhY2U6IGxpc3Rbc3RyXSA9IE5vbmUKCiAgICBkZWYgdG9fanNvbihzZWxmKSAtPiBzdHI6CiAgICAgICAgcmV0dXJuIGpzb24uZHVtcHMoYXNkaWN0KHNlbGYpLCBpbmRlbnQ9MikKCgpjbGFzcyBOQVRTTWVzaENvbm5lY3RvcjoKICAgICIiIgogICAgSW4tcHJvY2VzcyBOQVRTLWNvbXBhdGlibGUgZXZlbnQgbWVzaC4KICAgIEluIHByb2R1Y3Rpb24sIHJlcGxhY2Ugd2l0aCBuYXRzLXB5OiBgaW1wb3J0IG5hdHM7IG5jID0gYXdhaXQgbmF0cy5jb25uZWN0KClgCiAgICAiIiIKCiAgICBkZWYgX19pbml0X18oc2VsZiwgc2VydmljZV9uYW1lOiBzdHIpOgogICAgICAgIHNlbGYuc2VydmljZV9uYW1lID0gc2VydmljZV9uYW1lCiAgICAgICAgc2VsZi5zdWJzY3JpcHRpb25zOiBkaWN0W3N0ciwgbGlzdFtDYWxsYWJsZV1dID0gZGVmYXVsdGRpY3QobGlzdCkKICAgICAgICBzZWxmLmV2ZW50X2xvZzogbGlzdFtNZXNoRXZlbnRdID0gW10KICAgICAgICBzZWxmLmNvbm5lY3RlZCA9IEZhbHNlCgogICAgYXN5bmMgZGVmIGNvbm5lY3Qoc2VsZiwgbmF0c191cmw6IHN0ciA9ICJuYXRzOi8vMTI3LjAuMC4xOjQyMjIiKToKICAgICAgICAiIiJDb25uZWN0IHRvIE5BVFMgc2VydmVyLiBGYWxscyBiYWNrIHRvIGluLXByb2Nlc3MgbW9kZS4iIiIKICAgICAgICB0cnk6CiAgICAgICAgICAgICMgVHJ5IHJlYWwgTkFUUyBmaXJzdAogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBpbXBvcnQgbmF0cwogICAgICAgICAgICAgICAgc2VsZi5uYyA9IGF3YWl0IG5hdHMuY29ubmVjdChuYXRzX3VybCkKICAgICAgICAgICAgICAgIHNlbGYuY29ubmVjdGVkID0gVHJ1ZQogICAgICAgICAgICAgICAgc2VsZi5fbW9kZSA9ICJuYXRzIgogICAgICAgICAgICAgICAgcHJpbnQoZiJbe3NlbGYuc2VydmljZV9uYW1lfV0gQ29ubmVjdGVkIHRvIE5BVFMgYXQge25hdHNfdXJsfSIpCiAgICAgICAgICAgICAgICByZXR1cm4gVHJ1ZQogICAgICAgICAgICBleGNlcHQgSW1wb3J0RXJyb3I6CiAgICAgICAgICAgICAgICBwYXNzCgogICAgICAgICAgICAjIEZhbGxiYWNrOiBpbi1wcm9jZXNzCiAgICAgICAgICAgIHNlbGYuX21vZGUgPSAiaW4tcHJvY2VzcyIKICAgICAgICAgICAgc2VsZi5jb25uZWN0ZWQgPSBUcnVlCiAgICAgICAgICAgIHByaW50KGYiW3tzZWxmLnNlcnZpY2VfbmFtZX1dIFJ1bm5pbmcgaW4tcHJvY2VzcyBtZXNoIChpbnN0YWxsIG5hdHMtcHkgZm9yIGRpc3RyaWJ1dGVkIG1vZGUpIikKICAgICAgICAgICAgcmV0dXJuIFRydWUKICAgICAgICBleGNlcHQgRXhjZXB0aW9uIGFzIGU6CiAgICAgICAgICAgIHByaW50KGYiW3tzZWxmLnNlcnZpY2VfbmFtZX1dIENvbm5lY3Rpb24gZmFpbGVkOiB7ZX0iKQogICAgICAgICAgICByZXR1cm4gRmFsc2UKCiAgICBkZWYgc3Vic2NyaWJlKHNlbGYsIHN1YmplY3Q6IHN0ciwgaGFuZGxlcjogQ2FsbGFibGUpOgogICAgICAgICIiIlN1YnNjcmliZSB0byBhIHN1YmplY3QuIiIiCiAgICAgICAgc2VsZi5zdWJzY3JpcHRpb25zW3N1YmplY3RdLmFwcGVuZChoYW5kbGVyKQoKICAgIGFzeW5jIGRlZiBwdWJsaXNoKHNlbGYsIHN1YmplY3Q6IHN0ciwgcGF5bG9hZDogZGljdCwgdGFyZ2V0OiBzdHIgPSBOb25lKToKICAgICAgICAiIiJQdWJsaXNoIGFuIGV2ZW50IHRvIHRoZSBtZXNoLiIiIgogICAgICAgIGV2ZW50ID0gTWVzaEV2ZW50KAogICAgICAgICAgICBldmVudF9pZD1oYXNobGliLnNoYTI1NihmIntzdWJqZWN0fTp7dGltZS50aW1lKCl9Ii5lbmNvZGUoKSkuaGV4ZGlnZXN0KClbOjE2XSwKICAgICAgICAgICAgc3ViamVjdD1zdWJqZWN0LAogICAgICAgICAgICBzb3VyY2Vfc2VydmljZT1zZWxmLnNlcnZpY2VfbmFtZSwKICAgICAgICAgICAgdGFyZ2V0X3NlcnZpY2U9dGFyZ2V0LAogICAgICAgICAgICBwYXlsb2FkPXBheWxvYWQsCiAgICAgICAgICAgIHRpbWVzdGFtcD10aW1lLnRpbWUoKSwKICAgICAgICAgICAgdHJhY2U9W3NlbGYuc2VydmljZV9uYW1lXSwKICAgICAgICApCiAgICAgICAgc2VsZi5ldmVudF9sb2cuYXBwZW5kKGV2ZW50KQogICAgICAgIGF3YWl0IHNlbGYuX2Rpc3BhdGNoKGV2ZW50KQoKICAgIGFzeW5jIGRlZiBfZGlzcGF0Y2goc2VsZiwgZXZlbnQ6IE1lc2hFdmVudCk6CiAgICAgICAgIiIiUm91dGUgZXZlbnQgdG8gc3Vic2NyaWJlcnMuIiIiCiAgICAgICAgaGFuZGxlcnMgPSBzZWxmLnN1YnNjcmlwdGlvbnMuZ2V0KGV2ZW50LnN1YmplY3QsIFtdKQogICAgICAgIGZvciBoYW5kbGVyIGluIGhhbmRsZXJzOgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICByZXN1bHQgPSBoYW5kbGVyKGV2ZW50LnBheWxvYWQpCiAgICAgICAgICAgICAgICBpZiBhc3luY2lvLmlzY29yb3V0aW5lKHJlc3VsdCk6CiAgICAgICAgICAgICAgICAgICAgYXdhaXQgcmVzdWx0CiAgICAgICAgICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgZToKICAgICAgICAgICAgICAgIHByaW50KGYiW3tzZWxmLnNlcnZpY2VfbmFtZX1dIEhhbmRsZXIgZXJyb3Igb24ge2V2ZW50LnN1YmplY3R9OiB7ZX0iKQoKICAgICAgICAjIFdpbGRjYXJkIGRpc3BhdGNoCiAgICAgICAgZm9yIHN1YmplY3QsIHN1YnMgaW4gc2VsZi5zdWJzY3JpcHRpb25zLml0ZW1zKCk6CiAgICAgICAgICAgIGlmIHN1YmplY3QuZW5kc3dpdGgoIi4qIik6CiAgICAgICAgICAgICAgICBwcmVmaXggPSBzdWJqZWN0WzotMl0KICAgICAgICAgICAgICAgIGlmIGV2ZW50LnN1YmplY3Quc3RhcnRzd2l0aChwcmVmaXgpOgogICAgICAgICAgICAgICAgICAgIGZvciBoYW5kbGVyIGluIHN1YnM6CiAgICAgICAgICAgICAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IGhhbmRsZXIoZXZlbnQucGF5bG9hZCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGFzeW5jaW8uaXNjb3JvdXRpbmUocmVzdWx0KToKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCByZXN1bHQKICAgICAgICAgICAgICAgICAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbjoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhc3MKCiAgICBkZWYgaGVhbHRoKHNlbGYpIC0+IGRpY3Q6CiAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgInNlcnZpY2UiOiBzZWxmLnNlcnZpY2VfbmFtZSwKICAgICAgICAgICAgImNvbm5lY3RlZCI6IHNlbGYuY29ubmVjdGVkLAogICAgICAgICAgICAibW9kZSI6IGdldGF0dHIoc2VsZiwgIl9tb2RlIiwgImRpc2Nvbm5lY3RlZCIpLAogICAgICAgICAgICAic3Vic2NyaXB0aW9ucyI6IGxpc3Qoc2VsZi5zdWJzY3JpcHRpb25zLmtleXMoKSksCiAgICAgICAgICAgICJldmVudHNfcHVibGlzaGVkIjogbGVuKHNlbGYuZXZlbnRfbG9nKSwKICAgICAgICAgICAgInVwdGltZV9ldmVudHMiOiBsZW4oW2UgZm9yIGUgaW4gc2VsZi5ldmVudF9sb2cgaWYgdGltZS50aW1lKCkgLSBlLnRpbWVzdGFtcCA8IDM2MDBdKSwKICAgICAgICB9CgoKIyBTZXJ2aWNlIGZhY3Rvcnkg4oCUIGNyZWF0ZSBtZXNoIGNvbm5lY3RvcnMgZm9yIGFsbCAxNyBzZXJ2aWNlcwpkZWYgY3JlYXRlX21lc2goc2VydmljZV9uYW1lOiBzdHIpIC0+IE5BVFNNZXNoQ29ubmVjdG9yOgogICAgYXNzZXJ0IHNlcnZpY2VfbmFtZSBpbiBFVkVaX1NFUlZJQ0VTLCBmIlVua25vd24gc2VydmljZToge3NlcnZpY2VfbmFtZX0iCiAgICByZXR1cm4gTkFUU01lc2hDb25uZWN0b3Ioc2VydmljZV9uYW1lKQoKCmlmIF9fbmFtZV9fID09ICJfX21haW5fXyI6CiAgICBhc3luYyBkZWYgZGVtbygpOgogICAgICAgICMgQ3JlYXRlIGEgbWluaSBtZXNoIHdpdGggMyBzZXJ2aWNlcwogICAgICAgIGZpcmUgPSBjcmVhdGVfbWVzaCgiZmlyZS1kZXRlY3RvciIpCiAgICAgICAgem9vID0gY3JlYXRlX21lc2goImNyeXB0b3pvbyIpCiAgICAgICAgc3VwcmVtYWN5ID0gY3JlYXRlX21lc2goImNvZ25pdGl2ZS1zdXByZW1hY3kiKQoKICAgICAgICBhd2FpdCBmaXJlLmNvbm5lY3QoKQogICAgICAgIGF3YWl0IHpvby5jb25uZWN0KCkKICAgICAgICBhd2FpdCBzdXByZW1hY3kuY29ubmVjdCgpCgogICAgICAgICMgV2lyZSB1cCBzdWJzY3JpcHRpb25zCiAgICAgICAgZmlyZV9ldmVudHMgPSBbXQogICAgICAgIHpvby5zdWJzY3JpYmUoImZpcmUuZXZlbnQiLCBsYW1iZGEgcDogZmlyZV9ldmVudHMuYXBwZW5kKHApKQogICAgICAgIHN1cHJlbWFjeS5zdWJzY3JpYmUoImZpcmUuZXZlbnQiLCBsYW1iZGEgcDogcHJpbnQoZiJbc3VwcmVtYWN5XSBGSVJFIGV2ZW50IHJlY2VpdmVkOiB7cC5nZXQoJ2luZmxlY3Rpb25fdHlwZScpfSIpKQogICAgICAgIHN1cHJlbWFjeS5zdWJzY3JpYmUoInNwZWNpbWVuLmNsYXNzaWZpZWQiLCBsYW1iZGEgcDogcHJpbnQoZiJbc3VwcmVtYWN5XSBOZXcgc3BlY2ltZW46IHtwLmdldCgnc3BlY2ltZW5fY2xhc3MnKX0iKSkKICAgICAgICBmaXJlLnN1YnNjcmliZSgic3VwcmVtYWN5LnRyYW5zaXRpb24iLCBsYW1iZGEgcDogcHJpbnQoZiJbZmlyZV0gU3VwcmVtYWN5IHRyYW5zaXRpb246IHtwLmdldCgnZG9tYWluJyl9IikpCgogICAgICAgICMgU2ltdWxhdGUgZXZlbnQgZmxvdwogICAgICAgIGF3YWl0IGZpcmUucHVibGlzaCgiZmlyZS5ldmVudCIsIHsKICAgICAgICAgICAgImluZmxlY3Rpb25fdHlwZSI6ICJwaGFzZV9zaGlmdCIsCiAgICAgICAgICAgICJtYWduaXR1ZGUiOiAwLjM0LAogICAgICAgICAgICAicGhpIjogMC44OCwKICAgICAgICAgICAgInRpY2siOiAxNTAsCiAgICAgICAgfSkKCiAgICAgICAgYXdhaXQgem9vLnB1Ymxpc2goInNwZWNpbWVuLmNsYXNzaWZpZWQiLCB7CiAgICAgICAgICAgICJzcGVjaW1lbl9jbGFzcyI6ICJjcnlwdGlkIiwKICAgICAgICAgICAgInBoaV9jb2hlcmVuY2UiOiAwLjg4LAogICAgICAgICAgICAidl9hY2N1bXVsYXRvcl9tYXNzIjogMC43MiwKICAgICAgICB9KQoKICAgICAgICBhd2FpdCBzdXByZW1hY3kucHVibGlzaCgic3VwcmVtYWN5LnRyYW5zaXRpb24iLCB7CiAgICAgICAgICAgICJkb21haW4iOiAiaW50ZXJwcmV0YWJpbGl0eSIsCiAgICAgICAgICAgICJkZW5zaXR5IjogMC43OSwKICAgICAgICAgICAgInRhc2tfY291bnQiOiAxMiwKICAgICAgICB9KQoKICAgICAgICBwcmludChmIlxuWm9vIHJlY2VpdmVkIHtsZW4oZmlyZV9ldmVudHMpfSBGSVJFIGV2ZW50cyIpCiAgICAgICAgcHJpbnQoZiJGaXJlIGhlYWx0aDoge2ZpcmUuaGVhbHRoKCl9IikKICAgICAgICBwcmludChmIlpvbyBoZWFsdGg6IHt6b28uaGVhbHRoKCl9IikKCiAgICBhc3luY2lvLnJ1bihkZW1vKCkpCg== |