indiaai-hackathon / datalab /web /socketio_to_pty.js
arshjaved's picture
normal Model Upload (teja)
f9f1a35 verified
raw
history blame
16.3 kB
"use strict";
/*
* Copyright 2020 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.SocketIoToPty = void 0;
exports.WebSocketToPty = WebSocketToPty;
var nodePty = require("node-pty");
var socketio = require("socket.io");
var ws_1 = require("ws");
var logging = require("./logging");
var sockets_1 = require("./sockets");
var sessionCounter = 0;
// Inspired by
// https://xtermjs.org/docs/guides/flowcontrol/#ideas-for-a-better-mechanism.
var ACK_CALLBACK_EVERY_BYTES = 100000;
var UNACKED_HIGH_WATERMARK = 5;
var UNACKED_LOW_WATERMARK = 2;
/** Socket<->terminal adapter. */
var Session = /** @class */ (function () {
function Session(socket) {
var _this = this;
this.socket = socket;
this.pendingAckCallbacks = 0;
this.writtenBytes = 0;
this.id = sessionCounter++;
this.socket.onClose(function (reason) {
logging.getLogger().debug('PTY socket disconnected for session %d reason: %s', _this.id, reason);
// Handle client disconnects to close sockets, so as to free up resources.
_this.close();
});
this.socket.onStringMessage(function (data) {
// Propagate the message over to the pty.
logging.getLogger().debug('Send data in session %d\n%s', _this.id, data);
var message = JSON.parse(data);
if (message.data) {
_this.pty.write(message.data);
}
if (message.cols && message.rows) {
_this.pty.resize(message.cols, message.rows);
}
if (message.ack) {
_this.pendingAckCallbacks--;
if (_this.pendingAckCallbacks < UNACKED_LOW_WATERMARK) {
_this.pty.resume();
}
}
});
this.pty = nodePty.spawn('tmux', ['new-session', '-A', '-D', '-s', '0'], {
name: 'xterm-color',
cwd: './content', // Which path should terminal start
// Pass environment variables
env: process.env,
});
this.pty.onData(function (data) {
_this.writtenBytes += data.length;
if (_this.writtenBytes < ACK_CALLBACK_EVERY_BYTES) {
var message = { data: data };
_this.socket.sendString(JSON.stringify(message));
}
else {
var message = { data: data, ack: true };
_this.socket.sendString(JSON.stringify(message));
_this.pendingAckCallbacks++;
_this.writtenBytes = 0;
if (_this.pendingAckCallbacks > UNACKED_HIGH_WATERMARK) {
_this.pty.pause();
}
}
});
this.pty.onExit(function (_a) {
var exitCode = _a.exitCode, signal = _a.signal;
_this.socket.close(false);
});
}
Session.prototype.close = function () {
this.socket.close(false);
this.pty.kill();
};
return Session;
}());
/** SocketIO to node-pty adapter. */
var SocketIoToPty = /** @class */ (function () {
function SocketIoToPty(path, server) {
this.path = path;
var io = socketio(server, {
path: path,
transports: ['polling'],
allowUpgrades: false,
// v2.10 changed default from 60s to 5s, prefer the longer timeout to
// avoid errant disconnects.
pingTimeout: 60000,
});
io.of('/').on('connection', function (socket) {
// Session manages its own lifetime.
// tslint:disable-next-line:no-unused-expression
new Session(new sockets_1.SocketIOAdapter(socket));
});
}
/** Return true iff path is handled by socket.io. */
SocketIoToPty.prototype.isPathProxied = function (path) {
return path.indexOf(this.path + '/') === 0;
};
return SocketIoToPty;
}());
exports.SocketIoToPty = SocketIoToPty;
/** WebSocket to pty adapter. */
function WebSocketToPty(request, sock, head) {
new ws_1.Server({ noServer: true }).handleUpgrade(request, sock, head, function (ws) {
// Session manages its own lifetime.
// tslint:disable-next-line:no-unused-expression
new Session(new sockets_1.WebSocketAdapter(ws));
});
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic29ja2V0aW9fdG9fcHR5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vdGhpcmRfcGFydHkvY29sYWIvc291cmNlcy9zb2NrZXRpb190b19wdHkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Ozs7Ozs7Ozs7OztHQWNHOzs7QUE4SEgsd0NBT0M7QUFqSUQsa0NBQW9DO0FBQ3BDLG9DQUFzQztBQUN0Qyx5QkFBMEI7QUFFMUIsbUNBQXFDO0FBQ3JDLHFDQUFvRTtBQVNwRSxJQUFJLGNBQWMsR0FBRyxDQUFDLENBQUM7QUFFdkIsY0FBYztBQUNkLDZFQUE2RTtBQUM3RSxJQUFNLHdCQUF3QixHQUFHLE1BQU0sQ0FBQztBQUN4QyxJQUFNLHNCQUFzQixHQUFHLENBQUMsQ0FBQztBQUNqQyxJQUFNLHFCQUFxQixHQUFHLENBQUMsQ0FBQztBQUVoQyxpQ0FBaUM7QUFDakM7SUFNRSxpQkFBNkIsTUFBYztRQUEzQyxpQkEwREM7UUExRDRCLFdBQU0sR0FBTixNQUFNLENBQVE7UUFIbkMsd0JBQW1CLEdBQUcsQ0FBQyxDQUFDO1FBQ3hCLGlCQUFZLEdBQUcsQ0FBQyxDQUFDO1FBR3ZCLElBQUksQ0FBQyxFQUFFLEdBQUcsY0FBYyxFQUFFLENBQUM7UUFFM0IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsVUFBQyxNQUFNO1lBQ3pCLE9BQU8sQ0FBQyxTQUFTLEVBQUUsQ0FBQyxLQUFLLENBQ3JCLG1EQUFtRCxFQUFFLEtBQUksQ0FBQyxFQUFFLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFFMUUsMEVBQTBFO1lBQzFFLEtBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNmLENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLE1BQU0sQ0FBQyxlQUFlLENBQUMsVUFBQyxJQUFZO1lBQ3ZDLHlDQUF5QztZQUN6QyxPQUFPLENBQUMsU0FBUyxFQUFFLENBQUMsS0FBSyxDQUFDLDZCQUE2QixFQUFFLEtBQUks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QyxJQUFNLEVBQUUsR0FBRyxRQUFRLENBQUMsTUFBTSxFQUFFO1lBQzFCLElBQUksTUFBQTtZQUNKLFVBQVUsRUFBRSxDQUFDLFNBQVMsQ0FBQztZQUN2QixhQUFhLEVBQUUsS0FBSztZQUNwQixxRUFBcUU7WUFDckUsNEJBQTRCO1lBQzVCLFdBQVcsRUFBRSxLQUFLO1NBQ25CLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLFlBQVksRUFBRSxVQUFDLE1BQXVCO1lBQ2xELG9DQUFvQztZQUNwQyxnREFBZ0Q7WUFDaEQsSUFBSSxPQUFPLENBQUMsSUFBSSx5QkFBZSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7UUFDM0MsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsb0RBQW9EO0lBQ3BELHFDQUFhLEdBQWIsVUFBYyxJQUFZO1FBQ3hCLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUM3QyxDQUFDO0lBQ0gsb0JBQUM7QUFBRCxDQUFDLEFBdEJELElBc0JDO0FBdEJZLHNDQUFhO0FBeUIxQixnQ0FBZ0M7QUFDaEMsU0FBZ0IsY0FBYyxDQUMxQixPQUE2QixFQUFFLElBQWdCLEVBQUUsSUFBWTtJQUMvRCxJQUFJLFdBQU0sQ0FBQyxFQUFDLFFBQVEsRUFBRSxJQUFJLEVBQUMsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxPQUFPLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxVQUFDLEVBQUU7UUFDakUsb0NBQW9DO1FBQ3BDLGdEQUFnRDtRQUNoRCxJQUFJLE9BQU8sQ0FBQyxJQUFJLDBCQUFnQixDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDeEMsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTsgeW91IG1heSBub3RcbiAqIHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mXG4gKiB0aGUgTGljZW5zZSBhdFxuICpcbiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUywgV0lUSE9VVFxuICogV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiBTZWUgdGhlXG4gKiBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucyB1bmRlclxuICogdGhlIExpY2Vuc2UuXG4gKi9cblxuaW1wb3J0ICogYXMgaHR0cCBmcm9tICdodHRwJztcbmltcG9ydCAqIGFzIG5ldCBmcm9tICduZXQnO1xuaW1wb3J0ICogYXMgbm9kZVB0eSBmcm9tICdub2RlLXB0eSc7XG5pbXBvcnQgKiBhcyBzb2NrZXRpbyBmcm9tICdzb2NrZXQuaW8nO1xuaW1wb3J0IHtTZXJ2ZXJ9IGZyb20gJ3dzJztcblxuaW1wb3J0ICogYXMgbG9nZ2luZyBmcm9tICcuL2xvZ2dpbmcnO1xuaW1wb3J0IHtTb2NrZXQsIFNvY2tldElPQWRhcHRlciwgV2ViU29ja2V0QWRhcHRlcn0gZnJvbSAnLi9zb2NrZXRzJztcblxuXG4vLyBQYXVzZSBhbmQgcmVzdW1lIGFyZSBtaXNzaW5nIGZyb20gdGhlIHR5cGluZ3MuXG5pbnRlcmZhY2UgUHR5IHtcbiAgcGF1c2UoKTogdm9pZDtcbiAgcmVzdW1lKCk6IHZvaWQ7XG59XG5cbmxldCBzZXNzaW9uQ291bnRlciA9IDA7XG5cbi8vIEluc3BpcmVkIGJ5XG4vLyBodHRwczovL3h0ZXJtanMub3JnL2RvY3MvZ3VpZGVzL2Zsb3djb250cm9sLyNpZGVhcy1mb3ItYS1iZXR0ZXItbWVjaGFuaXNtLlxuY29uc3QgQUNLX0NBTExCQUNLX0VWRVJZX0JZVEVTID0gMTAwMDAwO1xuY29uc3QgVU5BQ0tFRF9ISUdIX1dBVEVSTUFSSyA9IDU7XG5jb25zdCBVTkFDS0VEX0xPV19XQVRFUk1BUksgPSAyO1xuXG4vKiogU29ja2V0PC0+dGVybWluYWwgYWRhcHRlci4gKi9cbmNsYXNzIFNlc3Npb24ge1xuICBwcml2YXRlIHJlYWRvbmx5IGlkOiBudW1iZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgcHR5OiBub2RlUHR5LklQdHk7XG4gIHByaXZhdGUgcGVuZGluZ0Fja0NhbGxiYWNrcyA9IDA7XG4gIHByaXZhdGUgd3JpdHRlbkJ5dGVzID0gMDtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IHNvY2tldDogU29ja2V0KSB7XG4gICAgdGhpcy5pZCA9IHNlc3Npb25Db3VudGVyKys7XG5cbiAgICB0aGlzLnNvY2tldC5vbkNsb3NlKChyZWFzb24pID0+IHtcbiAgICAgIGxvZ2dpbmcuZ2V0TG9nZ2VyKCkuZGVidWcoXG4gICAgICAgICAgJ1BUWSBzb2NrZXQgZGlzY29ubmVjdGVkIGZvciBzZXNzaW9uICVkIHJlYXNvbjogJXMnLCB0aGlzLmlkLCByZWFzb24pO1xuXG4gICAgICAvLyBIYW5kbGUgY2xpZW50IGRpc2Nvbm5lY3RzIHRvIGNsb3NlIHNvY2tldHMsIHNvIGFzIHRvIGZyZWUgdXAgcmVzb3VyY2VzLlxuICAgICAgdGhpcy5jbG9zZSgpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5zb2NrZXQub25TdHJpbmdNZXNzYWdlKChkYXRhOiBzdHJpbmcpID0+IHtcbiAgICAgIC8vIFByb3BhZ2F0ZSB0aGUgbWVzc2FnZSBvdmVyIHRvIHRoZSBwdHkuXG4gICAgICBsb2dnaW5nLmdldExvZ2dlcigpLmRlYnVnKCdTZW5kIGRhdGEgaW4gc2Vzc2lvbiAlZFxcbiVzJywgdGhpcy5pZCwgZGF0YSk7XG4gICAgICBjb25zdCBtZXNzYWdlID0gSlNPTi5wYXJzZShkYXRhKSBhcyBJbmNvbWluZ01lc3NhZ2U7XG4gICAgICBpZiAobWVzc2FnZS5kYXRhKSB7XG4gICAgICAgIHRoaXMucHR5LndyaXRlKG1lc3NhZ2UuZGF0YSk7XG4gICAgICB9XG4gICAgICBpZiAobWVzc2FnZS5jb2xzICYmIG1lc3NhZ2Uucm93cykge1xuICAgICAgICB0aGlzLnB0eS5yZXNpemUobWVzc2FnZS5jb2xzLCBtZXNzYWdlLnJvd3MpO1xuICAgICAgfVxuICAgICAgaWYgKG1lc3NhZ2UuYWNrKSB7XG4gICAgICAgIHRoaXMucGVuZGluZ0Fja0NhbGxiYWNrcy0tO1xuICAgICAgICBpZiAodGhpcy5wZW5kaW5nQWNrQ2FsbGJhY2tzIDwgVU5BQ0tFRF9MT1dfV0FURVJNQVJLKSB7XG4gICAgICAgICAgKHRoaXMucHR5IGFzIHVua25vd24gYXMgUHR5KS5yZXN1bWUoKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuXG4gICAgdGhpcy5wdHkgPSBub2RlUHR5LnNwYXduKCd0bXV4JywgWyduZXctc2Vzc2lvbicsICctQScsICctRCcsICctcycsICcwJ10sIHtcbiAgICAgIG5hbWU6ICd4dGVybS1jb2xvcicsXG4gICAgICBjd2Q6ICcuL2NvbnRlbnQnLCAgLy8gV2hpY2ggcGF0aCBzaG91bGQgdGVybWluYWwgc3RhcnRcbiAgICAgIC8vIFBhc3MgZW52aXJvbm1lbnQgdmFyaWFibGVzXG4gICAgICBlbnY6IHByb2Nlc3MuZW52IGFzIHtcbiAgICAgICAgW2tleTogc3RyaW5nXTogc3RyaW5nO1xuICAgICAgfSxcbiAgICB9KTtcblxuICAgIHRoaXMucHR5Lm9uRGF0YSgoZGF0YTogc3RyaW5nKSA9PiB7XG4gICAgICB0aGlzLndyaXR0ZW5CeXRlcyArPSBkYXRhLmxlbmd0aDtcbiAgICAgIGlmICh0aGlzLndyaXR0ZW5CeXRlcyA8IEFDS19DQUxMQkFDS19FVkVSWV9CWVRFUykge1xuICAgICAgICBjb25zdCBtZXNzYWdlOiBPdXRnb2luZ01lc3NhZ2UgPSB7ZGF0YX07XG4gICAgICAgIHRoaXMuc29ja2V0LnNlbmRTdHJpbmcoSlNPTi5zdHJpbmdpZnkobWVzc2FnZSkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgbWVzc2FnZTogT3V0Z29pbmdNZXNzYWdlID0ge2RhdGEsIGFjazogdHJ1ZX07XG4gICAgICAgIHRoaXMuc29ja2V0LnNlbmRTdHJpbmcoSlNPTi5zdHJpbmdpZnkobWVzc2FnZSkpO1xuICAgICAgICB0aGlzLnBlbmRpbmdBY2tDYWxsYmFja3MrKztcbiAgICAgICAgdGhpcy53cml0dGVuQnl0ZXMgPSAwO1xuICAgICAgICBpZiAodGhpcy5wZW5kaW5nQWNrQ2FsbGJhY2tzID4gVU5BQ0tFRF9ISUdIX1dBVEVSTUFSSykge1xuICAgICAgICAgICh0aGlzLnB0eSBhcyB1bmtub3duIGFzIFB0eSkucGF1c2UoKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuXG4gICAgdGhpcy5wdHkub25FeGl0KFxuICAgICAgICAoe2V4aXRDb2RlLCBzaWduYWx9OiB7ZXhpdENvZGU6IG51bWJlciwgc2lnbmFsPzogbnVtYmVyfSkgPT4ge1xuICAgICAgICAgIHRoaXMuc29ja2V0LmNsb3NlKGZhbHNlKTtcbiAgICAgICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGNsb3NlKCkge1xuICAgIHRoaXMuc29ja2V0LmNsb3NlKGZhbHNlKTtcbiAgICB0aGlzLnB0eS5raWxsKCk7XG4gIH1cbn1cblxuLyoqIFNvY2tldElPIHRvIG5vZGUtcHR5IGFkYXB0ZXIuICovXG5leHBvcnQgY2xhc3MgU29ja2V0SW9Ub1B0eSB7XG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgcGF0aDogc3RyaW5nLCBzZXJ2ZXI6IGh0dHAuU2VydmVyKSB7XG4gICAgY29uc3QgaW8gPSBzb2NrZXRpbyhzZXJ2ZXIsIHtcbiAgICAgIHBhdGgsXG4gICAgICB0cmFuc3BvcnRzOiBbJ3BvbGxpbmcnXSxcbiAgICAgIGFsbG93VXBncmFkZXM6IGZhbHNlLFxuICAgICAgLy8gdjIuMTAgY2hhbmdlZCBkZWZhdWx0IGZyb20gNjBzIHRvIDVzLCBwcmVmZXIgdGhlIGxvbmdlciB0aW1lb3V0IHRvXG4gICAgICAvLyBhdm9pZCBlcnJhbnQgZGlzY29ubmVjdHMuXG4gICAgICBwaW5nVGltZW91dDogNjAwMDAsXG4gICAgfSk7XG5cbiAgICBpby5vZignLycpLm9uKCdjb25uZWN0aW9uJywgKHNvY2tldDogU29ja2V0SU8uU29ja2V0KSA9PiB7XG4gICAgICAvLyBTZXNzaW9uIG1hbmFnZXMgaXRzIG93biBsaWZldGltZS5cbiAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby11bnVzZWQtZXhwcmVzc2lvblxuICAgICAgbmV3IFNlc3Npb24obmV3IFNvY2tldElPQWRhcHRlcihzb2NrZXQpKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKiBSZXR1cm4gdHJ1ZSBpZmYgcGF0aCBpcyBoYW5kbGVkIGJ5IHNvY2tldC5pby4gKi9cbiAgaXNQYXRoUHJveGllZChwYXRoOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gcGF0aC5pbmRleE9mKHRoaXMucGF0aCArICcvJykgPT09IDA7XG4gIH1cbn1cblxuXG4vKiogV2ViU29ja2V0IHRvIHB0eSBhZGFwdGVyLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIFdlYlNvY2tldFRvUHR5KFxuICAgIHJlcXVlc3Q6IGh0dHAuSW5jb21pbmdNZXNzYWdlLCBzb2NrOiBuZXQuU29ja2V0LCBoZWFkOiBCdWZmZXIpIHtcbiAgbmV3IFNlcnZlcih7bm9TZXJ2ZXI6IHRydWV9KS5oYW5kbGVVcGdyYWRlKHJlcXVlc3QsIHNvY2ssIGhlYWQsICh3cykgPT4ge1xuICAgIC8vIFNlc3Npb24gbWFuYWdlcyBpdHMgb3duIGxpZmV0aW1lLlxuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby11bnVzZWQtZXhwcmVzc2lvblxuICAgIG5ldyBTZXNzaW9uKG5ldyBXZWJTb2NrZXRBZGFwdGVyKHdzKSk7XG4gIH0pO1xufVxuXG5kZWNsYXJlIGludGVyZmFjZSBJbmNvbWluZ01lc3NhZ2Uge1xuICByZWFkb25seSBkYXRhPzogc3RyaW5nO1xuICByZWFkb25seSBjb2xzPzogbnVtYmVyO1xuICByZWFkb25seSByb3dzPzogbnVtYmVyO1xuICByZWFkb25seSBhY2s/OiBib29sZWFuO1xufVxuXG5kZWNsYXJlIGludGVyZmFjZSBPdXRnb2luZ01lc3NhZ2Uge1xuICByZWFkb25seSBkYXRhPzogc3RyaW5nO1xuICByZWFkb25seSBhY2s/OiBib29sZWFuO1xufVxuIl19