electron-compile
Version:
Electron supporting package to compile JS and CSS in Electron applications
725 lines (575 loc) • 85 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _mimeTypes = require('@paulcbetts/mime-types');
var _mimeTypes2 = _interopRequireDefault(_mimeTypes);
var _fs = require('fs');
var _fs2 = _interopRequireDefault(_fs);
var _zlib = require('zlib');
var _zlib2 = _interopRequireDefault(_zlib);
var _path = require('path');
var _path2 = _interopRequireDefault(_path);
var _promise = require('./promise');
var _forAllFiles = require('./for-all-files');
var _compileCache = require('./compile-cache');
var _compileCache2 = _interopRequireDefault(_compileCache);
var _fileChangeCache = require('./file-change-cache');
var _fileChangeCache2 = _interopRequireDefault(_fileChangeCache);
var _readOnlyCompiler = require('./read-only-compiler');
var _readOnlyCompiler2 = _interopRequireDefault(_readOnlyCompiler);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
const d = require('debug-electron')('electron-compile:compiler-host');
require('./rig-mime-types').init();
// This isn't even my
const finalForms = {
'text/javascript': true,
'application/javascript': true,
'text/html': true,
'text/css': true,
'image/svg+xml': true,
'application/json': true
};
/**
* This class is the top-level class that encapsulates all of the logic of
* compiling and caching application code. If you're looking for a "Main class",
* this is it.
*
* This class can be created directly but it is usually created via the methods
* in config-parser, which will among other things, set up the compiler options
* given a project root.
*
* CompilerHost is also the top-level class that knows how to serialize all of the
* information necessary to recreate itself, either as a development host (i.e.
* will allow cache misses and actual compilation), or as a read-only version of
* itself for production.
*/
class CompilerHost {
/**
* Creates an instance of CompilerHost. You probably want to use the methods
* in config-parser for development, or {@link createReadonlyFromConfiguration}
* for production instead.
*
* @param {string} rootCacheDir The root directory to use for the cache
*
* @param {Object} compilers an Object whose keys are input MIME types and
* whose values are instances of CompilerBase. Create
* this via the {@link createCompilers} method in
* config-parser.
*
* @param {FileChangedCache} fileChangeCache A file-change cache that is
* optionally pre-loaded.
*
* @param {boolean} readOnlyMode If True, cache misses will fail and
* compilation will not be attempted.
*
* @param {CompilerBase} fallbackCompiler (optional) When a file is compiled
* which doesn't have a matching compiler,
* this compiler will be used instead. If
* null, will fail compilation. A good
* alternate fallback is the compiler for
* 'text/plain', which is guaranteed to be
* present.
*/
constructor(rootCacheDir, compilers, fileChangeCache, readOnlyMode) {
let fallbackCompiler = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null;
let compilersByMimeType = Object.assign({}, compilers);
Object.assign(this, { rootCacheDir, compilersByMimeType, fileChangeCache, readOnlyMode, fallbackCompiler });
this.appRoot = this.fileChangeCache.appRoot;
this.cachesForCompilers = Object.keys(compilersByMimeType).reduce((acc, x) => {
let compiler = compilersByMimeType[x];
if (acc.has(compiler)) return acc;
acc.set(compiler, _compileCache2.default.createFromCompiler(rootCacheDir, compiler, fileChangeCache, readOnlyMode));
return acc;
}, new Map());
}
/**
* Creates a production-mode CompilerHost from the previously saved
* configuration
*
* @param {string} rootCacheDir The root directory to use for the cache. This
* cache must have cache information saved via
* {@link saveConfiguration}
*
* @param {string} appRoot The top-level directory for your application (i.e.
* the one which has your package.json).
*
* @param {CompilerBase} fallbackCompiler (optional) When a file is compiled
* which doesn't have a matching compiler,
* this compiler will be used instead. If
* null, will fail compilation. A good
* alternate fallback is the compiler for
* 'text/plain', which is guaranteed to be
* present.
*
* @return {Promise<CompilerHost>} A read-only CompilerHost
*/
static createReadonlyFromConfiguration(rootCacheDir, appRoot) {
let fallbackCompiler = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
return _asyncToGenerator(function* () {
let target = _path2.default.join(rootCacheDir, 'compiler-info.json.gz');
let buf = yield _promise.pfs.readFile(target);
let info = JSON.parse((yield _promise.pzlib.gunzip(buf)));
let fileChangeCache = _fileChangeCache2.default.loadFromData(info.fileChangeCache, appRoot, true);
let compilers = Object.keys(info.compilers).reduce(function (acc, x) {
let cur = info.compilers[x];
acc[x] = new _readOnlyCompiler2.default(cur.name, cur.compilerVersion, cur.compilerOptions, cur.inputMimeTypes);
return acc;
}, {});
return new CompilerHost(rootCacheDir, compilers, fileChangeCache, true, fallbackCompiler);
})();
}
/**
* Creates a development-mode CompilerHost from the previously saved
* configuration.
*
* @param {string} rootCacheDir The root directory to use for the cache. This
* cache must have cache information saved via
* {@link saveConfiguration}
*
* @param {string} appRoot The top-level directory for your application (i.e.
* the one which has your package.json).
*
* @param {Object} compilersByMimeType an Object whose keys are input MIME
* types and whose values are instances
* of CompilerBase. Create this via the
* {@link createCompilers} method in
* config-parser.
*
* @param {CompilerBase} fallbackCompiler (optional) When a file is compiled
* which doesn't have a matching compiler,
* this compiler will be used instead. If
* null, will fail compilation. A good
* alternate fallback is the compiler for
* 'text/plain', which is guaranteed to be
* present.
*
* @return {Promise<CompilerHost>} A read-only CompilerHost
*/
static createFromConfiguration(rootCacheDir, appRoot, compilersByMimeType) {
let fallbackCompiler = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
return _asyncToGenerator(function* () {
let target = _path2.default.join(rootCacheDir, 'compiler-info.json.gz');
let buf = yield _promise.pfs.readFile(target);
let info = JSON.parse((yield _promise.pzlib.gunzip(buf)));
let fileChangeCache = _fileChangeCache2.default.loadFromData(info.fileChangeCache, appRoot, false);
Object.keys(info.compilers).forEach(function (x) {
let cur = info.compilers[x];
compilersByMimeType[x].compilerOptions = cur.compilerOptions;
});
return new CompilerHost(rootCacheDir, compilersByMimeType, fileChangeCache, false, fallbackCompiler);
})();
}
/**
* Saves the current compiler configuration to a file that
* {@link createReadonlyFromConfiguration} can use to recreate the current
* compiler environment
*
* @return {Promise} Completion
*/
saveConfiguration() {
var _this = this;
return _asyncToGenerator(function* () {
let serializedCompilerOpts = Object.keys(_this.compilersByMimeType).reduce(function (acc, x) {
let compiler = _this.compilersByMimeType[x];
let Klass = Object.getPrototypeOf(compiler).constructor;
let val = {
name: Klass.name,
inputMimeTypes: Klass.getInputMimeTypes(),
compilerOptions: compiler.compilerOptions,
compilerVersion: compiler.getCompilerVersion()
};
acc[x] = val;
return acc;
}, {});
let info = {
fileChangeCache: _this.fileChangeCache.getSavedData(),
compilers: serializedCompilerOpts
};
let target = _path2.default.join(_this.rootCacheDir, 'compiler-info.json.gz');
let buf = yield _promise.pzlib.gzip(new Buffer(JSON.stringify(info)));
yield _promise.pfs.writeFile(target, buf);
})();
}
/**
* Compiles a file and returns the compiled result.
*
* @param {string} filePath The path to the file to compile
*
* @return {Promise<object>} An Object with the compiled result
*
* @property {Object} hashInfo The hash information returned from getHashForPath
* @property {string} code The source code if the file was a text file
* @property {Buffer} binaryData The file if it was a binary file
* @property {string} mimeType The MIME type saved in the cache.
* @property {string[]} dependentFiles The dependent files returned from
* compiling the file, if any.
*/
compile(filePath) {
return this.readOnlyMode ? this.compileReadOnly(filePath) : this.fullCompile(filePath);
}
/**
* Handles compilation in read-only mode
*
* @private
*/
compileReadOnly(filePath) {
var _this2 = this;
return _asyncToGenerator(function* () {
// We guarantee that node_modules are always shipped directly
let type = _mimeTypes2.default.lookup(filePath);
if (_fileChangeCache2.default.isInNodeModules(filePath)) {
return {
mimeType: type || 'application/javascript',
code: yield _promise.pfs.readFile(filePath, 'utf8')
};
}
let hashInfo = yield _this2.fileChangeCache.getHashForPath(filePath);
// NB: Here, we're basically only using the compiler here to find
// the appropriate CompileCache
let compiler = CompilerHost.shouldPassthrough(hashInfo) ? _this2.getPassthroughCompiler() : _this2.compilersByMimeType[type || '__lolnothere'];
if (!compiler) {
compiler = _this2.fallbackCompiler;
var _ref = yield compiler.get(filePath);
let code = _ref.code;
let binaryData = _ref.binaryData;
let mimeType = _ref.mimeType;
return { code: code || binaryData, mimeType };
}
let cache = _this2.cachesForCompilers.get(compiler);
var _ref2 = yield cache.get(filePath);
let code = _ref2.code;
let binaryData = _ref2.binaryData;
let mimeType = _ref2.mimeType;
code = code || binaryData;
if (!code || !mimeType) {
throw new Error(`Asked to compile ${ filePath } in production, is this file not precompiled?`);
}
return { code, mimeType };
})();
}
/**
* Handles compilation in read-write mode
*
* @private
*/
fullCompile(filePath) {
var _this3 = this;
return _asyncToGenerator(function* () {
d(`Compiling ${ filePath }`);
let hashInfo = yield _this3.fileChangeCache.getHashForPath(filePath);
let type = _mimeTypes2.default.lookup(filePath);
if (hashInfo.isInNodeModules) {
let code = hashInfo.sourceCode || (yield _promise.pfs.readFile(filePath, 'utf8'));
code = yield CompilerHost.fixNodeModulesSourceMapping(code, filePath, _this3.fileChangeCache.appRoot);
return { code, mimeType: type };
}
let compiler = CompilerHost.shouldPassthrough(hashInfo) ? _this3.getPassthroughCompiler() : _this3.compilersByMimeType[type || '__lolnothere'];
if (!compiler) {
d(`Falling back to passthrough compiler for ${ filePath }`);
compiler = _this3.fallbackCompiler;
}
if (!compiler) {
throw new Error(`Couldn't find a compiler for ${ filePath }`);
}
let cache = _this3.cachesForCompilers.get(compiler);
return yield cache.getOrFetch(filePath, function (filePath, hashInfo) {
return _this3.compileUncached(filePath, hashInfo, compiler);
});
})();
}
/**
* Handles invoking compilers independent of caching
*
* @private
*/
compileUncached(filePath, hashInfo, compiler) {
var _this4 = this;
return _asyncToGenerator(function* () {
let inputMimeType = _mimeTypes2.default.lookup(filePath);
if (hashInfo.isFileBinary) {
return {
binaryData: hashInfo.binaryData || (yield _promise.pfs.readFile(filePath)),
mimeType: inputMimeType,
dependentFiles: []
};
}
let ctx = {};
let code = hashInfo.sourceCode || (yield _promise.pfs.readFile(filePath, 'utf8'));
if (!(yield compiler.shouldCompileFile(code, ctx))) {
d(`Compiler returned false for shouldCompileFile: ${ filePath }`);
return { code, mimeType: _mimeTypes2.default.lookup(filePath), dependentFiles: [] };
}
let dependentFiles = yield compiler.determineDependentFiles(code, filePath, ctx);
d(`Using compiler options: ${ JSON.stringify(compiler.compilerOptions) }`);
let result = yield compiler.compile(code, filePath, ctx);
let shouldInlineHtmlify = inputMimeType !== 'text/html' && result.mimeType === 'text/html';
let isPassthrough = result.mimeType === 'text/plain' || !result.mimeType || CompilerHost.shouldPassthrough(hashInfo);
if (finalForms[result.mimeType] && !shouldInlineHtmlify || isPassthrough) {
// Got something we can use in-browser, let's return it
return Object.assign(result, { dependentFiles });
} else {
d(`Recursively compiling result of ${ filePath } with non-final MIME type ${ result.mimeType }, input was ${ inputMimeType }`);
hashInfo = Object.assign({ sourceCode: result.code, mimeType: result.mimeType }, hashInfo);
compiler = _this4.compilersByMimeType[result.mimeType || '__lolnothere'];
if (!compiler) {
d(`Recursive compile failed - intermediate result: ${ JSON.stringify(result) }`);
throw new Error(`Compiling ${ filePath } resulted in a MIME type of ${ result.mimeType }, which we don't know how to handle`);
}
return yield _this4.compileUncached(`${ filePath }.${ _mimeTypes2.default.extension(result.mimeType || 'txt') }`, hashInfo, compiler);
}
})();
}
/**
* Pre-caches an entire directory of files recursively. Usually used for
* building custom compiler tooling.
*
* @param {string} rootDirectory The top-level directory to compile
*
* @param {Function} shouldCompile (optional) A Function which allows the
* caller to disable compiling certain files.
* It takes a fully-qualified path to a file,
* and should return a Boolean.
*
* @return {Promise} Completion.
*/
compileAll(rootDirectory) {
var _this5 = this;
let shouldCompile = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
return _asyncToGenerator(function* () {
let should = shouldCompile || function () {
return true;
};
yield (0, _forAllFiles.forAllFiles)(rootDirectory, function (f) {
if (!should(f)) return;
d(`Compiling ${ f }`);
return _this5.compile(f, _this5.compilersByMimeType);
});
})();
}
/*
* Sync Methods
*/
compileSync(filePath) {
return this.readOnlyMode ? this.compileReadOnlySync(filePath) : this.fullCompileSync(filePath);
}
static createReadonlyFromConfigurationSync(rootCacheDir, appRoot) {
let fallbackCompiler = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
let target = _path2.default.join(rootCacheDir, 'compiler-info.json.gz');
let buf = _fs2.default.readFileSync(target);
let info = JSON.parse(_zlib2.default.gunzipSync(buf));
let fileChangeCache = _fileChangeCache2.default.loadFromData(info.fileChangeCache, appRoot, true);
let compilers = Object.keys(info.compilers).reduce((acc, x) => {
let cur = info.compilers[x];
acc[x] = new _readOnlyCompiler2.default(cur.name, cur.compilerVersion, cur.compilerOptions, cur.inputMimeTypes);
return acc;
}, {});
return new CompilerHost(rootCacheDir, compilers, fileChangeCache, true, fallbackCompiler);
}
static createFromConfigurationSync(rootCacheDir, appRoot, compilersByMimeType) {
let fallbackCompiler = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
let target = _path2.default.join(rootCacheDir, 'compiler-info.json.gz');
let buf = _fs2.default.readFileSync(target);
let info = JSON.parse(_zlib2.default.gunzipSync(buf));
let fileChangeCache = _fileChangeCache2.default.loadFromData(info.fileChangeCache, appRoot, false);
Object.keys(info.compilers).forEach(x => {
let cur = info.compilers[x];
compilersByMimeType[x].compilerOptions = cur.compilerOptions;
});
return new CompilerHost(rootCacheDir, compilersByMimeType, fileChangeCache, false, fallbackCompiler);
}
saveConfigurationSync() {
let serializedCompilerOpts = Object.keys(this.compilersByMimeType).reduce((acc, x) => {
let compiler = this.compilersByMimeType[x];
let Klass = Object.getPrototypeOf(compiler).constructor;
let val = {
name: Klass.name,
inputMimeTypes: Klass.getInputMimeTypes(),
compilerOptions: compiler.compilerOptions,
compilerVersion: compiler.getCompilerVersion()
};
acc[x] = val;
return acc;
}, {});
let info = {
fileChangeCache: this.fileChangeCache.getSavedData(),
compilers: serializedCompilerOpts
};
let target = _path2.default.join(this.rootCacheDir, 'compiler-info.json.gz');
let buf = _zlib2.default.gzipSync(new Buffer(JSON.stringify(info)));
_fs2.default.writeFileSync(target, buf);
}
compileReadOnlySync(filePath) {
// We guarantee that node_modules are always shipped directly
let type = _mimeTypes2.default.lookup(filePath);
if (_fileChangeCache2.default.isInNodeModules(filePath)) {
return {
mimeType: type || 'application/javascript',
code: _fs2.default.readFileSync(filePath, 'utf8')
};
}
let hashInfo = this.fileChangeCache.getHashForPathSync(filePath);
// We guarantee that node_modules are always shipped directly
if (hashInfo.isInNodeModules) {
return {
mimeType: type,
code: hashInfo.sourceCode || _fs2.default.readFileSync(filePath, 'utf8')
};
}
// NB: Here, we're basically only using the compiler here to find
// the appropriate CompileCache
let compiler = CompilerHost.shouldPassthrough(hashInfo) ? this.getPassthroughCompiler() : this.compilersByMimeType[type || '__lolnothere'];
if (!compiler) {
compiler = this.fallbackCompiler;
var _compiler$getSync = compiler.getSync(filePath);
let code = _compiler$getSync.code;
let binaryData = _compiler$getSync.binaryData;
let mimeType = _compiler$getSync.mimeType;
return { code: code || binaryData, mimeType };
}
let cache = this.cachesForCompilers.get(compiler);
var _cache$getSync = cache.getSync(filePath);
let code = _cache$getSync.code;
let binaryData = _cache$getSync.binaryData;
let mimeType = _cache$getSync.mimeType;
code = code || binaryData;
if (!code || !mimeType) {
throw new Error(`Asked to compile ${ filePath } in production, is this file not precompiled?`);
}
return { code, mimeType };
}
fullCompileSync(filePath) {
d(`Compiling ${ filePath }`);
let hashInfo = this.fileChangeCache.getHashForPathSync(filePath);
let type = _mimeTypes2.default.lookup(filePath);
if (hashInfo.isInNodeModules) {
let code = hashInfo.sourceCode || _fs2.default.readFileSync(filePath, 'utf8');
code = CompilerHost.fixNodeModulesSourceMappingSync(code, filePath, this.fileChangeCache.appRoot);
return { code, mimeType: type };
}
let compiler = CompilerHost.shouldPassthrough(hashInfo) ? this.getPassthroughCompiler() : this.compilersByMimeType[type || '__lolnothere'];
if (!compiler) {
d(`Falling back to passthrough compiler for ${ filePath }`);
compiler = this.fallbackCompiler;
}
if (!compiler) {
throw new Error(`Couldn't find a compiler for ${ filePath }`);
}
let cache = this.cachesForCompilers.get(compiler);
return cache.getOrFetchSync(filePath, (filePath, hashInfo) => this.compileUncachedSync(filePath, hashInfo, compiler));
}
compileUncachedSync(filePath, hashInfo, compiler) {
let inputMimeType = _mimeTypes2.default.lookup(filePath);
if (hashInfo.isFileBinary) {
return {
binaryData: hashInfo.binaryData || _fs2.default.readFileSync(filePath),
mimeType: inputMimeType,
dependentFiles: []
};
}
let ctx = {};
let code = hashInfo.sourceCode || _fs2.default.readFileSync(filePath, 'utf8');
if (!compiler.shouldCompileFileSync(code, ctx)) {
d(`Compiler returned false for shouldCompileFile: ${ filePath }`);
return { code, mimeType: _mimeTypes2.default.lookup(filePath), dependentFiles: [] };
}
let dependentFiles = compiler.determineDependentFilesSync(code, filePath, ctx);
let result = compiler.compileSync(code, filePath, ctx);
let shouldInlineHtmlify = inputMimeType !== 'text/html' && result.mimeType === 'text/html';
let isPassthrough = result.mimeType === 'text/plain' || !result.mimeType || CompilerHost.shouldPassthrough(hashInfo);
if (finalForms[result.mimeType] && !shouldInlineHtmlify || isPassthrough) {
// Got something we can use in-browser, let's return it
return Object.assign(result, { dependentFiles });
} else {
d(`Recursively compiling result of ${ filePath } with non-final MIME type ${ result.mimeType }, input was ${ inputMimeType }`);
hashInfo = Object.assign({ sourceCode: result.code, mimeType: result.mimeType }, hashInfo);
compiler = this.compilersByMimeType[result.mimeType || '__lolnothere'];
if (!compiler) {
d(`Recursive compile failed - intermediate result: ${ JSON.stringify(result) }`);
throw new Error(`Compiling ${ filePath } resulted in a MIME type of ${ result.mimeType }, which we don't know how to handle`);
}
return this.compileUncachedSync(`${ filePath }.${ _mimeTypes2.default.extension(result.mimeType || 'txt') }`, hashInfo, compiler);
}
}
compileAllSync(rootDirectory) {
let shouldCompile = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
let should = shouldCompile || function () {
return true;
};
(0, _forAllFiles.forAllFilesSync)(rootDirectory, f => {
if (!should(f)) return;
return this.compileSync(f, this.compilersByMimeType);
});
}
/*
* Other stuff
*/
/**
* Returns the passthrough compiler
*
* @private
*/
getPassthroughCompiler() {
return this.compilersByMimeType['text/plain'];
}
/**
* Determines whether we should even try to compile the content. Note that in
* some cases, content will still be in cache even if this returns true, and
* in other cases (isInNodeModules), we'll know explicitly to not even bother
* looking in the cache.
*
* @private
*/
static shouldPassthrough(hashInfo) {
return hashInfo.isMinified || hashInfo.isInNodeModules || hashInfo.hasSourceMap || hashInfo.isFileBinary;
}
/**
* Look at the code of a node modules and see the sourceMapping path.
* If there is any, check the path and try to fix it with and
* root relative path.
* @private
*/
static fixNodeModulesSourceMapping(sourceCode, sourcePath, appRoot) {
return _asyncToGenerator(function* () {
let regexSourceMapping = /\/\/#.*sourceMappingURL=(?!data:)([^"'].*)/i;
let sourceMappingCheck = sourceCode.match(regexSourceMapping);
if (sourceMappingCheck && sourceMappingCheck[1] && sourceMappingCheck[1] !== '') {
let sourceMapPath = sourceMappingCheck[1];
try {
yield _promise.pfs.stat(sourceMapPath);
} catch (error) {
let normRoot = _path2.default.normalize(appRoot);
let absPathToModule = _path2.default.dirname(sourcePath.replace(normRoot, '').substring(1));
let newMapPath = _path2.default.join(absPathToModule, sourceMapPath);
return sourceCode.replace(regexSourceMapping, `//# sourceMappingURL=${ newMapPath }`);
}
}
return sourceCode;
})();
}
/**
* Look at the code of a node modules and see the sourceMapping path.
* If there is any, check the path and try to fix it with and
* root relative path.
* @private
*/
static fixNodeModulesSourceMappingSync(sourceCode, sourcePath, appRoot) {
let regexSourceMapping = /\/\/#.*sourceMappingURL=(?!data:)([^"'].*)/i;
let sourceMappingCheck = sourceCode.match(regexSourceMapping);
if (sourceMappingCheck && sourceMappingCheck[1] && sourceMappingCheck[1] !== '') {
let sourceMapPath = sourceMappingCheck[1];
try {
_fs2.default.statSync(sourceMapPath);
} catch (error) {
let normRoot = _path2.default.normalize(appRoot);
let absPathToModule = _path2.default.dirname(sourcePath.replace(normRoot, '').substring(1));
let newMapPath = _path2.default.join(absPathToModule, sourceMapPath);
return sourceCode.replace(regexSourceMapping, `//# sourceMappingURL=${ newMapPath }`);
}
}
return sourceCode;
}
}
exports.default = CompilerHost;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9jb21waWxlci1ob3N0LmpzIl0sIm5hbWVzIjpbImQiLCJyZXF1aXJlIiwiaW5pdCIsImZpbmFsRm9ybXMiLCJDb21waWxlckhvc3QiLCJjb25zdHJ1Y3RvciIsInJvb3RDYWNoZURpciIsImNvbXBpbGVycyIsImZpbGVDaGFuZ2VDYWNoZSIsInJlYWRPbmx5TW9kZSIsImZhbGxiYWNrQ29tcGlsZXIiLCJjb21waWxlcnNCeU1pbWVUeXBlIiwiT2JqZWN0IiwiYXNzaWduIiwiYXBwUm9vdCIsImNhY2hlc0ZvckNvbXBpbGVycyIsImtleXMiLCJyZWR1Y2UiLCJhY2MiLCJ4IiwiY29tcGlsZXIiLCJoYXMiLCJzZXQiLCJjcmVhdGVGcm9tQ29tcGlsZXIiLCJNYXAiLCJjcmVhdGVSZWFkb25seUZyb21Db25maWd1cmF0aW9uIiwidGFyZ2V0Iiwiam9pbiIsImJ1ZiIsInJlYWRGaWxlIiwiaW5mbyIsIkpTT04iLCJwYXJzZSIsImd1bnppcCIsImxvYWRGcm9tRGF0YSIsImN1ciIsIm5hbWUiLCJjb21waWxlclZlcnNpb24iLCJjb21waWxlck9wdGlvbnMiLCJpbnB1dE1pbWVUeXBlcyIsImNyZWF0ZUZyb21Db25maWd1cmF0aW9uIiwiZm9yRWFjaCIsInNhdmVDb25maWd1cmF0aW9uIiwic2VyaWFsaXplZENvbXBpbGVyT3B0cyIsIktsYXNzIiwiZ2V0UHJvdG90eXBlT2YiLCJ2YWwiLCJnZXRJbnB1dE1pbWVUeXBlcyIsImdldENvbXBpbGVyVmVyc2lvbiIsImdldFNhdmVkRGF0YSIsImd6aXAiLCJCdWZmZXIiLCJzdHJpbmdpZnkiLCJ3cml0ZUZpbGUiLCJjb21waWxlIiwiZmlsZVBhdGgiLCJjb21waWxlUmVhZE9ubHkiLCJmdWxsQ29tcGlsZSIsInR5cGUiLCJsb29rdXAiLCJpc0luTm9kZU1vZHVsZXMiLCJtaW1lVHlwZSIsImNvZGUiLCJoYXNoSW5mbyIsImdldEhhc2hGb3JQYXRoIiwic2hvdWxkUGFzc3Rocm91Z2giLCJnZXRQYXNzdGhyb3VnaENvbXBpbGVyIiwiZ2V0IiwiYmluYXJ5RGF0YSIsImNhY2hlIiwiRXJyb3IiLCJzb3VyY2VDb2RlIiwiZml4Tm9kZU1vZHVsZXNTb3VyY2VNYXBwaW5nIiwiZ2V0T3JGZXRjaCIsImNvbXBpbGVVbmNhY2hlZCIsImlucHV0TWltZVR5cGUiLCJpc0ZpbGVCaW5hcnkiLCJkZXBlbmRlbnRGaWxlcyIsImN0eCIsInNob3VsZENvbXBpbGVGaWxlIiwiZGV0ZXJtaW5lRGVwZW5kZW50RmlsZXMiLCJyZXN1bHQiLCJzaG91bGRJbmxpbmVIdG1saWZ5IiwiaXNQYXNzdGhyb3VnaCIsImV4dGVuc2lvbiIsImNvbXBpbGVBbGwiLCJyb290RGlyZWN0b3J5Iiwic2hvdWxkQ29tcGlsZSIsInNob3VsZCIsImYiLCJjb21waWxlU3luYyIsImNvbXBpbGVSZWFkT25seVN5bmMiLCJmdWxsQ29tcGlsZVN5bmMiLCJjcmVhdGVSZWFkb25seUZyb21Db25maWd1cmF0aW9uU3luYyIsInJlYWRGaWxlU3luYyIsImd1bnppcFN5bmMiLCJjcmVhdGVGcm9tQ29uZmlndXJhdGlvblN5bmMiLCJzYXZlQ29uZmlndXJhdGlvblN5bmMiLCJnemlwU3luYyIsIndyaXRlRmlsZVN5bmMiLCJnZXRIYXNoRm9yUGF0aFN5bmMiLCJnZXRTeW5jIiwiZml4Tm9kZU1vZHVsZXNTb3VyY2VNYXBwaW5nU3luYyIsImdldE9yRmV0Y2hTeW5jIiwiY29tcGlsZVVuY2FjaGVkU3luYyIsInNob3VsZENvbXBpbGVGaWxlU3luYyIsImRldGVybWluZURlcGVuZGVudEZpbGVzU3luYyIsImNvbXBpbGVBbGxTeW5jIiwiaXNNaW5pZmllZCIsImhhc1NvdXJjZU1hcCIsInNvdXJjZVBhdGgiLCJyZWdleFNvdXJjZU1hcHBpbmciLCJzb3VyY2VNYXBwaW5nQ2hlY2siLCJtYXRjaCIsInNvdXJjZU1hcFBhdGgiLCJzdGF0IiwiZXJyb3IiLCJub3JtUm9vdCIsIm5vcm1hbGl6ZSIsImFic1BhdGhUb01vZHVsZSIsImRpcm5hbWUiLCJyZXBsYWNlIiwi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