From 381142a6ac9db4a3c437793cc08f7fdb5d31cad4 Mon Sep 17 00:00:00 2001 From: jason Date: Tue, 12 May 2026 15:48:08 -0500 Subject: [PATCH] feat: read 6-month desktop authToken from tokens-mcp.json (v0.1.2) Token resolution order: 1. PLAUD_TOKEN env var 2. ~/.plaud/tokens-mcp.json (desktop app authToken, ~6-month expiry) Written by plaud_decrypt_tokens.py via Electron safeStorage decryption 3. ~/.plaud/config.json (legacy 24-hour web token fallback) The Plaud desktop app stores a standard JWT authToken in Chromium v10 Electron safeStorage (AES-128-CBC / PBKDF2-SHA1). plaud_decrypt_tokens.py extracts this token and saves it to tokens-mcp.json. Current token expires 2026-11-25; re-run the decrypt script on that date to renew. --- server/plaud_mcp.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/plaud_mcp.py b/server/plaud_mcp.py index b98e1cf..97cdc2f 100644 --- a/server/plaud_mcp.py +++ b/server/plaud_mcp.py @@ -1 +1 @@ -IyEvdXNyL2Jpbi9lbnYgcHl0aG9uMwoiIiIKUGxhdWQgTUNQIFNlcnZlciBmb3IgTVBNCkNvbm5lY3RzIHRvIHRoZSBQbGF1ZCBBUEkgYW5kIGV4cG9zZXMgdG9vbHMgZm9yIGxpc3RpbmcsIHNlYXJjaGluZywKYW5kIHJlYWRpbmcgdHJhbnNjcmlwdHMsIHN1bW1hcmllcywgYW5kIG5vdGVzIGZyb20gUGxhdWQgcmVjb3JkaW5ncy4KCkNyZWRlbnRpYWxzOiByZWFkcyB0b2tlbiBmcm9tIH4vLnBsYXVkL2NvbmZpZy5qc29uLgoiIiIKCmltcG9ydCBnemlwCmltcG9ydCBqc29uCmltcG9ydCBvcwppbXBvcnQgc3VicHJvY2VzcwppbXBvcnQgdXJsbGliLnBhcnNlCmZyb20gZGF0ZXRpbWUgaW1wb3J0IGRhdGV0aW1lLCB0aW1lem9uZQpmcm9tIHBhdGhsaWIgaW1wb3J0IFBhdGgKZnJvbSB0eXBpbmcgaW1wb3J0IE9wdGlvbmFsCgpmcm9tIG1jcC5zZXJ2ZXIuZmFzdG1jcCBpbXBvcnQgRmFzdE1DUAoKIyDilIDilIAgQ29uZmlndXJhdGlvbiDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKUExBVURfUkVHSU9OID0gb3MuZW52aXJvbi5nZXQoIlBMQVVEX1JFR0lPTiIsICJ1cyIpCkJBU0VfVVJMID0gImh0dHBzOi8vYXBpLnBsYXVkLmV1IiBpZiBQTEFVRF9SRUdJT04gPT0gImV1IiBlbHNlICJodHRwczovL2FwaS5wbGF1ZC5haSIKQ09ORklHX1BBVEggPSBQYXRoLmhvbWUoKSAvICIucGxhdWQiIC8gImNvbmZpZy5qc29uIgoKCiMg4pSA4pSAIFRva2VuIHJlc29sdXRpb24g4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACgpkZWYgX2xvYWRfdG9rZW4oKSAtPiBPcHRpb25hbFtzdHJdOgogICAgZW52X3Rva2VuID0gb3MuZW52aXJvbi5nZXQoIlBMQVVEX1RPS0VOIiwgIiIpLnN0cmlwKCkKICAgIGlmIGVudl90b2tlbjoKICAgICAgICByZXR1cm4gZW52X3Rva2VuCgogICAgaWYgQ09ORklHX1BBVEguZXhpc3RzKCk6CiAgICAgICAgdHJ5OgogICAgICAgICAgICBkYXRhID0ganNvbi5sb2FkcyhDT05GSUdfUEFUSC5yZWFkX3RleHQoKSkKICAgICAgICAgICAgdG9rZW5fYmxvY2sgPSBkYXRhLmdldCgidG9rZW4iKQogICAgICAgICAgICBpZiBpc2luc3RhbmNlKHRva2VuX2Jsb2NrLCBkaWN0KToKICAgICAgICAgICAgICAgIHQgPSAodG9rZW5fYmxvY2suZ2V0KCJ0b2tlbiIpIG9yIHRva2VuX2Jsb2NrLmdldCgiYWNjZXNzVG9rZW4iKSBvciAiIikuc3RyaXAoKQogICAgICAgICAgICAgICAgaWYgdDoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdAogICAgICAgICAgICBpZiBpc2luc3RhbmNlKHRva2VuX2Jsb2NrLCBzdHIpIGFuZCB0b2tlbl9ibG9jay5zdHJpcCgpOgogICAgICAgICAgICAgICAgcmV0dXJuIHRva2VuX2Jsb2NrLnN0cmlwKCkKICAgICAgICBleGNlcHQgRXhjZXB0aW9uOgogICAgICAgICAgICBwYXNzCgogICAgcmV0dXJuIE5vbmUKCgpkZWYgX2dldF90b2tlbigpIC0+IHN0cjoKICAgIHRva2VuID0gX2xvYWRfdG9rZW4oKQogICAgaWYgbm90IHRva2VuOgogICAgICAgIHJhaXNlIFJ1bnRpbWVFcnJvcigKICAgICAgICAgICAgIk5vIFBsYXVkIHRva2VuIGZvdW5kLiBSdW4gdGhlIHBsYXVkLWNvbm5lY3RvciBpbXBvcnQtdG9rZW4gY29tbWFuZCAiCiAgICAgICAgICAgICJvciBzZXQgdGhlIFBMQVVEX1RPS0VOIGVudmlyb25tZW50IHZhcmlhYmxlLiIKICAgICAgICApCiAgICByZXR1cm4gdG9rZW4KCgojIOKUgOKUgCBIVFRQIGhlbHBlcnMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACgpkZWYgX2FwaV9nZXQocGF0aDogc3RyLCBwYXJhbXM6IE9wdGlvbmFsW2RpY3RdID0gTm9uZSkgLT4gZGljdDoKICAgICIiIkdFVCByZXF1ZXN0IHRvIHRoZSBQbGF1ZCBBUEkgdXNpbmcgY3VybCAoYnlwYXNzZXMgQ2xvdWRmbGFyZSBicm93c2VyIGNoZWNrKS4iIiIKICAgIHRva2VuID0gX2dldF90b2tlbigpCiAgICB1cmwgPSBmIntCQVNFX1VSTH17cGF0aH0iCiAgICBpZiBwYXJhbXM6CiAgICAgICAgcXVlcnkgPSAiJiIuam9pbigKICAgICAgICAgICAgZiJ7a309e3VybGxpYi5wYXJzZS5xdW90ZShzdHIodikpfSIKICAgICAgICAgICAgZm9yIGssIHYgaW4gcGFyYW1zLml0ZW1zKCkgaWYgdiBpcyBub3QgTm9uZQogICAgICAgICkKICAgICAgICBpZiBxdWVyeToKICAgICAgICAgICAgdXJsID0gZiJ7dXJsfT97cXVlcnl9IgoKICAgIHJlc3VsdCA9IHN1YnByb2Nlc3MucnVuKAogICAgICAgIFsiY3VybCIsICItcyIsICItZiIsCiAgICAgICAgICItSCIsIGYiQXV0aG9yaXphdGlvbjogQmVhcmVyIHt0b2tlbn0iLAogICAgICAgICAiLUgiLCAiQWNjZXB0OiBhcHBsaWNhdGlvbi9qc29uIiwKICAgICAgICAgdXJsXSwKICAgICAgICBjYXB0dXJlX291dHB1dD1UcnVlLCB0ZXh0PVRydWUsIHRpbWVvdXQ9MzAsCiAgICApCiAgICBpZiByZXN1bHQucmV0dXJuY29kZSAhPSAwOgogICAgICAgIHJhaXNlIFJ1bnRpbWVFcnJvcigKICAgICAgICAgICAgZiJQbGF1ZCBBUEkgZXJyb3IgKGN1cmwgZXhpdCB7cmVzdWx0LnJldHVybmNvZGV9KToge3Jlc3VsdC5zdGRlcnJbOjMwMF19IgogICAgICAgICkKICAgIHRyeToKICAgICAgICByZXR1cm4ganNvbi5sb2FkcyhyZXN1bHQuc3Rkb3V0KQogICAgZXhjZXB0IGpzb24uSlNPTkRlY29kZUVycm9yOgogICAgICAgIHJhaXNlIFJ1bnRpbWVFcnJvcihmIkludmFsaWQgSlNPTiBmcm9tIFBsYXVkIEFQSToge3Jlc3VsdC5zdGRvdXRbOjMwMF19IikKCgpkZWYgX2ZldGNoX3MzX2pzb24odXJsOiBzdHIpIC0+IG9iamVjdDoKICAgICIiIkZldGNoIGFuZCBkZWNvbXByZXNzIGEgZ3ppcHBlZCBKU09OIGZyb20gYSBzaWduZWQgUzMgVVJMLiIiIgogICAgcmVzdWx0ID0gc3VicHJvY2Vzcy5ydW4oCiAgICAgICAgWyJjdXJsIiwgIi1zIiwgIi1mIiwgdXJsXSwKICAgICAgICBjYXB0dXJlX291dHB1dD1UcnVlLCB0aW1lb3V0PTMwLAogICAgKQogICAgaWYgcmVzdWx0LnJldHVybmNvZGUgIT0gMDoKICAgICAgICByYWlzZSBSdW50aW1lRXJyb3IoZiJTMyBmZXRjaCBmYWlsZWQgKGN1cmwgZXhpdCB7cmVzdWx0LnJldHVybmNvZGV9KSIpCiAgICB0cnk6CiAgICAgICAgY29udGVudCA9IGd6aXAuZGVjb21wcmVzcyhyZXN1bHQuc3Rkb3V0KQogICAgZXhjZXB0IE9TRXJyb3I6CiAgICAgICAgY29udGVudCA9IHJlc3VsdC5zdGRvdXQgICMgTm90IGd6aXBwZWQKICAgIHJldHVybiBqc29uLmxvYWRzKGNvbnRlbnQuZGVjb2RlKCJ1dGYtOCIpKQoKCiMg4pSA4pSAIERhdGEgaGVscGVycyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKCmRlZiBfZm10X2R1cmF0aW9uKG1zOiBpbnQpIC0+IHN0cjoKICAgIG1pbnMgPSBtcyAvLyA2MDAwMAogICAgaWYgbWlucyA8IDYwOgogICAgICAgIHJldHVybiBmInttaW5zfW0iCiAgICByZXR1cm4gZiJ7bWlucyAvLyA2MH1oIHttaW5zICUgNjB9bSIKCgpkZWYgX2ZtdF9kYXRlKHRzX21zOiBpbnQpIC0+IHN0cjoKICAgIHRyeToKICAgICAgICBkdCA9IGRhdGV0aW1lLmZyb210aW1lc3RhbXAodHNfbXMgLyAxMDAwLCB0ej10aW1lem9uZS51dGMpCiAgICAgICAgcmV0dXJuIGR0LnN0cmZ0aW1lKCIlWS0lbS0lZCAlSDolTSBVVEMiKQogICAgZXhjZXB0IEV4Y2VwdGlvbjoKICAgICAgICByZXR1cm4gc3RyKHRzX21zKQoKCmRlZiBfc3VtbWFyaXNlX3JlY29yZGluZyhyOiBkaWN0KSAtPiBkaWN0OgogICAgIiIiUmV0dXJuIGEgY29tcGFjdCBkaWN0IHN1aXRhYmxlIGZvciBsaXN0aW5nLiIiIgogICAgcmV0dXJuIHsKICAgICAgICAiaWQiOiByLmdldCgiaWQiLCAiIiksCiAgICAgICAgInRpdGxlIjogci5nZXQoImZpbGVuYW1lIikgb3Igci5nZXQoImZpbGVfbmFtZSIpIG9yIHIuZ2V0KCJ0aXRsZSIpIG9yICIodW50aXRsZWQpIiwKICAgICAgICAiZGF0ZSI6IF9mbXRfZGF0ZShyLmdldCgic3RhcnRfdGltZSIsIDApKSwKICAgICAgICAiZHVyYXRpb24iOiBfZm10X2R1cmF0aW9uKHIuZ2V0KCJkdXJhdGlvbiIsIDApKSwKICAgICAgICAiaGFzX3RyYW5zY3JpcHQiOiBib29sKHIuZ2V0KCJpc190cmFucyIpKSwKICAgICAgICAiaGFzX3N1bW1hcnkiOiBib29sKHIuZ2V0KCJhdXRvX3N1bV9ub3RlIikgb3Igci5nZXQoImlzX3N1bSIpKSwKICAgIH0KCgpkZWYgX2Zvcm1hdF90cmFuc2NyaXB0KHNlZ21lbnRzOiBsaXN0KSAtPiBzdHI6CiAgICAiIiJGb3JtYXQgdHJhbnNjcmlwdCBzZWdtZW50cyBpbnRvIHJlYWRhYmxlIHRleHQuIiIiCiAgICBsaW5lcyA9IFtdCiAgICBjdXJyZW50X3NwZWFrZXIgPSBOb25lCiAgICBmb3Igc2VnIGluIHNlZ21lbnRzOgogICAgICAgIHNwZWFrZXIgPSBzZWcuZ2V0KCJzcGVha2VyIikgb3Igc2VnLmdldCgib3JpZ2luYWxfc3BlYWtlciIpIG9yICIiCiAgICAgICAgY29udGVudCA9IHNlZy5nZXQoImNvbnRlbnQiLCAiIikuc3RyaXAoKQogICAgICAgIGlmIG5vdCBjb250ZW50OgogICAgICAgICAgICBjb250aW51ZQogICAgICAgIGlmIHNwZWFrZXIgYW5kIHNwZWFrZXIgIT0gY3VycmVudF9zcGVha2VyOgogICAgICAgICAgICBpZiBsaW5lczoKICAgICAgICAgICAgICAgIGxpbmVzLmFwcGVuZCgiIikKICAgICAgICAgICAgbGluZXMuYXBwZW5kKGYiW3tzcGVha2VyfV0iKQogICAgICAgICAgICBjdXJyZW50X3NwZWFrZXIgPSBzcGVha2VyCiAgICAgICAgbGluZXMuYXBwZW5kKGNvbnRlbnQpCiAgICByZXR1cm4gIlxuIi5qb2luKGxpbmVzKQoKCmRlZiBfZ2V0X2NvbnRlbnRfdXJsKGNvbnRlbnRfbGlzdDogbGlzdCwgZGF0YV90eXBlOiBzdHIpIC0+IE9wdGlvbmFsW3N0cl06CiAgICAiIiJGaW5kIGEgZGF0YV9saW5rIFVSTCBmcm9tIGNvbnRlbnRfbGlzdCBieSBkYXRhX3R5cGUuIiIiCiAgICBmb3IgaXRlbSBpbiBjb250ZW50X2xpc3Q6CiAgICAgICAgaWYgaXRlbS5nZXQoImRhdGFfdHlwZSIpID09IGRhdGFfdHlwZSBhbmQgaXRlbS5nZXQoImRhdGFfbGluayIpOgogICAgICAgICAgICByZXR1cm4gaXRlbVsiZGF0YV9saW5rIl0KICAgIHJldHVybiBOb25lCgoKIyDilIDilIAgTUNQIHNlcnZlciDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKbWNwID0gRmFzdE1DUCgicGxhdWQtbXBtIikKCgpAbWNwLnRvb2woKQpkZWYgcGxhdWRfbGlzdF9yZWNvcmRpbmdzKAogICAgbGltaXQ6IGludCA9IDUwLAogICAgb25seV93aXRoX3RyYW5zY3JpcHQ6IGJvb2wgPSBGYWxzZSwKKSAtPiBzdHI6CiAgICAiIiIKICAgIExpc3QgUGxhdWQgcmVjb3JkaW5ncyBuZXdlc3QtZmlyc3QuCgogICAgQXJnczoKICAgICAgICBsaW1pdDogTWF4IG51bWJlciB0byByZXR1cm4gKGRlZmF1bHQgNTAsIG1heCAyMDApLgogICAgICAgIG9ubHlfd2l0aF90cmFuc2NyaXB0OiBJZiB0cnVlLCBvbmx5IHJldHVybiByZWNvcmRpbmdzIHRoYXQgaGF2ZSBhIHRyYW5zY3JpcHQuCiAgICAiIiIKICAgIHJlc3AgPSBfYXBpX2dldCgiL2ZpbGUvc2ltcGxlL3dlYiIpCiAgICBpZiBpc2luc3RhbmNlKHJlc3AsIGRpY3QpOgogICAgICAgIHJlY29yZGluZ3MgPSByZXNwLmdldCgiZGF0YV9maWxlX2xpc3QiKSBvciByZXNwLmdldCgiZGF0YSIpIG9yIFtdCiAgICBlbHNlOgogICAgICAgIHJlY29yZGluZ3MgPSByZXNwIGlmIGlzaW5zdGFuY2UocmVzcCwgbGlzdCkgZWxzZSBbXQoKICAgIGlmIG9ubHlfd2l0aF90cmFuc2NyaXB0OgogICAgICAgIHJlY29yZGluZ3MgPSBbciBmb3IgciBpbiByZWNvcmRpbmdzIGlmIHIuZ2V0KCJpc190cmFucyIpXQoKICAgIHJlY29yZGluZ3MgPSByZWNvcmRpbmdzWzptaW4obGltaXQsIDIwMCldCiAgICByZXR1cm4ganNvbi5kdW1wcyhbX3N1bW1hcmlzZV9yZWNvcmRpbmcocikgZm9yIHIgaW4gcmVjb3JkaW5nc10sIGluZGVudD0yKQoKCkBtY3AudG9vbCgpCmRlZiBwbGF1ZF9zZWFyY2hfcmVjb3JkaW5ncygKICAgIHRpdGxlX2NvbnRhaW5zOiBPcHRpb25hbFtzdHJdID0gTm9uZSwKICAgIHN0YXJ0X2RhdGU6IE9wdGlvbmFsW3N0cl0gPSBOb25lLAogICAgZW5kX2RhdGU6IE9wdGlvbmFsW3N0cl0gPSBOb25lLAogICAgb25seV93aXRoX3RyYW5zY3JpcHQ6IGJvb2wgPSBGYWxzZSwKICAgIG1heF9yZXN1bHRzOiBpbnQgPSAyMCwKKSAtPiBzdHI6CiAgICAiIiIKICAgIFNlYXJjaCByZWNvcmRpbmdzIGJ5IHRpdGxlIGFuZC9vciBkYXRlIHJhbmdlLgoKICAgIEFyZ3M6CiAgICAgICAgdGl0bGVfY29udGFpbnM6IFN1YnN0cmluZyB0byBtYXRjaCBpbiB0aGUgcmVjb3JkaW5nIHRpdGxlIChjYXNlLWluc2Vuc2l0aXZlKS4KICAgICAgICBzdGFydF9kYXRlOiBJU08gZGF0ZSBzdHJpbmcsIGUuZy4gJzIwMjYtMDQtMDEnLiBPbmx5IHJlY29yZGluZ3Mgb24gb3IgYWZ0ZXIgdGhpcyBkYXRlLgogICAgICAgIGVuZF9kYXRlOiBJU08gZGF0ZSBzdHJpbmcsIGUuZy4gJzIwMjYtMDUtMDEnLiBPbmx5IHJlY29yZGluZ3Mgb24gb3IgYmVmb3JlIHRoaXMgZGF0ZS4KICAgICAgICBvbmx5X3dpdGhfdHJhbnNjcmlwdDogSWYgdHJ1ZSwgb25seSByZXR1cm4gcmVjb3JkaW5ncyB0aGF0IGhhdmUgYSB0cmFuc2NyaXB0LgogICAgICAgIG1heF9yZXN1bHRzOiBNYXggbnVtYmVyIG9mIHJlc3VsdHMgdG8gcmV0dXJuIChkZWZhdWx0IDIwKS4KICAgICIiIgogICAgcmVzcCA9IF9hcGlfZ2V0KCIvZmlsZS9zaW1wbGUvd2ViIikKICAgIGlmIGlzaW5zdGFuY2UocmVzcCwgZGljdCk6CiAgICAgICAgcmVjb3JkaW5ncyA9IHJlc3AuZ2V0KCJkYXRhX2ZpbGVfbGlzdCIpIG9yIHJlc3AuZ2V0KCJkYXRhIikgb3IgW10KICAgIGVsc2U6CiAgICAgICAgcmVjb3JkaW5ncyA9IHJlc3AgaWYgaXNpbnN0YW5jZShyZXNwLCBsaXN0KSBlbHNlIFtdCgogICAgZGVmIG1hdGNoZXMocjogZGljdCkgLT4gYm9vbDoKICAgICAgICBpZiBvbmx5X3dpdGhfdHJhbnNjcmlwdCBhbmQgbm90IHIuZ2V0KCJpc190cmFucyIpOgogICAgICAgICAgICByZXR1cm4gRmFsc2UKICAgICAgICB0aXRsZSA9IChyLmdldCgiZmlsZW5hbWUiKSBvciByLmdldCgiZmlsZV9uYW1lIikgb3Igci5nZXQoInRpdGxlIikgb3IgIiIpLmxvd2VyKCkKICAgICAgICBpZiB0aXRsZV9jb250YWlucyBhbmQgdGl0bGVfY29udGFpbnMubG93ZXIoKSBub3QgaW4gdGl0bGU6CiAgICAgICAgICAgIHJldHVybiBGYWxzZQogICAgICAgIGlmIHN0YXJ0X2RhdGUgb3IgZW5kX2RhdGU6CiAgICAgICAgICAgIHRzX21zID0gci5nZXQoInN0YXJ0X3RpbWUiLCAwKQogICAgICAgICAgICByZWNfZGF0ZSA9IGRhdGV0aW1lLmZyb210aW1lc3RhbXAodHNfbXMgLyAxMDAwLCB0ej10aW1lem9uZS51dGMpLmRhdGUoKQogICAgICAgICAgICBpZiBzdGFydF9kYXRlIGFuZCByZWNfZGF0ZSA8IGRhdGV0aW1lLmZyb21pc29mb3JtYXQoc3RhcnRfZGF0ZSkuZGF0ZSgpOgogICAgICAgICAgICAgICAgcmV0dXJuIEZhbHNlCiAgICAgICAgICAgIGlmIGVuZF9kYXRlIGFuZCByZWNfZGF0ZSA+IGRhdGV0aW1lLmZyb21pc29mb3JtYXQoZW5kX2RhdGUpLmRhdGUoKToKICAgICAgICAgICAgICAgIHJldHVybiBGYWxzZQogICAgICAgIHJldHVybiBUcnVlCgogICAgbWF0Y2hlZCA9IFtyIGZvciByIGluIHJlY29yZGluZ3MgaWYgbWF0Y2hlcyhyKV1bOm1heF9yZXN1bHRzXQogICAgcmV0dXJuIGpzb24uZHVtcHMoW19zdW1tYXJpc2VfcmVjb3JkaW5nKHIpIGZvciByIGluIG1hdGNoZWRdLCBpbmRlbnQ9MikKCgpAbWNwLnRvb2woKQpkZWYgcGxhdWRfZ2V0X3RyYW5zY3JpcHQocmVjb3JkaW5nX2lkOiBzdHIpIC0+IHN0cjoKICAgICIiIgogICAgR2V0IHRoZSBmdWxsIHRyYW5zY3JpcHQgZm9yIGEgUGxhdWQgcmVjb3JkaW5nLgoKICAgIEFyZ3M6CiAgICAgICAgcmVjb3JkaW5nX2lkOiBUaGUgcmVjb3JkaW5nIElEIChmcm9tIHBsYXVkX2xpc3RfcmVjb3JkaW5ncykuCiAgICAiIiIKICAgIHJlc3AgPSBfYXBpX2dldChmIi9maWxlL2RldGFpbC97cmVjb3JkaW5nX2lkfSIpCiAgICBkYXRhID0gcmVzcC5nZXQoImRhdGEiLCByZXNwKSBpZiBpc2luc3RhbmNlKHJlc3AsIGRpY3QpIGVsc2UgcmVzcAoKICAgIHRpdGxlID0gZGF0YS5nZXQoImZpbGVfbmFtZSIpIG9yIGRhdGEuZ2V0KCJmaWxlbmFtZSIpIG9yIGRhdGEuZ2V0KCJ0aXRsZSIpIG9yICIodW50aXRsZWQpIgogICAgY29udGVudF9saXN0ID0gZGF0YS5nZXQoImNvbnRlbnRfbGlzdCIpIG9yIFtdCiAgICB0cmFuc2NyaXB0ID0gIiIKCiAgICAjIFRyeSBwb2xpc2hlZCB0cmFuc2NyaXB0IGZpcnN0LCBmYWxsIGJhY2sgdG8gcmF3CiAgICBmb3IgZHR5cGUgaW4gKCJ0cmFuc2FjdGlvbl9wb2xpc2giLCAidHJhbnNhY3Rpb24iKToKICAgICAgICB1cmwgPSBfZ2V0X2NvbnRlbnRfdXJsKGNvbnRlbnRfbGlzdCwgZHR5cGUpCiAgICAgICAgaWYgdXJsOgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBzZWdtZW50cyA9IF9mZXRjaF9zM19qc29uKHVybCkKICAgICAgICAgICAgICAgIGlmIGlzaW5zdGFuY2Uoc2VnbWVudHMsIGxpc3QpOgogICAgICAgICAgICAgICAgICAgIHRyYW5zY3JpcHQgPSBfZm9ybWF0X3RyYW5zY3JpcHQoc2VnbWVudHMpCiAgICAgICAgICAgICAgICAgICAgaWYgdHJhbnNjcmlwdDoKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOgogICAgICAgICAgICAgICAgdHJhbnNjcmlwdCA9IGYiRXJyb3IgZmV0Y2hpbmcgdHJhbnNjcmlwdDoge2V9IgogICAgICAgICAgICAgICAgYnJlYWsKCiAgICByZXR1cm4ganNvbi5kdW1wcyh7CiAgICAgICAgImlkIjogcmVjb3JkaW5nX2lkLAogICAgICAgICJ0aXRsZSI6IHRpdGxlLAogICAgICAgICJkYXRlIjogX2ZtdF9kYXRlKGRhdGEuZ2V0KCJzdGFydF90aW1lIiwgMCkpLAogICAgICAgICJkdXJhdGlvbiI6IF9mbXRfZHVyYXRpb24oZGF0YS5nZXQoImR1cmF0aW9uIiwgMCkpLAogICAgICAgICJ0cmFuc2NyaXB0IjogdHJhbnNjcmlwdCBvciAiTm8gdHJhbnNjcmlwdCBhdmFpbGFibGUgZm9yIHRoaXMgcmVjb3JkaW5nLiIsCiAgICB9LCBpbmRlbnQ9MikKCgpAbWNwLnRvb2woKQpkZWYgcGxhdWRfZ2V0X3N1bW1hcnkocmVjb3JkaW5nX2lkOiBzdHIpIC0+IHN0cjoKICAgICIiIgogICAgR2V0IHRoZSBBSS1nZW5lcmF0ZWQgc3VtbWFyeS9vdXRsaW5lIGZvciBhIFBsYXVkIHJlY29yZGluZy4KCiAgICBBcmdzOgogICAgICAgIHJlY29yZGluZ19pZDogVGhlIHJlY29yZGluZyBJRCAoZnJvbSBwbGF1ZF9saXN0X3JlY29yZGluZ3MpLgogICAgIiIiCiAgICByZXNwID0gX2FwaV9nZXQoZiIvZmlsZS9kZXRhaWwve3JlY29yZGluZ19pZH0iKQogICAgZGF0YSA9IHJlc3AuZ2V0KCJkYXRhIiwgcmVzcCkgaWYgaXNpbnN0YW5jZShyZXNwLCBkaWN0KSBlbHNlIHJlc3AKCiAgICB0aXRsZSA9IGRhdGEuZ2V0KCJmaWxlX25hbWUiKSBvciBkYXRhLmdldCgiZmlsZW5hbWUiKSBvciBkYXRhLmdldCgidGl0bGUiKSBvciAiKHVudGl0bGVkKSIKICAgIGNvbnRlbnRfbGlzdCA9IGRhdGEuZ2V0KCJjb250ZW50X2xpc3QiKSBvciBbXQogICAgc3VtbWFyeSA9ICIiCgogICAgdXJsID0gX2dldF9jb250ZW50X3VybChjb250ZW50X2xpc3QsICJvdXRsaW5lIikKICAgIGlmIHVybDoKICAgICAgICB0cnk6CiAgICAgICAgICAgIG91dGxpbmVfZGF0YSA9IF9mZXRjaF9zM19qc29uKHVybCkKICAgICAgICAgICAgaWYgaXNpbnN0YW5jZShvdXRsaW5lX2RhdGEsIGRpY3QpOgogICAgICAgICAgICAgICAgc3VtbWFyeSA9IGpzb24uZHVtcHMob3V0bGluZV9kYXRhLCBpbmRlbnQ9MikKICAgICAgICAgICAgZWxpZiBpc2luc3RhbmNlKG91dGxpbmVfZGF0YSwgbGlzdCk6CiAgICAgICAgICAgICAgICBwYXJ0cyA9IFtdCiAgICAgICAgICAgICAgICBmb3IgaXRlbSBpbiBvdXRsaW5lX2RhdGE6CiAgICAgICAgICAgICAgICAgICAgaWYgaXNpbnN0YW5jZShpdGVtLCBkaWN0KToKICAgICAgICAgICAgICAgICAgICAgICAgcGFydHMuYXBwZW5kKGl0ZW0uZ2V0KCJjb250ZW50Iikgb3IgaXRlbS5nZXQoInRleHQiKSBvciBzdHIoaXRlbSkpCiAgICAgICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICAgICAgcGFydHMuYXBwZW5kKHN0cihpdGVtKSkKICAgICAgICAgICAgICAgIHN1bW1hcnkgPSAiXG5cbiIuam9pbihwIGZvciBwIGluIHBhcnRzIGlmIHApCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBzdW1tYXJ5ID0gc3RyKG91dGxpbmVfZGF0YSkKICAgICAgICBleGNlcHQgRXhjZXB0aW9uIGFzIGU6CiAgICAgICAgICAgIHN1bW1hcnkgPSBmIkVycm9yIGZldGNoaW5nIHN1bW1hcnk6IHtlfSIKCiAgICByZXR1cm4ganNvbi5kdW1wcyh7CiAgICAgICAgImlkIjogcmVjb3JkaW5nX2lkLAogICAgICAgICJ0aXRsZSI6IHRpdGxlLAogICAgICAgICJkYXRlIjogX2ZtdF9kYXRlKGRhdGEuZ2V0KCJzdGFydF90aW1lIiwgMCkpLAogICAgICAgICJzdW1tYXJ5Ijogc3VtbWFyeSBvciAiTm8gc3VtbWFyeSBhdmFpbGFibGUgZm9yIHRoaXMgcmVjb3JkaW5nLiIsCiAgICB9LCBpbmRlbnQ9MikKCgpAbWNwLnRvb2woKQpkZWYgcGxhdWRfZ2V0X25vdGVzKHJlY29yZGluZ19pZDogc3RyKSAtPiBzdHI6CiAgICAiIiIKICAgIEdldCBBSS1nZW5lcmF0ZWQgbm90ZXMgYW5kIGFjdGlvbiBpdGVtcyBmb3IgYSBQbGF1ZCByZWNvcmRpbmcuCiAgICBSZXR1cm5zIGFsbCBub3RlIGVudHJpZXMgZnJvbSB0aGUgY29udGVudF9saXN0IChhY3Rpb24gaXRlbXMsIGtleSBwb2ludHMsIGV0Yy4pLgoKICAgIEFyZ3M6CiAgICAgICAgcmVjb3JkaW5nX2lkOiBUaGUgcmVjb3JkaW5nIElEIChmcm9tIHBsYXVkX2xpc3RfcmVjb3JkaW5ncykuCiAgICAiIiIKICAgIHJlc3AgPSBfYXBpX2dldChmIi9maWxlL2RldGFpbC97cmVjb3JkaW5nX2lkfSIpCiAgICBkYXRhID0gcmVzcC5nZXQoImRhdGEiLCByZXNwKSBpZiBpc2luc3RhbmNlKHJlc3AsIGRpY3QpIGVsc2UgcmVzcAoKICAgIHRpdGxlID0gZGF0YS5nZXQoImZpbGVfbmFtZSIpIG9yIGRhdGEuZ2V0KCJmaWxlbmFtZSIpIG9yIGRhdGEuZ2V0KCJ0aXRsZSIpIG9yICIodW50aXRsZWQpIgogICAgY29udGVudF9saXN0ID0gZGF0YS5nZXQoImNvbnRlbnRfbGlzdCIpIG9yIFtdCiAgICBub3RlcyA9IFtdCgogICAgZm9yIGl0ZW0gaW4gY29udGVudF9saXN0OgogICAgICAgIGR0eXBlID0gaXRlbS5nZXQoImRhdGFfdHlwZSIsICIiKQogICAgICAgIHVybCA9IGl0ZW0uZ2V0KCJkYXRhX2xpbmsiKQogICAgICAgIGlmIG5vdCB1cmwgb3IgZHR5cGUgaW4gKCJ0cmFuc2FjdGlvbiIsICJ0cmFuc2FjdGlvbl9wb2xpc2giKToKICAgICAgICAgICAgY29udGludWUgICMgU2tpcCByYXcgdHJhbnNjcmlwdCB0eXBlcwoKICAgICAgICBub3RlX3RpdGxlID0gaXRlbS5nZXQoImRhdGFfdGl0bGUiKSBvciBpdGVtLmdldCgiZGF0YV90YWJfbmFtZSIpIG9yIGR0eXBlCiAgICAgICAgdHJ5OgogICAgICAgICAgICBub3RlX2RhdGEgPSBfZmV0Y2hfczNfanNvbih1cmwpCiAgICAgICAgICAgIGlmIGlzaW5zdGFuY2Uobm90ZV9kYXRhLCBsaXN0KToKICAgICAgICAgICAgICAgIGNvbnRlbnQgPSAiXG4iLmpvaW4oCiAgICAgICAgICAgICAgICAgICAgc3RyKHNlZy5nZXQoImNvbnRlbnQiKSBvciBzZWcuZ2V0KCJ0ZXh0Iikgb3Igc2VnKQogICAgICAgICAgICAgICAgICAgIGZvciBzZWcgaW4gbm90ZV9kYXRhIGlmIHNlZwogICAgICAgICAgICAgICAgKQogICAgICAgICAgICBlbGlmIGlzaW5zdGFuY2Uobm90ZV9kYXRhLCBkaWN0KToKICAgICAgICAgICAgICAgIGNvbnRlbnQgPSBqc29uLmR1bXBzKG5vdGVfZGF0YSwgaW5kZW50PTIpCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBjb250ZW50ID0gc3RyKG5vdGVfZGF0YSkKCiAgICAgICAgICAgIGlmIGNvbnRlbnQuc3RyaXAoKToKICAgICAgICAgICAgICAgIG5vdGVzLmFwcGVuZCh7InR5cGUiOiBkdHlwZSwgInRpdGxlIjogbm90ZV90aXRsZSwgImNvbnRlbnQiOiBjb250ZW50fSkKICAgICAgICBleGNlcHQgRXhjZXB0aW9uIGFzIGU6CiAgICAgICAgICAgIG5vdGVzLmFwcGVuZCh7InR5cGUiOiBkdHlwZSwgInRpdGxlIjogbm90ZV90aXRsZSwgImNvbnRlbnQiOiBmIkVycm9yOiB7ZX0ifSkKCiAgICByZXR1cm4ganNvbi5kdW1wcyh7CiAgICAgICAgImlkIjogcmVjb3JkaW5nX2lkLAogICAgICAgICJ0aXRsZSI6IHRpdGxlLAogICAgICAgICJkYXRlIjogX2ZtdF9kYXRlKGRhdGEuZ2V0KCJzdGFydF90aW1lIiwgMCkpLAogICAgICAgICJub3RlcyI6IG5vdGVzIGlmIG5vdGVzIGVsc2UgW3sidHlwZSI6ICJub25lIiwgImNvbnRlbnQiOiAiTm8gbm90ZXMgYXZhaWxhYmxlIGZvciB0aGlzIHJlY29yZGluZy4ifV0sCiAgICB9LCBpbmRlbnQ9MikKCgpAbWNwLnRvb2woKQpkZWYgcGxhdWRfZ2V0X3JlY29yZGluZ19kZXRhaWwocmVjb3JkaW5nX2lkOiBzdHIpIC0+IHN0cjoKICAgICIiIgogICAgR2V0IGZ1bGwgbWV0YWRhdGEgZm9yIGEgUGxhdWQgcmVjb3JkaW5nIGluY2x1ZGluZyB0aXRsZSwgZGF0ZSwgZHVyYXRpb24sCiAgICB0cmFuc2NyaXB0IGF2YWlsYWJpbGl0eSwgYW5kIGF2YWlsYWJsZSBjb250ZW50IHR5cGVzLgoKICAgIEFyZ3M6CiAgICAgICAgcmVjb3JkaW5nX2lkOiBUaGUgcmVjb3JkaW5nIElEIChmcm9tIHBsYXVkX2xpc3RfcmVjb3JkaW5ncykuCiAgICAiIiIKICAgIHJlc3AgPSBfYXBpX2dldChmIi9maWxlL2RldGFpbC97cmVjb3JkaW5nX2lkfSIpCiAgICBkYXRhID0gcmVzcC5nZXQoImRhdGEiLCByZXNwKSBpZiBpc2luc3RhbmNlKHJlc3AsIGRpY3QpIGVsc2UgcmVzcAoKICAgIGNvbnRlbnRfbGlzdCA9IGRhdGEuZ2V0KCJjb250ZW50X2xpc3QiKSBvciBbXQogICAgY29udGVudF90eXBlcyA9IFtpdGVtLmdldCgiZGF0YV90eXBlIikgZm9yIGl0ZW0gaW4gY29udGVudF9saXN0IGlmIGl0ZW0uZ2V0KCJkYXRhX3R5cGUiKV0KCiAgICByZXR1cm4ganNvbi5kdW1wcyh7CiAgICAgICAgImlkIjogcmVjb3JkaW5nX2lkLAogICAgICAgICJ0aXRsZSI6IGRhdGEuZ2V0KCJmaWxlX25hbWUiKSBvciBkYXRhLmdldCgiZmlsZW5hbWUiKSBvciBkYXRhLmdldCgidGl0bGUiKSBvciAiKHVudGl0bGVkKSIsCiAgICAgICAgImRhdGUiOiBfZm10X2RhdGUoZGF0YS5nZXQoInN0YXJ0X3RpbWUiLCAwKSksCiAgICAgICAgImR1cmF0aW9uIjogX2ZtdF9kdXJhdGlvbihkYXRhLmdldCgiZHVyYXRpb24iLCAwKSksCiAgICAgICAgImhhc190cmFuc2NyaXB0IjogInRyYW5zYWN0aW9uIiBpbiBjb250ZW50X3R5cGVzIG9yICJ0cmFuc2FjdGlvbl9wb2xpc2giIGluIGNvbnRlbnRfdHlwZXMsCiAgICAgICAgImhhc19zdW1tYXJ5IjogIm91dGxpbmUiIGluIGNvbnRlbnRfdHlwZXMsCiAgICAgICAgImNvbnRlbnRfdHlwZXMiOiBjb250ZW50X3R5cGVzLAogICAgICAgICJkZXZpY2UiOiBkYXRhLmdldCgic2VyaWFsX251bWJlciIpIG9yIGRhdGEuZ2V0KCJkZXZpY2VfbmFtZSIpIG9yICJ1bmtub3duIiwKICAgICAgICAidGFncyI6IGRhdGEuZ2V0KCJmaWxldGFnX2lkX2xpc3QiKSBvciBkYXRhLmdldCgiZmlsZXRhZyIpIG9yIFtdLAogICAgfSwgaW5kZW50PTIpCgoKQG1jcC50b29sKCkKZGVmIHBsYXVkX3VzZXJfaW5mbygpIC0+IHN0cjoKICAgICIiIkdldCB0aGUgY3VycmVudCBQbGF1ZCBhY2NvdW50IGluZm9ybWF0aW9uIGFuZCBjb25uZWN0aW9uIHN0YXR1cy4iIiIKICAgIHJldHVybiBqc29uLmR1bXBzKHsKICAgICAgICAicmVnaW9uIjogUExBVURfUkVHSU9OLAogICAgICAgICJhcGlfYmFzZSI6IEJBU0VfVVJMLAogICAgICAgICJ0b2tlbl9sb2FkZWQiOiBib29sKF9sb2FkX3Rva2VuKCkpLAogICAgfSwgaW5kZW50PTIpCgoKaWYgX19uYW1lX18gPT0gIl9fbWFpbl9fIjoKICAgIG1jcC5ydW4oKQo= \ No newline at end of file +IyEvdXNyL2Jpbi9lbnYgcHl0aG9uMwoiIiIKUGxhdWQgTUNQIFNlcnZlciBmb3IgTVBNCkNvbm5lY3RzIHRvIHRoZSBQbGF1ZCBBUEkgYW5kIGV4cG9zZXMgdG9vbHMgZm9yIGxpc3RpbmcsIHNlYXJjaGluZywKYW5kIHJlYWRpbmcgdHJhbnNjcmlwdHMsIHN1bW1hcmllcywgYW5kIG5vdGVzIGZyb20gUGxhdWQgcmVjb3JkaW5ncy4KCkNyZWRlbnRpYWxzIChjaGVja2VkIGluIG9yZGVyKToKICAxLiBQTEFVRF9UT0tFTiBlbnZpcm9ubWVudCB2YXJpYWJsZQogIDIuIH4vLnBsYXVkL3Rva2Vucy1tY3AuanNvbiAgKGRlc2t0b3AgYXBwIGF1dGhUb2tlbiDigJQgdmFsaWQgfjYgbW9udGhzKQogIDMuIH4vLnBsYXVkL2NvbmZpZy5qc29uICAgICAgKG1hbnVhbGx5IGltcG9ydGVkIDI0LWhvdXIgd2ViIHRva2VuKQoKVG8gcmVuZXc6IHJlLXJ1biBwbGF1ZF9kZWNyeXB0X3Rva2Vucy5weSBmcm9tIHRoZSBDbGF1ZGUgQ29Xb3JrIGZvbGRlci4KIiIiCgppbXBvcnQgZ3ppcAppbXBvcnQganNvbgppbXBvcnQgb3MKaW1wb3J0IHN1YnByb2Nlc3MKaW1wb3J0IHVybGxpYi5wYXJzZQpmcm9tIGRhdGV0aW1lIGltcG9ydCBkYXRldGltZSwgdGltZXpvbmUKZnJvbSBwYXRobGliIGltcG9ydCBQYXRoCmZyb20gdHlwaW5nIGltcG9ydCBPcHRpb25hbAoKZnJvbSBtY3Auc2VydmVyLmZhc3RtY3AgaW1wb3J0IEZhc3RNQ1AKCiMg4pSA4pSAIENvbmZpZ3VyYXRpb24g4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAClBMQVVEX1JFR0lPTiA9IG9zLmVudmlyb24uZ2V0KCJQTEFVRF9SRUdJT04iLCAidXMiKQpCQVNFX1VSTCA9ICJodHRwczovL2FwaS5wbGF1ZC5ldSIgaWYgUExBVURfUkVHSU9OID09ICJldSIgZWxzZSAiaHR0cHM6Ly9hcGkucGxhdWQuYWkiCkNPTkZJR19QQVRIICAgICAgPSBQYXRoLmhvbWUoKSAvICIucGxhdWQiIC8gImNvbmZpZy5qc29uIgpUT0tFTlNfTUNQX1BBVEggID0gUGF0aC5ob21lKCkgLyAiLnBsYXVkIiAvICJ0b2tlbnMtbWNwLmpzb24iCgoKIyDilIDilIAgVG9rZW4gcmVzb2x1dGlvbiDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKCmRlZiBfbG9hZF90b2tlbigpIC0+IE9wdGlvbmFsW3N0cl06CiAgICAjIDEuIEVudmlyb25tZW50IHZhcmlhYmxlIG92ZXJyaWRlCiAgICBlbnZfdG9rZW4gPSBvcy5lbnZpcm9uLmdldCgiUExBVURfVE9LRU4iLCAiIikuc3RyaXAoKQogICAgaWYgZW52X3Rva2VuOgogICAgICAgIHJldHVybiBlbnZfdG9rZW4KCiAgICAjIDIuIHRva2Vucy1tY3AuanNvbiDigJQgZGVza3RvcCBhcHAgYXV0aFRva2VuICh+Ni1tb250aCBleHBpcnkpCiAgICAjICAgIFdyaXR0ZW4gYnkgcGxhdWRfZGVjcnlwdF90b2tlbnMucHk7IHJlbmV3IGJ5IHJlLXJ1bm5pbmcgdGhhdCBzY3JpcHQuCiAgICBpZiBUT0tFTlNfTUNQX1BBVEguZXhpc3RzKCk6CiAgICAgICAgdHJ5OgogICAgICAgICAgICBkYXRhID0ganNvbi5sb2FkcyhUT0tFTlNfTUNQX1BBVEgucmVhZF90ZXh0KCkpCiAgICAgICAgICAgIHQgPSBkYXRhLmdldCgiYWNjZXNzX3Rva2VuIiwgIiIpLnN0cmlwKCkKICAgICAgICAgICAgaWYgdDoKICAgICAgICAgICAgICAgIHJldHVybiB0CiAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbjoKICAgICAgICAgICAgcGFzcwoKICAgICMgMy4gY29uZmlnLmpzb24g4oCUIG1hbnVhbGx5IGltcG9ydGVkIDI0LWhvdXIgd2ViIHRva2VuIChsZWdhY3kgZmFsbGJhY2spCiAgICBpZiBDT05GSUdfUEFUSC5leGlzdHMoKToKICAgICAgICB0cnk6CiAgICAgICAgICAgIGRhdGEgPSBqc29uLmxvYWRzKENPTkZJR19QQVRILnJlYWRfdGV4dCgpKQogICAgICAgICAgICB0b2tlbl9ibG9jayA9IGRhdGEuZ2V0KCJ0b2tlbiIpCiAgICAgICAgICAgIGlmIGlzaW5zdGFuY2UodG9rZW5fYmxvY2ssIGRpY3QpOgogICAgICAgICAgICAgICAgdCA9ICh0b2tlbl9ibG9jay5nZXQoInRva2VuIikgb3IgdG9rZW5fYmxvY2suZ2V0KCJhY2Nlc3NUb2tlbiIpIG9yICIiKS5zdHJpcCgpCiAgICAgICAgICAgICAgICBpZiB0OgogICAgICAgICAgICAgICAgICAgIHJldHVybiB0CiAgICAgICAgICAgIGlmIGlzaW5zdGFuY2UodG9rZW5fYmxvY2ssIHN0cikgYW5kIHRva2VuX2Jsb2NrLnN0cmlwKCk6CiAgICAgICAgICAgICAgICByZXR1cm4gdG9rZW5fYmxvY2suc3RyaXAoKQogICAgICAgIGV4Y2VwdCBFeGNlcHRpb246CiAgICAgICAgICAgIHBhc3MKCiAgICByZXR1cm4gTm9uZQoKCmRlZiBfZ2V0X3Rva2VuKCkgLT4gc3RyOgogICAgdG9rZW4gPSBfbG9hZF90b2tlbigpCiAgICBpZiBub3QgdG9rZW46CiAgICAgICAgcmFpc2UgUnVudGltZUVycm9yKAogICAgICAgICAgICAiTm8gUGxhdWQgdG9rZW4gZm91bmQuIFJ1biB0aGUgcGxhdWQtY29ubmVjdG9yIGltcG9ydC10b2tlbiBjb21tYW5kICIKICAgICAgICAgICAgIm9yIHNldCB0aGUgUExBVURfVE9LRU4gZW52aXJvbm1lbnQgdmFyaWFibGUuIgogICAgICAgICkKICAgIHJldHVybiB0b2tlbgoKCiMg4pSA4pSAIEhUVFAgaGVscGVycyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKCmRlZiBfYXBpX2dldChwYXRoOiBzdHIsIHBhcmFtczogT3B0aW9uYWxbZGljdF0gPSBOb25lKSAtPiBkaWN0OgogICAgIiIiR0VUIHJlcXVlc3QgdG8gdGhlIFBsYXVkIEFQSSB1c2luZyBjdXJsIChieXBhc3NlcyBDbG91ZGZsYXJlIGJyb3dzZXIgY2hlY2spLiIiIgogICAgdG9rZW4gPSBfZ2V0X3Rva2VuKCkKICAgIHVybCA9IGYie0JBU0VfVVJMfXtwYXRofSIKICAgIGlmIHBhcmFtczoKICAgICAgICBxdWVyeSA9ICImIi5qb2luKAogICAgICAgICAgICBmIntrfT17dXJsbGliLnBhcnNlLnF1b3RlKHN0cih2KSl9IgogICAgICAgICAgICBmb3IgaywgdiBpbiBwYXJhbXMuaXRlbXMoKSBpZiB2IGlzIG5vdCBOb25lCiAgICAgICAgKQogICAgICAgIGlmIHF1ZXJ5OgogICAgICAgICAgICB1cmwgPSBmInt1cmx9P3txdWVyeX0iCgogICAgcmVzdWx0ID0gc3VicHJvY2Vzcy5ydW4oCiAgICAgICAgWyJjdXJsIiwgIi1zIiwgIi1mIiwKICAgICAgICAgIi1IIiwgZiJBdXRob3JpemF0aW9uOiBCZWFyZXIge3Rva2VufSIsCiAgICAgICAgICItSCIsICJBY2NlcHQ6IGFwcGxpY2F0aW9uL2pzb24iLAogICAgICAgICB1cmxdLAogICAgICAgIGNhcHR1cmVfb3V0cHV0PVRydWUsIHRleHQ9VHJ1ZSwgdGltZW91dD0zMCwKICAgICkKICAgIGlmIHJlc3VsdC5yZXR1cm5jb2RlICE9IDA6CiAgICAgICAgcmFpc2UgUnVudGltZUVycm9yKAogICAgICAgICAgICBmIlBsYXVkIEFQSSBlcnJvciAoY3VybCBleGl0IHtyZXN1bHQucmV0dXJuY29kZX0pOiB7cmVzdWx0LnN0ZGVycls6MzAwXX0iCiAgICAgICAgKQogICAgdHJ5OgogICAgICAgIHJldHVybiBqc29uLmxvYWRzKHJlc3VsdC5zdGRvdXQpCiAgICBleGNlcHQganNvbi5KU09ORGVjb2RlRXJyb3I6CiAgICAgICAgcmFpc2UgUnVudGltZUVycm9yKGYiSW52YWxpZCBKU09OIGZyb20gUGxhdWQgQVBJOiB7cmVzdWx0LnN0ZG91dFs6MzAwXX0iKQoKCmRlZiBfZmV0Y2hfczNfanNvbih1cmw6IHN0cikgLT4gb2JqZWN0OgogICAgIiIiRmV0Y2ggYW5kIGRlY29tcHJlc3MgYSBnemlwcGVkIEpTT04gZnJvbSBhIHNpZ25lZCBTMyBVUkwuIiIiCiAgICByZXN1bHQgPSBzdWJwcm9jZXNzLnJ1bigKICAgICAgICBbImN1cmwiLCAiLXMiLCAiLWYiLCB1cmxdLAogICAgICAgIGNhcHR1cmVfb3V0cHV0PVRydWUsIHRpbWVvdXQ9MzAsCiAgICApCiAgICBpZiByZXN1bHQucmV0dXJuY29kZSAhPSAwOgogICAgICAgIHJhaXNlIFJ1bnRpbWVFcnJvcihmIlMzIGZldGNoIGZhaWxlZCAoY3VybCBleGl0IHtyZXN1bHQucmV0dXJuY29kZX0pIikKICAgIHRyeToKICAgICAgICBjb250ZW50ID0gZ3ppcC5kZWNvbXByZXNzKHJlc3VsdC5zdGRvdXQpCiAgICBleGNlcHQgT1NFcnJvcjoKICAgICAgICBjb250ZW50ID0gcmVzdWx0LnN0ZG91dCAgIyBOb3QgZ3ppcHBlZAogICAgcmV0dXJuIGpzb24ubG9hZHMoY29udGVudC5kZWNvZGUoInV0Zi04IikpCgoKIyDilIDilIAgRGF0YSBoZWxwZXJzIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgAoKZGVmIF9mbXRfZHVyYXRpb24obXM6IGludCkgLT4gc3RyOgogICAgbWlucyA9IG1zIC8vIDYwMDAwCiAgICBpZiBtaW5zIDwgNjA6CiAgICAgICAgcmV0dXJuIGYie21pbnN9bSIKICAgIHJldHVybiBmInttaW5zIC8vIDYwfWgge21pbnMgJSA2MH1tIgoKCmRlZiBfZm10X2RhdGUodHNfbXM6IGludCkgLT4gc3RyOgogICAgdHJ5OgogICAgICAgIGR0ID0gZGF0ZXRpbWUuZnJvbXRpbWVzdGFtcCh0c19tcyAvIDEwMDAsIHR6PXRpbWV6b25lLnV0YykKICAgICAgICByZXR1cm4gZHQuc3RyZnRpbWUoIiVZLSVtLSVkICVIOiVNIFVUQyIpCiAgICBleGNlcHQgRXhjZXB0aW9uOgogICAgICAgIHJldHVybiBzdHIodHNfbXMpCgoKZGVmIF9zdW1tYXJpc2VfcmVjb3JkaW5nKHI6IGRpY3QpIC0+IGRpY3Q6CiAgICAiIiJSZXR1cm4gYSBjb21wYWN0IGRpY3Qgc3VpdGFibGUgZm9yIGxpc3RpbmcuIiIiCiAgICByZXR1cm4gewogICAgICAgICJpZCI6IHIuZ2V0KCJpZCIsICIiKSwKICAgICAgICAidGl0bGUiOiByLmdldCgiZmlsZW5hbWUiKSBvciByLmdldCgiZmlsZV9uYW1lIikgb3Igci5nZXQoInRpdGxlIikgb3IgIih1bnRpdGxlZCkiLAogICAgICAgICJkYXRlIjogX2ZtdF9kYXRlKHIuZ2V0KCJzdGFydF90aW1lIiwgMCkpLAogICAgICAgICJkdXJhdGlvbiI6IF9mbXRfZHVyYXRpb24oci5nZXQoImR1cmF0aW9uIiwgMCkpLAogICAgICAgICJoYXNfdHJhbnNjcmlwdCI6IGJvb2woci5nZXQoImlzX3RyYW5zIikpLAogICAgICAgICJoYXNfc3VtbWFyeSI6IGJvb2woci5nZXQoImF1dG9fc3VtX25vdGUiKSBvciByLmdldCgiaXNfc3VtIikpLAogICAgfQoKCmRlZiBfZm9ybWF0X3RyYW5zY3JpcHQoc2VnbWVudHM6IGxpc3QpIC0+IHN0cjoKICAgICIiIkZvcm1hdCB0cmFuc2NyaXB0IHNlZ21lbnRzIGludG8gcmVhZGFibGUgdGV4dC4iIiIKICAgIGxpbmVzID0gW10KICAgIGN1cnJlbnRfc3BlYWtlciA9IE5vbmUKICAgIGZvciBzZWcgaW4gc2VnbWVudHM6CiAgICAgICAgc3BlYWtlciA9IHNlZy5nZXQoInNwZWFrZXIiKSBvciBzZWcuZ2V0KCJvcmlnaW5hbF9zcGVha2VyIikgb3IgIiIKICAgICAgICBjb250ZW50ID0gc2VnLmdldCgiY29udGVudCIsICIiKS5zdHJpcCgpCiAgICAgICAgaWYgbm90IGNvbnRlbnQ6CiAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgaWYgc3BlYWtlciBhbmQgc3BlYWtlciAhPSBjdXJyZW50X3NwZWFrZXI6CiAgICAgICAgICAgIGlmIGxpbmVzOgogICAgICAgICAgICAgICAgbGluZXMuYXBwZW5kKCIiKQogICAgICAgICAgICBsaW5lcy5hcHBlbmQoZiJbe3NwZWFrZXJ9XSIpCiAgICAgICAgICAgIGN1cnJlbnRfc3BlYWtlciA9IHNwZWFrZXIKICAgICAgICBsaW5lcy5hcHBlbmQoY29udGVudCkKICAgIHJldHVybiAiXG4iLmpvaW4obGluZXMpCgoKZGVmIF9nZXRfY29udGVudF91cmwoY29udGVudF9saXN0OiBsaXN0LCBkYXRhX3R5cGU6IHN0cikgLT4gT3B0aW9uYWxbc3RyXToKICAgICIiIkZpbmQgYSBkYXRhX2xpbmsgVVJMIGZyb20gY29udGVudF9saXN0IGJ5IGRhdGFfdHlwZS4iIiIKICAgIGZvciBpdGVtIGluIGNvbnRlbnRfbGlzdDoKICAgICAgICBpZiBpdGVtLmdldCgiZGF0YV90eXBlIikgPT0gZGF0YV90eXBlIGFuZCBpdGVtLmdldCgiZGF0YV9saW5rIik6CiAgICAgICAgICAgIHJldHVybiBpdGVtWyJkYXRhX2xpbmsiXQogICAgcmV0dXJuIE5vbmUKCgojIOKUgOKUgCBNQ1Agc2VydmVyIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgAptY3AgPSBGYXN0TUNQKCJwbGF1ZC1tcG0iKQoKCkBtY3AudG9vbCgpCmRlZiBwbGF1ZF9saXN0X3JlY29yZGluZ3MoCiAgICBsaW1pdDogaW50ID0gNTAsCiAgICBvbmx5X3dpdGhfdHJhbnNjcmlwdDogYm9vbCA9IEZhbHNlLAopIC0+IHN0cjoKICAgICIiIgogICAgTGlzdCBQbGF1ZCByZWNvcmRpbmdzIG5ld2VzdC1maXJzdC4KCiAgICBBcmdzOgogICAgICAgIGxpbWl0OiBNYXggbnVtYmVyIHRvIHJldHVybiAoZGVmYXVsdCA1MCwgbWF4IDIwMCkuCiAgICAgICAgb25seV93aXRoX3RyYW5zY3JpcHQ6IElmIHRydWUsIG9ubHkgcmV0dXJuIHJlY29yZGluZ3MgdGhhdCBoYXZlIGEgdHJhbnNjcmlwdC4KICAgICIiIgogICAgcmVzcCA9IF9hcGlfZ2V0KCIvZmlsZS9zaW1wbGUvd2ViIikKICAgIGlmIGlzaW5zdGFuY2UocmVzcCwgZGljdCk6CiAgICAgICAgcmVjb3JkaW5ncyA9IHJlc3AuZ2V0KCJkYXRhX2ZpbGVfbGlzdCIpIG9yIHJlc3AuZ2V0KCJkYXRhIikgb3IgW10KICAgIGVsc2U6CiAgICAgICAgcmVjb3JkaW5ncyA9IHJlc3AgaWYgaXNpbnN0YW5jZShyZXNwLCBsaXN0KSBlbHNlIFtdCgogICAgaWYgb25seV93aXRoX3RyYW5zY3JpcHQ6CiAgICAgICAgcmVjb3JkaW5ncyA9IFtyIGZvciByIGluIHJlY29yZGluZ3MgaWYgci5nZXQoImlzX3RyYW5zIildCgogICAgcmVjb3JkaW5ncyA9IHJlY29yZGluZ3NbOm1pbihsaW1pdCwgMjAwKV0KICAgIHJldHVybiBqc29uLmR1bXBzKFtfc3VtbWFyaXNlX3JlY29yZGluZyhyKSBmb3IgciBpbiByZWNvcmRpbmdzXSwgaW5kZW50PTIpCgoKQG1jcC50b29sKCkKZGVmIHBsYXVkX3NlYXJjaF9yZWNvcmRpbmdzKAogICAgdGl0bGVfY29udGFpbnM6IE9wdGlvbmFsW3N0cl0gPSBOb25lLAogICAgc3RhcnRfZGF0ZTogT3B0aW9uYWxbc3RyXSA9IE5vbmUsCiAgICBlbmRfZGF0ZTogT3B0aW9uYWxbc3RyXSA9IE5vbmUsCiAgICBvbmx5X3dpdGhfdHJhbnNjcmlwdDogYm9vbCA9IEZhbHNlLAogICAgbWF4X3Jlc3VsdHM6IGludCA9IDIwLAopIC0+IHN0cjoKICAgICIiIgogICAgU2VhcmNoIHJlY29yZGluZ3MgYnkgdGl0bGUgYW5kL29yIGRhdGUgcmFuZ2UuCgogICAgQXJnczoKICAgICAgICB0aXRsZV9jb250YWluczogU3Vic3RyaW5nIHRvIG1hdGNoIGluIHRoZSByZWNvcmRpbmcgdGl0bGUgKGNhc2UtaW5zZW5zaXRpdmUpLgogICAgICAgIHN0YXJ0X2RhdGU6IElTTyBkYXRlIHN0cmluZywgZS5nLiAnMjAyNi0wNC0wMScuIE9ubHkgcmVjb3JkaW5ncyBvbiBvciBhZnRlciB0aGlzIGRhdGUuCiAgICAgICAgZW5kX2RhdGU6IElTTyBkYXRlIHN0cmluZywgZS5nLiAnMjAyNi0wNS0wMScuIE9ubHkgcmVjb3JkaW5ncyBvbiBvciBiZWZvcmUgdGhpcyBkYXRlLgogICAgICAgIG9ubHlfd2l0aF90cmFuc2NyaXB0OiBJZiB0cnVlLCBvbmx5IHJldHVybiByZWNvcmRpbmdzIHRoYXZlIGEgdHJhbnNjcmlwdC4KICAgICAgICBtYXhfcmVzdWx0czogTWF4IG51bWJlciBvZiByZXN1bHRzIHRvIHJldHVybiAoZGVmYXVsdCAyMCkuCiAgICAiIiIKICAgIHJlc3AgPSBfYXBpX2dldCgiL2ZpbGUvc2ltcGxlL3dlYiIpCiAgICBpZiBpc2luc3RhbmNlKHJlc3AsIGRpY3QpOgogICAgICAgIHJlY29yZGluZ3MgPSByZXNwLmdldCgiZGF0YV9maWxlX2xpc3QiKSBvciByZXNwLmdldCgiZGF0YSIpIG9yIFtdCiAgICBlbHNlOgogICAgICAgIHJlY29yZGluZ3MgPSByZXNwIGlmIGlzaW5zdGFuY2UocmVzcCwgbGlzdCkgZWxzZSBbXQoKICAgIGRlZiBtYXRjaGVzKHI6IGRpY3QpIC0+IGJvb2w6CiAgICAgICAgaWYgb25seV93aXRoX3RyYW5zY3JpcHQgYW5kIG5vdCByLmdldCgiaXNfdHJhbnMiKToKICAgICAgICAgICAgcmV0dXJuIEZhbHNlCiAgICAgICAgdGl0bGUgPSAoci5nZXQoImZpbGVuYW1lIikgb3Igci5nZXQoImZpbGVfbmFtZSIpIG9yIHIuZ2V0KCJ0aXRsZSIpIG9yICIiKS5sb3dlcigpCiAgICAgICAgaWYgdGl0bGVfY29udGFpbnMgYW5kIHRpdGxlX2NvbnRhaW5zLmxvd2VyKCkgbm90IGluIHRpdGxlOgogICAgICAgICAgICByZXR1cm4gRmFsc2UKICAgICAgICBpZiBzdGFydF9kYXRlIG9yIGVuZF9kYXRlOgogICAgICAgICAgICB0c19tcyA9IHIuZ2V0KCJzdGFydF90aW1lIiwgMCkKICAgICAgICAgICAgcmVjX2RhdGUgPSBkYXRldGltZS5mcm9tdGltZXN0YW1wKHRzX21zIC8gMTAwMCwgdHo9dGltZXpvbmUudXRjKS5kYXRlKCkKICAgICAgICAgICAgaWYgc3RhcnRfZGF0ZSBhbmQgcmVjX2RhdGUgPCBkYXRldGltZS5mcm9taXNvZm9ybWF0KHN0YXJ0X2RhdGUpLmRhdGUoKToKICAgICAgICAgICAgICAgIHJldHVybiBGYWxzZQogICAgICAgICAgICBpZiBlbmRfZGF0ZSBhbmQgcmVjX2RhdGUgPiBkYXRldGltZS5mcm9taXNvZm9ybWF0KGVuZF9kYXRlKS5kYXRlKCk6CiAgICAgICAgICAgICAgICByZXR1cm4gRmFsc2UKICAgICAgICByZXR1cm4gVHJ1ZQoKICAgIG1hdGNoZWQgPSBbciBmb3IgciBpbiByZWNvcmRpbmdzIGlmIG1hdGNoZXMocildWzptYXhfcmVzdWx0c10KICAgIHJldHVybiBqc29uLmR1bXBzKFtfc3VtbWFyaXNlX3JlY29yZGluZyhyKSBmb3IgciBpbiBtYXRjaGVkXSwgaW5kZW50PTIpCgoKQG1jcC50b29sKCkKZGVmIHBsYXVkX2dldF90cmFuc2NyaXB0KHJlY29yZGluZ19pZDogc3RyKSAtPiBzdHI6CiAgICAiIiIKICAgIEdldCB0aGUgZnVsbCB0cmFuc2NyaXB0IGZvciBhIFBsYXVkIHJlY29yZGluZy4KCiAgICBBcmdzOgogICAgICAgIHJlY29yZGluZ19pZDogVGhlIHJlY29yZGluZyBJRCAoZnJvbSBwbGF1ZF9saXN0X3JlY29yZGluZ3MpLgogICAgIiIiCiAgICByZXNwID0gX2FwaV9nZXQoZiIvZmlsZS9kZXRhaWwve3JlY29yZGluZ19pZH0iKQogICAgZGF0YSA9IHJlc3AuZ2V0KCJkYXRhIiwgcmVzcCkgaWYgaXNpbnN0YW5jZShyZXNwLCBkaWN0KSBlbHNlIHJlc3AKCiAgICB0aXRsZSA9IGRhdGEuZ2V0KCJmaWxlX25hbWUiKSBvciBkYXRhLmdldCgiZmlsZW5hbWUiKSBvciBkYXRhLmdldCgidGl0bGUiKSBvciAiKHVudGl0bGVkKSIKICAgIGNvbnRlbnRfbGlzdCA9IGRhdGEuZ2V0KCJjb250ZW50X2xpc3QiKSBvciBbXQogICAgdHJhbnNjcmlwdCA9ICIiCgogICAgIyBUcnkgcG9saXNoZWQgdHJhbnNjcmlwdCBmaXJzdCwgZmFsbCBiYWNrIHRvIHJhdwogICAgZm9yIGR0eXBlIGluICgidHJhbnNhY3Rpb25fcG9saXNoIiwgInRyYW5zYWN0aW9uIik6CiAgICAgICAgdXJsID0gX2dldF9jb250ZW50X3VybChjb250ZW50X2xpc3QsIGR0eXBlKQogICAgICAgIGlmIHVybDoKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgc2VnbWVudHMgPSBfZmV0Y2hfczNfanNvbih1cmwpCiAgICAgICAgICAgICAgICBpZiBpc2luc3RhbmNlKHNlZ21lbnRzLCBsaXN0KToKICAgICAgICAgICAgICAgICAgICB0cmFuc2NyaXB0ID0gX2Zvcm1hdF90cmFuc2NyaXB0KHNlZ21lbnRzKQogICAgICAgICAgICAgICAgICAgIGlmIHRyYW5zY3JpcHQ6CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgZToKICAgICAgICAgICAgICAgIHRyYW5zY3JpcHQgPSBmIkVycm9yIGZldGNoaW5nIHRyYW5zY3JpcHQ6IHtlfSIKICAgICAgICAgICAgICAgIGJyZWFrCgogICAgcmV0dXJuIGpzb24uZHVtcHMoewogICAgICAgICJpZCI6IHJlY29yZGluZ19pZCwKICAgICAgICAidGl0bGUiOiB0aXRsZSwKICAgICAgICAiZGF0ZSI6IF9mbXRfZGF0ZShkYXRhLmdldCgic3RhcnRfdGltZSIsIDApKSwKICAgICAgICAiZHVyYXRpb24iOiBfZm10X2R1cmF0aW9uKGRhdGEuZ2V0KCJkdXJhdGlvbiIsIDApKSwKICAgICAgICAidHJhbnNjcmlwdCI6IHRyYW5zY3JpcHQgb3IgIk5vIHRyYW5zY3JpcHQgYXZhaWxhYmxlIGZvciB0aGlzIHJlY29yZGluZy4iLAogICAgfSwgaW5kZW50PTIpCgoKQG1jcC50b29sKCkKZGVmIHBsYXVkX2dldF9zdW1tYXJ5KHJlY29yZGluZ19pZDogc3RyKSAtPiBzdHI6CiAgICAiIiIKICAgIEdldCB0aGUgQUktZ2VuZXJhdGVkIHN1bW1hcnkvb3V0bGluZSBmb3IgYSBQbGF1ZCByZWNvcmRpbmcuCgogICAgQXJnczoKICAgICAgICByZWNvcmRpbmdfaWQ6IFRoZSByZWNvcmRpbmcgSUQgKGZyb20gcGxhdWRfbGlzdF9yZWNvcmRpbmdzKS4KICAgICIiIgogICAgcmVzcCA9IF9hcGlfZ2V0KGYiL2ZpbGUvZGV0YWlsL3tyZWNvcmRpbmdfaWR9IikKICAgIGRhdGEgPSByZXNwLmdldCgiZGF0YSIsIHJlc3ApIGlmIGlzaW5zdGFuY2UocmVzcCwgZGljdCkgZWxzZSByZXNwCgogICAgdGl0bGUgPSBkYXRhLmdldCgiZmlsZV9uYW1lIikgb3IgZGF0YS5nZXQoImZpbGVuYW1lIikgb3IgZGF0YS5nZXQoInRpdGxlIikgb3IgIih1bnRpdGxlZCkiCiAgICBjb250ZW50X2xpc3QgPSBkYXRhLmdldCgiY29udGVudF9saXN0Iikgb3IgW10KICAgIHN1bW1hcnkgPSAiIgoKICAgIHVybCA9IF9nZXRfY29udGVudF91cmwoY29udGVudF9saXN0LCAib3V0bGluZSIpCiAgICBpZiB1cmw6CiAgICAgICAgdHJ5OgogICAgICAgICAgICBvdXRsaW5lX2RhdGEgPSBfZmV0Y2hfczNfanNvbih1cmwpCiAgICAgICAgICAgIGlmIGlzaW5zdGFuY2Uob3V0bGluZV9kYXRhLCBkaWN0KToKICAgICAgICAgICAgICAgIHN1bW1hcnkgPSBqc29uLmR1bXBzKG91dGxpbmVfZGF0YSwgaW5kZW50PTIpCiAgICAgICAgICAgIGVsaWYgaXNpbnN0YW5jZShvdXRsaW5lX2RhdGEsIGxpc3QpOgogICAgICAgICAgICAgICAgcGFydHMgPSBbXQogICAgICAgICAgICAgICAgZm9yIGl0ZW0gaW4gb3V0bGluZV9kYXRhOgogICAgICAgICAgICAgICAgICAgIGlmIGlzaW5zdGFuY2UoaXRlbSwgZGljdCk6CiAgICAgICAgICAgICAgICAgICAgICAgIHBhcnRzLmFwcGVuZChpdGVtLmdldCgiY29udGVudCIpIG9yIGl0ZW0uZ2V0KCJ0ZXh0Iikgb3Igc3RyKGl0ZW0pKQogICAgICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgICAgIHBhcnRzLmFwcGVuZChzdHIoaXRlbSkpCiAgICAgICAgICAgICAgICBzdW1tYXJ5ID0gIlxuXG4iLmpvaW4ocCBmb3IgcCBpbiBwYXJ0cyBpZiBwKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgc3VtbWFyeSA9IHN0cihvdXRsaW5lX2RhdGEpCiAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOgogICAgICAgICAgICBzdW1tYXJ5ID0gZiJFcnJvciBmZXRjaGluZyBzdW1tYXJ5OiB7ZX0iCgogICAgcmV0dXJuIGpzb24uZHVtcHMoewogICAgICAgICJpZCI6IHJlY29yZGluZ19pZCwKICAgICAgICAidGl0bGUiOiB0aXRsZSwKICAgICAgICAiZGF0ZSI6IF9mbXRfZGF0ZShkYXRhLmdldCgic3RhcnRfdGltZSIsIDApKSwKICAgICAgICAic3VtbWFyeSI6IHN1bW1hcnkgb3IgIk5vIHN1bW1hcnkgYXZhaWxhYmxlIGZvciB0aGlzIHJlY29yZGluZy4iLAogICAgfSwgaW5kZW50PTIpCgoKQG1jcC50b29sKCkKZGVmIHBsYXVkX2dldF9ub3RlcyhyZWNvcmRpbmdfaWQ6IHN0cikgLT4gc3RyOgogICAgIiIiCiAgICBHZXQgQUktZ2VuZXJhdGVkIG5vdGVzIGFuZCBhY3Rpb24gaXRlbXMgZm9yIGEgUGxhdWQgcmVjb3JkaW5nLgogICAgUmV0dXJucyBhbGwgbm90ZSBlbnRyaWVzIGZyb20gdGhlIGNvbnRlbnRfbGlzdCAoYWN0aW9uIGl0ZW1zLCBrZXkgcG9pbnRzLCBldGMuKS4KCiAgICBBcmdzOgogICAgICAgIHJlY29yZGluZ19pZDogVGhlIHJlY29yZGluZyBJRCAoZnJvbSBwbGF1ZF9saXN0X3JlY29yZGluZ3MpLgogICAgIiIiCiAgICByZXNwID0gX2FwaV9nZXQoZiIvZmlsZS9kZXRhaWwve3JlY29yZGluZ19pZH0iKQogICAgZGF0YSA9IHJlc3AuZ2V0KCJkYXRhIiwgcmVzcCkgaWYgaXNpbnN0YW5jZShyZXNwLCBkaWN0KSBlbHNlIHJlc3AKCiAgICB0aXRsZSA9IGRhdGEuZ2V0KCJmaWxlX25hbWUiKSBvciBkYXRhLmdldCgiZmlsZW5hbWUiKSBvciBkYXRhLmdldCgidGl0bGUiKSBvciAiKHVudGl0bGVkKSIKICAgIGNvbnRlbnRfbGlzdCA9IGRhdGEuZ2V0KCJjb250ZW50X2xpc3QiKSBvciBbXQogICAgbm90ZXMgPSBbXQoKICAgIGZvciBpdGVtIGluIGNvbnRlbnRfbGlzdDoKICAgICAgICBkdHlwZSA9IGl0ZW0uZ2V0KCJkYXRhX3R5cGUiLCAiIikKICAgICAgICB1cmwgPSBpdGVtLmdldCgiZGF0YV9saW5rIikKICAgICAgICBpZiBub3QgdXJsIG9yIGR0eXBlIGluICgidHJhbnNhY3Rpb24iLCAidHJhbnNhY3Rpb25fcG9saXNoIik6CiAgICAgICAgICAgIGNvbnRpbnVlICAjIFNraXAgcmF3IHRyYW5zY3JpcHQgdHlwZXMKCiAgICAgICAgbm90ZV90aXRsZSA9IGl0ZW0uZ2V0KCJkYXRhX3RpdGxlIikgb3IgaXRlbS5nZXQoImRhdGFfdGFiX25hbWUiKSBvciBkdHlwZQogICAgICAgIHRyeToKICAgICAgICAgICAgbm90ZV9kYXRhID0gX2ZldGNoX3MzX2pzb24odXJsKQogICAgICAgICAgICBpZiBpc2luc3RhbmNlKG5vdGVfZGF0YSwgbGlzdCk6CiAgICAgICAgICAgICAgICBjb250ZW50ID0gIlxuIi5qb2luKAogICAgICAgICAgICAgICAgICAgIHN0cihzZWcuZ2V0KCJjb250ZW50Iikgb3Igc2VnLmdldCgidGV4dCIpIG9yIHNlZykKICAgICAgICAgICAgICAgICAgICBmb3Igc2VnIGluIG5vdGVfZGF0YSBpZiBzZWcKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgZWxpZiBpc2luc3RhbmNlKG5vdGVfZGF0YSwgZGljdCk6CiAgICAgICAgICAgICAgICBjb250ZW50ID0ganNvbi5kdW1wcyhub3RlX2RhdGEsIGluZGVudD0yKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgY29udGVudCA9IHN0cihub3RlX2RhdGEpCgogICAgICAgICAgICBpZiBjb250ZW50LnN0cmlwKCk6CiAgICAgICAgICAgICAgICBub3Rlcy5hcHBlbmQoeyJ0eXBlIjogZHR5cGUsICJ0aXRsZSI6IG5vdGVfdGl0bGUsICJjb250ZW50IjogY29udGVudH0pCiAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOgogICAgICAgICAgICBub3Rlcy5hcHBlbmQoeyJ0eXBlIjogZHR5cGUsICJ0aXRsZSI6IG5vdGVfdGl0bGUsICJjb250ZW50IjogZiJFcnJvcjoge2V9In0pCgogICAgcmV0dXJuIGpzb24uZHVtcHMoewogICAgICAgICJpZCI6IHJlY29yZGluZ19pZCwKICAgICAgICAidGl0bGUiOiB0aXRsZSwKICAgICAgICAiZGF0ZSI6IF9mbXRfZGF0ZShkYXRhLmdldCgic3RhcnRfdGltZSIsIDApKSwKICAgICAgICAibm90ZXMiOiBub3RlcyBpZiBub3RlcyBlbHNlIFt7InR5cGUiOiAibm9uZSIsICJjb250ZW50IjogIk5vIG5vdGVzIGF2YWlsYWJsZSBmb3IgdGhpcyByZWNvcmRpbmcuIn1dLAogICAgfSwgaW5kZW50PTIpCgoKQG1jcC50b29sKCkKZGVmIHBsYXVkX2dldF9yZWNvcmRpbmdfZGV0YWlsKHJlY29yZGluZ19pZDogc3RyKSAtPiBzdHI6CiAgICAiIiIKICAgIEdldCBmdWxsIG1ldGFkYXRhIGZvciBhIFBsYXVkIHJlY29yZGluZyBpbmNsdWRpbmcgdGl0bGUsIGRhdGUsIGR1cmF0aW9uLAogICAgdHJhbnNjcmlwdCBhdmFpbGFiaWxpdHksIGFuZCBhdmFpbGFibGUgY29udGVudCB0eXBlcy4KCiAgICBBcmdzOgogICAgICAgIHJlY29yZGluZ19pZDogVGhlIHJlY29yZGluZyBJRCAoZnJvbSBwbGF1ZF9saXN0X3JlY29yZGluZ3MpLgogICAgIiIiCiAgICByZXNwID0gX2FwaV9nZXQoZiIvZmlsZS9kZXRhaWwve3JlY29yZGluZ19pZH0iKQogICAgZGF0YSA9IHJlc3AuZ2V0KCJkYXRhIiwgcmVzcCkgaWYgaXNpbnN0YW5jZShyZXNwLCBkaWN0KSBlbHNlIHJlc3AKCiAgICBjb250ZW50X2xpc3QgPSBkYXRhLmdldCgiY29udGVudF9saXN0Iikgb3IgW10KICAgIGNvbnRlbnRfdHlwZXMgPSBbaXRlbS5nZXQoImRhdGFfdHlwZSIpIGZvciBpdGVtIGluIGNvbnRlbnRfbGlzdCBpZiBpdGVtLmdldCgiZGF0YV90eXBlIildCgogICAgcmV0dXJuIGpzb24uZHVtcHMoewogICAgICAgICJpZCI6IHJlY29yZGluZ19pZCwKICAgICAgICAidGl0bGUiOiBkYXRhLmdldCgiZmlsZV9uYW1lIikgb3IgZGF0YS5nZXQoImZpbGVuYW1lIikgb3IgZGF0YS5nZXQoInRpdGxlIikgb3IgIih1bnRpdGxlZCkiLAogICAgICAgICJkYXRlIjogX2ZtdF9kYXRlKGRhdGEuZ2V0KCJzdGFydF90aW1lIiwgMCkpLAogICAgICAgICJkdXJhdGlvbiI6IF9mbXRfZHVyYXRpb24oZGF0YS5nZXQoImR1cmF0aW9uIiwgMCkpLAogICAgICAgICJoYXNfdHJhbnNjcmlwdCI6ICJ0cmFuc2FjdGlvbiIgaW4gY29udGVudF90eXBlcyBvciAidHJhbnNhY3Rpb25fcG9saXNoIiBpbiBjb250ZW50X3R5cGVzLAogICAgICAgICJoYXNfc3VtbWFyeSI6ICJvdXRsaW5lIiBpbiBjb250ZW50X3R5cGVzLAogICAgICAgICJjb250ZW50X3R5cGVzIjogY29udGVudF90eXBlcywKICAgICAgICAiZGV2aWNlIjogZGF0YS5nZXQoInNlcmlhbF9udW1iZXIiKSBvciBkYXRhLmdldCgiZGV2aWNlX25hbWUiKSBvciAidW5rbm93biIsCiAgICAgICAgInRhZ3MiOiBkYXRhLmdldCgiZmlsZXRhZ19pZF9saXN0Iikgb3IgZGF0YS5nZXQoImZpbGV0YWciKSBvciBbXSwKICAgIH0sIGluZGVudD0yKQoKCkBtY3AudG9vbCgpCmRlZiBwbGF1ZF91c2VyX2luZm8oKSAtPiBzdHI6CiAgICAiIiJHZXQgdGhlIGN1cnJlbnQgUGxhdWQgYWNjb3VudCBpbmZvcm1hdGlvbiBhbmQgY29ubmVjdGlvbiBzdGF0dXMuIiIiCiAgICByZXR1cm4ganNvbi5kdW1wcyh7CiAgICAgICAgInJlZ2lvbiI6IFBMQVVEX1JFR0lPTiwKICAgICAgICAiYXBpX2Jhc2UiOiBCQVNFX1VSTCwKICAgICAgICAidG9rZW5fbG9hZGVkIjogYm9vbChfbG9hZF90b2tlbigpKSwKICAgIH0sIGluZGVudD0yKQoKCmlmIF9fbmFtZV9fID09ICJfX21haW5fXyI6CiAgICBtY3AucnVuKCkK \ No newline at end of file