UNPKG

electron-compile

Version:

Electron supporting package to compile JS and CSS in Electron applications

270 lines (201 loc) 21.3 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _regenerator = require('babel-runtime/regenerator'); var _regenerator2 = _interopRequireDefault(_regenerator); var _typeof2 = require('babel-runtime/helpers/typeof'); var _typeof3 = _interopRequireDefault(_typeof2); var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator'); var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2); exports.rigHtmlDocumentToInitializeElectronCompile = rigHtmlDocumentToInitializeElectronCompile; exports.initializeProtocolHook = initializeProtocolHook; require('./babel-maybefill'); var _url = require('url'); var _url2 = _interopRequireDefault(_url); var _fs = require('fs'); var _fs2 = _interopRequireDefault(_fs); var _mimeTypes = require('@paulcbetts/mime-types'); var _mimeTypes2 = _interopRequireDefault(_mimeTypes); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var magicWords = "__magic__file__to__help__electron__compile.js"; // NB: These are duped in initialize-renderer so we can save startup time, make // sure to run both! var magicGlobalForRootCacheDir = '__electron_compile_root_cache_dir'; var magicGlobalForAppRootDir = '__electron_compile_app_root_dir'; var d = require('debug-electron')('electron-compile:protocol-hook'); var protocol = null; /** * Adds our script header to the top of all HTML files * * @private */ function rigHtmlDocumentToInitializeElectronCompile(doc) { var lines = doc.split("\n"); var replacement = '<head><script src="' + magicWords + '"></script>'; var replacedHead = false; for (var i = 0; i < lines.length; i++) { if (!lines[i].match(/<head>/i)) continue; lines[i] = lines[i].replace(/<head>/i, replacement); replacedHead = true; break; } if (!replacedHead) { replacement = '<html$1><head><script src="' + magicWords + '"></script></head>'; for (var _i = 0; _i < lines.length; _i++) { if (!lines[_i].match(/<html/i)) continue; lines[_i] = lines[_i].replace(/<html([^>]+)>/i, replacement); break; } } return lines.join("\n"); } function requestFileJob(filePath, finish) { _fs2.default.readFile(filePath, function (err, buf) { if (err) { if (err.errno === 34) { finish(-6); // net::ERR_FILE_NOT_FOUND return; } else { finish(-2); // net::FAILED return; } } finish({ data: buf, mimeType: _mimeTypes2.default.lookup(filePath) || 'text/plain' }); }); } /** * Initializes the protocol hook on file: that allows us to intercept files * loaded by Chromium and rewrite them. This method along with * {@link registerRequireExtension} are the top-level methods that electron-compile * actually uses to intercept code that Electron loads. * * @param {CompilerHost} compilerHost The compiler host to use for compilation. */ function initializeProtocolHook(compilerHost) { protocol = protocol || require('electron').protocol; global[magicGlobalForRootCacheDir] = compilerHost.rootCacheDir; global[magicGlobalForAppRootDir] = compilerHost.appRoot; var electronCompileSetupCode = 'if (window.require) require(\'electron-compile/lib/initialize-renderer\').initializeRendererProcess(' + compilerHost.readOnlyMode + ');'; protocol.interceptBufferProtocol('file', function () { var _ref = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee(request, finish) { var uri, filePath, _ret, result, err; return _regenerator2.default.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: uri = _url2.default.parse(request.url); d('Intercepting url ' + request.url); if (!(request.url.indexOf(magicWords) > -1)) { _context.next = 5; break; } finish({ mimeType: 'application/javascript', data: new Buffer(electronCompileSetupCode, 'utf8') }); return _context.abrupt('return'); case 5: if (!(uri.host && uri.host.length > 1)) { _context.next = 9; break; } //let newUri = request.url.replace(/^file:/, "https:"); // TODO: Jump off this bridge later d('TODO: Found bogus protocol-relative URL, can\'t fix it up!!'); finish(-2); return _context.abrupt('return'); case 9: filePath = decodeURIComponent(uri.pathname); // NB: pathname has a leading '/' on Win32 for some reason if (process.platform === 'win32') { filePath = filePath.slice(1); } // NB: Special-case files coming from atom.asar or node_modules if (!(filePath.match(/[\/\\](atom|electron).asar/) || filePath.match(/[\/\\](node_modules|bower_components)/))) { _context.next = 18; break; } if (!filePath.match(/\.html?$/i)) { _context.next = 16; break; } _ret = function () { var riggedContents = null; _fs2.default.readFile(filePath, 'utf8', function (err, contents) { if (err) { if (err.errno === 34) { finish(-6); // net::ERR_FILE_NOT_FOUND return; } else { finish(-2); // net::FAILED return; } } riggedContents = rigHtmlDocumentToInitializeElectronCompile(contents); finish({ data: new Buffer(riggedContents), mimeType: 'text/html' }); return; }); return { v: void 0 }; }(); if (!((typeof _ret === 'undefined' ? 'undefined' : (0, _typeof3.default)(_ret)) === "object")) { _context.next = 16; break; } return _context.abrupt('return', _ret.v); case 16: requestFileJob(filePath, finish); return _context.abrupt('return'); case 18: _context.prev = 18; _context.next = 21; return compilerHost.compile(filePath); case 21: result = _context.sent; if (result.mimeType === 'text/html') { result.code = rigHtmlDocumentToInitializeElectronCompile(result.code); } if (!(result.binaryData || result.code instanceof Buffer)) { _context.next = 28; break; } finish({ data: result.binaryData || result.code, mimeType: result.mimeType }); return _context.abrupt('return'); case 28: finish({ data: new Buffer(result.code), mimeType: result.mimeType }); return _context.abrupt('return'); case 30: _context.next = 41; break; case 32: _context.prev = 32; _context.t0 = _context['catch'](18); err = 'Failed to compile ' + filePath + ': ' + _context.t0.message + '\n' + _context.t0.stack; d(err); if (!(_context.t0.errno === 34 /*ENOENT*/)) { _context.next = 39; break; } finish(-6); // net::ERR_FILE_NOT_FOUND return _context.abrupt('return'); case 39: finish({ mimeType: 'text/plain', data: new Buffer(err) }); return _context.abrupt('return'); case 41: case 'end': return _context.stop(); } } }, _callee, this, [[18, 32]]); })); return function (_x, _x2) { return _ref.apply(this, arguments); }; }()); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9wcm90b2NvbC1ob29rLmpzIl0sIm5hbWVzIjpbInJpZ0h0bWxEb2N1bWVudFRvSW5pdGlhbGl6ZUVsZWN0cm9uQ29tcGlsZSIsImluaXRpYWxpemVQcm90b2NvbEhvb2siLCJtYWdpY1dvcmRzIiwibWFnaWNHbG9iYWxGb3JSb290Q2FjaGVEaXIiLCJtYWdpY0dsb2JhbEZvckFwcFJvb3REaXIiLCJkIiwicmVxdWlyZSIsInByb3RvY29sIiwiZG9jIiwibGluZXMiLCJzcGxpdCIsInJlcGxhY2VtZW50IiwicmVwbGFjZWRIZWFkIiwiaSIsImxlbmd0aCIsIm1hdGNoIiwicmVwbGFjZSIsImpvaW4iLCJyZXF1ZXN0RmlsZUpvYiIsImZpbGVQYXRoIiwiZmluaXNoIiwicmVhZEZpbGUiLCJlcnIiLCJidWYiLCJlcnJubyIsImRhdGEiLCJtaW1lVHlwZSIsImxvb2t1cCIsImNvbXBpbGVySG9zdCIsImdsb2JhbCIsInJvb3RDYWNoZURpciIsImFwcFJvb3QiLCJlbGVjdHJvbkNvbXBpbGVTZXR1cENvZGUiLCJyZWFkT25seU1vZGUiLCJpbnRlcmNlcHRCdWZmZXJQcm90b2NvbCIsInJlcXVlc3QiLCJ1cmkiLCJwYXJzZSIsInVybCIsImluZGV4T2YiLCJCdWZmZXIiLCJob3N0IiwiZGVjb2RlVVJJQ29tcG9uZW50IiwicGF0aG5hbWUiLCJwcm9jZXNzIiwicGxhdGZvcm0iLCJzbGljZSIsInJpZ2dlZENvbnRlbnRzIiwiY29udGVudHMiLCJjb21waWxlIiwicmVzdWx0IiwiY29kZSIsImJpbmFyeURhdGEiLCJtZXNzYWdlIiwic3RhY2siXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7OztRQXNCZ0JBLDBDLEdBQUFBLDBDO1FBcURBQyxzQixHQUFBQSxzQjs7QUEzRWhCOztBQUVBOzs7O0FBQ0E7Ozs7QUFDQTs7Ozs7O0FBRUEsSUFBTUMsYUFBYSwrQ0FBbkI7O0FBRUE7QUFDQTtBQUNBLElBQU1DLDZCQUE2QixtQ0FBbkM7QUFDQSxJQUFN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eWJlZmlsbCc7XG5cbmltcG9ydCB1cmwgZnJvbSAndXJsJztcbmltcG9ydCBmcyBmcm9tICdmcyc7XG5pbXBvcnQgbWltZSBmcm9tICdAcGF1bGNiZXR0cy9taW1lLXR5cGVzJztcblxuY29uc3QgbWFnaWNXb3JkcyA9IFwiX19tYWdpY19fZmlsZV9fdG9fX2hlbHBfX2VsZWN0cm9uX19jb21waWxlLmpzXCI7XG5cbi8vIE5COiBUaGVzZSBhcmUgZHVwZWQgaW4gaW5pdGlhbGl6ZS1yZW5kZXJlciBzbyB3ZSBjYW4gc2F2ZSBzdGFydHVwIHRpbWUsIG1ha2Vcbi8vIHN1cmUgdG8gcnVuIGJvdGghXG5jb25zdCBtYWdpY0dsb2JhbEZvclJvb3RDYWNoZURpciA9ICdfX2VsZWN0cm9uX2NvbXBpbGVfcm9vdF9jYWNoZV9kaXInO1xuY29uc3QgbWFnaWNHbG9iYWxGb3JBcHBSb290RGlyID0gJ19fZWxlY3Ryb25fY29tcGlsZV9hcHBfcm9vdF9kaXInO1xuXG5jb25zdCBkID0gcmVxdWlyZSgnZGVidWctZWxlY3Ryb24nKSgnZWxlY3Ryb24tY29tcGlsZTpwcm90b2NvbC1ob29rJyk7XG5cbmxldCBwcm90b2NvbCA9IG51bGw7XG5cbi8qKlxuICogQWRkcyBvdXIgc2NyaXB0IGhlYWRlciB0byB0aGUgdG9wIG9mIGFsbCBIVE1MIGZpbGVzXG4gKlxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJpZ0h0bWxEb2N1bWVudFRvSW5pdGlhbGl6ZUVsZWN0cm9uQ29tcGlsZShkb2MpIHtcbiAgbGV0IGxpbmVzID0gZG9jLnNwbGl0KFwiXFxuXCIpO1xuICBsZXQgcmVwbGFjZW1lbnQgPSBgPGhlYWQ+PHNjcmlwdCBzcmM9XCIke21hZ2ljV29yZHN9XCI+PC9zY3JpcHQ+YDtcbiAgbGV0IHJlcGxhY2VkSGVhZCA9IGZhbHNlO1xuXG4gIGZvciAobGV0IGk9MDsgaSA8IGxpbmVzLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKCFsaW5lc1tpXS5tYXRjaCgvPGhlYWQ+L2kpKSBjb250aW51ZTtcblxuICAgIGxpbmVzW2ldID0gKGxpbmVzW2ldKS5yZXBsYWNlKC88aGVhZD4vaSwgcmVwbGFjZW1lbnQpO1xuICAgIHJlcGxhY2VkSGVhZCA9IHRydWU7XG4gICAgYnJlYWs7XG4gIH1cblxuICBpZiAoIXJlcGxhY2VkSGVhZCkge1xuICAgIHJlcGxhY2VtZW50ID0gYDxodG1sJDE+PGhlYWQ+PHNjcmlwdCBzcmM9XCIke21hZ2ljV29yZHN9XCI+PC9zY3JpcHQ+PC9oZWFkPmA7XG4gICAgZm9yIChsZXQgaT0wOyBpIDwgbGluZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmICghbGluZXNbaV0ubWF0Y2goLzxodG1sL2kpKSBjb250aW51ZTtcblxuICAgICAgbGluZXNbaV0gPSAobGluZXNbaV0pLnJlcGxhY2UoLzxodG1sKFtePl0rKT4vaSwgcmVwbGFjZW1lbnQpO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGxpbmVzLmpvaW4oXCJcXG5cIik7XG59XG5cbmZ1bmN0aW9uIHJlcXVlc3RGaWxlSm9iKGZpbGVQYXRoLCBmaW5pc2gpIHtcbiAgZnMucmVhZEZpbGUoZmlsZVBhdGgsIChlcnIsIGJ1ZikgPT4ge1xuICAgIGlmIChlcnIpIHtcbiAgICAgIGlmIChlcnIuZXJybm8gPT09IDM0KSB7XG4gICAgICAgIGZpbmlzaCgtNik7IC8vIG5ldDo6RVJSX0ZJTEVfTk9UX0ZPVU5EXG4gICAgICAgIHJldHVybjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGZpbmlzaCgtMik7IC8vIG5ldDo6RkFJTEVEXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmaW5pc2goe1xuICAgICAgZGF0YTogYnVmLFxuICAgICAgbWltZVR5cGU6IG1pbWUubG9va3VwKGZpbGVQYXRoKSB8fCAndGV4dC9wbGFpbidcbiAgICB9KTtcbiAgfSk7XG59XG5cbi8qKlxuICogSW5pdGlhbGl6ZXMgdGhlIHByb3RvY29sIGhvb2sgb24gZmlsZTogdGhhdCBhbGxvd3MgdXMgdG8gaW50ZXJjZXB0IGZpbGVzXG4gKiBsb2FkZWQgYnkgQ2hyb21pdW0gYW5kIHJld3JpdGUgdGhlbS4gVGhpcyBtZXRob2QgYWxvbmcgd2l0aFxuICoge0BsaW5rIHJlZ2lzdGVyUmVxdWlyZUV4dGVuc2lvbn0gYXJlIHRoZSB0b3AtbGV2ZWwgbWV0aG9kcyB0aGF0IGVsZWN0cm9uLWNvbXBpbGVcbiAqIGFjdHVhbGx5IHVzZXMgdG8gaW50ZXJjZXB0IGNvZGUgdGhhdCBFbGVjdHJvbiBsb2Fkcy5cbiAqXG4gKiBAcGFyYW0gIHtDb21waWxlckhvc3R9IGNvbXBpbGVySG9zdCAgVGhlIGNvbXBpbGVyIGhvc3QgdG8gdXNlIGZvciBjb21waWxhdGlvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGluaXRpYWxpemVQcm90b2NvbEhvb2soY29tcGlsZXJIb3N0KSB7XG4gIHByb3RvY29sID0gcHJvdG9jb2wgfHwgcmVxdWlyZSgnZWxlY3Ryb24nKS5wcm90b2NvbDtcblxuICBnbG9iYWxbbWFnaWNHbG9iYWxGb3JSb290Q2FjaGVEaXJdID0gY29tcGlsZXJIb3N0LnJvb3RDYWNoZURpcjtcbiAgZ2xvYmFsW21hZ2ljR2xvYmFsRm9yQXBwUm9vdERpcl0gPSBjb21waWxlckhvc3QuYXBwUm9vdDtcblxuICBjb25zdCBlbGVjdHJvbkNvbXBpbGVTZXR1cENvZGUgPSBgaWYgKHdpbmRvdy5yZXF1aXJlKSByZXF1aXJlKCdlbGVjdHJvbi1jb21waWxlL2xpYi9pbml0aWFsaXplLXJlbmRlcmVyJykuaW5pdGlhbGl6ZVJlbmRlcmVyUHJvY2Vzcygke2NvbXBpbGVySG9zdC5yZWFkT25seU1vZGV9KTtgO1xuXG4gIHByb3RvY29sLmludGVyY2VwdEJ1ZmZlclByb3RvY29sKCdmaWxlJywgYXN5bmMgZnVuY3Rpb24ocmVxdWVzdCwgZmluaXNoKSB7XG4gICAgbGV0IHVyaSA9IHVybC5wYXJzZShyZXF1ZXN0LnVybCk7XG5cbiAgICBkKGBJbnRlcmNlcHRpbmcgdXJsICR7cmVxdWVzdC51cmx9YCk7XG4gICAgaWYgKHJlcXVlc3QudXJsLmluZGV4T2YobWFnaWNXb3JkcykgPiAtMSkge1xuICAgICAgZmluaXNoKHtcbiAgICAgICAgbWltZVR5cGU6ICdhcHBsaWNhdGlvbi9qYXZhc2NyaXB0JyxcbiAgICAgICAgZGF0YTogbmV3IEJ1ZmZlcihlbGVjdHJvbkNvbXBpbGVTZXR1cENvZGUsICd1dGY4JylcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gVGhpcyBpcyBhIHByb3RvY29sLXJlbGF0aXZlIFVSTCB0aGF0IGhhcyBnb25lIHBlYXItc2hhcGVkIGluIEVsZWN0cm9uLFxuICAgIC8vIGxldCdzIHJld3JpdGUgaXRcbiAgICBpZiAodXJpLmhvc3QgJiYgdXJpLmhvc3QubGVuZ3RoID4gMSkge1xuICAgICAgLy9sZXQgbmV3VXJpID0gcmVxdWVzdC51cmwucmVwbGFjZSgvXmZpbGU6LywgXCJodHRwczpcIik7XG4gICAgICAvLyBUT0RPOiBKdW1wIG9mZiB0aGlzIGJyaWRnZSBsYXRlclxuICAgICAgZChgVE9ETzogRm91bmQgYm9ndXMgcHJvdG9jb2wtcmVsYXRpdmUgVVJMLCBjYW4ndCBmaXggaXQgdXAhIWApO1xuICAgICAgZmluaXNoKC0yKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBsZXQgZmlsZVBhdGggPSBkZWNvZGVVUklDb21wb25lbnQodXJpLnBhdGhuYW1lKTtcblxuICAgIC8vIE5COiBwYXRobmFtZSBoYXMgYSBsZWFkaW5nICcvJyBvbiBXaW4zMiBmb3Igc29tZSByZWFzb25cbiAgICBpZiAocHJvY2Vzcy5wbGF0Zm9ybSA9PT0gJ3dpbjMyJykge1xuICAgICAgZmlsZVBhdGggPSBmaWxlUGF0aC5zbGljZSgxKTtcbiAgICB9XG5cbiAgICAvLyBOQjogU3BlY2lhbC1jYXNlIGZpbGVzIGNvbWluZyBmcm9tIGF0b20uYXNhciBvciBub2RlX21vZHVsZXNcbiAgICBpZiAoZmlsZVBhdGgubWF0Y2goL1tcXC9cXFxcXShhdG9tfGVsZWN0cm9uKS5hc2FyLykgfHwgZmlsZVBhdGgubWF0Y2goL1tcXC9cXFxcXShub2RlX21vZHVsZXN8Ym93ZXJfY29tcG9uZW50cykvKSkge1xuICAgICAgLy8gTkJzIG9uIE5CczogSWYgd2UncmUgbG9hZGluZyBhbiBIVE1MIGZpbGUgZnJvbSBub2RlX21vZHVsZXMsIHdlIHN0aWxsIGhhdmVcbiAgICAgIC8vIHRvIGRvIHRoZSBIVE1MIGRvY3VtZW50IHJpZ2dpbmdcbiAgICAgIGlmIChmaWxlUGF0aC5tYXRjaCgvXFwuaHRtbD8kL2kpKSB7XG4gICAgICAgIGxldCByaWdnZWRDb250ZW50cyA9IG51bGw7XG4gICAgICAgIGZzLnJlYWRGaWxlKGZpbGVQYXRoLCAndXRmOCcsIChlcnIsIGNvbnRlbnRzKSA9PiB7XG4gICAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgaWYgKGVyci5lcnJubyA9PT0gMzQpIHtcbiAgICAgICAgICAgICAgZmluaXNoKC02KTsgLy8gbmV0OjpFUlJfRklMRV9OT1RfRk9VTkRcbiAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgZmluaXNoKC0yKTsgLy8gbmV0OjpGQUlMRURcbiAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIHJpZ2dlZENvbnRlbnRzID0gcmlnSHRtbERvY3VtZW50VG9Jbml0aWFsaXplRWxlY3Ryb25Db21waWxlKGNvbnRlbnRzKTtcbiAgICAgICAgICBmaW5pc2goeyBkYXRhOiBuZXcgQnVmZmVyKHJpZ2dlZENvbnRlbnRzKSwgbWltZVR5cGU6ICd0ZXh0L2h0bWwnIH0pO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICByZXF1ZXN0RmlsZUpvYihmaWxlUGF0aCwgZmluaXNoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgbGV0IHJlc3VsdCA9IGF3YWl0IGNvbXBpbGVySG9zdC5jb21waWxlKGZpbGVQYXRoKTtcblxuICAgICAgaWYgKHJlc3VsdC5taW1lVHlwZSA9PT0gJ3RleHQvaHRtbCcpIHtcbiAgICAgICAgcmVzdWx0LmNvZGUgPSByaWdIdG1sRG9jdW1lbnRUb0luaXRpYWxpemVFbGVjdHJvbkNvbXBpbGUocmVzdWx0LmNvZGUpO1xuICAgICAgfVxuXG4gICAgICBpZiAocmVzdWx0LmJpbmFyeURhdGEgfHwgcmVzdWx0LmNvZGUgaW5zdGFuY2VvZiBCdWZmZXIpIHtcbiAgICAgICAgZmluaXNoKHsgZGF0YTogcmVzdWx0LmJpbmFyeURhdGEgfHwgcmVzdWx0LmNvZGUsIG1pbWVUeXBlOiByZXN1bHQubWltZVR5cGUgfSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGZpbmlzaCh7IGRhdGE6IG5ldyBCdWZmZXIocmVzdWx0LmNvZGUpLCBtaW1lVHlwZTogcmVzdWx0Lm1pbWVUeXBlIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgbGV0IGVyciA9IGBGYWlsZWQgdG8gY29tcGlsZSAke2ZpbGVQYXRofTogJHtlLm1lc3NhZ2V9XFxuJHtlLnN0YWNrfWA7XG4gICAgICBkKGVycik7XG5cbiAgICAgIGlmIChlLmVycm5vID09PSAzNCAvKkVOT0VOVCovKSB7XG4gICAgICAgIGZpbmlzaCgtNik7IC8vIG5ldDo6RVJSX0ZJTEVfTk9UX0ZPVU5EXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgZmluaXNoKHsgbWltZVR5cGU6ICd0ZXh0L3BsYWluJywgZGF0YTogbmV3IEJ1ZmZlcihlcnIpIH0pO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgfSk7XG59XG4iXX0=