@decaf-ts/fabric-weaver
Version:
template for ts projects
124 lines • 15 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.readFileYaml = readFileYaml;
exports.writeFileYaml = writeFileYaml;
const fs_1 = __importDefault(require("fs"));
const js_yaml_1 = __importDefault(require("js-yaml"));
const logging_1 = require("@decaf-ts/logging");
const logger = logging_1.Logging.for("yaml");
/**
* @description Reads and parses a YAML file, optionally retrieving a specific property.
* @summary This function reads a YAML file from the given path, parses its content, and returns either the entire parsed YAML object or a specific property value based on the provided path.
*
* @function readFileYaml
* @template T - The type of the returned value when a specific property is requested.
* @param {string} yamlFilePath - The path to the YAML file to be read.
* @param {string} [variable] - Optional. A dot-notated path string that specifies the property to retrieve from the parsed YAML.
* @return {Record<string, any> | T} Returns the entire parsed YAML object if no `variable` is provided, or the value of the specified property if `variable` is provided.
*
* @memberOf module:fabric-weaver.Utils
*
* @example
* // Example 1: Read the entire YAML file
* const config = readFileYaml("config/settings.yaml");
* console.log(config);
*
* @example
* // Example 2: Retrieve a specific property from the YAML file
* const dbHost = readFileYaml("config/settings.yaml", "database.host");
* console.log(dbHost);
*
* @example
* // Example 3: Handle an error if the property does not exist
* const invalidProperty = readFileYaml("config/settings.yaml", "server.port");
*
* @mermaid
* sequenceDiagram
* participant Caller
* participant readFileYaml
* participant logger
* participant fs
* participant yaml
*
* Caller->>readFileYaml: Call with yamlFilePath and optional variable
* readFileYaml->>logger: Log verbose message (Reading YAML file)
* readFileYaml->>fs: Read file content
* readFileYaml->>logger: Log verbose message (Parsed YAML content)
* readFileYaml->>yaml: Parse YAML content
* readFileYaml->>logger: Log verbose message (Parsed YAML object)
* alt variable is provided
* readFileYaml->>readFileYaml: Navigate through parsed YAML using variable path
* alt Property exists
* readFileYaml-->>Caller: Return specific property value
* else Property doesn't exist
* readFileYaml->>logger: Log error message
* readFileYaml-->>Caller: Return error
* end
* else variable is not provided
* readFileYaml-->>Caller: Return entire parsed YAML object
* end
*/
function readFileYaml(yamlFilePath, variable) {
const log = logger.for(readFileYaml);
log.debug(`Reading YAML file: ${yamlFilePath}`);
const content = fs_1.default.readFileSync(yamlFilePath, "utf8");
log.debug(`Parsed YAML content: ${content}`);
const parsedYAML = js_yaml_1.default.load(content);
log.debug(`Parsed YAML object: ${JSON.stringify(parsedYAML, null, 2)}`);
log.info(`Returning ${variable ? `property '${variable}'` : "the entire parsed YAML object"}`);
if (!variable)
return parsedYAML;
const variablePath = variable.split(".");
return variablePath.reduce((acc, key) => {
// eslint-disable-next-line no-prototype-builtins
if (!acc.hasOwnProperty(key)) {
throw new Error(`Unable to locate a property named '${key}' from path '${variable}' in file: \n> ${yamlFilePath}`);
}
return typeof acc[key] === "string" ? acc[key].trim() : acc[key];
}, parsedYAML);
}
/**
* @description Writes a JSON object to a YAML file.
* @summary This function takes a JSON object and writes it to a specified file path in YAML format.
* It uses js-yaml to convert the JSON to YAML, and then writes the content to the file.
*
* @function writeFileYaml
* @template T - The type of the JSON object to be written.
* @param {string} path - The file path where the YAML content will be written.
* @param {T} json - The JSON object to be converted to YAML and written to the file.
* @return {void}
*
* @memberOf module:fabric-weaver.Utils
*
* @example
* const config = { database: { host: 'localhost', port: 5432 } };
* writeFileYaml('config/settings.yaml', config);
*
* @mermaid
* sequenceDiagram
* participant Caller
* participant writeFileYaml
* participant logger
* participant yaml
* participant fs
*
* Caller->>writeFileYaml: Call with path and JSON
* writeFileYaml->>logger: Log verbose message (Writing YAML file)
* writeFileYaml->>logger: Log verbose message (Writing YAML content)
* writeFileYaml->>yaml: Convert JSON to YAML
* writeFileYaml->>logger: Log verbose message (Writing YAML content to file)
* writeFileYaml->>fs: Write YAML content to file
* writeFileYaml-->>Caller: Return (void)
*/
function writeFileYaml(path, json) {
const log = logger.for(writeFileYaml);
log.debug(`Writing YAML file: ${path}`);
log.debug(`Writing YAML content: ${JSON.stringify(json, null, 2)}`);
const content = js_yaml_1.default.dump(json, { indent: 2, lineWidth: -1 });
log.debug(`Writing YAML content to file: ${content}`);
fs_1.default.writeFileSync(path, content.replace(/ null$/gm, ""), "utf8");
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoieWFtbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlscy95YW1sLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBMERBLG9DQThCQztBQW1DRCxzQ0FTQztBQXBJRCw0Q0FBb0I7QUFDcEIsc0RBQTJCO0FBQzNCLCtDQUE0QztBQUU1QyxNQUFNLE1BQU0sR0FBRyxpQkFBTyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUVuQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBbURHO0FBQ0gsU0FBZ0IsWUFBWSxDQUMxQixZQUFvQixFQUNwQixRQUFpQjtJQUVqQixNQUFNLEdBQUcsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxDQUFDO0lBRXJDLEdBQUcsQ0FBQyxLQUFLLENBQUMsc0JBQXNCLFlBQVksRUFBRSxDQUFDLENBQUM7SUFDaEQsTUFBTSxPQUFPLEdBQUcsWUFBRSxDQUFDLFlBQVksQ0FBQyxZQUFZLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFFdEQsR0FBRyxDQUFDLEtBQUssQ0FBQyx3QkFBd0IsT0FBTyxFQUFFLENBQUMsQ0FBQztJQUM3QyxNQUFNLFVBQVUsR0FBRyxpQkFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQXdCLENBQUM7SUFFN0QsR0FBRyxDQUFDLEtBQUssQ0FBQyx1QkFBdUIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxVQUFVLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUV4RSxHQUFHLENBQUMsSUFBSSxDQUNOLGFBQWEsUUFBUSxDQUFDLENBQUMsQ0FBQyxhQUFhLFFBQVEsR0FBRyxDQUFDLENBQUMsQ0FBQywrQkFBK0IsRUFBRSxDQUNyRixDQUFDO0lBQ0YsSUFBSSxDQUFDLFFBQVE7UUFBRSxPQUFPLFVBQVUsQ0FBQztJQUVqQyxNQUFNLFlBQVksR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBRXpDLE9BQU8sWUFBWSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsRUFBRTtRQUN0QyxpREFBaUQ7UUFDakQsSUFBSSxDQUFDLEdBQUcsQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUM3QixNQUFNLElBQUksS0FBSyxDQUNiLHNDQUFzQyxHQUFHLGdCQUFnQixRQUFRLGtCQUFrQixZQUFZLEVBQUUsQ0FDbEcsQ0FBQztRQUNKLENBQUM7UUFDRCxPQUFPLE9BQU8sR0FBRyxDQUFDLEdBQUcsQ0FBQyxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDbkUsQ0FBQyxFQUFFLFVBQVUsQ0FBQyxDQUFDO0FBQ2pCLENBQUM7QUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FnQ0c7QUFDSCxTQUFnQixhQUFhLENBQUksSUFBWSxFQUFFLElBQU87SUFDcEQsTUFBTSxHQUFHLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUV0QyxHQUFHLENBQUMsS0FBSyxDQUFDLHNCQUFzQixJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQ3hDLEdBQUcsQ0FBQyxLQUFLLENBQUMseUJBQXlCLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDcEUsTUFBTSxPQUFPLEdBQUcsaUJBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLEVBQUUsTUFBTSxFQUFFLENBQUMsRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBRTlELEdBQUcsQ0FBQyxLQUFLLENBQUMsaUNBQWlDLE9BQU8sRUFBRSxDQUFDLENBQUM7SUFDdEQsWUFBRSxDQUFDLGFBQWEsQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLE9BQU8sQ0FBQyxVQUFVLEVBQUUsRUFBRSxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUM7QUFDbEUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBmcyBmcm9tIFwiZnNcIjtcbmltcG9ydCB5YW1sIGZyb20gXCJqcy15YW1sXCI7XG5pbXBvcnQgeyBMb2dnaW5nIH0gZnJvbSBcIkBkZWNhZi10cy9sb2dnaW5nXCI7XG5cbmNvbnN0IGxvZ2dlciA9IExvZ2dpbmcuZm9yKFwieWFtbFwiKTtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gUmVhZHMgYW5kIHBhcnNlcyBhIFlBTUwgZmlsZSwgb3B0aW9uYWxseSByZXRyaWV2aW5nIGEgc3BlY2lmaWMgcHJvcGVydHkuXG4gKiBAc3VtbWFyeSBUaGlzIGZ1bmN0aW9uIHJlYWRzIGEgWUFNTCBmaWxlIGZyb20gdGhlIGdpdmVuIHBhdGgsIHBhcnNlcyBpdHMgY29udGVudCwgYW5kIHJldHVybnMgZWl0aGVyIHRoZSBlbnRpcmUgcGFyc2VkIFlBTUwgb2JqZWN0IG9yIGEgc3BlY2lmaWMgcHJvcGVydHkgdmFsdWUgYmFzZWQgb24gdGhlIHByb3ZpZGVkIHBhdGguXG4gKlxuICogQGZ1bmN0aW9uIHJlYWRGaWxlWWFtbFxuICogQHRlbXBsYXRlIFQgLSBUaGUgdHlwZSBvZiB0aGUgcmV0dXJuZWQgdmFsdWUgd2hlbiBhIHNwZWNpZmljIHByb3BlcnR5IGlzIHJlcXVlc3RlZC5cbiAqIEBwYXJhbSB7c3RyaW5nfSB5YW1sRmlsZVBhdGggLSBUaGUgcGF0aCB0byB0aGUgWUFNTCBmaWxlIHRvIGJlIHJlYWQuXG4gKiBAcGFyYW0ge3N0cmluZ30gW3ZhcmlhYmxlXSAtIE9wdGlvbmFsLiBBIGRvdC1ub3RhdGVkIHBhdGggc3RyaW5nIHRoYXQgc3BlY2lmaWVzIHRoZSBwcm9wZXJ0eSB0byByZXRyaWV2ZSBmcm9tIHRoZSBwYXJzZWQgWUFNTC5cbiAqIEByZXR1cm4ge1JlY29yZDxzdHJpbmcsIGFueT4gfCBUfSBSZXR1cm5zIHRoZSBlbnRpcmUgcGFyc2VkIFlBTUwgb2JqZWN0IGlmIG5vIGB2YXJpYWJsZWAgaXMgcHJvdmlkZWQsIG9yIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIHByb3BlcnR5IGlmIGB2YXJpYWJsZWAgaXMgcHJvdmlkZWQuXG4gKlxuICogQG1lbWJlck9mIG1vZHVsZTpmYWJyaWMtd2VhdmVyLlV0aWxzXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIEV4YW1wbGUgMTogUmVhZCB0aGUgZW50aXJlIFlBTUwgZmlsZVxuICogY29uc3QgY29uZmlnID0gcmVhZEZpbGVZYW1sKFwiY29uZmlnL3NldHRpbmdzLnlhbWxcIik7XG4gKiBjb25zb2xlLmxvZyhjb25maWcpO1xuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBFeGFtcGxlIDI6IFJldHJpZXZlIGEgc3BlY2lmaWMgcHJvcGVydHkgZnJvbSB0aGUgWUFNTCBmaWxlXG4gKiBjb25zdCBkYkhvc3QgPSByZWFkRmlsZVlhbWwoXCJjb25maWcvc2V0dGluZ3MueWFtbFwiLCBcImRhdGFiYXNlLmhvc3RcIik7XG4gKiBjb25zb2xlLmxvZyhkYkhvc3QpO1xuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBFeGFtcGxlIDM6IEhhbmRsZSBhbiBlcnJvciBpZiB0aGUgcHJvcGVydHkgZG9lcyBub3QgZXhpc3RcbiAqIGNvbnN0IGludmFsaWRQcm9wZXJ0eSA9IHJlYWRGaWxlWWFtbChcImNvbmZpZy9zZXR0aW5ncy55YW1sXCIsIFwic2VydmVyLnBvcnRcIik7XG4gKlxuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBDYWxsZXJcbiAqICAgcGFydGljaXBhbnQgcmVhZEZpbGVZYW1sXG4gKiAgIHBhcnRpY2lwYW50IGxvZ2dlclxuICogICBwYXJ0aWNpcGFudCBmc1xuICogICBwYXJ0aWNpcGFudCB5YW1sXG4gKlxuICogICBDYWxsZXItPj5yZWFkRmlsZVlhbWw6IENhbGwgd2l0aCB5YW1sRmlsZVBhdGggYW5kIG9wdGlvbmFsIHZhcmlhYmxlXG4gKiAgIHJlYWRGaWxlWWFtbC0+PmxvZ2dlcjogTG9nIHZlcmJvc2UgbWVzc2FnZSAoUmVhZGluZyBZQU1MIGZpbGUpXG4gKiAgIHJlYWRGaWxlWWFtbC0+PmZzOiBSZWFkIGZpbGUgY29udGVudFxuICogICByZWFkRmlsZVlhbWwtPj5sb2dnZXI6IExvZyB2ZXJib3NlIG1lc3NhZ2UgKFBhcnNlZCBZQU1MIGNvbnRlbnQpXG4gKiAgIHJlYWRGaWxlWWFtbC0+PnlhbWw6IFBhcnNlIFlBTUwgY29udGVudFxuICogICByZWFkRmlsZVlhbWwtPj5sb2dnZXI6IExvZyB2ZXJib3NlIG1lc3NhZ2UgKFBhcnNlZCBZQU1MIG9iamVjdClcbiAqICAgYWx0IHZhcmlhYmxlIGlzIHByb3ZpZGVkXG4gKiAgICAgcmVhZEZpbGVZYW1sLT4+cmVhZEZpbGVZYW1sOiBOYXZpZ2F0ZSB0aHJvdWdoIHBhcnNlZCBZQU1MIHVzaW5nIHZhcmlhYmxlIHBhdGhcbiAqICAgICBhbHQgUHJvcGVydHkgZXhpc3RzXG4gKiAgICAgICByZWFkRmlsZVlhbWwtLT4+Q2FsbGVyOiBSZXR1cm4gc3BlY2lmaWMgcHJvcGVydHkgdmFsdWVcbiAqICAgICBlbHNlIFByb3BlcnR5IGRvZXNuJ3QgZXhpc3RcbiAqICAgICAgIHJlYWRGaWxlWWFtbC0+PmxvZ2dlcjogTG9nIGVycm9yIG1lc3NhZ2VcbiAqICAgICAgIHJlYWRGaWxlWWFtbC0tPj5DYWxsZXI6IFJldHVybiBlcnJvclxuICogICAgIGVuZFxuICogICBlbHNlIHZhcmlhYmxlIGlzIG5vdCBwcm92aWRlZFxuICogICAgIHJlYWRGaWxlWWFtbC0tPj5DYWxsZXI6IFJldHVybiBlbnRpcmUgcGFyc2VkIFlBTUwgb2JqZWN0XG4gKiAgIGVuZFxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVhZEZpbGVZYW1sPFQ+KFxuICB5YW1sRmlsZVBhdGg6IHN0cmluZyxcbiAgdmFyaWFibGU/OiBzdHJpbmdcbik6IFJlY29yZDxzdHJpbmcsIGFueT4gfCBUIHtcbiAgY29uc3QgbG9nID0gbG9nZ2VyLmZvcihyZWFkRmlsZVlhbWwpO1xuXG4gIGxvZy5kZWJ1ZyhgUmVhZGluZyBZQU1MIGZpbGU6ICR7eWFtbEZpbGVQYXRofWApO1xuICBjb25zdCBjb250ZW50ID0gZnMucmVhZEZpbGVTeW5jKHlhbWxGaWxlUGF0aCwgXCJ1dGY4XCIpO1xuXG4gIGxvZy5kZWJ1ZyhgUGFyc2VkIFlBTUwgY29udGVudDogJHtjb250ZW50fWApO1xuICBjb25zdCBwYXJzZWRZQU1MID0geWFtbC5sb2FkKGNvbnRlbnQpIGFzIFJlY29yZDxzdHJpbmcsIGFueT47XG5cbiAgbG9nLmRlYnVnKGBQYXJzZWQgWUFNTCBvYmplY3Q6ICR7SlNPTi5zdHJpbmdpZnkocGFyc2VkWUFNTCwgbnVsbCwgMil9YCk7XG5cbiAgbG9nLmluZm8oXG4gICAgYFJldHVybmluZyAke3ZhcmlhYmxlID8gYHByb3BlcnR5ICcke3ZhcmlhYmxlfSdgIDogXCJ0aGUgZW50aXJlIHBhcnNlZCBZQU1MIG9iamVjdFwifWBcbiAgKTtcbiAgaWYgKCF2YXJpYWJsZSkgcmV0dXJuIHBhcnNlZFlBTUw7XG5cbiAgY29uc3QgdmFyaWFibGVQYXRoID0gdmFyaWFibGUuc3BsaXQoXCIuXCIpO1xuXG4gIHJldHVybiB2YXJpYWJsZVBhdGgucmVkdWNlKChhY2MsIGtleSkgPT4ge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1wcm90b3R5cGUtYnVpbHRpbnNcbiAgICBpZiAoIWFjYy5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBVbmFibGUgdG8gbG9jYXRlIGEgcHJvcGVydHkgbmFtZWQgJyR7a2V5fScgZnJvbSBwYXRoICcke3ZhcmlhYmxlfScgaW4gZmlsZTogXFxuPiAke3lhbWxGaWxlUGF0aH1gXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gdHlwZW9mIGFjY1trZXldID09PSBcInN0cmluZ1wiID8gYWNjW2tleV0udHJpbSgpIDogYWNjW2tleV07XG4gIH0sIHBhcnNlZFlBTUwpO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBXcml0ZXMgYSBKU09OIG9iamVjdCB0byBhIFlBTUwgZmlsZS5cbiAqIEBzdW1tYXJ5IFRoaXMgZnVuY3Rpb24gdGFrZXMgYSBKU09OIG9iamVjdCBhbmQgd3JpdGVzIGl0IHRvIGEgc3BlY2lmaWVkIGZpbGUgcGF0aCBpbiBZQU1MIGZvcm1hdC5cbiAqIEl0IHVzZXMganMteWFtbCB0byBjb252ZXJ0IHRoZSBKU09OIHRvIFlBTUwsIGFuZCB0aGVuIHdyaXRlcyB0aGUgY29udGVudCB0byB0aGUgZmlsZS5cbiAqXG4gKiBAZnVuY3Rpb24gd3JpdGVGaWxlWWFtbFxuICogQHRlbXBsYXRlIFQgLSBUaGUgdHlwZSBvZiB0aGUgSlNPTiBvYmplY3QgdG8gYmUgd3JpdHRlbi5cbiAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoIC0gVGhlIGZpbGUgcGF0aCB3aGVyZSB0aGUgWUFNTCBjb250ZW50IHdpbGwgYmUgd3JpdHRlbi5cbiAqIEBwYXJhbSB7VH0ganNvbiAtIFRoZSBKU09OIG9iamVjdCB0byBiZSBjb252ZXJ0ZWQgdG8gWUFNTCBhbmQgd3JpdHRlbiB0byB0aGUgZmlsZS5cbiAqIEByZXR1cm4ge3ZvaWR9XG4gKlxuICogQG1lbWJlck9mIG1vZHVsZTpmYWJyaWMtd2VhdmVyLlV0aWxzXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IGNvbmZpZyA9IHsgZGF0YWJhc2U6IHsgaG9zdDogJ2xvY2FsaG9zdCcsIHBvcnQ6IDU0MzIgfSB9O1xuICogd3JpdGVGaWxlWWFtbCgnY29uZmlnL3NldHRpbmdzLnlhbWwnLCBjb25maWcpO1xuICpcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgQ2FsbGVyXG4gKiAgIHBhcnRpY2lwYW50IHdyaXRlRmlsZVlhbWxcbiAqICAgcGFydGljaXBhbnQgbG9nZ2VyXG4gKiAgIHBhcnRpY2lwYW50IHlhbWxcbiAqICAgcGFydGljaXBhbnQgZnNcbiAqXG4gKiAgIENhbGxlci0+PndyaXRlRmlsZVlhbWw6IENhbGwgd2l0aCBwYXRoIGFuZCBKU09OXG4gKiAgIHdyaXRlRmlsZVlhbWwtPj5sb2dnZXI6IExvZyB2ZXJib3NlIG1lc3NhZ2UgKFdyaXRpbmcgWUFNTCBmaWxlKVxuICogICB3cml0ZUZpbGVZYW1sLT4+bG9nZ2VyOiBMb2cgdmVyYm9zZSBtZXNzYWdlIChXcml0aW5nIFlBTUwgY29udGVudClcbiAqICAgd3JpdGVGaWxlWWFtbC0+PnlhbWw6IENvbnZlcnQgSlNPTiB0byBZQU1MXG4gKiAgIHdyaXRlRmlsZVlhbWwtPj5sb2dnZXI6IExvZyB2ZXJib3NlIG1lc3NhZ2UgKFdyaXRpbmcgWUFNTCBjb250ZW50IHRvIGZpbGUpXG4gKiAgIHdyaXRlRmlsZVlhbWwtPj5mczogV3JpdGUgWUFNTCBjb250ZW50IHRvIGZpbGVcbiAqICAgd3JpdGVGaWxlWWFtbC0tPj5DYWxsZXI6IFJldHVybiAodm9pZClcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHdyaXRlRmlsZVlhbWw8VD4ocGF0aDogc3RyaW5nLCBqc29uOiBUKSB7XG4gIGNvbnN0IGxvZyA9IGxvZ2dlci5mb3Iod3JpdGVGaWxlWWFtbCk7XG5cbiAgbG9nLmRlYnVnKGBXcml0aW5nIFlBTUwgZmlsZTogJHtwYXRofWApO1xuICBsb2cuZGVidWcoYFdyaXRpbmcgWUFNTCBjb250ZW50OiAke0pTT04uc3RyaW5naWZ5KGpzb24sIG51bGwsIDIpfWApO1xuICBjb25zdCBjb250ZW50ID0geWFtbC5kdW1wKGpzb24sIHsgaW5kZW50OiAyLCBsaW5lV2lkdGg6IC0xIH0pO1xuXG4gIGxvZy5kZWJ1ZyhgV3JpdGluZyBZQU1MIGNvbnRlbnQgdG8gZmlsZTogJHtjb250ZW50fWApO1xuICBmcy53cml0ZUZpbGVTeW5jKHBhdGgsIGNvbnRlbnQucmVwbGFjZSgvIG51bGwkL2dtLCBcIlwiKSwgXCJ1dGY4XCIpO1xufVxuIl19