This commit is contained in:
2022-09-30 05:39:11 +00:00
parent 41ee9463ae
commit 4687fa49bc
11418 changed files with 1312504 additions and 0 deletions

View File

@ -0,0 +1,8 @@
import { Lazy } from "lazy-val";
import { Packager } from "../packager";
export declare class ProjectInfoManager {
readonly packager: Packager;
readonly infoFile: Lazy<string>;
constructor(packager: Packager);
private saveConfigurationAndMetadata;
}

View File

@ -0,0 +1,64 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.ProjectInfoManager = void 0;
function _fsExtra() {
const data = require("fs-extra");
_fsExtra = function () {
return data;
};
return data;
}
function _lazyVal() {
const data = require("lazy-val");
_lazyVal = function () {
return data;
};
return data;
}
var path = _interopRequireWildcard(require("path"));
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (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; }
class ProjectInfoManager {
constructor(packager) {
this.packager = packager;
this.infoFile = new (_lazyVal().Lazy)(() => this.saveConfigurationAndMetadata());
}
async saveConfigurationAndMetadata() {
const packager = this.packager;
const tempDir = await packager.tempDirManager.createTempDir({
prefix: "remote-build-metadata"
}); // we cannot use getTempFile because file name must be constant
const info = {
metadata: packager.metadata,
configuration: packager.config,
repositoryInfo: await packager.repositoryInfo,
buildResourceDirName: path.basename(packager.buildResourcesDir)
};
if (packager.metadata !== packager.devMetadata && packager.devMetadata != null) {
info.devMetadata = packager.devMetadata;
}
const file = path.join(tempDir, "info.json");
await (0, _fsExtra().outputJson)(file, info);
return file;
}
} exports.ProjectInfoManager = ProjectInfoManager;
// __ts-babel@6.0.4
//# sourceMappingURL=ProjectInfoManager.js.map

View File

@ -0,0 +1 @@
{"version":3,"sources":["../../src/remoteBuilder/ProjectInfoManager.ts"],"names":[],"mappings":";;;;;;;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;;AACA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;;AACA;;;;;;AAGM,MAAO,kBAAP,CAAyB;AAG7B,EAAA,WAAA,CAAqB,QAArB,EAAuC;AAAlB,SAAA,QAAA,GAAA,QAAA;AAFZ,SAAA,QAAA,GAAW,KAAI,eAAJ,EAAS,MAAM,KAAK,4BAAL,EAAf,CAAX;AAGR;;AAEO,QAAM,4BAAN,GAAkC;AACxC,UAAM,QAAQ,GAAG,KAAK,QAAtB;AACA,UAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,cAAT,CAAwB,aAAxB,CAAsC;AAAC,MAAA,MAAM,EAAE;AAAT,KAAtC,CAAtB,CAFwC,CAGxC;;AACA,UAAM,IAAI,GAAQ;AAChB,MAAA,QAAQ,EAAE,QAAQ,CAAC,QADH;AAEhB,MAAA,aAAa,EAAE,QAAQ,CAAC,MAFR;AAGhB,MAAA,cAAc,EAAE,MAAM,QAAQ,CAAC,cAHf;AAIhB,MAAA,oBAAoB,EAAE,IAAI,CAAC,QAAL,CAAc,QAAQ,CAAC,iBAAvB;AAJN,KAAlB;;AAMA,QAAI,QAAQ,CAAC,QAAT,KAAsB,QAAQ,CAAC,WAA/B,IAA8C,QAAQ,CAAC,WAAT,IAAwB,IAA1E,EAAgF;AAC9E,MAAA,IAAI,CAAC,WAAL,GAAmB,QAAQ,CAAC,WAA5B;AACD;;AACD,UAAM,IAAI,GAAG,IAAI,CAAC,IAAL,CAAU,OAAV,EAAmB,WAAnB,CAAb;AACA,UAAM,2BAAW,IAAX,EAAiB,IAAjB,CAAN;AACA,WAAO,IAAP;AACD;;AAtB4B,C","sourcesContent":["import { outputJson } from \"fs-extra\"\nimport { Lazy } from \"lazy-val\"\nimport * as path from \"path\"\nimport { Packager } from \"../packager\"\n\nexport class ProjectInfoManager {\n readonly infoFile = new Lazy(() => this.saveConfigurationAndMetadata())\n\n constructor(readonly packager: Packager) {\n }\n\n private async saveConfigurationAndMetadata() {\n const packager = this.packager\n const tempDir = await packager.tempDirManager.createTempDir({prefix: \"remote-build-metadata\"})\n // we cannot use getTempFile because file name must be constant\n const info: any = {\n metadata: packager.metadata,\n configuration: packager.config,\n repositoryInfo: await packager.repositoryInfo,\n buildResourceDirName: path.basename(packager.buildResourcesDir)\n }\n if (packager.metadata !== packager.devMetadata && packager.devMetadata != null) {\n info.devMetadata = packager.devMetadata\n }\n const file = path.join(tempDir, \"info.json\")\n await outputJson(file, info)\n return file\n }\n}"],"sourceRoot":""}

