"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); // src/index.ts var src_exports = {}; __export(src_exports, { FFmpeg: () => FFmpeg, changeFFmpegFlags: () => changeFFmpegFlags, createFFmpegArgs: () => createFFmpegArgs, version: () => version }); module.exports = __toCommonJS(src_exports); // src/FFmpeg.ts var import_node_child_process = require("child_process"); var import_node_stream = require("stream"); var VERSION_REGEX = /version (.+) Copyright/im; var validatePathParam = /* @__PURE__ */ __name((path, displayName) => { if (!path) throw new Error(`Failed to resolve ${displayName}`); return path; }, "validatePathParam"); var _FFmpeg = class _FFmpeg extends import_node_stream.Duplex { /** * Create FFmpeg duplex stream * @param options Options to initialize ffmpeg * @example ```typescript * const ffmpeg = new FFmpeg({ * args: [ * '-analyzeduration', '0', * '-loglevel', '0', * '-f', 's16le', * '-ar', '48000', * '-ac', '2', * '-af', 'bass=g=10,acompressor' * ] * }); * * const pcm = input.pipe(ffmpeg); * * pcm.pipe(fs.createWriteStream('./audio.pcm')); * ``` */ constructor(options = {}) { super(options); /** * Current FFmpeg process */ __publicField(this, "process"); this.process = _FFmpeg.spawn(options); const EVENTS = { readable: this._reader, data: this._reader, end: this._reader, unpipe: this._reader, finish: this._writer, drain: this._writer }; this._readableState = this._reader._readableState; this._writableState = this._writer._writableState; this._copy(["write", "end"], this._writer); this._copy(["read", "setEncoding", "pipe", "unpipe"], this._reader); for (const method of [ "on", "once", "removeListener", "removeAllListeners", "listeners" ]) { this[method] = (ev, fn) => ( // @ts-expect-error EVENTS[ev] ? ( // @ts-expect-error EVENTS[ev][method](ev, fn) ) : ( // @ts-expect-error import_node_stream.Duplex.prototype[method].call(this, ev, fn) ) ); } const processError = /* @__PURE__ */ __name((error) => this.emit("error", error), "processError"); this._reader.on("error", processError); this._writer.on("error", processError); } /** * Checks if FFmpeg is loaded. */ static isLoaded() { return _FFmpeg.cached != null; } /** * Adds a new FFmpeg source. * @param source FFmpeg source */ static addSource(source) { if (_FFmpeg.sources.some((s) => s.name === source.name)) return false; _FFmpeg.sources.push(source); return true; } /** * Removes a FFmpeg source. * @param source FFmpeg source */ static removeSource(source) { const index = _FFmpeg.sources.findIndex((s) => s.name === source.name); if (index === -1) return false; _FFmpeg.sources.splice(index, 1); return true; } /** * Resolves FFmpeg path. Throws an error if it fails to resolve. * @param force if it should relocate the command */ static resolve(force = false) { if (!force && _FFmpeg.cached) return _FFmpeg.cached; const errors = []; for (const source of _FFmpeg.sources) { try { let path; if (source.module) { const mod = require(source.name); path = validatePathParam( mod.default?.path || mod.path || mod, source.name ); } else { path = source.name; } const result = (0, import_node_child_process.spawnSync)(path, ["-v"], { windowsHide: true }); const resolved = { result: result.stdout.toString(), command: path, module: source.module, name: source.name, path, version: VERSION_REGEX.exec(result.stderr.toString())?.[1] ?? "unknown" }; _FFmpeg.cached = resolved; errors.length = 0; return resolved; } catch (e) { const err = e && e instanceof Error ? e.message : `${e}`; const msg = `Failed to load ffmpeg using ${source.module ? `require('${source.name}')` : `spawn('${source.name}')`}. Error: ${err}`; errors.push(msg); } } throw new Error(`Could not load ffmpeg. Errors: ${errors.join("\n")}`); } /** * Resolves FFmpeg path safely. Returns null if it fails to resolve. * @param force if it should relocate the command */ static resolveSafe(force = false) { try { return _FFmpeg.resolve(force); } catch { return null; } } /** * Spawns ffmpeg process * @param options Spawn options */ static spawn({ args = [], shell = false } = {}) { if (!args.includes("-i")) args.unshift("-i", "-"); return (0, import_node_child_process.spawn)(_FFmpeg.resolve().command, args.concat(["pipe:1"]), { windowsHide: true, shell }); } get _reader() { return this.process.stdout; } get _writer() { return this.process.stdin; } _copy(methods, target) { for (const method of methods) { this[method] = target[method].bind(target); } } _destroy(err, cb) { this._cleanup(); if (cb) return cb(err); } _final(cb) { this._cleanup(); cb(); } _cleanup() { if (this.process) { this.once("error", () => { }); this.process.kill("SIGKILL"); this.process = null; } } }; __name(_FFmpeg, "FFmpeg"); /** * Cached FFmpeg source. */ __publicField(_FFmpeg, "cached", null); /** * Supported FFmpeg sources. */ __publicField(_FFmpeg, "sources", [ // paths { name: "ffmpeg", module: false }, { name: "./ffmpeg", module: false }, { name: "avconv", module: false }, { name: "./avconv", module: false }, // modules { name: "ffmpeg-static", module: true }, { name: "@ffmpeg-installer/ffmpeg", module: true }, { name: "@node-ffmpeg/node-ffmpeg-installer", module: true }, { name: "ffmpeg-binaries", module: true } ]); var FFmpeg = _FFmpeg; // src/common.ts function changeFFmpegFlags(oldFlags, newFlags) { const updatedFlags = [...oldFlags]; for (let i = 0; i < newFlags.length; i++) { const key = newFlags[i]; const value = newFlags[i + 1]; const oldIndex = updatedFlags.indexOf(key); if (oldIndex !== -1) { if (value && !value.startsWith("-")) { updatedFlags[oldIndex + 1] = value; i++; } else { updatedFlags.splice(oldIndex, 1); } } else { if (value && !value.startsWith("-")) { updatedFlags.push(key, value); i++; } else { updatedFlags.push(key); } } } return updatedFlags; } __name(changeFFmpegFlags, "changeFFmpegFlags"); // src/version.ts var version = ( /* @__MACRO__ getVersion */ "7.2.0" ); // src/index.ts var createFFmpegArgs = /* @__PURE__ */ __name((input, post) => { const args = []; for (const [key, value] of Object.entries(input)) { if (value == null) continue; args.push(`-${key}`, String(value)); } if (post) { Array.isArray(post) ? args.push(...post) : args.push(post); } return args; }, "createFFmpegArgs"); // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { FFmpeg, changeFFmpegFlags, createFFmpegArgs, version }); //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL2luZGV4LnRzIiwgIi4uL3NyYy9GRm1wZWcudHMiLCAiLi4vc3JjL2NvbW1vbi50cyIsICIuLi9zcmMvdmVyc2lvbi50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiZXhwb3J0ICogZnJvbSAnLi9GRm1wZWcnO1xuXG5leHBvcnQgdHlwZSBBcmdQcmltaXRpdmUgPSBzdHJpbmcgfCBudW1iZXIgfCBudWxsO1xuXG4vKipcbiAqIENyZWF0ZSBGRm1wZWcgYXJndW1lbnRzIGZyb20gYW4gb2JqZWN0LlxuICogQHBhcmFtIGlucHV0IFRoZSBpbnB1dCBvYmplY3QuXG4gKiBAcGFyYW0gcG9zdCBBZGRpdGlvbmFsIGFyZ3VtZW50cyB0byBhcHBlbmQuXG4gKiBAcmV0dXJucyBUaGUgRkZtcGVnIGFyZ3VtZW50cy5cbiAqIEBleGFtcGxlIGNyZWF0ZUZGbXBlZ0FyZ3MoeyBpOiAnaW5wdXQubXAzJywgYWY6IFsnYmFzcz1nPTEwJywnYWNvbXByZXNzb3InXSB9LCAnLi9vdXQubXAzJyk7XG4gKiAvLyA9PiBbJy1pJywgJ2lucHV0Lm1wMycsICctYWYnLCAnYmFzcz1nPTEwLGFjb21wcmVzc29yJywgJy4vb3V0Lm1wMyddXG4gKi9cbmV4cG9ydCBjb25zdCBjcmVhdGVGRm1wZWdBcmdzID0gKFxuaW5wdXQ6IFJlY29yZDxzdHJpbmcsIEFyZ1ByaW1pdGl2ZSB8IEFyZ1ByaW1pdGl2ZVtdPixcbnBvc3Q/OiBzdHJpbmcgfCBzdHJpbmdbXSlcbjogc3RyaW5nW10gPT4ge1xuICBjb25zdCBhcmdzID0gW107XG5cbiAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMoaW5wdXQpKSB7XG4gICAgaWYgKHZhbHVlID09IG51bGwpIGNvbnRpbnVlO1xuICAgIGFyZ3MucHVzaChgLSR7a2V5fWAsIFN0cmluZyh2YWx1ZSkpO1xuICB9XG5cbiAgaWYgKHBvc3QpIHtcbiAgICBBcnJheS5pc0FycmF5KHBvc3QpID8gYXJncy5wdXNoKC4uLnBvc3QpIDogYXJncy5wdXNoKHBvc3QpO1xuICB9XG5cbiAgcmV0dXJuIGFyZ3M7XG59O1xuXG5leHBvcnQgKiBmcm9tICcuL2NvbW1vbic7XG5leHBvcnQgeyB2ZXJzaW9uIH0gZnJvbSAnLi92ZXJzaW9uJzsiLCAiaW1wb3J0IHtcbiAgQ2hpbGRQcm9jZXNzV2l0aG91dE51bGxTdHJlYW1zLFxuICBzcGF3bixcbiAgc3Bhd25TeW5jIH0gZnJvbVxuJ25vZGU6Y2hpbGRfcHJvY2Vzcyc7XG5pbXBvcnQgeyBEdXBsZXgsIER1cGxleE9wdGlvbnMgfSBmcm9tICdub2RlOnN0cmVhbSc7XG5pbXBvcnQgeyBGRm1wZWdDYWxsYmFjaywgRkZtcGVnU291cmNlLCBSZXNvbHZlZEZGbXBlZ1NvdXJjZSB9IGZyb20gJy4vY29tbW9uJztcblxuZXhwb3J0IGludGVyZmFjZSBGRm1wZWdPcHRpb25zIGV4dGVuZHMgRHVwbGV4T3B0aW9ucyB7XG4gIGFyZ3M/OiBzdHJpbmdbXTtcbiAgc2hlbGw/OiBib29sZWFuO1xufVxuXG5jb25zdCBWRVJTSU9OX1JFR0VYID0gL3ZlcnNpb24gKC4rKSBDb3B5cmlnaHQvaW07XG5cbmNvbnN0IHZhbGlkYXRlUGF0aFBhcmFtID0gKHBhdGg6IHN0cmluZywgZGlzcGxheU5hbWU6IHN0cmluZykgPT4ge1xuICBpZiAoIXBhdGgpIHRocm93IG5ldyBFcnJvcihgRmFpbGVkIHRvIHJlc29sdmUgJHtkaXNwbGF5TmFtZX1gKTtcbiAgcmV0dXJuIHBhdGg7XG59O1xuXG5leHBvcnQgY2xhc3MgRkZtcGVnIGV4dGVuZHMgRHVwbGV4IHtcbiAgLyoqXG4gICAqIENhY2hlZCBGRm1wZWcgc291cmNlLlxuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgY2FjaGVkOiBSZXNvbHZlZEZGbXBlZ1NvdXJjZSB8IG51bGwgPSBudWxsO1xuICAvKipcbiAgICogU3VwcG9ydGVkIEZGbXBlZyBzb3VyY2VzLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBzb3VyY2VzOiBGRm1wZWdTb3VyY2VbXSA9IFtcbiAgLy8gcGF0aHNcbiAgeyBuYW1lOiAnZmZtcGVnJywgbW9kdWxlOiBmYWxzZSB9LFxuICB7IG5hbWU6ICcuL2ZmbXBlZycsIG1vZHVsZTogZmFsc2UgfSxcbiAgeyBuYW1lOiAnYXZjb252JywgbW9kdWxlOiBmYWxzZSB9LFxuICB7IG5hbWU6ICcuL2F2Y29udicsIG1vZHVsZTogZmFsc2UgfSxcbiAgLy8gbW9kdWxlc1xuICB7IG5hbWU6ICdmZm1wZWctc3RhdGljJywgbW9kdWxlOiB0cnVlIH0sXG4gIHsgbmFtZTogJ0BmZm1wZWctaW5zdGFsbGVyL2ZmbXBlZycsIG1vZHVsZTogdHJ1ZSB9LFxuICB7IG5hbWU6ICdAbm9kZS1mZm1wZWcvbm9kZS1mZm1wZWctaW5zdGFsbGVyJywgbW9kdWxlOiB0cnVlIH0sXG4gIHsgbmFtZTogJ2ZmbXBlZy1iaW5hcmllcycsIG1vZHVsZTogdHJ1ZSB9XTtcblxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgRkZtcGVnIGlzIGxvYWRlZC5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgaXNMb2FkZWQoKSB7XG4gICAgcmV0dXJuIEZGbXBlZy5jYWNoZWQgIT0gbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGRzIGEgbmV3IEZGbXBlZyBzb3VyY2UuXG4gICAqIEBwYXJhbSBzb3VyY2UgRkZtcGVnIHNvdXJjZVxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBhZGRTb3VyY2Uoc291cmNlOiBGRm1wZWdTb3VyY2UpIHtcbiAgICBpZiAoRkZtcGVnLnNvdXJjZXMuc29tZSgocykgPT4gcy5uYW1lID09PSBzb3VyY2UubmFtZSkpIHJldHVybiBmYWxzZTtcbiAgICBGRm1wZWcuc291cmNlcy5wdXNoKHNvdXJjZSk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlcyBhIEZGbXBlZyBzb3VyY2UuXG4gICAqIEBwYXJhbSBzb3VyY2UgRkZtcGVnIHNvdXJjZVxuICAgKi9cbiAgcHVibGljIHN0YXRpYyByZW1vdmVTb3VyY2Uoc291cmNlOiBGRm1wZWdTb3VyY2UpIHtcbiAgICBjb25zdCBpbmRleCA9IEZGbXBlZy5zb3VyY2VzLmZpbmRJbmRleCgocykgPT4gcy5uYW1lID09PSBzb3VyY2UubmFtZSk7XG4gICAgaWYgKGluZGV4ID09PSAtMSkgcmV0dXJuIGZhbHNlO1xuICAgIEZGbXBlZy5zb3VyY2VzLnNwbGljZShpbmRleCwgMSk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvKipcbiAgICogUmVzb2x2ZXMgRkZtcGVnIHBhdGguIFRocm93cyBhbiBlcnJvciBpZiBpdCBmYWlscyB0byByZXNvbHZlLlxuICAgKiBAcGFyYW0gZm9yY2UgaWYgaXQgc2hvdWxkIHJlbG9jYXRlIHRoZSBjb21tYW5kXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIHJlc29sdmUoZm9yY2UgPSBmYWxzZSkge1xuICAgIGlmICghZm9yY2UgJiYgRkZtcGVnLmNhY2hlZCkgcmV0dXJuIEZGbXBlZy5jYWNoZWQ7XG5cbiAgICBjb25zdCBlcnJvcnM6IHN0cmluZ1tdID0gW107XG5cbiAgICBmb3IgKGNvbnN0IHNvdXJjZSBvZiBGRm1wZWcuc291cmNlcykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgbGV0IHBhdGg6IHN0cmluZztcblxuICAgICAgICBpZiAoc291cmNlLm1vZHVsZSkge1xuICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdmFyLXJlcXVpcmVzXG4gICAgICAgICAgY29uc3QgbW9kID0gcmVxdWlyZShzb3VyY2UubmFtZSk7XG4gICAgICAgICAgcGF0aCA9IHZhbGlkYXRlUGF0aFBhcmFtKFxuICAgICAgICAgICAgbW9kLmRlZmF1bHQ/LnBhdGggfHwgbW9kLnBhdGggfHwgbW9kLFxuICAgICAgICAgICAgc291cmNlLm5hbWVcbiAgICAgICAgICApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHBhdGggPSBzb3VyY2UubmFtZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IHNwYXduU3luYyhwYXRoLCBbJy12J10sIHsgd2luZG93c0hpZGU6IHRydWUgfSk7XG5cbiAgICAgICAgY29uc3QgcmVzb2x2ZWQ6IFJlc29sdmVkRkZtcGVnU291cmNlID0ge1xuICAgICAgICAgIHJlc3VsdDogcmVzdWx0LnN0ZG91dC50b1N0cmluZygpLFxuICAgICAgICAgIGNvbW1hbmQ6IHBhdGgsXG4gICAgICAgICAgbW9kdWxlOiBzb3VyY2UubW9kdWxlLFxuICAgICAgICAgIG5hbWU6IHNvdXJjZS5uYW1lLFxuICAgICAgICAgIHBhdGgsXG4gICAgICAgICAgdmVyc2lvbjpcbiAgICAgICAgICBWRVJTSU9OX1JFR0VYLmV4ZWMocmVzdWx0LnN0ZGVyci50b1N0cmluZygpKT8uWzFdID8/ICd1bmtub3duJ1xuICAgICAgICB9O1xuXG4gICAgICAgIEZGbXBlZy5jYWNoZWQgPSByZXNvbHZlZDtcblxuICAgICAgICBlcnJvcnMubGVuZ3RoID0gMDtcblxuICAgICAgICByZXR1cm4gcmVzb2x2ZWQ7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGNvbnN0IGVyciA9IGUgJiYgZSBpbnN0YW5jZW9mIEVycm9yID8gZS5tZXNzYWdlIDogYCR7ZX1gO1xuICAgICAgICBjb25zdCBtc2cgPSBgRmFpbGVkIHRvIGxvYWQgZmZtcGVnIHVzaW5nICR7XG4gICAgICAgIHNvdXJjZS5tb2R1bGUgP1xuICAgICAgICBgcmVxdWlyZSgnJHtzb3VyY2UubmFtZX0nKWAgOlxuICAgICAgICBgc3Bhd24oJyR7c291cmNlLm5hbWV9JylgfS4gRXJyb3I6ICR7XG4gICAgICAgIGVycn1gO1xuXG4gICAgICAgIGVycm9ycy5wdXNoKG1zZyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IEVycm9yKGBDb3VsZCBub3QgbG9hZCBmZm1wZWcuIEVycm9yczpcXG4ke2Vycm9ycy5qb2luKCdcXG4nKX1gKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNvbHZlcyBGRm1wZWcgcGF0aCBzYWZlbHkuIFJldHVybnMgbnVsbCBpZiBpdCBmYWlscyB0byByZXNvbHZlLlxuICAgKiBAcGFyYW0gZm9yY2UgaWYgaXQgc2hvdWxkIHJlbG9jYXRlIHRoZSBjb21tYW5kXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIHJlc29sdmVTYWZlKGZvcmNlID0gZmFsc2UpIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIEZGbXBlZy5yZXNvbHZlKGZvcmNlKTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTcGF3bnMgZmZtcGVnIHByb2Nlc3NcbiAgICogQHBhcmFtIG9wdGlvbnMgU3Bhd24gb3B0aW9uc1xuICAgKi9cbiAgcHVibGljIHN0YXRpYyBzcGF3bih7IGFyZ3MgPSBbXSBhcyBzdHJpbmdbXSwgc2hlbGwgPSBmYWxzZSB9ID0ge30pIHtcbiAgICBpZiAoIWFyZ3MuaW5jbHVkZXMoJy1pJykpIGFyZ3MudW5zaGlmdCgnLWknLCAnLScpO1xuICAgIHJldHVybiBzcGF3bihGRm1wZWcucmVzb2x2ZSgpLmNvbW1hbmQsIGFyZ3MuY29uY2F0KFsncGlwZToxJ10pLCB7XG4gICAgICB3aW5kb3dzSGlkZTogdHJ1ZSxcbiAgICAgIHNoZWxsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQ3VycmVudCBGRm1wZWcgcHJvY2Vzc1xuICAgKi9cbiAgcHVibGljIHByb2Nlc3M6IENoaWxkUHJvY2Vzc1dpdGhvdXROdWxsU3RyZWFtcztcblxuICAvKipcbiAgICogQ3JlYXRlIEZGbXBlZyBkdXBsZXggc3RyZWFtXG4gICAqIEBwYXJhbSBvcHRpb25zIE9wdGlvbnMgdG8gaW5pdGlhbGl6ZSBmZm1wZWdcbiAgICogQGV4YW1wbGUgYGBgdHlwZXNjcmlwdFxuICAgKiBjb25zdCBmZm1wZWcgPSBuZXcgRkZtcGVnKHtcbiAgICogICBhcmdzOiBbXG4gICAqICAgICAnLWFuYWx5emVkdXJhdGlvbicsICcwJyxcbiAgICogICAgICctbG9nbGV2ZWwnLCAnMCcsXG4gICAqICAgICAnLWYnLCAnczE2bGUnLFxuICAgKiAgICAgJy1hcicsICc0ODAwMCcsXG4gICAqICAgICAnLWFjJywgJzInLFxuICAgKiAgICAgJy1hZicsICdiYXNzPWc9MTAsYWNvbXByZXNzb3InXG4gICAqICAgXVxuICAgKiB9KTtcbiAgICpcbiAgICogY29uc3QgcGNtID0gaW5wdXQucGlwZShmZm1wZWcpO1xuICAgKlxuICAgKiBwY20ucGlwZShmcy5jcmVhdGVXcml0ZVN0cmVhbSgnLi9hdWRpby5wY20nKSk7XG4gICAqIGBgYFxuICAgKi9cbiAgcHVibGljIGNvbnN0cnVjdG9yKG9wdGlvbnM6IEZGbXBlZ09wdGlvbnMgPSB7fSkge1xuICAgIHN1cGVyKG9wdGlvbnMpO1xuXG4gICAgdGhpcy5wcm9jZXNzID0gRkZtcGVnLnNwYXduKG9wdGlvbnMpO1xuXG4gICAgY29uc3QgRVZFTlRTID0ge1xuICAgICAgcmVhZGFibGU6IHRoaXMuX3JlYWRlcixcbiAgICAgIGRhdGE6IHRoaXMuX3JlYWRlcixcbiAgICAgIGVuZDogdGhpcy5fcmVhZGVyLFxuICAgICAgdW5waXBlOiB0aGlzLl9yZWFkZXIsXG4gICAgICBmaW5pc2g6IHRoaXMuX3dyaXRlcixcbiAgICAgIGRyYWluOiB0aGlzLl93cml0ZXJcbiAgICB9IGFzIGNvbnN0O1xuXG4gICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgIHRoaXMuX3JlYWRhYmxlU3RhdGUgPSB0aGlzLl9yZWFkZXIuX3JlYWRhYmxlU3RhdGU7XG4gICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgIHRoaXMuX3dyaXRhYmxlU3RhdGUgPSB0aGlzLl93cml0ZXIuX3dyaXRhYmxlU3RhdGU7XG5cbiAgICB0aGlzLl9jb3B5KFsnd3JpdGUnLCAnZW5kJ10sIHRoaXMuX3dyaXRlcik7XG4gICAgdGhpcy5fY29weShbJ3JlYWQnLCAnc2V0RW5jb2RpbmcnLCAncGlwZScsICd1bnBpcGUnXSwgdGhpcy5fcmVhZGVyKTtcblxuICAgIGZvciAoY29uc3QgbWV0aG9kIG9mIFtcbiAgICAnb24nLFxuICAgICdvbmNlJyxcbiAgICAncmVtb3ZlTGlzdGVuZXInLFxuICAgICdyZW1vdmVBbGxMaXN0ZW5lcnMnLFxuICAgICdsaXN0ZW5lcnMnXSBhc1xuICAgIGNvbnN0KSB7XG4gICAgICAvLyBAdHMtZXhwZWN0LWVycm9yXG4gICAgICB0aGlzW21ldGhvZF0gPSAoZXYsIGZuKSA9PlxuICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgICAgRVZFTlRTW2V2XSA/XG4gICAgICAvLyBAdHMtZXhwZWN0LWVycm9yXG4gICAgICBFVkVOVFNbZXZdW21ldGhvZF0oZXYsIGZuKSA6XG4gICAgICAvLyBAdHMtZXhwZWN0LWVycm9yXG4gICAgICBEdXBsZXgucHJvdG90eXBlW21ldGhvZF0uY2FsbCh0aGlzLCBldiwgZm4pO1xuICAgIH1cblxuICAgIGNvbnN0IHByb2Nlc3NFcnJvciA9IChlcnJvcjogRXJyb3IpID0+IHRoaXMuZW1pdCgnZXJyb3InLCBlcnJvcik7XG5cbiAgICB0aGlzLl9yZWFkZXIub24oJ2Vycm9yJywgcHJvY2Vzc0Vycm9yKTtcbiAgICB0aGlzLl93cml0ZXIub24oJ2Vycm9yJywgcHJvY2Vzc0Vycm9yKTtcbiAgfVxuXG4gIGdldCBfcmVhZGVyKCkge1xuICAgIHJldHVybiB0aGlzLnByb2Nlc3MhLnN0ZG91dDtcbiAgfVxuICBnZXQgX3dyaXRlcigpIHtcbiAgICByZXR1cm4gdGhpcy5wcm9jZXNzIS5zdGRpbjtcbiAgfVxuXG4gIHByaXZhdGUgX2NvcHkobWV0aG9kczogc3RyaW5nW10sIHRhcmdldDogdW5rbm93bikge1xuICAgIGZvciAoY29uc3QgbWV0aG9kIG9mIG1ldGhvZHMpIHtcbiAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3JcbiAgICAgIHRoaXNbbWV0aG9kXSA9IHRhcmdldFttZXRob2RdLmJpbmQodGFyZ2V0KTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgX2Rlc3Ryb3koZXJyOiBFcnJvciB8IG51bGwsIGNiOiBGRm1wZWdDYWxsYmFjazxbRXJyb3IgfCBudWxsXT4pIHtcbiAgICB0aGlzLl9jbGVhbnVwKCk7XG4gICAgaWYgKGNiKSByZXR1cm4gY2IoZXJyKTtcbiAgfVxuXG4gIHB1YmxpYyBfZmluYWwoY2I6IEZGbXBlZ0NhbGxiYWNrPFtdPikge1xuICAgIHRoaXMuX2NsZWFudXAoKTtcbiAgICBjYigpO1xuICB9XG5cbiAgcHJpdmF0ZSBfY2xlYW51cCgpIHtcbiAgICBpZiAodGhpcy5wcm9jZXNzKSB7XG4gICAgICB0aGlzLm9uY2UoJ2Vycm9yJywgKCkgPT4ge1xuXG4gICAgICAgIC8vXG4gICAgICB9KTt0aGlzLnByb2Nlc3Mua2lsbCgnU0lHS0lMTCcpO1xuICAgICAgdGhpcy5wcm9jZXNzID0gbnVsbCBhcyB1bmtub3duIGFzIENoaWxkUHJvY2Vzc1dpdGhvdXROdWxsU3RyZWFtcztcbiAgICB9XG4gIH1cbn0iLCAiZXhwb3J0IHR5cGUgRkZtcGVnTGliID1cbidmZm1wZWcnIHxcbicuL2ZmbXBlZycgfFxuJ2F2Y29udicgfFxuJy4vYXZjb252JyB8XG4nZmZtcGVnLXN0YXRpYycgfFxuJ0BmZm1wZWctaW5zdGFsbGVyL2ZmbXBlZycgfFxuJ0Bub2RlLWZmbXBlZy9ub2RlLWZmbXBlZy1pbnN0YWxsZXInIHxcbidmZm1wZWctYmluYXJpZXMnO1xuXG5leHBvcnQgdHlwZSBGRm1wZWdDYWxsYmFjazxBcmdzIGV4dGVuZHMgQXJyYXk8dW5rbm93bj4+ID0gKFxuLi4uYXJnczogQXJncylcbj0+IHVua25vd247XG5cbi8qKlxuICogRkZtcGVnIHNvdXJjZSBjb25maWd1cmF0aW9uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRkZtcGVnU291cmNlIHtcbiAgLyoqIE5hbWUgb3IgcGF0aCBvZiB0aGUgRkZtcGVnIGV4ZWN1dGFibGUgKi9cbiAgbmFtZTogRkZtcGVnTGliO1xuICAvKiogV2hldGhlciB0aGlzIHNvdXJjZSBpcyBhIE5vZGUuanMgbW9kdWxlICovXG4gIG1vZHVsZTogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSZXNvbHZlZEZGbXBlZ1NvdXJjZSBleHRlbmRzIEZGbXBlZ1NvdXJjZSB7XG4gIHBhdGg6IHN0cmluZztcbiAgdmVyc2lvbjogc3RyaW5nO1xuICBjb21tYW5kOiBzdHJpbmc7XG4gIHJlc3VsdDogc3RyaW5nO1xufVxuXG4vKipcbiAqIENvbXBhcmVzIGFuZCB1cGRhdGVzIEZGbXBlZyBmbGFncyBhcyBuZWVkZWRcbiAqIEBwYXJhbSBvbGRGbGFncyBUaGUgb2xkIGZsYWdzXG4gKiBAcGFyYW0gbmV3RmxhZ3MgVGhlIG5ldyBmbGFnc1xuICogQHJldHVybnMgVGhlIHVwZGF0ZWQgZmxhZ3NcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNoYW5nZUZGbXBlZ0ZsYWdzKG9sZEZsYWdzOiBzdHJpbmdbXSwgbmV3RmxhZ3M6IHN0cmluZ1tdKSB7XG4gIGNvbnN0IHVwZGF0ZWRGbGFncyA9IFsuLi5vbGRGbGFnc107XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBuZXdGbGFncy5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGtleSA9IG5ld0ZsYWdzW2ldO1xuICAgIGNvbnN0IHZhbHVlID0gbmV3RmxhZ3NbaSArIDFdO1xuXG4gICAgY29uc3Qgb2xkSW5kZXggPSB1cGRhdGVkRmxhZ3MuaW5kZXhPZihrZXkpO1xuXG4gICAgaWYgKG9sZEluZGV4ICE9PSAtMSkge1xuICAgICAgaWYgKHZhbHVlICYmICF2YWx1ZS5zdGFydHNXaXRoKCctJykpIHtcbiAgICAgICAgdXBkYXRlZEZsYWdzW29sZEluZGV4ICsgMV0gPSB2YWx1ZTtcbiAgICAgICAgaSsrO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdXBkYXRlZEZsYWdzLnNwbGljZShvbGRJbmRleCwgMSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh2YWx1ZSAmJiAhdmFsdWUuc3RhcnRzV2l0aCgnLScpKSB7XG4gICAgICAgIHVwZGF0ZWRGbGFncy5wdXNoKGtleSwgdmFsdWUpO1xuICAgICAgICBpKys7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB1cGRhdGVkRmxhZ3MucHVzaChrZXkpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB1cGRhdGVkRmxhZ3M7XG59IiwgIlxuXG5cblxuXG5cbmV4cG9ydCBjb25zdCB2ZXJzaW9uID0gLyogQF9fTUFDUk9fXyBnZXRWZXJzaW9uICovXCI3LjIuMFwiOyJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7O0FDQUEsZ0NBSUE7QUFDQSx5QkFBc0M7QUFRdEMsSUFBTSxnQkFBZ0I7QUFFdEIsSUFBTSxvQkFBb0Isd0JBQUMsTUFBYyxnQkFBd0I7QUFDL0QsTUFBSSxDQUFDLEtBQU0sT0FBTSxJQUFJLE1BQU0scUJBQXFCLFdBQVcsRUFBRTtBQUM3RCxTQUFPO0FBQ1QsR0FIMEI7QUFLbkIsSUFBTSxVQUFOLE1BQU0sZ0JBQWUsMEJBQU87QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUEwSjFCLFlBQVksVUFBeUIsQ0FBQyxHQUFHO0FBQzlDLFVBQU0sT0FBTztBQXZCZjtBQUFBO0FBQUE7QUFBQSx3QkFBTztBQXlCTCxTQUFLLFVBQVUsUUFBTyxNQUFNLE9BQU87QUFFbkMsVUFBTSxTQUFTO0FBQUEsTUFDYixVQUFVLEtBQUs7QUFBQSxNQUNmLE1BQU0sS0FBSztBQUFBLE1BQ1gsS0FBSyxLQUFLO0FBQUEsTUFDVixRQUFRLEtBQUs7QUFBQSxNQUNiLFFBQVEsS0FBSztBQUFBLE1BQ2IsT0FBTyxLQUFLO0FBQUEsSUFDZDtBQUdBLFNBQUssaUJBQWlCLEtBQUssUUFBUTtBQUVuQyxTQUFLLGlCQUFpQixLQUFLLFFBQVE7QUFFbkMsU0FBSyxNQUFNLENBQUMsU0FBUyxLQUFLLEdBQUcsS0FBSyxPQUFPO0FBQ3pD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