UNPKG

kaltura-node-typescript-client

Version:
197 lines (195 loc) 31.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.KalturaUploadRequestAdapter = void 0; var tslib_1 = require("tslib"); var utils_1 = require("./utils"); var kaltura_client_exception_1 = require("../api/kaltura-client-exception"); var kaltura_api_exception_1 = require("../api/kaltura-api-exception"); var cancelable_action_1 = require("../cancelable-action"); var got_1 = require("got"); var FormData = require("form-data"); var kaltura_logger_1 = require("../api/kaltura-logger"); var serviceStr = 'uploadtoken'; var actionStr = 'upload'; var KalturaUploadRequestAdapter = /** @class */ (function () { function KalturaUploadRequestAdapter(clientOptions, defaultRequestOptions) { this.clientOptions = clientOptions; this.defaultRequestOptions = defaultRequestOptions; /* noop */ } KalturaUploadRequestAdapter.prototype.transmit = function (request) { var _this = this; return new cancelable_action_1.CancelableAction(function (resolve, reject, action) { var uploadedFileSize = !isNaN(request.uploadedFileSize) && isFinite(request.uploadedFileSize) && request.uploadedFileSize > 0 ? request.uploadedFileSize : 0; var data = { resume: !!uploadedFileSize, finalChunk: false, resumeAt: uploadedFileSize }; var activeAction; var handleChunkUploadError = function (reason) { activeAction = null; reject(reason); }; var handleChunkUploadSuccess = function (result) { if (!data.finalChunk) { activeAction = _this._chunkUpload(request, data).then(handleChunkUploadSuccess, handleChunkUploadError); return; } activeAction = null; try { var response = request.handleResponse(result); if (response.error) { throw response.error; } else { resolve(response.result); } } catch (error) { if (error instanceof kaltura_client_exception_1.KalturaClientException) { reject(new kaltura_client_exception_1.KalturaClientException(error.message, error.code, (0, tslib_1.__assign)((0, tslib_1.__assign)({}, (error.args || {})), { service: serviceStr, action: actionStr }))); } else if (error instanceof kaltura_api_exception_1.KalturaAPIException) { reject(new kaltura_api_exception_1.KalturaAPIException(error.message, error.code, (0, tslib_1.__assign)((0, tslib_1.__assign)({}, (error.args || {})), { service: serviceStr, action: actionStr }))); } else { var errorMessage = error instanceof Error ? error.message : typeof error === 'string' ? error : null; reject(new kaltura_client_exception_1.KalturaClientException('client::response-unknown-error', errorMessage || 'Failed to parse response', { service: serviceStr, action: actionStr })); } } }; activeAction = _this._chunkUpload(request, data).then(handleChunkUploadSuccess, handleChunkUploadError); return function () { if (activeAction) { activeAction.cancel(); activeAction = null; } }; }); }; KalturaUploadRequestAdapter.prototype._getFormData = function (_a) { var fileName = _a.fileName, fileData = _a.fileData, ks = _a.ks; return (0, tslib_1.__awaiter)(this, void 0, void 0, function () { var form, ab, buffer; return (0, tslib_1.__generator)(this, function (_b) { switch (_b.label) { case 0: form = new FormData(); form.append('fileName', fileName); form.append('ks', ks); return [4 /*yield*/, fileData.arrayBuffer()]; case 1: ab = _b.sent(); buffer = Buffer.from(ab); form.append('fileData', buffer, { contentType: fileData.type, filename: fileName }); return [2 /*return*/, form]; } }); }); }; KalturaUploadRequestAdapter.prototype._getChunkFileSize = function () { var userChunkFileSize = this.clientOptions ? this.clientOptions.chunkFileSize : null; var actualChunkFileSize = 5e6; // default 5 mb if (userChunkFileSize && Number.isFinite(userChunkFileSize) && !Number.isNaN(userChunkFileSize)) { if (userChunkFileSize < 1e5) { kaltura_logger_1.Logger.warn("user requested for invalid upload chunk size '" + userChunkFileSize + "'. minimal value 100Kb. using minimal value 100Kb instead"); actualChunkFileSize = 1e5; } else { actualChunkFileSize = userChunkFileSize; } } kaltura_logger_1.Logger.info("using chunk size of " + userChunkFileSize + " bytes"); return actualChunkFileSize; }; KalturaUploadRequestAdapter.prototype._prepareRequest = function (request, uploadChunkData) { return (0, tslib_1.__awaiter)(this, void 0, void 0, function () { var actualChunkFileSize, file, fileStart, fileEnd, form, _a, service, action, ks, params, endpointUrl, searchParams; return (0, tslib_1.__generator)(this, function (_b) { switch (_b.label) { case 0: actualChunkFileSize = this._getChunkFileSize(); file = request.getFileInfo().file; uploadChunkData.finalChunk = (file.size - uploadChunkData.resumeAt) <= actualChunkFileSize; fileStart = uploadChunkData.resumeAt; fileEnd = uploadChunkData.finalChunk ? file.size : fileStart + actualChunkFileSize; return [4 /*yield*/, this._getFormData({ fileName: file.name, fileData: file.slice(fileStart, fileEnd, file.type), ks: this.defaultRequestOptions.ks })]; case 1: form = _b.sent(); _a = (0, utils_1.prepareParameters)(request, this.clientOptions, this.defaultRequestOptions), service = _a.service, action = _a.action, ks = _a.ks, params = (0, tslib_1.__rest)(_a, ["service", "action", "ks"]); endpointUrl = (0, utils_1.createEndpoint)(request, this.clientOptions, service, action); searchParams = new URLSearchParams((0, tslib_1.__assign)((0, tslib_1.__assign)({}, params), { resume: uploadChunkData.resume, resumeAt: uploadChunkData.resumeAt, finalChunk: uploadChunkData.finalChunk })); return [2 /*return*/, { endpointUrl: endpointUrl, form: form, searchParams: searchParams }]; } }); }); }; KalturaUploadRequestAdapter.prototype._chunkUpload = function (request, uploadChunkData) { var _this = this; return new cancelable_action_1.CancelableAction(function (resolve, reject) { var isComplete = false, isAborted = false; var xMe, xKalturaSession; var gotRequest; _this._prepareRequest(request, uploadChunkData).then(function (_a) { var endpointUrl = _a.endpointUrl, form = _a.form, searchParams = _a.searchParams; if (isAborted) { return; } gotRequest = got_1.default.post(endpointUrl, { body: form, searchParams: searchParams }); // save headers and parse response: gotRequest.then(function (response) { var _a, _b; isComplete = true; xMe = ((_a = response === null || response === void 0 ? void 0 : response.headers) === null || _a === void 0 ? void 0 : _a['x-me']) || ''; xKalturaSession = ((_b = response === null || response === void 0 ? void 0 : response.headers) === null || _b === void 0 ? void 0 : _b['x-kaltura-session']) || ''; kaltura_logger_1.Logger.debug("Kaltura response completed for: " + serviceStr + "/" + actionStr + ", x-me: " + xMe + ", x-kaltura-session: " + xKalturaSession); return gotRequest.json(); }) // handle parsed response: .then(function (parsedResponse) { if ((parsedResponse === null || parsedResponse === void 0 ? void 0 : parsedResponse.objectType) === 'KalturaAPIException') { reject(new kaltura_api_exception_1.KalturaAPIException(parsedResponse.message, parsedResponse.code, (0, tslib_1.__assign)((0, tslib_1.__assign)({}, (parsedResponse.args || {})), { service: serviceStr, action: actionStr }))); return; } if (parsedResponse.uploadedFileSize === undefined || parsedResponse.uploadedFileSize === null) { reject(new kaltura_client_exception_1.KalturaClientException('client::upload-failure', "uploaded chunk of file failed, expected response with property 'uploadedFileSize'", { service: serviceStr, action: actionStr })); return; } if (!uploadChunkData.finalChunk) { uploadChunkData.resumeAt = Number(parsedResponse.uploadedFileSize); uploadChunkData.resume = true; } resolve(parsedResponse); }) // handle errors: .catch(function (e) { var _a, _b, _c, _d, _e; isComplete = true; xMe || (xMe = ((_b = (_a = e.response) === null || _a === void 0 ? void 0 : _a.headers) === null || _b === void 0 ? void 0 : _b['x-me']) || ''); xKalturaSession || (xKalturaSession = ((_d = (_c = e.response) === null || _c === void 0 ? void 0 : _c.headers) === null || _d === void 0 ? void 0 : _d['x-kaltura-session']) || ''); var msg = ((_e = e.response) === null || _e === void 0 ? void 0 : _e.body) || e.message || 'failed to upload file'; var err = new kaltura_client_exception_1.KalturaClientException('client::upload-failure', msg); kaltura_logger_1.Logger.error("Kaltura response error: '" + (msg || '') + "', for: " + serviceStr + "/" + actionStr + ", x-me: " + xMe + ", x-kaltura-session: " + xKalturaSession); reject(err); }); }); return function () { if (!isComplete) { isComplete = true; isAborted = true; gotRequest === null || gotRequest === void 0 ? void 0 : gotRequest.cancel(); } }; }); }; return KalturaUploadRequestAdapter; }()); exports.KalturaUploadRequestAdapter = KalturaUploadRequestAdapter; //# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFkYXB0ZXJzL2thbHR1cmEtdXBsb2FkLXJlcXVlc3QtYWRhcHRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQ0EsaUNBQTREO0FBQzVELDRFQUF5RTtBQUd6RSxzRUFBbUU7QUFDbkUsMERBQXdEO0FBQ3hELDJCQUFzQjtBQUN0QixvQ0FBc0M7QUFDdEMsd0RBQStDO0FBUS9DLElBQU0sVUFBVSxHQUFHLGFBQXNCLENBQUE7QUFDekMsSUFBTSxTQUFTLEdBQUcsUUFBaUIsQ0FBQTtBQUVuQztJQUNFLHFDQUFtQixhQUFtQyxFQUFTLHFCQUE0QztRQUF4RixrQkFBYSxHQUFiLGFBQWEsQ0FBc0I7UUFBUywwQkFBcUIsR0FBckIscUJBQXFCLENBQXVCO1FBQ3pHLFVBQVU7SUFDWixDQUFDO0lBRUQsOENBQVEsR0FBUixVQUFTLE9BQWtDO1FBQTNDLGlCQW1EQztRQWxEQyxPQUFPLElBQUksb0NBQWdCLENBQUMsVUFBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU07WUFDbEQsSUFBTSxnQkFBZ0IsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxRQUFRLENBQUMsT0FBTyxDQUFDLGdCQUFnQixDQUFDLElBQUksT0FBTyxDQUFDLGdCQUFnQixHQUFHLENBQUM7Z0JBQzdILENBQUMsQ0FBQyxPQUFPLENBQUMsZ0JBQWdCO2dCQUMxQixDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ04sSUFBTSxJQUFJLEdBQXVCO2dCQUMvQixNQUFNLEVBQUUsQ0FBQyxDQUFDLGdCQUFnQjtnQkFDMUIsVUFBVSxFQUFFLEtBQUs7Z0JBQ2pCLFFBQVEsRUFBRSxnQkFBZ0I7YUFDM0IsQ0FBQztZQUNGLElBQUksWUFBbUMsQ0FBQztZQUV4QyxJQUFNLHNCQUFzQixHQUFHLFVBQUMsTUFBTTtnQkFDcEMsWUFBWSxHQUFHLElBQUksQ0FBQztnQkFDcEIsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ2pCLENBQUMsQ0FBQTtZQUVE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LElBQUksaURBQXNCLENBQUMsd0JBQXdCLEVBQUUsR0FBRyxDQUFDLENBQUM7b0JBQ3RFLHVCQUFNLENBQUMsS0FBSyxDQUFDLCtCQUE0QixHQUFHLElBQUksRUFBRSxpQkFBVyxVQUFVLFNBQUksU0FBUyxnQkFBVyxHQUFHLDZCQUF3QixlQUFpQixDQUFDLENBQUE7b0JBQzVJLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQTtnQkFDYixDQUFDLENBQUMsQ0FBQTtZQUNKLENBQUMsQ0FBQyxDQUFBO1lBRUYsT0FBTztnQkFDTCxJQUFJLENBQUMsVUFBVSxFQUFFO29CQUNmLFVBQVUsR0FBRyxJQUFJLENBQUM7b0JBQ2xCLFNBQVMsR0FBRyxJQUFJLENBQUE7b0JBQ2hCLFVBQVUsYUFBVixVQUFVLHVCQUFWLFVBQVUsQ0FBRSxNQUFNLEVBQUUsQ0FBQztpQkFDdEI7WUFDSCxDQUFDLENBQUE7UUFDSCxDQUFDLENBQUMsQ0FBQTtJQUNKLENBQUM7SUFDSCxrQ0FBQztBQUFELENBMUtBLEFBMEtDLElBQUE7QUExS1ksa0VBQTJCIiwiZmlsZSI6ImFkYXB0ZXJzL2thbHR1cmEtdXBsb2FkLXJlcXVlc3QtYWRhcHRlci5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEthbHR1cmFVcGxvYWRSZXF1ZXN0IH0gZnJvbSAnLi4vYXBpL2thbHR1cmEtdXBsb2FkLXJlcXVlc3QnO1xuaW1wb3J0IHsgY3JlYXRlRW5kcG9pbnQsIHByZXBhcmVQYXJhbWV0ZXJzIH0gZnJvbSAnLi91dGlscyc7XG5pbXBvcnQgeyBLYWx0dXJhQ2xpZW50RXhjZXB0aW9uIH0gZnJvbSAnLi4vYXBpL2thbHR1cmEtY2xpZW50LWV4Y2VwdGlvbic7XG5pbXBvcnQgeyBLYWx0dXJhUmVxdWVzdE9wdGlvbnMgfSBmcm9tICcuLi9hcGkva2FsdHVyYS1yZXF1ZXN0LW9wdGlvbnMnO1xuaW1wb3J0IHsgS2FsdHVyYUNsaWVudE9wdGlvbnMgfSBmcm9tICcuLi9rYWx0dXJhLWNsaWVudC1vcHRpb25zJztcbmltcG9ydCB7IEthbHR1cmFBUElFeGNlcHRpb24gfSBmcm9tICcuLi9hcGkva2FsdHVyYS1hcGktZXhjZXB0aW9uJztcbmltcG9ydCB7IENhbmNlbGFibGVBY3Rpb24gfSBmcm9tICcuLi9jYW5jZWxhYmxlLWFjdGlvbic7XG5pbXBvcnQgZ290IGZyb20gJ2dvdCc7XG5pbXBvcnQgKiBhcyBGb3JtRGF0YSBmcm9tICdmb3JtLWRhdGEnO1xuaW1wb3J0IHsgTG9nZ2VyIH0gZnJvbSBcIi4uL2FwaS9rYWx0dXJhLWxvZ2dlclwiO1xuXG5pbnRlcmZhY2UgVXBsb2FkQnlDaHVua3NEYXRhIHtcbiAgcmVzdW1lOiBib29sZWFuO1xuICByZXN1bWVBdDogbnVtYmVyO1xuICBmaW5hbENodW5rOiBib29sZWFuO1xufVxuXG5jb25zdCBzZXJ2aWNlU3RyID0gJ3VwbG9hZHRva2VuJyBhcyBjb25zdFxuY29uc3QgYWN0aW9uU3RyID0gJ3VwbG9hZCcgYXMgY29uc3RcblxuZXhwb3J0IGNsYXNzIEthbHR1cmFVcGxvYWRSZXF1ZXN0QWRhcHRlciB7XG4gIGNvbnN0cnVjdG9yKHB1YmxpYyBjbGllbnRPcHRpb25zOiBLYWx0dXJhQ2xpZW50T3B0aW9ucywgcHVibGljIGRlZmF1bHRSZXF1ZXN0T3B0aW9uczogS2FsdHVyYVJlcXVlc3RPcHRpb25zKSB7XG4gICAgLyogbm9vcCAqL1xuICB9XG5cbiAgdHJhbnNtaXQocmVxdWVzdDogS2FsdHVyYVVwbG9hZFJlcXVlc3Q8YW55Pik6IENhbmNlbGFibGVBY3Rpb248YW55PiB7XG4gICAgcmV0dXJuIG5ldyBDYW5jZWxhYmxlQWN0aW9uKChyZXNvbHZlLCByZWplY3QsIGFjdGlvbikgPT4ge1xuICAgICAgY29uc3QgdXBsb2FkZWRGaWxlU2l6ZSA9ICFpc05hTihyZXF1ZXN0LnVwbG9hZGVkRmlsZVNpemUpICYmIGlzRmluaXRlKHJlcXVlc3QudXBsb2FkZWRGaWxlU2l6ZSkgJiYgcmVxdWVzdC51cGxvYWRlZEZpbGVTaXplID4gMFxuICAgICAgICA/IHJlcXVlc3QudXBsb2FkZWRGaWxlU2l6ZVxuICAgICAgICA6IDA7XG4gICAgICBjb25zdCBkYXRhOiBVcGxvYWRCeUNodW5rc0RhdGEgPSB7XG4gICAgICAgIHJlc3VtZTogISF1cGxvYWRlZEZpbGVTaXplLFxuICAgICAgICBmaW5hbENodW5rOiBmYWxzZSxcbiAgICAgICAgcmVzdW1lQXQ6IHVwbG9hZGVkRmlsZVNpemVcbiAgICAgIH07XG4gICAgICBsZXQgYWN0aXZlQWN0aW9uOiBDYW5jZWxhYmxlQWN0aW9uPGFueT47XG5cbiAgICAgIGNvbnN0IGhhbmRsZUNodW5rVXBsb2FkRXJyb3IgPSAocmVhc29uKSA9PiB7XG4gICAgICAgIGFjdGl2ZUFjdGlvbiA9IG51bGw7XG4gICAgICAgIHJlamVjdChyZWFzb24pO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBoYW5kbGVDaHVua1VwbG9hZFN1Y2Nlc3MgPSAocmVzdWx0KSA9PiB7XG4gICAgICAgIGlmICghZGF0YS5maW5hbENodW5rKSB7XG4gICAgICAgICAgYWN0aXZlQWN0aW9uID0gdGhpcy5fY2h1bmtVcGxvYWQocmVxdWVzdCwgZGF0YSkudGhlbihoYW5kbGVDaHVua1VwbG9hZFN1Y2Nlc3MsIGhhbmRsZUNodW5rVXBsb2FkRXJyb3IpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGFjdGl2ZUFjdGlvbiA9IG51bGw7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSByZXF1ZXN0LmhhbmRsZVJlc3BvbnNlKHJlc3VsdCk7XG4gICAgICAgICAgaWYgKHJlc3BvbnNlLmVycm9yKSB7XG4gICAgICAgICAgICB0aHJvdyByZXNwb25zZS5lcnJvcjtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmVzb2x2ZShyZXNwb25zZS5yZXN1bHQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBLYWx0dXJhQ2xpZW50RXhjZXB0aW9uKSB7XG4gICAgICAgICAgICByZWplY3QobmV3IEthbHR1cmFDbGllbnRFeGNlcHRpb24oZXJyb3IubWVzc2FnZSwgZXJyb3IuY29kZSwgeyAuLi4oZXJyb3IuYXJncyB8fCB7fSksIHNlcnZpY2U6IHNlcnZpY2VTdHIsIGFjdGlvbjogYWN0aW9uU3RyIH0pKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKGVycm9yIGluc3RhbmNlb2YgS2FsdHVyYUFQSUV4Y2VwdGlvbikge1xuICAgICAgICAgICAgcmVqZWN0KG5ldyBLYWx0dXJhQVBJRXhjZXB0aW9uKGVycm9yLm1lc3NhZ2UsIGVycm9yLmNvZGUsIHsgLi4uKGVycm9yLmFyZ3MgfHwge30pLCBzZXJ2aWNlOiBzZXJ2aWNlU3RyLCBhY3Rpb246IGFjdGlvblN0ciB9KSlcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgZXJyb3JNZXNzYWdlID0gZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiB0eXBlb2YgZXJyb3IgPT09ICdzdHJpbmcnID8gZXJyb3IgOiBudWxsO1xuICAgICAgICAgICAgcmVqZWN0KG5ldyBLYWx0dXJhQ2xpZW50RXhjZXB0aW9uKCdjbGllbnQ6OnJlc3BvbnNlLXVua25vd24tZXJyb3InLCBlcnJvck1lc3NhZ2UgfHwgJ0ZhaWxlZCB0byBwYXJzZSByZXNwb25zZScsIHsgc2VydmljZTogc2VydmljZVN0ciwgYWN0aW9uOiBhY3Rpb25TdHIgfSkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBhY3RpdmVBY3Rpb24gPSB0aGlzLl9jaHVua1VwbG9hZChyZXF1ZXN0LCBkYXRhKS50aGVuKGhhbmRsZUNodW5rVXBsb2FkU3VjY2VzcywgaGFuZGxlQ2h1bmtVcGxvYWRFcnJvcik7XG4gICAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICBpZiAoYWN0aXZlQWN0aW9uKSB7XG4gICAgICAgICAgYWN0aXZlQWN0aW9uLmNhbmNlbCgpO1xuICAgICAgICAgIGFjdGl2ZUFjdGlvbiA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIF9nZXRGb3JtRGF0YShcbiAgICB7IGZpbGVOYW1lLCBmaWxlRGF0YSwga3MgfTogeyBmaWxlTmFtZTogc3RyaW5nLCBmaWxlRGF0YTogQmxvYiwga3M6c3RyaW5nIH1cbiAgKTogUHJvbWlzZTxGb3JtRGF0YT4ge1xuICAgIGNvbnN0IGZvcm0gPSBuZXcgRm9ybURhdGEoKTtcbiAgICBmb3JtLmFwcGVuZCgnZmlsZU5hbWUnLCBmaWxlTmFtZSlcbiAgICBmb3JtLmFwcGVuZCgna3MnLCBrcylcbiAgICBjb25zdCBhYiA9IGF3YWl0IGZpbGVEYXRhLmFycmF5QnVmZmVyKCk7XG4gICAgY29uc3QgYnVmZmVyID0gQnVmZmVyLmZyb20oYWIpO1xuICAgIGZvcm0uYXBwZW5kKCdmaWxlRGF0YScsIGJ1ZmZlciwgeyBjb250ZW50VHlwZTogZmlsZURhdGEudHlwZSwgZmlsZW5hbWU6IGZpbGVOYW1lIH0pXG4gICAgcmV0dXJuIGZvcm07XG4gIH1cblxuICBwcml2YXRlIF9nZXRDaHVua0ZpbGVTaXplKCk6IG51bWJlciB7XG4gICAgY29uc3QgdXNlckNodW5rRmlsZVNpemUgPSB0aGlzLmNsaWVudE9wdGlvbnMgPyB0aGlzLmNsaWVudE9wdGlvbnMuY2h1bmtGaWxlU2l6ZSA6IG51bGw7XG4gICAgbGV0IGFjdHVhbENodW5rRmlsZVNpemUgPSA1ZTY7IC8vIGRlZmF1bHQgNSBtYlxuICAgIGlmICh1c2VyQ2h1bmtGaWxlU2l6ZSAmJiBOdW1iZXIuaXNGaW5pdGUodXNlckNodW5rRmlsZVNpemUpICYmICFOdW1iZXIuaXNOYU4odXNlckNodW5rRmlsZVNpemUpKSB7XG4gICAgICBpZiAodXNlckNodW5rRmlsZVNpemUgPCAxZTUpIHtcbiAgICAgICAgTG9nZ2VyLndhcm4oYHVzZXIgcmVxdWVzdGVkIGZvciBpbnZhbGlkIHVwbG9hZCBjaHVuayBzaXplICcke3VzZXJDaHVua0ZpbGVTaXplfScuIG1pbmltYWwgdmFsdWUgMTAwS2IuIHVzaW5nIG1pbmltYWwgdmFsdWUgMTAwS2IgaW5zdGVhZGApXG4gICAgICAgIGFjdHVhbENodW5rRmlsZVNpemUgPSAxZTU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhY3R1YWxDaHVua0ZpbGVTaXplID0gdXNlckNodW5rRmlsZVNpemU7XG4gICAgICB9XG4gICAgfVxuICAgIExvZ2dlci5pbmZvKGB1c2luZyBjaHVuayBzaXplIG9mICR7dXNlckNodW5rRmlsZVNpemV9IGJ5dGVzYClcbiAgICByZXR1cm4gYWN0dWFsQ2h1bmtGaWxlU2l6ZVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBfcHJlcGFyZVJlcXVlc3QoXG4gICAgcmVxdWVzdDogS2FsdHVyYVVwbG9hZFJlcXVlc3Q8YW55PixcbiAgICB1cGxvYWRDaHVua0RhdGE6IFVwbG9hZEJ5Q2h1bmtzRGF0YVxuICApOiBQcm9taXNlPHsgZW5kcG9pbnRVcmw6IHN0cmluZywgZm9ybTogRm9ybURhdGEsIHNlYXJjaFBhcmFtczogVVJMU2VhcmNoUGFyYW1zIH0+IHtcbiAgICBjb25zdCBhY3R1YWxDaHVua0ZpbGVTaXplID0gdGhpcy5fZ2V0Q2h1bmtGaWxlU2l6ZSgpO1xuICAgIGNvbnN0IHsgZmlsZSB9ID0gcmVxdWVzdC5nZXRGaWxlSW5mbygpO1xuICAgIHVwbG9hZENodW5rRGF0YS5maW5hbENodW5rID0gKGZpbGUuc2l6ZSAtIHVwbG9hZENodW5rRGF0YS5yZXN1bWVBdCkgPD0gYWN0dWFsQ2h1bmtGaWxlU2l6ZTtcbiAgICBjb25zdCBmaWxlU3RhcnQgPSB1cGxvYWRDaHVua0RhdGEucmVzdW1lQXQ7XG4gICAgY29uc3QgZmlsZUVuZCA9IHVwbG9hZENodW5rRGF0YS5maW5hbENodW5rID8gZmlsZS5zaXplIDogZmlsZVN0YXJ0ICsgYWN0dWFsQ2h1bmtGaWxlU2l6ZTtcblxuICAgIGNvbnN0IGZvcm0gPSBhd2FpdCB0aGlzLl9nZXRGb3JtRGF0YSh7XG4gICAgICBmaWxlTmFtZTogZmlsZS5uYW1lLFxuICAgICAgZmlsZURhdGE6IGZpbGUuc2xpY2UoZmlsZVN0YXJ0LCBmaWxlRW5kLCBmaWxlLnR5cGUpLFxuICAgICAga3M6IHRoaXMuZGVmYXVsdFJlcXVlc3RPcHRpb25zLmtzXG4gICAgfSlcbiAgICBjb25zdCB7IHNlcnZpY2UsIGFjdGlvbiwga3MsIC4uLnBhcmFtcyB9ID0gcHJlcGFyZVBhcmFtZXRlcnMocmVxdWVzdCwgdGhpcy5jbGllbnRPcHRpb25zLCB0aGlzLmRlZmF1bHRSZXF1ZXN0T3B0aW9ucyk7XG4gICAgY29uc3QgZW5kcG9pbnRVcmwgPSBjcmVhdGVFbmRwb2ludChyZXF1ZXN0LCB0aGlzLmNsaWVudE9wdGlvbnMsIHNlcnZpY2UsIGFjdGlvbik7XG4gICAgY29uc3Qgc2VhcmNoUGFyYW1zID0gbmV3IFVSTFNlYXJjaFBhcmFtcyh7XG4gICAgICAuLi5wYXJhbXMsXG4gICAgICByZXN1bWU6IHVwbG9hZENodW5rRGF0YS5yZXN1bWUsXG4gICAgICByZXN1bWVBdDogdXBsb2FkQ2h1bmtEYXRhLnJlc3VtZUF0LFxuICAgICAgZmluYWxDaHVuazogdXBsb2FkQ2h1bmtEYXRhLmZpbmFsQ2h1bmtcbiAgICB9KVxuICAgIHJldHVybiB7IGVuZHBvaW50VXJsLCBmb3JtLCBzZWFyY2hQYXJhbXMgfVxuICB9XG5cbiAgcHJpdmF0ZSBfY2h1bmtVcGxvYWQoXG4gICAgcmVxdWVzdDogS2FsdHVyYVVwbG9hZFJlcXVlc3Q8YW55PixcbiAgICB1cGxvYWRDaHVua0RhdGE6IFVwbG9hZEJ5Q2h1bmtzRGF0YVxuICApOiBDYW5jZWxhYmxlQWN0aW9uPGFueT4ge1xuICAgIHJldHVybiBuZXcgQ2FuY2VsYWJsZUFjdGlvbigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBsZXQgaXNDb21wbGV0ZSA9IGZhbHNlLCBpc0Fib3J0ZWQgPSBmYWxzZVxuICAgICAgbGV0IHhNZSwgeEthbHR1cmFTZXNzaW9uXG4gICAgICBsZXQgZ290UmVxdWVzdFxuXG4gICAgICB0aGlzLl9wcmVwYXJlUmVxdWVzdChyZXF1ZXN0LCB1cGxvYWRDaHVua0RhdGEpLnRoZW4oKFxuICAgICAgICB7IGVuZHBvaW50VXJsLCBmb3JtLCBzZWFyY2hQYXJhbXMgfTp7IGVuZHBvaW50VXJsOiBzdHJpbmcsIGZvcm06IEZvcm1EYXRhLCBzZWFyY2hQYXJhbXM6IFVSTFNlYXJjaFBhcmFtcyB9XG4gICAgICApID0+IHtcbiAgICAgICAgaWYgKGlzQWJvcnRlZCkgeyByZXR1cm4gfVxuICAgICAgICBnb3RSZXF1ZXN0ID0gZ290LnBvc3QoZW5kcG9pbnRVcmwsIHsgYm9keTogZm9ybSwgc2VhcmNoUGFyYW1zIH0pXG4gICAgICAgIC8vIHNhdmUgaGVhZGVycyBhbmQgcGFyc2UgcmVzcG9uc2U6XG4gICAgICAgIGdvdFJlcXVlc3QudGhlbihyZXNwb25zZSA9PiB7XG4gICAgICAgICAgaXNDb21wbGV0ZSA9IHRydWVcbiAgICAgICAgICB4TWUgPSByZXNwb25zZT8uaGVhZGVycz8uWyd4LW1lJ10gfHwgJydcbiAgICAgICAgICB4S2FsdHVyYVNlc3Npb24gPSByZXNwb25zZT8uaGVhZGVycz8uWyd4LWthbHR1cmEtc2Vzc2lvbiddIHx8ICcnXG4gICAgICAgICAgTG9nZ2VyLmRlYnVnKGBLYWx0dXJhIHJlc3BvbnNlIGNvbXBsZXRlZCBmb3I6ICR7c2VydmljZVN0cn0vJHthY3Rpb25TdHJ9LCB4LW1lOiAke3hNZX0sIHgta2FsdHVyYS1zZXNzaW9uOiAke3hLYWx0dXJhU2Vzc2lvbn1gKVxuICAgICAgICAgIHJldHVybiBnb3RSZXF1ZXN0Lmpzb24oKVxuICAgICAgICB9KVxuICAgICAgICAvLyBoYW5kbGUgcGFyc2VkIHJlc3BvbnNlOlxuICAgICAgICAudGhlbigocGFyc2VkUmVzcG9uc2U6IGFueSkgPT4ge1xuICAgICAgICAgIGlmIChwYXJzZWRSZXNwb25zZT8ub2JqZWN0VHlwZSA9PT0gJ0thbHR1cmFBUElFeGNlcHRpb24nKSB7XG4gICAgICAgICAgICByZWplY3QobmV3IEthbHR1cmFBUElFeGNlcHRpb24ocGFyc2VkUmVzcG9uc2UubWVzc2FnZSwgcGFyc2VkUmVzcG9uc2UuY29kZSwgeyAuLi4ocGFyc2VkUmVzcG9uc2UuYXJncyB8fCB7fSksIHNlcnZpY2U6IHNlcnZpY2VTdHIsIGFjdGlvbjogYWN0aW9uU3RyIH0pKVxuICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChwYXJzZWRSZXNwb25zZS51cGxvYWRlZEZpbGVTaXplID09PSB1bmRlZmluZWQgfHwgcGFyc2VkUmVzcG9uc2UudXBsb2FkZWRGaWxlU2l6ZSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgcmVqZWN0KG5ldyBLYWx0dXJhQ2xpZW50RXhjZXB0aW9uKCdjbGllbnQ6OnVwbG9hZC1mYWlsdXJlJywgYHVwbG9hZGVkIGNodW5rIG9mIGZpbGUgZmFpbGVkLCBleHBlY3RlZCByZXNwb25zZSB3aXRoIHByb3BlcnR5ICd1cGxvYWRlZEZpbGVTaXplJ2AsIHsgc2VydmljZTogc2VydmljZVN0ciwgYWN0aW9uOiBhY3Rpb25TdHIgfSkpXG4gICAgICAgICAgICByZXR1cm5cbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKCF1cGxvYWRDaHVua0RhdGEuZmluYWxDaHVuaykge1xuICAgICAgICAgICAgdXBsb2FkQ2h1bmtEYXRhLnJlc3VtZUF0ID0gTnVtYmVyKHBhcnNlZFJlc3BvbnNlLnVwbG9hZGVkRmlsZVNpemUpXG4gICAgICAgICAgICB1cGxvYWRDaHVua0RhdGEucmVzdW1lID0gdHJ1ZVxuICAgICAgICAgIH1cbiAgICAgICAgICByZXNvbHZlKHBhcnNlZFJlc3BvbnNlKTtcbiAgICAgICAgfSlcbiAgICAgICAgLy8gaGFuZGxlIGVycm9yczpcbiAgICAgICAgLmNhdGNoKGUgPT4ge1xuICAgICAgICAgIGlzQ29tcGxldGUgPSB0cnVlXG4gICAgICAgICAgeE1lIHx8PSBlLnJlc3BvbnNlPy5oZWFkZXJzPy5bJ3gtbWUnXSB8fCAnJ1xuICAgICAgICAgIHhLYWx0dXJhU2Vzc2lvbiB8fD0gZS5yZXNwb25zZT8uaGVhZGVycz8uWyd4LWthbHR1cmEtc2Vzc2lvbiddIHx8ICcnXG4gICAgICAgICAgY29uc3QgbXNnID0gZS5yZXNwb25zZT8uYm9keSB8fCBlLm1lc3NhZ2UgfHwgJ2ZhaWxlZCB0byB1cGxvYWQgZmlsZSdcbiAgICAgICAgICBjb25zdCBlcnIgPSBuZXcgS2FsdHVyYUNsaWVudEV4Y2VwdGlvbignY2xpZW50Ojp1cGxvYWQtZmFpbHVyZScsIG1zZyk7XG4gICAgICAgICAgTG9nZ2VyLmVycm9yKGBLYWx0dXJhIHJlc3BvbnNlIGVycm9yOiAnJHttc2cgfHwgJyd9JywgZm9yOiAke3NlcnZpY2VTdHJ9LyR7YWN0aW9uU3RyfSwgeC1tZTogJHt4TWV9LCB4LWthbHR1cmEtc2Vzc2lvbjogJHt4S2FsdHVyYVNlc3Npb259YClcbiAgICAgICAgICByZWplY3QoZXJyKVxuICAgICAgICB9KVxuICAgICAgfSlcblxuICAgICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgaWYgKCFpc0NvbXBsZXRlKSB7XG4gICAgICAgICAgaXNDb21wbGV0ZSA9IHRydWU7XG4gICAgICAgICAgaXNBYm9ydGVkID0gdHJ1ZVxuICAgICAgICAgIGdvdFJlcXVlc3Q/LmNhbmNlbCgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSlcbiAgfVxufVxuIl19