UNPKG

@axway/amplify-cli-utils

Version:

Common utils for Axway CLI packages

428 lines (367 loc) 38.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "AmplifySDK", { enumerable: true, get: function () { return _amplifySdk.default; } }); Object.defineProperty(exports, "Config", { enumerable: true, get: function () { return _amplifyConfig.Config; } }); Object.defineProperty(exports, "Telemetry", { enumerable: true, get: function () { return _amplifySdk.Telemetry; } }); exports.buildParams = exports.buildAuthParams = buildAuthParams; exports.checkForUpdate = checkForUpdate; Object.defineProperty(exports, "createNPMRequestArgs", { enumerable: true, get: function () { return _request.createNPMRequestArgs; } }); Object.defineProperty(exports, "createRequestClient", { enumerable: true, get: function () { return _request.createRequestClient; } }); Object.defineProperty(exports, "createRequestOptions", { enumerable: true, get: function () { return _request.createRequestOptions; } }); exports.createTable = createTable; exports.environments = void 0; exports.getAuthConfigEnvSpecifier = getAuthConfigEnvSpecifier; exports.hlVer = hlVer; exports.initPlatformAccount = initPlatformAccount; exports.initSDK = initSDK; exports.isHeadless = isHeadless; Object.defineProperty(exports, "loadConfig", { enumerable: true, get: function () { return _amplifyConfig.default; } }); exports.telemetry = exports.request = exports.locations = void 0; var _sourceMapSupport = _interopRequireDefault(require("source-map-support")); var _amplifySdk = _interopRequireWildcard(require("@axway/amplify-sdk")); var _boxen = _interopRequireDefault(require("boxen")); var _checkKit = _interopRequireDefault(require("check-kit")); var _fs = _interopRequireDefault(require("fs")); var _amplifyConfig = _interopRequireWildcard(require("@axway/amplify-config")); var _snooplogg = _interopRequireDefault(require("snooplogg")); var _cliTable = _interopRequireDefault(require("cli-table3")); var _cliKit = require("cli-kit"); var _request = require("./request.js"); var environments = _interopRequireWildcard(require("./environments.js")); exports.environments = environments; var locations = _interopRequireWildcard(require("./locations.js")); exports.locations = locations; var request = _interopRequireWildcard(require("@axway/amplify-request")); exports.request = request; var telemetry = _interopRequireWildcard(require("./telemetry.js")); exports.telemetry = telemetry; function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /* istanbul ignore if */ if (!Error.prepareStackTrace) { _sourceMapSupport.default.install(); } const { warn } = (0, _snooplogg.default)('amplify-cli-utils'); const { cyan, gray, green } = _snooplogg.default.chalk; /** * Constructs a parameters object to pass into an Auth instance. * * @param {Object} [opts] - User option overrides. * @param {Config} [config] - The Amplify config object. * @returns {Object} */ async function buildAuthParams(opts = {}, config) { if (!opts || typeof opts !== 'object') { throw new Error('Expected options to be an object'); } if (!config) { config = await (0, _amplifyConfig.default)(); } const env = environments.resolve(opts.env || (await config.get('env'))); const { clientId, realm } = env.auth; const params = {}; const props = { baseUrl: undefined, clientId, clientSecret: undefined, env: env.name, interactiveLoginTimeout: undefined, homeDir: locations.axwayHome, password: undefined, persistSecrets: undefined, platformUrl: undefined, realm, secretFile: undefined, serverHost: undefined, serverPort: undefined, serviceAccount: undefined, tokenRefreshThreshold: 15 * 60, // 15 minutes tokenStore: undefined, tokenStoreDir: locations.axwayHome, tokenStoreType: undefined, username: undefined }; for (const prop of Object.keys(props)) { params[prop] = opts[prop] !== undefined ? opts[prop] : await config.get(`auth.${prop}`, props[prop]); } // detect if we're headless and default token store type to `file` if (params.tokenStoreType === undefined && isHeadless()) { params.tokenStoreType = 'file'; await config.set('auth.tokenStoreType', 'file'); try { await config.save(); } catch (err) { warn(err); } } params.requestOptions = (0, _request.createRequestOptions)(opts, config); return params; } // `buildParams()` is too ambiguous, so it was renamed to `buildAuthParams()`, but we still need to // maintain backwards compatibility /** * Checks if a new version of an npm package is available and returns a string with the formatted * update message. * * @param {Object} [opts] - Check update and request configuration options. * @param {Number} [opts.checkInterval=3600000] - The amount of time in milliseconds before * checking for an update. Defaults to 1 hour. * @param {String} [opts.cwd] - The current working directory used to locate the `package.json` if * `pkg` is not specified. * @param {String} [opts.distTag='latest'] - The tag to check for the latest version. * @param {Boolean} [opts.force=false] - Forces an update check. * @param {String} [opts.metaDir] - The directory to store package update information. * @param {Object|String} [opts.pkg] - The parsed `package.json`, path to the package.json file, or * falsey and it will scan parent directories looking for a package.json. * @param {String} [opts.registryUrl] - The npm registry URL. By default, it will autodetect the * URL based on the package name/scope. * @param {Number} [opts.timeout=1000] - The number of milliseconds to wait to query npm before * timing out. * @param {Config} [config] - An Amplify Config instance. If not specified, the config is loaded * from disk. * @returns {String} */ async function checkForUpdate(opts, config) { opts = (0, _request.createRequestOptions)(opts, config || (await (0, _amplifyConfig.default)())); const { current, latest, name, updateAvailable } = await (0, _checkKit.default)(opts); if (updateAvailable) { const msg = `Update available ${gray(current)}${green(latest)}\nRun ${cyan(`npm i -g ${name}`)} to update`; return (0, _boxen.default)(msg, { align: 'center', borderColor: 'yellow', borderStyle: 'round', margin: { bottom: 1, left: 4, right: 4, top: 1 }, padding: { bottom: 1, left: 4, right: 4, top: 1 } }); } } /** * Creates a table with default styles and padding. * * @param {Array.<String>} head - One or more headings. * @param {Number} [indent] - The number of spaces to indent the table. * @returns {Table} */ function createTable(head, indent = 0) { return new _cliTable.default({ chars: { bottom: '', 'bottom-left': '', 'bottom-mid': '', 'bottom-right': '', left: ' '.repeat(indent), 'left-mid': '', mid: '', 'mid-mid': '', middle: ' ', right: '', 'right-mid': '', top: '', 'top-left': '', 'top-mid': '', 'top-right': '' }, head: Array.isArray(head) ? head.map(_cliKit.ansi.toUpperCase) : head, style: { border: [], head: [], 'padding-left': 0, 'padding-right': 0 } }); } /** * Resovles the "auth.*" config key based on your environment. This is used to get or set the * default account and org. * * @param {String} env - The resolved environment name. * @returns {String} * * @example * await config.get(`${getAuthConfigEnvSpecifier(sdk.env.name)}.defaultAccount`); */ function getAuthConfigEnvSpecifier(env) { return !env || env === 'prod' ? 'auth' : `auth.environment.${env}`; } /** * Highlights the difference between two versions. * * @param {String} toVer - The latest version. * @param {String} fromVer - The current version. * @returns {String} */ function hlVer(toVer, fromVer) { const { green } = _snooplogg.default.styles; const version = []; let [from, fromTag] = fromVer.split(/-(.+)/); from = from.replace(/[^.\d]/g, '').split('.').map(x => parseInt(x)); let [to, toTag] = toVer.split(/-(.+)/); const toMatch = to.match(/^([^\d]+)?(.+)$/); to = (toMatch ? toMatch[2] : to).split('.').map(x => parseInt(x)); const tag = () => { if (toTag) { const toNum = toTag.match(/\d+$/); const fromNum = fromTag && fromTag.match(/\d+$/); if (fromNum && parseInt(fromNum[0]) >= parseInt(toNum)) { return `-${toTag}`; } else { return green(`-${toTag}`); } } return ''; }; while (to.length) { if (to[0] > from[0]) { if (version.length) { return (toMatch && toMatch[1] || '') + version.concat(green(to.join('.') + tag())).join('.'); } return green((toMatch && toMatch[1] || '') + to.join('.') + tag()); } version.push(to.shift()); from.shift(); } return (toMatch && toMatch[1] || '') + version.join('.') + tag(); } /** * Initializes the Amplify SDK, loads an account, and finds the default org id. * * @param {String} [accountName] - The name of the platform account to use. * @param {String} [org] - The name, id, or guid of the default organization. * @param {String} [env] - The environment name. * @param {boolean} [bypassPlatformAccountCheck] - Optional parameter to bypass check if the account is platform * @returns {Promise<Object>} */ async function initPlatformAccount(accountName, org, env, bypassPlatformAccountCheck = false) { const { config, sdk } = await initSDK({ env }); const authConfigEnvSpecifier = getAuthConfigEnvSpecifier(sdk.env.name); const account = await sdk.auth.find(accountName || (await config.get(`${authConfigEnvSpecifier}.defaultAccount`))); if (accountName) { if (!account) { throw new Error(`Account "${accountName}" not found`); } else if (!bypassPlatformAccountCheck && !account.isPlatform) { throw new Error(`Account "${accountName}" is not a platform account\n\nTo login, run: axway auth login`); } } else if (!account || !bypassPlatformAccountCheck && !account.isPlatform) { throw new Error('You must be logged into a platform account\n\nTo login, run: axway auth login'); } if (org) { org = await sdk.org.find(account, org); } else { try { // check the config for a default org for this account org = await sdk.org.find(account, await config.get(`${authConfigEnvSpecifier}.defaultOrg.${account.hash}`)); } catch (err) { // default org was stale, auto detect the default from the account orgs org = await sdk.org.find(account); } } return { account, config, org, sdk }; } /** * Loads the config and creates an Amplify SDK object, then returns both of them. * * @param {Object} [opts] - SDK options including `env` and auth options. * @param {Object} [config] - The Amplify await config. If not passed in, the config file is loaded. * @returns {Object} Returns an object containing the Axway CLI config and an initialized * Amplify SDK instance. */ async function initSDK(opts = {}, config) { if (!config) { config = await (0, _amplifyConfig.default)(); } return { config, sdk: new _amplifySdk.default(await buildAuthParams(opts, config)) }; } /** * Detects if the current terminal is headless (e.g. a Docker container or SSH session). * * @returns {Boolean} */ function isHeadless() { try { if (process.platform === 'linux' && (process.env.SSH_TTY || !process.env.DISPLAY || /docker|lxc/.test(_fs.default.readFileSync('/proc/1/cgroup', 'utf8')))) { return true; } if (process.platform === 'darwin' && process.env.SSH_TTY) { return true; } } catch (e) {// do nothing } return false; } //# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJuYW1lcyI6WyJFcnJvciIsInByZXBhcmVTdGFja1RyYWNlIiwic291cmNlTWFwU3VwcG9ydCIsImluc3RhbGwiLCJ3YXJuIiwiY3lhbiIsImdyYXkiLCJncmVlbiIsInNub29wbG9nZyIsImNoYWxrIiwiYnVpbGRBdXRoUGFyYW1zIiwib3B0cyIsImNvbmZpZyIsImVudiIsImVudmlyb25tZW50cyIsInJlc29sdmUiLCJnZXQiLCJjbGllbnRJZCIsInJlYWxtIiwiYXV0aCIsInBhcmFtcyIsInByb3BzIiwiYmFzZVVybCIsInVuZGVmaW5lZCIsImNsaWVudFNlY3JldCIsIm5hbWUiLCJpbnRlcmFjdGl2ZUxvZ2luVGltZW91dCIsImhvbWVEaXIiLCJsb2NhdGlvbnMiLCJheHdheUhvbWUiLCJwYXNzd29yZCIsInBlcnNpc3RTZWNyZXRzIiwicGxhdGZvcm1VcmwiLCJzZWNyZXRGaWxlIiwic2VydmVySG9zdCIsInNlcnZlclBvcnQiLCJzZXJ2aWNlQWNjb3VudCIsInRva2VuUmVmcmVzaFRocmVzaG9sZCIsInRva2VuU3RvcmUiLCJ0b2tlblN0b3JlRGlyIiwidG9rZW5TdG9yZVR5cGUiLCJ1c2VybmFtZSIsInByb3AiLCJPYmplY3QiLCJrZXlzIiwiaXNIZWFkbGVzcyIsInNldCIsInNhdmUiLCJlcnIiLCJyZXF1ZXN0T3B0aW9ucyIsImNoZWNrRm9yVXBkYXRlIiwiY3VycmVudCIsImxhdGVzdCIsInVwZGF0ZUF2YWlsYWJsZSIsIm1zZyIsImFsaWduIiwiYm9yZGVyQ29sb3IiLCJib3JkZXJTdHlsZSIsIm1hcmdpbiIsImJvdHRvbSIsImxlZnQiLCJyaWdodCIsInRvcCIsInBhZGRpbmciLCJjcmVhdGVUYWJsZSIsImhlYWQiLCJpbmRlbnQiLCJUYWJsZSIsImNoYXJzIiwicmVwZWF0IiwibWlkIiwibWlkZGxlIiwiQXJyYXkiLCJpc0FycmF5IiwibWFwIiwiYW5zaSIsInRvVXBwZXJDYXNlIiwic3R5bGUiLCJib3JkZXIiLCJnZXRBdXRoQ29uZmlnRW52U3BlY2lmaWVyIiwiaGxWZXIiLCJ0b1ZlciIsImZyb21WZXIiLCJzdHlsZXMiLCJ2ZXJzaW9uIiwiZnJvbSIsImZyb21UYWciLCJzcGxpdCIsInJlcGxhY2UiLCJ4IiwicGFyc2VJbnQiLCJ0byIsInRvVGFnIiwidG9NYXRjaCIsIm1hdGNoIiwidGFnIiwidG9OdW0iLCJmcm9tTnVtIiwibGVuZ3RoIiwiY29uY2F0Iiwiam9pbiIsInB1c2giLCJzaGlmdCIsImluaXRQbGF0Zm9ybUFjY291bnQiLCJhY2NvdW50TmFtZSIsIm9yZyIsImJ5cGFzc1BsYXRmb3JtQWNjb3VudENoZWNrIiwic2RrIiwiaW5pdFNESyIsImF1dGhDb25maWdFbnZTcGVjaWZpZXIiLCJhY2NvdW50IiwiZmluZCIsImlzUGxhdGZvcm0iLCJoYXNoIiwiQW1wbGlmeVNESyIsInByb2Nlc3MiLCJwbGF0Zm9ybSIsIlNTSF9UVFkiLCJESVNQTEFZIiwidGVzdCIsImZzIiwicmVhZEZpbGVTeW5jIiwiZSJdLCJzb3VyY2VzIjpbImluZGV4LmpzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBzb3VyY2VNYXBTdXBwb3J0IGZyb20gJ3NvdXJjZS1tYXAtc3VwcG9ydCc7XG4vKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbmlmICghRXJyb3IucHJlcGFyZVN0YWNrVHJhY2UpIHtcblx0c291cmNlTWFwU3VwcG9ydC5pbnN0YWxsKCk7XG59XG5cbmltcG9ydCBBbXBsaWZ5U0RLLCB7IFRlbGVtZXRyeSB9IGZyb20gJ0BheHdheS9hbXBsaWZ5LXNkayc7XG5pbXBvcnQgYm94ZW4gZnJvbSAnYm94ZW4nO1xuaW1wb3J0IGNoZWNrIGZyb20gJ2NoZWNrLWtpdCc7XG5pbXBvcnQgZnMgZnJvbSAnZnMnO1xuaW1wb3J0IGxvYWRDb25maWcsIHsgQ29uZmlnIH0gZnJvbSAnQGF4d2F5L2FtcGxpZnktY29uZmlnJztcbmltcG9ydCBzbm9vcGxvZ2cgZnJvbSAnc25vb3Bsb2dnJztcbmltcG9ydCBUYWJsZSBmcm9tICdjbGktdGFibGUzJztcbmltcG9ydCB7IGFuc2kgfSBmcm9tICdjbGkta2l0JztcbmltcG9ydCB7IGNyZWF0ZU5QTVJlcXVlc3RBcmdzLCBjcmVhdGVSZXF1ZXN0Q2xpZW50LCBjcmVhdGVSZXF1ZXN0T3B0aW9ucyB9IGZyb20gJy4vcmVxdWVzdC5qcyc7XG5pbXBvcnQgKiBhcyBlbnZpcm9ubWVudHMgZnJvbSAnLi9lbnZpcm9ubWVudHMuanMnO1xuaW1wb3J0ICogYXMgbG9jYXRpb25zIGZyb20gJy4vbG9jYXRpb25zLmpzJztcbmltcG9ydCAqIGFzIHJlcXVlc3QgZnJvbSAnQGF4d2F5L2FtcGxpZnktcmVxdWVzdCc7XG5pbXBvcnQgKiBhcyB0ZWxlbWV0cnkgZnJvbSAnLi90ZWxlbWV0cnkuanMnO1xuXG5leHBvcnQge1xuXHRBbXBsaWZ5U0RLLFxuXHRDb25maWcsXG5cdGNyZWF0ZU5QTVJlcXVlc3RBcmdzLFxuXHRjcmVhdGVSZXF1ZXN0Q2xpZW50LFxuXHRjcmVhdGVSZXF1ZXN0T3B0aW9ucyxcblx0ZW52aXJvbm1lbnRzLFxuXHRsb2FkQ29uZmlnLFxuXHRsb2NhdGlvbnMsXG5cdHJlcXVlc3QsXG5cdFRlbGVtZXRyeSxcblx0dGVsZW1ldHJ5XG59O1xuXG5jb25zdCB7IHdhcm4gfSA9IHNub29wbG9nZygnYW1wbGlmeS1jbGktdXRpbHMnKTtcbmNvbnN0IHsgY3lhbiwgZ3JheSwgZ3JlZW4gfSA9IHNub29wbG9nZy5jaGFsaztcblxuLyoqXG4gKiBDb25zdHJ1Y3RzIGEgcGFyYW1ldGVycyBvYmplY3QgdG8gcGFzcyBpbnRvIGFuIEF1dGggaW5zdGFuY2UuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IFtvcHRzXSAtIFVzZXIgb3B0aW9uIG92ZXJyaWRlcy5cbiAqIEBwYXJhbSB7Q29uZmlnfSBbY29uZmlnXSAtIFRoZSBBbXBsaWZ5IGNvbmZpZyBvYmplY3QuXG4gKiBAcmV0dXJucyB7T2JqZWN0fVxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYnVpbGRBdXRoUGFyYW1zKG9wdHMgPSB7fSwgY29uZmlnKSB7XG5cdGlmICghb3B0cyB8fCB0eXBlb2Ygb3B0cyAhPT0gJ29iamVjdCcpIHtcblx0XHR0aHJvdyBuZXcgRXJyb3IoJ0V4cGVjdGVkIG9wdGlvbnMgdG8gYmUgYW4gb2JqZWN0Jyk7XG5cdH1cblxuXHRpZiAoIWNvbmZpZykge1xuXHRcdGNvbmZpZyA9IGF3YWl0IGxvYWRDb25maWcoKTtcblx0fVxuXG5cdGNvbnN0IGVudiA9IGVudmlyb25tZW50cy5yZXNvbHZlKG9wdHMuZW52IHx8IGF3YWl0IGNvbmZpZy5nZXQoJ2VudicpKTtcblxuXHRjb25zdCB7IGNsaWVudElkLCByZWFsbSB9ID0gZW52LmF1dGg7XG5cdGNvbnN0IHBhcmFtcyA9IHt9O1xuXHRjb25zdCBwcm9wcyA9IHtcblx0XHRiYXNlVXJsOiAgICAgICAgICAgICAgICAgdW5kZWZpbmVkLFxuXHRcdGNsaWVudElkLFxuXHRcdGNsaWVudFNlY3JldDogICAgICAgICAgICB1bmRlZmluZWQsXG5cdFx0ZW52OiAgICAgICAgICAgICAgICAgICAgIGVudi5uYW1lLFxuXHRcdGludGVyYWN0aXZlTG9naW5UaW1lb3V0OiB1bmRlZmluZWQsXG5cdFx0aG9tZURpcjogICAgICAgICAgICAgICAgIGxvY2F0aW9ucy5heHdheUhvbWUsXG5cdFx0cGFzc3dvcmQ6ICAgICAgICAgICAgICAgIHVuZGVmaW5lZCxcblx0XHRwZXJzaXN0U2VjcmV0czogICAgICAgICAgdW5kZWZpbmVkLFxuXHRcdHBsYXRmb3JtVXJsOiAgICAgICAgICAgICB1bmRlZmluZWQsXG5cdFx0cmVhbG0sXG5cdFx0c2VjcmV0RmlsZTogICAgICAgICAgICAgIHVuZGVmaW5lZCxcblx0XHRzZXJ2ZXJIb3N0OiAgICAgICAgICAgICAgdW5kZWZpbmVkLFxuXHRcdHNlcnZlclBvcnQ6ICAgICAgICAgICAgICB1bmRlZmluZWQsXG5cdFx0c2VydmljZUFjY291bnQ6ICAgICAgICAgIHVuZGVmaW5lZCxcblx0XHR0b2tlblJlZnJlc2hUaHJlc2hvbGQ6ICAgMTUgKiA2MCwgLy8gMTUgbWludXRlc1xuXHRcdHRva2VuU3RvcmU6ICAgICAgICAgICAgICB1bmRlZmluZWQsXG5cdFx0dG9rZW5TdG9yZURpcjogICAgICAgICAgIGxvY2F0aW9ucy5heHdheUhvbWUsXG5cdFx0dG9rZW5TdG9yZVR5cGU6ICAgICAgICAgIHVuZGVmaW5lZCxcblx0XHR1c2VybmFtZTogICAgICAgICAgICAgICAgdW5kZWZpbmVkXG5cdH07XG5cblx0Zm9yIChjb25zdCBwcm9wIG9mIE9iamVjdC5rZXlzKHByb3BzKSkge1xuXHRcdHBhcmFtc1twcm9wXSA9IG9wdHNbcHJvcF0gIT09IHVuZGVmaW5lZCA/IG9wdHNbcHJvcF0gOiBhd2FpdCBjb25maWcuZ2V0KGBhdXRoLiR7cHJvcH1gLCBwcm9wc1twcm9wXSk7XG5cdH1cblxuXHQvLyBkZXRlY3QgaWYgd2UncmUgaGVhZGxlc3MgYW5kIGRlZmF1bHQgdG9rZW4gc3RvcmUgdHlwZSB0byBgZmlsZWBcblx0aWYgKHBhcmFtcy50b2tlblN0b3JlVHlwZSA9PT0gdW5kZWZpbmVkICYmIGlzSGVhZGxlc3MoKSkge1xuXHRcdHBhcmFtcy50b2tlblN0b3JlVHlwZSA9ICdmaWxlJztcblx0XHRhd2FpdCBjb25maWcuc2V0KCdhdXRoLnRva2VuU3RvcmVUeXBlJywgJ2ZpbGUnKTtcblx0XHR0cnkge1xuXHRcdFx0YXdhaXQgY29uZmlnLnNhdmUoKTtcblx0XHR9IGNhdGNoIChlcnIpIHtcblx0XHRcdHdhcm4oZXJyKTtcblx0XHR9XG5cdH1cblxuXHRwYXJhbXMucmVxdWVzdE9wdGlvbnMgPSBjcmVhdGVSZXF1ZXN0T3B0aW9ucyhvcHRzLCBjb25maWcpO1xuXG5cdHJldHVybiBwYXJhbXM7XG59XG5cbi8vIGBidWlsZFBhcmFtcygpYCBpcyB0b28gYW1iaWd1b3VzLCBzbyBpdCB3YXMgcmVuYW1lZCB0byBgYnVpbGRBdXRoUGFyYW1zKClgLCBidXQgd2Ugc3RpbGwgbmVlZCB0b1xuLy8gbWFpbnRhaW4gYmFja3dhcmRzIGNvbXBhdGliaWxpdHlcbmV4cG9ydCB7IGJ1aWxkQXV0aFBhcmFtcyBhcyBidWlsZFBhcmFtcyB9O1xuXG4vKipcbiAqIENoZWNrcyBpZiBhIG5ldyB2ZXJzaW9uIG9mIGFuIG5wbSBwYWNrYWdlIGlzIGF2YWlsYWJsZSBhbmQgcmV0dXJucyBhIHN0cmluZyB3aXRoIHRoZSBmb3JtYXR0ZWRcbiAqIHVwZGF0ZSBtZXNzYWdlLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0c10gLSBDaGVjayB1cGRhdGUgYW5kIHJlcXVlc3QgY29uZmlndXJhdGlvbiBvcHRpb25zLlxuICogQHBhcmFtIHtOdW1iZXJ9IFtvcHRzLmNoZWNrSW50ZXJ2YWw9MzYwMDAwMF0gLSBUaGUgYW1vdW50IG9mIHRpbWUgaW4gbWlsbGlzZWNvbmRzIGJlZm9yZVxuICogY2hlY2tpbmcgZm9yIGFuIHVwZGF0ZS4gRGVmYXVsdHMgdG8gMSBob3VyLlxuICogQHBhcmFtIHtTdHJpbmd9IFtvcHRzLmN3ZF0gLSBUaGUgY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeSB1c2VkIHRvIGxvY2F0ZSB0aGUgYHBhY2thZ2UuanNvbmAgaWZcbiAqIGBwa2dgIGlzIG5vdCBzcGVjaWZpZWQuXG4gKiBAcGFyYW0ge1N0cmluZ30gW29wdHMuZGlzdFRhZz0nbGF0ZXN0J10gLSBUaGUgdGFnIHRvIGNoZWNrIGZvciB0aGUgbGF0ZXN0IHZlcnNpb24uXG4gKiBAcGFyYW0ge0Jvb2xlYW59IFtvcHRzLmZvcmNlPWZhbHNlXSAtIEZvcmNlcyBhbiB1cGRhdGUgY2hlY2suXG4gKiBAcGFyYW0ge1N0cmluZ30gW29wdHMubWV0YURpcl0gLSBUaGUgZGlyZWN0b3J5IHRvIHN0b3JlIHBhY2thZ2UgdXBkYXRlIGluZm9ybWF0aW9uLlxuICogQHBhcmFtIHtPYmplY3R8U3RyaW5nfSBbb3B0cy5wa2ddIC0gVGhlIHBhcnNlZCBgcGFja2FnZS5qc29uYCwgcGF0aCB0byB0aGUgcGFja2FnZS5qc29uIGZpbGUsIG9yXG4gKiBmYWxzZXkgYW5kIGl0IHdpbGwgc2NhbiBwYXJlbnQgZGlyZWN0b3JpZXMgbG9va2luZyBmb3IgYSBwYWNrYWdlLmpzb24uXG4gKiBAcGFyYW0ge1N0cmluZ30gW29wdHMucmVnaXN0cnlVcmxdIC0gVGhlIG5wbSByZWdpc3RyeSBVUkwuIEJ5IGRlZmF1bHQsIGl0IHdpbGwgYXV0b2RldGVjdCB0aGVcbiAqIFVSTCBiYXNlZCBvbiB0aGUgcGFja2FnZSBuYW1lL3Njb3BlLlxuICogQHBhcmFtIHtOdW1iZXJ9IFtvcHRzLnRpbWVvdXQ9MTAwMF0gLSBUaGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyB0byB3YWl0IHRvIHF1ZXJ5IG5wbSBiZWZvcmVcbiAqIHRpbWluZyBvdXQuXG4gKiBAcGFyYW0ge0NvbmZpZ30gW2NvbmZpZ10gLSBBbiBBbXBsaWZ5IENvbmZpZyBpbnN0YW5jZS4gSWYgbm90IHNwZWNpZmllZCwgdGhlIGNvbmZpZyBpcyBsb2FkZWRcbiAqIGZyb20gZGlzay5cbiAqIEByZXR1cm5zIHtTdHJpbmd9XG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjaGVja0ZvclVwZGF0ZShvcHRzLCBjb25maWcpIHtcblx0b3B0cyA9IGNyZWF0ZVJlcXVlc3RPcHRpb25zKG9wdHMsIGNvbmZpZyB8fCBhd2FpdCBsb2FkQ29uZmlnKCkpO1xuXG5cdGNvbnN0IHtcblx0XHRjdXJyZW50LFxuXHRcdGxhdGVzdCxcblx0XHRuYW1lLFxuXHRcdHVwZGF0ZUF2YWlsYWJsZVxuXHR9ID0gYXdhaXQgY2hlY2sob3B0cyk7XG5cblx0aWYgKHVwZGF0ZUF2YWlsYWJsZSkge1xuXHRcdGNvbnN0IG1zZyA9IGBVcGRhdGUgYXZhaWxhYmxlICR7Z3JheShjdXJyZW50KX0g4oaSICR7Z3JlZW4obGF0ZXN0KX1cXG5SdW4gJHtjeWFuKGBucG0gaSAtZyAke25hbWV9YCl9IHRvIHVwZGF0ZWA7XG5cdFx0cmV0dXJuIGJveGVuKG1zZywge1xuXHRcdFx0YWxpZ246ICdjZW50ZXInLFxuXHRcdFx0Ym9yZGVyQ29sb3I6ICd5ZWxsb3cnLFxuXHRcdFx0Ym9yZGVyU3R5bGU6ICdyb3VuZCcsXG5cdFx0XHRtYXJnaW46IHsgYm90dG9tOiAxLCBsZWZ0OiA0LCByaWdodDogNCwgdG9wOiAxIH0sXG5cdFx0XHRwYWRkaW5nOiB7IGJvdHRvbTogMSwgbGVmdDogNCwgcmlnaHQ6IDQsIHRvcDogMSB9XG5cdFx0fSk7XG5cdH1cbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgdGFibGUgd2l0aCBkZWZhdWx0IHN0eWxlcyBhbmQgcGFkZGluZy5cbiAqXG4gKiBAcGFyYW0ge0FycmF5LjxTdHJpbmc+fSBoZWFkIC0gT25lIG9yIG1vcmUgaGVhZGluZ3MuXG4gKiBAcGFyYW0ge051bWJlcn0gW2luZGVudF0gLSBUaGUgbnVtYmVyIG9mIHNwYWNlcyB0byBpbmRlbnQgdGhlIHRhYmxlLlxuICogQHJldHVybnMge1RhYmxlfVxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlVGFibGUoaGVhZCwgaW5kZW50ID0gMCkge1xuXHRyZXR1cm4gbmV3IFRhYmxlKHtcblx0XHRjaGFyczoge1xuXHRcdFx0Ym90dG9tOiAnJywgJ2JvdHRvbS1sZWZ0JzogJycsICdib3R0b20tbWlkJzogJycsICdib3R0b20tcmlnaHQnOiAnJyxcblx0XHRcdGxlZnQ6ICcgJy5yZXBlYXQoaW5kZW50KSwgJ2xlZnQtbWlkJzogJycsXG5cdFx0XHRtaWQ6ICcnLCAnbWlkLW1pZCc6ICcnLCBtaWRkbGU6ICcgICcsXG5cdFx0XHRyaWdodDogJycsICdyaWdodC1taWQnOiAnJyxcblx0XHRcdHRvcDogJycsICd0b3AtbGVmdCc6ICcnLCAndG9wLW1pZCc6ICcnLCAndG9wLXJpZ2h0JzogJydcblx0XHR9LFxuXHRcdGhlYWQ6IEFycmF5LmlzQXJyYXkoaGVhZCkgPyBoZWFkLm1hcChhbnNpLnRvVXBwZXJDYXNlKSA6IGhlYWQsXG5cdFx0c3R5bGU6IHtcblx0XHRcdGJvcmRlcjogW10sXG5cdFx0XHRoZWFkOiBbXSxcblx0XHRcdCdwYWRkaW5nLWxlZnQnOiAwLFxuXHRcdFx0J3BhZGRpbmctcmlnaHQnOiAwXG5cdFx0fVxuXHR9KTtcbn1cblxuLyoqXG4gKiBSZXNvdmxlcyB0aGUgXCJhdXRoLipcIiBjb25maWcga2V5IGJhc2VkIG9uIHlvdXIgZW52aXJvbm1lbnQuIFRoaXMgaXMgdXNlZCB0byBnZXQgb3Igc2V0IHRoZVxuICogZGVmYXVsdCBhY2NvdW50IGFuZCBvcmcuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGVudiAtIFRoZSByZXNvbHZlZCBlbnZpcm9ubWVudCBuYW1lLlxuICogQHJldHVybnMge1N0cmluZ31cbiAqXG4gKiBAZXhhbXBsZVxuICogICBhd2FpdCBjb25maWcuZ2V0KGAke2dldEF1dGhDb25maWdFbnZTcGVjaWZpZXIoc2RrLmVudi5uYW1lKX0uZGVmYXVsdEFjY291bnRgKTtcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEF1dGhDb25maWdFbnZTcGVjaWZpZXIoZW52KSB7XG5cdHJldHVybiAhZW52IHx8IGVudiA9PT0gJ3Byb2QnID8gJ2F1dGgnIDogYGF1dGguZW52aXJvbm1lbnQuJHtlbnZ9YDtcbn1cblxuLyoqXG4gKiBIaWdobGlnaHRzIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gdHdvIHZlcnNpb25zLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSB0b1ZlciAtIFRoZSBsYXRlc3QgdmVyc2lvbi5cbiAqIEBwYXJhbSB7U3RyaW5nfSBmcm9tVmVyIC0gVGhlIGN1cnJlbnQgdmVyc2lvbi5cbiAqIEByZXR1cm5zIHtTdHJpbmd9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBobFZlcih0b1ZlciwgZnJvbVZlcikge1xuXHRjb25zdCB7IGdyZWVuIH0gPSBzbm9vcGxvZ2cuc3R5bGVzO1xuXHRjb25zdCB2ZXJzaW9uID0gW107XG5cblx0bGV0IFsgZnJvbSwgZnJvbVRhZyBdID0gZnJvbVZlci5zcGxpdCgvLSguKykvKTtcblx0ZnJvbSA9IGZyb20ucmVwbGFjZSgvW14uXFxkXS9nLCAnJykuc3BsaXQoJy4nKS5tYXAoeCA9PiBwYXJzZUludCh4KSk7XG5cblx0bGV0IFsgdG8sIHRvVGFnIF0gPSB0b1Zlci5zcGxpdCgvLSguKykvKTtcblx0Y29uc3QgdG9NYXRjaCA9IHRvLm1hdGNoKC9eKFteXFxkXSspPyguKykkLyk7XG5cdHRvID0gKHRvTWF0Y2ggPyB0b01hdGNoWzJdIDogdG8pLnNwbGl0KCcuJykubWFwKHggPT4gcGFyc2VJbnQoeCkpO1xuXG5cdGNvbnN0IHRhZyA9ICgpID0+IHtcblx0XHRpZiAodG9UYWcpIHtcblx0XHRcdGNvbnN0IHRvTnVtID0gdG9UYWcubWF0Y2goL1xcZCskLyk7XG5cdFx0XHRjb25zdCBmcm9tTnVtID0gZnJvbVRhZyAmJiBmcm9tVGFnLm1hdGNoKC9cXGQrJC8pO1xuXHRcdFx0aWYgKGZyb21OdW0gJiYgcGFyc2VJbnQoZnJvbU51bVswXSkgPj0gcGFyc2VJbnQodG9OdW0pKSB7XG5cdFx0XHRcdHJldHVybiBgLSR7dG9UYWd9YDtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHJldHVybiBncmVlbihgLSR7dG9UYWd9YCk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiAnJztcblx0fTtcblxuXHR3aGlsZSAodG8ubGVuZ3RoKSB7XG5cdFx0aWYgKHRvWzBdID4gZnJvbVswXSkge1xuXHRcdFx0aWYgKHZlcnNpb24ubGVuZ3RoKSB7XG5cdFx0XHRcdHJldHVybiAodG9NYXRjaCAmJiB0b01hdGNoWzFdIHx8ICcnKSArIHZlcnNpb24uY29uY2F0KGdyZWVuKHRvLmpvaW4oJy4nKSArIHRhZygpKSkuam9pbignLicpO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIGdyZWVuKCh0b01hdGNoICYmIHRvTWF0Y2hbMV0gfHwgJycpICsgdG8uam9pbignLicpICsgdGFnKCkpO1xuXHRcdH1cblx0XHR2ZXJzaW9uLnB1c2godG8uc2hpZnQoKSk7XG5cdFx0ZnJvbS5zaGlmdCgpO1xuXHR9XG5cblx0cmV0dXJuICh0b01hdGNoICYmIHRvTWF0Y2hbMV0gfHwgJycpICsgdmVyc2lvbi5qb2luKCcuJykgKyB0YWcoKTtcbn1cblxuLyoqXG4gKiBJbml0aWFsaXplcyB0aGUgQW1wbGlmeSBTREssIGxvYWRzIGFuIGFjY291bnQsIGFuZCBmaW5kcyB0aGUgZGVmYXVsdCBvcmcgaWQuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IFthY2NvdW50TmFtZV0gLSBUaGUgbmFtZSBvZiB0aGUgcGxhdGZvcm0gYWNjb3VudCB0byB1c2UuXG4gKiBAcGFyYW0ge1N0cmluZ30gW29yZ10gLSBUaGUgbmFtZSwgaWQsIG9yIGd1aWQgb2YgdGhlIGRlZmF1bHQgb3JnYW5pemF0aW9uLlxuICogQHBhcmFtIHtTdHJpbmd9IFtlbnZdIC0gVGhlIGVudmlyb25tZW50IG5hbWUuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtieXBhc3NQbGF0Zm9ybUFjY291bnRDaGVja10gLSBPcHRpb25hbCBwYXJhbWV0ZXIgdG8gYnlwYXNzIGNoZWNrIGlmIHRoZSBhY2NvdW50IGlzIHBsYXRmb3JtXG4gKiBAcmV0dXJucyB7UHJvbWlzZTxPYmplY3Q+fVxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaW5pdFBsYXRmb3JtQWNjb3VudChhY2NvdW50TmFtZSwgb3JnLCBlbnYsIGJ5cGFzc1BsYXRmb3JtQWNjb3VudENoZWNrID0gZmFsc2UpIHtcblx0Y29uc3QgeyBjb25maWcsIHNkayB9ID0gYXdhaXQgaW5pdFNESyh7IGVudiB9KTtcblx0Y29uc3QgYXV0aENvbmZpZ0VudlNwZWNpZmllciA9IGdldEF1dGhDb25maWdFbnZTcGVjaWZpZXIoc2RrLmVudi5uYW1lKTtcblx0Y29uc3QgYWNjb3VudCA9IGF3YWl0IHNkay5hdXRoLmZpbmQoYWNjb3VudE5hbWUgfHwgYXdhaXQgY29uZmlnLmdldChgJHthdXRoQ29uZmlnRW52U3BlY2lmaWVyfS5kZWZhdWx0QWNjb3VudGApKTtcblxuXHRpZiAoYWNjb3VudE5hbWUpIHtcblx0XHRpZiAoIWFjY291bnQpIHtcblx0XHRcdHRocm93IG5ldyBFcnJvcihgQWNjb3VudCBcIiR7YWNjb3VudE5hbWV9XCIgbm90IGZvdW5kYCk7XG5cdFx0fSBlbHNlIGlmICghYnlwYXNzUGxhdGZvcm1BY2NvdW50Q2hlY2sgJiYgIWFjY291bnQuaXNQbGF0Zm9ybSkge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKGBBY2NvdW50IFwiJHthY2NvdW50TmFtZX1cIiBpcyBub3QgYSBwbGF0Zm9ybSBhY2NvdW50XFxuXFxuVG8gbG9naW4sIHJ1bjogYXh3YXkgYXV0aCBsb2dpbmApO1xuXHRcdH1cblx0fSBlbHNlIGlmICghYWNjb3VudCB8fCAoIWJ5cGFzc1BsYXRmb3JtQWNjb3VudENoZWNrICYmICFhY2NvdW50LmlzUGxhdGZvcm0pKSB7XG5cdFx0dGhyb3cgbmV3IEVycm9yKCdZb3UgbXVzdCBiZSBsb2dnZWQgaW50byBhIHBsYXRmb3JtIGFjY291bnRcXG5cXG5UbyBsb2dpbiwgcnVuOiBheHdheSBhdXRoIGxvZ2luJyk7XG5cdH1cblxuXHRpZiAob3JnKSB7XG5cdFx0b3JnID0gYXdhaXQgc2RrLm9yZy5maW5kKGFjY291bnQsIG9yZyk7XG5cdH0gZWxzZSB7XG5cdFx0dHJ5IHtcblx0XHRcdC8vIGNoZWNrIHRoZSBjb25maWcgZm9yIGEgZGVmYXVsdCBvcmcgZm9yIHRoaXMgYWNjb3VudFxuXHRcdFx0b3JnID0gYXdhaXQgc2RrLm9yZy5maW5kKGFjY291bnQsIGF3YWl0IGNvbmZpZy5nZXQoYCR7YXV0aENvbmZpZ0VudlNwZWNpZmllcn0uZGVmYXVsdE9yZy4ke2FjY291bnQuaGFzaH1gKSk7XG5cdFx0fSBjYXRjaCAoZXJyKSB7XG5cdFx0XHQvLyBkZWZhdWx0IG9yZyB3YXMgc3RhbGUsIGF1dG8gZGV0ZWN0IHRoZSBkZWZhdWx0IGZyb20gdGhlIGFjY291bnQgb3Jnc1xuXHRcdFx0b3JnID0gYXdhaXQgc2RrLm9yZy5maW5kKGFjY291bnQpO1xuXHRcdH1cblx0fVxuXG5cdHJldHVybiB7XG5cdFx0YWNjb3VudCxcblx0XHRjb25maWcsXG5cdFx0b3JnLFxuXHRcdHNka1xuXHR9O1xufVxuXG4vKipcbiAqIExvYWRzIHRoZSBjb25maWcgYW5kIGNyZWF0ZXMgYW4gQW1wbGlmeSBTREsgb2JqZWN0LCB0aGVuIHJldHVybnMgYm90aCBvZiB0aGVtLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0c10gLSBTREsgb3B0aW9ucyBpbmNsdWRpbmcgYGVudmAgYW5kIGF1dGggb3B0aW9ucy5cbiAqIEBwYXJhbSB7T2JqZWN0fSBbY29uZmlnXSAtIFRoZSBBbXBsaWZ5IGF3YWl0IGNvbmZpZy4gSWYgbm90IHBhc3NlZCBpbiwgdGhlIGNvbmZpZyBmaWxlIGlzIGxvYWRlZC5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYW4gb2JqZWN0IGNvbnRhaW5pbmcgdGhlIEF4d2F5IENMSSBjb25maWcgYW5kIGFuIGluaXRpYWxpemVkXG4gKiBBbXBsaWZ5IFNESyBpbnN0YW5jZS5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGluaXRTREsob3B0cyA9IHt9LCBjb25maWcpIHtcblx0aWYgKCFjb25maWcpIHtcblx0XHRjb25maWcgPSBhd2FpdCBsb2FkQ29uZmlnKCk7XG5cdH1cblx0cmV0dXJuIHtcblx0XHRjb25maWcsXG5cdFx0c2RrOiBuZXcgQW1wbGlmeVNESyhhd2FpdCBidWlsZEF1dGhQYXJhbXMob3B0cywgY29uZmlnKSlcblx0fTtcbn1cblxuLyoqXG4gKiBEZXRlY3RzIGlmIHRoZSBjdXJyZW50IHRlcm1pbmFsIGlzIGhlYWRsZXNzIChlLmcuIGEgRG9ja2VyIGNvbnRhaW5lciBvciBTU0ggc2Vzc2lvbikuXG4gKlxuICogQHJldHVybnMge0Jvb2xlYW59XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0hlYWRsZXNzKCkge1xuXHR0cnkge1xuXHRcdGlmIChwcm9jZXNzLnBsYXRmb3JtID09PSAnbGludXgnICYmIChwcm9jZXNzLmVudi5TU0hfVFRZIHx8ICFwcm9jZXNzLmVudi5ESVNQTEFZIHx8IC9kb2NrZXJ8bHhjLy50ZXN0KGZzLnJlYWRGaWxlU3luYygnL3Byb2MvMS9jZ3JvdXAnLCAndXRmOCcpKSkpIHtcblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH1cblx0XHRpZiAocHJvY2Vzcy5wbGF0Zm9ybSA9PT0gJ2RhcndpbicgJiYgcHJvY2Vzcy5lbnYuU1NIX1RUWSkge1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXHR9IGNhdGNoIChlKSB7XG5cdFx0Ly8gZG8gbm90aGluZ1xuXHR9XG5cblx0cmV0dXJuIGZhbHNlO1xufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7O0FBTUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7Ozs7Ozs7Ozs7QUFqQkE7QUFDQSxJQUFJLENBQUNBLEtBQUssQ0FBQ0MsaUJBQVgsRUFBOEI7RUFDN0JDLDBCQUFpQkMsT0FBakI7QUFDQTs7QUE4QkQsTUFBTTtFQUFFQztBQUFGLElBQVcsd0JBQVUsbUJBQVYsQ0FBakI7QUFDQSxNQUFNO0VBQUVDLElBQUY7RUFBUUMsSUFBUjtFQUFjQztBQUFkLElBQXdCQyxtQkFBVUMsS0FBeEM7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFDTyxlQUFlQyxlQUFmLENBQStCQyxJQUFJLEdBQUcsRUFBdEMsRUFBMENDLE1BQTFDLEVBQWtEO0VBQ3hELElBQUksQ0FBQ0QsSUFBRCxJQUFTLE9BQU9BLElBQVAsS0FBZ0IsUUFBN0IsRUFBdUM7SUFDdEMsTUFBTSxJQUFJWCxLQUFKLENBQVUsa0NBQVYsQ0FBTjtFQUNBOztFQUVELElBQUksQ0FBQ1ksTUFBTCxFQUFhO0lBQ1pBLE1BQU0sR0FBRyxNQUFNLDZCQUFmO0VBQ0E7O0VBRUQsTUFBTUMsR0FBRyxHQUFHQyxZQUFZLENBQUNDLE9BQWIsQ0FBcUJKLElBQUksQ0FBQ0UsR0FBTCxLQUFZLE1BQU1ELE1BQU0sQ0FBQ0ksR0FBUCxDQUFXLEtBQVgsQ0FBbEIsQ0FBckIsQ0FBWjtFQUVBLE1BQU07SUFBRUMsUUFBRjtJQUFZQztFQUFaLElBQXNCTCxH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