UNPKG

@decaf-ts/fabric-weaver

Version:
165 lines 23.8 kB
import express from "express"; import { DEFAULT_PORT, MiddlewareRoutes } from "../constants/peer-middleware"; import { Logging, LogLevel } from "@decaf-ts/logging"; // import { info, mkdir, rm } from "@aeon/fabric-integration"; // import * as express from "express"; // import * as fs from "fs"; // import * as path from "path"; // import { Express } from "express"; // import { execSync } from "child_process"; // import { peerBootConfig } from "../utils/types"; // import { copyAndOverrideYaml } from "../utils/genesis"; // import * as bodyParser from "body-parser"; // import { MiddlewareRoutes } from "../../shared"; export class PeerMiddleware { constructor(port) { //Change later mock security this.accessKeys = []; // Mock security, replace with actual access keys this.app = express(); this.port = port || DEFAULT_PORT; this.log = Logging.for(PeerMiddleware); this.log.setConfig({ level: LogLevel.debug, }); // this.app.use(bodyParser.json({ limit: '50mb' })); // Adjust the size as needed // this.app.use(bodyParser.urlencoded({ limit: '50mb', extended: true })); // Middleware to parse JSON this.app.use(express.json()); // Route Setup this.routes(); } routes() { const methodNames = Object.getOwnPropertyNames(Object.getPrototypeOf(this)).filter((name) => name !== "constructor" && typeof this[name] === "function" && name !== "routes" && name !== "listen"); for (const methodName of methodNames) { try { this[methodName](); } catch (error) { this.log.error(`Error calling method ${methodName}: ${error}`); } } } addAccessKey() { this.log.info("Adding access key endpoint registered"); const addKey = (req, res) => { this.log.info("Received request to add access key"); const body = req.body; this.log.debug(`Received access key: ${body.accessKey}`); if (!body.accessKey) { return res.status(400).send({ error: "Missing access key" }); } if (this.accessKeys.includes(body.accessKey)) { return res.status(409).send({ error: "Access key already exists" }); } this.accessKeys.push(body.accessKey); this.log.debug(`Access keys: ${this.accessKeys.join(", ")}`); res .status(201) .contentType("application/json") .send({ message: "Access key added successfully" }); }; this.app.post(`${MiddlewareRoutes.ACCESS_KEY}`, addKey); } hello() { this.app.get("/", (req, res) => { res.send("Hello, world!"); }); } healthcheck() { this.log.info("Healthcheck endpoint registered"); const healthcheck = (req, res) => { res.status(200).contentType("application/json").send({ message: "OK" }); }; this.app.get(`${MiddlewareRoutes.HEALTZ}`, healthcheck); } // private handleOrganizationEnroll(req: express.Request, res: express.Response): void{ // const orgDetails = req.body // try { // mkdir('./temp/'); // const replacements = { // ORG_NAME: orgDetails.name, // ORG_MSPID: orgDetails.id, // ORG_MSPDIR: "/aeon/temp/ca/peers/peer-0/client/msp" // } // copyAndOverrideYaml('./configs/orgtx.yaml', './temp/configtx.yaml', replacements) // fs.writeFileSync('./temp/mspdir.tar.gz', Buffer.from(orgDetails.mspdir)); // execSync('tar -xvf ./temp/mspdir.tar.gz -C ./temp'); // execSync(`peer channel fetch config ./temp/config_block.pb \ // --channelID '${this.config.channel.name}' \ // --orderer '${this.config.channel.ordererEndpoint}' \ // --tls \ // --cafile '${this.config.tls.tls}'`); // execSync(`configtxlator proto_decode --input ./temp/config_block.pb \ // --type common.Block \ // --output ./temp/config_block.json`); // execSync(`jq .data.data[0].payload.data.config ./temp/config_block.json > ./temp/config.json`); // execSync(`cd temp && configtxgen -printOrg ${orgDetails.name} > ./org.json`) ; // execSync( `jq -s '.[0] * {"channel_group":{"groups":{"Application":{"groups": {"${orgDetails.name}":.[1]}}}}}' \ // ./temp/config.json \ // ./temp/org.json > ./temp/modified_config.json`); // execSync(`configtxlator proto_encode \ // --input ./temp/config.json \ // --type common.Config \ // --output ./temp/config.pb`); // execSync( `configtxlator proto_encode \ // --input ./temp/modified_config.json \ // --type common.Config \ // --output ./temp/modified_config.pb`); // execSync(`configtxlator compute_update \ // --channel_id aeon-main \ // --original ./temp/config.pb \ // --updated ./temp/modified_config.pb \ // --output ./temp/org_update.pb`); // execSync(`configtxlator proto_decode \ // --input ./temp/org_update.pb \ // --type common.ConfigUpdate \ // --output ./temp/org_update.json`); // execSync(`echo '{"payload":{"header":{"channel_header":{"channel_id":"'${this.config.channel.name}'", "type":2}},"data":{"config_update":'$(cat ./temp/org_update.json)'}}}' \ // | jq . > ./temp/org_update_in_envelope.json`); // execSync( `configtxlator proto_encode \ // --input ./temp/org_update_in_envelope.json \ // --type common.Envelope \ // --output ./temp/org_update_in_envelope.pb`); // execSync(`cd temp && peer channel signconfigtx \ // -f ./org_update_in_envelope.pb`); // execSync(`peer channel update \ // -f ./temp/org_update_in_envelope.pb \ // -c ${this.config.channel.name} \ // -o ${this.config.channel.ordererEndpoint} \ // --tls \ // --cafile ${this.config.tls.tls}`); // res.status(200).send({success:true}) // } catch(e:unknown) { // res.status(500).send(e) // } finally { // rm("./temp"); // } // } // private handleOrganizationPeerAnchor(req: express.Request, res: express.Response): void{ // const body = req.body // try { // mkdir('./temp/'); // fs.writeFileSync(path.join(process.cwd(), "temp/anchor_update_in_envelope.pb"), Buffer.from(body.block)) // execSync(`peer channel update \ // -f /aeon/temp/anchor_update_in_envelope.pb \ // --channelID ${this.config.channel.name} \ // --orderer ${this.config.channel.ordererEndpoint} \ // --tls \ // --cafile ${this.config.channel.ordererCaFile}`); // res.status(200).send({success:true}) // } catch (e: unknown) { // res.status(500).send(e) // } finally { // rm("./temp"); // } // } listen() { this.app.listen(this.port, () => { this.log.info(`Peer Middleware running on port: ${this.port}`); }); } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUGVlck1pZGRsZXdhcmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29yZS9taWRkbGV3YXJlcy9QZWVyTWlkZGxld2FyZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLE9BQU8sTUFBTSxTQUFTLENBQUM7QUFDOUIsT0FBTyxFQUFFLFlBQVksRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQzlFLE9BQU8sRUFBVSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDOUQsOERBQThEO0FBQzlELHNDQUFzQztBQUN0Qyw0QkFBNEI7QUFDNUIsZ0NBQWdDO0FBQ2hDLHFDQUFxQztBQUNyQyw0Q0FBNEM7QUFDNUMsbURBQW1EO0FBQ25ELDBEQUEwRDtBQUMxRCw2Q0FBNkM7QUFDN0MsbURBQW1EO0FBRW5ELE1BQU0sT0FBTyxjQUFjO0lBUXpCLFlBQVksSUFBWTtRQUh4Qiw0QkFBNEI7UUFDcEIsZUFBVSxHQUFhLEVBQUUsQ0FBQyxDQUFDLGlEQUFpRDtRQUdsRixJQUFJLENBQUMsR0FBRyxHQUFHLE9BQU8sRUFBRSxDQUFDO1FBQ3JCLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxJQUFJLFlBQVksQ0FBQztRQUNqQyxJQUFJLENBQUMsR0FBRyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsY0FBYyxDQUFDLENBQUM7UUFFdkMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUM7WUFDakIsS0FBSyxFQUFFLFFBQVEsQ0FBQyxLQUFLO1NBQ3RCLENBQUMsQ0FBQztRQUVILG9GQUFvRjtRQUNwRiwwRUFBMEU7UUFFMUUsMkJBQTJCO1FBQzNCLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBRTdCLGNBQWM7UUFDZCxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7SUFDaEIsQ0FBQztJQUVPLE1BQU07UUFD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SUFDbEMsa0JBQWtCO0lBQ2xCLHdCQUF3QjtJQUN4QixRQUFRO0lBQ1IsSUFBSTtJQUVKLDJGQUEyRjtJQUMzRiw0QkFBNEI7SUFFNUIsWUFBWTtJQUNaLDRCQUE0QjtJQUU1QixtSEFBbUg7SUFFbkgsMENBQTBDO0lBQzFDLDJEQUEyRDtJQUMzRCx3REFBd0Q7SUFDeEQsaUVBQWlFO0lBQ2pFLHNCQUFzQjtJQUN0QiwrREFBK0Q7SUFFL0QsK0NBQStDO0lBQy9DLDZCQUE2QjtJQUM3QixrQ0FBa0M7SUFDbEMsa0JBQWtCO0lBQ2xCLHdCQUF3QjtJQUN4QixRQUFRO0lBQ1IsSUFBSTtJQUVKLE1BQU07UUFDSixJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLEdBQUcsRUFBRTtZQUM5QixJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxvQ0FBb0MsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7UUFDakUsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBFeHByZXNzLCBSZXNwb25zZSwgUmVxdWVzdCB9IGZyb20gXCJleHByZXNzXCI7XG5pbXBvcnQgZXhwcmVzcyBmcm9tIFwiZXhwcmVzc1wiO1xuaW1wb3J0IHsgREVGQVVMVF9QT1JULCBNaWRkbGV3YXJlUm91dGVzIH0gZnJvbSBcIi4uL2NvbnN0YW50cy9wZWVyLW1pZGRsZXdhcmVcIjtcbmltcG9ydCB7IExvZ2dlciwgTG9nZ2luZywgTG9nTGV2ZWwgfSBmcm9tIFwiQGRlY2FmLXRzL2xvZ2dpbmdcIjtcbi8vIGltcG9ydCB7IGluZm8sIG1rZGlyLCBybSB9IGZyb20gXCJAYWVvbi9mYWJyaWMtaW50ZWdyYXRpb25cIjtcbi8vIGltcG9ydCAqIGFzIGV4cHJlc3MgZnJvbSBcImV4cHJlc3NcIjtcbi8vIGltcG9ydCAqIGFzIGZzIGZyb20gXCJmc1wiO1xuLy8gaW1wb3J0ICogYXMgcGF0aCBmcm9tIFwicGF0aFwiO1xuLy8gaW1wb3J0IHsgRXhwcmVzcyB9IGZyb20gXCJleHByZXNzXCI7XG4vLyBpbXBvcnQgeyBleGVjU3luYyB9IGZyb20gXCJjaGlsZF9wcm9jZXNzXCI7XG4vLyBpbXBvcnQgeyBwZWVyQm9vdENvbmZpZyB9IGZyb20gXCIuLi91dGlscy90eXBlc1wiO1xuLy8gaW1wb3J0IHsgY29weUFuZE92ZXJyaWRlWWFtbCB9IGZyb20gXCIuLi91dGlscy9nZW5lc2lzXCI7XG4vLyBpbXBvcnQgKiBhcyBib2R5UGFyc2VyIGZyb20gXCJib2R5LXBhcnNlclwiO1xuLy8gaW1wb3J0IHsgTWlkZGxld2FyZVJvdXRlcyB9IGZyb20gXCIuLi8uLi9zaGFyZWRcIjtcblxuZXhwb3J0IGNsYXNzIFBlZXJNaWRkbGV3YXJlIHtcbiAgcHJpdmF0ZSByZWFkb25seSBhcHA6IEV4cHJlc3M7XG4gIHByaXZhdGUgcmVhZG9ubHkgcG9ydDogbnVtYmVyO1xuICBwcml2YXRlIHJlYWRvbmx5IGxvZzogTG9nZ2VyO1xuXG4gIC8vQ2hhbmdlIGxhdGVyIG1vY2sgc2VjdXJpdHlcbiAgcHJpdmF0ZSBhY2Nlc3NLZXlzOiBzdHJpbmdbXSA9IFtdOyAvLyBNb2NrIHNlY3VyaXR5LCByZXBsYWNlIHdpdGggYWN0dWFsIGFjY2VzcyBrZXlzXG5cbiAgY29uc3RydWN0b3IocG9ydDogbnVtYmVyKSB7XG4gICAgdGhpcy5hcHAgPSBleHByZXNzKCk7XG4gICAgdGhpcy5wb3J0ID0gcG9ydCB8fCBERUZBVUxUX1BPUlQ7XG4gICAgdGhpcy5sb2cgPSBMb2dnaW5nLmZvcihQZWVyTWlkZGxld2FyZSk7XG5cbiAgICB0aGlzLmxvZy5zZXRDb25maWcoe1xuICAgICAgbGV2ZWw6IExvZ0xldmVsLmRlYnVnLFxuICAgIH0pO1xuXG4gICAgLy8gICAgdGhpcy5hcHAudXNlKGJvZHlQYXJzZXIuanNvbih7IGxpbWl0OiAnNTBtYicgfSkpOyAvLyBBZGp1c3QgdGhlIHNpemUgYXMgbmVlZGVkXG4gICAgLy8gdGhpcy5hcHAudXNlKGJvZHlQYXJzZXIudXJsZW5jb2RlZCh7IGxpbWl0OiAnNTBtYicsIGV4dGVuZGVkOiB0cnVlIH0pKTtcblxuICAgIC8vIE1pZGRsZXdhcmUgdG8gcGFyc2UgSlNPTlxuICAgIHRoaXMuYXBwLnVzZShleHByZXNzLmpzb24oKSk7XG5cbiAgICAvLyBSb3V0ZSBTZXR1cFxuICAgIHRoaXMucm91dGVzKCk7XG4gIH1cblxuICBwcml2YXRlIHJvdXRlcygpOiB2b2lkIHtcbiAgICBjb25zdCBtZXRob2ROYW1lcyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKFxuICAgICAgT2JqZWN0LmdldFByb3RvdHlwZU9mKHRoaXMpXG4gICAgKS5maWx0ZXIoXG4gICAgICAobmFtZSkgPT5cbiAgICAgICAgbmFtZSAhPT0gXCJjb25zdHJ1Y3RvclwiICYmXG4gICAgICAgIHR5cGVvZiB0aGlzW25hbWUgYXMga2V5b2YgUGVlck1pZGRsZXdhcmVdID09PSBcImZ1bmN0aW9uXCIgJiZcbiAgICAgICAgbmFtZSAhPT0gXCJyb3V0ZXNcIiAmJlxuICAgICAgICBuYW1lICE9PSBcImxpc3RlblwiXG4gICAgKTtcblxuICAgIGZvciAoY29uc3QgbWV0aG9kTmFtZSBvZiBtZXRob2ROYW1lcykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgdGhpc1ttZXRob2ROYW1lIGFzIGtleW9mIFBlZXJNaWRkbGV3YXJlXSgpO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgdGhpcy5sb2cuZXJyb3IoYEVycm9yIGNhbGxpbmcgbWV0aG9kICR7bWV0aG9kTmFtZX06ICR7ZXJyb3J9YCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhZGRBY2Nlc3NLZXkoKTogdm9pZCB7XG4gICAgdGhpcy5sb2cuaW5mbyhcIkFkZGluZyBhY2Nlc3Mga2V5IGVuZHBvaW50IHJlZ2lzdGVyZWRcIik7XG5cbiAgICBjb25zdCBhZGRLZXkgPSAocmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlKSA9PiB7XG4gICAgICB0aGlzLmxvZy5pbmZvKFwiUmVjZWl2ZWQgcmVxdWVzdCB0byBhZGQgYWNjZXNzIGtleVwiKTtcblxuICAgICAgY29uc3QgYm9keSA9IHJlcS5ib2R5O1xuXG4gICAgICB0aGlzLmxvZy5kZWJ1ZyhgUmVjZWl2ZWQgYWNjZXNzIGtleTogJHtib2R5LmFjY2Vzc0tleX1gKTtcblxuICAgICAgaWYgKCFib2R5LmFjY2Vzc0tleSkge1xuICAgICAgICByZXR1cm4gcmVzLnN0YXR1cyg0MDApLnNlbmQoeyBlcnJvcjogXCJNaXNzaW5nIGFjY2VzcyBrZXlcIiB9KTtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLmFjY2Vzc0tleXMuaW5jbHVkZXMoYm9keS5hY2Nlc3NLZXkpKSB7XG4gICAgICAgIHJldHVybiByZXMuc3RhdHVzKDQwOSkuc2VuZCh7IGVycm9yOiBcIkFjY2VzcyBrZXkgYWxyZWFkeSBleGlzdHNcIiB9KTtcbiAgICAgIH1cbiAgICAgIHRoaXMuYWNjZXNzS2V5cy5wdXNoKGJvZHkuYWNjZXNzS2V5KTtcblxuICAgICAgdGhpcy5sb2cuZGVidWcoYEFjY2VzcyBrZXlzOiAke3RoaXMuYWNjZXNzS2V5cy5qb2luKFwiLCBcIil9YCk7XG4gICAgICByZXNcbiAgICAgICAgLnN0YXR1cygyMDEpXG4gICAgICAgIC5jb250ZW50VHlwZShcImFwcGxpY2F0aW9uL2pzb25cIilcbiAgICAgICAgLnNlbmQoeyBtZXNzYWdlOiBcIkFjY2VzcyBrZXkgYWRkZWQgc3VjY2Vzc2Z1bGx5XCIgfSk7XG4gICAgfTtcblxuICAgIHRoaXMuYXBwLnBvc3QoYCR7TWlkZGxld2FyZVJvdXRlcy5BQ0NFU1NfS0VZfWAsIGFkZEtleSk7XG4gIH1cblxuICBwcml2YXRlIGhlbGxvKCk6IHZvaWQge1xuICAgIHRoaXMuYXBwLmdldChcIi9cIiwgKHJlcSwgcmVzKSA9PiB7XG4gICAgICByZXMuc2VuZChcIkhlbGxvLCB3b3JsZCFcIik7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGhlYWx0aGNoZWNrKCk6IHZvaWQge1xuICAgIHRoaXMubG9nLmluZm8oXCJIZWFsdGhjaGVjayBlbmRwb2ludCByZWdpc3RlcmVkXCIpO1xuICAgIGNvbnN0IGhlYWx0aGNoZWNrID0gKHJlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSkgPT4ge1xuICAgICAgcmVzLnN0YXR1cygyMDApLmNvbnRlbnRUeXBlKFwiYXBwbGljYXRpb24vanNvblwiKS5zZW5kKHsgbWVzc2FnZTogXCJPS1wiIH0pO1xuICAgIH07XG5cbiAgICB0aGlzLmFwcC5nZXQoYCR7TWlkZGxld2FyZVJvdXRlcy5IRUFMVFp9YCwgaGVhbHRoY2hlY2spO1xuICB9XG5cbiAgLy8gcHJpdmF0ZSBoYW5kbGVPcmdhbml6YXRpb25FbnJvbGwocmVxOiBleHByZXNzLlJlcXVlc3QsIHJlczogZXhwcmVzcy5SZXNwb25zZSk6IHZvaWR7XG4gIC8vICAgICBjb25zdCBvcmdEZXRhaWxzID0gcmVxLmJvZHlcblxuICAvLyAgICAgdHJ5IHtcbiAgLy8gICAgICAgICBta2RpcignLi90ZW1wLycpO1xuXG4gIC8vICAgICAgICAgY29uc3QgcmVwbGFjZW1lbnRzID0ge1xuICAvLyAgICAgICAgICAgICBPUkdfTkFNRTogb3JnRGV0YWlscy5uYW1lLFxuICAvLyAgICAgICAgICAgICBPUkdfTVNQSUQ6IG9yZ0RldGFpbHMuaWQsXG4gIC8vICAgICAgICAgICAgIE9SR19NU1BESVI6IFwiL2Flb24vdGVtcC9jYS9wZWVycy9wZWVyLTAvY2xpZW50L21zcFwiXG4gIC8vICAgICAgICAgfVxuXG4gIC8vICAgICAgICAgY29weUFuZE92ZXJyaWRlWWFtbCgnLi9jb25maWdzL29yZ3R4LnlhbWwnLCAnLi90ZW1wL2NvbmZpZ3R4LnlhbWwnLCByZXBsYWNlbWVudHMpXG5cbiAgLy8gICAgICAgICBmcy53cml0ZUZpbGVTeW5jKCcuL3RlbXAvbXNwZGlyLnRhci5neicsIEJ1ZmZlci5mcm9tKG9yZ0RldGFpbHMubXNwZGlyKSk7XG5cbiAgLy8gICAgICAgICBleGVjU3luYygndGFyIC14dmYgLi90ZW1wL21zcGRpci50YXIuZ3ogLUMgLi90ZW1wJyk7XG5cbiAgLy8gICAgICAgICBleGVjU3luYyhgcGVlciBjaGFubmVsIGZldGNoIGNvbmZpZyAuL3RlbXAvY29uZmlnX2Jsb2NrLnBiIFxcXG4gIC8vICAgICAgICAgICAgIC0tY2hhbm5lbElEICcke3RoaXMuY29uZmlnLmNoYW5uZWwubmFtZX0nIFxcXG4gIC8vICAgICAgICAgICAgIC0tb3JkZXJlciAnJHt0aGlzLmNvbmZpZy5jaGFubmVsLm9yZGVyZXJFbmRwb2ludH0nIFxcXG4gIC8vICAgICAgICAgICAgIC0tdGxzIFxcXG4gIC8vICAgICAgICAgICAgIC0tY2FmaWxlICcke3RoaXMuY29uZmlnLnRscy50bHN9J2ApO1xuXG4gIC8vICAgICAgICAgZXhlY1N5bmMoYGNvbmZpZ3R4bGF0b3IgcHJvdG9fZGVjb2RlIC0taW5wdXQgLi90ZW1wL2NvbmZpZ19ibG9jay5wYiBcXFxuICAvLyAgICAgICAgICAgICAtLXR5cGUgY29tbW9uLkJsb2NrIFxcXG4gIC8vICAgICAgICAgICAgIC0tb3V0cHV0IC4vdGVtcC9jb25maWdfYmxvY2suanNvbmApO1xuXG4gIC8vICAgICAgICAgZXhlY1N5bmMoYGpxIC5kYXRhLmRhdGFbMF0ucGF5bG9hZC5kYXRhLmNvbmZpZyAuL3RlbXAvY29uZmlnX2Jsb2NrLmpzb24gPiAuL3RlbXAvY29uZmlnLmpzb25gKTtcblxuICAvLyAgICAgICAgIGV4ZWNTeW5jKGBjZCB0ZW1wICYmIGNvbmZpZ3R4Z2VuIC1wcmludE9yZyAke29yZ0RldGFpbHMubmFtZX0gPiAuL29yZy5qc29uYCkgO1xuXG4gIC8vICAgICAgICAgZXhlY1N5bmMoIGBqcSAtcyAnLlswXSAqIHtcImNoYW5uZWxfZ3JvdXBcIjp7XCJncm91cHNcIjp7XCJBcHBsaWNhdGlvblwiOntcImdyb3Vwc1wiOiB7XCIke29yZ0RldGFpbHMubmFtZX1cIjouWzFdfX19fX0nIFxcXG4gIC8vICAgICAgICAgICAgIC4vdGVtcC9jb25maWcuanNvbiBcXFxuICAvLyAgICAgICAgICAgICAuL3RlbXAvb3JnLmpzb24gPiAuL3RlbXAvbW9kaWZpZWRfY29uZmlnLmpzb25gKTtcblxuICAvLyAgICAgICAgIGV4ZWNTeW5jKGBjb25maWd0eGxhdG9yIHByb3RvX2VuY29kZSBcXFxuICAvLyAgICAgICAgICAgICAtLWlucHV0IC4vdGVtcC9jb25maWcuanNvbiBcXFxuICAvLyAgICAgICAgICAgICAtLXR5cGUgY29tbW9uLkNvbmZpZyBcXFxuICAvLyAgICAgICAgICAgICAtLW91dHB1dCAuL3RlbXAvY29uZmlnLnBiYCk7XG5cbiAgLy8gICAgICAgICBleGVjU3luYyggYGNvbmZpZ3R4bGF0b3IgcHJvdG9fZW5jb2RlIFxcXG4gIC8vICAgICAgICAgICAgIC0taW5wdXQgLi90ZW1wL21vZGlmaWVkX2NvbmZpZy5qc29uIFxcXG4gIC8vICAgICAgICAgICAgIC0tdHlwZSBjb21tb24uQ29uZmlnIFxcXG4gIC8vICAgICAgICAgICAgIC0tb3V0cHV0IC4vdGVtcC9tb2RpZmllZF9jb25maWcucGJgKTtcblxuICAvLyAgICAgICAgIGV4ZWNTeW5jKGBjb25maWd0eGxhdG9yIGNvbXB1dGVfdXBkYXRlIFxcXG4gIC8vICAgICAgICAgICAgIC0tY2hhbm5lbF9pZCBhZW9uLW1haW4gXFxcbiAgLy8gICAgICAgICAgICAgLS1vcmlnaW5hbCAuL3RlbXAvY29uZmlnLnBiIFxcXG4gIC8vICAgICAgICAgICAgIC0tdXBkYXRlZCAuL3RlbXAvbW9kaWZpZWRfY29uZmlnLnBiIFxcXG4gIC8vICAgICAgICAgICAgIC0tb3V0cHV0IC4vdGVtcC9vcmdfdXBkYXRlLnBiYCk7XG5cbiAgLy8gICAgICAgICBleGVjU3luYyhgY29uZmlndHhsYXRvciBwcm90b19kZWNvZGUgXFxcbiAgLy8gICAgICAgICAgICAgLS1pbnB1dCAuL3RlbXAvb3JnX3VwZGF0ZS5wYiBcXFxuICAvLyAgICAgICAgICAgICAtLXR5cGUgY29tbW9uLkNvbmZpZ1VwZGF0ZSBcXFxuICAvLyAgICAgICAgICAgICAtLW91dHB1dCAuL3RlbXAvb3JnX3VwZGF0ZS5qc29uYCk7XG5cbiAgLy8gICAgICAgICBleGVjU3luYyhgZWNobyAne1wicGF5bG9hZFwiOntcImhlYWRlclwiOntcImNoYW5uZWxfaGVhZGVyXCI6e1wiY2hhbm5lbF9pZFwiOlwiJyR7dGhpcy5jb25maWcuY2hhbm5lbC5uYW1lfSdcIiwgXCJ0eXBlXCI6Mn19LFwiZGF0YVwiOntcImNvbmZpZ191cGRhdGVcIjonJChjYXQgLi90ZW1wL29yZ191cGRhdGUuanNvbiknfX19JyBcXFxuICAvLyAgICAgICAgICAgICB8IGpxIC4gPiAuL3RlbXAvb3JnX3VwZGF0ZV9pbl9lbnZlbG9wZS5qc29uYCk7XG5cbiAgLy8gICAgICAgICBleGVjU3luYyggYGNvbmZpZ3R4bGF0b3IgcHJvdG9fZW5jb2RlIFxcXG4gIC8vICAgICAgICAgICAgIC0taW5wdXQgLi90ZW1wL29yZ191cGRhdGVfaW5fZW52ZWxvcGUuanNvbiBcXFxuICAvLyAgICAgICAgICAgICAtLXR5cGUgY29tbW9uLkVudmVsb3BlIFxcXG4gIC8vICAgICAgICAgICAgIC0tb3V0cHV0IC4vdGVtcC9vcmdfdXBkYXRlX2luX2VudmVsb3BlLnBiYCk7XG5cbiAgLy8gICAgICAgICBleGVjU3luYyhgY2QgdGVtcCAmJiBwZWVyIGNoYW5uZWwgc2lnbmNvbmZpZ3R4IFxcXG4gIC8vICAgICAgICAgICAgIC1mIC4vb3JnX3VwZGF0ZV9pbl9lbnZlbG9wZS5wYmApO1xuXG4gIC8vICAgICAgICAgZXhlY1N5bmMoYHBlZXIgY2hhbm5lbCB1cGRhdGUgXFxcbiAgLy8gICAgICAgICAgICAgLWYgLi90ZW1wL29yZ191cGRhdGVfaW5fZW52ZWxvcGUucGIgXFxcbiAgLy8gICAgICAgICAgICAgLWMgJHt0aGlzLmNvbmZpZy5jaGFubmVsLm5hbWV9IFxcXG4gIC8vICAgICAgICAgICAgIC1vICR7dGhpcy5jb25maWcuY2hhbm5lbC5vcmRlcmVyRW5kcG9pbnR9IFxcXG4gIC8vICAgICAgICAgICAgIC0tdGxzIFxcXG4gIC8vICAgICAgICAgICAgIC0tY2FmaWxlICR7dGhpcy5jb25maWcudGxzLnRsc31gKTtcblxuICAvLyAgICAgICAgIHJlcy5zdGF0dXMoMjAwKS5zZW5kKHtzdWNjZXNzOnRydWV9KVxuXG4gIC8vICAgICB9IGNhdGNoKGU6dW5rbm93bikge1xuICAvLyAgICAgICAgIHJlcy5zdGF0dXMoNTAwKS5zZW5kKGUpXG4gIC8vICAgICB9IGZpbmFsbHkge1xuICAvLyAgICAgICAgIHJtKFwiLi90ZW1wXCIpO1xuICAvLyAgICAgfVxuICAvLyB9XG5cbiAgLy8gcHJpdmF0ZSBoYW5kbGVPcmdhbml6YXRpb25QZWVyQW5jaG9yKHJlcTogZXhwcmVzcy5SZXF1ZXN0LCByZXM6IGV4cHJlc3MuUmVzcG9uc2UpOiB2b2lke1xuICAvLyAgICAgY29uc3QgYm9keSA9IHJlcS5ib2R5XG5cbiAgLy8gICAgIHRyeSB7XG4gIC8vICAgICAgICAgbWtkaXIoJy4vdGVtcC8nKTtcblxuICAvLyAgICAgICAgIGZzLndyaXRlRmlsZVN5bmMocGF0aC5qb2luKHByb2Nlc3MuY3dkKCksIFwidGVtcC9hbmNob3JfdXBkYXRlX2luX2VudmVsb3BlLnBiXCIpLCBCdWZmZXIuZnJvbShib2R5LmJsb2NrKSlcblxuICAvLyAgICAgICAgIGV4ZWNTeW5jKGBwZWVyIGNoYW5uZWwgdXBkYXRlIFxcXG4gIC8vICAgICAgICAgICAgIC1mIC9hZW9uL3RlbXAvYW5jaG9yX3VwZGF0ZV9pbl9lbnZlbG9wZS5wYiBcXFxuICAvLyAgICAgICAgICAgICAtLWNoYW5uZWxJRCAke3RoaXMuY29uZmlnLmNoYW5uZWwubmFtZX0gXFxcbiAgLy8gICAgICAgICAgICAgLS1vcmRlcmVyICR7dGhpcy5jb25maWcuY2hhbm5lbC5vcmRlcmVyRW5kcG9pbnR9IFxcXG4gIC8vICAgICAgICAgICAgIC0tdGxzIFxcXG4gIC8vICAgICAgICAgICAgIC0tY2FmaWxlICR7dGhpcy5jb25maWcuY2hhbm5lbC5vcmRlcmVyQ2FGaWxlfWApO1xuXG4gIC8vICAgICAgICAgcmVzLnN0YXR1cygyMDApLnNlbmQoe3N1Y2Nlc3M6dHJ1ZX0pXG4gIC8vICAgICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gIC8vICAgICAgICAgcmVzLnN0YXR1cyg1MDApLnNlbmQoZSlcbiAgLy8gICAgIH0gZmluYWxseSB7XG4gIC8vICAgICAgICAgcm0oXCIuL3RlbXBcIik7XG4gIC8vICAgICB9XG4gIC8vIH1cblxuICBsaXN0ZW4oKTogdm9pZCB7XG4gICAgdGhpcy5hcHAubGlzdGVuKHRoaXMucG9ydCwgKCkgPT4ge1xuICAgICAgdGhpcy5sb2cuaW5mbyhgUGVlciBNaWRkbGV3YXJlIHJ1bm5pbmcgb24gcG9ydDogJHt0aGlzLnBvcnR9YCk7XG4gICAgfSk7XG4gIH1cbn1cbiJdfQ==