%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /home/opti/workflow/node_modules/email-templates/lib/
Upload File :
Create Path :
Current File : /home/opti/workflow/node_modules/email-templates/lib/index.js

"use strict";

function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }

function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }

function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }

function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }

function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }

function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }

const fs = require('fs');

const path = require('path');

const juice = require('juice');

const debug = require('debug')('email-templates');

const htmlToText = require('html-to-text');

const I18N = require('@ladjs/i18n');

const autoBind = require('auto-bind');

const nodemailer = require('nodemailer');

const consolidate = require('consolidate');

const previewEmail = require('preview-email');

const _ = require('lodash');

const _Promise = require('bluebird');

const s = require('underscore.string');

const getPaths = require('get-paths'); // promise version of `juice.juiceResources`


const juiceResources = (html, options) => {
  return new _Promise((resolve, reject) => {
    juice.juiceResources(html, options, (err, html) => {
      if (err) return reject(err);
      resolve(html);
    });
  });
};

const env = (process.env.NODE_ENV || 'development').toLowerCase();

const stat = _Promise.promisify(fs.stat);

const readFile = _Promise.promisify(fs.readFile);

class Email {
  constructor(config = {}) {
    debug('config passed %O', config); // 2.x backwards compatible support

    if (config.juiceOptions) {
      config.juiceResources = config.juiceOptions;
      delete config.juiceOptions;
    }

    if (config.disableJuice) {
      config.juice = false;
      delete config.disableJuice;
    }

    if (config.render) {
      config.customRender = true;
    }

    this.config = _.merge({
      views: {
        // directory where email templates reside
        root: path.resolve('emails'),
        options: {
          // default file extension for template
          extension: 'pug',
          map: {
            hbs: 'handlebars',
            njk: 'nunjucks'
          },
          engineSource: consolidate
        },
        // locals to pass to templates for rendering
        locals: {
          // turn on caching for non-development environments
          cache: !['development', 'test'].includes(env),
          // pretty is automatically set to `false` for subject/text
          pretty: true
        }
      },
      // <https://nodemailer.com/message/>
      message: {},
      send: !['development', 'test'].includes(env),
      preview: env === 'development',
      // <https://github.com/ladjs/i18n>
      // set to an object to configure and enable it
      i18n: false,
      // pass a custom render function if necessary
      render: this.render.bind(this),
      customRender: false,
      // force text-only rendering of template (disregards template folder)
      textOnly: false,
      // <https://github.com/werk85/node-html-to-text>
      htmlToText: {
        ignoreImage: true
      },
      subjectPrefix: false,
      // <https://github.com/Automattic/juice>
      juice: true,
      juiceResources: {
        preserveImportant: true,
        webResources: {
          relativeTo: path.resolve('build'),
          images: false
        }
      },
      // pass a transport configuration object or a transport instance
      // (e.g. an instance is created via `nodemailer.createTransport`)
      // <https://nodemailer.com/transports/>
      transport: {}
    }, config); // override existing method

    this.render = this.config.render;
    if (!_.isFunction(this.config.transport.sendMail)) this.config.transport = nodemailer.createTransport(this.config.transport);
    debug('transformed config %O', this.config);
    autoBind(this);
  } // shorthand use of `juiceResources` with the config
  // (mainly for custom renders like from a database)


  juiceResources(html) {
    return juiceResources(html, this.config.juiceResources);
  } // a simple helper function that gets the actual file path for the template


  getTemplatePath(template) {
    var _this = this;

    return _asyncToGenerator(function* () {
      const _ref = path.isAbsolute(template) ? [path.dirname(template), path.basename(template)] : [_this.config.views.root, template],
            _ref2 = _slicedToArray(_ref, 2),
            root = _ref2[0],
            view = _ref2[1];

      const paths = yield getPaths(root, view, _this.config.views.options.extension);
      const filePath = path.resolve(root, paths.rel);
      return {
        filePath,
        paths
      };
    })();
  } // returns true or false if a template exists
  // (uses same look-up approach as `render` function)


  templateExists(view) {
    var _this2 = this;

    return _asyncToGenerator(function* () {
      try {
        const _ref3 = yield _this2.getTemplatePath(view),
              filePath = _ref3.filePath;

        const stats = yield stat(filePath);
        if (!stats.isFile()) throw new Error(`${filePath} was not a file`);
        return true;
      } catch (err) {
        debug('templateExists', err);
        return false;
      }
    })();
  } // promise version of consolidate's render
  // inspired by koa-views and re-uses the same config
  // <https://github.com/queckezz/koa-views>


  render(view, locals = {}) {
    var _this3 = this;

    return _asyncToGenerator(function* () {
      const _this3$config$views$o = _this3.config.views.options,
            map = _this3$config$views$o.map,
            engineSource = _this3$config$views$o.engineSource;

      const _ref4 = yield _this3.getTemplatePath(view),
            filePath = _ref4.filePath,
            paths = _ref4.paths;

      if (paths.ext === 'html' && !map) {
        const res = yield readFile(filePath, 'utf8');
        return res;
      }

      const engineName = map && map[paths.ext] ? map[paths.ext] : paths.ext;
      const renderFn = engineSource[engineName];
      if (!engineName || !renderFn) throw new Error(`Engine not found for the ".${paths.ext}" file extension`);

      if (_.isObject(_this3.config.i18n)) {
        const i18n = new I18N(Object.assign({}, _this3.config.i18n, {
          register: locals
        })); // support `locals.user.last_locale`
        // (e.g. for <https://lad.js.org>)

        if (_.isObject(locals.user) && _.isString(locals.user.last_locale)) locals.locale = locals.user.last_locale;
        if (_.isString(locals.locale)) i18n.setLocale(locals.locale);
      }

      const res = yield _Promise.promisify(renderFn)(filePath, locals); // transform the html with juice using remote paths
      // google now supports media queries
      // https://developers.google.com/gmail/design/reference/supported_css

      if (!_this3.config.juice) return res;
      const html = yield _this3.juiceResources(res);
      return html;
    })();
  } // TODO: this needs refactored
  // so that we render templates asynchronously


