1 | ;
|
2 |
|
3 | Object.defineProperty(exports, "__esModule", {
|
4 | value: true
|
5 | });
|
6 |
|
7 | var _promise = require('babel-runtime/core-js/promise');
|
8 |
|
9 | var _promise2 = _interopRequireDefault(_promise);
|
10 |
|
11 | var _regenerator = require('babel-runtime/regenerator');
|
12 |
|
13 | var _regenerator2 = _interopRequireDefault(_regenerator);
|
14 |
|
15 | var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator');
|
16 |
|
17 | var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);
|
18 |
|
19 | var _getPrototypeOf = require('babel-runtime/core-js/object/get-prototype-of');
|
20 |
|
21 | var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf);
|
22 |
|
23 | var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
|
24 |
|
25 | var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
|
26 |
|
27 | var _createClass2 = require('babel-runtime/helpers/createClass');
|
28 |
|
29 | var _createClass3 = _interopRequireDefault(_createClass2);
|
30 |
|
31 | var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
|
32 |
|
33 | var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
|
34 |
|
35 | var _inherits2 = require('babel-runtime/helpers/inherits');
|
36 |
|
37 | var _inherits3 = _interopRequireDefault(_inherits2);
|
38 |
|
39 | var _cliEngineCommand = require('cli-engine-command');
|
40 |
|
41 | var _path = require('path');
|
42 |
|
43 | var _path2 = _interopRequireDefault(_path);
|
44 |
|
45 | var _rwlockfile = require('rwlockfile');
|
46 |
|
47 | var _rwlockfile2 = _interopRequireDefault(_rwlockfile);
|
48 |
|
49 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
50 |
|
51 | var _class = function (_Base) {
|
52 | (0, _inherits3.default)(_class, _Base);
|
53 |
|
54 | function _class() {
|
55 | (0, _classCallCheck3.default)(this, _class);
|
56 | return (0, _possibleConstructorReturn3.default)(this, (_class.__proto__ || (0, _getPrototypeOf2.default)(_class)).apply(this, arguments));
|
57 | }
|
58 |
|
59 | (0, _createClass3.default)(_class, [{
|
60 | key: 'fetchManifest',
|
61 | value: function () {
|
62 | var _ref = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee(channel) {
|
63 | var url, manifest;
|
64 | return _regenerator2.default.wrap(function _callee$(_context) {
|
65 | while (1) {
|
66 | switch (_context.prev = _context.next) {
|
67 | case 0:
|
68 | if (this.config.s3.host) {
|
69 | _context.next = 2;
|
70 | break;
|
71 | }
|
72 |
|
73 | throw new Error('S3 host not defined');
|
74 |
|
75 | case 2:
|
76 | _context.prev = 2;
|
77 | url = 'https://' + this.config.s3.host + '/' + this.config.name + '/channels/' + channel + '/' + process.platform + '-' + process.arch;
|
78 | _context.next = 6;
|
79 | return this.http.get(url);
|
80 |
|
81 | case 6:
|
82 | manifest = _context.sent;
|
83 | return _context.abrupt('return', manifest);
|
84 |
|
85 | case 10:
|
86 | _context.prev = 10;
|
87 | _context.t0 = _context['catch'](2);
|
88 |
|
89 | if (!(_context.t0.statusCode === 403)) {
|
90 | _context.next = 14;
|
91 | break;
|
92 | }
|
93 |
|
94 | throw new Error('HTTP 403: Invalid channel ' + channel);
|
95 |
|
96 | case 14:
|
97 | throw _context.t0;
|
98 |
|
99 | case 15:
|
100 | case 'end':
|
101 | return _context.stop();
|
102 | }
|
103 | }
|
104 | }, _callee, this, [[2, 10]]);
|
105 | }));
|
106 |
|
107 | function fetchManifest(_x) {
|
108 | return _ref.apply(this, arguments);
|
109 | }
|
110 |
|
111 | return fetchManifest;
|
112 | }()
|
113 | }, {
|
114 | key: 'update',
|
115 | value: function () {
|
116 | var _ref2 = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee2(manifest) {
|
117 | var url, stream, dir, tmp;
|
118 | return _regenerator2.default.wrap(function _callee2$(_context2) {
|
119 | while (1) {
|
120 | switch (_context2.prev = _context2.next) {
|
121 | case 0:
|
122 | if (this.config.s3.host) {
|
123 | _context2.next = 2;
|
124 | break;
|
125 | }
|
126 |
|
127 | throw new Error('S3 host not defined');
|
128 |
|
129 | case 2:
|
130 | url = 'https://' + this.config.s3.host + '/' + this.config.name + '/channels/' + manifest.channel + '/' + this.base(manifest) + '.tar.gz';
|
131 | _context2.next = 5;
|
132 | return this.http.stream(url);
|
133 |
|
134 | case 5:
|
135 | stream = _context2.sent;
|
136 | dir = _path2.default.join(this.config.dirs.data, 'cli');
|
137 | tmp = _path2.default.join(this.config.dirs.data, 'cli_tmp');
|
138 | _context2.next = 10;
|
139 | return this.extract(stream, tmp);
|
140 |
|
141 | case 10:
|
142 | _context2.next = 12;
|
143 | return _rwlockfile2.default.write(this.updatelockfile, { skipOwnPid: true });
|
144 |
|
145 | case 12:
|
146 | this.fs.removeSync(dir);
|
147 | this.fs.renameSync(_path2.default.join(tmp, this.base(manifest)), dir);
|
148 | this.fs.removeSync(tmp);
|
149 |
|
150 | case 15:
|
151 | case 'end':
|
152 | return _context2.stop();
|
153 | }
|
154 | }
|
155 | }, _callee2, this);
|
156 | }));
|
157 |
|
158 | function update(_x2) {
|
159 | return _ref2.apply(this, arguments);
|
160 | }
|
161 |
|
162 | return update;
|
163 | }()
|
164 | }, {
|
165 | key: 'extract',
|
166 | value: function extract(stream, dir) {
|
167 | var _this2 = this;
|
168 |
|
169 | var zlib = require('zlib');
|
170 | var tar = require('tar-stream');
|
171 |
|
172 | return new _promise2.default(function (resolve) {
|
173 | _this2.fs.removeSync(dir);
|
174 | var extract = tar.extract();
|
175 | extract.on('entry', function (header, stream, next) {
|
176 | var p = _path2.default.join(dir, header.name);
|
177 | var opts = { mode: header.mode };
|
178 | switch (header.type) {
|
179 | case 'directory':
|
180 | _this2.fs.mkdirpSync(p, opts);
|
181 | next();
|
182 | break;
|
183 | case 'file':
|
184 | stream.pipe(_this2.fs.createWriteStream(p, opts));
|
185 | break;
|
186 | case 'symlink':
|
187 | // ignore symlinks since they will not work on windows
|
188 | next();
|
189 | break;
|
190 | default:
|
191 | throw new Error(header.type);
|
192 | }
|
193 | stream.resume();
|
194 | stream.on('end', next);
|
195 | });
|
196 | extract.on('finish', resolve);
|
197 | stream.pipe(zlib.createGunzip()).pipe(extract);
|
198 | });
|
199 | }
|
200 | }, {
|
201 | key: 'base',
|
202 | value: function base(manifest) {
|
203 | return this.config.name + '-v' + manifest.version + '-' + process.platform + '-' + process.arch;
|
204 | }
|
205 | }, {
|
206 | key: 'restartCLI',
|
207 | value: function () {
|
208 | var _ref3 = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee3() {
|
209 | var _require, spawnSync, _spawnSync, status;
|
210 |
|
211 | return _regenerator2.default.wrap(function _callee3$(_context3) {
|
212 | while (1) {
|
213 | switch (_context3.prev = _context3.next) {
|
214 | case 0:
|
215 | _context3.next = 2;
|
216 | return _rwlockfile2.default.read(this.updatelockfile);
|
217 |
|
218 | case 2:
|
219 | _rwlockfile2.default.unreadSync(this.updatelockfile);
|
220 | _require = require('child_process'), spawnSync = _require.spawnSync;
|
221 |
|
222 | if (this.binPath) {
|
223 | _context3.next = 6;
|
224 | break;
|
225 | }
|
226 |
|
227 | return _context3.abrupt('return');
|
228 |
|
229 | case 6:
|
230 | _spawnSync = spawnSync(this.binPath, process.argv.slice(2), { stdio: 'inherit', shell: true }), status = _spawnSync.status;
|
231 |
|
232 | this.exit(status);
|
233 |
|
234 | case 8:
|
235 | case 'end':
|
236 | return _context3.stop();
|
237 | }
|
238 | }
|
239 | }, _callee3, this);
|
240 | }));
|
241 |
|
242 | function restartCLI() {
|
243 | return _ref3.apply(this, arguments);
|
244 | }
|
245 |
|
246 | return restartCLI;
|
247 | }()
|
248 | }, {
|
249 | key: 'autoupdate',
|
250 | value: function () {
|
251 | var _ref4 = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee4() {
|
252 | var _this3 = this;
|
253 |
|
254 | var fd, _require2, spawn;
|
255 |
|
256 | return _regenerator2.default.wrap(function _callee4$(_context4) {
|
257 | while (1) {
|
258 | switch (_context4.prev = _context4.next) {
|
259 | case 0:
|
260 | _context4.prev = 0;
|
261 |
|
262 | if (this.autoupdateNeeded) {
|
263 | _context4.next = 3;
|
264 | break;
|
265 | }
|
266 |
|
267 | return _context4.abrupt('return');
|
268 |
|
269 | case 3:
|
270 | this.fs.writeFileSync(this.autoupdatefile, '');
|
271 |
|
272 | if (!this.config.updateDisabled) {
|
273 | _context4.next = 7;
|
274 | break;
|
275 | }
|
276 |
|
277 | _context4.next = 7;
|
278 | return this.warnIfUpdateAvailable();
|
279 |
|
280 | case 7:
|
281 | _context4.next = 9;
|
282 | return this.checkIfUpdating();
|
283 |
|
284 | case 9:
|
285 | fd = this.fs.openSync(this.autoupdatelogfile, 'a');
|
286 |
|
287 | if (this.binPath) {
|
288 | _context4.next = 12;
|
289 | break;
|
290 | }
|
291 |
|
292 | return _context4.abrupt('return');
|
293 |
|
294 | case 12:
|
295 | _require2 = require('child_process'), spawn = _require2.spawn;
|
296 |
|
297 | spawn(this.binPath, ['update'], { stdio: [null, fd, fd], detached: true }).on('error', function (e) {
|
298 | return _this3.warn(e, 'autoupdate:');
|
299 | });
|
300 | _context4.next = 19;
|
301 | break;
|
302 |
|
303 | case 16:
|
304 | _context4.prev = 16;
|
305 | _context4.t0 = _context4['catch'](0);
|
306 | this.warn(_context4.t0, 'autoupdate:');
|
307 | case 19:
|
308 | case 'end':
|
309 | return _context4.stop();
|
310 | }
|
311 | }
|
312 | }, _callee4, this, [[0, 16]]);
|
313 | }));
|
314 |
|
315 | function autoupdate() {
|
316 | return _ref4.apply(this, arguments);
|
317 | }
|
318 |
|
319 | return autoupdate;
|
320 | }()
|
321 | }, {
|
322 | key: 'warnIfUpdateAvailable',
|
323 | value: function () {
|
324 | var _ref5 = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee5() {
|
325 | var manifest, local, remote;
|
326 | return _regenerator2.default.wrap(function _callee5$(_context5) {
|
327 | while (1) {
|
328 | switch (_context5.prev = _context5.next) {
|
329 | case 0:
|
330 | _context5.next = 2;
|
331 | return this.fetchManifest(this.config.channel);
|
332 |
|
333 | case 2:
|
334 | manifest = _context5.sent;
|
335 | local = this.config.version.split('.');
|
336 | remote = manifest.version.split('.');
|
337 |
|
338 | if (local[0] !== remote[0] || local[1] !== remote[1]) {
|
339 | this.stderr.log(this.config.name + ': update available from ' + this.config.version + ' to ' + manifest.version);
|
340 | }
|
341 |
|
342 | case 6:
|
343 | case 'end':
|
344 | return _context5.stop();
|
345 | }
|
346 | }
|
347 | }, _callee5, this);
|
348 | }));
|
349 |
|
350 | function warnIfUpdateAvailable() {
|
351 | return _ref5.apply(this, arguments);
|
352 | }
|
353 |
|
354 | return warnIfUpdateAvailable;
|
355 | }()
|
356 | }, {
|
357 | key: 'checkIfUpdating',
|
358 | value: function () {
|
359 | var _ref6 = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee6() {
|
360 | var lock;
|
361 | return _regenerator2.default.wrap(function _callee6$(_context6) {
|
362 | while (1) {
|
363 | switch (_context6.prev = _context6.next) {
|
364 | case 0:
|
365 | lock = require('rwlockfile');
|
366 | _context6.next = 3;
|
367 | return lock.hasWriter(this.updatelockfile);
|
368 |
|
369 | case 3:
|
370 | if (!_context6.sent) {
|
371 | _context6.next = 9;
|
372 | break;
|
373 | }
|
374 |
|
375 | this.warn(this.config.name + ': warning: update in process');
|
376 | _context6.next = 7;
|
377 | return this.restartCLI();
|
378 |
|
379 | case 7:
|
380 | _context6.next = 11;
|
381 | break;
|
382 |
|
383 | case 9:
|
384 | _context6.next = 11;
|
385 | return lock.read(this.updatelockfile);
|
386 |
|
387 | case 11:
|
388 | case 'end':
|
389 | return _context6.stop();
|
390 | }
|
391 | }
|
392 | }, _callee6, this);
|
393 | }));
|
394 |
|
395 | function checkIfUpdating() {
|
396 | return _ref6.apply(this, arguments);
|
397 | }
|
398 |
|
399 | return checkIfUpdating;
|
400 | }()
|
401 | }, {
|
402 | key: 'autoupdatefile',
|
403 | get: function get() {
|
404 | return _path2.default.join(this.config.dirs.cache, 'autoupdate');
|
405 | }
|
406 | }, {
|
407 | key: 'autoupdatelogfile',
|
408 | get: function get() {
|
409 | return _path2.default.join(this.config.dirs.cache, 'autoupdate.log');
|
410 | }
|
411 | }, {
|
412 | key: 'updatelockfile',
|
413 | get: function get() {
|
414 | return _path2.default.join(this.config.dirs.cache, 'update.lock');
|
415 | }
|
416 | }, {
|
417 | key: 'binPath',
|
418 | get: function get() {
|
419 | return process.env.CLI_BINPATH;
|
420 | }
|
421 | }, {
|
422 | key: 'autoupdateNeeded',
|
423 | get: function get() {
|
424 | try {
|
425 | var moment = require('moment');
|
426 | var stat = this.fs.statSync(this.autoupdatefile);
|
427 | return moment(stat.mtime).isBefore(moment().subtract(4, 'hours'));
|
428 | } catch (err) {
|
429 | if (err.code !== 'ENOENT') console.error(err.stack);
|
430 | return true;
|
431 | }
|
432 | }
|
433 | }]);
|
434 | return _class;
|
435 | }(_cliEngineCommand.Base);
|
436 | /* globals
|
437 | stream$Readable
|
438 | */
|
439 |
|
440 | exports.default = _class;
|
441 | //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy91cGRhdGVyLmpzIl0sIm5hbWVzIjpbImNoYW5uZWwiLCJjb25maWciLCJzMyIsImhvc3QiLCJFcnJvciIsInVybCIsIm5hbWUiLCJwcm9jZXNzIiwicGxhdGZvcm0iLCJhcmNoIiwiaHR0cCIsImdldCIsIm1hbmlmZXN0Iiwic3RhdHVzQ29kZSIsImJhc2UiLCJzdHJlYW0iLCJkaXIiLCJqb2luIiwiZGlycyIsImRhdGEiLCJ0bXAiLCJleHRyYWN0Iiwid3JpdGUiLCJ1cGRhdGVsb2NrZmlsZSIsInNraXBPd25QaWQiLCJmcyIsInJlbW92ZVN5bmMiLCJyZW5hbWVTeW5jIiwiemxpYiIsInJlcXVpcmUiLCJ0YXIiLCJvbiIsImhlYWRlciIsIm5leHQiLCJwIiwib3B0cyIsIm1vZGUiLCJ0eXBlIiwibWtkaXJwU3luYyIsInBpcGUiLCJjcmVhdGVXcml0ZVN0cmVhbSIsInJlc3VtZSIsInJlc29sdmUiLCJjcmVhdGVHdW56aXAiLCJ2ZXJzaW9uIiwicmVhZCIsInVucmVhZFN5bmMiLCJzcGF3blN5bmMiLCJiaW5QYXRoIiwiYXJndiIsInNsaWNlIiwic3RkaW8iLCJzaGVsbCIsInN0YXR1cyIsImV4aXQiLCJhdXRvdXBkYXRlTmVlZGVkIiwid3JpdGVGaWxlU3luYyIsImF1dG91cGRhdGVmaWxlIiwidXBkYXRlRGlzYWJsZWQiLCJ3YXJuSWZVcGRhdGVBdmFpbGFibGUiLCJjaGVja0lmVXBkYXRpbmciLCJmZCIsIm9wZW5TeW5jIiwiYXV0b3VwZGF0ZWxvZ2ZpbGUiLCJzcGF3biIsImRldGFjaGVkIiwid2FybiIsImUiLCJmZXRjaE1hbmlmZXN0IiwibG9jYWwiLCJzcGxpdCIsInJlbW90ZSIsInN0ZGVyciIsImxvZyIsImxvY2siLCJoYXNXcml0ZXIiLCJyZXN0YXJ0Q0xJIiwiY2FjaGUiLCJlbnYiLCJDTElfQklOUEFUSCIsIm1vbWVudCIsInN0YXQiLCJzdGF0U3luYyIsIm10aW1lIiwiaXNCZWZvcmUiLCJzdWJ0cmFjdCIsImVyciIsImNv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QUwsQ0FBYSxLQUFLakUsTUFBTCxDQUFZSyxJQUF6Qjs7dUJBQ00sS0FBS3NFLFVBQUwsRTs7Ozs7Ozs7dUJBQ0tGLEtBQUs3QixJQUFMLENBQVUsS0FBS3RCLGNBQWYsQzs7Ozs7Ozs7Ozs7Ozs7Ozs7O3dCQXBIZTtBQUFFLGFBQU8sZUFBS04sSUFBTCxDQUFVLEtBQUtoQixNQUFMLENBQVlpQixJQUFaLENBQWlCMkQsS0FBM0IsRUFBa0MsWUFBbEMsQ0FBUDtBQUF3RDs7O3dCQUN2RDtBQUFFLGFBQU8sZUFBSzVELElBQUwsQ0FBVSxLQUFLaEIsTUFBTCxDQUFZaUIsSUFBWixDQUFpQjJELEtBQTNCLEVBQWtDLGdCQUFsQyxDQUFQO0FBQTREOzs7d0JBQ2pFO0FBQUUsYUFBTyxlQUFLNUQsSUFBTCxDQUFVLEtBQUtoQixNQUFMLENBQVlpQixJQUFaLENBQWlCMkQsS0FBM0IsRUFBa0MsYUFBbEMsQ0FBUDtBQUF5RDs7O3dCQUNqRTtBQUFFLGFBQU90RSxRQUFRdUUsR0FBUixDQUFZQyxXQUFuQjtBQUFnQzs7O3dCQTBFbEM7QUFDdEIsVUFBSTtBQUNGLFlBQU1DLFNBQVNuRCxRQUFRLFFBQVIsQ0FBZjtBQUNBLFlBQU1vRCxPQUFPLEtBQUt4RCxFQUFMLENBQVF5RCxRQUFSLENBQWlCLEtBQUt6QixjQUF0QixDQUFiO0FBQ0EsZUFBT3VCLE9BQU9DLEtBQUtFLEtBQVosRUFBbUJDLFFBQW5CLENBQTRCSixTQUFTSyxRQUFULENBQWtCLENBQWxCLEVBQXFCLE9BQXJCLENBQTVCLENBQVA7QUFDRCxPQUpELENBSUUsT0FBT0MsR0FBUCxFQUFZO0FBQ1osWUFBSUEsSUFBSUMsSUFBSixLQUFhLFFBQWpCLEVBQTJCQyxRQUFRQyxLQUFSLENBQWNILElBQUlJLEtBQWxCO0FBQzNCLGVBQU8sSUFBUDtBQUNEO0FBQ0Y7Ozs7QUFyR0giLCJmaWxlIjoidXBkYXRlci5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8vIEBmbG93XG4vKiBnbG9iYWxzXG4gICBzdHJlYW0kUmVhZGFibGVcbiovXG5cbmltcG9ydCB7QmFzZX0gZnJvbSAnY2xpLWVuZ2luZS1jb21tYW5kJ1xuaW1wb3J0IHBhdGggZnJvbSAncGF0aCdcbmltcG9ydCBsb2NrIGZyb20gJ3J3bG9ja2ZpbGUnXG5cbnR5cGUgTWFuaWZlc3QgPSB7XG4gIHZlcnNpb246IHN0cmluZyxcbiAgY2hhbm5lbDogc3RyaW5nLFxuICBzaGEyNTY6IHN0cmluZ1xufVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBleHRlbmRzIEJhc2Uge1xuICBnZXQgYXV0b3VwZGF0ZWZpbGUgKCk6IHN0cmluZyB7IHJldHVybiBwYXRoLmpvaW4odGhpcy5jb25maWcuZGlycy5jYWNoZSwgJ2F1dG91cGRhdGUnKSB9XG4gIGdldCBhdXRvdXBkYXRlbG9nZmlsZSAoKTogc3RyaW5nIHsgcmV0dXJuIHBhdGguam9pbih0aGlzLmNvbmZpZy5kaXJzLmNhY2hlLCAnYXV0b3VwZGF0ZS5sb2cnKSB9XG4gIGdldCB1cGRhdGVsb2NrZmlsZSAoKTogc3RyaW5nIHsgcmV0dXJuIHBhdGguam9pbih0aGlzLmNvbmZpZy5kaXJzLmNhY2hlLCAndXBkYXRlLmxvY2snKSB9XG4gIGdldCBiaW5QYXRoICgpOiA/c3RyaW5nIHsgcmV0dXJuIHByb2Nlc3MuZW52LkNMSV9CSU5QQVRIIH1cblxuICBhc3luYyBmZXRjaE1hbmlmZXN0IChjaGFubmVsOiBzdHJpbmcpOiBQcm9taXNlPE1hbmlmZXN0PiB7XG4gICAgaWYgKCF0aGlzLmNvbmZpZy5zMy5ob3N0KSB0aHJvdyBuZXcgRXJyb3IoJ1MzIGhvc3Qgbm90IGRlZmluZWQnKVxuICAgIHRyeSB7XG4gICAgICBsZXQgdXJsID0gYGh0dHBzOi8vJHt0aGlzLmNvbmZpZy5zMy5ob3N0fS8ke3RoaXMuY29uZmlnLm5hbWV9L2NoYW5uZWxzLyR7Y2hhbm5lbH0vJHtwcm9jZXNzLnBsYXRmb3JtfS0ke3Byb2Nlc3MuYXJjaH1gXG4gICAgICBsZXQgbWFuaWZlc3QgPSBhd2FpdCB0aGlzLmh0dHAuZ2V0KHVybClcbiAgICAgIHJldHVybiAoKG1hbmlmZXN0OiBhbnkpOiBQcm9taXNlPE1hbmlmZXN0PilcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGlmIChlcnIuc3RhdHVzQ29kZSA9PT0gNDAzKSB0aHJvdyBuZXcgRXJyb3IoYEhUVFAgNDAzOiBJbnZhbGlkIGNoYW5uZWwgJHtjaGFubmVsfWApXG4gICAgICB0aHJvdyBlcnJcbiAgICB9XG4gIH1cblxuICBhc3luYyB1cGRhdGUgKG1hbmlmZXN0OiBNYW5pZmVzdCkge1xuICAgIGlmICghdGhpcy5jb25maWcuczMuaG9zdCkgdGhyb3cgbmV3IEVycm9yKCdTMyBob3N0IG5vdCBkZWZpbmVkJylcbiAgICBsZXQgdXJsID0gYGh0dHBzOi8vJHt0aGlzLmNvbmZpZy5zMy5ob3N0fS8ke3RoaXMuY29uZmlnLm5hbWV9L2NoYW5uZWxzLyR7bWFuaWZlc3QuY2hhbm5lbH0vJHt0aGlzLmJhc2UobWFuaWZlc3QpfS50YXIuZ3pgXG4gICAgbGV0IHN0cmVhbSA9IGF3YWl0IHRoaXMuaHR0cC5zdHJlYW0odXJsKVxuICAgIGxldCBkaXIgPSBwYXRoLmpvaW4odGhpcy5jb25maWcuZGlycy5kYXRhLCAnY2xpJylcbiAgICBsZXQgdG1wID0gcGF0aC5qb2luKHRoaXMuY29uZmlnLmRpcnMuZGF0YSwgJ2NsaV90bXAnKVxuICAgIGF3YWl0IHRoaXMuZXh0cmFjdChzdHJlYW0sIHRtcClcbiAgICBhd2FpdCBsb2NrLndyaXRlKHRoaXMudXBkYXRlbG9ja2ZpbGUsIHtza2lwT3duUGlkOiB0cnVlfSlcbiAgICB0aGlzLmZzLnJlbW92ZVN5bmMoZGlyKVxuICAgIHRoaXMuZnMucmVuYW1lU3luYyhwYXRoLmpvaW4odG1wLCB0aGlzLmJhc2UobWFuaWZlc3QpKSwgZGlyKVxuICAgIHRoaXMuZnMucmVtb3ZlU3luYyh0bXApXG4gIH1cblxuICBleHRyYWN0IChzdHJlYW06IHN0cmVhbSRSZWFkYWJsZSwgZGlyOiBzdHJpbmcpIHtcbiAgICBjb25zdCB6bGliID0gcmVxdWlyZSgnemxpYicpXG4gICAgY29uc3QgdGFyID0gcmVxdWlyZSgndGFyLXN0cmVhbScpXG5cbiAgICByZXR1cm4gbmV3IFByb21pc2UocmVzb2x2ZSA9PiB7XG4gICAgICB0aGlzLmZzLnJlbW92ZVN5bmMoZGlyKVxuICAgICAgbGV0IGV4dHJhY3QgPSB0YXIuZXh0cmFjdCgpXG4gICAgICBleHRyYWN0Lm9uKCdlbnRyeScsIChoZWFkZXIsIHN0cmVhbSwgbmV4dCkgPT4ge1xuICAgICAgICBsZXQgcCA9IHBhdGguam9pbihkaXIsIGhlYWRlci5uYW1lKVxuICAgICAgICBsZXQgb3B0cyA9IHttb2RlOiBoZWFkZXIubW9kZX1cbiAgICAgICAgc3dpdGNoIChoZWFkZXIudHlwZSkge1xuICAgICAgICAgIGNhc2UgJ2RpcmVjdG9yeSc6XG4gICAgICAgICAgICB0aGlzLmZzLm1rZGlycFN5bmMocCwgb3B0cylcbiAgICAgICAgICAgIG5leHQoKVxuICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICBjYXNlICdmaWxlJzpcbiAgICAgICAgICAgIHN0cmVhbS5waXBlKHRoaXMuZnMuY3JlYXRlV3JpdGVTdHJlYW0ocCwgb3B0cykpXG4gICAgICAgICAgICBicmVha1xuICAgICAgICAgIGNhc2UgJ3N5bWxpbmsnOlxuICAgICAgICAgICAgLy8gaWdub3JlIHN5bWxpbmtzIHNpbmNlIHRoZXkgd2lsbCBub3Qgd29yayBvbiB3aW5kb3dzXG4gICAgICAgICAgICBuZXh0KClcbiAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgZGVmYXVsdDogdGhyb3cgbmV3IEVycm9yKGhlYWRlci50eXBlKVxuICAgICAgICB9XG4gICAgICAgIHN0cmVhbS5yZXN1bWUoKVxuICAgICAgICBzdHJlYW0ub24oJ2VuZCcsIG5leHQpXG4gICAgICB9KVxuICAgICAgZXh0cmFjdC5vbignZmluaXNoJywgcmVzb2x2ZSlcbiAgICAgIHN0cmVhbVxuICAgICAgLnBpcGUoemxpYi5jcmVhdGVHdW56aXAoKSlcbiAgICAgIC5waXBlKGV4dHJhY3QpXG4gICAgfSlcbiAgfVxuXG4gIGJhc2UgKG1hbmlmZXN0OiBNYW5pZmVzdCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGAke3RoaXMuY29uZmlnLm5hbWV9LXYke21hbmlmZXN0LnZlcnNpb259LSR7cHJvY2Vzcy5wbGF0Zm9ybX0tJHtwcm9jZXNzLmFyY2h9YFxuICB9XG5cbiAgYXN5bmMgcmVzdGFydENMSSAoKSB7XG4gICAgYXdhaXQgbG9jay5yZWFkKHRoaXMudXBkYXRlbG9ja2ZpbGUpXG4gICAgbG9jay51bnJlYWRTeW5jKHRoaXMudXBkYXRlbG9ja2ZpbGUpXG4gICAgY29uc3Qge3NwYXduU3luY30gPSByZXF1aXJlKCdjaGlsZF9wcm9jZXNzJylcbiAgICBpZiAoIXRoaXMuYmluUGF0aCkgcmV0dXJuXG4gICAgY29uc3Qge3N0YXR1c30gPSBzcGF3blN5bmModGhpcy5iaW5QYXRoLCBwcm9jZXNzLmFyZ3Yuc2xpY2UoMiksIHtzdGRpbzogJ2luaGVyaXQnLCBzaGVsbDogdHJ1ZX0pXG4gICAgdGhpcy5leGl0KHN0YXR1cylcbiAgfVxuXG4gIGdldCBhdXRvdXBkYXRlTmVlZGVkICgpIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgbW9tZW50ID0gcmVxdWlyZSgnbW9tZW50JylcbiAgICAgIGNvbnN0IHN0YXQgPSB0aGlzLmZzLnN0YXRTeW5jKHRoaXMuYXV0b3VwZGF0ZWZpbGUpXG4gICAgICByZXR1cm4gbW9tZW50KHN0YXQubXRpbWUpLmlzQmVmb3JlKG1vbWVudCgpLnN1YnRyYWN0KDQsICdob3VycycpKVxuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgaWYgKGVyci5jb2RlICE9PSAnRU5PRU5UJykgY29uc29sZS5lcnJvcihlcnIuc3RhY2spXG4gICAgICByZXR1cm4gdHJ1ZVxuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGF1dG91cGRhdGUgKCkge1xuICAgIHRyeSB7XG4gICAgICBpZiAoIXRoaXMuYXV0b3VwZGF0ZU5lZWRlZCkgcmV0dXJuXG4gICAgICB0aGlzLmZzLndyaXRlRmlsZVN5bmModGhpcy5hdXRvdXBkYXRlZmlsZSwgJycpXG4gICAgICBpZiAodGhpcy5jb25maWcudXBkYXRlRGlzYWJsZWQpIGF3YWl0IHRoaXMud2FybklmVXBkYXRlQXZhaWxhYmxlKClcbiAgICAgIGF3YWl0IHRoaXMuY2hlY2tJZlVwZGF0aW5nKClcbiAgICAgIGxldCBmZCA9IHRoaXMuZnMub3BlblN5bmModGhpcy5hdXRvdXBkYXRlbG9nZmlsZSwgJ2EnKVxuICAgICAgaWYgKCF0aGlzLmJpblBhdGgpIHJldHVyblxuICAgICAgY29uc3Qge3NwYXdufSA9IHJlcXVpcmUoJ2NoaWxkX3Byb2Nlc3MnKVxuICAgICAgc3Bhd24odGhpcy5iaW5QYXRoLCBbJ3VwZGF0ZSddLCB7c3RkaW86IFtudWxsLCBmZCwgZmRdLCBkZXRhY2hlZDogdHJ1ZX0pXG4gICAgICAub24oJ2Vycm9yJywgZSA9PiB0aGlzLndhcm4oZSwgJ2F1dG91cGRhdGU6JykpXG4gICAgfSBjYXRjaCAoZSkgeyB0aGlzLndhcm4oZSwgJ2F1dG91cGRhdGU6JykgfVxuICB9XG5cbiAgYXN5bmMgd2FybklmVXBkYXRlQXZhaWxhYmxlICgpIHtcbiAgICBjb25zdCBtYW5pZmVzdCA9IGF3YWl0IHRoaXMuZmV0Y2hNYW5pZmVzdCh0aGlzLmNvbmZpZy5jaGFubmVsKVxuICAgIGxldCBsb2NhbCA9IHRoaXMuY29uZmlnLnZlcnNpb24uc3BsaXQoJy4nKVxuICAgIGxldCByZW1vdGUgPSBtYW5pZmVzdC52ZXJzaW9uLnNwbGl0KCcuJylcbiAgICBpZiAobG9jYWxbMF0gIT09IHJlbW90ZVswXSB8fCBsb2NhbFsxXSAhPT0gcmVtb3RlWzFdKSB7XG4gICAgICB0aGlzLnN0ZGVyci5sb2coYCR7dGhpcy5jb25maWcubmFtZX06IHVwZGF0ZSBhdmFpbGFibGUgZnJvbSAke3RoaXMuY29uZmlnLnZlcnNpb259IHRvICR7bWFuaWZlc3QudmVyc2lvbn1gKVxuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGNoZWNrSWZVcGRhdGluZyAoKSB7XG4gICAgY29uc3QgbG9jayA9IHJlcXVpcmUoJ3J3bG9ja2ZpbGUnKVxuICAgIGlmIChhd2FpdCBsb2NrLmhhc1dyaXRlcih0aGlzLnVwZGF0ZWxvY2tmaWxlKSkge1xuICAgICAgdGhpcy53YXJuKGAke3RoaXMuY29uZmlnLm5hbWV9OiB3YXJuaW5nOiB1cGRhdGUgaW4gcHJvY2Vzc2ApXG4gICAgICBhd2FpdCB0aGlzLnJlc3RhcnRDTEkoKVxuICAgIH0gZWxzZSBhd2FpdCBsb2NrLnJlYWQodGhpcy51cGRhdGVsb2NrZmlsZSlcbiAgfVxufVxuIl19 |
\ | No newline at end of file |