net.js
27.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.uploadFile = uploadFile;
exports.downloadFile = downloadFile;
require("source-map-support/register");
var _lodash = _interopRequireDefault(require("lodash"));
var _fs = _interopRequireDefault(require("./fs"));
var _url = _interopRequireDefault(require("url"));
var _bluebird = _interopRequireDefault(require("bluebird"));
var _util = require("./util");
var _logger = _interopRequireDefault(require("./logger"));
var _jsftp = _interopRequireDefault(require("jsftp"));
var _timing = _interopRequireDefault(require("./timing"));
var _axios = _interopRequireDefault(require("axios"));
var _formData = _interopRequireDefault(require("form-data"));
function toAxiosAuth(auth) {
if (!_lodash.default.isPlainObject(auth)) {
return null;
}
const axiosAuth = {
username: auth.username || auth.user,
password: auth.password || auth.pass
};
return axiosAuth.username && axiosAuth.password ? axiosAuth : null;
}
async function uploadFileToHttp(localFileStream, parsedUri, uploadOptions = {}) {
const {
method = 'POST',
timeout = 5000,
headers,
auth,
fileFieldName = 'file',
formFields
} = uploadOptions;
const {
href
} = parsedUri;
const requestOpts = {
url: href,
method,
timeout,
maxContentLength: Infinity,
maxBodyLength: Infinity
};
const axiosAuth = toAxiosAuth(auth);
if (axiosAuth) {
requestOpts.auth = axiosAuth;
}
if (fileFieldName) {
const form = new _formData.default();
form.append(fileFieldName, localFileStream);
if (formFields) {
let pairs = [];
if (_lodash.default.isArray(formFields)) {
pairs = formFields;
} else if (_lodash.default.isPlainObject(formFields)) {
pairs = _lodash.default.toPairs(formFields);
}
for (const [key, value] of pairs) {
if (_lodash.default.toLower(key) !== _lodash.default.toLower(fileFieldName)) {
form.append(key, value);
}
}
}
requestOpts.headers = Object.assign({}, _lodash.default.isPlainObject(headers) ? headers : {}, form.getHeaders());
requestOpts.data = form;
} else {
if (_lodash.default.isPlainObject(headers)) {
requestOpts.headers = headers;
}
requestOpts.data = localFileStream;
}
_logger.default.debug(`Performing ${method} to ${href} with options (excluding data): ` + JSON.stringify(_lodash.default.omit(requestOpts, ['data'])));
const {
status,
statusText
} = await (0, _axios.default)(requestOpts);
_logger.default.info(`Server response: ${status} ${statusText}`);
}
async function uploadFileToFtp(localFileStream, parsedUri, uploadOptions = {}) {
const {
auth,
user,
pass
} = uploadOptions;
const {
hostname,
port,
protocol,
pathname
} = parsedUri;
const ftpOpts = {
host: hostname,
port: port || 21
};
if (auth !== null && auth !== void 0 && auth.user && auth !== null && auth !== void 0 && auth.pass || user && pass) {
ftpOpts.user = (auth === null || auth === void 0 ? void 0 : auth.user) || user;
ftpOpts.pass = (auth === null || auth === void 0 ? void 0 : auth.pass) || pass;
}
_logger.default.debug(`${protocol} upload options: ${JSON.stringify(ftpOpts)}`);
return await new _bluebird.default((resolve, reject) => {
new _jsftp.default(ftpOpts).put(localFileStream, pathname, err => {
if (err) {
reject(err);
} else {
resolve();
}
});
});
}
async function uploadFile(localPath, remoteUri, uploadOptions = {}) {
if (!(await _fs.default.exists(localPath))) {
throw new Error(`'${localPath}' does not exists or is not accessible`);
}
const {
isMetered = true
} = uploadOptions;
const parsedUri = _url.default.parse(remoteUri);
const {
size
} = await _fs.default.stat(localPath);
if (isMetered) {
_logger.default.info(`Uploading '${localPath}' of ${(0, _util.toReadableSizeString)(size)} size to '${remoteUri}'`);
}
const timer = new _timing.default().start();
if (['http:', 'https:'].includes(parsedUri.protocol)) {
if (!uploadOptions.fileFieldName) {
uploadOptions.headers = Object.assign({}, _lodash.default.isPlainObject(uploadOptions.headers) ? uploadOptions.headers : {}, {
'Content-Length': size
});
}
await uploadFileToHttp(_fs.default.createReadStream(localPath), parsedUri, uploadOptions);
} else if (parsedUri.protocol === 'ftp:') {
await uploadFileToFtp(_fs.default.createReadStream(localPath), parsedUri, uploadOptions);
} else {
throw new Error(`Cannot upload the file at '${localPath}' to '${remoteUri}'. ` + `Unsupported remote protocol '${parsedUri.protocol}'. ` + `Only http/https and ftp/ftps protocols are supported.`);
}
if (isMetered) {
_logger.default.info(`Uploaded '${localPath}' of ${(0, _util.toReadableSizeString)(size)} size in ` + `${timer.getDuration().asSeconds.toFixed(3)}s`);
}
}
async function downloadFile(remoteUrl, dstPath, downloadOptions = {}) {
const {
isMetered = true,
auth,
timeout = 5000,
headers
} = downloadOptions;
const requestOpts = {
url: remoteUrl,
responseType: 'stream',
timeout
};
const axiosAuth = toAxiosAuth(auth);
if (axiosAuth) {
requestOpts.auth = axiosAuth;
}
if (_lodash.default.isPlainObject(headers)) {
requestOpts.headers = headers;
}
const timer = new _timing.default().start();
let responseLength;
try {
const writer = _fs.default.createWriteStream(dstPath);
const {
data: responseStream,
headers: responseHeaders
} = await (0, _axios.default)(requestOpts);
responseLength = parseInt(responseHeaders['content-length'], 10);
responseStream.pipe(writer);
await new _bluebird.default((resolve, reject) => {
responseStream.once('error', reject);
writer.once('finish', resolve);
writer.once('error', e => {
responseStream.unpipe(writer);
reject(e);
});
});
} catch (err) {
throw new Error(`Cannot download the file from ${remoteUrl}: ${err.message}`);
}
const {
size
} = await _fs.default.stat(dstPath);
if (responseLength && size !== responseLength) {
await _fs.default.rimraf(dstPath);
throw new Error(`The size of the file downloaded from ${remoteUrl} (${size} bytes) ` + `differs from the one in Content-Length response header (${responseLength} bytes)`);
}
if (isMetered) {
const secondsElapsed = timer.getDuration().asSeconds;
_logger.default.debug(`${remoteUrl} (${(0, _util.toReadableSizeString)(size)}) ` + `has been downloaded to '${dstPath}' in ${secondsElapsed.toFixed(3)}s`);
if (secondsElapsed >= 2) {
const bytesPerSec = Math.floor(size / secondsElapsed);
_logger.default.debug(`Approximate download speed: ${(0, _util.toReadableSizeString)(bytesPerSec)}/s`);
}
}
}require('source-map-support').install();
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImxpYi9uZXQuanMiXSwibmFtZXMiOlsidG9BeGlvc0F1dGgiLCJhdXRoIiwiXyIsImlzUGxhaW5PYmplY3QiLCJheGlvc0F1dGgiLCJ1c2VybmFtZSIsInVzZXIiLCJwYXNzd29yZCIsInBhc3MiLCJ1cGxvYWRGaWxlVG9IdHRwIiwibG9jYWxGaWxlU3RyZWFtIiwicGFyc2VkVXJpIiwidXBsb2FkT3B0aW9ucyIsIm1ldGhvZCIsInRpbWVvdXQiLCJoZWFkZXJzIiwiZmlsZUZpZWxkTmFtZSIsImZvcm1GaWVsZHMiLCJocmVmIiwicmVxdWVzdE9wdHMiLCJ1cmwiLCJtYXhDb250ZW50TGVuZ3RoIiwiSW5maW5pdHkiLCJtYXhCb2R5TGVuZ3RoIiwiZm9ybSIsIkZvcm1EYXRhIiwiYXBwZW5kIiwicGFpcnMiLCJpc0FycmF5IiwidG9QYWlycyIsImtleSIsInZhbHVlIiwidG9Mb3dlciIsIk9iamVjdCIsImFzc2lnbiIsImdldEhlYWRlcnMiLCJkYXRhIiwibG9nIiwiZGVidWciLCJKU09OIiwic3RyaW5naWZ5Iiwib21pdCIsInN0YXR1cyIsInN0YXR1c1RleHQiLCJpbmZvIiwidXBsb2FkRmlsZVRvRnRwIiwiaG9zdG5hbWUiLCJwb3J0IiwicHJvdG9jb2wiLCJwYXRobmFtZSIsImZ0cE9wdHMiLCJob3N0IiwiQiIsInJlc29sdmUiLCJyZWplY3QiLCJGdHAiLCJwdXQiLCJlcnIiLCJ1cGxvYWRGaWxlIiwibG9jYWxQYXRoIiwicmVtb3RlVXJpIiwiZnMiLCJleGlzdHMiLCJFcnJvciIsImlzTWV0ZXJlZCIsInBhcnNlIiwic2l6ZSIsInN0YXQiLCJ0aW1lciIsIlRpbWVyIiwic3RhcnQiLCJpbmNsdWRlcyIsImNyZWF0ZVJlYWRTdHJlYW0iLCJnZXREdXJhdGlvbiIsImFzU2Vjb25kcyIsInRvRml4ZWQiLCJkb3dubG9hZEZpbGUiLCJyZW1vdGVVcmwiLCJkc3RQYXRoIiwiZG93bmxvYWRPcHRpb25zIiwicmVzcG9uc2VUeXBlIiwicmVzcG9uc2VMZW5ndGgiLCJ3cml0ZXIiLCJjcmVhdGVXcml0ZVN0cmVhbSIsInJlc3BvbnNlU3RyZWFtIiwicmVzcG9uc2VIZWFkZXJzIiwicGFyc2VJbnQiLCJwaXBlIiwib25jZSIsImUiLCJ1bnBpcGUiLCJtZXNzYWdlIiwicmltcmFmIiwic2Vjb25kc0VsYXBzZWQiLCJieXRlc1BlclNlYyIsIk1hdGgiLCJmbG9vciJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBR0EsU0FBU0EsV0FBVCxDQUFzQkMsSUFBdEIsRUFBNEI7QUFDMUIsTUFBSSxDQUFDQyxnQkFBRUMsYUFBRixDQUFnQkYsSUFBaEIsQ0FBTCxFQUE0QjtBQUMxQixXQUFPLElBQVA7QUFDRDs7QUFFRCxRQUFNRyxTQUFTLEdBQUc7QUFDaEJDLElBQUFBLFFBQVEsRUFBRUosSUFBSSxDQUFDSSxRQUFMLElBQWlCSixJQUFJLENBQUNLLElBRGhCO0FBRWhCQyxJQUFBQSxRQUFRLEVBQUVOLElBQUksQ0FBQ00sUUFBTCxJQUFpQk4sSUFBSSxDQUFDTztBQUZoQixHQUFsQjtBQUlBLFNBQVFKLFNBQVMsQ0FBQ0MsUUFBVixJQUFzQkQsU0FBUyxDQUFDRyxRQUFqQyxHQUE2Q0gsU0FBN0MsR0FBeUQsSUFBaEU7QUFDRDs7QUFFRCxlQUFlSyxnQkFBZixDQUFpQ0MsZUFBakMsRUFBa0RDLFNBQWxELEVBQTZEQyxhQUFhLEdBQUcsRUFBN0UsRUFBaUY7QUFDL0UsUUFBTTtBQUNKQyxJQUFBQSxNQUFNLEdBQUcsTUFETDtBQUVKQyxJQUFBQSxPQUFPLEdBQUcsSUFGTjtBQUdKQyxJQUFBQSxPQUhJO0FBSUpkLElBQUFBLElBSkk7QUFLSmUsSUFBQUEsYUFBYSxHQUFHLE1BTFo7QUFNSkMsSUFBQUE7QUFOSSxNQU9GTCxhQVBKO0FBUUEsUUFBTTtBQUFFTSxJQUFBQTtBQUFGLE1BQVdQLFNBQWpCO0FBRUEsUUFBTVEsV0FBVyxHQUFHO0FBQ2xCQyxJQUFB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LEtBQUssQ0FBQ0ssV0FBTixHQUFvQkMsU0FBM0M7O0FBQ0FyQyxvQkFBSUMsS0FBSixDQUFXLEdBQUV1QyxTQUFVLEtBQUksZ0NBQXFCWCxJQUFyQixDQUEyQixJQUE1QyxHQUNQLDJCQUEwQlksT0FBUSxRQUFPZSxjQUFjLENBQUNsQixPQUFmLENBQXVCLENBQXZCLENBQTBCLEdBRHRFOztBQUVBLFFBQUlrQixjQUFjLElBQUksQ0FBdEIsRUFBeUI7QUFDdkIsWUFBTUMsV0FBVyxHQUFHQyxJQUFJLENBQUNDLEtBQUwsQ0FBVzlCLElBQUksR0FBRzJCLGNBQWxCLENBQXBCOztBQUNBeEQsc0JBQUlDLEtBQUosQ0FBVywrQkFBOEIsZ0NBQXFCd0QsV0FBckIsQ0FBa0MsSUFBM0U7QUFDRDtBQUNGO0FBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgXyBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IGZzIGZyb20gJy4vZnMnO1xuaW1wb3J0IHVybCBmcm9tICd1cmwnO1xuaW1wb3J0IEIgZnJvbSAnYmx1ZWJpcmQnO1xuaW1wb3J0IHsgdG9SZWFkYWJsZVNpemVTdHJpbmcgfSBmcm9tICcuL3V0aWwnO1xuaW1wb3J0IGxvZyBmcm9tICcuL2xvZ2dlcic7XG5pbXBvcnQgRnRwIGZyb20gJ2pzZnRwJztcbmltcG9ydCBUaW1lciBmcm9tICcuL3RpbWluZyc7XG5pbXBvcnQgYXhpb3MgZnJvbSAnYXhpb3MnO1xuaW1wb3J0IEZvcm1EYXRhIGZyb20gJ2Zvcm0tZGF0YSc7XG5cblxuZnVuY3Rpb24gdG9BeGlvc0F1dGggKGF1dGgpIHtcbiAgaWYgKCFfLmlzUGxhaW5PYmplY3QoYXV0aCkpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGNvbnN0IGF4aW9zQXV0aCA9IHtcbiAgICB1c2VybmFtZTogYXV0aC51c2VybmFtZSB8fCBhdXRoLnVzZXIsXG4gICAgcGFzc3dvcmQ6IGF1dGgucGFzc3dvcmQgfHwgYXV0aC5wYXNzLFxuICB9O1xuICByZXR1cm4gKGF4aW9zQXV0aC51c2VybmFtZSAmJiBheGlvc0F1dGgucGFzc3dvcmQpID8gYXhpb3NBdXRoIDogbnVsbDtcbn1cblxuYXN5bmMgZnVuY3Rpb24gdXBsb2FkRmlsZVRvSHR0cCAobG9jYWxGaWxlU3RyZWFtLCBwYXJzZWRVcmksIHVwbG9hZE9wdGlvbnMgPSB7fSkge1xuICBjb25zdCB7XG4gICAgbWV0aG9kID0gJ1BPU1QnLFxuICAgIHRpbWVvdXQgPSA1MDAwLFxuICAgIGhlYWRlcnMsXG4gICAgYXV0aCxcbiAgICBmaWxlRmllbGROYW1lID0gJ2ZpbGUnLFxuICAgIGZvcm1GaWVsZHMsXG4gIH0gPSB1cGxvYWRPcHRpb25zO1xuICBjb25zdCB7IGhyZWYgfSA9IHBhcnNlZFVyaTtcblxuICBjb25zdCByZXF1ZXN0T3B0cyA9IHtcbiAgICB1cmw6IGhyZWYsXG4gICAgbWV0aG9kLFxuICAgIHRpbWVvdXQsXG4gICAgbWF4Q29udGVudExlbmd0aDogSW5maW5pdHksXG4gICAgbWF4Qm9keUxlbmd0aDogSW5maW5pdHksXG4gIH07XG4gIGNvbnN0IGF4aW9zQXV0aCA9IHRvQXhpb3NBdXRoKGF1dGgpO1xuICBpZiAoYXhpb3NBdXRoKSB7XG4gICAgcmVxdWVzdE9wdHMuYXV0aCA9IGF4aW9zQXV0aDtcbiAgfVxuICBpZiAoZmlsZUZpZWxkTmFtZSkge1xuICAgIGNvbnN0IGZvcm0gPSBuZXcgRm9ybURhdGEoKTtcbiAgICBmb3JtLmFwcGVuZChmaWxlRmllbGROYW1lLCBsb2NhbEZpbGVTdHJlYW0pO1xuICAgIGlmIChmb3JtRmllbGRzKSB7XG4gICAgICBsZXQgcGFpcnMgPSBbXTtcbiAgICAgIGlmIChfLmlzQXJyYXkoZm9ybUZpZWxkcykpIHtcbiAgICAgICAgcGFpcnMgPSBmb3JtRmllbGRzO1xuICAgICAgfSBlbHNlIGlmIChfLmlzUGxhaW5PYmplY3QoZm9ybUZpZWxkcykpIHtcbiAgICAgICAgcGFpcnMgPSBfLnRvUGFpcnMoZm9ybUZpZWxkcyk7XG4gICAgICB9XG4gICAgICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBwYWlycykge1xuICAgICAgICBpZiAoXy50b0xvd2VyKGtleSkgIT09IF8udG9Mb3dlcihmaWxlRmllbGROYW1lKSkge1xuICAgICAgICAgIGZvcm0uYXBwZW5kKGtleSwgdmFsdWUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJlcXVlc3RPcHRzLmhlYWRlcnMgPSBPYmplY3QuYXNzaWduKHt9LCBfLmlzUGxhaW5PYmplY3QoaGVhZGVycykgPyBoZWFkZXJzIDoge30sXG4gICAgICBmb3JtLmdldEhlYWRlcnMoKSk7XG4gICAgcmVxdWVzdE9wdHMuZGF0YSA9IGZvcm07XG4gIH0gZWxzZSB7XG4gICAgaWYgKF8uaXNQbGFpbk9iamVjdChoZWFkZXJzKSkge1xuICAgICAgcmVxdWVzdE9wdHMuaGVhZGVycyA9IGhlYWRlcnM7XG4gICAgfVxuICAgIHJlcXVlc3RPcHRzLmRhdGEgPSBsb2NhbEZpbGVTdHJlYW07XG4gIH1cbiAgbG9nLmRlYnVnKGBQZXJmb3JtaW5nICR7bWV0aG9kfSB0byAke2hyZWZ9IHdpdGggb3B0aW9ucyAoZXhjbHVkaW5nIGRhdGEpOiBgICtcbiAgICBKU09OLnN0cmluZ2lmeShfLm9taXQocmVxdWVzdE9wdHMsIFsnZGF0YSddKSkpO1xuXG4gIGNvbnN0IHtzdGF0dXMsIHN0YXR1c1RleHR9ID0gYXdhaXQgYXhpb3MocmVxdWVzdE9wdHMpO1xuICBsb2cuaW5mbyhgU2VydmVyIHJlc3BvbnNlOiAke3N0YXR1c30gJHtzdGF0dXNUZXh0fWApO1xufVxuXG5hc3luYyBmdW5jdGlvbiB1cGxvYWRGaWxlVG9GdHAgKGxvY2FsRmlsZVN0cmVhbSwgcGFyc2VkVXJpLCB1cGxvYWRPcHRpb25zID0ge30pIHtcbiAgY29uc3Qge1xuICAgIGF1dGgsXG4gICAgdXNlcixcbiAgICBwYXNzLFxuICB9ID0gdXBsb2FkT3B0aW9ucztcbiAgY29uc3Qge1xuICAgIGhvc3RuYW1lLFxuICAgIHBvcnQsXG4gICAgcHJvdG9jb2wsXG4gICAgcGF0aG5hbWUsXG4gIH0gPSBwYXJzZWRVcmk7XG5cbiAgY29uc3QgZnRwT3B0cyA9IHtcbiAgICBob3N0OiBob3N0bmFtZSxcbiAgICBwb3J0OiBwb3J0IHx8IDIxLFxuICB9O1xuICBpZiAoKGF1dGg/LnVzZXIgJiYgYXV0aD8ucGFzcykgfHwgKHVzZXIgJiYgcGFzcykpIHtcbiAgICBmdHBPcHRzLnVzZXIgPSBhdXRoPy51c2VyIHx8IHVzZXI7XG4gICAgZnRwT3B0cy5wYXNzID0gYXV0aD8ucGFzcyB8fCBwYXNzO1xuICB9XG4gIGxvZy5kZWJ1ZyhgJHtwcm90b2NvbH0gdXBsb2FkIG9wdGlvbnM6ICR7SlNPTi5zdHJpbmdpZnkoZnRwT3B0cyl9YCk7XG4gIHJldHVybiBhd2FpdCBuZXcgQigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgbmV3IEZ0cChmdHBPcHRzKS5wdXQobG9jYWxGaWxlU3RyZWFtLCBwYXRobmFtZSwgKGVycikgPT4ge1xuICAgICAgaWYgKGVycikge1xuICAgICAgICByZWplY3QoZXJyKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlc29sdmUoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSk7XG59XG5cbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gQXV0aENyZWRlbnRpYWxzXG4gKiBAcHJvcGVydHkge3N0cmluZ30gdXNlciAtIE5vbi1lbXB0eSB1c2VyIG5hbWVcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBwYXNzIC0gTm9uLWVtcHR5IHBhc3N3b3JkXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBGdHBVcGxvYWRPcHRpb25zXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IGlzTWV0ZXJlZCBbdHJ1ZV0gLSBXaGV0aGVyIHRvIGxvZyB0aGUgYWN0dWFsIHVwbG9hZCBwZXJmb3JtYW5jZVxuICogKGUuZy4gdGltaW5ncyBhbmQgc3BlZWQpXG4gKiBAcHJvcGVydHkge0F1dGhDcmVkZW50aWFsc30gYXV0aFxuICovXG5cbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gSHR0cFVwbG9hZE9wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gaXNNZXRlcmVkIFt0cnVlXSAtIFdoZXRoZXIgdG8gbG9nIHRoZSBhY3R1YWwgdXBsb2FkIHBlcmZvcm1hbmNlXG4gKiAoZS5nLiB0aW1pbmdzIGFuZCBzcGVlZClcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBtZXRob2QgW1BPU1RdIC0gVGhlIEhUVFAgbWV0aG9kIHVzZWQgZm9yIGZpbGUgdXBsb2FkXG4gKiBAcHJvcGVydHkge0F1dGhDcmVkZW50aWFsc30gYXV0aFxuICogQHByb3BlcnR5IHtudW1iZXJ9IHRpbWVvdXQgWzUwMDBdIC0gVGhlIGFjdHVhbCByZXF1ZXN0IHRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzXG4gKiBAcHJvcGVydHkge09iamVjdH0gaGVhZGVycyAtIEFkZGl0aW9uYWwgcmVxdWVzdCBoZWFkZXJzIG1hcHBpbmdcbiAqIEBwcm9wZXJ0eSB7P3N0cmluZ30gZmlsZUZpZWxkTmFtZSBbZmlsZV0gLSBUaGUgbmFtZSBvZiB0aGUgZm9ybSBmaWVsZCBjb250YWluaW5nIHRoZSBmaWxlXG4gKiBjb250ZW50IHRvIGJlIHVwbG9hZGVkLiBBbnkgZmFsc3kgdmFsdWUgbWFrZSB0aGUgcmVxdWVzdCB0byB1c2Ugbm9uLW11bHRpcGFydCB1cGxvYWRcbiAqIEBwcm9wZXJ0eSB7QXJyYXk8UGFpcj58T2JqZWN0fSBmb3JtRmllbGRzIC0gVGhlIGFkZGl0aW9uYWwgZm9ybSBmaWVsZHNcbiAqIHRvIGJlIGluY2x1ZGVkIGludG8gdGhlIHVwbG9hZCByZXF1ZXN0LiBUaGlzIHByb3BlcnR5IGlzIG9ubHkgY29uc2lkZXJlZCBpZlxuICogYGZpbGVGaWVsZE5hbWVgIGlzIHNldFxuICovXG5cbi8qKlxuICogVXBsb2FkcyB0aGUgZ2l2ZW4gZmlsZSB0byBhIHJlbW90ZSBsb2NhdGlvbi4gSFRUUChTKSBhbmQgRlRQXG4gKiBwcm90b2NvbHMgYXJlIHN1cHBvcnRlZC5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gbG9jYWxQYXRoIC0gVGhlIHBhdGggdG8gYSBmaWxlIG9uIHRoZSBsb2NhbCBzdG9yYWdlLlxuICogQHBhcmFtIHtzdHJpbmd9IHJlbW90ZVVyaSAtIFRoZSByZW1vdGUgVVJJIHRvIHVwbG9hZCB0aGUgZmlsZSB0by5cbiAqIEBwYXJhbSB7P0Z0cFVwbG9hZE9wdGlvbnN8SHR0cFVwbG9hZE9wdGlvbnN9IHVwbG9hZE9wdGlvbnNcbiAqL1xuYXN5bmMgZnVuY3Rpb24gdXBsb2FkRmlsZSAobG9jYWxQYXRoLCByZW1vdGVVcmksIHVwbG9hZE9wdGlvbnMgPSB7fSkge1xuICBpZiAoIWF3YWl0IGZzLmV4aXN0cyhsb2NhbFBhdGgpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yIChgJyR7bG9jYWxQYXRofScgZG9lcyBub3QgZXhpc3RzIG9yIGlzIG5vdCBhY2Nlc3NpYmxlYCk7XG4gIH1cblxuICBjb25zdCB7XG4gICAgaXNNZXRlcmVkID0gdHJ1ZSxcbiAgfSA9IHVwbG9hZE9wdGlvbnM7XG5cbiAgY29uc3QgcGFyc2VkVXJpID0gdXJsLnBhcnNlKHJlbW90ZVVyaSk7XG4gIGNvbnN0IHtzaXplfSA9IGF3YWl0IGZzLnN0YXQobG9jYWxQYXRoKTtcbiAgaWYgKGlzTWV0ZXJlZCkge1xuICAgIGxvZy5pbmZvKGBVcGxvYWRpbmcgJyR7bG9jYWxQYXRofScgb2YgJHt0b1JlYWRhYmxlU2l6ZVN0cmluZyhzaXplKX0gc2l6ZSB0byAnJHtyZW1vdGVVcml9J2ApO1xuICB9XG4gIGNvbnN0IHRpbWVyID0gbmV3IFRpbWVyKCkuc3RhcnQoKTtcbiAgaWYgKFsnaHR0cDonLCAnaHR0cHM6J10uaW5jbHVkZXMocGFyc2VkVXJpLnByb3RvY29sKSkge1xuICAgIGlmICghdXBsb2FkT3B0aW9ucy5maWxlRmllbGROYW1lKSB7XG4gICAgICB1cGxvYWRPcHRpb25zLmhlYWRlcnMgPSBPYmplY3QuYXNzaWduKHt9LFxuICAgICAgICBfLmlzUGxhaW5PYmplY3QodXBsb2FkT3B0aW9ucy5oZWFkZXJzKSA/IHVwbG9hZE9wdGlvbnMuaGVhZGVycyA6IHt9LFxuICAgICAgICB7J0NvbnRlbnQtTGVuZ3RoJzogc2l6ZX1cbiAgICAgICk7XG4gICAgfVxuICAgIGF3YWl0IHVwbG9hZEZpbGVUb0h0dHAoZnMuY3JlYXRlUmVhZFN0cmVhbShsb2NhbFBhdGgpLCBwYXJzZWRVcmksIHVwbG9hZE9wdGlvbnMpO1xuICB9IGVsc2UgaWYgKHBhcnNlZFVyaS5wcm90b2NvbCA9PT0gJ2Z0cDonKSB7XG4gICAgYXdhaXQgdXBsb2FkRmlsZVRvRnRwKGZzLmNyZWF0ZVJlYWRTdHJlYW0obG9jYWxQYXRoKSwgcGFyc2VkVXJpLCB1cGxvYWRPcHRpb25zKTtcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCB1cGxvYWQgdGhlIGZpbGUgYXQgJyR7bG9jYWxQYXRofScgdG8gJyR7cmVtb3RlVXJpfScuIGAgK1xuICAgICAgYFVuc3VwcG9ydGVkIHJlbW90ZSBwcm90b2NvbCAnJHtwYXJzZWRVcmkucHJvdG9jb2x9Jy4gYCArXG4gICAgICBgT25seSBodHRwL2h0dHBzIGFuZCBmdHAvZnRwcyBwcm90b2NvbHMgYXJlIHN1cHBvcnRlZC5gKTtcbiAgfVxuICBpZiAoaXNNZXRlcmVkKSB7XG4gICAgbG9nLmluZm8oYFVwbG9hZGVkICcke2xvY2FsUGF0aH0nIG9mICR7dG9SZWFkYWJsZVNpemVTdHJpbmcoc2l6ZSl9IHNpemUgaW4gYCArXG4gICAgICBgJHt0aW1lci5nZXREdXJhdGlvbigpLmFzU2Vjb25kcy50b0ZpeGVkKDMpfXNgKTtcbiAgfVxufVxuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IERvd25sb2FkT3B0aW9uc1xuICogQHByb3BlcnR5IHtib29sZWFufSBpc01ldGVyZWQgW3RydWVdIC0gV2hldGhlciB0byBsb2cgdGhlIGFjdHVhbCBkb3dubG9hZCBwZXJmb3JtYW5jZVxuICogKGUuZy4gdGltaW5ncyBhbmQgc3BlZWQpXG4gKiBAcHJvcGVydHkge0F1dGhDcmVkZW50aWFsc30gYXV0aFxuICogQHByb3BlcnR5IHtudW1iZXJ9IHRpbWVvdXQgWzUwMDBdIC0gVGhlIGFjdHVhbCByZXF1ZXN0IHRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzXG4gKiBAcHJvcGVydHkge09iamVjdH0gaGVhZGVycyAtIFJlcXVlc3QgaGVhZGVycyBtYXBwaW5nXG4gKi9cblxuLyoqXG4gKiBEb3dubG9hZHMgdGhlIGdpdmVuIGZpbGUgdmlhIEhUVFAoUylcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gcmVtb3RlVXJsIC0gVGhlIHJlbW90ZSB1cmxcbiAqIEBwYXJhbSB7c3RyaW5nfSBkc3RQYXRoIC0gVGhlIGxvY2FsIHBhdGggdG8gZG93bmxvYWQgdGhlIGZpbGUgdG9cbiAqIEBwYXJhbSB7P0Rvd25sb2FkT3B0aW9uc30gZG93bmxvYWRPcHRpb25zXG4gKiBAdGhyb3dzIHtFcnJvcn0gSWYgZG93bmxvYWQgb3BlcmF0aW9uIGZhaWxzXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGRvd25sb2FkRmlsZSAocmVtb3RlVXJsLCBkc3RQYXRoLCBkb3dubG9hZE9wdGlvbnMgPSB7fSkge1xuICBjb25zdCB7XG4gICAgaXNNZXRlcmVkID0gdHJ1ZSxcbiAgICBhdXRoLFxuICAgIHRpbWVvdXQgPSA1MDAwLFxuICAgIGhlYWRlcnMsXG4gIH0gPSBkb3dubG9hZE9wdGlvbnM7XG5cbiAgY29uc3QgcmVxdWVzdE9wdHMgPSB7XG4gICAgdXJsOiByZW1vdGVVcmwsXG4gICAgcmVzcG9uc2VUeXBlOiAnc3RyZWFtJyxcbiAgICB0aW1lb3V0LFxuICB9O1xuICBjb25zdCBheGlvc0F1dGggPSB0b0F4aW9zQXV0aChhdXRoKTtcbiAgaWYgKGF4aW9zQXV0aCkge1xuICAgIHJlcXVlc3RPcHRzLmF1dGggPSBheGlvc0F1dGg7XG4gIH1cbiAgaWYgKF8uaXNQbGFpbk9iamVjdChoZWFkZXJzKSkge1xuICAgIHJlcXVlc3RPcHRzLmhlYWRlcnMgPSBoZWFkZXJzO1xuICB9XG5cbiAgY29uc3QgdGltZXIgPSBuZXcgVGltZXIoKS5zdGFydCgpO1xuICBsZXQgcmVzcG9uc2VMZW5ndGg7XG4gIHRyeSB7XG4gICAgY29uc3Qgd3JpdGVyID0gZnMuY3JlYXRlV3JpdGVTdHJlYW0oZHN0UGF0aCk7XG4gICAgY29uc3Qge1xuICAgICAgZGF0YTogcmVzcG9uc2VTdHJlYW0sXG4gICAgICBoZWFkZXJzOiByZXNwb25zZUhlYWRlcnMsXG4gICAgfSA9IGF3YWl0IGF4aW9zKHJlcXVlc3RPcHRzKTtcbiAgICByZXNwb25zZUxlbmd0aCA9IHBhcnNlSW50KHJlc3BvbnNlSGVhZGVyc1snY29udGVudC1sZW5ndGgnXSwgMTApO1xuICAgIHJlc3BvbnNlU3RyZWFtLnBpcGUod3JpdGVyKTtcblxuICAgIGF3YWl0IG5ldyBCKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHJlc3BvbnNlU3RyZWFtLm9uY2UoJ2Vycm9yJywgcmVqZWN0KTtcbiAgICAgIHdyaXRlci5vbmNlKCdmaW5pc2gnLCByZXNvbHZlKTtcbiAgICAgIHdyaXRlci5vbmNlKCdlcnJvcicsIChlKSA9PiB7XG4gICAgICAgIHJlc3BvbnNlU3RyZWFtLnVucGlwZSh3cml0ZXIpO1xuICAgICAgICByZWplY3QoZSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBDYW5ub3QgZG93bmxvYWQgdGhlIGZpbGUgZnJvbSAke3JlbW90ZVVybH06ICR7ZXJyLm1lc3NhZ2V9YCk7XG4gIH1cblxuICBjb25zdCB7c2l6ZX0gPSBhd2FpdCBmcy5zdGF0KGRzdFBhdGgpO1xuICBpZiAocmVzcG9uc2VMZW5ndGggJiYgc2l6ZSAhPT0gcmVzcG9uc2VMZW5ndGgpIHtcbiAgICBhd2FpdCBmcy5yaW1yYWYoZHN0UGF0aCk7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBUaGUgc2l6ZSBvZiB0aGUgZmlsZSBkb3dubG9hZGVkIGZyb20gJHtyZW1vdGVVcmx9ICgke3NpemV9IGJ5dGVzKSBgICtcbiAgICAgIGBkaWZmZXJzIGZyb20gdGhlIG9uZSBpbiBDb250ZW50LUxlbmd0aCByZXNwb25zZSBoZWFkZXIgKCR7cmVzcG9uc2VMZW5ndGh9IGJ5dGVzKWApO1xuICB9XG4gIGlmIChpc01ldGVyZWQpIHtcbiAgICBjb25zdCBzZWNvbmRzRWxhcHNlZCA9IHRpbWVyLmdldER1cmF0aW9uKCkuYXNTZWNvbmRzO1xuICAgIGxvZy5kZWJ1ZyhgJHtyZW1vdGVVcmx9ICgke3RvUmVhZGFibGVTaXplU3RyaW5nKHNpemUpfSkgYCArXG4gICAgICBgaGFzIGJlZW4gZG93bmxvYWRlZCB0byAnJHtkc3RQYXRofScgaW4gJHtzZWNvbmRzRWxhcHNlZC50b0ZpeGVkKDMpfXNgKTtcbiAgICBpZiAoc2Vjb25kc0VsYXBzZWQgPj0gMikge1xuICAgICAgY29uc3QgYnl0ZXNQZXJTZWMgPSBNYXRoLmZsb29yKHNpemUgLyBzZWNvbmRzRWxhcHNlZCk7XG4gICAgICBsb2cuZGVidWcoYEFwcHJveGltYXRlIGRvd25sb2FkIHNwZWVkOiAke3RvUmVhZGFibGVTaXplU3RyaW5nKGJ5dGVzUGVyU2VjKX0vc2ApO1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgeyB1cGxvYWRGaWxlLCBkb3dubG9hZEZpbGUgfTtcbiJdLCJmaWxlIjoibGliL25ldC5qcyIsInNvdXJjZVJvb3QiOiIuLi8uLiJ9