UNPKG

electron-compile

Version:

Electron supporting package to compile JS and CSS in Electron applications

311 lines (232 loc) 23.5 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.initializeRendererProcess = initializeRendererProcess; 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('mime-types'); var _mimeTypes2 = _interopRequireDefault(_mimeTypes); var _compilerHost = require('./compiler-host'); var _compilerHost2 = _interopRequireDefault(_compilerHost); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var magicWords = "__magic__file__to__help__electron__compile.js"; var magicGlobalForRootCacheDir = '__electron_compile_root_cache_dir'; var magicGlobalForAppRootDir = '__electron_compile_app_root_dir'; var d = require('debug')('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' }); }); } var rendererInitialized = false; /** * Called by our rigged script file at the top of every HTML file to set up * the same compilers as the browser process that created us * * @private */ function initializeRendererProcess(readOnlyMode) { if (rendererInitialized) return; // NB: If we don't do this, we'll get a renderer crash if you enable debug require('debug/browser'); var rootCacheDir = require('remote').getGlobal(magicGlobalForRootCacheDir); var appRoot = require('remote').getGlobal(magicGlobalForAppRootDir); var compilerHost = null; // NB: This has to be synchronous because we need to block HTML parsing // until we're set up if (readOnlyMode) { d('Setting up electron-compile in precompiled mode with cache dir: ' + rootCacheDir); compilerHost = _compilerHost2.default.createReadonlyFromConfigurationSync(rootCacheDir, appRoot); } else { d('Setting up electron-compile in development mode with cache dir: ' + rootCacheDir); var _require = require('./config-parser'); var createCompilers = _require.createCompilers; var compilersByMimeType = createCompilers(); compilerHost = _compilerHost2.default.createFromConfigurationSync(rootCacheDir, appRoot, compilersByMimeType); } require('./x-require'); require('./require-hook').default(compilerHost); rendererInitialized = true; } /** * 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('protocol'); global[magicGlobalForRootCacheDir] = compilerHost.rootCacheDir; global[magicGlobalForAppRootDir] = compilerHost.appRoot; var electronCompileSetupCode = 'if (window.require) require(\'electron-compile/lib/protocol-hook\').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.asar/) || filePath.match(/[\/\\]node_modules/))) { _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: undefined }; }(); 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,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9wcm90b2NvbC1ob29rLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7OztRQW9CZ0I7UUFxREE7UUFxQ0E7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUF2R2hCLElBQU0sYUFBYSwrQ0FBYjtBQUNOLElBQU0sNkJBQTZCLG1DQUE3QjtBQUNOLElBQU0sMkJBQTJCLGlDQUEzQjs7QUFFTixJQUFNLElBQUksUUFBUSxPQUFSLEVBQWlCLGdDQUFqQixDQUFKOztBQUVOLElBQUksV0FBVyxJQUFYOzs7Ozs7O0FBT0csU0FBUywwQ0FBVCxDQUFvRCxHQUFwRCxFQUF5RDtBQUM5RCxNQUFJLFFBQVEsSUFBSSxLQUFKLENBQVUsSUFBVixDQUFSLENBRDBEO0FBRTlELE1BQUksc0NBQW9DLDBCQUFwQyxDQUYwRDtBQUc5RCxNQUFJLGVBQWUsS0FBZixDQUgwRDs7QUFLOUQsT0FBSyxJQUFJLElBQUUsQ0FBRixFQUFLLElBQUksTUFBTSxNQUFOLEVBQWMsR0FBaEMsRUFBcUM7QUFDbkMsUUFBSSxDQUFDLE1BQU0sQ0FBTixFQUFTLEtBQVQsQ0FBZSxTQUFmLENBQUQsRUFBNEIsU0FBaEM7O0FBRUEsVUFBTSxDQUFOLElBQVcsS0FBQyxDQUFNLENBQU4sQ0FBRCxDQUFXLE9BQVgsQ0FBbUIsU0FBbkIsRUFBOEIsV0FBOUIsQ0FBWCxDQUhtQztBQUluQyxtQkFBZSxJQUFmLENBSm1DO0FBS25DLFVBTG1DO0dBQXJDOztBQVFBLE1BQUksQ0FBQyxZQUFELEVBQWU7QUFDakIsa0RBQTRDLGlDQUE1QyxDQURpQjtBQUVqQixTQUFLLElBQUksSUFBRSxDQUFGLEVBQUssSUFBSSxNQUFNLE1BQU4sRUFBYyxHQUFoQyxFQUFxQztBQUNuQyxVQUFJLENBQUMsTUFBTSxDQUFOLEVBQVMsS0FBVCxDQUFlLFFBQWYsQ0FBRCxFQUEyQixTQUEvQjs7QUFFQSxZQUFNLENBQU4sSUFBVyxLQUFDLENBQU0sQ0FBTixDQUFELENBQVcsT0FBWCxDQUFt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Ozs7Ozs7Ozs7O0FBSUUsMkNBQTJCLGtCQUFhLFlBQUUsT0FBRixVQUFjLFlBQUUsS0FBRjs7QUFDMUQsZ0JBQUUsR0FBRjs7b0JBRUksWUFBRSxLQUFGLEtBQVksRUFBWjs7Ozs7QUFDRixxQkFBTyxDQUFDLENBQUQsQ0FBUDs7Ozs7QUFJRixxQkFBTyxFQUFFLFVBQVUsWUFBVixFQUF3QixNQUFNLElBQUksTUFBSixDQUFXLEdBQVgsQ0FBTixFQUFqQzs7Ozs7Ozs7O0tBbEZxQzs7OztLQUF6QyxFQVJtRDtDQUE5QyIsImZpbGUiOiJwcm90b2NvbC1ob29rLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICcuL2JhYmVsLW1heWJlZmlsbCc7XG5pbXBvcnQgdXJsIGZyb20gJ3VybCc7XG5pbXBvcnQgZnMgZnJvbSAnZnMnO1xuaW1wb3J0IG1pbWUgZnJvbSAnbWltZS10eXBlcyc7XG5cbmltcG9ydCBDb21waWxlckhvc3QgZnJvbSAnLi9jb21waWxlci1ob3N0JztcblxuY29uc3QgbWFnaWNXb3JkcyA9IFwiX19tYWdpY19fZmlsZV9fdG9fX2hlbHBfX2VsZWN0cm9uX19jb21waWxlLmpzXCI7XG5jb25zdCBtYWdpY0dsb2JhbEZvclJvb3RDYWNoZURpciA9ICdfX2VsZWN0cm9uX2NvbXBpbGVfcm9vdF9jYWNoZV9kaXInO1xuY29uc3QgbWFnaWNHbG9iYWxGb3JBcHBSb290RGlyID0gJ19fZWxlY3Ryb25fY29tcGlsZV9hcHBfcm9vdF9kaXInO1xuXG5jb25zdCBkID0gcmVxdWlyZSgnZGVidWcnKSgnZWxlY3Ryb24tY29tcGlsZTpwcm90b2NvbC1ob29rJyk7XG5cbmxldCBwcm90b2NvbCA9IG51bGw7XG5cbi8qKlxuICogQWRkcyBvdXIgc2NyaXB0IGhlYWRlciB0byB0aGUgdG9wIG9mIGFsbCBIVE1MIGZpbGVzXG4gKlxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJpZ0h0bWxEb2N1bWVudFRvSW5pdGlhbGl6ZUVsZWN0cm9uQ29tcGlsZShkb2MpIHtcbiAgbGV0IGxpbmVzID0gZG9jLnNwbGl0KFwiXFxuXCIpO1xuICBsZXQgcmVwbGFjZW1lbnQgPSBgPGhlYWQ+PHNjcmlwdCBzcmM9XCIke21hZ2ljV29yZHN9XCI+PC9zY3JpcHQ+YDtcbiAgbGV0IHJlcGxhY2VkSGVhZCA9IGZhbHNlO1xuXG4gIGZvciAobGV0IGk9MDsgaSA8IGxpbmVzLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKCFsaW5lc1tpXS5tYXRjaCgvPGhlYWQ+L2kpKSBjb250aW51ZTtcblxuICAgIGxpbmVzW2ldID0gKGxpbmVzW2ldKS5yZXBsYWNlKC88aGVhZD4vaSwgcmVwbGFjZW1lbnQpO1xuICAgIHJlcGxhY2VkSGVhZCA9IHRydWU7XG4gICAgYnJlYWs7XG4gIH1cblxuICBpZiAoIXJlcGxhY2VkSGVhZCkge1xuICAgIHJlcGxhY2VtZW50ID0gYDxodG1sJDE+PGhlYWQ+PHNjcmlwdCBzcmM9XCIke21hZ2ljV29yZHN9XCI+PC9zY3JpcHQ+PC9oZWFkPmA7XG4gICAgZm9yIChsZXQgaT0wOyBpIDwgbGluZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmICghbGluZXNbaV0ubWF0Y2goLzxodG1sL2kpKSBjb250aW51ZTtcblxuICAgICAgbGluZXNbaV0gPSAobGluZXNbaV0pLnJlcGxhY2UoLzxodG1sKFtePl0rKT4vaSwgcmVwbGFjZW1lbnQpO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGxpbmVzLmpvaW4oXCJcXG5cIik7XG59XG5cbmZ1bmN0aW9uIHJlcXVlc3RGaWxlSm9iKGZpbGVQYXRoLCBmaW5pc2gpIHtcbiAgZnMucmVhZEZpbGUoZmlsZVBhdGgsIChlcnIsIGJ1ZikgPT4ge1xuICAgIGlmIChlcnIpIHtcbiAgICAgIGlmIChlcnIuZXJybm8gPT09IDM0KSB7XG4gICAgICAgIGZpbmlzaCgtNik7IC8vIG5ldDo6RVJSX0ZJTEVfTk9UX0ZPVU5EXG4gICAgICAgIHJldHVybjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGZpbmlzaCgtMik7IC8vIG5ldDo6RkFJTEVEXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmaW5pc2goe1xuICAgICAgZGF0YTogYnVmLFxuICAgICAgbWltZVR5cGU6IG1pbWUubG9va3VwKGZpbGVQYXRoKSB8fCAndGV4dC9wbGFpbidcbiAgICB9KTtcbiAgfSk7XG59XG5cbmxldCByZW5kZXJlckluaXRpYWxpemVkID0gZmFsc2U7XG5cbi8qKlxuICogQ2FsbGVkIGJ5IG91ciByaWdnZWQgc2NyaXB0IGZpbGUgYXQgdGhlIHRvcCBvZiBldmVyeSBIVE1MIGZpbGUgdG8gc2V0IHVwXG4gKiB0aGUgc2FtZSBjb21waWxlcnMgYXMgdGhlIGJyb3dzZXIgcHJvY2VzcyB0aGF0IGNyZWF0ZWQgdXNcbiAqXG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gaW5pdGlhbGl6ZVJlbmRlcmVyUHJvY2VzcyhyZWFkT25seU1vZGUpIHtcbiAgaWYgKHJlbmRlcmVySW5pdGlhbGl6ZWQpIHJldHVybjtcblxuICAvLyBOQjogSWYgd2UgZG9uJ3QgZG8gdGhpcywgd2UnbGwgZ2V0IGEgcmVuZGVyZXIgY3Jhc2ggaWYgeW91IGVuYWJsZSBkZWJ1Z1xuICByZXF1aXJlKCdkZWJ1Zy9icm93c2VyJyk7XG5cbiAgbGV0IHJvb3RDYWNoZURpciA9IHJlcXVpcmUoJ3JlbW90ZScpLmdldEdsb2JhbChtYWdpY0dsb2JhbEZvclJvb3RDYWNoZURpcik7XG4gIGxldCBhcHBSb290ID0gcmVxdWlyZSgncmVtb3RlJykuZ2V0R2xvYmFsKG1hZ2ljR2xvYmFsRm9yQXBwUm9vdERpcik7XG4gIGxldCBjb21waWxlckhvc3QgPSBudWxsO1xuXG4gIC8vIE5COiBUaGlzIGhhcyB0byBiZSBzeW5jaHJvbm91cyBiZWNhdXNlIHdlIG5lZWQgdG8gYmxvY2sgSFRNTCBwYXJzaW5nXG4gIC8vIHVudGlsIHdlJ3JlIHNldCB1cFxuICBpZiAocmVhZE9ubHlNb2RlKSB7XG4gICAgZChgU2V0dGluZyB1cCBlbGVjdHJvbi1jb21waWxlIGluIHByZWNvbXBpbGVkIG1vZGUgd2l0aCBjYWNoZSBkaXI6ICR7cm9vdENhY2hlRGlyfWApO1xuICAgIGNvbXBpbGVySG9zdCA9IENvbXBpbGVySG9zdC5jcmVhdGVSZWFkb25seUZyb21Db25maWd1cmF0aW9uU3luYyhyb290Q2FjaGVEaXIsIGFwcFJvb3QpO1xuICB9IGVsc2Uge1xuICAgIGQoYFNldHRpbmcgdXAgZWxlY3Ryb24tY29tcGlsZSBpbiBkZXZlbG9wbWVudCBtb2RlIHdpdGggY2FjaGUgZGlyOiAke3Jvb3RDYWNoZURpcn1gKTtcbiAgICBjb25zdCB7IGNyZWF0ZUNvbXBpbGVycyB9ID0gcmVxdWlyZSgnLi9jb25maWctcGFyc2VyJyk7XG4gICAgY29uc3QgY29tcGlsZXJzQnlNaW1lVHlwZSA9IGNyZWF0ZUNvbXBpbGVycygpO1xuXG4gICAgY29tcGlsZXJIb3N0ID0gQ29tcGlsZXJIb3N0LmNyZWF0ZUZyb21Db25maWd1cmF0aW9uU3luYyhyb290Q2FjaGVEaXIsIGFwcFJvb3QsIGNvbXBpbGVyc0J5TWltZVR5cGUpO1xuICB9XG5cbiAgcmVxdWlyZSgnLi94LXJlcXVpcmUnKTtcbiAgcmVxdWlyZSgnLi9yZXF1aXJlLWhvb2snKS5kZWZhdWx0KGNvbXBpbGVySG9zdCk7XG4gIHJlbmRlcmVySW5pdGlhbGl6ZWQgPSB0cnVlO1xufVxuXG5cbi8qKlxuICogSW5pdGlhbGl6ZXMgdGhlIHByb3RvY29sIGhvb2sgb24gZmlsZTogdGhhdCBhbGxvd3MgdXMgdG8gaW50ZXJjZXB0IGZpbGVzXG4gKiBsb2FkZWQgYnkgQ2hyb21pdW0gYW5kIHJld3JpdGUgdGhlbS4gVGhpcyBtZXRob2QgYWxvbmcgd2l0aFxuICoge0BsaW5rIHJlZ2lzdGVyUmVxdWlyZUV4dGVuc2lvbn0gYXJlIHRoZSB0b3AtbGV2ZWwgbWV0aG9kcyB0aGF0IGVsZWN0cm9uLWNvbXBpbGVcbiAqIGFjdHVhbGx5IHVzZXMgdG8gaW50ZXJjZXB0IGNvZGUgdGhhdCBFbGVjdHJvbiBsb2Fkcy5cbiAqXG4gKiBAcGFyYW0gIHtDb21waWxlckhvc3R9IGNvbXBpbGVySG9zdCAgVGhlIGNvbXBpbGVyIGhvc3QgdG8gdXNlIGZvciBjb21waWxhdGlvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGluaXRpYWxpemVQcm90b2NvbEhvb2soY29tcGlsZXJIb3N0KSB7XG4gIHByb3RvY29sID0gcHJvdG9jb2wgfHwgcmVxdWlyZSgncHJvdG9jb2wnKTtcblxuICBnbG9iYWxbbWFnaWNHbG9iYWxGb3JSb290Q2FjaGVEaXJdID0gY29tcGlsZXJIb3N0LnJvb3RDYWNoZURpcjtcbiAgZ2xvYmFsW21hZ2ljR2xvYmFsRm9yQXBwUm9vdERpcl0gPSBjb21waWxlckhvc3QuYXBwUm9vdDtcblxuICBjb25zdCBlbGVjdHJvbkNvbXBpbGVTZXR1cENvZGUgPSBgaWYgKHdpbmRvdy5yZXF1aXJlKSByZXF1aXJlKCdlbGVjdHJvbi1jb21waWxlL2xpYi9wcm90b2NvbC1ob29rJykuaW5pdGlhbGl6ZVJlbmRlcmVyUHJvY2Vzcygke2NvbXBpbGVySG9zdC5yZWFkT25seU1vZGV9KTtgO1xuXG4gIHByb3RvY29sLmludGVyY2VwdEJ1ZmZlclByb3RvY29sKCdmaWxlJywgYXN5bmMgZnVuY3Rpb24ocmVxdWVzdCwgZmluaXNoKSB7XG4gICAgbGV0IHVyaSA9IHVybC5wYXJzZShyZXF1ZXN0LnVybCk7XG5cbiAgICBkKGBJbnRlcmNlcHRpbmcgdXJsICR7cmVxdWVzdC51cmx9YCk7XG4gICAgaWYgKHJlcXVlc3QudXJsLmluZGV4T2YobWFnaWNXb3JkcykgPiAtMSkge1xuICAgICAgZmluaXNoKHtcbiAgICAgICAgbWltZVR5cGU6ICdhcHBsaWNhdGlvbi9qYXZhc2NyaXB0JyxcbiAgICAgICAgZGF0YTogbmV3IEJ1ZmZlcihlbGVjdHJvbkNvbXBpbGVTZXR1cENvZGUsICd1dGY4JylcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gVGhpcyBpcyBhIHByb3RvY29sLXJlbGF0aXZlIFVSTCB0aGF0IGhhcyBnb25lIHBlYXItc2hhcGVkIGluIEVsZWN0cm9uLFxuICAgIC8vIGxldCdzIHJld3JpdGUgaXRcbiAgICBpZiAodXJpLmhvc3QgJiYgdXJpLmhvc3QubGVuZ3RoID4gMSkge1xuICAgICAgLy9sZXQgbmV3VXJpID0gcmVxdWVzdC51cmwucmVwbGFjZSgvXmZpbGU6LywgXCJodHRwczpcIik7XG4gICAgICAvLyBUT0RPOiBKdW1wIG9mZiB0aGlzIGJyaWRnZSBsYXRlclxuICAgICAgZChgVE9ETzogRm91bmQgYm9ndXMgcHJvdG9jb2wtcmVsYXRpdmUgVVJMLCBjYW4ndCBmaXggaXQgdXAhIWApO1xuICAgICAgZmluaXNoKC0yKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBsZXQgZmlsZVBhdGggPSBkZWNvZGVVUklDb21wb25lbnQodXJpLnBhdGhuYW1lKTtcblxuICAgIC8vIE5COiBwYXRobmFtZSBoYXMgYSBsZWFkaW5nICcvJyBvbiBXaW4zMiBmb3Igc29tZSByZWFzb25cbiAgICBpZiAocHJvY2Vzcy5wbGF0Zm9ybSA9PT0gJ3dpbjMyJykge1xuICAgICAgZmlsZVBhdGggPSBmaWxlUGF0aC5zbGljZSgxKTtcbiAgICB9XG5cbiAgICAvLyBOQjogU3BlY2lhbC1jYXNlIGZpbGVzIGNvbWluZyBmcm9tIGF0b20uYXNhciBvciBub2RlX21vZHVsZXNcbiAgICBpZiAoZmlsZVBhdGgubWF0Y2goL1tcXC9cXFxcXWF0b20uYXNhci8pIHx8IGZpbGVQYXRoLm1hdGNoKC9bXFwvXFxcXF1ub2RlX21vZHVsZXMvKSkge1xuICAgICAgLy8gTkJzIG9uIE5CczogSWYgd2UncmUgbG9hZGluZyBhbiBIVE1MIGZpbGUgZnJvbSBub2RlX21vZHVsZXMsIHdlIHN0aWxsIGhhdmVcbiAgICAgIC8vIHRvIGRvIHRoZSBIVE1MIGRvY3VtZW50IHJpZ2dpbmdcbiAgICAgIGlmIChmaWxlUGF0aC5tYXRjaCgvXFwuaHRtbD8kL2kpKSB7XG4gICAgICAgIGxldCByaWdnZWRDb250ZW50cyA9IG51bGw7XG4gICAgICAgIGZzLnJlYWRGaWxlKGZpbGVQYXRoLCAndXRmOCcsIChlcnIsIGNvbnRlbnRzKSA9PiB7XG4gICAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgaWYgKGVyci5lcnJubyA9PT0gMzQpIHtcbiAgICAgICAgICAgICAgZmluaXNoKC02KTsgLy8gbmV0OjpFUlJfRklMRV9OT1RfRk9VTkRcbiAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgZmluaXNoKC0yKTsgLy8gbmV0OjpGQUlMRURcbiAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIHJpZ2dlZENvbnRlbnRzID0gcmlnSHRtbERvY3VtZW50VG9Jbml0aWFsaXplRWxlY3Ryb25Db21waWxlKGNvbnRlbnRzKTtcbiAgICAgICAgICBmaW5pc2goeyBkYXRhOiBuZXcgQnVmZmVyKHJpZ2dlZENvbnRlbnRzKSwgbWltZVR5cGU6ICd0ZXh0L2h0bWwnIH0pO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICByZXF1ZXN0RmlsZUpvYihmaWxlUGF0aCwgZmluaXNoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgbGV0IHJlc3VsdCA9IGF3YWl0IGNvbXBpbGVySG9zdC5jb21waWxlKGZpbGVQYXRoKTtcblxuICAgICAgaWYgKHJlc3VsdC5taW1lVHlwZSA9PT0gJ3RleHQvaHRtbCcpIHtcbiAgICAgICAgcmVzdWx0LmNvZGUgPSByaWdIdG1sRG9jdW1lbnRUb0luaXRpYWxpemVFbGVjdHJvbkNvbXBpbGUocmVzdWx0LmNvZGUpO1xuICAgICAgfVxuXG4gICAgICBpZiAocmVzdWx0LmJpbmFyeURhdGEgfHwgcmVzdWx0LmNvZGUgaW5zdGFuY2VvZiBCdWZmZXIpIHtcbiAgICAgICAgZmluaXNoKHsgZGF0YTogcmVzdWx0LmJpbmFyeURhdGEgfHwgcmVzdWx0LmNvZGUsIG1pbWVUeXBlOiByZXN1bHQubWltZVR5cGUgfSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGZpbmlzaCh7IGRhdGE6IG5ldyBCdWZmZXIocmVzdWx0LmNvZGUpLCBtaW1lVHlwZTogcmVzdWx0Lm1pbWVUeXBlIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgbGV0IGVyciA9IGBGYWlsZWQgdG8gY29tcGlsZSAke2ZpbGVQYXRofTogJHtlLm1lc3NhZ2V9XFxuJHtlLnN0YWNrfWA7XG4gICAgICBkKGVycik7XG5cbiAgICAgIGlmIChlLmVycm5vID09PSAzNCAvKkVOT0VOVCovKSB7XG4gICAgICAgIGZpbmlzaCgtNik7IC8vIG5ldDo6RVJSX0ZJTEVfTk9UX0ZPVU5EXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgZmluaXNoKHsgbWltZVR5cGU6ICd0ZXh0L3BsYWluJywgZGF0YTogbmV3IEJ1ZmZlcihlcnIpIH0pO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgfSk7XG59XG4iXX0=