View File

@ -0,0 +1,13 @@
import { Arch } from "builder-util";
import { Target } from "../core";
import { PlatformPackager } from "../platformPackager";
export declare class RemoteBuilder {
readonly packager: PlatformPackager<any>;
private readonly toBuild;
private buildStarted;
constructor(packager: PlatformPackager<any>);
scheduleBuild(target: Target, arch: Arch, unpackedDirectory: string): void;
build(): Promise<any>;
private _build;
private artifactInfoToArtifactCreatedEvent;
}

View File

@ -0,0 +1,197 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.RemoteBuilder = void 0;
function _bluebirdLst() {
const data = _interopRequireDefault(require("bluebird-lst"));
_bluebirdLst = function () {
return data;
};
return data;
}
function _builderUtil() {
const data = require("builder-util");
_builderUtil = function () {
return data;
};
return data;
}
var path = _interopRequireWildcard(require("path"));
function _core() {
const data = require("../core");
_core = function () {
return data;
};
return data;
}
function _platformPackager() {
const data = require("../platformPackager");
_platformPackager = function () {
return data;
};
return data;
}
function _appBuilder() {
const data = require("../util/appBuilder");
_appBuilder = function () {
return data;
};
return data;
}
function _ProjectInfoManager() {
const data = require("./ProjectInfoManager");
_ProjectInfoManager = function () {
return data;
};
return data;
}
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (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 }; }
class RemoteBuilder {
constructor(packager) {
this.packager = packager;
this.toBuild = new Map();
this.buildStarted = false;
}
scheduleBuild(target, arch, unpackedDirectory) {
if (!(0, _builderUtil().isEnvTrue)(process.env._REMOTE_BUILD) && this.packager.config.remoteBuild === false) {
throw new (_builderUtil().InvalidConfigurationError)("Target is not supported on your OS and using of Electron Build Service is disabled (\"remoteBuild\" option)");
}
let list = this.toBuild.get(arch);
if (list == null) {
list = [];
this.toBuild.set(arch, list);
}
list.push({
name: target.name,
arch: _builderUtil().Arch[arch],
unpackedDirectory,
outDir: target.outDir
});
}
build() {
if (this.buildStarted) {
return Promise.resolve();
}
this.buildStarted = true;
return _bluebirdLst().default.mapSeries(Array.from(this.toBuild.keys()), arch => {
return this._build(this.toBuild.get(arch), this.packager);
});
} // noinspection JSMethodCanBeStatic
async _build(targets, packager) {
if (_builderUtil().log.isDebugEnabled) {
_builderUtil().log.debug({
remoteTargets: JSON.stringify(targets, null, 2)
}, "remote building");
}
const projectInfoManager = new (_ProjectInfoManager().ProjectInfoManager)(packager.info);
const buildRequest = {
targets: targets.map(it => {
return {
name: it.name,
arch: it.arch,
unpackedDirName: path.basename(it.unpackedDirectory)
};
}),
platform: packager.platform.buildConfigurationKey
};
if ((0, _platformPackager().isSafeToUnpackElectronOnRemoteBuildServer)(packager)) {
buildRequest.electronDownload = {
version: packager.info.framework.version,
platform: _core().Platform.LINUX.nodeName,
arch: targets[0].arch
};
const linuxPackager = packager;
buildRequest.executableName = linuxPackager.executableName;
}
const req = Buffer.from(JSON.stringify(buildRequest)).toString("base64");
const outDir = targets[0].outDir;
const args = ["remote-build", "--request", req, "--output", outDir];
args.push("--file", targets[0].unpackedDirectory);
args.push("--file", await projectInfoManager.infoFile.value);
const buildResourcesDir = packager.buildResourcesDir;
if (buildResourcesDir === packager.projectDir) {
throw new (_builderUtil().InvalidConfigurationError)(`Build resources dir equals to project dir and so, not sent to remote build agent. It will lead to incorrect results.\nPlease set "directories.buildResources" to separate dir or leave default ("build" directory in the project root)`);
}
args.push("--build-resource-dir", buildResourcesDir);
const result = await (0, _appBuilder().executeAppBuilderAsJson)(args);
if (result.error != null) {
throw new (_builderUtil().InvalidConfigurationError)(`Remote builder error (if you think that it is not your application misconfiguration issue, please file issue to https://github.com/electron-userland/electron-builder/issues):\n\n${result.error}`, "REMOTE_BUILDER_ERROR");
} else if (result.files != null) {
for (const artifact of result.files) {
const localFile = path.join(outDir, artifact.file);
const artifactCreatedEvent = this.artifactInfoToArtifactCreatedEvent(artifact, localFile, outDir); // PublishManager uses outDir and options, real (the same as for local build) values must be used
await this.packager.info.callArtifactBuildCompleted(artifactCreatedEvent);
}
}
}
artifactInfoToArtifactCreatedEvent(artifact, localFile, outDir) {
const target = artifact.target; // noinspection SpellCheckingInspection
return { ...artifact,
file: localFile,
target: target == null ? null : new FakeTarget(target, outDir, this.packager.config[target]),
packager: this.packager
};
}
}
exports.RemoteBuilder = RemoteBuilder;
class FakeTarget extends _core().Target {
constructor(name, outDir, options) {
super(name);
this.outDir = outDir;
this.options = options;
} // eslint-disable-next-line @typescript-eslint/no-unused-vars
async build(appOutDir, arch) {// no build
}
}
// __ts-babel@6.0.4
//# sourceMappingURL=RemoteBuilder.js.map

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
export {};

