turbo-gulp
Version:
Gulp tasks to boost high-quality projects.
192 lines (190 loc) • 32.8 kB
JavaScript
import { existsSync } from "fs";
import { Minimatch } from "minimatch";
import { posix as posixPath } from "path";
import { Readable as ReadableStream } from "stream";
import * as typescript from "typescript";
import Vinyl from "vinyl";
import { DEV_TSC_OPTIONS, mergeTscOptionsJson } from "../options/tsc";
import { OutModules } from "../options/typescript";
import { resolveProject } from "../project";
import { getBuildTypescriptTask, getBuildTypescriptWatchTask } from "../target-tasks/build-typescript";
import { getTsconfigJsonTask } from "../target-tasks/tsconfig-json";
import { generateTask as generateCleanTask } from "../task-generators/clean";
import * as copy from "../task-generators/copy";
import * as matcher from "../utils/matcher";
/**
* Generate a copy task (and the corresponding watch task) for the copy operations described by `copyOptions`
*
* @param gulp Gulp instance to use for utility methods.
* @param srcDir Base directory for source resolution.
* @param targetDir Base directory for target (build) resolution.
* @param copyOptions Simple copy operations to apply for this copy task.
* @return A tuple with the task function and corresponding watch task function.
*/
export function getCopy(gulp, srcDir, targetDir, copyOptions) {
const tasks = [];
const watchTasks = [];
for (const options of copyOptions) {
const from = options.src === undefined ? srcDir : posixPath.join(srcDir, options.src);
const files = options.files === undefined ? ["**/*"] : options.files;
const to = options.dest === undefined ? targetDir : posixPath.join(targetDir, options.dest);
const completeOptions = { from, files, to };
tasks.push(copy.generateTask(gulp, completeOptions));
watchTasks.push(() => copy.watch(gulp, completeOptions));
}
const task = gulp.parallel(tasks);
const watch = gulp.parallel(watchTasks);
return [task, watch];
}
/**
* Resolve absolute paths and dependencies for the provided target.
*
* @param target Non-resolved target.
* @return Resolved target.
*/
export function resolveTargetBase(target) {
const project = resolveProject(target.project);
const srcDir = typeof target.srcDir === "string" ?
posixPath.join(project.absRoot, target.srcDir) :
project.srcDir;
const buildDir = typeof target.buildDir === "string" ?
posixPath.join(project.absRoot, target.buildDir) :
posixPath.join(project.absBuildDir, target.name);
const scripts = [];
if (target.scripts === undefined) {
scripts.push(posixPath.join(srcDir, "**", "*.ts"));
}
else {
for (const script of target.scripts) {
scripts.push(matcher.asString(matcher.join(srcDir, new Minimatch(script))));
}
}
const defaultCustomTypingsDir = posixPath.join(srcDir, "custom-typings");
const customTypingsDir = target.customTypingsDir !== undefined ?
(target.customTypingsDir !== null ? posixPath.join(project.absRoot, target.customTypingsDir) : null) :
(existsSync(defaultCustomTypingsDir) ? defaultCustomTypingsDir : null);
const tscOptions = mergeTscOptionsJson(DEV_TSC_OPTIONS, target.tscOptions);
const outModules = target.outModules !== undefined ? target.outModules : OutModules.Js;
const tsconfigJson = target.tsconfigJson !== undefined ?
(target.tsconfigJson !== null ? posixPath.join(project.absRoot, target.tsconfigJson) : null) :
posixPath.join(srcDir, "tsconfig.json");
const dependencies = { typescript };
if (target.dependencies !== undefined) {
Object.assign(dependencies, target.dependencies);
}
return {
project,
name: target.name,
srcDir,
buildDir,
scripts,
customTypingsDir,
tscOptions,
outModules,
tsconfigJson,
dependencies,
copy: target.copy,
clean: target.clean,
};
}
/**
* Adds a display name to the supplied task function and returns the task function.
*
* @param name The display name to set.
* @param task The task function to name.
* @return The input task, with its `displayName` property set to `name`.
*/
export function nameTask(name, task) {
task.displayName = name;
return task;
}
/**
* Name a task function and register it to the provided gulp instance.
*/
export function addTask(gulp, displayName, task) {
gulp.task(nameTask(displayName, task));
return task;
}
/**
* Creates a Vinyl stream source from a Buffer.
*/
export function gulpBufferSrc(filename, data) {
const src = new ReadableStream({ objectMode: true });
src._read = function () {
this.push(new Vinyl({
path: filename,
contents: data,
}));
this.push(null);
};
return src;
}
/**
* Generates gulp tasks available for every target (base tasks).
*
* @param gulp Gulp instance used to generate tasks manipulating files.
* @param targetOptions Target configuration.
*/
export function generateBaseTasks(gulp, targetOptions) {
const target = resolveTargetBase(targetOptions);
const result = {};
// Typescript options
const tsOptions = {
tscOptions: target.tscOptions,
tsconfigJson: target.tsconfigJson,
customTypingsDir: target.customTypingsDir,
packageJson: target.project.absPackageJson,
buildDir: target.buildDir,
srcDir: target.srcDir,
scripts: target.scripts,
outModules: target.outModules,
};
const watchTasks = [];
// build:scripts
result.buildScripts = nameTask(`${target.name}:build:scripts`, getBuildTypescriptTask(gulp, tsOptions));
watchTasks.push(nameTask(`${target.name}:watch:scripts`, getBuildTypescriptWatchTask(gulp, tsOptions)));
// build:copy
if (target.copy !== undefined) {
const [copyTask, copyWatchTask] = getCopy(gulp, target.srcDir, target.buildDir, target.copy);
result.buildCopy = nameTask(`${target.name}:build:copy`, copyTask);
watchTasks.push(nameTask(`${target.name}:watch:copy`, copyWatchTask));
}
// build
const buildTasks = [result.buildScripts];
if (result.buildCopy !== undefined) {
buildTasks.push(result.buildCopy);
}
result.build = nameTask(`${target.name}:build`, gulp.parallel(buildTasks));
result.watch = nameTask(`${target.name}:watch`, gulp.series(result.build, gulp.parallel(watchTasks)));
// clean
if (target.clean !== undefined) {
const cleanOptions = {
base: target.project.absRoot,
dirs: target.clean.dirs,
files: target.clean.files,
};
result.clean = nameTask(`${target.name}:clean`, generateCleanTask(gulp, cleanOptions));
}
// tsconfig.json
if (target.tsconfigJson !== null) {
result.tsconfigJson = nameTask(`${target.name}:tsconfig.json`, getTsconfigJsonTask(tsOptions));
}
return result;
}
/**
* Generates and registers gulp tasks available for every target (base tasks).
*
* @param gulp Gulp instance where the tasks will be registered.
* @param targetOptions Target configuration.
*/
export function registerBaseTasks(gulp, targetOptions) {
const tasks = generateBaseTasks(gulp, targetOptions);
for (const key in tasks) {
const task = tasks[key];
if (task !== undefined) {
gulp.task(task);
}
}
return tasks;
}
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIl9zcmMvdGFyZ2V0cy9fYmFzZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFhLE1BQU0sSUFBSSxDQUFDO0FBRTNDLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDdEMsT0FBTyxFQUFFLEtBQUssSUFBSSxTQUFTLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDMUMsT0FBTyxFQUFFLFFBQVEsSUFBSSxjQUFjLEVBQUUsTUFBTSxRQUFRLENBQUM7QUFDcEQsT0FBTyxLQUFLLFVBQVUsTUFBTSxZQUFZLENBQUM7QUFDekMsT0FBTyxLQUFLLE1BQU0sT0FBTyxDQUFDO0FBRzFCLE9BQU8sRUFBdUIsZUFBZSxFQUFFLG1CQUFtQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDM0YsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ25ELE9BQU8sRUFBNEIsY0FBYyxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBRXRFLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSwyQkFBMkIsRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBQ3ZHLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQ3BFLE9BQU8sRUFBaUMsWUFBWSxJQUFJLGlCQUFpQixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDNUcsT0FBTyxLQUFLLElBQUksTUFBTSx5QkFBeUIsQ0FBQztBQUVoRCxPQUFPLEtBQUssT0FBTyxNQUFNLGtCQUFrQixDQUFDO0FBSTVDOzs7Ozs7OztHQVFHO0FBQ0gsTUFBTSxrQkFDSixJQUFVLEVBQ1YsTUFBYyxFQUNkLFNBQWlCLEVBQ2pCLFdBQWtDO0lBRWxDLE1BQU0sS0FBSyxHQUFtQixFQUFFLENBQUM7SUFDakMsTUFBTSxVQUFVLEdBQXdCLEVBQUUsQ0FBQztJQUMzQyxLQUFLLE1BQU0sT0FBTyxJQUFJLFdBQVcsRUFBRTtRQUNqQyxNQUFNLElBQUksR0FBVyxPQUFPLENBQUMsR0FBRyxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDOUYsTUFBTSxLQUFLLEdBQWEsT0FBTyxDQUFDLEtBQUssS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUM7UUFDL0UsTUFBTSxFQUFFLEdBQVcsT0FBTyxDQUFDLElBQUksS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBRXBHLE1BQU0sZUFBZSxHQUFpQixFQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsRUFBRSxFQUFDLENBQUM7UUFDeEQsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxlQUFlLENBQUMsQ0FBQyxDQUFDO1FBQ3JELFVBQVUsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsZUFBZSxDQUFDLENBQUMsQ0FBQztLQUMxRDtJQUVELE1BQU0sSUFBSSxHQUFpQixJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ2hELE1BQU0sS0FBSyxHQUFpQixJQUFJLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ3RELE9BQU8sQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUM7QUFDdkIsQ0FBQztBQWlJRDs7Ozs7R0FLRztBQUNILE1BQU0sNEJBQTRCLE1BQWtCO0lBQ2xELE1BQU0sT0FBTyxHQUFvQixjQUFjLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBRWhFLE1BQU0sTUFBTSxHQUFpQixPQUFPLE1BQU0sQ0FBQyxNQUFNLEtBQUssUUFBUSxDQUFDLENBQUM7UUFDOUQsU0FBUyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO1FBQ2hELE9BQU8sQ0FBQyxNQUFNLENBQUM7SUFFakIsTUFBTSxRQUFRLEdBQWlCLE9BQU8sTUFBTSxDQUFDLFFBQVEsS0FBSyxRQUFRLENBQUMsQ0FBQztRQUNsRSxTQUFTLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7UUFDbEQsU0FBUyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUVuRCxNQUFNLE9BQU8sR0FBYSxFQUFFLENBQUM7SUFDN0IsSUFBSSxNQUFNLENBQUMsT0FBTyxLQUFLLFNBQVMsRUFBRTtRQUNoQyxPQUFPLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDO0tBQ3BEO1NBQU07UUFDTCxLQUFLLE1BQU0sTUFBTSxJQUFJLE1BQU0sQ0FBQyxPQUFPLEVBQUU7WUFDbkMsT0FBTyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLElBQUksU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1NBQzdFO0tBQ0Y7SUFFRCxNQUFNLHVCQUF1QixHQUFpQixTQUFTLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDO0lBRXZGLE1BQU0sZ0JBQWdCLEdBQXdCLE1BQU0sQ0FBQyxnQkFBZ0IsS0FBSyxTQUFTLENBQUMsQ0FBQztRQUNuRixDQUFDLE1BQU0sQ0FBQyxnQkFBZ0IsS0FBSyxJQUFJLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUN0RyxDQUFDLFVBQVUsQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7SUFFekUsTUFBTSxVQUFVLEdBQXdCLG1CQUFtQixDQUFDLGVBQWUsRUFBRSxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUM7SUFFaEcsTUFBTSxVQUFVLEdBQWUsTUFBTSxDQUFDLFVBQVUsS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUM7SUFFbkcsTUFBTSxZQUFZLEdBQXdCLE1BQU0sQ0FBQyxZQUFZLEtBQUssU0FBUyxDQUFDLENBQUM7UUFDM0UsQ0FBQyxNQUFNLENBQUMsWUFBWSxLQUFLLElBQUksQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUM5RixTQUFTLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxlQUFlLENBQUMsQ0FBQztJQUUxQyxNQUFNLFlBQVksR0FBNkIsRUFBQyxVQUFVLEVBQUMsQ0FBQztJQUM1RCxJQUFJLE1BQU0sQ0FBQyxZQUFZLEtBQUssU0FBUyxFQUFFO1FBQ3JDLE1BQU0sQ0FBQyxNQUFNLENBQUMsWUFBWSxFQUFFLE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQztLQUNsRDtJQUVELE9BQU87UUFDTCxPQUFPO1FBQ1AsSUFBSSxFQUFFLE1BQU0sQ0FBQyxJQUFJO1FBQ2pCLE1BQU07UUFDTixRQUFRO1FBQ1IsT0FBTztRQUNQLGdCQUFnQjtRQUNoQixVQUFVO1FBQ1YsVUFBVTtRQUNWLFlBQVk7UUFDWixZQUFZO1FBQ1osSUFBSSxFQUFFLE1BQU0sQ0FBQyxJQUFJO1FBQ2pCLEtBQUssRUFBRSxNQUFNLENBQUMsS0FBSztLQUNwQixDQUFDO0FBQ0osQ0FBQztBQUVEOzs7Ozs7R0FNRztBQUNILE1BQU0sbUJBQTJDLElBQVksRUFBRSxJQUFPO0lBQ3BFLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDO0lBQ3hCLE9BQW1DLElBQUksQ0FBQztBQUMxQyxDQUFDO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLGtCQUFrQixJQUFVLEVBQUUsV0FBbUIsRUFBRSxJQUFrQjtJQUN6RSxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxXQUFXLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQztJQUN2QyxPQUFPLElBQUksQ0FBQztBQUNkLENBQUM7QUFFRDs7R0FFRztBQUNILE1BQU0sd0JBQXdCLFFBQWdCLEVBQUUsSUFBWTtJQUMxRCxNQUFNLEdBQUcsR0FBbUIsSUFBSSxjQUFjLENBQUMsRUFBQyxVQUFVLEVBQUUsSUFBSSxFQUFDLENBQUMsQ0FBQztJQUNuRSxHQUFHLENBQUMsS0FBSyxHQUFHO1FBQ1YsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEtBQUssQ0FBQztZQUNsQixJQUFJLEVBQUUsUUFBUTtZQUNkLFFBQVEsRUFBRSxJQUFJO1NBQ2YsQ0FBQyxDQUFDLENBQUM7UUFDSixJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ2xCLENBQUMsQ0FBQztJQUNGLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQWNEOzs7OztHQUtHO0FBQ0gsTUFBTSw0QkFBNEIsSUFBVSxFQUFFLGFBQXlCO0lBQ3JFLE1BQU0sTUFBTSxHQUF1QixpQkFBaUIsQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUVwRSxNQUFNLE1BQU0sR0FBb0IsRUFBRSxDQUFDO0lBRW5DLHFCQUFxQjtJQUNyQixNQUFNLFNBQVMsR0FBcUI7UUFDbEMsVUFBVSxFQUFFLE1BQU0sQ0FBQyxVQUFVO1FBQzdCLFlBQVksRUFBRSxNQUFNLENBQUMsWUFBWTtRQUNqQyxnQkFBZ0IsRUFBRSxNQUFNLENBQUMsZ0JBQWdCO1FBQ3pDLFdBQVcsRUFBRSxNQUFNLENBQUMsT0FBTyxDQUFDLGNBQWM7UUFDMUMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxRQUFRO1FBQ3pCLE1BQU0sRUFBRSxNQUFNLENBQUMsTUFBTTtRQUNyQixPQUFPLEVBQUUsTUFBTSxDQUFDLE9BQU87UUFDdkIsVUFBVSxFQUFFLE1BQU0sQ0FBQyxVQUFVO0tBQzlCLENBQUM7SUFFRixNQUFNLFVBQVUsR0FBbUIsRUFBRSxDQUFDO0lBRXRDLGdCQUFnQjtJQUNoQixNQUFNLENBQUMsWUFBWSxHQUFHLFFBQVEsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxJQUFJLGdCQUFnQixFQUFFLHNCQUFzQixDQUFDLElBQUksRUFBRSxTQUFTLENBQUMsQ0FBQyxDQUFDO0lBQ3hHLFVBQVUsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsTUFBTSxDQUFDLElBQUksZ0JBQWdCLEVBQUUsMkJBQTJCLENBQUMsSUFBSSxFQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUV4RyxhQUFhO0lBQ2IsSUFBSSxNQUFNLENBQUMsSUFBSSxLQUFLLFNBQVMsRUFBRTtRQUM3QixNQUFNLENBQUMsUUFBUSxFQUFFLGFBQWEsQ0FBQyxHQUFpQyxPQUFPLENBQ3JFLElBQUksRUFDSixNQUFNLENBQUMsTUFBTSxFQUNiLE1BQU0sQ0FBQyxRQUFRLEVBQ2YsTUFBTSxDQUFDLElBQUksQ0FDWixDQUFDO1FBQ0YsTUFBTSxDQUFDLFNBQVMsR0FBRyxRQUFRLENBQUMsR0FBRyxNQUFNLENBQUMsSUFBSSxhQUFhLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDbkUsVUFBVSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxNQUFNLENBQUMsSUFBSSxhQUFhLEVBQUUsYUFBYSxDQUFDLENBQUMsQ0FBQztLQUN2RTtJQUVELFFBQVE7SUFDUixNQUFNLFVBQVUsR0FBbUIsQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLENBQUM7SUFDekQsSUFBSSxNQUFNLENBQUMsU0FBUyxLQUFLLFNBQVMsRUFBRTtRQUNsQyxVQUFVLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQztLQUNuQztJQUNELE1BQU0sQ0FBQyxLQUFLLEdBQUcsUUFBUSxDQUFDLEdBQUcsTUFBTSxDQUFDLElBQUksUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQztJQUMzRSxNQUFNLENBQUMsS0FBSyxHQUFHLFFBQVEsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxJQUFJLFFBQVEsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFFdEcsUUFBUTtJQUNSLElBQUksTUFBTSxDQUFDLEtBQUssS0FBSyxTQUFTLEVBQUU7UUFDOUIsTUFBTSxZQUFZLEdBQWtCO1lBQ2xDLElBQUksRUFBRSxNQUFNLENBQUMsT0FBTyxDQUFDLE9BQU87WUFDNUIsSUFBSSxFQUFFLE1BQU0sQ0FBQyxLQUFLLENBQUMsSUFBSTtZQUN2QixLQUFLLEVBQUUsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLO1NBQzFCLENBQUM7UUFDRixNQUFNLENBQUMsS0FBSyxHQUFHLFFBQVEsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxJQUFJLFFBQVEsRUFBRSxpQkFBaUIsQ0FBQyxJQUFJLEVBQUUsWUFBWSxDQUFDLENBQUMsQ0FBQztLQUN4RjtJQUVELGdCQUFnQjtJQUNoQixJQUFJLE1BQU0sQ0FBQyxZQUFZLEtBQUssSUFBSSxFQUFFO1FBQ2hDLE1BQU0sQ0FBQyxZQUFZLEdBQUcsUUFBUSxDQUFDLEdBQUcsTUFBTSxDQUFDLElBQUksZ0JBQWdCLEVBQUUsbUJBQW1CLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQztLQUNoRztJQUVELE9BQU8sTUFBTSxDQUFDO0FBQ2hCLENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILE1BQU0sNEJBQTRCLElBQVUsRUFBRSxhQUF5QjtJQUNyRSxNQUFNLEtBQUssR0FBYyxpQkFBaUIsQ0FBQyxJQUFJLEVBQUUsYUFBYSxDQUFDLENBQUM7SUFDaEUsS0FBSyxNQUFNLEdBQUcsSUFBSSxLQUFLLEVBQUU7UUFDdkIsTUFBTSxJQUFJLEdBQW9DLEtBQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUMxRCxJQUFJLElBQUksS0FBSyxTQUFTLEVBQUU7WUFDdEIsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztTQUNqQjtLQUNGO0lBQ0QsT0FBTyxLQUFLLENBQUM7QUFDZixDQUFDIiwiZmlsZSI6InRhcmdldHMvX2Jhc2UuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBleGlzdHNTeW5jLCBGU1dhdGNoZXIgfSBmcm9tIFwiZnNcIjtcbmltcG9ydCB7IEd1bHAsIFRhc2tGdW5jdGlvbiB9IGZyb20gXCJndWxwXCI7XG5pbXBvcnQgeyBNaW5pbWF0Y2ggfSBmcm9tIFwibWluaW1hdGNoXCI7XG5pbXBvcnQgeyBwb3NpeCBhcyBwb3NpeFBhdGggfSBmcm9tIFwicGF0aFwiO1xuaW1wb3J0IHsgUmVhZGFibGUgYXMgUmVhZGFibGVTdHJlYW0gfSBmcm9tIFwic3RyZWFtXCI7XG5pbXBvcnQgKiBhcyB0eXBlc2NyaXB0IGZyb20gXCJ0eXBlc2NyaXB0XCI7XG5pbXBvcnQgVmlueWwgZnJvbSBcInZpbnlsXCI7XG5pbXBvcnQgeyBDbGVhbk9wdGlvbnMgfSBmcm9tIFwiLi4vb3B0aW9ucy9jbGVhblwiO1xuaW1wb3J0IHsgQ29weU9wdGlvbnMgfSBmcm9tIFwiLi4vb3B0aW9ucy9jb3B5XCI7XG5pbXBvcnQgeyBDb21waWxlck9wdGlvbnNKc29uLCBERVZfVFNDX09QVElPTlMsIG1lcmdlVHNjT3B0aW9uc0pzb24gfSBmcm9tIFwiLi4vb3B0aW9ucy90c2NcIjtcbmltcG9ydCB7IE91dE1vZHVsZXMgfSBmcm9tIFwiLi4vb3B0aW9ucy90eXBlc2NyaXB0XCI7XG5pbXBvcnQgeyBQcm9qZWN0LCBSZXNvbHZlZFByb2plY3QsIHJlc29sdmVQcm9qZWN0IH0gZnJvbSBcIi4uL3Byb2plY3RcIjtcbmltcG9ydCB7IFR5cGVzY3JpcHRDb25maWcgfSBmcm9tIFwiLi4vdGFyZ2V0LXRhc2tzL190eXBlc2NyaXB0XCI7XG5pbXBvcnQgeyBnZXRCdWlsZFR5cGVzY3JpcHRUYXNrLCBnZXRCdWlsZFR5cGVzY3JpcHRXYXRjaFRhc2sgfSBmcm9tIFwiLi4vdGFyZ2V0LXRhc2tzL2J1aWxkLXR5cGVzY3JpcHRcIjtcbmltcG9ydCB7IGdldFRzY29uZmlnSnNvblRhc2sgfSBmcm9tIFwiLi4vdGFyZ2V0LXRhc2tzL3RzY29uZmlnLWpzb25cIjtcbmltcG9ydCB7IENsZWFuT3B0aW9ucyBhcyBfQ2xlYW5PcHRpb25zLCBnZW5lcmF0ZVRhc2sgYXMgZ2VuZXJhdGVDbGVhblRhc2sgfSBmcm9tIFwiLi4vdGFzay1nZW5lcmF0b3JzL2NsZWFuXCI7XG5pbXBvcnQgKiBhcyBjb3B5IGZyb20gXCIuLi90YXNrLWdlbmVyYXRvcnMvY29weVwiO1xuaW1wb3J0IHsgQWJzUG9zaXhQYXRoLCBSZWxQb3NpeFBhdGggfSBmcm9tIFwiLi4vdHlwZXNcIjtcbmltcG9ydCAqIGFzIG1hdGNoZXIgZnJvbSBcIi4uL3V0aWxzL21hdGNoZXJcIjtcblxuZXhwb3J0IHR5cGUgV2F0Y2hUYXNrRnVuY3Rpb24gPSAoVGFza0Z1bmN0aW9uICYgKCgpID0+IEZTV2F0Y2hlcikpO1xuXG4vKipcbiAqIEdlbmVyYXRlIGEgY29weSB0YXNrIChhbmQgdGhlIGNvcnJlc3BvbmRpbmcgd2F0Y2ggdGFzaykgZm9yIHRoZSBjb3B5IG9wZXJhdGlvbnMgZGVzY3JpYmVkIGJ5IGBjb3B5T3B0aW9uc2BcbiAqXG4gKiBAcGFyYW0gZ3VscCBHdWxwIGluc3RhbmNlIHRvIHVzZSBmb3IgdXRpbGl0eSBtZXRob2RzLlxuICogQHBhcmFtIHNyY0RpciBCYXNlIGRpcmVjdG9yeSBmb3Igc291cmNlIHJlc29sdXRpb24uXG4gKiBAcGFyYW0gdGFyZ2V0RGlyIEJhc2UgZGlyZWN0b3J5IGZvciB0YXJnZXQgKGJ1aWxkKSByZXNvbHV0aW9uLlxuICogQHBhcmFtIGNvcHlPcHRpb25zIFNpbXBsZSBjb3B5IG9wZXJhdGlvbnMgdG8gYXBwbHkgZm9yIHRoaXMgY29weSB0YXNrLlxuICogQHJldHVybiBBIHR1cGxlIHdpdGggdGhlIHRhc2sgZnVuY3Rpb24gYW5kIGNvcnJlc3BvbmRpbmcgd2F0Y2ggdGFzayBmdW5jdGlvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldENvcHkoXG4gIGd1bHA6IEd1bHAsXG4gIHNyY0Rpcjogc3RyaW5nLFxuICB0YXJnZXREaXI6IHN0cmluZyxcbiAgY29weU9wdGlvbnM6IEl0ZXJhYmxlPENvcHlPcHRpb25zPixcbik6IFtUYXNrRnVuY3Rpb24sIFRhc2tGdW5jdGlvbl0ge1xuICBjb25zdCB0YXNrczogVGFza0Z1bmN0aW9uW10gPSBbXTtcbiAgY29uc3Qgd2F0Y2hUYXNrczogV2F0Y2hUYXNrRnVuY3Rpb25bXSA9IFtdO1xuICBmb3IgKGNvbnN0IG9wdGlvbnMgb2YgY29weU9wdGlvbnMpIHtcbiAgICBjb25zdCBmcm9tOiBzdHJpbmcgPSBvcHRpb25zLnNyYyA9PT0gdW5kZWZpbmVkID8gc3JjRGlyIDogcG9zaXhQYXRoLmpvaW4oc3JjRGlyLCBvcHRpb25zLnNyYyk7XG4gICAgY29uc3QgZmlsZXM6IHN0cmluZ1tdID0gb3B0aW9ucy5maWxlcyA9PT0gdW5kZWZpbmVkID8gW1wiKiovKlwiXSA6IG9wdGlvbnMuZmlsZXM7XG4gICAgY29uc3QgdG86IHN0cmluZyA9IG9wdGlvbnMuZGVzdCA9PT0gdW5kZWZpbmVkID8gdGFyZ2V0RGlyIDogcG9zaXhQYXRoLmpvaW4odGFyZ2V0RGlyLCBvcHRpb25zLmRlc3QpO1xuXG4gICAgY29uc3QgY29tcGxldGVPcHRpb25zOiBjb3B5Lk9wdGlvbnMgPSB7ZnJvbSwgZmlsZXMsIHRvfTtcbiAgICB0YXNrcy5wdXNoKGNvcHkuZ2VuZXJhdGVUYXNrKGd1bHAsIGNvbXBsZXRlT3B0aW9ucykpO1xuICAgIHdhdGNoVGFza3MucHVzaCgoKSA9PiBjb3B5LndhdGNoKGd1bHAsIGNvbXBsZXRlT3B0aW9ucykpO1xuICB9XG5cbiAgY29uc3QgdGFzazogVGFza0Z1bmN0aW9uID0gZ3VscC5wYXJhbGxlbCh0YXNrcyk7XG4gIGNvbnN0IHdhdGNoOiBUYXNrRnVuY3Rpb24gPSBndWxwLnBhcmFsbGVsKHdhdGNoVGFza3MpO1xuICByZXR1cm4gW3Rhc2ssIHdhdGNoXTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUYXJnZXRCYXNlIHtcbiAgcHJvamVjdDogUHJvamVjdDtcblxuICAvKipcbiAgICogTmFtZSBvZiB0aGUgdGFyZ2V0LlxuICAgKiBBbGwgdGhlIHRhc2tzIHJlbGF0ZWQgdG8gdGhpcyB0YXJnZXQgd2lsbCBiZSBwcmVmaXhlZCBieSB0aGlzIG5hbWUuXG4gICAqIEl0IHdpbGwgYWxzbyBiZSB1c2VkIHRvIHJlc29sdmUgdGhlIGRlZmF1bHQgdmFsdWVzIGZvciBzb21lIHBhdGhzLCBzbyBpdCBtdXN0IGF2b2lkIGFueSBzcGVjaWFsIGNoYXJhY3RlcnMuXG4gICAqL1xuICBuYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFJlbGF0aXZlIHBhdGggdG8gdGhlIGJhc2UgZGlyZWN0b3J5IGZvciB0aGUgc291cmNlcywgcmVsYXRpdmUgdG8gYHByb2plY3Qucm9vdERpcmAuXG4gICAqIFRoZSBkZWZhdWx0IHZhbHVlIGlzIGBwcm9qZWN0LnNyY0RpcmAuXG4gICAqL1xuICBzcmNEaXI/OiBSZWxQb3NpeFBhdGg7XG5cbiAgLyoqXG4gICAqIFJlbGF0aXZlIHBhdGggdG8gdGhlIGJ1aWxkIGRpcmVjdG9yeSBmb3IgdGhpcyB0YXJnZXQsIHJlbGF0aXZlIHRvIGBwcm9qZWN0LnJvb3REaXJgLlxuICAgKiBUaGUgZGVmYXVsdCB2YWx1ZSBpcyBgam9pbihwcm9qZWN0LmJ1aWxkRGlyLCB0YXJnZXQubmFtZSlgLlxuICAgKi9cbiAgYnVpbGREaXI/OiBSZWxQb3NpeFBhdGg7XG5cbiAgLyoqXG4gICAqIEdsb2IgcGF0dGVybnMgZm9yIHRoZSBUeXBlc2NyaXB0IHNvdXJjZXMsIHJlbGF0aXZlIHRvIGB0YXJnZXQuc3JjRGlyYC5cbiAgICpcbiAgICogSXQgdXNlcyB0aGUgYG1pbmltYXRjaGAgcGF0dGVybnMuIEdsb2Igc3RhcnMgKHdpbGQgc3RhcnMsIGAqKmApIHVzZSBgdGFyZ2V0LnNyY0RpcmAgYXMgdGhlaXIgYmFzZSBkaXJlY3RvcnkuXG4gICAqXG4gICAqIERlZmF1bHQ6IGBbam9pbih0YXJnZXQuc3JjRGlyLCBcIioqXCIsIFwiKi50c1wiKV1gXG4gICAqL1xuICBzY3JpcHRzPzogSXRlcmFibGU8c3RyaW5nPjtcblxuICAvKipcbiAgICogRGlyZWN0b3J5IGNvbnRhaW5pbmcgY3VzdG9tIHR5cGluZ3MsIHJlbGF0aXZlIHRvIGBwcm9qZWN0LnJvb3REaXJgLlxuICAgKiBDdXN0b20gdHlwaW5ncyBhcmUgdHlwaW5ncyB0aGF0IGFyZSBub3QgYXZhaWxhYmxlIG9uIGBAdHlwZXNgLlxuICAgKiBgbnVsbGAgbWVhbnMgdGhhdCB5b3UgZG9uJ3QgdXNlIGN1c3RvbSB0eXBpbmdzLlxuICAgKiBUaGUgZGVmYXVsdCB2YWx1ZSB3aWxsIGJlIGBqb2luKHRhcmdldC5zcmNEaXIsIFwiY3VzdG9tLXR5cGluZ3NcIilgIGlmIGl0IGV4aXN0cyAoc3luYyB0ZXN0KSwgZWxzZSBgbnVsbGAuXG4gICAqL1xuICBjdXN0b21UeXBpbmdzRGlyPzogUmVsUG9zaXhQYXRoIHwgbnVsbDtcblxuICAvKipcbiAgICogT3ZlcnJpZGVzIGZvciB0aGUgb3B0aW9ucyBvZiB0aGUgVHlwZXNjcmlwdCBjb21waWxlci5cbiAgICovXG4gIHRzY09wdGlvbnM/OiBDb21waWxlck9wdGlvbnNKc29uO1xuXG4gIC8qKlxuICAgKiBPdXRwdXQgbW9kdWxlcy5cbiAgICpcbiAgICogLSBgSnNgOiBVc2UgdGhlIGNvbXBpbGVyIG9wdGlvbnMgdG8gZW1pdCBgKi5qc2AgZmlsZXMuXG4gICAqIC0gYE1qc2A6IEVuZm9yY2UgYGVzMjAxNWAgbW9kdWxlcyBhbmQgZW1pdCBgKi5tanNgIGZpbGVzLlxuICAgKiAtIGBCb3RoYDogRW1pdCBib3RoIGAqLmpzYCBmaWxlcyB1c2luZyB0aGUgY29tcGlsZXIgb3B0aW9ucyBhbmQgYCoubWpzYCB1c2luZyBgZXMyMDE1YC5cbiAgICpcbiAgICogRGVmYXVsdDogYEpzYFxuICAgKi9cbiAgb3V0TW9kdWxlcz86IE91dE1vZHVsZXM7XG5cbiAgLyoqXG4gICAqIFBhdGggdG8gdGhlIGB0c2NvbmZpZy5qc29uYCBmaWxlIGZvciB0aGlzIHRhcmdldCwgcmVsYXRpdmUgdG8gYHByb2plY3Qucm9vdERpcmAuXG4gICAqIFVzZSBgbnVsbGAgdG8gbm90IGdlbmVyYXRlIGEgYHRzY29uZmlnLmpzb25gIHRhc2suXG4gICAqXG4gICAqIFRoZSBkZWZhdWx0IHZhbHVlIGlzIGBqb2luKHRhcmdldC5zcmNEaXIsIFwidHNjb25maWcuanNvblwiKWAuXG4gICAqL1xuICB0c2NvbmZpZ0pzb24/OiBSZWxQb3NpeFBhdGggfCBudWxsO1xuXG4gIC8qKlxuICAgKiBPdmVycmlkZSBkZWZhdWx0IGRlcGVuZGVuY2llcyBvciBwcm92aWRlIG9wdGlvbmFsIGRlcGVuZGVuY2llcy5cbiAgICovXG4gIGRlcGVuZGVuY2llcz86IEJhc2VEZXBlbmRlbmNpZXM7XG5cbiAgLyoqXG4gICAqIEEgbGlzdCBvZiBjb3B5IG9wZXJhdGlvbnMgdG8gcGVyZm9ybSBkdXJpbmcgdGhlIGJ1aWxkIHByb2Nlc3MuXG4gICAqXG4gICAqIERlZmF1bHQ6IGBbXWBcbiAgICovXG4gIGNvcHk/OiBDb3B5T3B0aW9uc1tdO1xuXG4gIC8qKlxuICAgKiBNaW5pbWF0Y2ggcGF0dGVybnMgdG8gY2xlYW4gdGhlIGZpbGVzIGNyZWF0ZSBkdXJpbmcgdGhlIGBidWlsZGAgYW5kIGBkaXN0YCB0YXNrcywgcmVsYXRpdmUgdG8gYHByb2plY3Qucm9vdGAuXG4gICAqXG4gICAqIERlZmF1bHQ6XG4gICAqIHtcbiAgICogICBkaXJzOiBbXG4gICAqICAgICBwYXRoLmpvaW4ocHJvamVjdC5idWlsZERpciwgdGFyZ2V0LnRhcmdldERpciksXG4gICAqICAgICBwYXRoLmpvaW4ocHJvamVjdC5kaXN0RGlyLCB0YXJnZXQudGFyZ2V0RGlyKVxuICAgKiAgIF1cbiAgICogfVxuICAgKi9cbiAgY2xlYW4/OiBDbGVhbk9wdGlvbnM7XG59XG5cbi8qKlxuICogTGlicmFyeSB3aXRoIGZ1bGx5IHJlc29sdmVkIHBhdGhzIGFuZCBkZXBlbmRlbmNpZXMuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmVzb2x2ZWRUYXJnZXRCYXNlIGV4dGVuZHMgVGFyZ2V0QmFzZSB7XG4gIHJlYWRvbmx5IHByb2plY3Q6IFJlc29sdmVkUHJvamVjdDtcblxuICByZWFkb25seSBzcmNEaXI6IEFic1Bvc2l4UGF0aDtcblxuICByZWFkb25seSBidWlsZERpcjogQWJzUG9zaXhQYXRoO1xuXG4gIHJlYWRvbmx5IHNjcmlwdHM6IEl0ZXJhYmxlPHN0cmluZz47XG5cbiAgcmVhZG9ubHkgY3VzdG9tVHlwaW5nc0RpcjogQWJzUG9zaXhQYXRoIHwgbnVsbDtcblxuICByZWFkb25seSB0c2NPcHRpb25zOiBDb21waWxlck9wdGlvbnNKc29uO1xuXG4gIHJlYWRvbmx5IG91dE1vZHVsZXM6IE91dE1vZHVsZXM7XG5cbiAgcmVhZG9ubHkgdHNjb25maWdKc29uOiBBYnNQb3NpeFBhdGggfCBudWxsO1xuXG4gIHJlYWRvbmx5IGRlcGVuZGVuY2llczogUmVzb2x2ZWRCYXNlRGVwZW5kZW5jaWVzO1xuXG4gIHJlYWRvbmx5IGNvcHk/OiBDb3B5T3B0aW9uc1tdO1xuXG4gIHJlYWRvbmx5IGNsZWFuPzogQ2xlYW5PcHRpb25zO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEJhc2VEZXBlbmRlbmNpZXMge1xuICByZWFkb25seSB0eXBlc2NyaXB0PzogdHlwZW9mIHR5cGVzY3JpcHQ7XG59XG5cbi8qKlxuICogRnVsbHkgcmVzb2x2ZWQgZGVwZW5kZW5jaWVzLCBlaXRoZXIgdXNpbmcgZGVmYXVsdHMgb3IgdGhlIGxpYnJhcnkgcHJvdmlkZWQgYnkgdGhlIHVzZXIuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmVzb2x2ZWRCYXNlRGVwZW5kZW5jaWVzIGV4dGVuZHMgQmFzZURlcGVuZGVuY2llcyB7XG4gIHJlYWRvbmx5IHR5cGVzY3JpcHQ6IHR5cGVvZiB0eXBlc2NyaXB0O1xufVxuXG4vKipcbiAqIFJlc29sdmUgYWJzb2x1dGUgcGF0aHMgYW5kIGRlcGVuZGVuY2llcyBmb3IgdGhlIHByb3ZpZGVkIHRhcmdldC5cbiAqXG4gKiBAcGFyYW0gdGFyZ2V0IE5vbi1yZXNvbHZlZCB0YXJnZXQuXG4gKiBAcmV0dXJuIFJlc29sdmVkIHRhcmdldC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVUYXJnZXRCYXNlKHRhcmdldDogVGFyZ2V0QmFzZSk6IFJlc29sdmVkVGFyZ2V0QmFzZSB7XG4gIGNvbnN0IHByb2plY3Q6IFJlc29sdmVkUHJvamVjdCA9IHJlc29sdmVQcm9qZWN0KHRhcmdldC5wcm9qZWN0KTtcblxuICBjb25zdCBzcmNEaXI6IEFic1Bvc2l4UGF0aCA9IHR5cGVvZiB0YXJnZXQuc3JjRGlyID09PSBcInN0cmluZ1wiID9cbiAgICBwb3NpeFBhdGguam9pbihwcm9qZWN0LmFic1Jvb3QsIHRhcmdldC5zcmNEaXIpIDpcbiAgICBwcm9qZWN0LnNyY0RpcjtcblxuICBjb25zdCBidWlsZERpcjogQWJzUG9zaXhQYXRoID0gdHlwZW9mIHRhcmdldC5idWlsZERpciA9PT0gXCJzdHJpbmdcIiA/XG4gICAgcG9zaXhQYXRoLmpvaW4ocHJvamVjdC5hYnNSb290LCB0YXJnZXQuYnVpbGREaXIpIDpcbiAgICBwb3NpeFBhdGguam9pbihwcm9qZWN0LmFic0J1aWxkRGlyLCB0YXJnZXQubmFtZSk7XG5cbiAgY29uc3Qgc2NyaXB0czogc3RyaW5nW10gPSBbXTtcbiAgaWYgKHRhcmdldC5zY3JpcHRzID09PSB1bmRlZmluZWQpIHtcbiAgICBzY3JpcHRzLnB1c2gocG9zaXhQYXRoLmpvaW4oc3JjRGlyLCBcIioqXCIsIFwiKi50c1wiKSk7XG4gIH0gZWxzZSB7XG4gICAgZm9yIChjb25zdCBzY3JpcHQgb2YgdGFyZ2V0LnNjcmlwdHMpIHtcbiAgICAgIHNjcmlwdHMucHVzaChtYXRjaGVyLmFzU3RyaW5nKG1hdGNoZXIuam9pbihzcmNEaXIsIG5ldyBNaW5pbWF0Y2goc2NyaXB0KSkpKTtcbiAgICB9XG4gIH1cblxuICBjb25zdCBkZWZhdWx0Q3VzdG9tVHlwaW5nc0RpcjogQWJzUG9zaXhQYXRoID0gcG9zaXhQYXRoLmpvaW4oc3JjRGlyLCBcImN1c3RvbS10eXBpbmdzXCIpO1xuXG4gIGNvbnN0IGN1c3RvbVR5cGluZ3NEaXI6IEFic1Bvc2l4UGF0aCB8IG51bGwgPSB0YXJnZXQuY3VzdG9tVHlwaW5nc0RpciAhPT0gdW5kZWZpbmVkID9cbiAgICAodGFyZ2V0LmN1c3RvbVR5cGluZ3NEaXIgIT09IG51bGwgPyBwb3NpeFBhdGguam9pbihwcm9qZWN0LmFic1Jvb3QsIHRhcmdldC5jdXN0b21UeXBpbmdzRGlyKSA6IG51bGwpIDpcbiAgICAoZXhpc3RzU3luYyhkZWZhdWx0Q3VzdG9tVHlwaW5nc0RpcikgPyBkZWZhdWx0Q3VzdG9tVHlwaW5nc0RpciA6IG51bGwpO1xuXG4gIGNvbnN0IHRzY09wdGlvbnM6IENvbXBpbGVyT3B0aW9uc0pzb24gPSBtZXJnZVRzY09wdGlvbnNKc29uKERFVl9UU0NfT1BUSU9OUywgdGFyZ2V0LnRzY09wdGlvbnMpO1xuXG4gIGNvbnN0IG91dE1vZHVsZXM6IE91dE1vZHVsZXMgPSB0YXJnZXQub3V0TW9kdWxlcyAhPT0gdW5kZWZpbmVkID8gdGFyZ2V0Lm91dE1vZHVsZXMgOiBPdXRNb2R1bGVzLkpzO1xuXG4gIGNvbnN0IHRzY29uZmlnSnNvbjogQWJzUG9zaXhQYXRoIHwgbnVsbCA9IHRhcmdldC50c2NvbmZpZ0pzb24gIT09IHVuZGVmaW5lZCA/XG4gICAgKHRhcmdldC50c2NvbmZpZ0pzb24gIT09IG51bGwgPyBwb3NpeFBhdGguam9pbihwcm9qZWN0LmFic1Jvb3QsIHRhcmdldC50c2NvbmZpZ0pzb24pIDogbnVsbCkgOlxuICAgIHBvc2l4UGF0aC5qb2luKHNyY0RpciwgXCJ0c2NvbmZpZy5qc29uXCIpO1xuXG4gIGNvbnN0IGRlcGVuZGVuY2llczogUmVzb2x2ZWRCYXNlRGVwZW5kZW5jaWVzID0ge3R5cGVzY3JpcHR9O1xuICBpZiAodGFyZ2V0LmRlcGVuZGVuY2llcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgT2JqZWN0LmFzc2lnbihkZXBlbmRlbmNpZXMsIHRhcmdldC5kZXBlbmRlbmNpZXMpO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBwcm9qZWN0LFxuICAgIG5hbWU6IHRhcmdldC5uYW1lLFxuICAgIHNyY0RpcixcbiAgICBidWlsZERpcixcbiAgICBzY3JpcHRzLFxuICAgIGN1c3RvbVR5cGluZ3NEaXIsXG4gICAgdHNjT3B0aW9ucyxcbiAgICBvdXRNb2R1bGVzLFxuICAgIHRzY29uZmlnSnNvbixcbiAgICBkZXBlbmRlbmNpZXMsXG4gICAgY29weTogdGFyZ2V0LmNvcHksXG4gICAgY2xlYW46IHRhcmdldC5jbGVhbixcbiAgfTtcbn1cblxuLyoqXG4gKiBBZGRzIGEgZGlzcGxheSBuYW1lIHRvIHRoZSBzdXBwbGllZCB0YXNrIGZ1bmN0aW9uIGFuZCByZXR1cm5zIHRoZSB0YXNrIGZ1bmN0aW9uLlxuICpcbiAqIEBwYXJhbSBuYW1lIFRoZSBkaXNwbGF5IG5hbWUgdG8gc2V0LlxuICogQHBhcmFtIHRhc2sgVGhlIHRhc2sgZnVuY3Rpb24gdG8gbmFtZS5cbiAqIEByZXR1cm4gVGhlIGlucHV0IHRhc2ssIHdpdGggaXRzIGBkaXNwbGF5TmFtZWAgcHJvcGVydHkgc2V0IHRvIGBuYW1lYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5hbWVUYXNrPFQgZXh0ZW5kcyBUYXNrRnVuY3Rpb24+KG5hbWU6IHN0cmluZywgdGFzazogVCk6IFQgJiB7ZGlzcGxheU5hbWU6IHN0cmluZ30ge1xuICB0YXNrLmRpc3BsYXlOYW1lID0gbmFtZTtcbiAgcmV0dXJuIDxUICYge2Rpc3BsYXlOYW1lOiBzdHJpbmd9PiB0YXNrO1xufVxuXG4vKipcbiAqIE5hbWUgYSB0YXNrIGZ1bmN0aW9uIGFuZCByZWdpc3RlciBpdCB0byB0aGUgcHJvdmlkZWQgZ3VscCBpbnN0YW5jZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFkZFRhc2soZ3VscDogR3VscCwgZGlzcGxheU5hbWU6IHN0cmluZywgdGFzazogVGFza0Z1bmN0aW9uKTogVGFza0Z1bmN0aW9uIHtcbiAgZ3VscC50YXNrKG5hbWVUYXNrKGRpc3BsYXlOYW1lLCB0YXNrKSk7XG4gIHJldHVybiB0YXNrO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBWaW55bCBzdHJlYW0gc291cmNlIGZyb20gYSBCdWZmZXIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBndWxwQnVmZmVyU3JjKGZpbGVuYW1lOiBzdHJpbmcsIGRhdGE6IEJ1ZmZlcik6IE5vZGVKUy5SZWFkYWJsZVN0cmVhbSB7XG4gIGNvbnN0IHNyYzogUmVhZGFibGVTdHJlYW0gPSBuZXcgUmVhZGFibGVTdHJlYW0oe29iamVjdE1vZGU6IHRydWV9KTtcbiAgc3JjLl9yZWFkID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMucHVzaChuZXcgVmlueWwoe1xuICAgICAgcGF0aDogZmlsZW5hbWUsXG4gICAgICBjb250ZW50czogZGF0YSxcbiAgICB9KSk7XG4gICAgdGhpcy5wdXNoKG51bGwpO1xuICB9O1xuICByZXR1cm4gc3JjO1xufVxuXG4vKipcbiAqIEJhc2UgdGFza3MgYXZhaWxhYmxlIGZvciBldmVyeSB0YXJnZXQuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQmFzZVRhc2tzIHtcbiAgYnVpbGRTY3JpcHRzOiBUYXNrRnVuY3Rpb247XG4gIGJ1aWxkQ29weT86IFRhc2tGdW5jdGlvbjtcbiAgYnVpbGQ6IFRhc2tGdW5jdGlvbjtcbiAgd2F0Y2g/OiBUYXNrRnVuY3Rpb247XG4gIGNsZWFuPzogVGFza0Z1bmN0aW9uO1xuICB0c2NvbmZpZ0pzb24/OiBUYXNrRnVuY3Rpb247XG59XG5cbi8qKlxuICogR2VuZXJhdGVzIGd1bHAgdGFza3MgYXZhaWxhYmxlIGZvciBldmVyeSB0YXJnZXQgKGJhc2UgdGFza3MpLlxuICpcbiAqIEBwYXJhbSBndWxwIEd1bHAgaW5zdGFuY2UgdXNlZCB0byBnZW5lcmF0ZSB0YXNrcyBtYW5pcHVsYXRpbmcgZmlsZXMuXG4gKiBAcGFyYW0gdGFyZ2V0T3B0aW9ucyBUYXJnZXQgY29uZmlndXJhdGlvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdlbmVyYXRlQmFzZVRhc2tzKGd1bHA6IEd1bHAsIHRhcmdldE9wdGlvbnM6IFRhcmdldEJhc2UpOiBCYXNlVGFza3Mge1xuICBjb25zdCB0YXJnZXQ6IFJlc29sdmVkVGFyZ2V0QmFzZSA9IHJlc29sdmVUYXJnZXRCYXNlKHRhcmdldE9wdGlvbnMpO1xuXG4gIGNvbnN0IHJlc3VsdDogQmFzZVRhc2tzID0gPGFueT4ge307XG5cbiAgLy8gVHlwZXNjcmlwdCBvcHRpb25zXG4gIGNvbnN0IHRzT3B0aW9uczogVHlwZXNjcmlwdENvbmZpZyA9IHtcbiAgICB0c2NPcHRpb25zOiB0YXJnZXQudHNjT3B0aW9ucyxcbiAgICB0c2NvbmZpZ0pzb246IHRhcmdldC50c2NvbmZpZ0pzb24sXG4gICAgY3VzdG9tVHlwaW5nc0RpcjogdGFyZ2V0LmN1c3RvbVR5cGluZ3NEaXIsXG4gICAgcGFja2FnZUpzb246IHRhcmdldC5wcm9qZWN0LmFic1BhY2thZ2VKc29uLFxuICAgIGJ1aWxkRGlyOiB0YXJnZXQuYnVpbGREaXIsXG4gICAgc3JjRGlyOiB0YXJnZXQuc3JjRGlyLFxuICAgIHNjcmlwdHM6IHRhcmdldC5zY3JpcHRzLFxuICAgIG91dE1vZHVsZXM6IHRhcmdldC5vdXRNb2R1bGVzLFxuICB9O1xuXG4gIGNvbnN0IHdhdGNoVGFza3M6IFRhc2tGdW5jdGlvbltdID0gW107XG5cbiAgLy8gYnVpbGQ6c2NyaXB0c1xuICByZXN1bHQuYnVpbGRTY3JpcHRzID0gbmFtZVRhc2soYCR7dGFyZ2V0Lm5hbWV9OmJ1aWxkOnNjcmlwdHNgLCBnZXRCdWlsZFR5cGVzY3JpcHRUYXNrKGd1bHAsIHRzT3B0aW9ucykpO1xuICB3YXRjaFRhc2tzLnB1c2gobmFtZVRhc2soYCR7dGFyZ2V0Lm5hbWV9OndhdGNoOnNjcmlwdHNgLCBnZXRCdWlsZFR5cGVzY3JpcHRXYXRjaFRhc2soZ3VscCwgdHNPcHRpb25zKSkpO1xuXG4gIC8vIGJ1aWxkOmNvcHlcbiAgaWYgKHRhcmdldC5jb3B5ICE9PSB1bmRlZmluZWQpIHtcbiAgICBjb25zdCBbY29weVRhc2ssIGNvcHlXYXRjaFRhc2tdOiBbVGFza0Z1bmN0aW9uLCBUYXNrRnVuY3Rpb25dID0gZ2V0Q29weShcbiAgICAgIGd1bHAsXG4gICAgICB0YXJnZXQuc3JjRGlyLFxuICAgICAgdGFyZ2V0LmJ1aWxkRGlyLFxuICAgICAgdGFyZ2V0LmNvcHksXG4gICAgKTtcbiAgICByZXN1bHQuYnVpbGRDb3B5ID0gbmFtZVRhc2soYCR7dGFyZ2V0Lm5hbWV9OmJ1aWxkOmNvcHlgLCBjb3B5VGFzayk7XG4gICAgd2F0Y2hUYXNrcy5wdXNoKG5hbWVUYXNrKGAke3RhcmdldC5uYW1lfTp3YXRjaDpjb3B5YCwgY29weVdhdGNoVGFzaykpO1xuICB9XG5cbiAgLy8gYnVpbGRcbiAgY29uc3QgYnVpbGRUYXNrczogVGFza0Z1bmN0aW9uW10gPSBbcmVzdWx0LmJ1aWxkU2NyaXB0c107XG4gIGlmIChyZXN1bHQuYnVpbGRDb3B5ICE9PSB1bmRlZmluZWQpIHtcbiAgICBidWlsZFRhc2tzLnB1c2gocmVzdWx0LmJ1aWxkQ29weSk7XG4gIH1cbiAgcmVzdWx0LmJ1aWxkID0gbmFtZVRhc2soYCR7dGFyZ2V0Lm5hbWV9OmJ1aWxkYCwgZ3VscC5wYXJhbGxlbChidWlsZFRhc2tzKSk7XG4gIHJlc3VsdC53YXRjaCA9IG5hbWVUYXNrKGAke3RhcmdldC5uYW1lfTp3YXRjaGAsIGd1bHAuc2VyaWVzKHJlc3VsdC5idWlsZCwgZ3VscC5wYXJhbGxlbCh3YXRjaFRhc2tzKSkpO1xuXG4gIC8vIGNsZWFuXG4gIGlmICh0YXJnZXQuY2xlYW4gIT09IHVuZGVmaW5lZCkge1xuICAgIGNvbnN0IGNsZWFuT3B0aW9uczogX0NsZWFuT3B0aW9ucyA9IHtcbiAgICAgIGJhc2U6IHRhcmdldC5wcm9qZWN0LmFic1Jvb3QsXG4gICAgICBkaXJzOiB0YXJnZXQuY2xlYW4uZGlycyxcbiAgICAgIGZpbGVzOiB0YXJnZXQuY2xlYW4uZmlsZXMsXG4gICAgfTtcbiAgICByZXN1bHQuY2xlYW4gPSBuYW1lVGFzayhgJHt0YXJnZXQubmFtZX06Y2xlYW5gLCBnZW5lcmF0ZUNsZWFuVGFzayhndWxwLCBjbGVhbk9wdGlvbnMpKTtcbiAgfVxuXG4gIC8vIHRzY29uZmlnLmpzb25cbiAgaWYgKHRhcmdldC50c2NvbmZpZ0pzb24gIT09IG51bGwpIHtcbiAgICByZXN1bHQudHNjb25maWdKc29uID0gbmFtZVRhc2soYCR7dGFyZ2V0Lm5hbWV9OnRzY29uZmlnLmpzb25gLCBnZXRUc2NvbmZpZ0pzb25UYXNrKHRzT3B0aW9ucykpO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqXG4gKiBHZW5lcmF0ZXMgYW5kIHJlZ2lzdGVycyBndWxwIHRhc2tzIGF2YWlsYWJsZSBmb3IgZXZlcnkgdGFyZ2V0IChiYXNlIHRhc2tzKS5cbiAqXG4gKiBAcGFyYW0gZ3VscCBHdWxwIGluc3RhbmNlIHdoZXJlIHRoZSB0YXNrcyB3aWxsIGJlIHJlZ2lzdGVyZWQuXG4gKiBAcGFyYW0gdGFyZ2V0T3B0aW9ucyBUYXJnZXQgY29uZmlndXJhdGlvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlZ2lzdGVyQmFzZVRhc2tzKGd1bHA6IEd1bHAsIHRhcmdldE9wdGlvbnM6IFRhcmdldEJhc2UpOiBCYXNlVGFza3Mge1xuICBjb25zdCB0YXNrczogQmFzZVRhc2tzID0gZ2VuZXJhdGVCYXNlVGFza3MoZ3VscCwgdGFyZ2V0T3B0aW9ucyk7XG4gIGZvciAoY29uc3Qga2V5IGluIHRhc2tzKSB7XG4gICAgY29uc3QgdGFzazogVGFza0Z1bmN0aW9uIHwgdW5kZWZpbmVkID0gKDxhbnk+IHRhc2tzKVtrZXldO1xuICAgIGlmICh0YXNrICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGd1bHAudGFzayh0YXNrKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRhc2tzO1xufVxuIl0sInNvdXJjZVJvb3QiOiIuLiJ9