UNPKG

react-static

Version:

A progressive static site generator for React

392 lines (321 loc) 45.5 kB
"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = getConfig; exports.buildConfig = buildConfig; var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator")); var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator")); var _path = _interopRequireDefault(require("path")); var _chokidar = _interopRequireDefault(require("chokidar")); var _resolveFrom = _interopRequireDefault(require("resolve-from")); var _fsExtra = _interopRequireDefault(require("fs-extra")); var _utils = require("../utils"); var _plugins = _interopRequireWildcard(require("./plugins")); function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } // the default static.config.js location var defaultConfig = {}; var DEFAULT_NAME_FOR_STATIC_CONFIG_FILE = 'static.config.js'; var DEFAULT_PATH_FOR_STATIC_CONFIG = _path["default"].resolve(_path["default"].join(process.cwd(), DEFAULT_NAME_FOR_STATIC_CONFIG_FILE)); var DEFAULT_ROUTES = [{ path: '/' }]; var DEFAULT_ENTRY = 'index.js'; var DEFAULT_EXTENSIONS = ['.js', '.jsx']; // Retrieves the static.config.js from the current project directory function getConfig(state) { var callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : /*#__PURE__*/function () { var _ref = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee(config) { return _regenerator["default"].wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: if (state.debug) { console.log('getConfig():'); console.log(state); } return _context.abrupt("return", config); case 2: case "end": return _context.stop(); } } }, _callee); })); return function (_x) { return _ref.apply(this, arguments); }; }(); var configPath = state.configPath || state.packageConfig.config || DEFAULT_PATH_FOR_STATIC_CONFIG; state = _objectSpread(_objectSpread({}, state), {}, { originalConfig: configPath }); var resolvedPath = _path["default"].resolve(configPath); var noConfig = configPath === DEFAULT_PATH_FOR_STATIC_CONFIG && !resolvedPath; if (noConfig) { // last state = buildConfig(state, defaultConfig); return callback(state)["catch"](console.error); } state = buildConfigFromPath(state, resolvedPath || configPath); if (state.stage === 'dev') { _chokidar["default"].watch(resolvedPath, { ignoreInitial: true }).on('all', /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee2() { return _regenerator["default"].wrap(function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: console.log(''); console.log("Updating static.config.js"); state = buildConfigFromPath(state, resolvedPath); callback(state)["catch"](console.error); case 4: case "end": return _context2.stop(); } } }, _callee2); }))); } return callback(state)["catch"](console.error); } function buildConfigFromPath(state, configPath) { delete require.cache[configPath]; var config = require(configPath)["default"]; return buildConfig(state, config); } function buildConfig(state) { var config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; // Default Paths var paths = _objectSpread({ root: _path["default"].resolve(process.cwd()), src: 'src', dist: 'dist', temp: 'tmp', buildArtifacts: 'artifacts', devDist: 'tmp/dev-server', "public": 'public', plugins: 'plugins', pages: 'src/pages', nodeModules: 'node_modules', assets: '' }, config.paths || {}); // Use the root to resolve all other relative paths var resolvePath = function resolvePath(relativePath) { return _path["default"].resolve(paths.root, relativePath); }; // Resolve and replace all pathss var DIST = process.env.REACT_STATIC_ENV === 'development' ? resolvePath(paths.devDist || paths.dist) : resolvePath(paths.dist); var ASSETS = _path["default"].resolve(DIST, paths.assets); paths = { ROOT: paths.root, SRC: resolvePath(paths.src), DIST: DIST, ASSETS: ASSETS, PLUGINS: resolvePath(paths.plugins), TEMP: resolvePath(paths.temp), ARTIFACTS: resolvePath(paths.buildArtifacts), PUBLIC: resolvePath(paths["public"]), NODE_MODULES: resolvePath(paths.nodeModules), EXCLUDE_MODULES: paths.excludeResolvedModules || resolvePath(paths.nodeModules), PACKAGE: resolvePath('package.json'), HTML_TEMPLATE: _path["default"].join(DIST, 'index.html'), STATIC_DATA: _path["default"].join(ASSETS, 'staticData') }; // siteRoot, basePath, publicPath, and assetPath resolution var siteRoot = ''; var basePath = ''; var assetsPath = ''; if (process.env.REACT_STATIC_ENV === 'development') { basePath = (0, _utils.cleanSlashes)(config.devBasePath); assetsPath = config.devAssetsPath || paths.assets || assetsPath; } else if (state.staging) { siteRoot = (0, _utils.cutPathToRoot)(config.stagingSiteRoot || '/', '$1'); basePath = (0, _utils.cleanSlashes)(config.stagingBasePath); assetsPath = config.stagingAssetsPath || paths.assets || assetsPath; } else { siteRoot = (0, _utils.cutPathToRoot)(config.siteRoot || '/', '$1'); basePath = (0, _utils.cleanSlashes)(config.basePath); assetsPath = config.assetsPath || paths.assets || assetsPath; } var publicPath = "".concat((0, _utils.cleanSlashes)("".concat(siteRoot, "/").concat(basePath), { leading: false }), "/"); if (assetsPath && !(0, _utils.isAbsoluteUrl)(assetsPath)) { assetsPath = "/".concat((0, _utils.cleanSlashes)("".concat(basePath, "/").concat(assetsPath)), "/"); } // add trailing slash only if assetsPath was supplied, but no trailing slash if (assetsPath && !assetsPath.endsWith('/')) { assetsPath = "".concat(assetsPath, "/"); } // Add the project root as a plugin. This allows the dev // to use the plugin api directory in their project if they want var plugins = [].concat((0, _toConsumableArray2["default"])(config.plugins || []), [paths.ROOT]); // if (process.env.NODE_ENV !== 'test' && !entry) { // throw new Error( // `Could not resolve entry file from location: ${entry} using extensions: ${( // config.extensions || DEFAULT_EXTENSIONS // ).join(', ')}` // ) // } // Defaults config = _objectSpread(_objectSpread({ // Defaults getSiteData: function getSiteData() { return {}; }, prefetchRate: 5, maxThreads: Infinity, disableRoutePrefixing: false, outputFileRate: 100, extensions: DEFAULT_EXTENSIONS, getRoutes: function () { var _getRoutes = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee3() { return _regenerator["default"].wrap(function _callee3$(_context3) { while (1) { switch (_context3.prev = _context3.next) { case 0: return _context3.abrupt("return", DEFAULT_ROUTES); case 1: case "end": return _context3.stop(); } } }, _callee3); })); function getRoutes() { return _getRoutes.apply(this, arguments); } return getRoutes; }(), minLoadTime: 200, disablePreload: false, disableRuntime: false, preloadPollInterval: 300, productionSourceMaps: false, silent: false, entry: DEFAULT_ENTRY }, config), {}, { // Materialized Overrides paths: paths, plugins: plugins, siteRoot: siteRoot, basePath: basePath, publicPath: publicPath, assetsPath: assetsPath, extractCssChunks: config.extractCssChunks || false, inlineCss: config.inlineCss || false, babelExcludes: config.babelExcludes || [], devServer: _objectSpread({ host: 'localhost', port: 3000 }, config.devServer || {}) }); config.terser = config.terser || {}; config.terser.terserOptions = config.terser.terserOptions || {}; config.terser.terserOptions.mangle = config.terser.terserOptions.mangle || {}; config.terser.terserOptions.parse = config.terser.terserOptions.parse || {}; config.terser.terserOptions.compress = config.terser.terserOptions.compress || {}; config.terser.terserOptions.output = config.terser.terserOptions.output || {}; // Set env variables to be used client side process.env.REACT_STATIC_MIN_LOAD_TIME = config.minLoadTime; process.env.REACT_STATIC_PREFETCH_RATE = config.prefetchRate; process.env.REACT_STATIC_DISABLE_ROUTE_PREFIXING = config.disableRoutePrefixing; process.env.REACT_STATIC_DISABLE_PRELOAD = config.disablePreload; process.env.REACT_STATIC_DISABLE_RUNTIME = config.disableRuntime; process.env.REACT_STATIC_PRELOAD_POLL_INTERVAL = config.preloadPollInterval; process.env.REACT_STATIC_SILENT = config.silent; process.env.REACT_STATIC_ROOT_PATH_READ_ONLY = paths.ROOT; process.env.REACT_STATIC_TEMPLATES_PATH = _path["default"].join(paths.ARTIFACTS, 'react-static-templates.js'); process.env.REACT_STATIC_PLUGINS_PATH = _path["default"].join(paths.ARTIFACTS, 'react-static-browser-plugins.js'); var resolvePlugin = function resolvePlugin(originalLocation) { var options = {}; if (Array.isArray(originalLocation)) { options = originalLocation[1] || {}; originalLocation = originalLocation[0]; } var location = [function () { // Absolute require try { var found = require.resolve(originalLocation); return found.includes('.') ? _path["default"].resolve(found, '../') : found; } catch (err) {// } }, function () { // Absolute if (_fsExtra["default"].pathExistsSync(originalLocation)) { return originalLocation; } }, function () { // Plugins Dir var found = _path["default"].resolve(paths.PLUGINS, originalLocation); if (_fsExtra["default"].pathExistsSync(found)) { return found; } }, function () { // Plugins Dir require try { var found = (0, _resolveFrom["default"])(paths.PLUGINS, originalLocation); return found.includes('.') ? _path["default"].resolve(found, '../') : found; } catch (err) {// } }, function () { // CWD var found = _path["default"].resolve(process.cwd(), originalLocation); if (_fsExtra["default"].pathExistsSync(found)) { return found; } }, function () { // CWD require try { var found = (0, _resolveFrom["default"])(process.cwd(), originalLocation); return found.includes('.') ? _path["default"].resolve(found, '../') : found; } catch (err) {// } }, function () { if (process.env.NODE_ENV === 'test') { // Allow plugins to be mocked return require('path').resolve('./src/static/__mocks__/mock-plugin'); } }].reduce(function (prev, curr) { return prev || curr(); }, null); // TODO: We have to do this because we don't have a good mock for process.cwd() :( if (!location) { throw new Error("Could not find a plugin directory for the plugin: \"".concat(originalLocation, "\". We must bail!")); } var nodeLocation = _path["default"].join(location, 'node.api.js'); var browserLocation = _path["default"].join(location, 'browser.api.js'); // Detect if the node plugin entry exists, and provide the nodeResolver to it nodeLocation = _fsExtra["default"].pathExistsSync(nodeLocation) ? nodeLocation : null; // Detect if the browser plugin entry exists, and provide the nodeResolver to it browserLocation = _fsExtra["default"].pathExistsSync(browserLocation) ? browserLocation : null; var buildPluginHooks = function buildPluginHooks() { return {}; }; try { // Get the hooks for the node api if (nodeLocation) { buildPluginHooks = require(nodeLocation)["default"]; } else if (originalLocation !== paths.ROOT && !browserLocation) { throw new Error("Could not find a valid node.api.js or browser.api.js plugin file in \"".concat(location, "\". \n") + "The original location: \"".concat(originalLocation, "\". \n") + "The root location: \"".concat(paths.ROOT, "\".")); } var resolvedPlugin = { location: location, nodeLocation: nodeLocation, browserLocation: browserLocation, options: options, hooks: buildPluginHooks(options) || {} }; (0, _plugins.validatePlugin)(resolvedPlugin); // Recursively resolve plugins if (resolvedPlugin.plugins) { resolvedPlugin.plugins = resolvedPlugin.plugins.map(resolvePlugin); } return resolvedPlugin; } catch (err) { console.error("The following error occurred in the plugin: \"".concat(originalLocation, "\"")); throw err; } }; state = _objectSpread(_objectSpread({}, state), {}, { plugins: config.plugins.map(resolvePlugin), config: config }); return _plugins["default"].afterGetConfig(state); } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zdGF0aWMvZ2V0Q29uZmlnLmpzIl0sIm5hbWVzIjpbImRlZmF1bHRDb25maWciLCJERUZBVUxUX05BTUVfRk9SX1NUQVRJQ19DT05GSUdfRklMRSIsIkRFRkFVTFRfUEFUSF9GT1JfU1RBVElDX0NPTkZJRyIsIm5vZGVQYXRoIiwicmVzb2x2ZSIsImpvaW4iLCJwcm9jZXNzIiwiY3dkIiwiREVGQVVMVF9ST1VURVMiLCJwYXRoIiwiREVGQVVMVF9FTlRSWSIsIkRFRkFVTFRfRVhURU5TSU9OUyIsImdldENvbmZpZyIsInN0YXRlIiwiY2FsbGJhY2siLCJjb25maWciLCJkZWJ1ZyIsImNvbnNvbGUiLCJsb2ciLCJjb25maWdQYXRoIiwicGFja2FnZUNvbmZpZyIsIm9yaWdpbmFsQ29uZmlnIiwicmVzb2x2ZWRQYXRoIiwibm9Db25maWciLCJidWlsZENvbmZpZyIsImVycm9yIiwiYnVpbGRDb25maWdGcm9tUGF0aCIsInN0YWdlIiwiY2hva2lkYXIiLCJ3YXRjaCIsImlnbm9yZUluaXRpYWwiLCJvbiIsInJlcXVpcmUiLCJjYWNoZSIsInBhdGhzIiwicm9vdCIsInNyYyIsImRpc3QiLCJ0ZW1wIiwiYnVpbGRBcnRpZmFjdHMiLCJkZXZEaXN0IiwicGx1Z2lucyIsInBhZ2VzIiwibm9kZU1vZHVsZXMiLCJhc3NldHMiLCJyZXNvbHZlUGF0aCIsInJlbGF0aXZlUGF0aCIsIkRJU1QiLCJlbnYiLCJSRUFDVF9TVEFUSUNfRU5WIiwiQVNTRVRTIiwiUk9PVCIsIlNSQyIsIlBMVUdJTlMiLCJURU1QIiwiQVJUSUZBQ1RTIiwiUFVCTElDIiwiTk9ERV9NT0RVTEVTIiwiRVhDTFVERV9NT0RVTEVTIiwiZXhjbHVkZVJlc29sdmVkTW9kdWxlcyIsIlBBQ0tBR0UiLCJIVE1MX1RFTVBMQVRFIiwiU1RBVElDX0RBVEEiLCJzaXRlUm9vdCIsImJhc2VQYXRoIiwiYXNzZXRzUGF0aCIsImRldkJhc2VQYXRoIiwiZGV2QXNzZXRzUGF0aCIsInN0YWdpbmciLCJzdGFnaW5nU2l0ZVJvb3QiLCJzdGFnaW5nQmFzZVBhdGgiLCJzdGFnaW5nQXNzZXRzUGF0aCIsInB1YmxpY1BhdGgiLCJsZWFkaW5nIiwiZW5kc1dpdGgiLCJnZXRTaXRlRGF0YSIsInByZWZldGNoUmF0ZSIsIm1heFRocmVhZHMiLCJJbmZpbml0eSIsImRpc2FibGVSb3V0ZVByZWZpeGluZyIsIm91dHB1dEZpbGVSYXRlIiwiZXh0ZW5zaW9ucyIsImdldFJvdXRlcyIsIm1pbkxvYWRUaW1lIiwiZGlzYWJsZVByZWxvYWQiLCJkaXNhYmxlUnVudGltZSIsInByZWxvYWRQb2xsSW50ZXJ2YWwiLCJwcm9kdWN0aW9uU291cmNlTWFwcyIsInNpbGVudCIsImVudHJ5IiwiZXh0cmFjdENzc0NodW5rcyIsImlubGluZUNzcyIsImJhYmVsRXhjbHVkZXMiLCJkZXZTZXJ2ZXIiLCJob3N0IiwicG9ydCIsInRlcnNlciIsInRlcnNlck9wdGlvbnMiLCJtYW5nbGUiLCJwYXJzZSIsImNvbXByZXNzIiwib3V0cHV0IiwiUkVBQ1RfU1RBVElDX01JTl9MT0FEX1RJTUUiLCJSRUFDVF9TVEFUSUNfUFJFRkVUQ0hfUkFURSIsIlJFQUNUX1NUQVRJQ19ESVNBQkxFX1JPVVRFX1BSRUZJWElORyIsIlJFQUNUX1NUQVRJQ19ESVNBQkxFX1BSRUxPQUQiLCJSRUFDVF9TVEFUSUNfRElTQUJMRV9SVU5USU1FIiwiUkVBQ1RfU1RBVElDX1BSRUxPQURfUE9MTF9JTlRFUlZBTCIsIlJFQUNUX1NUQVRJQ19TSUxFTlQiLCJSRUFDVF9TVEFUSUNfUk9PVF9QQVRIX1JFQURfT05MWSIsIlJFQUNUX1NUQVRJQ19URU1QTEFURVNfUEFUSCIsIlJFQUNUX1NUQVRJQ19QTFVHSU5TX1BBVEgiLCJyZXNvbHZlUGx1Z2luIiwib3JpZ2luYWxMb2NhdGlvbiIsIm9wdGlvbnMiLCJBcnJheSIsImlzQXJyYXkiLCJsb2NhdGlvbiIsImZvdW5kIiwiaW5jbHVkZXMiLCJlcnIiLCJmcyIsInBhdGhFeGlzdHNTeW5jIiwiTk9ERV9FTlYiLCJyZWR1Y2UiLCJwcmV2IiwiY3VyciIsIkVycm9yIiwibm9kZUxvY2F0aW9uIiwiYnJvd3NlckxvY2F0aW9uIiwiYnVpbGRQbHVnaW5Ib29rcyIsInJlc29sdmVkUGx1Z2luIiwiaG9va3MiLCJtYXAiLCJjb3JlUGx1Z2lucyIsImFmdGVyR2V0Q29uZmlnIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUVBOztBQUNBOztBQUNBOztBQUNBOztBQUVBOztBQUNBOzs7Ozs7QUFFQTtBQUNBLElBQU1BLGFBQWEsR0FBRyxFQUF0QjtBQUNBLElBQU1DLG1DQUFtQyxHQUFHLGtCQUE1Qzs7QUFDQSxJQUFNQyw4QkFBOEIsR0FBR0MsaUJBQVNDLE9BQVQsQ0FDckNELGlCQUFTRSxJQUFULENBQWNDLE9BQU8sQ0FBQ0MsR0FBUixFQUFkLEVBQTZCTixtQ0FBN0IsQ0FEcUMsQ0FBdkM7O0FBR0EsSUFBTU8sY0FBYyxHQUFHLENBQUM7QUFBRUMsRUFBQUEsSUFBSSxFQUFFO0FBQVIsQ0FBRCxDQUF2QjtBQUNBLElBQU1DLGFBQWEsR0FBRyxVQUF0QjtBQUNBLElBQU1DLGtCQUFrQixHQUFHLENBQUMsS0FBRCxFQUFRLE1BQVIsQ0FBM0IsQyxDQUVBOztBQUNlLFNBQVNDLFNBQVQsQ0FDYkMsS0FEYSxFQVNiO0FBQUEsTUFQQUMsUUFPQTtBQUFBLDZGQVBXLGlCQUFNQyxNQUFOO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDVCxrQkFBSUYsS0FBSyxDQUFDRyxLQUFWLEVBQWlCO0FBQ2ZDLGdCQUFBQSxPQUFPLENBQUNDLEdBQVIsQ0FBWSxjQUFaO0FBQ0FELGdCQUFBQSxPQUFPLENBQUNDLEdBQVIsQ0FBWUwsS0FBWjtBQUNEOztBQUpRLCtDQUtGRSxNQUxFOztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLEtBT1g7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQSxNQUFNSSxVQUFVLEdBQ2ROLEtBQUssQ0FBQ00sVUFBTixJQUNBTixLQUFLLENBQUNPLGFBQU4sQ0FBb0JMLE1BRHBCLElB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O0FBQ0EsVUFBSUEsY0FBYyxDQUFDMUYsT0FBbkIsRUFBNEI7QUFDMUIwRixRQUFBQSxjQUFjLENBQUMxRixPQUFmLEdBQXlCMEYsY0FBYyxDQUFDMUYsT0FBZixDQUF1QjRGLEdBQXZCLENBQTJCckIsYUFBM0IsQ0FBekI7QUFDRDs7QUFFRCxhQUFPbUIsY0FBUDtBQUNELEtBNUJELENBNEJFLE9BQU9YLEdBQVAsRUFBWTtBQUNadkcsTUFBQUEsT0FBTyxDQUFDUSxLQUFSLHlEQUNrRHdGLGdCQURsRDtBQUdBLFlBQU1PLEdBQU47QUFDRDtBQUNGLEdBckhEOztBQXVIQTNHLEVBQUFBLEtBQUssbUNBQ0FBLEtBREE7QUFFSDRCLElBQUFBLE9BQU8sRUFBRTFCLE1BQU0sQ0FBQzBCLE9BQVAsQ0FBZTRGLEdBQWYsQ0FBbUJyQixhQUFuQixDQUZOO0FBR0hqRyxJQUFBQSxNQUFNLEVBQU5BO0FBSEcsSUFBTDtBQU1BLFNBQU91SCxvQkFBWUMsY0FBWixDQUEyQjFILEtBQTNCLENBQVA7QUFDRCIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlIGltcG9ydC9uby1keW5hbWljLXJlcXVpcmUgKi9cblxuaW1wb3J0IG5vZGVQYXRoIGZyb20gJ3BhdGgnXG5pbXBvcnQgY2hva2lkYXIgZnJvbSAnY2hva2lkYXInXG5pbXBvcnQgcmVzb2x2ZUZyb20gZnJvbSAncmVzb2x2ZS1mcm9tJ1xuaW1wb3J0IGZzIGZyb20gJ2ZzLWV4dHJhJ1xuLy9cbmltcG9ydCB7IGNsZWFuU2xhc2hlcywgY3V0UGF0aFRvUm9vdCwgaXNBYnNvbHV0ZVVybCB9IGZyb20gJy4uL3V0aWxzJ1xuaW1wb3J0IGNvcmVQbHVnaW5zLCB7IHZhbGlkYXRlUGx1Z2luIH0gZnJvbSAnLi9wbHVnaW5zJ1xuXG4vLyB0aGUgZGVmYXVsdCBzdGF0aWMuY29uZmlnLmpzIGxvY2F0aW9uXG5jb25zdCBkZWZhdWx0Q29uZmlnID0ge31cbmNvbnN0IERFRkFVTFRfTkFNRV9GT1JfU1RBVElDX0NPTkZJR19GSUxFID0gJ3N0YXRpYy5jb25maWcuanMnXG5jb25zdCBERUZBVUxUX1BBVEhfRk9SX1NUQVRJQ19DT05GSUcgPSBub2RlUGF0aC5yZXNvbHZlKFxuICBub2RlUGF0aC5qb2luKHByb2Nlc3MuY3dkKCksIERFRkFVTFRfTkFNRV9GT1JfU1RBVElDX0NPTkZJR19GSUxFKVxuKVxuY29uc3QgREVGQVVMVF9ST1VURVMgPSBbeyBwYXRoOiAnLycgfV1cbmNvbnN0IERFRkFVTFRfRU5UUlkgPSAnaW5kZXguanMnXG5jb25zdCBERUZBVUxUX0VYVEVOU0lPTlMgPSBbJy5qcycsICcuanN4J11cblxuLy8gUmV0cmlldmVzIHRoZSBzdGF0aWMuY29uZmlnLmpzIGZyb20gdGhlIGN1cnJlbnQgcHJvamVjdCBkaXJlY3RvcnlcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGdldENvbmZpZyhcbiAgc3RhdGUsXG4gIGNhbGxiYWNrID0gYXN5bmMgY29uZmlnID0+IHtcbiAgICBpZiAoc3RhdGUuZGVidWcpIHtcbiAgICAgIGNvbnNvbGUubG9nKCdnZXRDb25maWcoKTonKVxuICAgICAgY29uc29sZS5sb2coc3RhdGUpXG4gICAgfVxuICAgIHJldHVybiBjb25maWdcbiAgfVxuKSB7XG4gIGNvbnN0IGNvbmZpZ1BhdGggPVxuICAgIHN0YXRlLmNvbmZpZ1BhdGggfHxcbiAgICBzdGF0ZS5wYWNrYWdlQ29uZmlnLmNvbmZpZyB8fFxuICAgIERFRkFVTFRfUEFUSF9GT1JfU1RBVElDX0NPTkZJR1xuXG4gIHN0YXRlID0ge1xuICAgIC4uLnN0YXRlLFxuICAgIG9yaWdpbmFsQ29uZmlnOiBjb25maWdQYXRoLFxuICB9XG5cbiAgY29uc3QgcmVzb2x2ZWRQYXRoID0gbm9kZVBhdGgucmVzb2x2ZShjb25maWdQYXRoKVxuXG4gIGNvbnN0IG5vQ29uZmlnID1cbiAgICBjb25maWdQYXRoID09PSBERUZBVUxUX1BBVEhfRk9SX1NUQVRJQ19DT05GSUcgJiYgIXJlc29sdmVkUGF0aFxuXG4gIGlmIChub0NvbmZpZykge1xuICAgIC8vIGxhc3RcbiAgICBzdGF0ZSA9IGJ1aWxkQ29uZmlnKHN0YXRlLCBkZWZhdWx0Q29uZmlnKVxuICAgIHJldHVybiBjYWxsYmFjayhzdGF0ZSkuY2F0Y2goY29uc29sZS5lcnJvcilcbiAgfVxuXG4gIHN0YXRlID0gYnVpbGRDb25maWdGcm9tUGF0aChzdGF0ZSwgcmVzb2x2ZWRQYXRoIHx8IGNvbmZpZ1BhdGgpXG5cbiAgaWYgKHN0YXRlLnN0YWdlID09PSAnZGV2Jykge1xuICAgIGNob2tpZGFyXG4gICAgICAud2F0Y2gocmVzb2x2ZWRQYXRoLCB7XG4gICAgICAgIGlnbm9yZUluaXRpYWw6IHRydWUsXG4gICAgICB9KVxuICAgICAgLm9uKCdhbGwnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnNvbGUubG9nKCcnKVxuICAgICAgICBjb25zb2xlLmxvZyhgVXBkYXRpbmcgc3RhdGljLmNvbmZpZy5qc2ApXG4gICAgICAgIHN0YXRlID0gYnVpbGRDb25maWdGcm9tUGF0aChzdGF0ZSwgcmVzb2x2ZWRQYXRoKVxuICAgICAgICBjYWxsYmFjayhzdGF0ZSkuY2F0Y2goY29uc29sZS5lcnJvcilcbiAgICAgIH0pXG4gIH1cblxuICByZXR1cm4gY2FsbGJhY2soc3RhdGUpLmNhdGNoKGNvbnNvbGUuZXJyb3IpXG59XG5cbmZ1bmN0aW9uIGJ1aWxkQ29uZmlnRnJvbVBhdGgoc3RhdGUsIGNvbmZpZ1BhdGgpIHtcbiAgZGVsZXRlIHJlcXVpcmUuY2FjaGVbY29uZmlnUGF0aF1cbiAgY29uc3QgY29uZmlnID0gcmVxdWlyZShjb25maWdQYXRoKS5kZWZhdWx0XG4gIHJldHVybiBidWlsZENvbmZpZyhzdGF0ZSwgY29uZmlnKVxufVxuXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRDb25maWcoc3RhdGUsIGNvbmZpZyA9IHt9KSB7XG4gIC8vIERlZmF1bHQgUGF0aHNcbiAgbGV0IHBhdGhzID0ge1xuICAgIHJvb3Q6IG5vZGVQYXRoLnJlc29sdmUocHJvY2Vzcy5jd2QoKSksXG4gICAgc3JjOiAnc3JjJyxcbiAgICBkaXN0OiAnZGlzdCcsXG4gICAgdGVtcDogJ3RtcCcsXG4gICAgYnVpbGRBcnRpZmFjdHM6ICdhcnRpZmFjdHMnLFxuICAgIGRldkRpc3Q6ICd0bXAvZGV2LXNlcnZlcicsXG4gICAgcHVibGljOiAncHVibGljJyxcbiAgICBwbHVnaW5zOiAncGx1Z2lucycsXG4gICAgcGFnZXM6ICdzcmMvcGFnZXMnLFxuICAgIG5vZGVNb2R1bGVzOiAnbm9kZV9tb2R1bGVzJyxcbiAgICBhc3NldHM6ICcnLFxuICAgIC4uLihjb25maWcucGF0aHMgfHwge30pLFxuICB9XG5cbiAgLy8gVXNlIHRoZSByb290IHRvIHJlc29sdmUgYWxsIG90aGVyIHJlbGF0aXZlIHBhdGhzXG4gIGNvbnN0IHJlc29sdmVQYXRoID0gcmVsYXRpdmVQYXRoID0+IG5vZGVQYXRoLnJlc29sdmUocGF0aHMucm9vdCwgcmVsYXRpdmVQYXRoKVxuXG4gIC8vIFJlc29sdmUgYW5kIHJlcGxhY2UgYWxsIHBhdGhzc1xuICBjb25zdCBESVNUID1cbiAgICBwcm9jZXNzLmVudi5SRUFDVF9TVEFUSUNfRU5WID09PSAnZGV2ZWxvcG1lbnQnXG4gICAgICA/IHJlc29sdmVQYXRoKHBhdGhzLmRldkRpc3QgfHwgcGF0aHMuZGlzdClcbiAgICAgIDogcmVzb2x2ZVBhdGgocGF0aHMuZGlzdClcbiAgY29uc3QgQVNTRVRTID0gbm9kZVBhdGgucmVzb2x2ZShESVNULCBwYXRocy5hc3NldHMpXG5cbiAgcGF0aHMgPSB7XG4gICAgUk9PVDogcGF0aHMucm9vdCxcbiAgICBTUkM6IHJlc29sdmVQYXRoKHBhdGhzLnNyYyksXG4gICAgRElTVCxcbiAgICBBU1NFVFMsXG4gICAgUExVR0lOUzogcmVzb2x2ZVBhdGgocGF0aHMucGx1Z2lucyksXG4gICAgVEVNUDogcmVzb2x2ZVBhdGgocGF0aHMudGVtcCksXG4gICAgQVJUSUZBQ1RTOiByZXNvbHZlUGF0aChwYXRocy5idWlsZEFydGlmYWN0cyksXG4gICAgUFVCTElDOiByZXNvbHZlUGF0aChwYXRocy5wdWJsaWMpLFxuICAgIE5PREVfTU9EVUxFUzogcmVzb2x2ZVBhdGgocGF0aHMubm9kZU1vZHVsZXMpLFxuICAgIEVYQ0xVREVfTU9EVUxFUzpcbiAgICAgIHBhdGhzLmV4Y2x1ZGVSZXNvbHZlZE1vZHVsZXMgfHwgcmVzb2x2ZVBhdGgocGF0aHMubm9kZU1vZHVsZXMpLFxuICAgIFBBQ0tBR0U6IHJlc29sdmVQYXRoKCdwYWNrYWdlLmpzb24nKSxcbiAgICBIVE1MX1RFTVBMQVRFOiBub2RlUGF0aC5qb2luKERJU1QsICdpbmRleC5odG1sJyksXG4gICAgU1RBVElDX0RBVEE6IG5vZGVQYXRoLmpvaW4oQVNTRVRTLCAnc3RhdGljRGF0YScpLFxuICB9XG5cbiAgLy8gc2l0ZVJvb3QsIGJhc2VQYXRoLCBwdWJsaWNQYXRoLCBhbmQgYXNzZXRQYXRoIHJlc29sdXRpb25cbiAgbGV0IHNpdGVSb290ID0gJydcbiAgbGV0IGJhc2VQYXRoID0gJydcbiAgbGV0IGFzc2V0c1BhdGggPSAnJ1xuICBpZiAocHJvY2Vzcy5lbnYuUkVBQ1RfU1RBVElDX0VOViA9PT0gJ2RldmVsb3BtZW50Jykge1xuICAgIGJhc2VQYXRoID0gY2xlYW5TbGFzaGVzKGNvbmZpZy5kZXZCYXNlUGF0aClcbiAgICBhc3NldHNQYXRoID0gY29uZmlnLmRldkFzc2V0c1BhdGggfHwgcGF0aHMuYXNzZXRzIHx8IGFzc2V0c1BhdGhcbiAgfSBlbHNlIGlmIChzdGF0ZS5zdGFnaW5nKSB7XG4gICAgc2l0ZVJvb3QgPSBjdXRQYXRoVG9Sb290KGNvbmZpZy5zdGFnaW5nU2l0ZVJvb3QgfHwgJy8nLCAnJDEnKVxuICAgIGJhc2VQYXRoID0gY2xlYW5TbGFzaGVzKGNvbmZpZy5zdGFnaW5nQmFzZVBhdGgpXG4gICAgYXNzZXRzUGF0aCA9IGNvbmZpZy5zdGFnaW5nQXNzZXRzUGF0aCB8fCBwYXRocy5hc3NldHMgfHwgYXNzZXRzUGF0aFxuICB9IGVsc2Uge1xuICAgIHNpdGVSb290ID0gY3V0UGF0aFRvUm9vdChjb25maWcuc2l0ZVJvb3QgfHwgJy8nLCAnJDEnKVxuICAgIGJhc2VQYXRoID0gY2xlYW5TbGFzaGVzKGNvbmZpZy5iYXNlUGF0aClcbiAgICBhc3NldHNQYXRoID0gY29uZmlnLmFzc2V0c1BhdGggfHwgcGF0aHMuYXNzZXRzIHx8IGFzc2V0c1BhdGhcbiAgfVxuICBjb25zdCBwdWJsaWNQYXRoID0gYCR7Y2xlYW5TbGFzaGVzKGAke3NpdGVSb290fS8ke2Jhc2VQYXRofWAsIHtcbiAgICBsZWFkaW5nOiBmYWxzZSxcbiAgfSl9L2BcblxuICBpZiAoYXNzZXRzUGF0aCAmJiAhaXNBYnNvbHV0ZVVybChhc3NldHNQYXRoKSkge1xuICAgIGFzc2V0c1BhdGggPSBgLyR7Y2xlYW5TbGFzaGVzKGAke2Jhc2VQYXRofS8ke2Fzc2V0c1BhdGh9YCl9L2BcbiAgfVxuXG4gIC8vIGFkZCB0cmFpbGluZyBzbGFzaCBvbmx5IGlmIGFzc2V0c1BhdGggd2FzIHN1cHBsaWVkLCBidXQgbm8gdHJhaWxpbmcgc2xhc2hcbiAgaWYgKGFzc2V0c1BhdGggJiYgIWFzc2V0c1BhdGguZW5kc1dpdGgoJy8nKSkge1xuICAgIGFzc2V0c1BhdGggPSBgJHthc3NldHNQYXRofS9gXG4gIH1cblxuICAvLyBBZGQgdGhlIHByb2plY3Qgcm9vdCBhcyBhIHBsdWdpbi4gVGhpcyBhbGxvd3MgdGhlIGRldlxuICAvLyB0byB1c2UgdGhlIHBsdWdpbiBhcGkgZGlyZWN0b3J5IGluIHRoZWlyIHByb2plY3QgaWYgdGhleSB3YW50XG4gIGNvbnN0IHBsdWdpbnMgPSBbLi4uKGNvbmZpZy5wbHVnaW5zIHx8IFtdKSwgcGF0aHMuUk9PVF1cblxuICAvLyBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICd0ZXN0JyAmJiAhZW50cnkpIHtcbiAgLy8gICB0aHJvdyBuZXcgRXJyb3IoXG4gIC8vICAgICBgQ291bGQgbm90IHJlc29sdmUgZW50cnkgZmlsZSBmcm9tIGxvY2F0aW9uOiAke2VudHJ5fSB1c2luZyBleHRlbnNpb25zOiAkeyhcbiAgLy8gICAgICAgY29uZmlnLmV4dGVuc2lvbnMgfHwgREVGQVVMVF9FWFRFTlNJT05TXG4gIC8vICAgICApLmpvaW4oJywgJyl9YFxuICAvLyAgIClcbiAgLy8gfVxuXG4gIC8vIERlZmF1bHRzXG4gIGNvbmZpZyA9IHtcbiAgICAvLyBEZWZhdWx0c1xuICAgIGdldFNpdGVEYXRhOiAoKSA9PiAoe30pLFxuICAgIHByZWZldGNoUmF0ZTogNSxcbiAgICBtYXhUaHJlYWRzOiBJbmZpbml0eSxcbiAgICBkaXNhYmxlUm91dGVQcmVmaXhpbmc6IGZhbHNlLFxuICAgIG91dHB1dEZpbGVSYXRlOiAxMDAsXG4gICAgZXh0ZW5zaW9uczogREVGQVVMVF9FWFRFTlNJT05TLFxuICAgIGdldFJvdXRlczogYXN5bmMgKCkgPT4gREVGQVVMVF9ST1VURVMsXG4gICAgbWluTG9hZFRpbWU6IDIwMCxcbiAgICBkaXNhYmxlUHJlbG9hZDogZmFsc2UsXG4gICAgZGlzYWJsZVJ1bnRpbWU6IGZhbHNlLFxuICAgIHByZWxvYWRQb2xsSW50ZXJ2YWw6IDMwMCxcbiAgICBwcm9kdWN0aW9uU291cmNlTWFwczogZmFsc2UsXG4gICAgc2lsZW50OiBmYWxzZSxcbiAgICBlbnRyeTogREVGQVVMVF9FTlRSWSxcblxuICAgIC8vIENvbmZpZyBPdmVycmlkZXNcbiAgICAuLi5jb25maWcsXG5cbiAgICAvLyBNYXRlcmlhbGl6ZWQgT3ZlcnJpZGVzXG4gICAgcGF0aHMsXG4gICAgcGx1Z2lucyxcbiAgICBzaXRlUm9vdCxcbiAgICBiYXNlUGF0aCxcbiAgICBwdWJsaWNQYXRoLFxuICAgIGFzc2V0c1BhdGgsXG4gICAgZXh0cmFjdENzc0NodW5rczogY29uZmlnLmV4dHJhY3RDc3NDaHVua3MgfHwgZmFsc2UsXG4gICAgaW5saW5lQ3NzOiBjb25maWcuaW5saW5lQ3NzIHx8IGZhbHNlLFxuICAgIGJhYmVsRXhjbHVkZXM6IGNvbmZpZy5iYWJlbEV4Y2x1ZGVzIHx8IFtdLFxuICAgIGRldlNlcnZlcjoge1xuICAgICAgaG9zdDogJ2xvY2FsaG9zdCcsXG4gICAgICBwb3J0OiAzMDAwLFxuICAgICAgLi4uKGNvbmZpZy5kZXZTZXJ2ZXIgfHwge30pLFxuICAgIH0sXG4gIH1cblxuICBjb25maWcudGVyc2VyID0gY29uZmlnLnRlcnNlciB8fCB7fVxuICBjb25maWcudGVyc2VyLnRlcnNlck9wdGlvbnMgPSBjb25maWcudGVyc2VyLnRlcnNlck9wdGlvbnMgfHwge31cbiAgY29uZmlnLnRlcnNlci50ZXJzZXJPcHRpb25zLm1hbmdsZSA9IGNvbmZpZy50ZXJzZXIudGVyc2VyT3B0aW9ucy5tYW5nbGUgfHwge31cbiAgY29uZmlnLnRlcnNlci50ZXJzZXJPcHRpb25zLnBhcnNlID0gY29uZmlnLnRlcnNlci50ZXJzZXJPcHRpb25zLnBhcnNlIHx8IHt9XG4gIGNvbmZpZy50ZXJzZXIudGVyc2VyT3B0aW9ucy5jb21wcmVzcyA9XG4gICAgY29uZmlnLnRlcnNlci50ZXJzZXJPcHRpb25zLmNvbXByZXNzIHx8IHt9XG4gIGNvbmZpZy50ZXJzZXIudGVyc2VyT3B0aW9ucy5vdXRwdXQgPSBjb25maWcudGVyc2VyLnRlcnNlck9wdGlvbnMub3V0cHV0IHx8IHt9XG5cbiAgLy8gU2V0IGVudiB2YXJpYWJsZXMgdG8gYmUgdXNlZCBjbGllbnQgc2lkZVxuICBwcm9jZXNzLmVudi5SRUFDVF9TVEFUSUNfTUlOX0xPQURfVElNRSA9IGNvbmZpZy5taW5Mb2FkVGltZVxuICBwcm9jZXNzLmVudi5SRUFDVF9TVEFUSUNfUFJFRkVUQ0hfUkFURSA9IGNvbmZpZy5wcmVmZXRjaFJhdGVcbiAgcHJvY2Vzcy5lbnYuUkVBQ1RfU1RBVElDX0RJU0FCTEVfUk9VVEVfUFJFRklYSU5HID1cbiAgICBjb25maWcuZGlzYWJsZVJvdXRlUHJlZml4aW5nXG4gIHByb2Nlc3MuZW52LlJFQUNUX1NUQVRJQ19ESVNBQkxFX1BSRUxPQUQgPSBjb25maWcuZGlzYWJsZVByZWxvYWRcbiAgcHJvY2Vzcy5lbnYuUkVBQ1RfU1RBVElDX0RJU0FCTEVfUlVOVElNRSA9IGNvbmZpZy5kaXNhYmxlUnVudGltZVxuICBwcm9jZXNzLmVudi5SRUFDVF9TVEFUSUNfUFJFTE9BRF9QT0xMX0lOVEVSVkFMID0gY29uZmlnLnByZWxvYWRQb2xsSW50ZXJ2YWxcbiAgcHJvY2Vzcy5lbnYuUkVBQ1RfU1RBVElDX1NJTEVOVCA9IGNvbmZpZy5zaWxlbnRcblxuICBwcm9jZXNzLmVudi5SRUFDVF9TVEFUSUNfUk9PVF9QQVRIX1JFQURfT05MWSA9IHBhdGhzLlJPT1RcblxuICBwcm9jZXNzLmVudi5SRUFDVF9TVEFUSUNfVEVNUExBVEVTX1BBVEggPSBub2RlUGF0aC5qb2luKFxuICAgIHBhdGhzLkFSVElGQUNUUyxcbiAgICAncmVhY3Qtc3RhdGljLXRlbXBsYXRlcy5qcydcbiAgKVxuICBwcm9jZXNzLmVudi5SRUFDVF9TVEFUSUNfUExVR0lOU19QQVRIID0gbm9kZVBhdGguam9pbihcbiAgICBwYXRocy5BUlRJRkFDVFMsXG4gICAgJ3JlYWN0LXN0YXRpYy1icm93c2VyLXBsdWdpbnMuanMnXG4gIClcblxuICBjb25zdCByZXNvbHZlUGx1Z2luID0gb3JpZ2luYWxMb2NhdGlvbiA9PiB7XG4gICAgbGV0IG9wdGlvbnMgPSB7fVxuICAgIGlmIChBcnJheS5pc0FycmF5KG9yaWdpbmFsTG9jYXRpb24pKSB7XG4gICAgICBvcHRpb25zID0gb3JpZ2luYWxMb2NhdGlvblsxXSB8fCB7fVxuICAgICAgb3JpZ2luYWxMb2NhdGlvbiA9IG9yaWdpbmFsTG9jYXRpb25bMF1cbiAgICB9XG5cbiAgICBjb25zdCBsb2NhdGlvbiA9IFtcbiAgICAgICgpID0+IHtcbiAgICAgICAgLy8gQWJzb2x1dGUgcmVxdWlyZVxuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IGZvdW5kID0gcmVxdWlyZS5yZXNvbHZlKG9yaWdpbmFsTG9jYXRpb24pXG4gICAgICAgICAgcmV0dXJuIGZvdW5kLmluY2x1ZGVzKCcuJykgPyBub2RlUGF0aC5yZXNvbHZlKGZvdW5kLCAnLi4vJykgOiBmb3VuZFxuICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAvL1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgKCkgPT4ge1xuICAgICAgICAvLyBBYnNvbHV0ZVxuICAgICAgICBpZiAoZnMucGF0aEV4aXN0c1N5bmMob3JpZ2luYWxMb2NhdGlvbikpIHtcbiAgICAgICAgICByZXR1cm4gb3JpZ2luYWxMb2NhdGlvblxuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgKCkgPT4ge1xuICAgICAgICAvLyBQbHVnaW5zIERpclxuICAgICAgICBjb25zdCBmb3VuZCA9IG5vZGVQYXRoLnJlc29sdmUocGF0aHMuUExVR0lOUywgb3JpZ2luYWxMb2NhdGlvbilcbiAgICAgICAgaWYgKGZzLnBhdGhFeGlzdHNTeW5jKGZvdW5kKSkge1xuICAgICAgICAgIHJldHVybiBmb3VuZFxuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgKCkgPT4ge1xuICAgICAgICAvLyBQbHVnaW5zIERpciByZXF1aXJlXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgZm91bmQgPSByZXNvbHZlRnJvbShwYXRocy5QTFVHSU5TLCBvcmlnaW5hbExvY2F0aW9uKVxuICAgICAgICAgIHJldHVybiBmb3VuZC5pbmNsdWRlcygnLicpID8gbm9kZVBhdGgucmVzb2x2ZShmb3VuZCwgJy4uLycpIDogZm91bmRcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgLy9cbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgICgpID0+IHtcbiAgICAgICAgLy8gQ1dEXG4gICAgICAgIGNvbnN0IGZvdW5kID0gbm9kZVBhdGgucmVzb2x2ZShwcm9jZXNzLmN3ZCgpLCBvcmlnaW5hbExvY2F0aW9uKVxuICAgICAgICBpZiAoZnMucGF0aEV4aXN0c1N5bmMoZm91bmQpKSB7XG4gICAgICAgICAgcmV0dXJuIGZvdW5kXG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICAoKSA9PiB7XG4gICAgICAgIC8vIENXRCByZXF1aXJlXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgZm91bmQgPSByZXNvbHZlRnJvbShwcm9jZXNzLmN3ZCgpLCBvcmlnaW5hbExvY2F0aW9uKVxuICAgICAgICAgIHJldHVybiBmb3VuZC5pbmNsdWRlcygnLicpID8gbm9kZVBhdGgucmVzb2x2ZShmb3VuZCwgJy4uLycpIDogZm91bmRcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgLy9cbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgICgpID0+IHtcbiAgICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSAndGVzdCcpIHtcbiAgICAgICAgICAvLyBBbGxvdyBwbHVnaW5zIHRvIGJlIG1vY2tlZFxuICAgICAgICAgIHJldHVybiByZXF1aXJlKCdwYXRoJykucmVzb2x2ZSgnLi9zcmMvc3RhdGljL19fbW9ja3NfXy9tb2NrLXBsdWdpbicpXG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgXS5yZWR1Y2UoKHByZXYsIGN1cnIpID0+IHByZXYgfHwgY3VycigpLCBudWxsKVxuXG4gICAgLy8gVE9ETzogV2UgaGF2ZSB0byBkbyB0aGlzIGJlY2F1c2Ugd2UgZG9uJ3QgaGF2ZSBhIGdvb2QgbW9jayBmb3IgcHJvY2Vzcy5jd2QoKSA6KFxuICAgIGlmICghbG9jYXRpb24pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYENvdWxkIG5vdCBmaW5kIGEgcGx1Z2luIGRpcmVjdG9yeSBmb3IgdGhlIHBsdWdpbjogXCIke29yaWdpbmFsTG9jYXRpb259XCIuIFdlIG11c3QgYmFpbCFgXG4gICAgICApXG4gICAgfVxuXG4gICAgbGV0IG5vZGVMb2NhdGlvbiA9IG5vZGVQYXRoLmpvaW4obG9jYXRpb24sICdub2RlLmFwaS5qcycpXG4gICAgbGV0IGJyb3dzZXJMb2NhdGlvbiA9IG5vZGVQYXRoLmpvaW4obG9jYXRpb24sICdicm93c2VyLmFwaS5qcycpXG5cbiAgICAvLyBEZXRlY3QgaWYgdGhlIG5vZGUgcGx1Z2luIGVudHJ5IGV4aXN0cywgYW5kIHByb3ZpZGUgdGhlIG5vZGVSZXNvbHZlciB0byBpdFxuICAgIG5vZGVMb2NhdGlvbiA9IGZzLnBhdGhFeGlzdHNTeW5jKG5vZGVMb2NhdGlvbikgPyBub2RlTG9jYXRpb24gOiBudWxsXG5cbiAgICAvLyBEZXRlY3QgaWYgdGhlIGJyb3dzZXIgcGx1Z2luIGVudHJ5IGV4aXN0cywgYW5kIHByb3ZpZGUgdGhlIG5vZGVSZXNvbHZlciB0byBpdFxuICAgIGJyb3dzZXJMb2NhdGlvbiA9IGZzLnBhdGhFeGlzdHNTeW5jKGJyb3dzZXJMb2NhdGlvbilcbiAgICAgID8gYnJvd3NlckxvY2F0aW9uXG4gICAgICA6IG51bGxcblxuICAgIGxldCBidWlsZFBsdWdpbkhvb2tzID0gKCkgPT4gKHt9KVxuXG4gICAgdHJ5IHtcbiAgICAgIC8vIEdldCB0aGUgaG9va3MgZm9yIHRoZSBub2RlIGFwaVxuICAgICAgaWYgKG5vZGVMb2NhdGlvbikge1xuICAgICAgICBidWlsZFBsdWdpbkhvb2tzID0gcmVxdWlyZShub2RlTG9jYXRpb24pLmRlZmF1bHRcbiAgICAgIH0gZWxzZSBpZiAob3JpZ2luYWxMb2NhdGlvbiAhPT0gcGF0aHMuUk9PVCAmJiAhYnJvd3NlckxvY2F0aW9uKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBgQ291bGQgbm90IGZpbmQgYSB2YWxpZCBub2RlLmFwaS5qcyBvciBicm93c2VyLmFwaS5qcyBwbHVnaW4gZmlsZSBpbiBcIiR7bG9jYXRpb259XCIuIFxcbmAgK1xuICAgICAgICAgICAgYFRoZSBvcmlnaW5hbCBsb2NhdGlvbjogXCIke29yaWdpbmFsTG9jYXRpb259XCIuIFxcbmAgK1xuICAgICAgICAgICAgYFRoZSByb290IGxvY2F0aW9uOiBcIiR7cGF0aHMuUk9PVH1cIi5gXG4gICAgICAgIClcbiAgICAgIH1cblxuICAgICAgY29uc3QgcmVzb2x2ZWRQbHVnaW4gPSB7XG4gICAgICAgIGxvY2F0aW9uLFxuICAgICAgICBub2RlTG9jYXRpb24sXG4gICAgICAgIGJyb3dzZXJMb2NhdGlvbixcbiAgICAgICAgb3B0aW9ucyxcbiAgICAgICAgaG9va3M6IGJ1aWxkUGx1Z2luSG9va3Mob3B0aW9ucykgfHwge30sXG4gICAgICB9XG5cbiAgICAgIHZhbGlkYXRlUGx1Z2luKHJlc29sdmVkUGx1Z2luKVxuXG4gICAgICAvLyBSZWN1cnNpdmVseSByZXNvbHZlIHBsdWdpbnNcbiAgICAgIGlmIChyZXNvbHZlZFBsdWdpbi5wbHVnaW5zKSB7XG4gICAgICAgIHJlc29sdmVkUGx1Z2luLnBsdWdpbnMgPSByZXNvbHZlZFBsdWdpbi5wbHVnaW5zLm1hcChyZXNvbHZlUGx1Z2luKVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gcmVzb2x2ZWRQbHVnaW5cbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoXG4gICAgICAgIGBUaGUgZm9sbG93aW5nIGVycm9yIG9jY3VycmVkIGluIHRoZSBwbHVnaW46IFwiJHtvcmlnaW5hbExvY2F0aW9ufVwiYFxuICAgICAgKVxuICAgICAgdGhyb3cgZXJyXG4gICAgfVxuICB9XG5cbiAgc3RhdGUgPSB7XG4gICAgLi4uc3RhdGUsXG4gICAgcGx1Z2luczogY29uZmlnLnBsdWdpbnMubWFwKHJlc29sdmVQbHVnaW4pLFxuICAgIGNvbmZpZyxcbiAgfVxuXG4gIHJldHVybiBjb3JlUGx1Z2lucy5hZnRlckdldENvbmZpZyhzdGF0ZSlcbn1cbiJdfQ==