View File

@ -0,0 +1,131 @@
"use strict";
function _fsExtra() {
const data = require("fs-extra");
_fsExtra = function () {
return data;
};
return data;
}
var path = _interopRequireWildcard(require("path"));
function _() {
const data = require("..");
_ = function () {
return data;
};
return data;
}
function _builderUtil() {
const data = require("builder-util");
_builderUtil = function () {
return data;
};
return data;
}
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (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; }
if (process.env.BUILDER_REMOVE_STAGE_EVEN_IF_DEBUG == null) {
process.env.BUILDER_REMOVE_STAGE_EVEN_IF_DEBUG = "true";
}
async function doBuild(data) {
if (process.env.APP_BUILDER_TMP_DIR == null) {
throw new (_builderUtil().InvalidConfigurationError)("Env APP_BUILDER_TMP_DIR must be set for builder process");
}
const projectDir = process.env.PROJECT_DIR;
if (projectDir == null) {
throw new (_builderUtil().InvalidConfigurationError)("Env PROJECT_DIR must be set for builder process");
}
const targets = data.targets;
if (data.platform == null) {
throw new (_builderUtil().InvalidConfigurationError)("platform not specified");
}
if (targets == null) {
throw new (_builderUtil().InvalidConfigurationError)("targets path not specified");
}
if (!Array.isArray(targets)) {
throw new (_builderUtil().InvalidConfigurationError)("targets must be array of target name");
}
const infoFile = projectDir + path.sep + "info.json";
const info = await (0, _fsExtra().readJson)(infoFile);
const projectOutDir = process.env.PROJECT_OUT_DIR;
if (projectDir == null) {
throw new (_builderUtil().InvalidConfigurationError)("Env PROJECT_OUT_DIR must be set for builder process");
} // yes, for now we expect the only target
const prepackaged = projectDir + path.sep + targets[0].unpackedDirName; // do not use build function because we don't need to publish artifacts
const options = {
prepackaged,
projectDir,
[data.platform]: targets.map(it => it.name + ":" + it.arch),
publish: "never"
};
const packager = new (_().Packager)(options);
const artifacts = [];
const relativePathOffset = projectOutDir.length + 1;
packager.artifactCreated(event => {
if (event.file == null) {
return;
}
artifacts.push({
file: event.file.substring(relativePathOffset),
target: event.target == null ? null : event.target.name,
arch: event.arch,
safeArtifactName: event.safeArtifactName,
isWriteUpdateInfo: event.isWriteUpdateInfo === true,
updateInfo: event.updateInfo
});
});
packager.stageDirPathCustomizer = (target, packager, arch) => {
// snap creates a lot of files and so, we cannot use tmpfs to avoid out of memory error
const parentDir = target.name === "snap" && !target.isUseTemplateApp ? projectOutDir : projectDir;
return parentDir + path.sep + `__${target.name}-${_().Arch[arch]}`;
}; // _build method expects final effective configuration - packager.options.config is ignored
await packager._build({ ...info.configuration,
publish: null,
beforeBuild: null,
afterPack: null,
afterSign: null,
afterAllArtifactBuild: null,
onNodeModuleFile: null,
directories: {
output: projectOutDir,
buildResources: projectDir + path.sep + info.buildResourceDirName
}
}, info.metadata, info.devMetadata, info.repositoryInfo); // writeJson must be not used because it adds unwanted \n as last file symbol
await (0, _fsExtra().writeFile)(path.join(process.env.APP_BUILDER_TMP_DIR, "__build-result.json"), JSON.stringify(artifacts));
}
doBuild(JSON.parse(process.argv[2])).catch(error => {
process.exitCode = 0;
return (0, _fsExtra().writeFile)(path.join(process.env.APP_BUILDER_TMP_DIR, "__build-result.json"), (error.stack || error).toString());
});
// __ts-babel@6.0.4
//# sourceMappingURL=builder-cli.js.map

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,2 @@
export declare const ELECTRON_BUILD_SERVICE_LOCAL_CA_CERT: Buffer;
export declare const ELECTRON_BUILD_SERVICE_CA_CERT: Buffer;

