UNPKG

@adobe/ccweb-add-on-devcert

Version:

Generate trusted local SSL/TLS certificates for local SSL development

107 lines 17.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ensureConfigDirs = exports.getLegacyConfigDir = exports.rootCACertPath = exports.rootCAKeyPath = exports.rootCADir = exports.withDomainCertificateConfig = exports.withDomainSigningRequestConfig = exports.caSelfSignConfig = exports.opensslDatabaseFilePath = exports.opensslSerialFilePath = exports.caVersionFile = exports.pathForDomain = exports.domainsDir = exports.getStableDomainPath = exports.configPath = exports.configDir = exports.isWindows = exports.isLinux = exports.isMac = void 0; const tslib_1 = require("tslib"); const path_1 = tslib_1.__importDefault(require("path")); const fs_1 = require("fs"); const mkdirp_1 = require("mkdirp"); const lodash_1 = require("lodash"); const applicationConfigPath = require("application-config-path"); const eol_1 = tslib_1.__importDefault(require("eol")); const utils_1 = require("./utils"); // Platform shortcuts exports.isMac = process.platform === 'darwin'; exports.isLinux = process.platform === 'linux'; exports.isWindows = process.platform === 'win32'; // Common paths exports.configDir = applicationConfigPath(path_1.default.join('Adobe', 'CCWebAddOn', 'devcert')); exports.configPath = path_1.default.join.bind(path_1.default, exports.configDir); const getFilteredDomains = (domains) => Array.from(domains .sort((a, b) => b.length - a.length) .reduce((filteredList, domain) => Array.from(filteredList) .reduce((matches, item) => { if (item.indexOf(domain) > -1) { matches.add(domain); } else if (domain.indexOf(item) === -1 && item.indexOf(domain) === -1) { matches.add(item); matches.add(domain); } else { matches.add(item); } return matches; }, new Set()), new Set([domains[0]]))).sort(); const getStableDomainPath = (domains) => domains.length === 1 ? domains[0] : 'san-' + utils_1.numericHash(getFilteredDomains(domains).join('')); exports.getStableDomainPath = getStableDomainPath; exports.domainsDir = exports.configPath('domains'); exports.pathForDomain = path_1.default.join.bind(path_1.default, exports.domainsDir); exports.caVersionFile = exports.configPath('devcert-ca-version'); exports.opensslSerialFilePath = exports.configPath('certificate-authority', 'serial'); exports.opensslDatabaseFilePath = exports.configPath('certificate-authority', 'index.txt'); exports.caSelfSignConfig = path_1.default.join(__dirname, '../openssl-configurations/certificate-authority-self-signing.conf'); function generateSubjectAltNames(domains) { return domains .reduce((dnsEntries, domain) => dnsEntries.concat([ `DNS.${dnsEntries.length + 1} = ${domain}`, `DNS.${dnsEntries.length + 2} = *.${domain}`, ]), []) .join("\r\n"); } function withDomainSigningRequestConfig(domains, cb) { const domain = domains[0]; const subjectAltNames = generateSubjectAltNames(domains); let tmpFile = utils_1.mktmp(); let source = fs_1.readFileSync(path_1.default.join(__dirname, '../openssl-configurations/domain-certificate-signing-requests.conf'), 'utf-8'); let template = lodash_1.template(source); let result = template({ domain, subjectAltNames }); fs_1.writeFileSync(tmpFile, eol_1.default.auto(result)); cb(tmpFile); fs_1.unlinkSync(tmpFile); } exports.withDomainSigningRequestConfig = withDomainSigningRequestConfig; function withDomainCertificateConfig(domains, cb) { const domainPath = exports.getStableDomainPath(domains); const subjectAltNames = generateSubjectAltNames(domains); let tmpFile = utils_1.mktmp(); let source = fs_1.readFileSync(path_1.default.join(__dirname, '../openssl-configurations/domain-certificates.conf'), 'utf-8'); let template = lodash_1.template(source); let result = template({ subjectAltNames, serialFile: exports.opensslSerialFilePath, databaseFile: exports.opensslDatabaseFilePath, domainDir: exports.pathForDomain(domainPath) }); fs_1.writeFileSync(tmpFile, eol_1.default.auto(result)); cb(tmpFile); fs_1.unlinkSync(tmpFile); } exports.withDomainCertificateConfig = withDomainCertificateConfig; // confTemplate = confTemplate.replace(/DATABASE_PATH/, configPath('index.txt').replace(/\\/g, '\\\\')); // confTemplate = confTemplate.replace(/SERIAL_PATH/, configPath('serial').replace(/\\/g, '\\\\')); // confTemplate = eol.auto(confTemplate); exports.rootCADir = exports.configPath('certificate-authority'); exports.rootCAKeyPath = exports.configPath('certificate-authority', 'private-key.key'); exports.rootCACertPath = exports.configPath('certificate-authority', 'certificate.cert'); // Exposed for uninstallation purposes. function getLegacyConfigDir() { if (exports.isWindows && process.env.LOCALAPPDATA) { return path_1.default.join(process.env.LOCALAPPDATA, 'devcert', 'config'); } else { let uid = process.getuid && process.getuid(); let userHome = (exports.isLinux && uid === 0) ? path_1.default.resolve('/usr/local/share') : require('os').homedir(); return path_1.default.join(userHome, '.config', 'devcert'); } } exports.getLegacyConfigDir = getLegacyConfigDir; function ensureConfigDirs() { mkdirp_1.sync(exports.configDir); mkdirp_1.sync(exports.domainsDir); mkdirp_1.sync(exports.rootCADir); } exports.ensureConfigDirs = ensureConfigDirs; ensureConfigDirs(); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uc3RhbnRzLmpzIiwic291cmNlUm9vdCI6Ii4vIiwic291cmNlcyI6WyJjb25zdGFudHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLHdEQUF3QjtBQUN4QiwyQkFBNEY7QUFDNUYsbUNBQXdDO0FBQ3hDLG1DQUFrRDtBQUNsRCxpRUFBa0U7QUFDbEUsc0RBQXNCO0FBQ3RCLG1DQUEyQztBQUUzQyxxQkFBcUI7QUFDUixRQUFBLEtBQUssR0FBRyxPQUFPLENBQUMsUUFBUSxLQUFLLFFBQVEsQ0FBQztBQUN0QyxRQUFBLE9BQU8sR0FBRyxPQUFPLENBQUMsUUFBUSxLQUFLLE9BQU8sQ0FBQztBQUN2QyxRQUFBLFNBQVMsR0FBRyxPQUFPLENBQUMsUUFBUSxLQUFLLE9BQU8sQ0FBQztBQUV0RCxlQUFlO0FBQ0YsUUFBQSxTQUFTLEdBQUcscUJBQXFCLENBQUMsY0FBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsWUFBWSxFQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUM7QUFDL0UsUUFBQSxVQUFVLEdBQTBDLGNBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGNBQUksRUFBRSxpQkFBUyxDQUFDLENBQUM7QUFFakcsTUFBTSxrQkFBa0IsR0FBRyxDQUFDLE9BQWlCLEVBQUUsRUFBRSxDQUMvQyxLQUFLLENBQUMsSUFBSSxDQUNSLE9BQU87S0FDSixJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUM7S0FDbkMsTUFBTSxDQUFDLENBQUMsWUFBWSxFQUFFLE1BQU0sRUFBRSxFQUFFLENBQy9CLEtBQUssQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDO0tBQ3JCLE1BQU0sQ0FBQyxDQUFDLE9BQU8sRUFBRSxJQUFJLEVBQUUsRUFBRTtJQUN4QixJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUU7UUFD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SUFBSSxPQUFPLENBQUMsR0FBRyxDQUFDLFlBQVksRUFBRTtRQUN6QyxPQUFPLGNBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxZQUFZLEVBQUUsU0FBUyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0tBQ2pFO1NBQU07UUFDTCxJQUFJLEdBQUcsR0FBRyxPQUFPLENBQUMsTUFBTSxJQUFJLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUM3QyxJQUFJLFFBQVEsR0FBRyxDQUFDLGVBQU8sSUFBSSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLGNBQUksQ0FBQyxPQUFPLENBQUMsa0JBQWtCLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ25HLE9BQU8sY0FBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsU0FBUyxFQUFFLFNBQVMsQ0FBQyxDQUFDO0tBQ2xEO0FBQ0gsQ0FBQztBQVJELGdEQVFDO0FBRUQsU0FBZ0IsZ0JBQWdCO0lBQzlCLGFBQU0sQ0FBQyxpQkFBUyxDQUFDLENBQUM7SUFDbEIsYUFBTSxDQUFDLGtCQUFVLENBQUMsQ0FBQztJQUNuQixhQUFNLENBQUMsaUJBQVMsQ0FBQyxDQUFDO0FBQ3BCLENBQUM7QUFKRCw0Q0FJQztBQUVELGdCQUFnQixFQUFFLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCB7IHVubGlua1N5bmMgYXMgcm0sIHdyaXRlRmlsZVN5bmMgYXMgd3JpdGVGaWxlLCByZWFkRmlsZVN5bmMgYXMgcmVhZEZpbGUgfSBmcm9tICdmcyc7XG5pbXBvcnQgeyBzeW5jIGFzIG1rZGlycCB9IGZyb20gJ21rZGlycCc7XG5pbXBvcnQgeyB0ZW1wbGF0ZSBhcyBtYWtlVGVtcGxhdGUgfSBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IGFwcGxpY2F0aW9uQ29uZmlnUGF0aCA9IHJlcXVpcmUoJ2FwcGxpY2F0aW9uLWNvbmZpZy1wYXRoJyk7XG5pbXBvcnQgZW9sIGZyb20gJ2VvbCc7XG5pbXBvcnQge21rdG1wLCBudW1lcmljSGFzaH0gZnJvbSAnLi91dGlscyc7XG5cbi8vIFBsYXRmb3JtIHNob3J0Y3V0c1xuZXhwb3J0IGNvbnN0IGlzTWFjID0gcHJvY2Vzcy5wbGF0Zm9ybSA9PT0gJ2Rhcndpbic7XG5leHBvcnQgY29uc3QgaXNMaW51eCA9IHByb2Nlc3MucGxhdGZvcm0gPT09ICdsaW51eCc7XG5leHBvcnQgY29uc3QgaXNXaW5kb3dzID0gcHJvY2Vzcy5wbGF0Zm9ybSA9PT0gJ3dpbjMyJztcblxuLy8gQ29tbW9uIHBhdGhzXG5leHBvcnQgY29uc3QgY29uZmlnRGlyID0gYXBwbGljYXRpb25Db25maWdQYXRoKHBhdGguam9pbignQWRvYmUnLCAnQ0NXZWJBZGRPbicsICdkZXZjZXJ0JykpO1xuZXhwb3J0IGNvbnN0IGNvbmZpZ1BhdGg6ICguLi5wYXRoU2VnbWVudHM6IHN0cmluZ1tdKSA9PiBzdHJpbmcgPSBwYXRoLmpvaW4uYmluZChwYXRoLCBjb25maWdEaXIpO1xuXG5jb25zdCBnZXRGaWx0ZXJlZERvbWFpbnMgPSAoZG9tYWluczogc3RyaW5nW10pID0+XG4gIEFycmF5LmZyb20oXG4gICAgZG9tYWluc1xuICAgICAgLnNvcnQoKGEsIGIpID0+IGIubGVuZ3RoIC0gYS5sZW5ndGgpXG4gICAgICAucmVkdWNlKChmaWx0ZXJlZExpc3QsIGRvbWFpbikgPT5cbiAgICAgICAgQXJyYXkuZnJvbShmaWx0ZXJlZExpc3QpXG4gICAgICAgICAgLnJlZHVjZSgobWF0Y2hlcywgaXRlbSkgPT4ge1xuICAgICAgICAgICAgaWYgKGl0ZW0uaW5kZXhPZihkb21haW4pID4gLTEpIHtcbiAgICAgICAgICAgICAgbWF0Y2hlcy5hZGQoZG9tYWluKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoZG9tYWluLmluZGV4T2YoaXRlbSkgPT09IC0xICYmIGl0ZW0uaW5kZXhPZihkb21haW4pID09PSAtMSkge1xuICAgICAgICAgICAgICBtYXRjaGVzLmFkZChpdGVtKTtcbiAgICAgICAgICAgICAgbWF0Y2hlcy5hZGQoZG9tYWluKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIG1hdGNoZXMuYWRkKGl0ZW0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gbWF0Y2hlcztcbiAgICAgICAgICB9LCBuZXcgU2V0KClcbiAgICAgICAgICApLCBuZXcgU2V0KFtkb21haW5zWzBdXSlcbiAgICAgIClcbiAgKS5zb3J0KCk7XG5cbmV4cG9ydCBjb25zdCBnZXRTdGFibGVEb21haW5QYXRoID0gKGRvbWFpbnM6IHN0cmluZ1tdKSA9PlxuICBkb21haW5zLmxlbmd0aCA9PT0gMSA/XG4gICAgZG9tYWluc1swXSA6XG4gICAgJ3Nhbi0nICsgbnVtZXJpY0hhc2goZ2V0RmlsdGVyZWREb21haW5zKGRvbWFpbnMpLmpvaW4oJycpKTtcbmV4cG9ydCBjb25zdCBkb21haW5zRGlyID0gY29uZmlnUGF0aCgnZG9tYWlucycpO1xuZXhwb3J0IGNvbnN0IHBhdGhGb3JEb21haW46IChkb21haW46IHN0cmluZywgLi4ucGF0aFNlZ21lbnRzOiBzdHJpbmdbXSkgPT4gc3RyaW5nID0gcGF0aC5qb2luLmJpbmQocGF0aCwgZG9tYWluc0RpcilcblxuZXhwb3J0IGNvbnN0IGNhVmVyc2lvbkZpbGUgPSBjb25maWdQYXRoKCdkZXZjZXJ0LWNhLXZlcnNpb24nKTtcbmV4cG9ydCBjb25zdCBvcGVuc3NsU2VyaWFsRmlsZVBhdGggPSBjb25maWdQYXRoKCdjZXJ0aWZpY2F0ZS1hdXRob3JpdHknLCAnc2VyaWFsJyk7XG5leHBvcnQgY29uc3Qgb3BlbnNzbERhdGFiYXNlRmlsZVBhdGggPSBjb25maWdQYXRoKCdjZXJ0aWZpY2F0ZS1hdXRob3JpdHknLCAnaW5kZXgudHh0Jyk7XG5leHBvcnQgY29uc3QgY2FTZWxmU2lnbkNvbmZpZyA9IHBhdGguam9pbihfX2Rpcm5hbWUsICcuLi9vcGVuc3NsLWNvbmZpZ3VyYXRpb25zL2NlcnRpZmljYXRlLWF1dGhvcml0eS1zZWxmLXNpZ25pbmcuY29uZicpO1xuXG5mdW5jdGlvbiBnZW5lcmF0ZVN1YmplY3RBbHROYW1lcyhkb21haW5zOiBzdHJpbmdbXSk6IHN0cmluZyB7XG4gIHJldHVybiBkb21haW5zXG4gICAgLnJlZHVjZSgoZG5zRW50cmllcywgZG9tYWluKSA9PlxuICAgICAgZG5zRW50cmllcy5jb25jYXQoW1xuICAgICAgICBgRE5TLiR7ZG5zRW50cmllcy5sZW5ndGggKyAxfSA9ICR7ZG9tYWlufWAsXG4gICAgICAgIGBETlMuJHtkbnNFbnRyaWVzLmxlbmd0aCArIDJ9ID0gKi4ke2RvbWFpbn1gLFxuICAgICAgXSksIFtdIGFzIHN0cmluZ1tdKVxuICAgIC5qb2luKFwiXFxyXFxuXCIpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gd2l0aERvbWFpblNpZ25pbmdSZXF1ZXN0Q29uZmlnKGRvbWFpbnM6IHN0cmluZ1tdLCBjYjogKGZpbGVwYXRoOiBzdHJpbmcpID0+IHZvaWQpIHtcbiAgY29uc3QgZG9tYWluID0gZG9tYWluc1swXTtcbiAgY29uc3Qgc3ViamVjdEFsdE5hbWVzID0gZ2VuZXJhdGVTdWJqZWN0QWx0TmFtZXMoZG9tYWlucyk7XG4gIGxldCB0bXBGaWxlID0gbWt0bXAoKTtcbiAgbGV0IHNvdXJjZSA9IHJlYWRGaWxlKHBhdGguam9pbihfX2Rpcm5hbWUsICcuLi9vcGVuc3NsLWNvbmZpZ3VyYXRpb25zL2RvbWFpbi1jZXJ0aWZpY2F0ZS1zaWduaW5nLXJlcXVlc3RzLmNvbmYnKSwgJ3V0Zi04Jyk7XG4gIGxldCB0ZW1wbGF0ZSA9IG1ha2VUZW1wbGF0ZShzb3VyY2UpO1xuICBsZXQgcmVzdWx0ID0gdGVtcGxhdGUoe2RvbWFpbiwgc3ViamVjdEFsdE5hbWVzfSk7XG4gIHdyaXRlRmlsZSh0bXBGaWxlLCBlb2wuYXV0byhyZXN1bHQpKTtcbiAgY2IodG1wRmlsZSk7XG4gIHJtKHRtcEZpbGUpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gd2l0aERvbWFpbkNlcnRpZmljYXRlQ29uZmlnKGRvbWFpbnM6IHN0cmluZ1tdLCBjYjogKGZpbGVwYXRoOiBzdHJpbmcpID0+IHZvaWQpIHtcbiAgY29uc3QgZG9tYWluUGF0aCA9IGdldFN0YWJsZURvbWFpblBhdGgoZG9tYWlucyk7XG4gIGNvbnN0IHN1YmplY3RBbHROYW1lcyA9IGdlbmVyYXRlU3ViamVjdEFsdE5hbWVzKGRvbWFpbnMpO1xuICBsZXQgdG1wRmlsZSA9IG1rdG1wKCk7XG4gIGxldCBzb3VyY2UgPSByZWFkRmlsZShwYXRoLmpvaW4oX19kaXJuYW1lLCAnLi4vb3BlbnNzbC1jb25maWd1cmF0aW9ucy9kb21haW4tY2VydGlmaWNhdGVzLmNvbmYnKSwgJ3V0Zi04Jyk7XG4gIGxldCB0ZW1wbGF0ZSA9IG1ha2VUZW1wbGF0ZShzb3VyY2UpO1xuICBsZXQgcmVzdWx0ID0gdGVtcGxhdGUoe1xuICAgIHN1YmplY3RBbHROYW1lcyxcbiAgICBzZXJpYWxGaWxlOiBvcGVuc3NsU2VyaWFsRmlsZVBhdGgsXG4gICAgZGF0YWJhc2VGaWxlOiBvcGVuc3NsRGF0YWJhc2VGaWxlUGF0aCxcbiAgICBkb21haW5EaXI6IHBhdGhGb3JEb21haW4oZG9tYWluUGF0aClcbiAgfSk7XG4gIHdyaXRlRmlsZSh0bXBGaWxlLCBlb2wuYXV0byhyZXN1bHQpKTtcbiAgY2IodG1wRmlsZSk7XG4gIHJtKHRtcEZpbGUpO1xufVxuXG4gIC8vIGNvbmZUZW1wbGF0ZSA9IGNvbmZUZW1wbGF0ZS5yZXBsYWNlKC9EQVRBQkFTRV9QQVRILywgY29uZmlnUGF0aCgnaW5kZXgudHh0JykucmVwbGFjZSgvXFxcXC9nLCAnXFxcXFxcXFwnKSk7XG4gIC8vIGNvbmZUZW1wbGF0ZSA9IGNvbmZUZW1wbGF0ZS5yZXBsYWNlKC9TRVJJQUxfUEFUSC8sIGNvbmZpZ1BhdGgoJ3NlcmlhbCcpLnJlcGxhY2UoL1xcXFwvZywgJ1xcXFxcXFxcJykpO1xuICAvLyBjb25mVGVtcGxhdGUgPSBlb2wuYXV0byhjb25mVGVtcGxhdGUpO1xuXG5leHBvcnQgY29uc3Qgcm9vdENBRGlyID0gY29uZmlnUGF0aCgnY2VydGlmaWNhdGUtYXV0aG9yaXR5Jyk7XG5leHBvcnQgY29uc3Qgcm9vdENBS2V5UGF0aCA9IGNvbmZpZ1BhdGgoJ2NlcnRpZmljYXRlLWF1dGhvcml0eScsICdwcml2YXRlLWtleS5rZXknKTtcbmV4cG9ydCBjb25zdCByb290Q0FDZXJ0UGF0aCA9IGNvbmZpZ1BhdGgoJ2NlcnRpZmljYXRlLWF1dGhvcml0eScsICdjZXJ0aWZpY2F0ZS5jZXJ0Jyk7XG5cblxuXG4vLyBFeHBvc2VkIGZvciB1bmluc3RhbGxhdGlvbiBwdXJwb3Nlcy5cbmV4cG9ydCBmdW5jdGlvbiBnZXRMZWdhY3lDb25maWdEaXIoKTogc3RyaW5nIHtcbiAgaWYgKGlzV2luZG93cyAmJiBwcm9jZXNzLmVudi5MT0NBTEFQUERBVEEpIHtcbiAgICByZXR1cm4gcGF0aC5qb2luKHByb2Nlc3MuZW52LkxPQ0FMQVBQREFUQSwgJ2RldmNlcnQnLCAnY29uZmlnJyk7XG4gIH0gZWxzZSB7XG4gICAgbGV0IHVpZCA9IHByb2Nlc3MuZ2V0dWlkICYmIHByb2Nlc3MuZ2V0dWlkKCk7XG4gICAgbGV0IHVzZXJIb21lID0gKGlzTGludXggJiYgdWlkID09PSAwKSA/IHBhdGgucmVzb2x2ZSgnL3Vzci9sb2NhbC9zaGFyZScpIDogcmVxdWlyZSgnb3MnKS5ob21lZGlyKCk7XG4gICAgcmV0dXJuIHBhdGguam9pbih1c2VySG9tZSwgJy5jb25maWcnLCAnZGV2Y2VydCcpO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBlbnN1cmVDb25maWdEaXJzKCkge1xuICBta2RpcnAoY29uZmlnRGlyKTtcbiAgbWtkaXJwKGRvbWFpbnNEaXIpO1xuICBta2RpcnAocm9vdENBRGlyKTtcbn1cblxuZW5zdXJlQ29uZmlnRGlycygpO1xuIl19