  renderAll(template, locals = {}, message = {}) {
    var _this4 = this;

    return _asyncToGenerator(function* () {
      let subjectTemplateExists = _this4.config.customRender;
      let htmlTemplateExists = _this4.config.customRender;
      let textTemplateExists = _this4.config.customRender;

      if (template && !_this4.config.customRender) {
        var _ref5 = yield _Promise.all([_this4.templateExists(`${template}/subject`), _this4.templateExists(`${template}/html`), _this4.templateExists(`${template}/text`)]);

        var _ref6 = _slicedToArray(_ref5, 3);

        subjectTemplateExists = _ref6[0];
        htmlTemplateExists = _ref6[1];
        textTemplateExists = _ref6[2];
      }

      if (!message.subject && subjectTemplateExists) {
        message.subject = yield _this4.render(`${template}/subject`, Object.assign({}, locals, {
          pretty: false
        }));
        message.subject = message.subject.trim();
      }

      if (message.subject && _this4.config.subjectPrefix) message.subject = _this4.config.subjectPrefix + message.subject;
      if (!message.html && htmlTemplateExists) message.html = yield _this4.render(`${template}/html`, locals);
      if (!message.text && textTemplateExists) message.text = yield _this4.render(`${template}/text`, Object.assign({}, locals, {
        pretty: false
      }));
      if (_this4.config.htmlToText && message.html && !message.text) // we'd use nodemailer-html-to-text plugin
        // but we really don't need to support cid
        // <https://github.com/andris9/nodemailer-html-to-text>
        message.text = htmlToText.fromString(message.html, _this4.config.htmlToText); // if we only want a text-based version of the email

      if (_this4.config.textOnly) delete message.html; // if no subject, html, or text content exists then we should
      // throw an error that says at least one must be found
      // otherwise the email would be blank (defeats purpose of email-templates)

      if (s.isBlank(message.subject) && s.isBlank(message.text) && s.isBlank(message.html) && _.isArray(message.attachments) && _.isEmpty(message.attachments)) throw new Error(`No content was passed for subject, html, text, nor attachments message props. Check that the files for the template "${template}" exist.`);
      return message;
    })();
  }

  send(options = {}) {
    var _this5 = this;

    return _asyncToGenerator(function* () {
      options = Object.assign({
        template: '',
        message: {},
        locals: {}
      }, options);
      let _options = options,
          template = _options.template,
          message = _options.message,
          locals = _options.locals;
      const attachments = message.attachments || _this5.config.message.attachments || [];
      message = _.defaultsDeep({}, _.omit(message, 'attachments'), _.omit(_this5.config.message, 'attachments'));
      locals = _.defaultsDeep({}, _this5.config.views.locals, locals);
      if (attachments) message.attachments = attachments;
      debug('template %s', template);
      debug('message %O', message);
      debug('locals (keys only): %O', Object.keys(locals)); // get all available templates

      const obj = yield _this5.renderAll(template, locals, message); // assign the object variables over to the message

      Object.assign(message, obj);

      if (_this5.config.preview) {
        debug('using `preview-email` to preview email');
        if (_.isObject(_this5.config.preview)) yield previewEmail(message, null, true, _this5.config.preview);else yield previewEmail(message);
      }

      if (!_this5.config.send) {
        debug('send disabled so we are ensuring JSONTransport'); // <https://github.com/nodemailer/nodemailer/issues/798>
        // if (this.config.transport.name !== 'JSONTransport')

        _this5.config.transport = nodemailer.createTransport({
          jsonTransport: true
        });
      }

      const res = yield _this5.config.transport.sendMail(message);
      debug('message sent');
      res.originalMessage = message;
      return res;
    })();
  }

}