View File

@ -0,0 +1,35 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.ELECTRON_BUILD_SERVICE_CA_CERT = exports.ELECTRON_BUILD_SERVICE_LOCAL_CA_CERT = void 0;
// noinspection SpellCheckingInspection
const ELECTRON_BUILD_SERVICE_LOCAL_CA_CERT = Buffer.from(`-----BEGIN CERTIFICATE-----
MIIBiDCCAS+gAwIBAgIRAPHSzTRLcN2nElhQdaRP47IwCgYIKoZIzj0EAwIwJDEi
MCAGA1UEAxMZZWxlY3Ryb24uYnVpbGQubG9jYWwgcm9vdDAeFw0xNzExMTMxNzI4
NDFaFw0yNzExMTExNzI4NDFaMCQxIjAgBgNVBAMTGWVsZWN0cm9uLmJ1aWxkLmxv
Y2FsIHJvb3QwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQVyduuCT2acuk2QH06
yal/b6O7eTTpOHk3Ucjc+ZZta2vC2+c1IKcSAwimKbTbK+nRxWWJl9ZYx9RTwbRf
QjD6o0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E
FgQUlm08vBe4CUNAOTQN5Z1RNTfJjjYwCgYIKoZIzj0EAwIDRwAwRAIgMXlT6YM8
4pQtnhUjijVMz+NlcYafS1CEbNBMaWhP87YCIGXUmu7ON9hRLanXzBNBlrtTQG+i
l/NT6REwZA64/lNy
-----END CERTIFICATE-----
`); // noinspection SpellCheckingInspection
exports.ELECTRON_BUILD_SERVICE_LOCAL_CA_CERT = ELECTRON_BUILD_SERVICE_LOCAL_CA_CERT;
const ELECTRON_BUILD_SERVICE_CA_CERT = Buffer.from(`-----BEGIN CERTIFICATE-----
MIIBfTCCASOgAwIBAgIRAIdieK1+3C4abgOvQ7pVVqAwCgYIKoZIzj0EAwIwHjEc
MBoGA1UEAxMTZWxlY3Ryb24uYnVpbGQgcm9vdDAeFw0xNzExMTMxNzI4NDFaFw0x
ODExMTMxNzI4NDFaMB4xHDAaBgNVBAMTE2VsZWN0cm9uLmJ1aWxkIHJvb3QwWTAT
BgcqhkjOPQIBBggqhkjOPQMBBwNCAAR+4b6twzizN/z27yvwrCV5kinGUrfo+W7n
L/l28ErscNe1BDSyh/IYrnMWb1rDMSLGhvkgI9Cfex1whNPHR101o0IwQDAOBgNV
HQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU6Dq8kK7tQlrt
zkIYrYiTZGpHEp0wCgYIKoZIzj0EAwIDSAAwRQIgKSfjAQbYlY/S1wMLUi84r8QN
hhMnUwsOmlDan0xPalICIQDLIAXAIyArVtH38a4aizvhH8YeXrxzpJh3U8RolBZF
SA==
-----END CERTIFICATE-----
`); exports.ELECTRON_BUILD_SERVICE_CA_CERT = ELECTRON_BUILD_SERVICE_CA_CERT;
// __ts-babel@6.0.4
//# sourceMappingURL=remote-builder-certs.js.map

