projen
Version:
CDK for software projects
251 lines • 27 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.Biome = void 0;
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
const path = __importStar(require("node:path"));
const fast_json_patch_1 = require("fast-json-patch");
const component_1 = require("../../component");
const json_1 = require("../../json");
const util_1 = require("../../util");
const util_2 = require("../util");
const biome_config_1 = require("./biome-config");
/**
* Enabling VCS configuration by default.
*
* Note that this differs from `biome init`, as projen can be presumed to use version control
*/
const DEFAULT_CONFIG = {
vcs: {
clientKind: biome_config_1.VcsClientKind.GIT,
enabled: true,
useIgnoreFile: true,
},
files: {
ignoreUnknown: false,
},
};
/**
* Default linting configuration if linter is enabled.
*
* Ignores by default following patterns: '*.js', '*.d.ts', 'node_modules/', '*.generated.ts', 'coverage'.
*/
const DEFAULT_LINTER = {
linter: {
enabled: true,
rules: {
preset: biome_config_1.PresetConfig.RECOMMENDED,
},
},
};
/**
* Default formatting configuration if formatter is enabled.
*/
const DEFAULT_FORMATTER = {
formatter: {
enabled: true,
indentStyle: biome_config_1.IndentStyle.TAB,
},
javascript: {
formatter: {
quoteStyle: biome_config_1.QuoteStyle.DOUBLE,
},
},
};
/**
* Default code assist actions
*/
const DEFAULT_ASSIST = {
assist: {
enabled: true,
actions: {
preset: biome_config_1.PresetConfig.RECOMMENDED,
},
},
};
/**
* Biome component.
*/
class Biome extends component_1.Component {
options;
static [JSII_RTTI_SYMBOL_1] = { fqn: "projen.javascript.Biome", version: "0.103.12" };
static of(project) {
const isBiome = (c) => c instanceof Biome;
return project.components.find(isBiome);
}
biomeConfiguration;
_filePatterns;
biomeCommand = [
"biome",
"check",
"--no-errors-on-unmatched",
"--write",
];
/**
* Biome task.
*/
task;
/**
* Biome configuration file content
*/
file;
constructor(project, options = {}) {
super(project);
this.options = options;
const biomejs = `@biomejs/biome`;
project.addDevDeps(`${biomejs}@${options.version ?? "^2.5"}`);
const defaultConfig = {
...DEFAULT_CONFIG,
...((options.linter ?? true) ? DEFAULT_LINTER : {}),
...((options.formatter ?? true) ? DEFAULT_FORMATTER : {}),
...((options.assist ?? true) ? DEFAULT_ASSIST : {}),
};
this._filePatterns = new Set([
...(0, fast_json_patch_1.deepClone)(options.biomeConfig?.files?.includes ?? []),
...(0, fast_json_patch_1.deepClone)(defaultConfig.files?.includes ?? []),
]);
// Get generated file patterns to ignore
const getGeneratedIgnorePatterns = () => {
if (options.ignoreGeneratedFiles === false) {
return [];
}
const generatedFiles = this.project.files
.filter((file) => file.readonly && file.marker)
.map((file) => `!${file.path}`);
return generatedFiles;
};
this.biomeConfiguration = (0, util_1.deepMerge)([
(0, biome_config_1.toJson_BiomeConfiguration)((0, fast_json_patch_1.deepClone)(defaultConfig)),
(0, biome_config_1.toJson_BiomeConfiguration)((0, fast_json_patch_1.deepClone)(options.biomeConfig ?? {})),
{
$schema: () => {
const resolvedSchema = (0, util_2.tryResolveModule)(`${biomejs}/configuration_schema.json`, { paths: [this.project.outdir] });
if (
// not found
!resolvedSchema ||
// not within the project dir
!path
.resolve(resolvedSchema)
.startsWith(path.resolve(this.project.outdir))) {
return "https://biomejs.dev/schemas/latest/schema.json";
}
return (0, util_1.normalizePersistedPath)(path.relative(this.project.outdir, resolvedSchema));
},
files: {
includes: () => {
const patterns = Array.from(this._filePatterns);
const generatedPatterns = getGeneratedIgnorePatterns();
// Use Set to deduplicate patterns
return [...new Set([...patterns, ...generatedPatterns])];
},
},
},
], { mergeArrays: options.mergeArraysInConfiguration ?? true });
this.file = new (class extends json_1.JsonFile {
get marker() {
return `biome-ignore-all format: ${super.marker ?? "generated file"}`;
}
})(this, "biome.jsonc", {
obj: this.biomeConfiguration,
allowComments: true,
marker: true,
readonly: false, // biome will always re-write the config file
});
this.task = this.createLocalBiomeTask();
project.testTask.spawn(this.task);
}
/**
* Runs biome once, right after the project is first created, so the generated code is linted and formatted immediately.
*/
postProjectCreation(_initProject) {
this.project.tasks.runTask(this.task.name);
}
/**
* Add a file pattern to biome.
*
* Use ! or !! to ignore a file pattern.
* @param pattern Biome glob pattern
* @see https://biomejs.dev/guides/configure-biome/#control-files-via-configuration
*/
addFilePattern(pattern) {
this._filePatterns.add(pattern);
}
/**
* Add a biome override to set rules for a specific file pattern.
* @param override Override object
* @see https://biomejs.dev/reference/configuration/#overrides
*/
addOverride(override) {
if (!this.biomeConfiguration.overrides) {
this.biomeConfiguration.overrides = [];
}
this.biomeConfiguration.overrides.push((0, biome_config_1.toJson_OverridePattern)(override));
}
/**
* Expand the linting rules applied.
*
* Use `undefined` to remove the rule or group.
*
* @param rules Rules to apply.
* @see https://biomejs.dev/reference/configuration/#linterrulesgroup
* @example
* biome.expandLintingRules({
* style: undefined,
* suspicious: {
* noExplicitAny: undefined,
* noDuplicateCase: "info",
* }
* })
*/
expandLinterRules(rules) {
this.biomeConfiguration.linter.rules = (0, biome_config_1.toJson_Rules)((0, util_1.deepMerge)([this.biomeConfiguration.linter.rules, rules], {
mergeArrays: this.options.mergeArraysInConfiguration ?? true,
destructive: true,
}));
}
createLocalBiomeTask() {
return this.project.addTask("biome", {
description: "Runs Biome against the codebase",
steps: [
{
execArgs: this.biomeCommand,
receiveArgs: true,
},
],
});
}
}
exports.Biome = Biome;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmlvbWUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvamF2YXNjcmlwdC9iaW9tZS9iaW9tZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsZ0RBQWtDO0FBQ2xDLHFEQUE0QztBQUM1QywrQ0FBNEM7QUFFNUMscUNBQXNDO0FBR3RDLHFDQUErRDtBQUMvRCxrQ0FBMkM7QUFDM0MsaURBV3dCO0FBRXhCOzs7O0dBSUc7QUFDSCxNQUFNLGNBQWMsR0FBOEM7SUFDaEUsR0FBRyxFQUFFO1FBQ0gsVUFBVSxFQUFFLDRCQUFhLENBQUMsR0FBRztRQUM3QixPQUFPLEVBQUUsSUFBSTtRQUNiLGFBQWEsRUFBRSxJQUFJO0tBQ3BCO0lBQ0QsS0FBSyxFQUFFO1FBQ0wsYUFBYSxFQUFFLEtBQUs7S0FDckI7Q0FDRixDQUFDO0FBRUY7Ozs7R0FJRztBQUNILE1BQU0sY0FBYyxHQUF1QztJQUN6RCxNQUFNLEVBQUU7UUFDTixPQUFPLEVBQUUsSUFBSTtRQUNiLEtBQUssRUFBRTtZQUNMLE1BQU0sRUFBRSwyQkFBWSxDQUFDLFdBQVc7U0FDakM7S0FDRjtDQUNGLENBQUM7QUFFRjs7R0FFRztBQUNILE1BQU0saUJBQWlCLEdBQ3JCO0lBQ0UsU0FBUyxFQUFFO1FBQ1QsT0FBTyxFQUFFLElBQUk7UUFDYixXQUFXLEVBQUUsMEJBQVcsQ0FBQyxHQUFHO0tBQzdCO0lBQ0QsVUFBVSxFQUFFO1FBQ1YsU0FBUyxFQUFFO1lBQ1QsVUFBVSxFQUFFLHlCQUFVLENBQUMsTUFBTTtTQUM5QjtLQUNGO0NBQ0YsQ0FBQztBQUVKOztHQUVHO0FBQ0gsTUFBTSxjQUFjLEdBQXVDO0lBQ3pELE1BQU0sRUFBRTtRQUNOLE9BQU8sRUFBRSxJQUFJO1FBQ2IsT0FBTyxFQUFFO1lBQ1AsTUFBTSxFQUFFLDJCQUFZLENBQUMsV0FBVztTQUNqQztLQUNGO0NBQ0YsQ0FBQztBQXFERjs7R0FFRztBQUNILE1BQWEsS0FBTSxTQUFRLHFCQUFTO0lBMEJ4Qjs7SUF6QkgsTUFBTSxDQUFDLEVBQUUsQ0FBQyxPQUFnQjtRQUMvQixNQUFNLE9BQU8sR0FBRyxDQUFDLENBQVksRUFBYyxFQUFFLENBQUMsQ0FBQyxZQUFZLEtBQUssQ0FBQztRQUNqRSxPQUFPLE9BQU8sQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQzFDLENBQUM7SUFFZ0Isa0JBQWtCLENBQXNCO0lBQ3hDLGFBQWEsQ0FBYztJQUMzQixZQUFZLEdBQUc7UUFDOUIsT0FBTztRQUNQLE9BQU87UUFDUCwwQkFBMEI7UUFDMUIsU0FBUztLQUNWLENBQUM7SUFFRjs7T0FFRztJQUNhLElBQUksQ0FBTztJQUMzQjs7T0FFRztJQUNhLElBQUksQ0FBVztJQUUvQixZQUNFLE9BQW9CLEVBQ1osVUFBd0IsRUFBRTtRQUVsQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7UUFGUCxZQUFPLEdBQVAsT0FBTyxDQUFtQjtRQUlsQyxNQUFNLE9BQU8sR0FBRyxnQkFBZ0IsQ0FBQztRQUNqQyxPQUFPLENBQUMsVUFBVSxDQUFDLEdBQUcsT0FBTyxJQUFJLE9BQU8sQ0FBQyxPQUFPLElBQUksTUFBTSxFQUFFLENBQUMsQ0FBQztRQUU5RCxNQUFNLGFBQWEsR0FBdUI7WUFDeEMsR0FBRyxjQUFjO1lBQ2pCLEdBQUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQ25ELEdBQUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxTQUFTLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLGlCQUFpQixDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDekQsR0FBRyxDQUFDLENBQUMsT0FBTyxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7U0FDcEQsQ0FBQztRQUVGLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxHQUFHLENBQUM7WUFDM0IsR0FBRyxJQUFBLDJCQUFTLEVBQUMsT0FBTyxDQUFDLFdBQVcsRUFBRSxLQUFLLEVBQUUsUUFBUSxJQUFJLEVBQUUsQ0FBQztZQUN4RCxHQUFHLElBQUEsMkJBQVMsRUFBQyxhQUFhLENBQUMsS0FBSyxFQUFFLFFBQVEsSUFBSSxFQUFFLENBQUM7U0FDbEQsQ0FBQyxDQUFDO1FBRUgsd0NBQXdDO1FBQ3hDLE1BQU0sMEJBQTBCLEdBQUcsR0FBRyxFQUFFO1lBQ3RDLElBQUksT0FBTyxDQUFDLG9CQUFvQixLQUFLLEtBQUssRUFBRSxDQUFDO2dCQUMzQyxPQUFPLEVBQUUsQ0FBQztZQUNaLENBQUM7WUFFRCxNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUs7aUJBQ3RDLE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLFFBQVEsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDO2lCQUM5QyxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLElBQUksSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7WUFFbEMsT0FBTyxjQUFjLENBQUM7UUFDeEIsQ0FBQyxDQUFDO1FBRUYsSUFBSSxDQUFDLGtCQUFrQixHQUFHLElBQUEsZ0JBQVMsRUFDakM7WUFDRSxJQUFBLHdDQUF5QixFQUFDLElBQUEsMkJBQVMsRUFBQyxhQUFhLENBQUMsQ0FBQztZQUNuRCxJQUFBLHdDQUF5QixFQUFDLElBQUEsMkJBQVMsRUFBQyxPQUFPLENBQUMsV0FBVyxJQUFJLEVBQUUsQ0FBQyxDQUFDO1lBQy9EO2dCQUNFLE9BQU8sRUFBRSxHQUFHLEVBQUU7b0JBQ1osTUFBTSxjQUFjLEdBQUcsSUFBQSx1QkFBZ0IsRUFDckMsR0FBRyxPQUFPLDRCQUE0QixFQUN0QyxFQUFFLEtBQUssRUFBRSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FDakMsQ0FBQztvQkFDRjtvQkFDRSxZQUFZO29CQUNaLENBQUMsY0FBYzt3QkFDZiw2QkFBNkI7d0JBQzdCLENBQUMsSUFBSTs2QkFDRixPQUFPLENBQUMsY0FBYyxDQUFDOzZCQUN2QixVQUFVLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQ2hELENBQUM7d0JBQ0QsT0FBTyxnREFBZ0QsQ0FBQztvQkFDMUQsQ0FBQztvQkFFRCxPQUFPLElBQUEsNkJBQXNCLEVBQzNCLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsY0FBYyxDQUFDLENBQ25ELENBQUM7Z0JBQ0osQ0FBQztnQkFDRCxLQUFLLEVBQUU7b0JBQ0wsUUFBUSxFQUFFLEdBQUcsRUFBRTt3QkFDYixNQUFNLFFBQVEsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQzt3QkFDaEQsTUFBTSxpQkFBaUIsR0FBRywwQkFBMEIsRUFBRSxDQUFDO3dCQUN2RCxrQ0FBa0M7d0JBQ2xDLE9BQU8sQ0FBQyxHQUFHLElBQUksR0FBRyxDQUFDLENBQUMsR0FBRyxRQUFRLEVBQUUsR0FBRyxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsQ0FBQztvQkFDM0QsQ0FBQztpQkFDRjthQUNGO1NBQ0YsRUFDRCxFQUFFLFdBQVcsRUFBRSxPQUFPLENBQUMsMEJBQTBCLElBQUksSUFBSSxFQUFFLENBQzVELENBQUM7UUFFRixJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFNLFNBQVEsZUFBUTtZQUNyQyxJQUFXLE1BQU07Z0JBQ2YsT0FBTyw0QkFBNEIsS0FBSyxDQUFDLE1BQU0sSUFBSSxnQkFBZ0IsRUFBRSxDQUFDO1lBQ3hFLENBQUM7U0FDRixDQUFDLENBQUMsSUFBSSxFQUFFLGFBQWEsRUFBRTtZQUN0QixHQUFHLEVBQUUsSUFBSSxDQUFDLGtCQUFrQjtZQUM1QixhQUFhLEVBQUUsSUFBSTtZQUNuQixNQUFNLEVBQUUsSUFBSTtZQUNaLFFBQVEsRUFBRSxLQUFLLEVBQUUsNkNBQTZDO1NBQy9ELENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUM7UUFDeEMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3BDLENBQUM7SUFFRDs7T0FFRztJQUNJLG1CQUFtQixDQUFDLFlBQXlCO1FBQ2xELElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzdDLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSSxjQUFjLENBQUMsT0FBZTtRQUNuQyxJQUFJLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNsQyxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNJLFdBQVcsQ0FBQyxRQUF5QjtRQUMxQyxJQUFJLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQ3ZDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxTQUFTLEdBQUcsRUFBRSxDQUFDO1FBQ3pDLENBQUM7UUFFRCxJQUFJLENBQUMsa0JBQWtCLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFBLHFDQUFzQixFQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7SUFDM0UsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7Ozs7T0FlRztJQUNJLGlCQUFpQixDQUFDLEtBQVk7UUFDbkMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLE1BQU0sQ0FBQyxLQUFLLEdBQUcsSUFBQSwyQkFBWSxFQUNqRCxJQUFBLGdCQUFTLEVBQUMsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsRUFBRTtZQUN2RCxXQUFXLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQywwQkFBMEIsSUFBSSxJQUFJO1lBQzVELFdBQVcsRUFBRSxJQUFJO1NBQ2xCLENBQUMsQ0FDSCxDQUFDO0lBQ0osQ0FBQztJQUVPLG9CQUFvQjtRQUMxQixPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRTtZQUNuQyxXQUFXLEVBQUUsaUNBQWlDO1lBQzlDLEtBQUssRUFBRTtnQkFDTDtvQkFDRSxRQUFRLEVBQUUsSUFBSSxDQUFDLFlBQVk7b0JBQzNCLFdBQVcsRUFBRSxJQUFJO2lCQUNsQjthQUNGO1NBQ0YsQ0FBQyxDQUFDO0lBQ0wsQ0FBQzs7QUFqTEgsc0JBa0xDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgcGF0aCBmcm9tIFwibm9kZTpwYXRoXCI7XG5pbXBvcnQgeyBkZWVwQ2xvbmUgfSBmcm9tIFwiZmFzdC1qc29uLXBhdGNoXCI7XG5pbXBvcnQgeyBDb21wb25lbnQgfSBmcm9tIFwiLi4vLi4vY29tcG9uZW50XCI7XG5pbXBvcnQgdHlwZSB7IE5vZGVQcm9qZWN0IH0gZnJvbSBcIi4uLy4uL2phdmFzY3JpcHQvbm9kZS1wcm9qZWN0XCI7XG5pbXBvcnQgeyBKc29uRmlsZSB9IGZyb20gXCIuLi8uLi9qc29uXCI7XG5pbXBvcnQgdHlwZSB7IEluaXRQcm9qZWN0LCBQcm9qZWN0IH0gZnJvbSBcIi4uLy4uL3Byb2plY3RcIjtcbmltcG9ydCB0eXBlIHsgVGFzayB9IGZyb20gXCIuLi8uLi90YXNrXCI7XG5pbXBvcnQgeyBkZWVwTWVyZ2UsIG5vcm1hbGl6ZVBlcnNpc3RlZFBhdGggfSBmcm9tIFwiLi4vLi4vdXRpbFwiO1xuaW1wb3J0IHsgdHJ5UmVzb2x2ZU1vZHVsZSB9IGZyb20gXCIuLi91dGlsXCI7XG5pbXBvcnQge1xuICB0eXBlIEJpb21lQ29uZmlndXJhdGlvbixcbiAgSW5kZW50U3R5bGUsXG4gIHR5cGUgT3ZlcnJpZGVQYXR0ZXJuLFxuICBQcmVzZXRDb25maWcsXG4gIFF1b3RlU3R5bGUsXG4gIHR5cGUgUnVsZXMsXG4gIHRvSnNvbl9CaW9tZUNvbmZpZ3VyYXRpb24sXG4gIHRvSnNvbl9PdmVycmlkZVBhdHRlcm4sXG4gIHRvSnNvbl9SdWxlcyxcbiAgVmNzQ2xpZW50S2luZCxcbn0gZnJvbSBcIi4vYmlvbWUtY29uZmlnXCI7XG5cbi8qKlxuICogRW5hYmxpbmcgVkNTIGNvbmZpZ3VyYXRpb24gYnkgZGVmYXVsdC5cbiAqXG4gKiBOb3RlIHRoYXQgdGhpcyBkaWZmZXJzIGZyb20gYGJpb21lIGluaXRgLCBhcyBwcm9qZW4gY2FuIGJlIHByZXN1bWVkIHRvIHVzZSB2ZXJzaW9uIGNvbnRyb2xcbiAqL1xuY29uc3QgREVGQVVMVF9DT05GSUc6IFBpY2s8QmlvbWVDb25maWd1cmF0aW9uLCBcInZjc1wiIHwgXCJmaWxlc1wiPiA9IHtcbiAgdmNzOiB7XG4gICAgY2xpZW50S2luZDogVmNzQ2xpZW50S2luZC5HSVQsXG4gICAgZW5hYmxlZDogdHJ1ZSxcbiAgICB1c2VJZ25vcmVGaWxlOiB0cnVlLFxuICB9LFxuICBmaWxlczoge1xuICAgIGlnbm9yZVVua25vd246IGZhbHNlLFxuICB9LFxufTtcblxuLyoqXG4gKiBEZWZhdWx0IGxpbnRpbmcgY29uZmlndXJhdGlvbiBpZiBsaW50ZXIgaXMgZW5hYmxlZC5cbiAqXG4gKiBJZ25vcmVzIGJ5IGRlZmF1bHQgZm9sbG93aW5nIHBhdHRlcm5zOiAnKi5qcycsICcqLmQudHMnLCAnbm9kZV9tb2R1bGVzLycsICcqLmdlbmVyYXRlZC50cycsICdjb3ZlcmFnZScuXG4gKi9cbmNvbnN0IERFRkFVTFRfTElOVEVSOiBQaWNrPEJpb21lQ29uZmlndXJhdGlvbiwgXCJsaW50ZXJcIj4gPSB7XG4gIGxpbnRlcjoge1xuICAgIGVuYWJsZWQ6IHRydWUsXG4gICAgcnVsZXM6IHtcbiAgICAgIHByZXNldDogUHJlc2V0Q29uZmlnLlJFQ09NTUVOREVELFxuICAgIH0sXG4gIH0sXG59O1xuXG4vKipcbiAqIERlZmF1bHQgZm9ybWF0dGluZyBjb25maWd1cmF0aW9uIGlmIGZvcm1hdHRlciBpcyBlbmFibGVkLlxuICovXG5jb25zdCBERUZBVUxUX0ZPUk1BVFRFUjogUGljazxCaW9tZUNvbmZpZ3VyYXRpb24sIFwiZm9ybWF0dGVyXCIgfCBcImphdmFzY3JpcHRcIj4gPVxuICB7XG4gICAgZm9ybWF0dGVyOiB7XG4gICAgICBlbmFibGVkOiB0cnVlLFxuICAgICAgaW5kZW50U3R5bGU6IEluZGVudFN0eWxlLlRBQixcbiAgICB9LFxuICAgIGphdmFzY3JpcHQ6IHtcbiAgICAgIGZvcm1hdHRlcjoge1xuICAgICAgICBxdW90ZVN0eWxlOiBRdW90ZVN0eWxlLkRPVUJMRSxcbiAgICAgIH0sXG4gICAgfSxcbiAgfTtcblxuLyoqXG4gKiBEZWZhdWx0IGNvZGUgYXNzaXN0IGFjdGlvbnNcbiAqL1xuY29uc3QgREVGQVVMVF9BU1NJU1Q6IFBpY2s8QmlvbWVDb25maWd1cmF0aW9uLCBcImFzc2lzdFwiPiA9IHtcbiAgYXNzaXN0OiB7XG4gICAgZW5hYmxlZDogdHJ1ZSxcbiAgICBhY3Rpb25zOiB7XG4gICAgICBwcmVzZXQ6IFByZXNldENvbmZpZy5SRUNPTU1FTkRFRCxcbiAgICB9LFxuICB9LFxufTtcblxuZXhwb3J0IGludGVyZmFjZSBCaW9tZU9wdGlvbnMge1xuICAvKipcbiAgICogVmVyc2lvbiBvZiBCaW9tZSB0byB1c2VcbiAgICpcbiAgICogQGRlZmF1bHQgXCJeMi41XCJcbiAgICovXG4gIHJlYWRvbmx5IHZlcnNpb24/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBFbmFibGUgbGludGluZyB3aXRoIHJlY29tbWVuZGVkIHJ1bGVzLlxuICAgKlxuICAgKiBAZGVmYXVsdCB0cnVlXG4gICAqL1xuICByZWFkb25seSBsaW50ZXI/OiBib29sZWFuO1xuICAvKipcbiAgICogRW5hYmxlIGNvZGUgZm9ybWF0dGVyIHdpdGggcmVjb21tZW5kZWQgc2V0dGluZ3MuXG4gICAqXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIHJlYWRvbmx5IGZvcm1hdHRlcj86IGJvb2xlYW47XG4gIC8qKlxuICAgKiBFbmFibGUgY29kZSBhc3Npc3Qgd2l0aCByZWNvbW1lbmRlZCBhY3Rpb25zLlxuICAgKlxuICAgKiBAZGVmYXVsdCB0cnVlXG4gICAqL1xuICByZWFkb25seSBhc3Npc3Q/OiBib29sZWFuO1xuICAvKipcbiAgICogU2hvdWxkIGFycmF5cyBiZSBtZXJnZWQgb3Igb3ZlcndyaXR0ZW4gd2hlbiBjcmVhdGluZyBCaW9tZSBjb25maWd1cmF0aW9uXG4gICAqXG4gICAqIEJ5IGRlZmF1bHQgYXJyYXlzIGFyZSBtZXJnZWQgYW5kIGR1cGxpY2F0ZSB2YWx1ZXMgYXJlIHJlbW92ZWRcbiAgICpcbiAgICogQGRlZmF1bHQgdHJ1ZVxuICAgKi9cbiAgcmVhZG9ubHkgbWVyZ2VBcnJheXNJbkNvbmZpZ3VyYXRpb24/OiBib29sZWFuO1xuICAvKipcbiAgICogQXV0b21hdGljYWxseSBpZ25vcmUgYWxsIGdlbmVyYXRlZCBmaWxlcy5cbiAgICpcbiAgICogVGhpcyBwcmV2ZW50cyBCaW9tZSBmcm9tIHRyeWluZyB0byBmb3JtYXQgb3IgbGludCBmaWxlcyB0aGF0IGFyZSBtYXJrZWQgYXMgZ2VuZXJhdGVkLFxuICAgKiB3aGljaCB3b3VsZCBmYWlsIHNpbmNlIGdlbmVyYXRlZCBmaWxlcyBhcmUgdHlwaWNhbGx5IHJlYWQtb25seS5cbiAgICpcbiAgICogQGRlZmF1bHQgdHJ1ZVxuICAgKi9cbiAgcmVhZG9ubHkgaWdub3JlR2VuZXJhdGVkRmlsZXM/OiBib29sZWFuO1xuICAvKipcbiAgICogRnVsbCBCaW9tZSBjb25maWd1cmF0aW9uLlxuICAgKlxuICAgKiBUaGlzIGNvbmZpZ3VyYXRpb24gZGljdGF0ZXMgdGhlIGZpbmFsIG91dGNvbWUgaWYgdmFsdWUgaXMgc2V0LlxuICAgKiBGb3IgZXhhbXBsZSwgaWYgdGhlIGxpbnRlciBpcyBkaXNhYmxlZCBhdCB0aGUgdG9wLWxldmVsLCBpdCBjYW4gYmUgZW5hYmxlZCB3aXRoIGBiaW9tZUNvbmZpZy5saW50ZXIuZW5hYmxlZGAuXG4gICAqL1xuICByZWFkb25seSBiaW9tZUNvbmZpZz86IEJpb21lQ29uZmlndXJhdGlvbjtcbn1cblxuLyoqXG4gKiBCaW9tZSBjb21wb25lbnQuXG4gKi9cbmV4cG9ydCBjbGFzcyBCaW9tZSBleHRlbmRzIENvbXBvbmVudCB7XG4gIHB1YmxpYyBzdGF0aWMgb2YocHJvamVjdDogUHJvamVjdCk6IEJpb21lIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBpc0Jpb21lID0gKGM6IENvbXBvbmVudCk6IGMgaXMgQmlvbWUgPT4gYyBpbnN0YW5jZW9mIEJpb21lO1xuICAgIHJldHVybiBwcm9qZWN0LmNvbXBvbmVudHMuZmluZChpc0Jpb21lKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVhZG9ubHkgYmlvbWVDb25maWd1cmF0aW9uOiBSZWNvcmQ8c3RyaW5nLCBhbnk+O1xuICBwcml2YXRlIHJlYWRvbmx5IF9maWxlUGF0dGVybnM6IFNldDxzdHJpbmc+O1xuICBwcml2YXRlIHJlYWRvbmx5IGJpb21lQ29tbWFuZCA9IFtcbiAgICBcImJpb21lXCIsXG4gICAgXCJjaGVja1wiLFxuICAgIFwiLS1uby1lcnJvcnMtb24tdW5tYXRjaGVkXCIsXG4gICAgXCItLXdyaXRlXCIsXG4gIF07XG5cbiAgLyoqXG4gICAqIEJpb21lIHRhc2suXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgdGFzazogVGFzaztcbiAgLyoqXG4gICAqIEJpb21lIGNvbmZpZ3VyYXRpb24gZmlsZSBjb250ZW50XG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgZmlsZTogSnNvbkZpbGU7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJvamVjdDogTm9kZVByb2plY3QsXG4gICAgcHJpdmF0ZSBvcHRpb25zOiBCaW9tZU9wdGlvbnMgPSB7fSxcbiAgKSB7XG4gICAgc3VwZXIocHJvamVjdCk7XG5cbiAgICBjb25zdCBiaW9tZWpzID0gYEBiaW9tZWpzL2Jpb21lYDtcbiAgICBwcm9qZWN0LmFkZERldkRlcHMoYCR7YmlvbWVqc31AJHtvcHRpb25zLnZlcnNpb24gPz8gXCJeMi41XCJ9YCk7XG5cbiAgICBjb25zdCBkZWZhdWx0Q29uZmlnOiBCaW9tZUNvbmZpZ3VyYXRpb24gPSB7XG4gICAgICAuLi5ERUZBVUxUX0NPTkZJRyxcbiAgICAgIC4uLigob3B0aW9ucy5saW50ZXIgPz8gdHJ1ZSkgPyBERUZBVUxUX0xJTlRFUiA6IHt9KSxcbiAgICAgIC4uLigob3B0aW9ucy5mb3JtYXR0ZXIgPz8gdHJ1ZSkgPyBERUZBVUxUX0ZPUk1BVFRFUiA6IHt9KSxcbiAgICAgIC4uLigob3B0aW9ucy5hc3Npc3QgPz8gdHJ1ZSkgPyBERUZBVUxUX0FTU0lTVCA6IHt9KSxcbiAgICB9O1xuXG4gICAgdGhpcy5fZmlsZVBhdHRlcm5zID0gbmV3IFNldChbXG4gICAgICAuLi5kZWVwQ2xvbmUob3B0aW9ucy5iaW9tZUNvbmZpZz8uZmlsZXM/LmluY2x1ZGVzID8/IFtdKSxcbiAgICAgIC4uLmRlZXBDbG9uZShkZWZhdWx0Q29uZmlnLmZpbGVzPy5pbmNsdWRlcyA/PyBbXSksXG4gICAgXSk7XG5cbiAgICAvLyBHZXQgZ2VuZXJhdGVkIGZpbGUgcGF0dGVybnMgdG8gaWdub3JlXG4gICAgY29uc3QgZ2V0R2VuZXJhdGVkSWdub3JlUGF0dGVybnMgPSAoKSA9PiB7XG4gICAgICBpZiAob3B0aW9ucy5pZ25vcmVHZW5lcmF0ZWRGaWxlcyA9PT0gZmFsc2UpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBnZW5lcmF0ZWRGaWxlcyA9IHRoaXMucHJvamVjdC5maWxlc1xuICAgICAgICAuZmlsdGVyKChmaWxlKSA9PiBmaWxlLnJlYWRvbmx5ICYmIGZpbGUubWFya2VyKVxuICAgICAgICAubWFwKChmaWxlKSA9PiBgISR7ZmlsZS5wYXRofWApO1xuXG4gICAgICByZXR1cm4gZ2VuZXJhdGVkRmlsZXM7XG4gICAgfTtcblxuICAgIHRoaXMuYmlvbWVDb25maWd1cmF0aW9uID0gZGVlcE1lcmdlKFxuICAgICAgW1xuICAgICAgICB0b0pzb25fQmlvbWVDb25maWd1cmF0aW9uKGRlZXBDbG9uZShkZWZhdWx0Q29uZmlnKSksXG4gICAgICAgIHRvSnNvbl9CaW9tZUNvbmZpZ3VyYXRpb24oZGVlcENsb25lKG9wdGlvbnMuYmlvbWVDb25maWcgPz8ge30pKSxcbiAgICAgICAge1xuICAgICAgICAgICRzY2hlbWE6ICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHJlc29sdmVkU2NoZW1hID0gdHJ5UmVzb2x2ZU1vZHVsZShcbiAgICAgICAgICAgICAgYCR7YmlvbWVqc30vY29uZmlndXJhdGlvbl9zY2hlbWEuanNvbmAsXG4gICAgICAgICAgICAgIHsgcGF0aHM6IFt0aGlzLnByb2plY3Qub3V0ZGlyXSB9LFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgLy8gbm90IGZvdW5kXG4gICAgICAgICAgICAgICFyZXNvbHZlZFNjaGVtYSB8fFxuICAgICAgICAgICAgICAvLyBub3Qgd2l0aGluIHRoZSBwcm9qZWN0IGRpclxuICAgICAgICAgICAgICAhcGF0aFxuICAgICAgICAgICAgICAgIC5yZXNvbHZlKHJlc29sdmVkU2NoZW1hKVxuICAgICAgICAgICAgICAgIC5zdGFydHNXaXRoKHBhdGgucmVzb2x2ZSh0aGlzLnByb2plY3Qub3V0ZGlyKSlcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICByZXR1cm4gXCJodHRwczovL2Jpb21lanMuZGV2L3NjaGVtYXMvbGF0ZXN0L3NjaGVtYS5qc29uXCI7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBub3JtYWxpemVQZXJzaXN0ZWRQYXRoKFxuICAgICAgICAgICAgICBwYXRoLnJlbGF0aXZlKHRoaXMucHJvamVjdC5vdXRkaXIsIHJlc29sdmVkU2NoZW1hKSxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSxcbiAgICAgICAgICBmaWxlczoge1xuICAgICAgICAgICAgaW5jbHVkZXM6ICgpID0+IHtcbiAgICAgICAgICAgICAgY29uc3QgcGF0dGVybnMgPSBBcnJheS5mcm9tKHRoaXMuX2ZpbGVQYXR0ZXJucyk7XG4gICAgICAgICAgICAgIGNvbnN0IGdlbmVyYXRlZFBhdHRlcm5zID0gZ2V0R2VuZXJhdGVkSWdub3JlUGF0dGVybnMoKTtcbiAgICAgICAgICAgICAgLy8gVXNlIFNldCB0byBkZWR1cGxpY2F0ZSBwYXR0ZXJuc1xuICAgICAgICAgICAgICByZXR1cm4gWy4uLm5ldyBTZXQoWy4uLnBhdHRlcm5zLCAuLi5nZW5lcmF0ZWRQYXR0ZXJuc10pXTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgICB7IG1lcmdlQXJyYXlzOiBvcHRpb25zLm1lcmdlQXJyYXlzSW5Db25maWd1cmF0aW9uID8/IHRydWUgfSxcbiAgICApO1xuXG4gICAgdGhpcy5maWxlID0gbmV3IChjbGFzcyBleHRlbmRzIEpzb25GaWxlIHtcbiAgICAgIHB1YmxpYyBnZXQgbWFya2VyKCk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgICAgIHJldHVybiBgYmlvbWUtaWdub3JlLWFsbCBmb3JtYXQ6ICR7c3VwZXIubWFya2VyID8/IFwiZ2VuZXJhdGVkIGZpbGVcIn1gO1xuICAgICAgfVxuICAgIH0pKHRoaXMsIFwiYmlvbWUuanNvbmNcIiwge1xuICAgICAgb2JqOiB0aGlzLmJpb21lQ29uZmlndXJhdGlvbixcbiAgICAgIGFsbG93Q29tbWVudHM6IHRydWUsXG4gICAgICBtYXJrZXI6IHRydWUsXG4gICAgICByZWFkb25seTogZmFsc2UsIC8vIGJpb21lIHdpbGwgYWx3YXlzIHJlLXdyaXRlIHRoZSBjb25maWcgZmlsZVxuICAgIH0pO1xuXG4gICAgdGhpcy50YXNrID0gdGhpcy5jcmVhdGVMb2NhbEJpb21lVGFzaygpO1xuICAgIHByb2plY3QudGVzdFRhc2suc3Bhd24odGhpcy50YXNrKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGJpb21lIG9uY2UsIHJpZ2h0IGFmdGVyIHRoZSBwcm9qZWN0IGlzIGZpcnN0IGNyZWF0ZWQsIHNvIHRoZSBnZW5lcmF0ZWQgY29kZSBpcyBsaW50ZWQgYW5kIGZvcm1hdHRlZCBpbW1lZGlhdGVseS5cbiAgICovXG4gIHB1YmxpYyBwb3N0UHJvamVjdENyZWF0aW9uKF9pbml0UHJvamVjdDogSW5pdFByb2plY3QpIHtcbiAgICB0aGlzLnByb2plY3QudGFza3MucnVuVGFzayh0aGlzLnRhc2submFtZSk7XG4gIH1cblxuICAvKipcbiAgICogQWRkIGEgZmlsZSBwYXR0ZXJuIHRvIGJpb21lLlxuICAgKlxuICAgKiBVc2UgISBvciAhISB0byBpZ25vcmUgYSBmaWxlIHBhdHRlcm4uXG4gICAqIEBwYXJhbSBwYXR0ZXJuIEJpb21lIGdsb2IgcGF0dGVyblxuICAgKiBAc2VlIGh0dHBzOi8vYmlvbWVqcy5kZXYvZ3VpZGVzL2NvbmZpZ3VyZS1iaW9tZS8jY29udHJvbC1maWxlcy12aWEtY29uZmlndXJhdGlvblxuICAgKi9cbiAgcHVibGljIGFkZEZpbGVQYXR0ZXJuKHBhdHRlcm46IHN0cmluZykge1xuICAgIHRoaXMuX2ZpbGVQYXR0ZXJucy5hZGQocGF0dGVybik7XG4gIH1cblxuICAvKipcbiAgICogQWRkIGEgYmlvbWUgb3ZlcnJpZGUgdG8gc2V0IHJ1bGVzIGZvciBhIHNwZWNpZmljIGZpbGUgcGF0dGVybi5cbiAgICogQHBhcmFtIG92ZXJyaWRlIE92ZXJyaWRlIG9iamVjdFxuICAgKiBAc2VlIGh0dHBzOi8vYmlvbWVqcy5kZXYvcmVmZXJlbmNlL2NvbmZpZ3VyYXRpb24vI292ZXJyaWRlc1xuICAgKi9cbiAgcHVibGljIGFkZE92ZXJyaWRlKG92ZXJyaWRlOiBPdmVycmlkZVBhdHRlcm4pIHtcbiAgICBpZiAoIXRoaXMuYmlvbWVDb25maWd1cmF0aW9uLm92ZXJyaWRlcykge1xuICAgICAgdGhpcy5iaW9tZUNvbmZpZ3VyYXRpb24ub3ZlcnJpZGVzID0gW107XG4gICAgfVxuXG4gICAgdGhpcy5iaW9tZUNvbmZpZ3VyYXRpb24ub3ZlcnJpZGVzLnB1c2godG9Kc29uX092ZXJyaWRlUGF0dGVybihvdmVycmlkZSkpO1xuICB9XG5cbiAgLyoqXG4gICAqIEV4cGFuZCB0aGUgbGludGluZyBydWxlcyBhcHBsaWVkLlxuICAgKlxuICAgKiBVc2UgYHVuZGVmaW5lZGAgdG8gcmVtb3ZlIHRoZSBydWxlIG9yIGdyb3VwLlxuICAgKlxuICAgKiBAcGFyYW0gcnVsZXMgUnVsZXMgdG8gYXBwbHkuXG4gICAqIEBzZWUgaHR0cHM6Ly9iaW9tZWpzLmRldi9yZWZlcmVuY2UvY29uZmlndXJhdGlvbi8jbGludGVycnVsZXNncm91cFxuICAgKiBAZXhhbXBsZVxuICAgKiBiaW9tZS5leHBhbmRMaW50aW5nUnVsZXMoe1xuICAgKiAgIHN0eWxlOiB1bmRlZmluZWQsXG4gICAqICAgc3VzcGljaW91czoge1xuICAgKiAgICAgbm9FeHBsaWNpdEFueTogdW5kZWZpbmVkLFxuICAgKiAgICAgbm9EdXBsaWNhdGVDYXNlOiBcImluZm9cIixcbiAgICogICB9XG4gICAqIH0pXG4gICAqL1xuICBwdWJsaWMgZXhwYW5kTGludGVyUnVsZXMocnVsZXM6IFJ1bGVzKSB7XG4gICAgdGhpcy5iaW9tZUNvbmZpZ3VyYXRpb24ubGludGVyLnJ1bGVzID0gdG9Kc29uX1J1bGVzKFxuICAgICAgZGVlcE1lcmdlKFt0aGlzLmJpb21lQ29uZmlndXJhdGlvbi5saW50ZXIucnVsZXMsIHJ1bGVzXSwge1xuICAgICAgICBtZXJnZUFycmF5czogdGhpcy5vcHRpb25zLm1lcmdlQXJyYXlzSW5Db25maWd1cmF0aW9uID8/IHRydWUsXG4gICAgICAgIGRlc3RydWN0aXZlOiB0cnVlLFxuICAgICAgfSksXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlTG9jYWxCaW9tZVRhc2soKSB7XG4gICAgcmV0dXJuIHRoaXMucHJvamVjdC5hZGRUYXNrKFwiYmlvbWVcIiwge1xuICAgICAgZGVzY3JpcHRpb246IFwiUnVucyBCaW9tZSBhZ2FpbnN0IHRoZSBjb2RlYmFzZVwiLFxuICAgICAgc3RlcHM6IFtcbiAgICAgICAge1xuICAgICAgICAgIGV4ZWNBcmdzOiB0aGlzLmJpb21lQ29tbWFuZCxcbiAgICAgICAgICByZWNlaXZlQXJnczogdHJ1ZSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfSk7XG4gIH1cbn1cbiJdfQ==