module.exports = Email;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9pbmRleC5qcyJdLCJuYW1lcyI6WyJmcyIsInJlcXVpcmUiLCJwYXRoIiwianVpY2UiLCJkZWJ1ZyIsImh0bWxUb1RleHQiLCJJMThOIiwiYXV0b0JpbmQiLCJub2RlbWFpbGVyIiwiY29uc29saWRhdGUiLCJwcmV2aWV3RW1haWwiLCJfIiwiUHJvbWlzZSIsInMiLCJnZXRQYXRocyIsImp1aWNlUmVzb3VyY2VzIiwiaHRtbCIsIm9wdGlvbnMiLCJyZXNvbHZlIiwicmVqZWN0IiwiZXJyIiwiZW52IiwicHJvY2VzcyIsIk5PREVfRU5WIiwidG9Mb3dlckNhc2UiLCJzdGF0IiwicHJvbWlzaWZ5IiwicmVhZEZpbGUiLCJFbWFpbCIsImNvbnN0cnVjdG9yIiwiY29uZmlnIiwianVpY2VPcHRpb25zIiwiZGlzYWJsZUp1aWNlIiwicmVuZGVyIiwiY3VzdG9tUmVuZGVyIiwibWVyZ2UiLCJ2aWV3cyIsInJvb3QiLCJleHRlbnNpb24iLCJtYXAiLCJoYnMiLCJuamsiLCJlbmdpbmVTb3VyY2UiLCJsb2NhbHMiLCJjYWNoZSIsImluY2x1ZGVzIiwicHJldHR5IiwibWVzc2FnZSIsInNlbmQiLCJwcmV2aWV3IiwiaTE4biIsImJpbmQiLCJ0ZXh0T25seSIsImlnbm9yZUltYWdlIiwic3ViamVjdFByZWZpeCIsInByZXNlcnZlSW1wb3J0YW50Iiwid2ViUmVzb3VyY2VzIiwicmVsYXRpdmVUbyIsImltYWdlcyIsInRyYW5zcG9ydCIsImlzRnVuY3Rpb24iLCJzZW5kTWFpbCIsImNyZWF0ZVRyYW5zcG9ydCIsImdldFRlbXBsYXRlUGF0aCIsInRlbXBsYXRlIiwiaXNBYnNvbHV0ZSIsImRpcm5hbWUiLCJiYXNlbmFtZSIsInZpZXciLCJwYXRocyIsImZpbGVQYXRoIiwicmVsIiwidGVtcGxhdGVFeGlzdHMiLCJzdGF0cyIsImlzRmlsZSIsIkVycm9yIiwiZXh0IiwicmVzIiwiZW5naW5lTmFtZSIsInJlbmRlckZuIiwiaXNPYmplY3QiLCJPYmplY3QiLCJhc3NpZ24iLCJyZWdpc3RlciIsInVzZXIiLCJpc1N0cmluZyIsImxhc3RfbG9jYWxlIiwibG9jYWxlIiwic2V0TG9jYWxlIiwicmVuZGVyQWxsIiwic3ViamVjdFRlbXBsYXRlRXhpc3RzIiwiaHRtbFRlbXBsYXRlRXhpc3RzIiwidGV4dFRlbXBsYXRlRXhpc3RzIiwiYWxsIiwic3ViamVjdCIsInRyaW0iLCJ0ZXh0IiwiZnJvbVN0cmluZyIsImlzQmxhbmsiLCJpc0FycmF5IiwiYXR0YWNobWVudHMiLCJpc0VtcHR5IiwiZGVmYXVsdHNEZWVwIiwib21pdCIsImtleXMiLCJvYmoiLCJqc29uVHJhbnNwb3J0Iiwib3JpZ2luYWxNZXNzYWdlIiwibW9kdWxlIiwiZXhwb3J0cyJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7QUFBQSxNQUFNQSxFQUFFLEdBQUdDLE9BQU8sQ0FBQyxJQUFELENBQWxCOztBQUNBLE1BQU1DLElBQUksR0FBR0QsT0FBTyxDQUFDLE1BQUQsQ0FBcEI7O0FBQ0EsTUFBTUUsS0FBSyxHQUFHRixPQUFPLENBQUMsT0FBRCxDQUFyQjs7QUFDQSxNQUFNRyxLQUFLLEdBQUdILE9BQU8sQ0FBQyxPQUFELENBQVAsQ0FBaUIsaUJBQWpCLENBQWQ7O0FBQ0EsTUFBTUksVUFBVSxHQUFHSixPQUFPLENBQUMsY0FBRCxDQUExQjs7QUFDQSxNQUFNSyxJQUFJLEdBQUdMLE9BQU8sQ0FBQyxhQUFELENBQXBCOztBQUNBLE1BQU1NLFFBQVEsR0FBR04sT0FBTyxDQUFDLFdBQUQsQ0FBeEI7O0FBQ0EsTUFBTU8sVUFBVSxHQUFHUCxPQUFPLENBQUMsWUFBRCxDQUExQjs7QUFDQSxNQUFNUSxXQUFXLEdBQUdSLE9BQU8sQ0FBQyxhQUFELENBQTNCOztBQUNBLE1BQU1TLFlBQVksR0FBR1QsT0FBTyxDQUFDLGVBQUQsQ0FBNUI7O0FBQ0EsTUFBTVUsQ0FBQyxHQUFHVixPQUFPLENBQUMsUUFBRCxDQUFqQjs7QUFDQSxNQUFNVyxRQUFPLEdBQUdYLE9BQU8sQ0FBQyxVQUFELENBQXZCOztBQUNB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LE9BQS9CLENBQWxCO0FBQ0EzQyxNQUFBQSxLQUFLLENBQUMsY0FBRCxDQUFMO0FBQ0F5RSxNQUFBQSxHQUFHLENBQUM4QixlQUFKLEdBQXNCNUQsT0FBdEI7QUFDQSxhQUFPOEIsR0FBUDtBQXJEdUI7QUFzRHhCOztBQTNSUzs7QUE4UlorQixNQUFNLENBQUNDLE9BQVAsR0FBaUJqRixLQUFqQiIsInNvdXJjZXNDb250ZW50IjpbImNvbnN0IGZzID0gcmVxdWlyZSgnZnMnKTtcbmNvbnN0IHBhdGggPSByZXF1aXJlKCdwYXRoJyk7XG5jb25zdCBqdWljZSA9IHJlcXVpcmUoJ2p1aWNlJyk7XG5jb25zdCBkZWJ1ZyA9IHJlcXVpcmUoJ2RlYnVnJykoJ2VtYWlsLXRlbXBsYXRlcycpO1xuY29uc3QgaHRtbFRvVGV4dCA9IHJlcXVpcmUoJ2h0bWwtdG8tdGV4dCcpO1xuY29uc3QgSTE4TiA9IHJlcXVpcmUoJ0BsYWRqcy9pMThuJyk7XG5jb25zdCBhdXRvQmluZCA9IHJlcXVpcmUoJ2F1dG8tYmluZCcpO1xuY29uc3Qgbm9kZW1haWxlciA9IHJlcXVpcmUoJ25vZGVtYWlsZXInKTtcbmNvbnN0IGNvbnNvbGlkYXRlID0gcmVxdWlyZSgnY29uc29saWRhdGUnKTtcbmNvbnN0IHByZXZpZXdFbWFpbCA9IHJlcXVpcmUoJ3ByZXZpZXctZW1haWwnKTtcbmNvbnN0IF8gPSByZXF1aXJlKCdsb2Rhc2gnKTtcbmNvbnN0IFByb21pc2UgPSByZXF1aXJlKCdibHVlYmlyZCcpO1xuY29uc3QgcyA9IHJlcXVpcmUoJ3VuZGVyc2NvcmUuc3RyaW5nJyk7XG5cbmNvbnN0IGdldFBhdGhzID0gcmVxdWlyZSgnZ2V0LXBhdGhzJyk7XG5cbi8vIHByb21pc2UgdmVyc2lvbiBvZiBganVpY2UuanVpY2VSZXNvdXJjZXNgXG5jb25zdCBqdWljZVJlc291cmNlcyA9IChodG1sLCBvcHRpb25zKSA9PiB7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAganVpY2UuanVpY2VSZXNvdXJjZXMoaHRtbCwgb3B0aW9ucywgKGVyciwgaHRtbCkgPT4ge1xuICAgICAgaWYgKGVycikgcmV0dXJuIHJlamVjdChlcnIpO1xuICAgICAgcmVzb2x2ZShodG1sKTtcbiAgICB9KTtcbiAgfSk7XG59O1xuXG5jb25zdCBlbnYgPSAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgfHwgJ2RldmVsb3BtZW50JykudG9Mb3dlckNhc2UoKTtcbmNvbnN0IHN0YXQgPSBQcm9taXNlLnByb21pc2lmeShmcy5zdGF0KTtcbmNvbnN0IHJlYWRGaWxlID0gUHJvbWlzZS5wcm9taXNpZnkoZnMucmVhZEZpbGUpO1xuXG5jbGFzcyBFbWFpbCB7XG4gIGNvbnN0cnVjdG9yKGNvbmZpZyA9IHt9KSB7XG4gICAgZGVidWcoJ2NvbmZpZyBwYXNzZWQgJU8nLCBjb25maWcpO1xuXG4gICAgLy8gMi54IGJhY2t3YXJkcyBjb21wYXRpYmxlIHN1cHBvcnRcbiAgICBpZiAoY29uZmlnLmp1aWNlT3B0aW9ucykge1xuICAgICAgY29uZmlnLmp1aWNlUmVzb3VyY2VzID0gY29uZmlnLmp1aWNlT3B0aW9ucztcbiAgICAgIGRlbGV0ZSBjb25maWcuanVpY2VPcHRpb25zO1xuICAgIH1cblxuICAgIGlmIChjb25maWcuZGlzYWJsZUp1aWNlKSB7XG4gICAgICBjb25maWcuanVpY2UgPSBmYWxzZTtcbiAgICAgIGRlbGV0ZSBjb25maWcuZGlzYWJsZUp1aWNlO1xuICAgIH1cblxuICAgIGlmIChjb25maWcucmVuZGVyKSB7XG4gICAgICBjb25maWcuY3VzdG9tUmVuZGVyID0gdHJ1ZTtcbiAgICB9XG5cbiAgICB0aGlzLmNvbmZpZyA9IF8ubWVyZ2UoXG4gICAgICB7XG4gICAgICAgIHZpZXdzOiB7XG4gICAgICAgICAgLy8gZGlyZWN0b3J5IHdoZXJlIGVtYWlsIHRlbXBsYXRlcyByZXNpZGVcbiAgICAgICAgICByb290OiBwYXRoLnJlc29sdmUoJ2VtYWlscycpLFxuICAgICAgICAgIG9wdGlvbnM6IHtcbiAgICAgICAgICAgIC8vIGRlZmF1bHQgZmlsZSBleHRlbnNpb24gZm9yIHRlbXBsYXRlXG4gICAgICAgICAgICBleHRlbnNpb246ICdwdWcnLFxuICAgICAgICAgICAgbWFwOiB7XG4gICAgICAgICAgICAgIGhiczogJ2hhbmRsZWJhcnMnLFxuICAgICAgICAgICAgICBuams6ICdudW5qdWNrcydcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBlbmdpbmVTb3VyY2U6IGNvbnNvbGlkYXRlXG4gICAgICAgICAgfSxcbiAgICAgICAgICAvLyBsb2NhbHMgdG8gcGFzcyB0byB0ZW1wbGF0ZXMgZm9yIHJlbmRlcmluZ1xuICAgICAgICAgIGxvY2Fsczoge1xuICAgICAgICAgICAgLy8gdHVybiBvbiBjYWNoaW5nIGZvciBub24tZGV2ZWxvcG1lbnQgZW52aXJvbm1lbnRzXG4gICAgICAgICAgICBjYWNoZTogIVsnZGV2ZWxvcG1lbnQnLCAndGVzdCddLmluY2x1ZGVzKGVudiksXG4gICAgICAgICAgICAvLyBwcmV0dHkgaXMgYXV0b21hdGljYWxseSBzZXQgdG8gYGZhbHNlYCBmb3Igc3ViamVjdC90ZXh0XG4gICAgICAgICAgICBwcmV0dHk6IHRydWVcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIC8vIDxodHRwczovL25vZGVtYWlsZXIuY29tL21lc3NhZ2UvPlxuICAgICAgICBtZXNzYWdlOiB7fSxcbiAgICAgICAgc2VuZDogIVsnZGV2ZWxvcG1lbnQnLCAndGVzdCddLmluY2x1ZGVzKGVudiksXG4gICAgICAgIHByZXZpZXc6IGVudiA9PT0gJ2RldmVsb3BtZW50JyxcbiAgICAgICAgLy8gPGh0dHBzOi8vZ2l0aHViLmNvbS9sYWRqcy9pMThuPlxuICAgICAgICAvLyBzZXQgdG8gYW4gb2JqZWN0IHRvIGNvbmZpZ3VyZSBhbmQgZW5hYmxlIGl0XG4gICAgICAgIGkxOG46IGZhbHNlLFxuICAgICAgICAvLyBwYXNzIGEgY3VzdG9tIHJlbmRlciBmdW5jdGlvbiBpZiBuZWNlc3NhcnlcbiAgICAgICAgcmVuZGVyOiB0aGlzLnJlbmRlci5iaW5kKHRoaXMpLFxuICAgICAgICBjdXN0b21SZW5kZXI6IGZhbHNlLFxuICAgICAgICAvLyBmb3JjZSB0ZXh0LW9ubHkgcmVuZGVyaW5nIG9mIHRlbXBsYXRlIChkaXNyZWdhcmRzIHRlbXBsYXRlIGZvbGRlcilcbiAgICAgICAgdGV4dE9ubHk6IGZhbHNlLFxuICAgICAgICAvLyA8aHR0cHM6Ly9naXRodWIuY29tL3dlcms4NS9ub2RlLWh0bWwtdG8tdGV4dD5cbiAgICAgICAgaHRtbFRvVGV4dDoge1xuICAgICAgICAgIGlnbm9yZUltYWdlOiB0cnVlXG4gICAgICAgIH0sXG4gICAgICAgIHN1YmplY3RQcmVmaXg6IGZhbHNlLFxuICAgICAgICAvLyA8aHR0cHM6Ly9naXRodWIuY29tL0F1dG9tYXR0aWMvanVpY2U+XG4gICAgICAgIGp1aWNlOiB0cnVlLFxuICAgICAgICBqdWljZVJlc291cmNlczoge1xuICAgICAgICAgIHByZXNlcnZlSW1wb3J0YW50OiB0cnVlLFxuICAgICAgICAgIHdlYlJlc291cmNlczoge1xuICAgICAgICAgICAgcmVsYXRpdmVUbzogcGF0aC5yZXNvbHZlKCdidWlsZCcpLFxuICAgICAgICAgICAgaW1hZ2VzOiBmYWxzZVxuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgLy8gcGFzcyBhIHRyYW5zcG9ydCBjb25maWd1cmF0aW9uIG9iamVjdCBvciBhIHRyYW5zcG9ydCBpbnN0YW5jZVxuICAgICAgICAvLyAoZS5nLiBhbiBpbnN0YW5jZSBpcyBjcmVhdGVkIHZpYSBgbm9kZW1haWxlci5jcmVhdGVUcmFuc3BvcnRgKVxuICAgICAgICAvLyA8aHR0cHM6Ly9ub2RlbWFpbGVyLmNvbS90cmFuc3BvcnRzLz5cbiAgICAgICAgdHJhbnNwb3J0OiB7fVxuICAgICAgfSxcbiAgICAgIGNvbmZpZ1xuICAgICk7XG5cbiAgICAvLyBvdmVycmlkZSBleGlzdGluZyBtZXRob2RcbiAgICB0aGlzLnJlbmRlciA9IHRoaXMuY29uZmlnLnJlbmRlcjtcblxuICAgIGlmICghXy5pc0Z1bmN0aW9uKHRoaXMuY29uZmlnLnRyYW5zcG9ydC5zZW5kTWFpbCkpXG4gICAgICB0aGlzLmNvbmZpZy50cmFuc3BvcnQgPSBub2RlbWFpbGVyLmNyZWF0ZVRyYW5zcG9ydCh0aGlzLmNvbmZpZy50cmFuc3BvcnQpO1xuXG4gICAgZGVidWcoJ3RyYW5zZm9ybWVkIGNvbmZpZyAlTycsIHRoaXMuY29uZmlnKTtcblxuICAgIGF1dG9CaW5kKHRoaXMpO1xuICB9XG5cbiAgLy8gc2hvcnRoYW5kIHVzZSBvZiBganVpY2VSZXNvdXJjZXNgIHdpdGggdGhlIGNvbmZpZ1xuICAvLyAobWFpbmx5IGZvciBjdXN0b20gcmVuZGVycyBsaWtlIGZyb20gYSBkYXRhYmFzZSlcbiAganVpY2VSZXNvdXJjZXMoaHRtbCkge1xuICAgIHJldHVybiBqdWljZVJlc291cmNlcyhodG1sLCB0aGlzLmNvbmZpZy5qdWljZVJlc291cmNlcyk7XG4gIH1cblxuICAvLyBhIHNpbXBsZSBoZWxwZXIgZnVuY3Rpb24gdGhhdCBnZXRzIHRoZSBhY3R1YWwgZmlsZSBwYXRoIGZvciB0aGUgdGVtcGxhdGVcbiAgYXN5bmMgZ2V0VGVtcGxhdGVQYXRoKHRlbXBsYXRlKSB7XG4gICAgY29uc3QgW3Jvb3QsIHZpZXddID0gcGF0aC5pc0Fic29sdXRlKHRlbXBsYXRlKVxuICAgICAgPyBbcGF0aC5kaXJuYW1lKHRlbXBsYXRlKSwgcGF0aC5iYXNlbmFtZSh0ZW1wbGF0ZSldXG4gICAgICA6IFt0aGlzLmNvbmZpZy52aWV3cy5yb290LCB0ZW1wbGF0ZV07XG4gICAgY29uc3QgcGF0aHMgPSBhd2FpdCBnZXRQYXRocyhcbiAgICAgIHJvb3QsXG4gICAgICB2aWV3LFxuICAgICAgdGhpcy5jb25maWcudmlld3Mub3B0aW9ucy5leHRlbnNpb25cbiAgICApO1xuICAgIGNvbnN0IGZpbGVQYXRoID0gcGF0aC5yZXNvbHZlKHJvb3QsIHBhdGhzLnJlbCk7XG4gICAgcmV0dXJuIHsgZmlsZVBhdGgsIHBhdGhzIH07XG4gIH1cblxuICAvLyByZXR1cm5zIHRydWUgb3IgZmFsc2UgaWYgYSB0ZW1wbGF0ZSBleGlzdHNcbiAgLy8gKHVzZXMgc2FtZSBsb29rLXVwIGFwcHJvYWNoIGFzIGByZW5kZXJgIGZ1bmN0aW9uKVxuICBhc3luYyB0ZW1wbGF0ZUV4aXN0cyh2aWV3KSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHsgZmlsZVBhdGggfSA9IGF3YWl0IHRoaXMuZ2V0VGVtcGxhdGVQYXRoKHZpZXcpO1xuICAgICAgY29uc3Qgc3RhdHMgPSBhd2FpdCBzdGF0KGZpbGVQYXRoKTtcbiAgICAgIGlmICghc3RhdHMuaXNGaWxlKCkpIHRocm93IG5ldyBFcnJvcihgJHtmaWxlUGF0aH0gd2FzIG5vdCBhIGZpbGVgKTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgZGVidWcoJ3RlbXBsYXRlRXhpc3RzJywgZXJyKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICAvLyBwcm9taXNlIHZlcnNpb24gb2YgY29uc29saWRhdGUncyByZW5kZXJcbiAgLy8gaW5zcGlyZWQgYnkga29hLXZpZXdzIGFuZCByZS11c2VzIHRoZSBzYW1lIGNvbmZpZ1xuICAvLyA8aHR0cHM6Ly9naXRodWIuY29tL3F1ZWNrZXp6L2tvYS12aWV3cz5cbiAgYXN5bmMgcmVuZGVyKHZpZXcsIGxvY2FscyA9IHt9KSB7XG4gICAgY29uc3QgeyBtYXAsIGVuZ2luZVNvdXJjZSB9ID0gdGhpcy5jb25maWcudmlld3Mub3B0aW9ucztcbiAgICBjb25zdCB7IGZpbGVQYXRoLCBwYXRocyB9ID0gYXdhaXQgdGhpcy5nZXRUZW1wbGF0ZVBhdGgodmlldyk7XG4gICAgaWYgKHBhdGhzLmV4dCA9PT0gJ2h0bWwnICYmICFtYXApIHtcbiAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IHJlYWRGaWxlKGZpbGVQYXRoLCAndXRmOCcpO1xuICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG5cbiAgICBjb25zdCBlbmdpbmVOYW1lID0gbWFwICYmIG1hcFtwYXRocy5leHRdID8gbWFwW3BhdGhzLmV4dF0gOiBwYXRocy5leHQ7XG4gICAgY29uc3QgcmVuZGVyRm4gPSBlbmdpbmVTb3VyY2VbZW5naW5lTmFtZV07XG4gICAgaWYgKCFlbmdpbmVOYW1lIHx8ICFyZW5kZXJGbilcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYEVuZ2luZSBub3QgZm91bmQgZm9yIHRoZSBcIi4ke3BhdGhzLmV4dH1cIiBmaWxlIGV4dGVuc2lvbmBcbiAgICAgICk7XG5cbiAgICBpZiAoXy5pc09iamVjdCh0aGlzLmNvbmZpZy5pMThuKSkge1xuICAgICAgY29uc3QgaTE4biA9IG5ldyBJMThOKFxuICAgICAgICBPYmplY3QuYXNzaWduKHt9LCB0aGlzLmNvbmZpZy5pMThuLCB7XG4gICAgICAgICAgcmVnaXN0ZXI6IGxvY2Fsc1xuICAgICAgICB9KVxuICAgICAgKTtcblxuICAgICAgLy8gc3VwcG9ydCBgbG9jYWxzLnVzZXIubGFzdF9sb2NhbGVgXG4gICAgICAvLyAoZS5nLiBmb3IgPGh0dHBzOi8vbGFkLmpzLm9yZz4pXG4gICAgICBpZiAoXy5pc09iamVjdChsb2NhbHMudXNlcikgJiYgXy5pc1N0cmluZyhsb2NhbHMudXNlci5sYXN0X2xvY2FsZSkpXG4gICAgICAgIGxvY2Fscy5sb2NhbGUgPSBsb2NhbHMudXNlci5sYXN0X2xvY2FsZTtcblxuICAgICAgaWYgKF8uaXNTdHJpbmcobG9jYWxzLmxvY2FsZSkpIGkxOG4uc2V0TG9jYWxlKGxvY2Fscy5sb2NhbGUpO1xuICAgIH1cblxuICAgIGNvbnN0IHJlcyA9IGF3YWl0IFByb21pc2UucHJvbWlzaWZ5KHJlbmRlckZuKShmaWxlUGF0aCwgbG9jYWxzKTtcbiAgICAvLyB0cmFuc2Zvcm0gdGhlIGh0bWwgd2l0aCBqdWljZSB1c2luZyByZW1vdGUgcGF0aHNcbiAgICAvLyBnb29nbGUgbm93IHN1cHBvcnRzIG1lZGlhIHF1ZXJpZXNcbiAgICAvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9nbWFpbC9kZXNpZ24vcmVmZXJlbmNlL3N1cHBvcnRlZF9jc3NcbiAgICBpZiAoIXRoaXMuY29uZmlnLmp1aWNlKSByZXR1cm4gcmVzO1xuICAgIGNvbnN0IGh0bWwgPSBhd2FpdCB0aGlzLmp1aWNlUmVzb3VyY2VzKHJlcyk7XG4gICAgcmV0dXJuIGh0bWw7XG4gIH1cblxuICAvLyBUT0RPOiB0aGlzIG5lZWRzIHJlZmFjdG9yZWRcbiAgLy8gc28gdGhhdCB3ZSByZW5kZXIgdGVtcGxhdGVzIGFzeW5jaHJvbm91c2x5XG4gIGFzeW5jIHJlbmRlckFsbCh0ZW1wbGF0ZSwgbG9jYWxzID0ge30sIG1lc3NhZ2UgPSB7fSkge1xuICAgIGxldCBzdWJqZWN0VGVtcGxhdGVFeGlzdHMgPSB0aGlzLmNvbmZpZy5jdXN0b21SZW5kZXI7XG4gICAgbGV0IGh0bWxUZW1wbGF0ZUV4aXN0cyA9IHRoaXMuY29uZmlnLmN1c3RvbVJlbmRlcjtcbiAgICBsZXQgdGV4dFRlbXBsYXRlRXhpc3RzID0gdGhpcy5jb25maWcuY3VzdG9tUmVuZGVyO1xuXG4gICAgaWYgKHRlbXBsYXRlICYmICF0aGlzLmNvbmZpZy5jdXN0b21SZW5kZXIpXG4gICAgICBbXG4gICAgICAgIHN1YmplY3RUZW1wbGF0ZUV4aXN0cyxcbiAgICAgICAgaHRtbFRlbXBsYXRlRXhpc3RzLFxuICAgICAgICB0ZXh0VGVtcGxhdGVFeGlzdHNcbiAgICAgIF0gPSBhd2FpdCBQcm9taXNlLmFsbChbXG4gICAgICAgIHRoaXMudGVtcGxhdGVFeGlzdHMoYCR7dGVtcGxhdGV9L3N1YmplY3RgKSxcbiAgICAgICAgdGhpcy50ZW1wbGF0ZUV4aXN0cyhgJHt0ZW1wbGF0ZX0vaHRtbGApLFxuICAgICAgICB0aGlzLnRlbXBsYXRlRXhpc3RzKGAke3RlbXBsYXRlfS90ZXh0YClcbiAgICAgIF0pO1xuXG4gICAgaWYgKCFtZXNzYWdlLnN1YmplY3QgJiYgc3ViamVjdFRlbXBsYXRlRXhpc3RzKSB7XG4gICAgICBtZXNzYWdlLnN1YmplY3QgPSBhd2FpdCB0aGlzLnJlbmRlcihcbiAgICAgICAgYCR7dGVtcGxhdGV9L3N1YmplY3RgLFxuICAgICAgICBPYmplY3QuYXNzaWduKHt9LCBsb2NhbHMsIHsgcHJldHR5OiBmYWxzZSB9KVxuICAgICAgKTtcbiAgICAgIG1lc3NhZ2Uuc3ViamVjdCA9IG1lc3NhZ2Uuc3ViamVjdC50cmltKCk7XG4gICAgfVxuXG4gICAgaWYgKG1lc3NhZ2Uuc3ViamVjdCAmJiB0aGlzLmNvbmZpZy5zdWJqZWN0UHJlZml4KVxuICAgICAgbWVzc2FnZS5zdWJqZWN0ID0gdGhpcy5jb25maWcuc3ViamVjdFByZWZpeCArIG1lc3NhZ2Uuc3ViamVjdDtcblxuICAgIGlmICghbWVzc2FnZS5odG1sICYmIGh0bWxUZW1wbGF0ZUV4aXN0cylcbiAgICAgIG1lc3NhZ2UuaHRtbCA9IGF3YWl0IHRoaXMucmVuZGVyKGAke3RlbXBsYXRlfS9odG1sYCwgbG9jYWxzKTtcblxuICAgIGlmICghbWVzc2FnZS50ZXh0ICYmIHRleHRUZW1wbGF0ZUV4aXN0cylcbiAgICAgIG1lc3NhZ2UudGV4dCA9IGF3YWl0IHRoaXMucmVuZGVyKFxuICAgICAgICBgJHt0ZW1wbGF0ZX0vdGV4dGAsXG4gICAgICAgIE9iamVjdC5hc3NpZ24oe30sIGxvY2FscywgeyBwcmV0dHk6IGZhbHNlIH0pXG4gICAgICApO1xuXG4gICAgaWYgKHRoaXMuY29uZmlnLmh0bWxUb1RleHQgJiYgbWVzc2FnZS5odG1sICYmICFtZXNzYWdlLnRleHQpXG4gICAgICAvLyB3ZSdkIHVzZSBub2RlbWFpbGVyLWh0bWwtdG8tdGV4dCBwbHVnaW5cbiAgICAgIC8vIGJ1dCB3ZSByZWFsbHkgZG9uJ3QgbmVlZCB0byBzdXBwb3J0IGNpZFxuICAgICAgLy8gPGh0dHBzOi8vZ2l0aHViLmNvbS9hbmRyaXM5L25vZGVtYWlsZXItaHRtbC10by10ZXh0PlxuICAgICAgbWVzc2FnZS50ZXh0ID0gaHRtbFRvVGV4dC5mcm9tU3RyaW5nKFxuICAgICAgICBtZXNzYWdlLmh0bWwsXG4gICAgICAgIHRoaXMuY29uZmlnLmh0bWxUb1RleHRcbiAgICAgICk7XG5cbiAgICAvLyBpZiB3ZSBvbmx5IHdhbnQgYSB0ZXh0LWJhc2VkIHZlcnNpb24gb2YgdGhlIGVtYWlsXG4gICAgaWYgKHRoaXMuY29uZmlnLnRleHRPbmx5KSBkZWxldGUgbWVzc2FnZS5odG1sO1xuXG4gICAgLy8gaWYgbm8gc3ViamVjdCwgaHRtbCwgb3IgdGV4dCBjb250ZW50IGV4aXN0cyB0aGVuIHdlIHNob3VsZFxuICAgIC8vIHRocm93IGFuIGVycm9yIHRoYXQgc2F5cyBhdCBsZWFzdCBvbmUgbXVzdCBiZSBmb3VuZFxuICAgIC8vIG90aGVyd2lzZSB0aGUgZW1haWwgd291bGQgYmUgYmxhbmsgKGRlZmVhdHMgcHVycG9zZSBvZiBlbWFpbC10ZW1wbGF0ZXMpXG4gICAgaWYgKFxuICAgICAgcy5pc0JsYW5rKG1lc3NhZ2Uuc3ViamVjdCkgJiZcbiAgICAgIHMuaXNCbGFuayhtZXNzYWdlLnRleHQpICYmXG4gICAgICBzLmlzQmxhbmsobWVzc2FnZS5odG1sKSAmJlxuICAgICAgXy5pc0FycmF5KG1lc3NhZ2UuYXR0YWNobWVudHMpICYmXG4gICAgICBfLmlzRW1wdHkobWVzc2FnZS5hdHRhY2htZW50cylcbiAgICApXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBObyBjb250ZW50IHdhcyBwYXNzZWQgZm9yIHN1YmplY3QsIGh0bWwsIHRleHQsIG5vciBhdHRhY2htZW50cyBtZXNzYWdlIHByb3BzLiBDaGVjayB0aGF0IHRoZSBmaWxlcyBmb3IgdGhlIHRlbXBsYXRlIFwiJHt0ZW1wbGF0ZX1cIiBleGlzdC5gXG4gICAgICApO1xuXG4gICAgcmV0dXJuIG1lc3NhZ2U7XG4gIH1cblxuICBhc3luYyBzZW5kKG9wdGlvbnMgPSB7fSkge1xuICAgIG9wdGlvbnMgPSBPYmplY3QuYXNzaWduKFxuICAgICAge1xuICAgICAgICB0ZW1wbGF0ZTogJycsXG4gICAgICAgIG1lc3NhZ2U6IHt9LFxuICAgICAgICBsb2NhbHM6IHt9XG4gICAgICB9LFxuICAgICAgb3B0aW9uc1xuICAgICk7XG5cbiAgICBsZXQgeyB0ZW1wbGF0ZSwgbWVzc2FnZSwgbG9jYWxzIH0gPSBvcHRpb25zO1xuXG4gICAgY29uc3QgYXR0YWNobWVudHMgPVxuICAgICAgbWVzc2FnZS5hdHRhY2htZW50cyB8fCB0aGlzLmNvbmZpZy5tZXNzYWdlLmF0dGFjaG1lbnRzIHx8IFtdO1xuXG4gICAgbWVzc2FnZSA9IF8uZGVmYXVsdHNEZWVwKFxuICAgICAge30sXG4gICAgICBfLm9taXQobWVzc2FnZSwgJ2F0dGFjaG1lbnRzJyksXG4gICAgICBfLm9taXQodGhpcy5jb25maWcubWVzc2FnZSwgJ2F0dGFjaG1lbnRzJylcbiAgICApO1xuICAgIGxvY2FscyA9IF8uZGVmYXVsdHNEZWVwKHt9LCB0aGlzLmNvbmZpZy52aWV3cy5sb2NhbHMsIGxvY2Fscyk7XG5cbiAgICBpZiAoYXR0YWNobWVudHMpIG1lc3NhZ2UuYXR0YWNobWVudHMgPSBhdHRhY2htZW50cztcblxuICAgIGRlYnVnKCd0ZW1wbGF0ZSAlcycsIHRlbXBsYXRlKTtcbiAgICBkZWJ1ZygnbWVzc2FnZSAlTycsIG1lc3NhZ2UpO1xuICAgIGRlYnVnKCdsb2NhbHMgKGtleXMgb25seSk6ICVPJywgT2JqZWN0LmtleXMobG9jYWxzKSk7XG5cbiAgICAvLyBnZXQgYWxsIGF2YWlsYWJsZSB0ZW1wbGF0ZXNcbiAgICBjb25zdCBvYmogPSBhd2FpdCB0aGlzLnJlbmRlckFsbCh0ZW1wbGF0ZSwgbG9jYWxzLCBtZXNzYWdlKTtcblxuICAgIC8vIGFzc2lnbiB0aGUgb2JqZWN0IHZhcmlhYmxlcyBvdmVyIHRvIHRoZSBtZXNzYWdlXG4gICAgT2JqZWN0LmFzc2lnbihtZXNzYWdlLCBvYmopO1xuXG4gICAgaWYgKHRoaXMuY29uZmlnLnByZXZpZXcpIHtcbiAgICAgIGRlYnVnKCd1c2luZyBgcHJldmlldy1lbWFpbGAgdG8gcHJldmlldyBlbWFpbCcpO1xuICAgICAgaWYgKF8uaXNPYmplY3QodGhpcy5jb25maWcucHJldmlldykpXG4gICAgICAgIGF3YWl0IHByZXZpZXdFbWFpbChtZXNzYWdlLCBudWxsLCB0cnVlLCB0aGlzLmNvbmZpZy5wcmV2aWV3KTtcbiAgICAgIGVsc2UgYXdhaXQgcHJldmlld0VtYWlsKG1lc3NhZ2UpO1xuICAgIH1cblxuICAgIGlmICghdGhpcy5jb25maWcuc2VuZCkge1xuICAgICAgZGVidWcoJ3NlbmQgZGlzYWJsZWQgc28gd2UgYXJlIGVuc3VyaW5nIEpTT05UcmFuc3BvcnQnKTtcbiAgICAgIC8vIDxodHRwczovL2dpdGh1Yi5jb20vbm9kZW1haWxlci9ub2RlbWFpbGVyL2lzc3Vlcy83OTg+XG4gICAgICAvLyBpZiAodGhpcy5jb25maWcudHJhbnNwb3J0Lm5hbWUgIT09ICdKU09OVHJhbnNwb3J0JylcbiAgICAgIHRoaXMuY29uZmlnLnRyYW5zcG9ydCA9IG5vZGVtYWlsZXIuY3JlYXRlVHJhbnNwb3J0KHtcbiAgICAgICAganNvblRyYW5zcG9ydDogdHJ1ZVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgY29uc3QgcmVzID0gYXdhaXQgdGhpcy5jb25maWcudHJhbnNwb3J0LnNlbmRNYWlsKG1lc3NhZ2UpO1xuICAgIGRlYnVnKCdtZXNzYWdlIHNlbnQnKTtcbiAgICByZXMub3JpZ2luYWxNZXNzYWdlID0gbWVzc2FnZTtcbiAgICByZXR1cm4gcmVzO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gRW1haWw7XG4iXX0=

Zerion Mini Shell 1.0