View File

@ -0,0 +1 @@
{"version":3,"sources":["../../src/remoteBuilder/remote-builder-certs.ts"],"names":[],"mappings":";;;;;;AAAA;AACO,MAAM,oCAAoC,GAAG,MAAM,CAAC,IAAP,CAAY;;;;;;;;;;;CAAZ,CAA7C,C,CAaP;;;AACO,MAAM,8BAA8B,GAAG,MAAM,CAAC,IAAP,CAAY;;;;;;;;;;;CAAZ,CAAvC,C","sourcesContent":["// noinspection SpellCheckingInspection\nexport const ELECTRON_BUILD_SERVICE_LOCAL_CA_CERT = Buffer.from(`-----BEGIN CERTIFICATE-----\nMIIBiDCCAS+gAwIBAgIRAPHSzTRLcN2nElhQdaRP47IwCgYIKoZIzj0EAwIwJDEi\nMCAGA1UEAxMZZWxlY3Ryb24uYnVpbGQubG9jYWwgcm9vdDAeFw0xNzExMTMxNzI4\nNDFaFw0yNzExMTExNzI4NDFaMCQxIjAgBgNVBAMTGWVsZWN0cm9uLmJ1aWxkLmxv\nY2FsIHJvb3QwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQVyduuCT2acuk2QH06\nyal/b6O7eTTpOHk3Ucjc+ZZta2vC2+c1IKcSAwimKbTbK+nRxWWJl9ZYx9RTwbRf\nQjD6o0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E\nFgQUlm08vBe4CUNAOTQN5Z1RNTfJjjYwCgYIKoZIzj0EAwIDRwAwRAIgMXlT6YM8\n4pQtnhUjijVMz+NlcYafS1CEbNBMaWhP87YCIGXUmu7ON9hRLanXzBNBlrtTQG+i\nl/NT6REwZA64/lNy\n-----END CERTIFICATE-----\n`)\n\n// noinspection SpellCheckingInspection\nexport const ELECTRON_BUILD_SERVICE_CA_CERT = Buffer.from(`-----BEGIN CERTIFICATE-----\nMIIBfTCCASOgAwIBAgIRAIdieK1+3C4abgOvQ7pVVqAwCgYIKoZIzj0EAwIwHjEc\nMBoGA1UEAxMTZWxlY3Ryb24uYnVpbGQgcm9vdDAeFw0xNzExMTMxNzI4NDFaFw0x\nODExMTMxNzI4NDFaMB4xHDAaBgNVBAMTE2VsZWN0cm9uLmJ1aWxkIHJvb3QwWTAT\nBgcqhkjOPQIBBggqhkjOPQMBBwNCAAR+4b6twzizN/z27yvwrCV5kinGUrfo+W7n\nL/l28ErscNe1BDSyh/IYrnMWb1rDMSLGhvkgI9Cfex1whNPHR101o0IwQDAOBgNV\nHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU6Dq8kK7tQlrt\nzkIYrYiTZGpHEp0wCgYIKoZIzj0EAwIDSAAwRQIgKSfjAQbYlY/S1wMLUi84r8QN\nhhMnUwsOmlDan0xPalICIQDLIAXAIyArVtH38a4aizvhH8YeXrxzpJh3U8RolBZF\nSA==\n-----END CERTIFICATE-----\n`)"],"sourceRoot":""}